NFT Compression

Cost efficient NFTs.


Helius enables developers to interact with compressed NFTs via the Digital Asset Standard (DAS) API, an open-source specification and indexer. The API documentation can be found at Digital Asset Standard API.

What is NFT compression?

Compressed NFTs cost roughly 1% of the usual price to mint.
Solana NFT compression allows developers to mint large amounts of NFTs for a fraction of the cost. This is achieved by maintaining NFT state off-chain with indexing companies (e.g. Helius) instead of accounts. There is a validation mechanism that ensures off-chain and program interactions are legitimate and secure.
TLDR – Compression eliminates the need for complete on-chain storage while still retaining the decentralization, security, and programmability of Solana.
Compressed NFTs are stored in a Merkle tree on the Solana ledger and the off-chain indexers. The validity of the Merkle tree can be checked by looking at the "root hash" – derived by iteratively hashing together the contents of the entire tree. The root hash is stored on-chain. Modifications to a compressed NFT require a "proof" to ensure that the NFT cannot be maliciously modified. The data returned by an off-chain indexer can also be verified by comparing the root hash with what is stored on-chain. For a deeper dive into how this works, please read the Metaplex documentation.

How are compressed NFTs different?

  • Compressed NFTs are not native Solana tokens. They do not have a token account, mint account, or metadata.
  • One account exists per Merkle tree and each tree can hold millions of NFTs.
  • One collection is able to use multiple Merkle trees (recommended for larger collections).
  • A Merkle tree account can also hold multiple collections (not recommended).
  • An API call is required to read any information about a compressed NFT (e.g. attributes, collection information, etc). This would have affect on Solana dApps loading your assets, etc.
  • All NFT modifications must happen through the Bubblegum program.
  • A compressed NFT can be converted to a regular NFT (but not the other way around).
For practical reasons it is recommended to keep the tree size to 1 million or less. This is because the proof path will begin to exceed the Solana transaction account limit.

What modifications are possible?

At the time of writing, the following methods are supported by Bubblegum:
  • Mint - Mint compressed NFT
  • Transfer - Transfer compressed NFT
  • Burn - Burn compressed NFT
  • Delegate, CancelDelegate - Delegate authority of an NFT to a different wallet/Cancel the redemption of an NFT (Put the NFT back into the Merkle tree)
  • Redeem, CancelRedeem - Redeem an NFT (remove from tree and store in a voucher PDA)/* Cancel the redemption of an NFT (Put the NFT back into the Merkle tree).
  • Decompress - Decompress an NFT into an uncompressed Metaplex NFT. This will cost the rent for the token-metadata and master edition accounts that will need to be created.
  • VerifyCreator, SetAndVerifyCreator - Verify and un-verify a creator that exists in the NFT’s creator array.
  • VerifyCollection, SetAndVerifyCollection - Verify or un-verify an NFT as a member of a Metaplex Certified collection when the collection is already set in the Metadata. Or set a new collection in the metadata and verify the NFT as a member of the new collection.
You can find out more from the Bubblegum program docs here.

How does the indexer work?

As mentioned before, compression NFT information is not stored on in a traditional Solana account. Instead they have all of their metadata stored on a ledger and need help of indexing services to quickly fetch the metadata required.
The DAS indexer listens to all Bubblegum transactions, parses them, and updates an off-chain database. For example, when a compressed NFT is minted the indexer will parse that transaction and extract all of the NFT info (name, collection, owner). If a tree was never seen before or it is missing an update, the indexer will fetch the tree's transaction history and reconstruct the state.
The indexer code can be found here.


You can get started with the following examples:

Further Reading