MplBubblegum

Hex.pmHex DocsLicense

A comprehensive Elixir library for working with compressed NFTs (cNFTs) on Solana using the Metaplex Bubblegum protocol.

Overview

Compressed NFTs (cNFTs) offer significant cost savings over traditional NFTs by leveraging Solana's state compression feature. MplBubblegum provides a simple API to:

This library provides Elixir bindings to the Solana programs needed for working with compressed NFTs, with most of the heavy lifting implemented in Rust using NIFs for maximum performance.

Installation

  1. Add mpl_bubblegum_exs to your list of dependencies in mix.exs:
def deps do
  [
    {:mpl_bubblegum_exs, "~> 0.1.0"}
  ]
end
  1. Ensure you have Rust installed on your system for compiling the NIFs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  1. Install the hex package:
mix deps.get

Requirements

Quick Start

Setting up a Connection

Before using any functionality, establish a connection to a Solana RPC endpoint:

# Initialize with your wallet's secret key and Helius RPC URL
secret_key = "your_wallet_private_key" 
rpc_url = "https://your-helius-rpc-endpoint.helius.xyz/..."

MplBubblegum.create_connection(secret_key, rpc_url)

IMPORTANT: You must use a Helius RPC URL that supports the Digital Asset Standard (DAS) API for compressed NFT operations. Standard Solana RPC endpoints will not work.

Creating a Merkle Tree

Create a tree to store your compressed NFTs:

# Create a new Merkle tree for storing cNFTs
merkle_tree_address = MplBubblegum.create_tree_config()

# The returned address can now be used for minting

Minting a Compressed NFT

Mint a new compressed NFT into your Merkle tree:

# Mint a compressed NFT
signature = MplBubblegum.mint_v1(
  merkle_tree_address,  # The Merkle tree address from create_tree_config
  "My Awesome NFT",     # NFT name
  "MANFT",              # Symbol
  "https://arweave.net/your-metadata-json-uri",  # Metadata URI
  "your_wallet_address",  # Creator address
  "100"                   # 100% royalty to creator
)

# The signature can be used to view the transaction on Solana Explorer
# https://explorer.solana.com/tx/<signature>

Transferring a Compressed NFT

Transfer a compressed NFT to another wallet:

# Transfer the NFT to another wallet
recipient = "recipient_wallet_address"  # The recipient&#39;s wallet address
asset_id = "compressed_nft_asset_id"    # The asset ID of the NFT to transfer

signature = MplBubblegum.transfer(asset_id, recipient)

Advanced Usage

For more complex operations, you can use the module-specific functions:

Connection Management

alias MplBubblegum.Connection

# Create a connection
Connection.create_connection(secret_key, rpc_url)

# Get the stored secret key
key = Connection.get_secret_key()

# Get the stored RPC URL
url = Connection.get_rpc_url()

Tree Operations

alias MplBubblegum.Tree

# Create a Merkle tree with default parameters
tree_address = Tree.create_tree_config()

Minting Operations

alias MplBubblegum.Mint

# Mint a compressed NFT 
signature = Mint.mint_v1(
  merkle_tree,
  name,
  symbol, 
  uri,
  creator_address,
  royalty_share
)

Transfer Operations

alias MplBubblegum.Transfer

# Transfer a compressed NFT to a new owner
signature = Transfer.transfer(asset_id, recipient_address)

RPC Operations

alias MplBubblegum.RPC

# Send a transaction
{:ok, signature} = RPC.send_transaction(serialized_transaction)

# Get asset data
{:ok, asset_data} = RPC.get_asset_data(asset_id) 

# Get asset proof
{:ok, proof_data} = RPC.get_asset_proof(asset_id)

Cost Comparison: Traditional NFTs vs. Compressed NFTs

Operation Traditional NFT Compressed NFT Savings
One-time setup 0 SOL ~0.01 SOL -0.01 SOL
Mint cost (per NFT) ~0.01 SOL ~0.000005 SOL 99.95%
Storage cost (10K NFTs) ~100 SOL ~0.1 SOL 99.9%

Metadata Structure

When creating NFT metadata for your URI JSON, follow this structure:

{
  "name": "My NFT Name",
  "symbol": "SYMBOL",
  "description": "Description of my NFT",
  "image": "https://arweave.net/image-uri",
  "animation_url": "https://arweave.net/animation-uri",
  "external_url": "https://example.com",
  "attributes": [
    { "trait_type": "Background", "value": "Blue" },
    { "trait_type": "Eyes", "value": "Green" }
  ],
  "properties": {
    "files": [
      {
        "uri": "https://arweave.net/image-uri",
        "type": "image/png"
      }
    ],
    "category": "image",
    "creators": [
      {
        "address": "creator_wallet_address",
        "share": 100
      }
    ]
  }
}

Error Handling

MplBubblegum uses descriptive error messages to help diagnose issues:

try do
  MplBubblegum.mint_v1(merkle_tree, name, symbol, uri, creator, royalty)
rescue
  e in RuntimeError ->
    # Handle the error
    IO.puts("Error: #{e.message}")
end

Development

Building from Source

  1. Clone the repository:
git clone https://github.com/rishavmehra/mpl-bubblegum-ex.git
cd mpl-bubblegum-ex
  1. Install dependencies:
mix deps.get
  1. Compile the project:
mix compile

Running Tests

mix test

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgements