Use this file to discover all available pages before exploring further.
// Compress SPL tokens to compressed tokensconst compressionSignature = await compress( rpc, payer, mint, // SPL mint with token pool for compression amount, payer, // owner of SPL tokens tokenAccount.address, // source SPL token account (sourceTokenAccount parameter) recipient, // recipient owner address (toAddress parameter));
Function Difference and Best Practice:
compress(amount, sourceTokenAccount, toAddress) compresses specific amounts from source to a specified recipient. Use for transfers and precise amounts.
compressSplTokenAccount(tokenAccount, remainingAmount) compresses the entire SPL token account balance minus optional remaining amount only to the same owner. Use to migrate complete token accounts with optional partial retention. Here is how.
In the code examples, use createRpc(RPC_URL) with the devnet URL.
Before we can compress or decompresss, we need:
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().
For compress() SPL tokens in an Associated Token Account, or
For decompress() compressed token accounts with sufficient balance.
import "dotenv/config";import { Keypair } from "@solana/web3.js";import { createRpc } from "@lightprotocol/stateless.js";import { createMint, mintTo, decompress } from "@lightprotocol/compressed-token";import { createAssociatedTokenAccount } from "@solana/spl-token";import { homedir } from "os";import { readFileSync } from "fs";// devnet:const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;// localnet:// const RPC_URL = undefined;const payer = Keypair.fromSecretKey( new Uint8Array( JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")) ));(async function () { // devnet: const rpc = createRpc(RPC_URL); // localnet: // const rpc = createRpc(); // Setup: Create mint and mint compressed tokens const { mint } = await createMint(rpc, payer, payer.publicKey, 9); await mintTo(rpc, payer, mint, payer.publicKey, payer, 1_000_000_000); const splAta = await createAssociatedTokenAccount(rpc, payer, mint, payer.publicKey); // Decompress to SPL tokens const tx = await decompress(rpc, payer, mint, 500_000_000, payer, splAta); console.log("Mint:", mint.toBase58()); console.log("Tx:", tx);})();
Make sure the SPL mint has a token pool for compression. The script creates this token pool for you.For development, you can create a new mint with token pool via createMint() or add a token pool to an existing mint via createTokenPool().
Insufficient balance between decompress and compress
Check your balances before operations:
// For decompression - check compressed balanceconst compressedAccounts = await rpc.getCompressedTokenAccountsByOwner( owner.publicKey, { mint });const compressedBalance = compressedAccounts.items.reduce( (sum, account) => sum.add(account.parsed.amount), new BN(0));// For compression - check SPL token balanceconst tokenBalance = await rpc.getTokenAccountBalance(tokenAccount);const splBalance = new BN(tokenBalance.value.amount);console.log("Can decompress up to:", compressedBalance.toString());console.log("Can compress up to:", splBalance.toString());
Invalid owner
Ensure the signer owns the tokens being decompressed/compressed:
// The owner parameter must be the actual ownerconst decompressTx = await decompress( rpc, payer, // can be different (pays fees) mint, amount, actualOwner, // must own compressed tokens destinationAta,);const compressTx = await compress( rpc, payer, // can be different (pays fees) mint, amount, actualOwner, // must own SPL tokens sourceAta, recipient,);