Complete guide to merge multiple compressed token accounts into a single account with mergeTokenAccounts(), troubleshooting and advanced configurations.
The mergeTokenAccounts() function consolidates multiple compressed accounts of the same mint into a single compressed account.The function
consumes multiple compressed token accounts (up to 8 accounts), and
creates a single output compressed token account with combined balance for the owner.
State trees where compressed account’s are stored, are append only. mergeTokenAccounts() reduces account fragmentation to simplify balance calculations from getCompressedTokenAccountsByOwner.
Report incorrect code
Copy
Ask AI
// Combines multiple compressed token accounts into single compressed accountconst transactionSignature = await mergeTokenAccounts( rpc, payer, mint, // SPL mint with token pool for compression owner,);
# Start a local test validatorlight test-validator## ensure you have the Solana CLI accessible in your system PATH
Report incorrect code
Copy
Ask AI
// createRpc() defaults to local test validator endpointsimport { 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();
Replace <your-api-key> with your actual API key. Get your API key here, if you don’t have one yet.
Report incorrect code
Copy
Ask AI
import { createRpc } from "@lightprotocol/stateless.js";// Helius exposes Solana and Photon RPC endpoints through a single URLconst 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);
Run this script to merge multiple compressed token accounts into one!
merge-compressed-accounts.ts
Report incorrect code
Copy
Ask AI
// 1: Setup funded payer and connect to local validator// 2. Create mint and multiple compressed accounts// 3. Call mergeTokenAccounts() to consolidate multiple compressed accounts to one output// 4. Use getCompressedTokenAccountsByOwner() to query account states before and after mergeimport { Keypair, PublicKey } from '@solana/web3.js';import { createRpc } from '@lightprotocol/stateless.js';import { createMint, mintTo, mergeTokenAccounts} from '@lightprotocol/compressed-token';async function mergeCompressedAccounts() { // 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 } = await createMint(rpc, payer, payer.publicKey, 9); console.log("SPL Mint with token pool created:", mint.toBase58()); const tokenOwner = Keypair.generate(); const amounts = [300_000_000, 200_000_000, 500_000_000]; // 0.3, 0.2, 0.5 tokens console.log("Creating multiple compressed accounts..."); for (let i = 0; i < amounts.length; i++) { await mintTo( rpc, payer, mint, // SPL mint with token pool for compression tokenOwner.publicKey,// recipient address (toPubkey parameter) payer, // mint authority amounts[i], ); } // Step 2a: Get all compressed accounts before merging const accountsBefore = await rpc.getCompressedTokenAccountsByOwner( tokenOwner.publicKey, { mint } ); console.log("Number of accounts before merge:", accountsBefore.items.length); // Step 2b: Calculate total balance across all compressed accounts const totalBalance = accountsBefore.items.reduce( (sum, account) => sum.add(account.parsed.amount), new (require('bn.js'))(0) ); console.log("Total balance:", totalBalance.toNumber() / 1_000_000_000, "tokens"); accountsBefore.items.forEach((account, index) => { console.log(`Account ${index + 1}:`, account.parsed.amount.toNumber() / 1_000_000_000, "tokens"); }); // Step 3: Call mergeTokenAccounts() to consolidate into single account // Nullify old compressed accounts and create one with combined balance const mergeTx = await mergeTokenAccounts( rpc, payer, mint, // SPL mint with token pool for compression tokenOwner, ); console.log("\nMerge Compressed Accounts..."); console.log("Transaction:", mergeTx); // Step 4: Verify merge results - check single compressed account contains total balance const accountsAfter = await rpc.getCompressedTokenAccountsByOwner( tokenOwner.publicKey, { mint } ); console.log("Number of accounts after merge:", accountsAfter.items.length); if (accountsAfter.items.length > 0) { const mergedBalance = accountsAfter.items[0].parsed.amount; console.log("Merged account balance:", mergedBalance.toNumber() / 1_000_000_000, "tokens"); } return { mint, tokenOwner, mergeTransaction: mergeTx, accountsBefore: accountsBefore.items.length, accountsAfter: accountsAfter.items.length };}mergeCompressedAccounts().catch(console.error);
Before we merge compressed accounts, we need
Multiple compressed token accounts of the same mint owned by the same wallet, and
an SPL mint with a token pool for compression. This token pool can be created for new SPL mints via createMint() or added to existing SPL mints via createTokenPool().