Getting Started on Solana
This guide takes you from nothing to a running Solana indexer with a live GraphQL API. If you've used HyperIndex on EVM the workflow is identical — only the config and handlers differ.
Prerequisites
- Node.js v20+ and pnpm (or npm/yarn/bun)
- Docker Desktop (for the local Postgres + GraphQL stack)
- A HyperSync API token — the CLI's login flow sets this up for you, or generate one in the Envio Cloud portal. See API tokens.
1. Scaffold a project
pnpx envio init
Choose Solana at the ecosystem prompt, then choose a template:
- Metaplex Token Metadata (instructions) — indexes the Metaplex Token Metadata program's
CreateMetadataAccountV3/UpdateMetadataAccountV2instructions. A realistic instruction-indexing starting point. - Feature: Block Handler (
onSlot) — a minimal slot handler that fetches each block over RPC.
Non-interactive equivalents:
pnpx envio init svm template --template metaplex-token-metadata --name my-indexer
pnpx envio init svm template --template feature-block-handler --name my-indexer
The --language flag is ignored for Solana; projects are always scaffolded in
TypeScript. There is no contract-import flow for Solana — unlike EVM/Fuel you
wire up programs in config.yaml by hand (see Configuration).
The template scaffolds:
my-indexer/
├── config.yaml # chain + program/instruction selection
├── schema.graphql # the entities you index into
├── src/
│ └── handlers/…ts # your onInstruction / onSlot handlers
├── .env # ENVIO_API_TOKEN, RPC URL
└── package.json
envio init also runs codegen, installs dependencies, and initializes git.
2. Pick a start slot
start_block in config.yaml is a slot number, not a block number, and
HyperSync for Solana keeps a rolling window of recent history — so don't hard-code
an old slot. Query the current head and start somewhere sensible below it:
curl -s https://solana.hypersync.xyz/height
# => {"height": 421234567}
Set start_block in config.yaml to, say, a few thousand slots below the head
for a quick backfill, or to the slot your program was deployed at for a full history
(within the retention window).
3. Run it
pnpm install # if you didn't let init do it
pnpm envio codegen # regenerate types from config.yaml + schema.graphql
pnpm envio dev # start Postgres + the indexer + GraphQL (Docker)
envio dev brings up the local stack and runs the indexer with hot reload. The
GraphQL playground (Hasura) is at http://localhost:8080 (default admin
secret testing). See Navigating Hasura.
To run the pieces separately:
pnpm envio local docker up # start Postgres + Hasura
pnpm envio codegen
pnpm envio start # run the indexer against the running stack
Editing config.yaml or schema.graphql — including adding a program,
instruction, or IDL — requires pnpm envio codegen to regenerate the typed
envio module and the entity types in .envio/.
4. Add your own program
Open config.yaml and add a program under programs_experimental with the
instructions you want, then write a handler. The shortest path:
- Point at an Anchor IDL if you have one — HyperIndex derives the argument and account layout for you (IDL decoding).
- Or declare an inline schema (
args+accounts) for programs without an IDL (inline schema). - Add a
discriminatorper instruction so HyperIndex knows which instruction to match (discriminators). - Register a handler with
indexer.onInstruction.
ecosystem: svm
chains:
- rpc: https://api.mainnet-beta.solana.com
start_block: 417995000
programs_experimental:
- name: TokenMetadata
program_id: metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
instructions:
- name: CreateMetadataAccountV3
discriminator: "0x21"
field_selection:
transaction_fields: true
import { indexer, type TokenMetadataAccount } from "envio";
indexer.onInstruction(
{ program: "TokenMetadata", instruction: "CreateMetadataAccountV3" },
async ({ event, context }) => {
const decoded = event.instruction.decoded;
if (!decoded) return; // discriminator matched but decode failed — skip
context.TokenMetadataAccount.set({
id: decoded.accounts.metadata,
mint: decoded.accounts.mint ?? "",
createdAtSlot: event.slot,
lastTxSignature: event.transaction?.signatures[0],
});
},
);
Next steps
- Configuration — every
config.yamlfield for Solana. - Instruction Handlers — the full event object, token balances, CPIs, and testing.
- Decoding & IDLs — discriminators, IDLs, inline schemas, supported types.
- Deploy to Envio Cloud — host your Solana indexer the same way as EVM.