Cardstack’s Card Folio App: Community Demo

An example Web app built using Cardstack’s architecture

Cardstack’s first Discord community demo was held last week, showcasing the latest work on Card Folio — an example Web app built on the Cardstack Framework that provides live tracking of cryptocurrency portfolios by importing wallet data, public on-chain data, and third-party currency exchange APIs.

In this demo, Founding Director Chris Tse and Lead Blockchain Engineer Hassan Abdel-Rahman take a deep dive through the app’s code, showing the capability of the Cardstack Framework as a way to integrate disparate data sources quickly.

Card Folio is the basis for a Cardstack product suite the community will be able to add to and build upon, using our composable card system and leveraging the full power of both the cloud and blockchains.

Below, we break the demo into four sections of abridged transcript.

Chris Tse: Hello Cardstack community! This is Chris and Hassan here from New York City at the new Cardstack Studio, which, as you can see, is totally empty. Hopefully not for much longer, but this is kind of our first week here. It’s pretty exciting, and we want to give you an update of a lot of work that we’ve been doing with the team that’s around the world in New York, Boston, California, and in Europe.

We’re excited to show you not only a little demo of the code that you can play with — we’ll open-source it soon — but also walk you through a bit of this minimum viable integration of the different Cardstack components into something that resembles an application.

Our vision is to build essentially the platform for Web 3.0. For those of you who have been in the Cardstack community, you know that we define Web 3.0 slightly differently than other people who define Web3.

With Web 1.0, pages linked together to form a true Web, and everything became hyperlinked; surfing the Web was very exciting. It was very easy to become a Web developer and build something. What ended up happening is: As the Web grew up to today’s Web 2.0, with these social networks and communities, the websites got bigger and became more of a hub model, where everyone congregates around one or two websites.

These websites like Facebook, Google, and Amazon apparently own a lot more than you think. And that’s the Web 2.0 era, with digital superpowers really winning over the consumers, but now creating a situation where this hub and spoke model causes a lot of problems. This is the centralization problem that a lot of people in crypto and blockchain are trying to solve.

We see Web 3.0 as the combination of four aspects that are concurrently coming into the world in terms of the next iteration of the Web — Web, App, Game, and Crypto.

Firstly, we need to bring some of the diversity of Web 1.0, with its different websites and different styles, with the connectivity of Web 2.0. There are good design patterns and product ideas that we are incorporating.

But secondly, we also have to think about Web Dev 3.0: the development structure of moving away from server side programming languages to JavaScript and API in particular, so that it runs both on your browser and sometimes on the server. That gives you a lot of flexibility to integrate data and to integrate APIs in a cohesive way, regardless of whether you’re doing it as a client in the browser or on the server. We leverage a lot of Web Dev 3.0 techniques in the Cardstack stack.

Thirdly, there’s Web 3D, this idea of gaming. Some of the most innovative and engaged communities on the Internet are emerging within Fortnite and other games. People build up credentials, trade objects, and have their own identities and economies.

Finally, crypto — Web3 — especially Ethereum, brings us the value exchange that combines these concepts in a special way, which allows fees to be paid and people to be compensated and rewarded.

These four ideas combined — Web, App, Game, and Crypto — form the substrate of our Web 3.0 idea. We have worked hard to incorporate all the qualities of today’s Web within the Cardstack Framework: qualities like the Web being linkable, inclusive, and referenceable; apps being functional, focused, and empowering; games being spatial, tangible, and interactive; and crypto being verifiable, transferable, and synchronized. But we want to go beyond all that, asking: What does the user see? What is the tangible object the user can interact with in Web 3.0?

Chris Tse: Card UI allows for individual objects — cards — to be stored, exchanged, sent as messages, turned into content, data or assets, and so on. The app is what contains these cards, which are written in HTML and JavaScript. That way, they can be easily incorporated: my card can be in your app, and your app can become a card in my app.

To explain in a tangible and concrete way what cards can be, we decided to build an application that showcases them. A card is a representation of data in the ecosystem. Now, the obvious choice for some data in the crypto ecosystem to be represented is some cryptocurrency. Our demo is in Ethereum, but you can certainly use our stack to support other things as well.

We’ve been using a “crypto portfolio tracker” to show how you can represent something for which you possess the private key and say, “this is something I posses,” the same way you would with a boarding pass or a credit card.

These are active assets that you might have in the Bitcoin network, other types of fork networks or privacy coin networks, and they can be organized and summarized. But each of the cards can then zoom out to give you low-level context.

We thought of what you might need, other than on-chain information: You need to have exchange rates, which come from API, and you need to know the address in your wallet, which comes from another API and other data sources.

We take different data that could exist on the cloud, on a device, in a personal data repository, or on the blockchain, and combine all that information. In the future, you might even tag it to additional annotations that are particularly meaningful to you.

You’ll be able to organize all of your information, not worrying about whether it’s in a wallet in someone else’s custody, in your own Trezor wallet, or in an exchange — we can summarize all your assets in one place.

These cards are mobile and tactile, similar to objects in a game. You can stack them, organize them, and so on. This tactileness of cards requires a slightly different programming model.

We believe this idea of embedding requires us to rethink what an app really is. Not only does a card require you to have a template and the logic in Javascript and the data model; you also need to figure out relationships, delegation, metadata access — in this case — permissions, constraints, schemas, and mapping to different data sources. To create a card, you just need these in a Github repository.

If you want all these applications to be truly useful, you need to have these user experiences. And how do you synthesize all that data? That’s what the Cardstack application framework is trying to do: provide not only the basic framework to build this, but also sample applications that you can compose.

When the data comes from your computer, a full node on the cloud, or a Geth node, it gets synthesized into a data synthesis workflow indexing engine that is part of the Cardstack framework — and that also turns the data into new objects, which represent something that is real to you, rather than being just a bunch of hashes in the block explorer.

We’re going to show you an example of an app that has all these things working — running the infrastructure, synthesizing the data, tapping the consensus of the node itself, and the UI component. We call this demo app Card Folio, and it will be open-sourced very shortly. It’s a combination of a blockchain explorer, a portfolio tracker, and a wallet app.

If I want to know the details of an Ethereum transaction — what the gas fees were, if it succeeded, etc. — I need an Ethereum plugin to look in the full node, or even an explorer as an API to get that information. Once you have enough transactions, you can show a summary of the individual transactions. On top of that, you can inspect and introspect the smart contract and look at the balance of any currency.

To keep track of all these assets, you get a list of all the addresses and networks they came from. You could also scrape a Trezor wallet (which is an upcoming feature) to find the addresses, which can then look for the assets and the transactions and synthesize the data. That’s how we give you a portfolio.

With exchange rates, we take the history of that transaction — when you got the ETH, when you took the ERC-20 out — and correlate it to a price feed that captures it nicely. We tell you your buy-in and buy-out, your airdrops — the total value of your portfolio, which is composed and synthesized on the top.

You could run this system on the cloud, but you could also run Cardstack on your own computer, so that your entire watch list and its addresses are never leaked to anyone. That depends on whether you take a more convenient approach or you want to run it yourself.

In the future, with e-banking, this same portfolio user could connect to an existing account within a financial institution. You could use the portfolio and its cards to tap into those data sources.

This is how the Cardstack plugins in our Github repository will be synthesized. All this — the Ethereum plugin reflecting your ETH access, having a watch list in Git, getting a portfolio mapped to an exchange rate that allows you to log in and see information — that is what we ship and what this demo UX will show.We are using this as a way to expand the scope of not just Card Folio as a product, but also Cardstack as a framework for building these decentralized financial applications.

Hassan Abdel-Rahman: Hi everyone, my name is Hassan. I’m a developer here at Cardstack.

Chris’ challenge for us was to create an interesting, novel app using the Cardstack plugin, and I’m going to show you some of those features today.

This is a live app running in our staging environment. As Chris was explaining, there are a lot of different data aggregations. At the highest level, what we’re looking at here is a portfolio. A portfolio contains wallets, a wallet contains assets, and these assets happen to be addresses on various crypto networks.

We see both the values from individual assets being rolled up along with the various sums at each of the different levels. Here you see an Ethereum address, and this is the current value in US dollars for today. You also see one for Bitcoin, Litecoin, and ZCash. We’re pulling the conversion rates for these various cryptocurrencies into US dollars live. This is all coming from CryptoCompare, so we roll that up into the overall value for the wallet itself as well as for the portfolio.

What we’re looking at now is the wallet, but we can separate information and look at individual currencies. We see all the Bitcoin assets, the Ethereum assets, the Litecoin assets, as well as the USD value, then we can sum that up for each different class of cryptocurrency and roll it all up.

The power of this is coming from our server-side computeds — that’s what’s allowing us to do all the heavy lifting in terms of correlations between different data sources, and it’s performing that work on the server so the client has all the baked information all ready to go, and only needs to worry about how to render that on the screen, not how to sum up currencies for each wallet.

Let’s take a look at this particular card, an Ethereum asset. One of the things you’ll notice is that when I switch back and forth between this card, you see an embedded view and an isolated view. When a card lives within another card, it’s said to be embedded into another card. We can then isolate that embedded card, and that card now takes up the full screen.

In this particular Ethereum asset card, you can see the value of the asset over time at the exchange rate for that particular day. CryptoCompare has the weighted volume average daily rate, which means on midnight at GMT we take the value of the asset and create a data point for it. We see that asset fluctuate when transactions occur, we also plot those, and you’ll see the transaction value at the time the transaction occurred.

We can also keep track of these asset values in different currencies. This is a USD currency, and now we’re looking at the Euro currency, or we can look at this in terms of BTC. When we do that we actually are changing the whole site, so now I can see everything in terms of BTC.

If I want to take a look and see how everything is sliced and diced in terms of BTC, you can do that as well, as we’re just using a really standard charting library here. Additionally, for each transaction we see transaction embedded cards. So I can click on a transaction and isolate that embedded transaction card, and look at the isolated transaction card.

Going back to this card: it’s pulling live data, so I can perform an Ethereum transaction. Well, let’s do that right now — we can actually see it happen live. I have my Trezor wallet, so let’s send ETH to this particular address.

That transaction is being mined, and once it’s done we’ll have a Geth node — one of our Ethereum plugins — that we’re using as one of our data sources. It’s listening for new blocks, and as blocks are mined it’s looking to see if a transaction occurs from the particular address that we’re tracking. And if it detects one, it fires an event that says we have a new transaction, and the Cardstack Hub does its thing.

It then indexes that data source with a new address for that transaction, which triggers invalidations within our index. When invalidations occur, we recompute our server-side computed so we have an asset history that is correlating the address value with the transactions for that address, as well as CryptoCompare rates for that day, and putting it all together to create a time series of the data points for that asset’s value over time.

We can even scroll down and see this new transaction, which looks similar to what you’d see on Etherscan. We’re pulling the same information that Etherscan pulls and displaying it in a slightly different way.

I’ve mentioned that we have many different data sources. We have a Git data source that we’re using for user provided data, which in this case are the actual assets we’re interested in, their addresses, the wallet, and all the addresses that are contained within the wallet, then the portfolio itself, which is an aggregation of those wallets.

We could have chosen many different data sources, but we thought Git was really interesting in this particular case — especially for developers. Developers are very familiar with Git, and know it can version while keeping versioned data sources in a sophisticated way. If you want to track content and people contributing to content, Git’s an awesome way of doing that, because code is a type of content.

As users save information, it is saved into Git rendering it in the portfolio itself, which is associated to a user. In this manner, only I can see my portfolio and no one else.

The structure we’re using is called JSON:API, a fascinating format for data and expressing relationships. It’s built into Ember, so it is the simplest database structure to use. We find it’s very robust in terms of being able to represent relationships.

You can see various assets in this wallet, one of them being the Ethereum address. Diving one level deeper, you can see the asset itself; this is an example of the Ethereum address we were just looking at as an asset. You’ll notice it is not related to a user, because in Ethererum everything is global; there’s nothing inherently private about an asset or an address on Ethereum. So in this case, we’re just saying the asset is related to this address by virtue of its ID, and that it’s related to the Ethererum network. Once we do that, we have all the information Cardstack needs to start tracking this address and listening for new events occurring on the blockchain.

A lot of the features you’re seeing are native to Cardstack, some of them coming from the Folio app itself. If you take a look at a Cardstack application, it is basically a mono repo. Within the mono repo are NPM modules for each of your different cards, as well as an NPM module for the application itself. For those of you familiar with Ember, this will probably look very familiar: you’re looking at an Ember application with Ember add-ons, which are Ember’s way of having shareable, reusable modules.

Within the Ember application itself as well as within each of the cards is a folder called Cardstack. The way we’re able to allow all this to work, is we have a place for all the front-end logic and a place for all the back-end logic. A card is really a vertical stack through all the layers of application. The idea is that it’s all about creating useful places to provide your data and logic.

The front-end parts of the cards are governed by standard Ember layout, and the back-end parts are governed by this Cardstack folder and what are called features. A feature could comprise of one of the many different types of plugins we have. We have searcher features, we have indexer features, we have middleware features, and we have authentication features. These different types of features help drive capability for your cards.

We have an Ethereum data source that says where the Geth node is and what the content types are that hold fields containing addresses that we want to track. Then the data source configuration file describes a bit more about interesting computed properties that will be patched into these various Ethereum models that come out of the box when you NPM install the Cardstack Hub.

We also have a CryptoCompare data source — we create a cache for each currency for that exchange rate so that we never ask for CryptoCompare more than once for any exchange rate. So this allows us to incredibly efficiently use CryptoCompare’s API.

Those exchange rates are then cached in the Cardstack’s index. We have a synthesized data source, and this is our asset history. The asset history is where different data sources come together. In this case, we have our Ethereum and CryptoCompare data sources coming together with our Git data source, which is also describing our tracked addresses.

Let’s go a little bit deeper into a specific card: the asset card. You’ll remember the asset card has both an isolated view, which was the full screen view, and an embedded view. We have templates for the the embedded view of the asset as well as for the isolated view.

Ember Animated picks out the interesting parts of each of these templates, then animates them for us so we don’t have to write any code. Going down into the actual Cardstack features, what we see here is static-model type of feature where we’re able to describe the schema for a card.

These are the different fields that comprise an asset. For this field, we have today’s rates as a computed field, which is coming from the intersection of information that’s in Git as well as the information that’s in CryptoCompare.

Computeds are the part of Cardstack where the different data sources intersect, and the correlations between different data sources occurs. We have various computed fields that we define here as part of our schema, then we have various grants.

These are the permissions that are available. Assets aren’t too exciting in terms of grants — anyone can see an asset, because assets aren’t inherently private to a particular person since they are available on the blockchain.