Solana · Arazzo Workflow

Solana Scan a Program's Owned Accounts

Version 1.0.0

Verify an address is an executable program, list the accounts it owns, and batch-read the first of them.

1 workflow 1 source API 1 provider
View Spec View on GitHub BlockchainCryptocurrencyWeb3DeFiTransactionsTokensArazzoWorkflows

Provider

solana

Workflows

program-accounts-scan
Confirm a program address and enumerate the accounts it owns.
Guards on the executable flag before running an expensive program-account scan, then batch-reads the results.
3 steps inputs: programId outputs: batchedAccounts, ownedAccounts, programOwner, scannedAtSlot
1
verifyProgram
getAccountInfo
Read the address and confirm the executable flag is set. Running a program-account scan against a non-program address wastes an expensive call and returns nothing useful.
2
listOwnedAccounts
getProgramAccounts
List every account owned by the program, parsed so the account state is readable without decoding the raw data blob.
3
batchReadAccounts
getMultipleAccounts
Re-read the leading owned accounts in a single batched call, the pattern that keeps an indexer inside its rate limit instead of issuing one request per account.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Solana Scan a Program's Owned Accounts
  summary: Verify an address is an executable program, list the accounts it owns, and batch-read the first of them.
  description: >-
    The discovery path for anyone indexing a Solana program's on-chain state.
    The workflow first reads the supplied address and confirms it is actually an
    executable program rather than a data account, then lists every account
    owned by that program in parsed form, and finally batch-reads the leading
    owned accounts in a single getMultipleAccounts call rather than one request
    per account. getProgramAccounts is one of the heaviest methods on the RPC
    surface and many public endpoints restrict or rate-limit it, which is
    exactly why the executable check comes first. Every step spells out its
    JSON-RPC request inline so the flow can be read and executed without opening
    the underlying OpenAPI description.
  version: 1.0.0
sourceDescriptions:
- name: solanaRpcApi
  url: ../openapi/solana-rpc-api-openapi.yml
  type: openapi
workflows:
- workflowId: program-accounts-scan
  summary: Confirm a program address and enumerate the accounts it owns.
  description: >-
    Guards on the executable flag before running an expensive program-account
    scan, then batch-reads the results.
  inputs:
    type: object
    required:
    - programId
    properties:
      programId:
        type: string
        description: Base58-encoded public key of the program to scan.
  steps:
  - stepId: verifyProgram
    description: >-
      Read the address and confirm the executable flag is set. Running a
      program-account scan against a non-program address wastes an expensive
      call and returns nothing useful.
    operationId: getAccountInfo
    requestBody:
      contentType: application/json
      payload:
        jsonrpc: "2.0"
        id: 1
        method: getAccountInfo
        params:
        - $inputs.programId
        - encoding: base64
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.result.value.executable == true
      type: jsonpath
    outputs:
      executable: $response.body#/result/value/executable
      owner: $response.body#/result/value/owner
      lamports: $response.body#/result/value/lamports
    onFailure:
    - name: abortWhenNotAProgram
      type: end
  - stepId: listOwnedAccounts
    description: >-
      List every account owned by the program, parsed so the account state is
      readable without decoding the raw data blob.
    operationId: getProgramAccounts
    requestBody:
      contentType: application/json
      payload:
        jsonrpc: "2.0"
        id: 1
        method: getProgramAccounts
        params:
        - $inputs.programId
        - encoding: jsonParsed
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.result
      type: jsonpath
    outputs:
      accounts: $response.body#/result
      firstPubkey: $response.body#/result/0/pubkey
      secondPubkey: $response.body#/result/1/pubkey
    onSuccess:
    - name: hasOwnedAccounts
      type: goto
      stepId: batchReadAccounts
      criteria:
      - context: $response.body
        condition: $.result.length > 0
        type: jsonpath
  - stepId: batchReadAccounts
    description: >-
      Re-read the leading owned accounts in a single batched call, the pattern
      that keeps an indexer inside its rate limit instead of issuing one request
      per account.
    operationId: getMultipleAccounts
    requestBody:
      contentType: application/json
      payload:
        jsonrpc: "2.0"
        id: 1
        method: getMultipleAccounts
        params:
        - - $steps.listOwnedAccounts.outputs.firstPubkey
          - $steps.listOwnedAccounts.outputs.secondPubkey
        - encoding: base64
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.result.value
      type: jsonpath
    outputs:
      accounts: $response.body#/result/value
      slot: $response.body#/result/context/slot
      firstAccountLamports: $response.body#/result/value/0/lamports
      firstAccountSpace: $response.body#/result/value/0/space
  outputs:
    programOwner: $steps.verifyProgram.outputs.owner
    ownedAccounts: $steps.listOwnedAccounts.outputs.accounts
    batchedAccounts: $steps.batchReadAccounts.outputs.accounts
    scannedAtSlot: $steps.batchReadAccounts.outputs.slot