> For the complete documentation index, see [llms.txt](https://docs.envio.dev/llms.txt).

# EVM vs Solana

The HyperIndex workflow is the same on both: define a `config.yaml` and
`schema.graphql`, write handlers, run `codegen`, then `dev`/`start`. What changes
is the unit of work: EVM indexes **events** emitted by **contracts**, Solana
indexes **instructions** executed by **programs**. This page collects every
difference in one place.

## Concept mapping

| EVM | Solana |
| --- | --- |
| Smart contract | Program |
| ABI | IDL (Anchor, Shank, Codama) or a declared layout |
| Event / log | Instruction |
| `indexer.onEvent` | `indexer.onInstruction` |
| `event.params.<name>` | `instruction.args.<name>` |
| Event signature / topic0 | Instruction discriminator |
| Indexed event args | Named account slots, filtered with the handler's `where.accounts` |
| `indexer.onBlock` | `indexer.onSlot` |
| Block number | Slot number |
| Address `0x…` (20 bytes, hex) | Pubkey (32 bytes, base58) |
| Internal calls (not surfaced) | Inner instructions / CPIs (first-class) |
| `bigint` params | `u64`+ args as `bigint`, smaller ints as `number` |

## Config differences

|  | EVM | Solana |
| --- | --- | --- |
| `ecosystem` | `evm` (default) | `svm` |
| What you list | `contracts` (with `abi_file_path`, `address`, `events`) | top-level `programs` (with `program_id`, optional `idl`, `instructions`) |
| Chain identity | `chains[].id` (public chain ID) | `chains[].id` is a cluster label: `solana` (7565164) or `solana-devnet` (7565165) |
| Start of indexing | `start_block` (a block number, or `latest`) | `start_slot` (a **slot** number, or `latest`) |
| Matching key | event signature (from ABI) | `discriminator` (a hex data prefix of any byte length) |
| Decoding source | ABI | an IDL (Anchor, Shank, Codama) or an inline `args` + `accounts` layout |
| Field selection | the handler's `fields` option, or `field_selection` in `config.yaml` | the handler's `fields` option only, with the extra `instruction`, `accountActivity` and `log` knobs |
| Data source config | HyperSync endpoint inferred from `chains[].id` | inferred from `chains[].id` too; set `hypersync_config.url` to pin a specific one |
| Data source | HyperSync or RPC | HyperSync only; `chains[].rpc` is accepted but unused |
| Reorg options | `rollback_on_reorg`, `save_full_history` | none: reorg rollback is always on |

:::note `chains`, not `networks`
Current HyperIndex uses `chains` for both EVM and Solana. (V2 used `networks`
for EVM; if you see that in an old guide, it's the same idea.)
:::

## Handler differences

**EVM:**

```typescript
indexer.onEvent(
  { contract: "ERC20", event: "Transfer" },
  async ({ event, context }) => {
    const from = event.params.from;       // decoded by ABI
    const amount = event.params.value;    // bigint
    const chainId = event.chainId;
    const contract = event.srcAddress;    // 0x… hex
  },
);
```

**Solana:**

```typescript
const fields = {
  instruction: ["args", "accounts", "isInner", "programId"],
  transaction: ["signature"],
} as const;

indexer.onInstruction(
  { program: "Jupiter", instruction: "sharedAccountsRoute", fields },
  async ({ instruction, context }) => {
    const inAmount = instruction.args.inAmount; // bigint, decoded from the u64
    const sourceMint = instruction.accounts.sourceMint.address; // base58
    const programId = instruction.programId; // base58
    const slot = instruction.block.slot;
    const txSig = instruction.transaction.signature; // needs fields.transaction
    const isInner = instruction.isInner; // CPI?
  },
);
```

Key handler-level differences:

- **A failed decode never reaches the handler.** EVM `event.params` is always populated (the ABI is known); on Solana an instruction whose data the configured layout rejects is skipped, so `args` and `accounts` need no null checks.
- **Accounts are objects, not strings.** `instruction.accounts.<name>` is `{ address, accountName, instructionAccountIndex, activity }` - read `.address` for the pubkey.
- **Addresses are base58.** No `0x` lowercase/checksum concerns; pubkeys are base58 strings.
- **Every field is opt-in.** Instruction, transaction, account-activity, block and log fields all come from the registration's [`fields`](/docs/HyperIndex/solana/instruction-handlers#selecting-fields); on EVM the event always carries some block context.
- **The chain id is a big number.** `context.chain.id === 7565164` on mainnet (`7565165` on devnet).

## CPIs vs internal calls

On EVM, a contract calling another contract doesn't emit a separate indexable
event for the internal call. On Solana, **cross-program invocations are real
instructions**: if you index the inner program, you receive them, with
`isInner: true` and a `path` that reconstructs the call tree.
This makes Solana's composability directly indexable (e.g. the Raydium/Orca swaps
underneath a Jupiter route). See
[Inner instructions](/docs/HyperIndex/solana/instruction-handlers#inner-instructions-cpis).

## Account activity

Solana instructions can carry **pre/post lamport and SPL Token balances** for the
accounts a transaction touched (`fields.accountActivity`). This gives you net
value movement (the balance *change*) without indexing every transfer
instruction; there's no direct EVM equivalent built into the event. The amounts
are `bigint` raw base units, and each token entry carries the mint's `decimals`.
See [Account activity](/docs/HyperIndex/solana/instruction-handlers#account-activity).

## Slots vs blocks

- `start_slot` is a **slot**, and history doesn't reach genesis yet - see [choosing a start slot](/docs/HyperIndex/solana/configuration#choosing-an-endpoint-and-a-start-slot).
- Some slots have **no block** (skipped leader). Slot handlers must handle the empty case.
- The handler arg for `onSlot` is `{ slot: number }`, not a `block` object.

## Not supported on Solana (yet)

Contract import, dynamic registration, wildcard indexing across programs,
account-change and log handlers, and ReScript codegen have no Solana equivalent
today. The [overview](/docs/HyperIndex/solana#what-is-not-supported-yet) lists
each one and what to reach for instead.

What's the same: the [schema file](/docs/HyperIndex/schema), the entity
`context` API, the [Effect API](/docs/HyperIndex/effect-api), local Docker dev,
the GraphQL/Hasura layer, [preload optimization](/docs/HyperIndex/preload-optimization),
and [Envio Cloud](/docs/HyperIndex/hosted-service) deployment.

## Related

- [Solana Overview](/docs/HyperIndex/solana)
- [Configuration](/docs/HyperIndex/solana/configuration)
- [Instruction Handlers](/docs/HyperIndex/solana/instruction-handlers)
- [Decoding Instructions](/docs/HyperIndex/solana/decoding)
