Back to blog

Building Private NFTs on Solana

Building Private NFTs on Solana

Steve

A few weeks ago we published a post on Private NFTs and how you can build them using Pinata’s Private IPFS API. It’s a working solution for token gating extra files that are attached to the NFT’s metadata, which enables a lot of possibilities for crypto developers. It got us wondering if we could build something similar for Solana, and the answer is yes! You can see it live at solana.concealmint.com. In this post, we’ll go over some of the details on how we did it and some of the differences we saw with Solana. In the end, the principles stay the same and enable developers to use Private IPFS on any blockchain. Let’s dive in.

Solana Programs

One of the things that sets Solana apart right away from other blockchains is its design around smart contracts, or more correctly “programs.” If you want to mint NFTs on an EVM chain, it generally means you have to setup and deploy your own smart contract. You also generally need some kind of indexer to record ownership of NFTs. On Solana there’s lots of Token and NFT standards that while similar to EVM have more publicly available programs you can interact with right away. Using Umi, a Javascript implementation for Solana, a use can simply connect a wallet, upload metadata, then mint an NFT right out of the gate. Additionally Solana’s JSON RPC standard includes methods that can be used in place of indexers to get information about NFTs.

Solana Metadata

A key piece to Private NFTs is the metadata. Traditionally, on EVM chains, this is a JSON file that lives offchain and is referenced in the contract. On Solana, the same principle applies but with slightly different standards that the NFT must abide by. Here’s an example JSON file:

{
	"name": "Pinnie Secrets",
	"description": "Secrets only Pinnie can know",
	"external_url": "<https://solana.concealmint.com>",
	"image": "<https://dweb.mypinata.cloud/ipfs/bafkreibx2dfgwof5vclwt2ns6xaddkxzza5vwvym64wnqrpwp72o6yhox4>",
	"properties": {
		"files": [
		  {
				"uri": "<https://dweb.mypinata.cloud/ipfs/bafkreibx2dfgwof5vclwt2ns6xaddkxzza5vwvym64wnqrpwp72o6yhox4>",
				"type": "image/png"
			},
			{
				"uri": "bafkreig7ztgu2y3gevjvlmkpppkr223uhubh4gofe5kargjn7zf7n4md3q",
				"type": "cid"
			}
		],
		"category": "files"
	}
}

Some of these fields will be familiar to a Solidity dev, such as the name, description, exeternal_url, and image. An additional field required for the Token Metadata Standard by Metaplex is the properties object. This holds a files[] array and a category. The first file in the array is the same image as our image property that gives extra info about what kind of image it is. If we had other fields like animation_url for a video we could designate the content here as well. The second file in the array is our own custom type which we just called cid, and this is the file on Private IPFS that only the owner will have access to. While this metadata is offchain, we could just as easily use one of the Metaplex Token Extensions to add a key-value pair to the NFT with a file property as well!

Solana Auth

In order for the owner of the NFT to access this private file, they have to prove they own the NFT. To do this, we used a pretty traditional authentication mechanism: Sign In With Solana (SIWS). With this standard, we use the cryptography of a user’s wallet to authenticate them and grant access. When a user first signs in we have them sign a message which we pass to the backend of our app to verify the signature. If it is valid, then we create a temporary JWT which stores the user’s wallet address. Now, when the user makes a request from the app to access the private file of their NFT, we can use that JWT, verify it’s still valid, pull the wallet address from the JWT, then check if the address matches the owner of the NFT onchain. If that passes, then we can create a temporary signed URL from our Private IPFS API that lets the user access the file.

0:00
/0:07

Wrapping Up

While blockchains will vary on multiple technical fronts, there are usually two needs that always come up:

  • Verifiable and secure offchain data
  • Truly private content

IPFS has proven itself over the past several years that it is the perfect companion to blockchains, as its content addressability and peer-to-peer persistence makes it ideal for offchain data references. Pinata’s history is a testament to this fact. Something equally true is that encryption does not mean private. Ask any enterprise security team and they’ll let you know that encrypted public data is not sufficient. This is why Pinata has been building and perfecting Private IPFS, to provide a new way to keep content private, but keep the content addressability through CIDs as well as the possibility of private peer-to-peer connections. We’re just getting started, and we can’t wait to see what you build.

Happy Pinning!

Subscribe to paid plan image

Share this post:

Stay up to date

Join our newsletter for the latest stories & product updates from the Pinata community.