Skip to main content
POST
/
getCompressedAccountsByOwner
{
  "context": "<any>",
  "value": "<any>"
}
ThegetCompressedAccountsByOwner RPC method returns all compressed accounts owned by a specific address, with support for filtering, pagination, and data slicing.
You can test this method via the OpenAPI example or custom examples below.
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
  1. owner (PublicKey, required): Base58-encoded public key of the account owner to query compressed accounts for.
  2. options (object, optional): Configuration object for filtering and pagination:
    • filters (array, optional): Array of filter objects to narrow results by specific criteria
    • dataSlice (object, optional): Slice of account data to return with offset and length fields
    • cursor (string, optional): Cursor for pagination from previous response to fetch next page
    • limit (BN, optional): Maximum number of accounts to return (use bn() 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 context
    • hash (string): Unique hash identifying the account for merkle proof generation
    • address (string, optional): Account address if available
    • lamports (number): Account balance in lamports
    • owner (string): Public key of the account owner
    • data (object): Account data information including discriminator and data hash
    • tree (string): Public key of the merkle tree storing this account
    • leafIndex (number): Position of account in the merkle tree
    • seq (number): Sequence number for account ordering
    • slotCreated (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
Owner has no compressed accountsThis is normal for new addresses or those that haven’t used compression:
const accounts = await rpc.getCompressedAccountsByOwner(owner);

if (accounts.items.length === 0) {
    console.log("No compressed accounts found for this owner");
    console.log("Create compressed accounts first using createAccountWithLamports or token operations");
}
Too many accounts returned at onceUse pagination and data slicing to reduce response size:
const accounts = await rpc.getCompressedAccountsByOwner(owner, {
    limit: bn(50),        // Smaller batch size
    dataSlice: {          // Reduce data per account
        offset: 0,
        length: 10
    }
});
Examples The below examples work - just make sure you installed the dependencies.
npm install @lightprotocol/stateless.js @solana/web3.js
For Rust examples: Requires light-client, solana-sdk, anyhow, and tokio crates. See Rust example comments for setup details.
Example: Get All Compressed Accounts
  • TypeScript
  • cURL
  • Rust
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
TypeScript
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();

Body

application/json
id
enum<string>
required

An ID to identify the request.

Available options:
test-account
jsonrpc
enum<string>
required

The version of the JSON-RPC protocol.

Available options:
2.0
method
enum<string>
required

The name of the method to invoke.

Available options:
getCompressedAccountsByOwner
params
object
required

Response

context
any
required
value
any
required