How to Display Your NFT Collectibles Like NBA Top Shot With Flow and IPFS

Using Pinata: Part 2

Justin Hunter
Mar 4 · 8 min read

This is part two of a three-part series focused on the Flow blockchain, NFTs, and IPFS. You can read part one here:

In this tutorial, we’re going to build a simple React application that interfaces with Flow smart contracts to authenticate and to fetch NFTs owned by a user. We will then resolve the NFT’s metadata to get the IPFS location of the NFT’s underlying digital asset (in this case a video). Quick reminder about the NFT we’re working on — we’re building NFTs that, like NBA Top Shot, back video content, but unlike Top Shot, the videos are of people smashing piñatas.

Setup

For this tutorial, you’ll need to have your Flow emulator running. If you don’t remember how to start that, take a look at the previous post or check out the Flow CLI docs. It’s important to note that the Flow emulator is an in-memory representation of the Flow blockchain. So if between the first post and this one, you shut down the emulator, you’ll need to go ahead and do the following:

  • Start the emulator
  • Deploy the project
  • Mint your NFT

Each of those steps is covered in detail in part one of this series.

In addition, you’re going to need to have NodeJS installed on your machine. You can install it here.

And as usual, you’ll need a text editor.

Setting Up React And Dependencies

I’m going to be creating my React app within the parent pinata-party directory I started in part one of these tutorials. However, if you want, you can create your React app in a completely new directory.

To create our app, run:

When everything is done installing, you’ll have a new directory called pinata-party-frontend. Switch into that directory, and we’ll need to install some dependencies.

First, per the documentation on Flow here, you’ll need to install the Flow JS SDK. In fact, for the first part of the frontend setup, we’re just going to follow the Flow documentation.

Let’s continue. Run:

We’re going to store some values as global variables for our application. We will make use of environment variables. In react, this means creating a .env file and setting key value pairs where the keys are prefixed with REACT_APP. If you follow the Flow documentation, you’ll be set up to be connected with their testnet. For the sake of this tutorial, we’re connecting to the Flow emulator. So, we’ll need to make some changes. In your .env file add the following:

Replace the REACT_APP_ACCESS_NODE value with the local emulator url as indicated above. Replace the REACT_APP_CONTRACT_PROFILE value with the address you received when you deployed your project.

Now that we have that, we need to create a config file that we will use to interact with the Flow JS SDK. Create a file in the src directory called config.js. Add the following:

This configuration file just helps the JS SDK work with the Flow blockchain (or emulator in this case). To make this file available throughout the app, open up the index.js file and add this line:

Now, let’s wire up some authentication. You don’t need to force people to authenticate into the site if you don’t want to, but it will be important to have authentication for part three of the tutorial which enables the transferring of NFT assets.

We need to create an authentication component. In your src directory, create a file called AuthCluster.js. Inside that file, add the following:

This is simple using a login and sign up button to leverage the Flow JS SDK’s ability to connect to a wallet discovery provider. You’ll be able to sign up for an account or sign in with an existing account. It’s pretty nice!

Now, we need to get this component into our app. Let’s keep it simple for now. Replace your App.js file with the following:

If you start the app now (npm start), you should see a page with a login and a sign up button. In fact, both of those buttons are functional. Try it out.

Ok, now that our React app is largely set up and our dependencies are installed, let’s get to building out the ability to fetch NFTs for an account and display them.

Fetching NFTs From Flow

In order to display our NFT that minted in the first post, we need to be able to communicate with the Flow blockchain. In the case of this tutorial, we need to be able to communicate with the Flow emulator. We already told our app that the emulator was running on port 8080 when we set up our .env file. But now, how do we use JavaScript to talk to Flow?

Fortunately, Flow has this functionality built into their JS SDK. If you remember, we previously wrote a script to look up an NFT based on its token id and return the token’s metadata. It looked like this:

Now, we just need to be able to convert that into a JavaScript call. Let’s create a new component that will allow us to both fetch data and eventually display the NFT data. In your src directory, create a file called TokenData.js. In that file, add the following:

In this file, we are creating a component that has a button to fetch token data. We are also creating a button to clear token data. When the fetch button is clicked, it calls a function we created called fetchTokenData. That function uses the Flow JS SDK to execute the exact same script we executed in part one of this tutorial from the command line, but in React. We take the results of the execution and we set the results to a state variable called nftInfo. If that variable exists, we render the key value pairs from the NFT metadata on screen and a button that lets us clear the data.

I’ve also added a bit of CSS to make things look less plain. If you want to add the same CSS, it’s here, and all you have to do is replace App.css with this:

Now, just add your new component to App.js below the AuthCluster component like this:

Check out your app now and try to fetch your token data. It should look like this:

This is pretty cool! We are looking up an NFT owned by the account we specified, then we are fetching the metadata from that token. We are displaying that metadata on screen, but we know that one value in that metadata resolves to a video file. Let’s see if we can get that rendered on screen shall we?

Getting Media From IPFS

You already signed up for a Pinata account and you added your video file to IPFS through the Pinata upload interface. That means you have been able to fetch content from IPFS already. In the Pin Explorer, when you click on a hash, you are taken to the Pinata IPFS gateway where your IPFS content is resolved and displayed to you. For the sake of this tutorial, we’re going to keep things a little more general while at the same time highlighting the beauty of IPFS.

That is to say, you don’t have to fetch your content from the Pinata gateway. Instead, we’re going to fetch it from the public Protocol Labs gateway.

Let’s dive in.

Back in your TokenData.js file, let’s add a way to display the video file we ultimately retrieve from IPFS. Update your file to look like this:

We’ve added a video element with the source pointing to the file on IPFS. You’ll notice that we had to split the uri value to get just the IPFS hash so that we could fetch the content from the IPFS gateway. Let’s talk about that URI for a moment.

The uri we created with our NFT look like ipfs://Qm.... We created it that way because the IPFS desktop client will allow you to click on and open links that look like that by default. Also, the Brave browser supports pasting in links that look like that. We think this link format will be supported more and more as we go.

However, in this case, we need the hash so that we can fetch the content from the IPFS public gateway. When we’re done, the link would look like this:

https://ipfs.io/ipfs/QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6

Now, if you try fetching the token data in our app, you should get something like this:

Our NFT is no longer a faceless token on a blockchain. It’s a real live digital asset! Your video will probably be different, but hopefully the result you see in your app is essentially the same experience.

Wrapping Up

This is a very simple app, and there is a lot you can do to make it prettier, make it more interactive, and even add more Flow elements to it. The Flow JS SDK is powerful, so I recommend reading through the docs.

We successfully added authentication to our app using Flow, we created an interface to fetch information about an NFT, and we created a way to display not just the raw metadata but the underlying digital asset. All of this is secured by both the Flow blockchain and IPFS. We know that the NFT is owned by the person who says they own it, and we know the content displayed is valid because the hash is encoded into the NFT.

In the final installment of this series, we’ll focus on creating a mini-marketplace that will allow us transfer NFTs.

Happy Pinning!

Go to part 3:

Additional reading:

The Easiest Way to Use IPFS

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store