getProgramAccounts

Explore getProgramAccounts: Use Cases, Code Examples, Parameters, Response Format, and Expert Tips

The getProgramAccounts RPC method lets you fetch all on‐chain accounts owned by a given program—essential for any application that needs to discover or monitor program‑specific state. Since a program can own thousands of accounts, this method offers powerful filtering to narrow your results and optimize performance.


🔍 Common Use Cases

  • Token Holders Discovery Find every SPL token account for a specific mint to list all token holders.

  • User‑Specific Data Retrieval Fetch all accounts created by a program for a user (e.g., a DeFi position, game state).

  • Custom Account Indexing Locate all instances of a bespoke account type defined by your program.

  • Program State Monitoring Track every account under a program to observe its overall activity and health.

  • Explorer & Analytics Tooling Aggregate and analyze program data for dashboards or block explorers.


🛠 Request Parameters

{
  "programId": "<base58ProgramPubkey>",  // Required
  "options": {                           // Optional
    "commitment": "processed|confirmed|finalized",
    "encoding": "base64|base58|base64+zstd|jsonParsed",
    "filters": [
      { "dataSize": <u64> },
      { "memcmp": { "offset": <usize>, "bytes": "<base58Bytes>" } }
      // up to 4 total filters
    ],
    "dataSlice": { "offset": <usize>, "length": <usize> },
    "withContext": true|false,
    "minContextSlot": <u64>
  }
}
  • programId: Base‑58 public key of the on‑chain program (e.g., "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").

  • commitment: Desired confirmation level.

  • encoding:

    • base64 (default)

    • base58

    • base64+zstd

    • jsonParsed (highly recommended for supported programs)

  • filters (max 4):

    • dataSize: Match accounts by byte length.

    • memcmp: Compare a slice of account data at offset with bytes.

  • dataSlice: Return only a byte range—ideal for large accounts.

  • withContext: Wrap results in an object with context (slot) and value (accounts) when true.

  • minContextSlot: Ensure data is at least as recent as this slot.


📦 Response Structure

Returns either a raw array or, if withContext: true, an RPC response object:

[
  {
    "pubkey": "<accountPubkey>",
    "account": {
      "lamports": <u64>,
      "owner": "<programId>",
      "data": ["<encoded>", "<encoding>"] | { /* parsed JSON */ },
      "executable": true|false,
      "rentEpoch": <u64>,
      "space": <u64>  // data length in bytes
    }
  },

]
  • pubkey: Account’s base‑58 public key.

  • account:

    • lamports: Balance in lamports.

    • owner: Program that owns this account.

    • data: Encoded or parsed account data.

    • executable: true if this account is a program.

    • rentEpoch: Next epoch when rent is due.

    • space: Byte length of the data.


💡 Examples

  1. All USDC Token Accounts Filter by dataSize: 165 and memcmp at offset 0 matching the USDC mint key.

  2. Accounts Owned by a Wallet Use dataSize: 165 and memcmp at offset 32 to match the wallet’s public key.


Code Examples

const fetch = require('node-fetch');

async function getProgramAccounts(rpcUrl) {
  try {
    const response = await fetch(rpcUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method: 'getProgramAccounts',
        "params": [
            "4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
            {
              "commitment": "finalized",
              "filters": [
                { "dataSize": 17 },
                {
                  "memcmp": {
                    "offset": 4,
                    "bytes": "3Mc6vR"
                  }
                }
              ]
            }
          ]
      }),
    });

    const data = await response.json();
    
    // Print the exact full response
    console.log('Full RPC Response:');
    console.log(JSON.stringify(data, null, 2));
    
    return data;
  } catch (error) {
    console.error('Error getting health:', error.message);
    return null;
  }
}

// Example usage
const RPC_URL = 'https://rpc.coinvera.io/?x-api-key=your-coinvera-x-api-key';

getProgramAccounts(RPC_URL);

Example Response

{
  "jsonrpc": "2.0",
  "result": [
    {
      "pubkey": "CxELquR1gPP8wHe33gZ4QxqGB3sZ9RSwsJ2KshVewkFY",
      "account": {
        "data": "2R9jLfiAQ9bgdcw6h8s44439",
        "executable": false,
        "lamports": 15298080,
        "owner": "4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
        "rentEpoch": 28,
        "space": 42
      }
    }
  ],
  "id": 1
}

🧠 Developer Tips

  • Always Filter: Without filters, queries can be extremely heavy and may time out.

  • No Pagination: Large result sets aren’t paginated—design filters to keep results manageable.

  • Rate Limits: Heavy usage can hit provider limits (e.g., CoinVera).

  • Know Your Layout: Effective memcmp filters require precise knowledge of account byte structure.

  • Prefer jsonParsed: For SPL Token, Stake, and other common programs, jsonParsed saves manual decoding.


By mastering getProgramAccounts and its filters, you’ll efficiently query and manipulate program‑owned accounts at scale on Solana.

Last updated