Documentation Index Fetch the complete documentation index at: https://luminouslabs-cc5545c6-indexing-tokens.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
compressSplTokenAccount()
partialCompression()
// Compress entire SPL token account balance
const transactionSignature = await compressSplTokenAccount (
rpc ,
payer ,
mint , // SPL mint with token pool for compression
owner ,
tokenAccount , // SPL token account to compress
);
After compression, empty token accounts can now be closed to reclaim rent with closeAccount() .
Function Difference and Best Practice:
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.
compress(amount, sourceTokenAccount, toAddress) compresses specific amounts from source to a specified recipient. Use for transfers and precise amounts. Here is how .
Get Started
Compress SPL Token Accounts
Install packages in your working directory: npm install @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: npm install -g @lightprotocol/zk-compression-cli@beta
Install packages in your working directory: yarn add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: yarn global add @lightprotocol/zk-compression-cli@beta
Install packages in your working directory: pnpm add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Install the CLI globally: pnpm add -g @lightprotocol/zk-compression-cli@beta
# start local test-validator in a separate terminal
light test-validator
In the code examples, use createRpc() without arguments for localnet.
Get an API key from Helius and add to .env: API_KEY =< your-helius-api-key >
In the code examples, use createRpc(RPC_URL) with the devnet URL.
import "dotenv/config" ;
import { Keypair } from "@solana/web3.js" ;
import { createRpc , bn } from "@lightprotocol/stateless.js" ;
import { createMint , compressSplTokenAccount } from "@lightprotocol/compressed-token" ;
import { createAssociatedTokenAccount , mintTo , TOKEN_PROGRAM_ID } 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 SPL token account with tokens
const { mint } = await createMint ( rpc , payer , payer . publicKey , 9 );
const owner = Keypair . generate ();
const tokenAccount = await createAssociatedTokenAccount (
rpc ,
payer ,
mint ,
owner . publicKey ,
undefined ,
TOKEN_PROGRAM_ID
);
await mintTo ( rpc , payer , mint , tokenAccount , payer , bn ( 1_000_000_000 ). toNumber ());
// Compress entire SPL token account balance
const tx = await compressSplTokenAccount (
rpc ,
payer ,
mint ,
owner ,
tokenAccount
);
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() .
Troubleshooting
Insufficient balance in token account
The token account doesn’t have enough tokens for the operation. // Check token account balance before compression
const balance = await rpc . getTokenAccountBalance ( tokenAccount );
if ( Number ( balance . value . amount ) === 0 ) {
console . log ( "Token account is empty" );
return ;
}
console . log ( "Available balance:" , Number ( balance . value . amount ));
// Proceed with compression
const compressTx = await compressSplTokenAccount (
rpc ,
payer ,
mint ,
owner ,
tokenAccount ,
);
Remaining amount exceeds balance
The remainingAmount parameter exceeds the current account balance. const balance = await rpc . getTokenAccountBalance ( tokenAccount );
const availableAmount = Number ( balance . value . amount );
const remainingAmount = bn ( 500_000_000 ); // 0.5 tokens
if ( remainingAmount . gt ( bn ( availableAmount ))) {
console . log ( `Cannot leave ${ remainingAmount . toString () } tokens` );
console . log ( `Available balance: ${ availableAmount } ` );
throw new Error ( "Remaining amount exceeds balance" );
}
// Use valid remaining amount
const compressTx = await compressSplTokenAccount (
rpc ,
payer ,
mint ,
owner ,
tokenAccount ,
remainingAmount , // must be <= balance
);
Advanced Configuration
Partial Account Compression
Compress most tokens while leaving some in SPL format: import { bn } from '@lightprotocol/stateless.js' ;
// Leave 100 tokens (0.1 with 9 decimals) in SPL account
const remainingAmount = bn ( 100_000_000 );
const compressTx = await compressSplTokenAccount (
rpc ,
payer ,
mint ,
owner ,
tokenAccount ,
remainingAmount , // amount to keep in SPL format
);
// Account will retain remainingAmount tokens
Compress Multiple Accounts
Compress several token accounts for the same mint: const tokenAccounts = [
{ account: new PublicKey ( "ACCOUNT_1" ), owner: owner1 },
{ account: new PublicKey ( "ACCOUNT_2" ), owner: owner2 },
{ account: new PublicKey ( "ACCOUNT_3" ), owner: owner3 },
];
// Compress each account
for ( const { account , owner } of tokenAccounts ) {
console . log ( `Compressing account: ${ account . toBase58 () } ` );
try {
const compressTx = await compressSplTokenAccount (
rpc ,
payer ,
mint ,
owner ,
account ,
);
console . log ( `Compressed: ${ compressTx } ` );
} catch ( error ) {
console . log ( `Failed: ${ error . message } ` );
}
}
Next Steps
How to Create a Mint Account with Token Pool