Creating Bubblegum Trees


Whilst the data of Compressed NFTs is stored inside transactions and not on-chain accounts, we still need some on-chain accounts to keep track of the Merkle Tree and its configuration. As such, before we can start minting Compressed NFTs, we need to create two accounts:

  • A Merkle Tree account. This account holds a generic Merkle Tree that can be used to verify the authenticity of any type of data. It is owned by the Account Compression Program created and maintained by Solana. In our case, we will use it to verify the authenticity of Compressed NFTs.
  • A Tree Config account. This second account is a PDA derived from the address of the Merkle Tree account. It allows us to store additional configurations for the Merkle Tree that are specific to Compressed NFTs — e.g. the tree creator, the number of minted cNFTs, etc.

With these two accounts, we have everything we need to start minting Compressed NFTs. Note that, we will refer to Merkle Tree accounts with associated Tree Config accounts as Bubblegum Trees.

Creating a Bubblegum Tree

Let's now see how one can create both of these accounts to create a Bubblegum Tree. Fortunately, our libraries make this process easy by providing a Create Tree operation that takes care of everything for us. This operation accepts a variety of parameters — most of them optional — that allow us to customize the Bubblegum Tree to our needs. The most important ones are:

  • Merkle Tree: A newly generated signer that will be used to create the Merkle Tree account. The Merkle Tree account will then be accessible at this address.

  • Tree Creator: The address of the account that will be able to manage the Bubblegum Tree and mint Compressed NFTs.

  • Max Depth and Max Buffer Size: The Max Depth parameter is used to compute the maximum number of leaves — and therefore Compressed NFTs — that the Merkle Tree can hold. This maximum is calculated by 2^maxDepth. The Max Buffer Size parameter indicates the minimum concurrency limit of the Merkle Tree. In other words, it defines how many changes can happen in the tree in parallel. These two parameters cannot be chosen arbitrarily and have to be selected from a pre-defined set of values as displayed in the table below.

  • Public: Whether or not the Bubblegum Tree should be public. If it is public, anyone will be able to mint Compressed NFTs from it. Otherwise, only the Tree Creator or the Tree Delegate (as discussed in Delegating cNFTs) will be able to mint Compressed NFTs.

Here is how one can create a Bubblegum Tree using our libraries:

Create a Bubblegum Tree

import { generateSigner } from '@metaplex-foundation/umi'
import { createTree } from '@metaplex-foundation/mpl-bubblegum'

const merkleTree = generateSigner(umi)
const builder = await createTree(umi, {
  maxDepth: 14,
  maxBufferSize: 64,
await builder.sendAndConfirm(umi)

By default, the Tree Creator is set to the Umi identity and the Public parameter is set to false. However, these parameters can be customized as shown in the example below.

const customTreeCreator = generateSigner(umi)
const builder = await createTree(umi, {
  // ...
  treeCreator: customTreeCreator,
  public: true,

Fetching a Bubblegum Tree

Since a Bubblegum Tree is composed of two on-chain accounts, let's see how to fetch either of them.

Fetching a Merkle Tree

The Merkle Tree account contains various information about the tree such as:

  • The Tree Header which stores the Max Depth, the Max Buffer Size, the Authority of the tree and the Creation Slot of when the tree was created.
  • The Tree itself which stores low-level information about the tree such as its Change Logs (or roots), its Sequence Number, etc. We talk more about Concurrent Merkle Trees in a dedicated page of this documentation.
  • The Canopy as discussed in the Merkle Tree Canopy page.

Here is how one can fetch all of that data using our libraries:

Fetch a Merkle Tree

import { fetchMerkleTree } from '@metaplex-foundation/mpl-bubblegum'

const merkleTreeAccount = await fetchMerkleTree(umi, merkleTree)

Fetching a Tree Config

The Tree Config account contains data specific to Compressed NFTs. It stores:

  • The Tree Creator of the Bubblegum Tree.
  • The Tree Delegate of the Bubblegum Tree, if any. Otherwise, it is set to the Tree Creator.
  • The Total Capacity of the Bubblegum Tree which is the maximum number of cNFTs that can be minted from the tree.
  • The Number Minted which keeps track of the number of cNFTs minted into the tree. This value is important as it is used as a Nonce ("number used once") value for operations to ensure the Merkle tree leaves are unique. Thus, this nonce acts as a tree-scoped unique identifier of the asset.
  • The Is Public parameter which indicates whether or not anyone can mint cNFTs from the tree.

Here is how one can fetch all of that data using our libraries:

Fetch a Tree Config

import { fetchTreeConfigFromSeeds } from '@metaplex-foundation/mpl-bubblegum'

const treeConfig = await fetchTreeConfigFromSeeds(umi, { merkleTree })