getCompressedTokenAccountsByOwner
Retrieve compressed token accounts owned by a specific address. RPC method guide with use cases, tips and examples.
ThegetCompressedTokenAccountsByOwner
RPC method retrieves all compressed token accounts owned by a specific public key. The method supports mint filtering to query specific tokens, cursor-based pagination for handling large result sets, and returns parsed token data with merkle context for verification.
An ID to identify the request.
The version of the JSON-RPC protocol.
The name of the method to invoke.
Invalid request.
Unauthorized request.
Request was forbidden.
The specified resource was not found.
Exceeded rate limit.
The server encountered an unexpected condition that prevented it from fulfilling the request.
POST / HTTP/1.1
Host: mainnet.helius-rpc.com
Content-Type: application/json
Accept: */*
Content-Length: 233
{
"id": "test-account",
"jsonrpc": "2.0",
"method": "getCompressedTokenAccountsByOwner",
"params": {
"cursor": "3J98t1WpEZ73CNm",
"limit": 1,
"mint": "11111113pNDtm61yGF8j2ycAwLEPsuWQXobye5qDR",
"owner": "11111113pNDtm61yGF8j2ycAwLEPsuWQXobye5qDR"
}
}
{
"context": {
"slot": 100
},
"value": null
}
Common Use Cases
Token Portfolio Display: Show all compressed tokens owned by a wallet address
Balance Aggregation: Calculate total token holdings across multiple compressed accounts
Token Transfer Setup: Find available token accounts to use as transfer sources
Wallet Integration: Support compressed token discovery in wallet interfaces
DeFi Protocol Integration: Query user token holdings for lending, trading, or staking
Parameters
owner
(PublicKey, required): Base58-encoded public key of the account owner to query token accounts for.options
(object, optional): Configuration object containing filtering and pagination parameters:mint
(PublicKey, optional): Base58-encoded mint address to filter results by specific tokencursor
(string, optional): Pagination cursor from previous response for fetching next pagelimit
(BN, optional): Maximum number of accounts to return (usebn()
helper function)
Note: All parameters are optional within the options object. Without filters, returns all compressed token accounts for the owner.
Response
The response contains a paginated list of compressed token accounts:
items
(array): Array of compressed token account objectscompressedAccount
(object): Compressed account data and merkle proof contextaddress
(string): Compressed account address (if available)owner
(string): Account owner public keylamports
(number): Account lamportsdata
(object): Account data informationhash
(string): Account hash for merkle proof verification
parsed
(object): Parsed token-specific informationmint
(PublicKey): Token mint addressowner
(PublicKey): Token account owneramount
(BN): Token amount as BN object - use .toString() for exact valuedelegate
(PublicKey | null): Delegate address if set, null otherwisestate
(number): Account state (0=initialized, 1=frozen, etc.)tlv
(Buffer | null): Type-Length-Value extension data if present
cursor
(string | null): Pagination cursor for next batch, null if no more results
Developer Tips
BN Object Handling: The
amount
field is a BN object - use.toString()
for exact values or.toNumber()
for small amountsState Values: The
state
field is a numeric enum (0=initialized, 1=frozen, etc.) not a stringParameter Types: Use
bn()
helper function for thelimit
parameter, not raw numbersPagination: Use cursor-based pagination for large token portfolios to avoid timeouts
Performance: Filter by mint address when querying specific tokens to reduce response size
Empty Responses: Handle cases where owners have no compressed token accounts gracefully
Examples
The below examples work - just make sure you installed the dependencies.
Example: Get All Token Accounts
curl -X POST https://devnet.helius-rpc.com?api-key=YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getCompressedTokenAccountsByOwner",
"params": {
"owner": "OWNER_PUBKEY_HERE"
}
}'
Example: Filter by Specific Token Mint
import { createRpc, bn, Rpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const rpc: Rpc = createRpc(
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY',
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY'
);
async function getTokenAccountsByMint(): Promise<void> {
const owner = new PublicKey('OWNER_ADDRESS_HERE');
const mint = new PublicKey('TOKEN_MINT_HERE');
const result = await rpc.getCompressedTokenAccountsByOwner(owner, {
mint
});
if (result.items.length === 0) {
console.log('No compressed token accounts found for this mint');
return;
}
let totalBalance = bn(0);
result.items.forEach((account, index) => {
const amount = account.parsed.amount;
totalBalance = totalBalance.add(amount);
console.log(`Account ${index + 1}:`);
console.log(` Amount: ${amount.toString()}`);
console.log(` Hash: ${account.compressedAccount.hash}`);
});
console.log(`Total Balance: ${totalBalance.toString()}`);
return result;
}
getTokenAccountsByMint();
Example: Paginated Token Discovery
import { createRpc, bn, Rpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const rpc: Rpc = createRpc(
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY',
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY'
);
async function getAllTokenAccountsPaginated(owner: PublicKey) {
let allAccounts = [];
let cursor = undefined;
const batchSize = 50; // Smaller batch size for DevNet
do {
const batch = await rpc.getCompressedTokenAccountsByOwner(owner, {
cursor,
limit: bn(batchSize)
});
allAccounts.push(...batch.items);
cursor = batch.cursor;
console.log(`Fetched ${batch.items.length} token accounts, total: ${allAccounts.length}`);
// Rate limiting for DevNet
await new Promise(resolve => setTimeout(resolve, 100));
} while (cursor);
// Group by mint
const accountsByMint = new Map();
allAccounts.forEach(account => {
const mintKey = account.parsed.mint.toBase58();
if (!accountsByMint.has(mintKey)) {
accountsByMint.set(mintKey, []);
}
accountsByMint.get(mintKey).push(account);
});
console.log(`Total compressed token accounts: ${allAccounts.length}`);
console.log(`Unique token mints: ${accountsByMint.size}`);
return { allAccounts, accountsByMint };
}
// Usage
const owner = new PublicKey('OWNER_ADDRESS_HERE');
getAllTokenAccountsPaginated(owner);
Example: Calculate Token Portfolio Value
import { createRpc, bn, Rpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const rpc: Rpc = createRpc(
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY',
'https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY'
);
async function calculateTokenPortfolio(): Promise<Map<string, any>> {
const owner = new PublicKey('OWNER_ADDRESS_HERE');
const tokenAccounts = await rpc.getCompressedTokenAccountsByOwner(owner);
if (tokenAccounts.items.length === 0) {
console.log('No compressed token accounts found');
return;
}
const portfolio = new Map();
tokenAccounts.items.forEach(account => {
const mintKey = account.parsed.mint.toBase58();
const amount = account.parsed.amount;
if (portfolio.has(mintKey)) {
const existing = portfolio.get(mintKey);
portfolio.set(mintKey, existing.add(amount));
} else {
portfolio.set(mintKey, amount);
}
});
console.log('Compressed Token Portfolio:');
portfolio.forEach((balance, mint) => {
console.log(` ${mint}: ${balance.toString()}`);
});
return portfolio;
}
calculateTokenPortfolio();
Last updated