For AI agents: the documentation index is at /llms.txt. Markdown versions of pages are available by appending .md to the URL.
Skip to main content

Solana Configuration File

A Solana indexer is defined by a config.yaml with ecosystem: svm. It tells HyperIndex which chain to read, which programs and instructions to match, and how to decode them. This page is the field-by-field reference; for the meaning of discriminators, IDLs and argument types see Decoding & IDLs.

Add this line at the top of the file for editor autocompletion and validation:

# yaml-language-server: $schema=./node_modules/envio/svm.schema.json

A complete example

config.yaml
# yaml-language-server: $schema=./node_modules/envio/svm.schema.json
name: my-solana-indexer
description: Index Jupiter swaps and Metaplex NFT mints
ecosystem: svm
chains:
- rpc: https://api.mainnet-beta.solana.com
hypersync_config:
url: https://solana.hypersync.xyz # optional; this is the default
start_block: 417995000 # a SLOT number, not a block
programs_experimental:
# --- decoded from an Anchor IDL ---
- name: Jupiter
program_id: JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4
idl: idls/jupiter.json
instructions:
- name: sharedAccountsRoute
discriminator: "0xc1209b3341d69c81"
field_selection:
token_balance_fields: true
# --- decoded from an inline schema (no IDL) ---
- name: Raydium
program_id: 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
instructions:
- name: swap
discriminator: "0x09"
args:
- { name: amountIn, type: u64 }
- { name: minAmountOut, type: u64 }
accounts:
- tokenProgram
- amm
- userSourceTokenAccount
- userDestTokenAccount
field_selection:
token_balance_fields: true

Top-level fields

FieldRequiredDefaultNotes
nameProject name.
ecosystemMust be svm.
chainsOne or more chains to index (see below).
descriptionFree-text description.
schemaschema.graphqlPath to your GraphQL schema.
full_batch_size5000Batch size for processing.
storagepostgres: trueStorage backends (postgres, clickhouse).
No EVM-style global fields

For Solana, several EVM top-level fields don't apply: contracts, rollback_on_reorg, save_full_history, raw_events, a global field_selection, and address_format. Reorg-related options are fixed off (Solana indexes finalized data). Field selection is per-instruction only (see field selection).

chains

Each entry is one Solana cluster.

FieldRequiredDefaultNotes
rpcRPC URL. Used by slot handlers and the Effect API.
start_blockThe slot to start indexing from.
hypersync_config.urlhttps://solana.hypersync.xyzThe HyperSync endpoint that serves historical instructions.
end_blockStop at this slot (inclusive of the range processed). Useful for finite backfills and tests.
block_lagStay this many slots behind the head.
skipfalseSkip this chain.
programs_experimentalPrograms to index (see below).
EVM difference: no chain id

EVM chains require an id (the public chain ID). Solana chains have no id — the cluster is identified by the rpc / hypersync_config you point at. Inside handlers the Solana chain id is 0.

programs_experimental

The list of Solana programs to index on this chain. The YAML key is programs_experimental to signal that this shape is still evolving.

FieldRequiredDefaultNotes
nameA unique name you choose. Used in handlers (onInstruction({ program: "<name>" })) and generated types.
program_idThe base58 program address.
instructionsInstructions to match within this program (see below).
idlPath to an Anchor IDL JSON. If set, HyperIndex derives each instruction's args + accounts from it. Mutually exclusive with per-instruction inline args/accounts.
handlerautoPath to the file that registers this program's handlers. By default handler files are auto-loaded.

instructions

Each entry selects one instruction of the program to index. Only name is required, but in practice you'll add a discriminator so HyperIndex can tell your instruction apart from the program's others.

FieldRequiredDefaultNotes
nameThe instruction name. For Anchor IDL programs this should match the IDL instruction (the snake_cased name is used to derive the default discriminator). Also the key in onInstruction({ instruction: "<name>" }).
discriminatorHex bytes that identify the instruction (e.g. "0xc1209b3341d69c81"). See discriminators. Without it, the instruction matches purely on program + filters and isn't decoded by discriminator.
is_innerunsettrue = inner (CPI) only, false = top-level only, omitted = matches both.
argsInline argument schema (Borsh), { name, type } per arg. Requires accounts too. Mutually exclusive with the program's idl. See supported types.
accountsInline ordered list of account names. The Nth name labels the Nth account. Requires args too.
account_filtersRestrict matches by the pubkey in specific account positions (see below).
field_selectionOpt into extra data on the event (see below).

Field selection

By default a handler receives only the instruction itself. Opt into more data per instruction:

ToggleAdds to the event
transaction_fields: trueevent.transaction — signatures, fee payer, fee, compute units, success, account keys.
token_balance_fields: trueevent.transaction.tokenBalances — pre/post SPL Token balances. Implies transaction_fields.
log_fields: trueevent.logs — program logs scoped to this instruction.
field_selection:
token_balance_fields: true # also gives you transaction fields
log_fields: true
true only, for now

Each toggle currently accepts true (all fields) only. Per-field name lists are not yet supported.

Account filters

Match an instruction only when specific account positions hold specific pubkeys — useful to index, say, only swaps that touch a particular pool or mint. Positions are 05; within a position values are OR-ed, and across positions they are AND-ed.

instructions:
- name: swap
discriminator: "0x09"
account_filters:
- position: 1
values:
- 58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2 # only this pool

Use any_of to OR several AND-groups together:

    account_filters:
any_of:
- [ { position: 0, values: [So11111111111111111111111111111111111111112] } ]
- [ { position: 1, values: [EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v] } ]

Choosing what to index

Solana's highest-frequency programs (SPL Token, System) produce enormous volumes of instructions. Matching them directly can swamp a backfill. Two practical patterns:

  • Index DeFi/protocol instructions and read value flow from token balances. Enabling token_balance_fields on a protocol instruction gives you the transaction's net token movements without indexing every Transfer.
  • Scope high-volume instructions with account_filters or a tight slot window (start_block/end_block) when you do need them.