Add Compressed Token Support to Your Wallet
The following page describes how to add compressed token support to your wallet application.
Integration Steps
1. Install the SDK
Package Manager
Command
npm
npm install --save \
@lightprotocol/stateless.js \
@lightprotocol/compressed-token \
@solana/web3.js
Yarn
yarn add \
@lightprotocol/stateless.js \
@lightprotocol/compressed-token \
@solana/web3.js
2. Create an RPC Connection
import {
Rpc,
createRpc,
} from "@lightprotocol/stateless.js";
const RPC_ENDPOINT = "https://devnet.helius-rpc.com?api-key=<api_key>";
const connection: Rpc = createRpc(RPC_ENDPOINT)
3. Display Compressed Token Balances
import { Rpc, createRpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const RPC_ENDPOINT = 'https://devnet.helius-rpc.com?api-key=<api_key>';
const connection: Rpc = createRpc(RPC_ENDPOINT);
const publicKey = new PublicKey('CLEuMG7pzJX9xAuKCFzBP154uiG1GaNo4Fq7x6KAcAfG');
(async () => {
// Returns balance for owner per mint
// Can optionally apply filter: {mint, limit, cursor}
const balances =
await connection.getCompressedTokenBalancesByOwnerV2(publicKey);
console.log(balances);
})();
4. Get Compression Signature History By Owner
import { Rpc, createRpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const RPC_ENDPOINT = 'https://devnet.helius-rpc.com?api-key=<api_key>';
const connection: Rpc = createRpc(RPC_ENDPOINT);
const publicKey = new PublicKey('CLEuMG7pzJX9xAuKCFzBP154uiG1GaNo4Fq7x6KAcAfG');
(async () => {
// 1. Fetch signatures for the user
//
// Returns confirmed signatures for compression transactions involving the
// specified account owner
const signatures =
await connection.getCompressionSignaturesForOwner(publicKey);
console.log(signatures);
// 2. Fetch transactions with compression info
//
// Returns pre- and post-compressed token balances grouped by owner
const parsedTransaction =
await connection.getTransactionWithCompressionInfo(signatures[0].signature)
console.log(parsedTransaction)
})();
Full JSON RPC API:
JSON RPC Methods5. Send Compressed Tokens
import {
Rpc,
createRpc,
bn,
dedupeSigner,
sendAndConfirmTx,
buildAndSignTx,
} from "@lightprotocol/stateless.js";
import {
CompressedTokenProgram,
selectMinCompressedTokenAccountsForTransfer,
} from "@lightprotocol/compressed-token";
import { ComputeBudgetProgram, Keypair } from "@solana/web3.js";
// 0. Set these values
const RPC_ENDPOINT = "https://mainnet.helius-rpc.com?api-key=<api_key>";
const mint = <MINT_ADDRESS>;
const payer = <PAYER_KEYPAIR>;
const owner = payer;
const recipient = Keypair.generate();
const amount = bn(1e8);
const connection: Rpc = createRpc(RPC_ENDPOINT);
(async () => {
// 1. Fetch latest token account state
const compressedTokenAccounts =
await connection.getCompressedTokenAccountsByOwner(owner.publicKey, {
mint,
});
// 2. Select accounts to transfer from based on the transfer amount
const [inputAccounts] = selectMinCompressedTokenAccountsForTransfer(
compressedTokenAccounts.items,
amount
);
// 3. Fetch recent validity proof
const proof = await connection.getValidityProof(
inputAccounts.map((account) => account.compressedAccount.hash)
);
// 4. Create transfer instruction
const ix = await CompressedTokenProgram.transfer({
payer: payer.publicKey,
inputCompressedTokenAccounts: inputAccounts,
toAddress: recipient.publicKey,
amount,
recentInputStateRootIndices: proof.rootIndices,
recentValidityProof: proof.compressedProof,
});
// 8. Sign, send, and confirm...
const { blockhash } = await connection.getLatestBlockhash();
const additionalSigners = dedupeSigner(payer, [owner]);
const signedTx = buildAndSignTx(
[ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }), ix],
payer,
blockhash,
additionalSigners
);
return await sendAndConfirmTx(connection, signedTx);
})();
Advanced Integration
Best Practices
Clear UI Indicators — Provide clear visual distinctions between compressed and uncompressed SPL tokens
Transaction History — Provide detailed transaction histories for compressed tokens
Decompression and Compression — Provide a clear path for users to convert between compressed and uncompressed tokens when needed
Support
For additional support or questions, please refer to our documentation or contact Swen or Mert on Telegram or via email.
Last updated