A Node Proxy for Pinning Tezos NFTs Using Pinata

Maddy Bishop Van Horn on background

Maddy Closs

Tezos coins

There’s a lot of background information needed to follow this post. Rather than trying to cover it all here, I’m going to link out to some resources:

Diagram that shows how various blockchains communicate via the internet

As you now know if you watched the video above, the internet most of us think of uses location addressing. URL stands for Uniform Resource Locator (emphasis added by me). A URL tells a browser which folder on which server to go to find the content to display. For example, let’s take the following URL:

https://www.savaslabs.com/sites/default/files/2021-09/Infographic.png

This URL tells the browser to display the image named Infographic.png that can be found in the sites/default/files/2021-09 folder on the server hosting the Savas Labs website.

If someone went into that folder and replaced Infographic.png with a completely different image, but with the same name, the new image would display. The original content isn’t inherently tied to the address. 

This poses a problem for NFTs, where being able to verify the authenticity of the file is crucial. For this reason, best practices state that NFT assets should be hosted on IPFS (InterPlanetary File System), a system leveraging content addressing - that is an address that is tied to the content of the file. 

Enter Pinata, a service that bills itself as making managing NFT media and utilizing content addressing easier. I think of Pinata as cloud storage for generating and managing IPFS files, with a nice API on top.

For a recent project, we were building an NFT WordPress plugin called Minterpress that would allow artists to mint and display NFTs on a public-facing WordPress site. But pinning media with Pinata requires the usage of Pinata’s Node SDK and WordPress is written in PHP, not Node. In order to use Pinata to manage the NFTs we create in our WordPress plugin, we needed to pass all of the information we collect about the NFT (the metadata) to be created through a Node app to Pinata.

So, I built a microservice to act as a Pinata proxy: https://github.com/savaslabs/minterpress-pinata-proxy

Based very heavily on @claudebarde’s backend approach in How to mint NFTs on Tezos using Taquito and Pinata, the proxy provides a single endpoint for pinning media and metadata from any client-side application to Pinata, where a cryptographic hash is created and pinned to IPFS. This is a one-way encryption system. There is no way to reverse-engineer a file from an IPFS hash. This guarantees that the URL where the (soon to be minted) NFT is located will always store the pinned content. The file can’t be replaced by another file, because that file would have a different IPFS hash and therefore not exist at the minted URL.

Infographic diagram that shows how Tezos, IPFS, Pinata, and our custom plugin communicate with one another.

Step-by-Step

And here’s a step-by-step explanation of how the proxy works:

  1. The endpoint receives a POST with `multipart/form-data` which is processed by Express middleware multer.
  2. The FormData contains Pinata credentials (client-side application developers should take care to securely store credentials). It uses the credentials to authenticate to Pinata via the Pinata SDK.
  3. Next, it fetches the media file via URL
    1. We fetch via URL instead of sending the file itself via FormData so that the image can be uploaded via a 3rd party file upload module. In our case, this is the default WordPress media upload service, but it could be something like Uppy or FilePond. These provide a sleeker and more familiar user interface (drag and drop, previews…) than <input type=”file” />.
  4. It then pipes the file to be pinned to a readableStream, which is the file format required by Pinata.
  5. It sends the stream to Pinata to pin to IPFS using pinata.pinFileToIPFS
    1. pinata.pinFileToIPFS returns an IPFS hash. No matter how many times a file is run through the IPFS hashing system, the resulting hash (described by IPFS as the CID or Content Identifier) will be the same. If the file changes in any way, the resulting hash will be different. 
  6. Then, it takes that IPFS hash and adds it to the metadata.
  7. It sends the resulting metadata to Pinata to pin to IPFS using pinata.pinFileToIPFS
    1. Metadata follows TZIP-21 protocol. This is specific to the Tezos blockchain, but the metadata format could be easily adapted to another blockchain or an updated protocol.
    2. Pinata returns the IPFS hash / CID for the metadata.
  8. Our proxy endpoint returns both the media IPFS hash and the metadata IPFS hash to the client application.

Finally, back on the client-side, the metadata IPFS hash can be used to mint an NFT on the blockchain. 

And there you have it! A microservice for apps without Node backends to utilize Pinata for pinning media to IPFS.

https://github.com/savaslabs/minterpress-pinata-proxy

If you enjoyed my blog post and are interested in working with Savas Labs for your next project, I invite you to schedule a discovery session with our Business Development team here. However, if you have specific questions regarding my work with the Minterpress plugin, I would be happy to answer them, feel free contact me here!