At a high level, state compression is a technique in which off-chain data is secured by the Solana ledger, using a hashing algorithm to "fingerprint" the off-chain data and storing it inside a special on-chain Merkle tree, called a Concurrent Merkle Tree.
With this technology, compressed NFTs can be created on-chain in a similar manner as before, but for a fraction of the cost as before. As a frame of reference of on-chain cost reduction, take a 1 million NFT collection:
- traditional NFTs (aka non-compressed):
- 1 million NFTs ~= 12,000 SOL
- compressed NFTs:
- 1 million NFTs ~= 5 SOL
- Solana Docs for State Compression
- written guide minting compressed NFTs (which is based on this repo)
- uses TypeScript and NodeJS
- yarn (as the node package manager)
- Clone this repo to your local system
- Install the packages via
yarn install
- Rename the
example.env
file to be named.env
- Update the
RPC_URL
variable to be the cluster URL of a supporting RPC provider
If you have the Solana CLI installed locally: update the LOCAL_PAYER_JSON_ABSPATH
environment
variable to be the absolute path of your local testing wallet keypair JSON file.
After setting up locally, I recommend exploring the code of the following files (in order):
After reviewing the code, then running each of these scripts in the same order.
Note: Running each of these scripts will save some bits of data to a
.local_keys
folder within this repo for use by the other scripts later in this ordered list. Therefore, running them in a different order will result in them not working as written. You have been warned :)
Once you're setup locally, you will be able to run the scripts included within this repo:
yarn demo ./scripts/<script>
Performs all the following actions:
- create a new Merkle tree on-chain
- create a new NFT collection
- mint two compressed NFTs (to different addresses)
Functionally the same as scripts/createAndMint.ts
. This script adds extra console logging and
comments for explanation purposes.
Uses the ReadApi fetchAssetsByOwner
method to fetch the NFTs owners by the two addresses.
Uses the ReadApi fetchAssetsByGroup
method to fetch the NFTs belonging to the same collection,
compressed or otherwise.
Performs the complete process to transfer compressed NFTs. Specifically:
- fetching the NFT asset data from the RPC
- fetching the asset's proof from the RPC
- verifying the RPC provided proof on the client side
- builds the compressed NFT transfer function
Mint additional compressed NFTs into an already existing collection and/or tree.
This repo also contains code examples of how to use the
@metaplex-foundation/js
sdk to work with
compressed NFTs, including reading and transferring them.
After setting up locally, I recommend exploring the code of the following metaplex specific files (in order):
./metaplex/mintToCollection.ts
./metaplex/transferNFT.ts
./metaplex/fetchNFTsByOwner.ts
./metaplex/simpleProofVerification.ts
Mint a single compressed NFT to an existing tree and collection, using the metaplex sdk. This
requires you to create your tree and collection ahead of time. See the
./scripts/verboseCreateAndMint.ts
script for details on how
to create a tree and collection.
Transfer a compressed NFT using the metaplex sdk. This method only requires you to know the
assetId
of the compressed NFT to transfer.
Uses the ReadApi fetchAssetsByOwner
method to fetch the NFTs owned by a single address.
Uses the ReadApi fetchAssetsByGroup
method to fetch the NFTs belonging to the same collection,
compressed or otherwise.
Mint additional compressed NFTs into an already existing collection and/or tree.
- Solana Docs:
- State Compression
- Guide for compressed NFTs (which is based on this repo)
- Account Compression SPL Program:
- Metaplex Read API:
- Metaplex Compression examples: