How to Mint Compressed Tokens

Complete guide to mint compressed tokens with `mintTo()`, troubleshooting, and advanced configurations.

The mintTo() function creates compressed token accounts for recipients and increases the mint's token supply. Only the mint authority can perform this operation.

The mintTo() function

  1. Mints SPL tokens to token pool PDA, the for compression and decompression of tokens

  2. Create compressed accounts containing mint, owner, and amount for each recipient

Before minting compressed tokens, you need an SPL mint registered with the compressed token program via createMint() for a new mint, or createTokenPool() for an existing mint.

function-mint-compressed-tokens.ts
import { mintTo } from '@lightprotocol/compressed-token';
import { PublicKey } from '@solana/web3.js';

// Use existing mint with token pool for compression to mint compressed tokens
const mint = new PublicKey("MINT_ADDRESS");
const recipient = new PublicKey("RECIPIENT_WALLET_ADDRESS");
const amount = 1_000_000_000; // 1 token (9 decimals)

// Mint compressed tokens - mints SPL tokens to pool, creates compressed token accounts
const transactionSignature = await mintTo(
    rpc,
    payer,
    mint, // SPL mint with token pool for compression
    recipient, // recipient address (toPubkey parameter)
    payer, // mint authority
    amount,
);

Full Code Example

1

Prerequisites

Make sure you have dependencies and developer environment set up!

Prerequisites & Setup

Dependencies

npm install --save-dev typescript tsx @types/node && \
npm install --save \
    @lightprotocol/stateless.js \
    @lightprotocol/compressed-token \
    @solana/web3.js \
    @solana/spl-token

Alternatives:

yarn add --dev typescript tsx @types/node && \
yarn add \
    @lightprotocol/stateless.js \
    @lightprotocol/compressed-token \
    @solana/web3.js \
    @solana/spl-token
pnpm add --save-dev typescript tsx @types/node && \
pnpm add \
    @lightprotocol/stateless.js \
    @lightprotocol/compressed-token \
    @solana/web3.js \
    @solana/spl-token

Developer Environment

By default, this guide uses Localnet.

# Install the development CLI
npm install @lightprotocol/zk-compression-cli
# Start a local test validator
light test-validator

## ensure you have the Solana CLI accessible in your system PATH 
// createRpc() defaults to local test validator endpoints
import {
  Rpc,
  createRpc,
} from "@lightprotocol/stateless.js";

const connection: Rpc = createRpc();

async function main() {
  let slot = await connection.getSlot();
  console.log(slot);

  let health = await connection.getIndexerHealth(slot);
  console.log(health);
  // "Ok"
}

main();

Alternative: Using Devnet

Follow these steps to create an RPC Connection. Replace <your_api_key> with your API key before running.

Get your API Key here, if you don't have one yet.

import { createRpc } from "@lightprotocol/stateless.js";

// Helius exposes Solana and Photon RPC endpoints through a single URL
const RPC_ENDPOINT = "https://devnet.helius-rpc.com?api-key=<your_api_key>";
const connection = createRpc(RPC_ENDPOINT, RPC_ENDPOINT, RPC_ENDPOINT);

console.log("Connection created!");
console.log("RPC Endpoint:", RPC_ENDPOINT);
2

Minting Compressed Tokens

Run this script to mint compressed tokens to a recipient!

mint-compressed-tokens.ts
// 1. Setup funded payer and connect to local validator
// 2. Create SPL mint with token pool for compression
// 3. Call mintTo() with mint, recipient, and amount - mint SPL tokens to pool and create compressed token accounts
// 4. Verify via getCompressedTokenAccountsByOwner

import { Keypair, PublicKey } from '@solana/web3.js';
import { createRpc } from '@lightprotocol/stateless.js';
import { createMint, mintTo } from '@lightprotocol/compressed-token';

async function mintCompressedTokens() {
    // Step 1: Setup funded payer and connect to local validator
    const rpc = createRpc(); // defaults to localhost:8899
    const payer = Keypair.generate();
    const airdropSignature = await rpc.requestAirdrop(payer.publicKey, 1000000000); // 1 SOL
    await rpc.confirmTransaction(airdropSignature);

    // Step 2: Create SPL mint with token pool for compression
    const { mint, transactionSignature: mintCreateTx } = await createMint(
        rpc,
        payer,
        payer.publicKey, // mint authority
        9
    );

    console.log("Mint with token pool for compression created!");
    console.log("Mint address:", mint.toBase58());
    console.log("Create mint transaction:", mintCreateTx);
    
    // Generate recipient keypair
    const recipient = Keypair.generate();
    
    // Define amount to mint
    const mintAmount = 1_000_000_000; // 1 token with 9 decimals

    // Step 3: Call mintTo() with mint, recipient, and amount
    // Mint SPL tokens to pool and create compressed token account
    const transactionSignature = await mintTo(
        rpc,
        payer,
        mint, // SPL mint with token pool for compression
        recipient.publicKey,
        payer, // mint authority
        mintAmount
    );

    console.log("\nCompressed token minted!");
    console.log("Recipient:", recipient.publicKey.toBase58());
    console.log("Compressed Token Balance:", mintAmount / 1_000_000_000, "tokens");
    console.log("Mint token transaction:", transactionSignature);

    // Step 4: Verify via getCompressedTokenAccountsByOwner
    const tokenAccounts = await rpc.getCompressedTokenAccountsByOwner(
        recipient.publicKey,
        { mint }
    );

    if (tokenAccounts.items.length > 0) {
        const balance = tokenAccounts.items[0].parsed.amount;    }

    return { transactionSignature, recipient: recipient.publicKey, amount: mintAmount };
}

mintCompressedTokens().catch(console.error);
3

Success!

You've successfully minted compressed tokens. The output shows:

  • Compressed token supply: Increased the total supply of your mint

  • Compressed token balance

Troubleshooting

"TokenPool not found"
// Error message: "TokenPool not found. Please create a compressed token
// pool for mint: [ADDRESS] via createTokenPool().

The mint does no have a token pool for compression. Ensure you created the mint using createMint.

// Create mint with token pool for compression
import { createMint } from '@lightprotocol/compressed-token';
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
"TokenPool mint does not match the provided mint"

The token pool info doesn't correspond to the mint address. Ensure you're fetching the correct pool:

// Get the correct token pool for your mint
const tokenPoolInfo = await getTokenPoolInfos(rpc, mint);
"Amount and toPubkey arrays must have the same length"

When minting to multiple recipients, ensure arrays are the same size.

// Wrong: Mismatched array lengths
const recipients = [addr1, addr2, addr3];
const amounts = [100, 200]; // Only 2 amounts for 3 recipients

// Correct: Same length arrays
const recipients = [addr1, addr2, addr3];
const amounts = [100, 200, 300]; // 3 amounts for 3 recipients

Advanced Configuration

Mint to Multiple Recipients
// Mint different amounts to multiple recipients
const recipients = [
    Keypair.generate().publicKey,
    Keypair.generate().publicKey,
    Keypair.generate().publicKey,
];

const amounts = [
    1_000_000_000, // 1 token
    2_000_000_000, // 2 tokens  
    500_000_000,   // 0.5 tokens
];

const transactionSignature = await mintTo(
    rpc,
    payer,
    mint, // SPL mint with token pool for compression
    recipients, // array of recipients (toPubkey parameter)
    payer, // mint authority
    amounts, // array of amounts (amount parameter)
);
With Custom Mint Authority

Mint tokens using a custom mint authority with approveAndMintTo():

import { approveAndMintTo } from '@lightprotocol/compressed-token';

// Mint tokens with a separate mint authority
const transactionSignature = await approveAndMintTo(
    rpc,
    payer, 
    mint, // SPL mint with token pool for compression
    recipient.publicKey, // recipient of minted tokens (toPubkey parameter)
    mintAuthority, // mint authority
    mintAmount,
);

Next Steps

Learn how to transfer compressed tokens you just minted.

How to Transfer Compressed Token

Last updated