Merge Compressed Token Accounts
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.
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 viacreateTokenPool().
State trees where compressed account's are stored, are append only. mergeTokenAccounts() reduces account fragmentation to simplify balance calculations from getCompressedTokenAccountsByOwner.
// Combines multiple compressed token accounts into single compressed account
const transactionSignature = await mergeTokenAccounts(
rpc,
payer,
mint, // SPL mint with token pool for compression
owner,
);Full Code Example
Merging Compressed Accounts
Run this script to merge multiple compressed token accounts into one!
// 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 merge
import { 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);Troubleshooting
Advanced Configuration
Next Steps
Learn how to approve and revoke delegate authority for compressed token accounts.
Approve and Revoke Delegate AuthorityLast updated
Was this helpful?