getCompressedAccountsByOwner
Retrieve all compressed accounts owned by a specific address. RPC method guide with use cases, tips and examples.
ThegetCompressedAccountsByOwner
RPC method returns all compressed accounts owned by a specific address, with support for filtering, pagination, and data slicing.
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: 162
{
"id": "test-account",
"jsonrpc": "2.0",
"method": "getCompressedAccountsByOwner",
"params": {
"cursor": {},
"limit": 1,
"owner": "11111113pNDtm61yGF8j2ycAwLEPsuWQXobye5qDR"
}
}
{
"context": {
"slot": 100
},
"value": null
}
Common Use Cases
Portfolio Discovery: Find all compressed accounts for a wallet
Token Account Enumeration: Discover user's compressed token holdings
Account Migration: Identify accounts to migrate from regular to compressed
Balance Aggregation: Calculate total holdings across all accounts
Parameters
owner
(PublicKey, required): Base58-encoded public key of the account owner to query compressed accounts for.options
(object, optional): Configuration object for filtering and pagination:filters
(array, optional): Array of filter objects to narrow results by specific criteriadataSlice
(object, optional): Slice of account data to return withoffset
andlength
fieldscursor
(string, optional): Cursor for pagination from previous response to fetch next pagelimit
(BN, optional): Maximum number of accounts to return (usebn()
helper)
Note: All options parameters are optional. Without filters, returns all compressed accounts for the owner.
Response
The response contains a paginated list of compressed accounts:
items
(array): Array of compressed account objects with merkle contexthash
(string): Unique hash identifying the account for merkle proof generationaddress
(string, optional): Account address if availablelamports
(number): Account balance in lamportsowner
(string): Public key of the account ownerdata
(object): Account data information including discriminator and data hashtree
(string): Public key of the merkle tree storing this accountleafIndex
(number): Position of account in the merkle treeseq
(number): Sequence number for account orderingslotCreated
(number): Slot when account was created
cursor
(string | null): Pagination cursor for next batch, null if no more results
Developer Tips
Pagination Strategy: Use cursor-based pagination for owners with many accounts to avoid timeouts and ensure consistent results
Data Slicing Optimization: Implement data slicing when you only need account metadata to reduce response size and improve performance
Empty Response Handling: Handle cases gracefully where new addresses have no compressed accounts - this is normal behavior
Caching Considerations: Cache results appropriately as compressed account states can change with each transaction
Batch Size: Start with smaller batch sizes (50-100) and adjust based on response times and data needs
Troubleshooting
Examples
The below examples work - just make sure you installed the dependencies.
Example: Get All Compressed Accounts
import { createRpc, 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 getAllCompressedAccounts() {
const owner = new PublicKey('OWNER_ADDRESS_HERE');
const result = await rpc.getCompressedAccountsByOwner(owner);
console.log(`Found ${result.items.length} compressed accounts`);
result.items.forEach((account, index) => {
console.log(`Account ${index + 1}:`);
console.log(` Hash: ${account.hash.toString()}`);
console.log(` Lamports: ${account.lamports.toString()}`);
console.log(` Owner: ${account.owner.toBase58()}`);
});
return result;
}
getAllCompressedAccounts();
Example: Paginated Account Discovery with Balance Aggregation
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 getAllAccountsPaginated(owner: PublicKey) {
let allAccounts = [];
let cursor = undefined;
let totalBalance = bn(0);
const batchSize = 100;
do {
const batch = await rpc.getCompressedAccountsByOwner(owner, {
cursor,
limit: bn(batchSize)
});
allAccounts.push(...batch.items);
cursor = batch.cursor;
// Calculate running balance
batch.items.forEach(account => {
totalBalance = totalBalance.add(account.lamports);
});
console.log(`Fetched ${batch.items.length} accounts, total: ${allAccounts.length}`);
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 100));
} while (cursor);
console.log(`Total compressed accounts: ${allAccounts.length}`);
console.log(`Total balance: ${totalBalance.toString()} lamports`);
return { accounts: allAccounts, totalBalance };
}
// Usage
const owner = new PublicKey('OWNER_ADDRESS_HERE');
getAllAccountsPaginated(owner);
Example: Filter by Data Slice
import { createRpc } from '@lightprotocol/stateless.js';
import { PublicKey } from '@solana/web3.js';
const rpc = createRpc("https://devnet.helius-rpc.com?api-key=<your-api-key>");
const owner = new PublicKey("OWNER_PUBKEY_HERE");
async function getAccountsWithDataSlice() {
const accounts = await rpc.getCompressedAccountsByOwner(owner, {
dataSlice: {
offset: 0,
length: 32 // First 32 bytes only
}
});
console.log(`Found ${accounts.items.length} accounts with data slice`);
accounts.items.forEach((account, index) => {
console.log(`Account ${index + 1}:`);
console.log(` Hash: ${account.hash.toString()}`);
console.log(` Data length: ${account.data?.data?.length || 0} bytes`);
});
return accounts;
}
getAccountsWithDataSlice();
Last updated