mpl-bubblegum 2.1.1

Metaplex Bubblegum SDK
Documentation
<h1>
  Metaplex Bubblegum SDK
</h1>
<p>
  Rust library for interacting with <a href="https://github.com/metaplex-foundation/mpl-bubblegum">Metaplex Bublegum</a> program.
</p>

## Getting started

From your project folder:

```bash
cargo add mpl-bubblegum
```

> **Note**
> If you are using a `solana-program` version prior to `1.16`, first add the `solana-program` dependency to your project and then add `mpl-bubblegum`. This will make sure you only have a single copy of the `borsh` crate.

## Structure

The client SDK is divided into several modules:

- `accounts`: structs representing the accounts of the program
- `errors`: enums representing the program errors
- `instructions`: structs to facilitate the creation of instructions, instruction arguments and CPI instructions
- `types`: structs representing types used by the program

## Instruction Builders

One of the main features of the client SDK is to facilitate the creation of instructions. There are two "types" of instruction builders automatically generated – both support passing accounts by name and optional positional.

### _Client_ instruction builders

This are intended to be used by off-chain client code. Each instruction is represented by a corresponding struct – e.g., `MintV1`:

```rust
pub struct MintV1 {
    pub tree_config: solana_program::pubkey::Pubkey,

    pub leaf_owner: solana_program::pubkey::Pubkey,

    pub leaf_delegate: solana_program::pubkey::Pubkey,

    pub merkle_tree: solana_program::pubkey::Pubkey,

    pub payer: solana_program::pubkey::Pubkey,

    pub tree_creator_or_delegate: solana_program::pubkey::Pubkey,

    pub log_wrapper: solana_program::pubkey::Pubkey,

    pub compression_program: solana_program::pubkey::Pubkey,

    pub system_program: solana_program::pubkey::Pubkey,
}
```

After filling in the instruction account fields, you can use the `instruction(...)` method to generate the corresponding `solana_program::instruction::Instruction`:

```rust
// instruction args
let metadata = MetadataArgs {
    name,
    uri,
    creators,
    ...
};

// instruction accounts
let mint_ix = MintV1 {
    tree_config,
    leaf_owner,
    leaf_delegate,
    merkle_tree,
    payer,
    tree_creator_or_delegate,
    log_wrapper: spl_noop::ID,
    compression_program: spl_account_compression::ID,
    system_program: system_program::ID,
};

// creates the instruction
let create_ix = create_ix.instruction(
    MintV1InstructionArgs {
        metadata,
    });
```

Alternatively, you can use the `MintV1Builder` to create the appropriate instruction:

```rust
let mint_ix = MintV1Builder::new()
    .tree_config(tree_config)
    .leaf_owner(leaf_owner)
    .leaf_delegate(leaf_delegate)
    .merkle_tree(merkle_tree)
    .payer(payer_pubkey)
    .tree_creator_or_delegate(tree_creator)
    .metadata(metadata)
    .instruction();
```

### _CPI_ instruction builders

These are builders to be used by on-chain code, which will CPI into Bubblegum. Similarly to "off-chain" builders, each instruction has a struct to invoke CPI instructions – e.g., `MintV1Cpi`:

```rust
pub struct MintV1Cpi<'a, 'b> {
    /// The program to invoke.
    pub __program: &'b solana_program::account_info::AccountInfo<'a>,

    pub tree_config: &'b solana_program::account_info::AccountInfo<'a>,

    pub leaf_owner: &'b solana_program::account_info::AccountInfo<'a>,

    pub leaf_delegate: &'b solana_program::account_info::AccountInfo<'a>,

    pub merkle_tree: &'b solana_program::account_info::AccountInfo<'a>,

    pub payer: &'b solana_program::account_info::AccountInfo<'a>,

    pub tree_creator_or_delegate: &'b solana_program::account_info::AccountInfo<'a>,

    pub log_wrapper: &'b solana_program::account_info::AccountInfo<'a>,

    pub compression_program: &'b solana_program::account_info::AccountInfo<'a>,

    pub system_program: &'b solana_program::account_info::AccountInfo<'a>,
    /// The arguments for the instruction.
    pub __args: MintV1InstructionArgs,
}
```

After filling in the program, instruction accounts and argument fields, you can use the `invoke()` or `invoke_signed(...)` method to perform the CPI:

```rust
// instruction args
let metadata = MetadataArgs {
    name,
    uri,
    creators,
    ...
    };

// instruction accounts
let cpi_mint = MintV1Cpi::new(
    bubblegum_info,
    MintV1CpiAccounts {
        compression_program: spl_account_compression_info,
        leaf_delegate: authority_info,
        leaf_owner: authority_info,
        log_wrapper: spl_noop_info,
        merkle_tree: merkle_tree_info,
        payer: payer_info,
        system_program: system_program_info,
        tree_config: tree_config_info,
        tree_creator_or_delegate: delegate_info,
    },
    MintV1InstructionArgs { metadata },
);

// performs the CPI
cpi_mint.invoke_signed(&[&signer_seeds])
```

You can also use the `MintV1CpiBuilder` to simplify the process:

```rust
let cpi_mint = MintV1CpiBuilder::new(ctx.accounts.bubblegum)
    .compression_program(compression_program_info)
    .leaf_delegate(leaf_delegate_info)
    .leaf_owner(leaf_owner_info)
    .log_wrapper(log_wrapper_info)
    .merkle_tree(merkle_tree_info)
    .payer(payer_info)
    .system_program(system_program_info)
    .tree_config(tree_config_info)
    .metadata(metadata);

// performs the CPI
cpi_mint.invoke_signed(&[&signer_seeds])
```

> **Note** > `*Builder` provide a simplified way to create the required structs, since they take advantage of any default value set on the Kinobi config and do not require to set a `None` value to optional fields.

## PDA helpers

Account types (e.g., `TreeConfig`) have associated functions to find PDA or to create PDA `TreeConfig`s:

```rust
impl TreeConfig {
    pub fn create_pda(
        merkle_tree: Pubkey,
        bump: u8,
    ) -> Result<solana_program::pubkey::Pubkey, solana_program::pubkey::PubkeyError> {
        solana_program::pubkey::Pubkey::create_program_address(
            &[merkle_tree.as_ref(), &[bump]],
            &crate::MPL_BUBBLEGUM_ID,
        )
    }

    pub fn find_pda(merkle_tree: &Pubkey) -> (solana_program::pubkey::Pubkey, u8) {
        solana_program::pubkey::Pubkey::find_program_address(
            &[merkle_tree.as_ref()],
            &crate::MPL_BUBBLEGUM_ID,
        )
    }
}
```

> If a bump seed is known, it is _cheaper_ (in terms of compute units) to use the `create_pda` function, in particular for on-chain code.

## Testing

To run the SDK tests, run the following from the root directory of the repository:

```bash
pnpm install
```

and then:

```bash
pnpm clients:rust:test
```

## Documentation

The crate documentation can be found [here](https://docs.rs/mpl-bubblegum/latest/mpl_bubblegum/).