Envio Developer Update August 2026
We are excited to open Solana HyperSync support up for early access. Indexing Solana programs at the instruction level is in beta on top of it, and the Rust client has its query API locked at 0.2.0. If you are building on Solana we would love you to try it.
Elsewhere, seven HyperIndex releases took us from v3.5.0 to v3.9.0. Factory indexers stopped hitting a wall at around 8 million addresses, multichain projects can isolate entities per chain with a single flag, and we announced HyperPipe, which streams decoded onchain data to any destination from one YAML file. We also started letting people run unmodified subgraphs on HyperIndex. We will be at Devcon in Mumbai and Solana Breakpoint in London, both in November.
Let's dive in!
Introducing Solana HyperSync
HyperSync for Solana is open for early access. It is the same data engine behind our EVM indexing, serving slots, transactions, instruction calls, logs, account activity and rewards from one endpoint, so historical backfills are fast and you never touch an RPC node for the bulk of indexing.
On top of it, HyperIndex indexes Solana programs at the instruction level, now in beta. You select the programs and instructions you care about, HyperIndex decodes them, arguments and accounts, using your Anchor IDL or an inline schema, and writes the results to Postgres with an auto-generated GraphQL API.
pnpx envio init
Choose Solana when prompted, then pick a starter template, either a Metaplex NFT instruction indexer or a minimal slot handler.
Two ways to index Solana
| Approach | API | Data source | Use it for |
|---|---|---|---|
| Instruction handlers | indexer.onInstruction | HyperSync | The main path. Decode and index program instructions such as swaps, deposits, mints and transfers, including inner and CPI instructions, with token balance changes. |
| Slot handlers | indexer.onSlot | RPC via the Effect API | Per-slot orchestration, time-series snapshots, or pulling extra data from RPC on a schedule. |
Most indexers use instruction handlers. Slot handlers are for running logic on a slot cadence rather than reacting to a specific instruction.
Coming from EVM
The shift is mostly vocabulary.
| EVM | Solana |
|---|---|
| Contract + ABI | Program + IDL |
Event (onEvent) | Instruction (onInstruction) |
event.params | instruction.params.args |
| Topic0 / event signature | Instruction discriminator |
Block (onBlock) | Slot (onSlot) |
| Hex addresses | Base58 addresses |
start_block = block number | start_block = slot number |
As of v3.9.0 the HyperSync endpoint is derived from your chain.id automatically, so experimental.hypersync_config is optional. Each endpoint serves history back to its own floor slot, and that floor moves forward over time, so pick your start_block deliberately.
What works today
IDL-aware decoding against a standard Anchor IDL, legacy or 0.30 and up, with an inline schema as the fallback when there is no IDL. Inner instructions (CPIs) decode the same way as top-level ones, with a full instruction-address path so you can reconstruct the call tree. Pre and post SPL Token and Token-2022 balances come per transaction, so you get net token movement without indexing every transfer. Transaction metadata and per-instruction program logs are available through field selection, and local dev, GraphQL and Envio Cloud work exactly as they do on EVM.
Retention and clients
Only a rolling window of recent slots is retained, so anchor your ranges to GET /height rather than hard-coding a lower bound. The Rust client hypersync-client-solana reached 0.2.0 this month with its query API locked.
Tell us what you need
Early access means talking to us. Get in touch with the team on Discord and we will get you set up. Share a sample transaction signature or program ID and we will map it to a concrete query path, and tell us what you are building because that is what we are prioritising against.
Read the docs: Indexing on Solana and Solana HyperSync
Prefer clicking to typing? The Query Builder builds Solana queries visually.
HyperIndex v3.5.0 -> v3.9.0
v3.9.0
Per-Chain Entities Get Postgres Partitions
Set disable_default_cross_chain: true and per-chain entities are now split into Postgres partitions, which speeds up reads and writes when a query targets one chain. The automatically added chainId column can also be used in your ClickHouse orderBy configuration.
Support One Address for Multiple Contracts
Handy when the factory addresses are not yours to control. The same address can now be routed to more than one contract definition.
name: shared-address-routing
contracts:
- name: Token
events:
- event: Transfer(address indexed from, address indexed to, uint256 value)
- name: Vault
events:
- event: Transfer(address indexed from, address indexed to, uint256 value)
- event: Deposit(address indexed owner, uint256 amount)
chains:
- id: 1
contracts:
- name: Token
address: "${sharedAddress}"
- name: Vault
address:
- "${sharedAddress}" # An error before, now a legit case
- "${vaultOnlyAddress}"
Nullability with @derivedFrom
Derived fields now accept any nullability combination, which matches subgraph behaviour more closely and matters if you are running a subgraph on HyperIndex.
type Parent {
id: ID!
strict: [Child!]! @derivedFrom(field: "parent")
nullableList: [Child!] @derivedFrom(field: "parent")
nullableItems: [Child]! @derivedFrom(field: "parent")
nullableBoth: [Child] @derivedFrom(field: "parent")
}
type Child {
id: ID!
parent: Parent!
}
Clearer Schema Validation Errors
Validation errors on schema.graphql now give an exact location, a concise description and a suggested fix.
schema.graphql:7:13: Invalid `@index` on `Second`:
`missing` is not a column of the entity.
Available columns: `id`, `value`.
Solana Config Gets Simpler
experimental.hypersync_config is now optional and derived from chain.id, instruction.args is no longer optional because instructions that fail to decode are skipped, and the SVM handler and data types are finalised.
v3.8.0
Hiding Entities From the GraphQL API with @internal
Some entities exist for the indexer, not for the consumer. Bookkeeping state, checkpoints, and anything sensitive you would rather not expose publicly. Mark an entity @internal and it stays out of the GraphQL API entirely, with no queries, no relationships, and no introspection entry, while remaining fully usable in your handlers.
type Secret @internal {
id: ID!
note: String!
}
An exposed entity cannot reference an @internal one, because that relationship could never be served over GraphQL. Either mark the referencing entity @internal too, or store a plain id field instead of a relationship.
More in the schema docs.
Skipping Indexes for ClickHouse
Even more control to optimise query performance for your ClickHouse storage, configured per entity alongside partitioning and sort keys.
type Transfer @storage(
clickhouse: {
partitionBy: "toYYYYMM(timestamp)"
orderBy: ["chainId", "timestamp"]
skippingIndexes: [
{
name: "idx_from"
expr: "fromAddress"
type: "bloom_filter(0.01)"
granularity: 4
},
{
name: "idx_to"
expr: "toAddress"
type: "bloom_filter(0.01)"
}
]
}
) { ... }
Breaking: Solana API Changes
We are getting closer to a stable Solana release, and this version lands most of the API we intend to keep. The onInstruction API had a large overhaul for more correct and descriptive types, field_selection for Solana moved to the per-handler fields option introduced in v3.7.0, and Solana chains now require an explicit id: solana in config.yaml or a custom number of your choosing. The internal Solana chain id also moved from 0 to 7565164 to avoid colliding with Fuel. The Test Indexer now supports the simulate API with Solana instructions.
See the Solana section above for where support stands.
v3.7.0
Per-Handler Field Selection
A new way to declare the transaction and block fields your handler logic uses, listed under a fields option right where you consume them. It is type-safe, and we fetch and decode only the fields you list.
indexer.onEvent(
{
contract: "MyContract",
event: "Transfer",
fields: {
transaction: ["hash", "from"],
block: ["timestamp"],
},
},
async ({ event, context }) => {
event.transaction.hash; // string
event.block.timestamp; // number
// Type error, not listed in fields:
event.transaction.gasUsed;
},
);
The field_selection option in config is still supported with no breaking changes, but fields in handlers is the recommended approach going forward.
More Fields on the RPC Source
Indexers running on the RPC source can now select 20 more transaction fields and 15 more block fields, including gas, nonce, status, effectiveGasPrice and the L1 fee fields that matter on L2s.
Transaction (20): gas, nonce, v, r, s, yParity, type, maxFeePerBlobGas, blobVersionedHashes, cumulativeGasUsed, effectiveGasPrice, gasUsed, logsBloom, root, status, l1Fee, l1GasPrice, l1GasUsed, l1FeeScalar, gasUsedForL1
Block (15): sha3Uncles, logsBloom, transactionsRoot, receiptsRoot, totalDifficulty, size, uncles, blobGasUsed, excessBlobGas, parentBeaconBlockRoot, withdrawalsRoot, l1BlockNumber, sendCount, sendRoot, mixHash
Reorg detection also improved for SVM and for an edge case on the EVM RPC source.
v3.6.0
Per-Chain Isolation By Default
One step closer to truly isolated multichain. Until now every entity row was shared across every chain, so multichain indexers namespaced ids by hand with patterns like ${event.chainId}_${pool}. This release lets you turn that off.
# Recommended for all projects,
# and the default in HyperIndex v4
name: my-indexer
disable_default_cross_chain: true
With the flag on, entities and effects are scoped per chain. Entity tables get a composite (id, chainId) primary key, so the same id on two chains is two independent rows. Handlers do not change, because a handler always runs on a single chain, and context.Token.get(id) reads that chain's row.
Where you do want shared data, add @crossChain to an entity or crossChain: true to an effect.
# Per-chain, one row per (id, chainId)
type Counter {
id: ID!
count: BigInt!
}
# One row shared by every chain
type GlobalCounter @crossChain {
id: ID!
count: BigInt!
}
Outside a handler there is no chain in context, so Test Indexer operations now take one explicitly with indexer.Counter.set({ id, count, chainId }), and getWhere is available on the test indexer's entity operations. The envio init templates drop the ${event.chainId}_ prefix from entity ids, and the bundled indexer skills teach the per-chain convention.
We recommend the flag for all projects, and it becomes the default in v4.
v3.6.1 followed two days later with a reliability improvement for chains that go long stretches without events, keeping the indexer moving at the head.
v3.5.0
v3.5.0 landed the day after last month's update went out, so it belongs here.
Factories With Billions of Addresses
Factory contracts previously began to strain HyperIndex at around 8 million addresses. That ceiling is gone. The number of supported addresses is now effectively unlimited, bound only by the resources you give it.
We got there by having HyperIndex switch automatically from server-side to client-side filtering, which cuts the number of queries dramatically, plus a partial Rust rewrite that reduces resource usage during event processing.
A full backfill of Uniswap V2 on mainnet, one of the busiest protocols ever deployed, now completes from scratch in just over a day.
Deferred Postgres Index Creation
Postgres indexes defined in schema.graphql used to be created upfront, which could cause significant write backpressure during backfill. They are now created just before the indexer enters realtime, once the backfill is complete. On top of that, when a handler makes a getWhere call, HyperIndex generates the index for the required field automatically, so you no longer need to declare those in your schema. Indexes in schema.graphql are now specifically for your production GraphQL server.
Up to 2.5x faster backfill for some users.
Bottleneck Observability
Two new Prometheus metrics pinpoint where an indexer is actually spending its time:
envio_processing_stalled_on_fetch_seconds, time spent idle with an empty buffer, waiting for events to be fetchedenvio_processing_stalled_on_storage_write_seconds, time spent idle due to write backpressure
We also added utility metrics that make every scrape self-describing, which is useful for monitoring tools and for AI agents reading the output. Those are envio_process_start_time_seconds, envio_process_metric_time_seconds and envio_process_elapsed_seconds. The elapsed metric means you can interpret counters from a single payload with no rate() and no external clock, so envio_processing_stalled_on_storage_write_seconds / envio_process_elapsed_seconds gives you the fraction of the run spent stalled on writes.
Full details are in the Production Observability guide.
Numeric Entity IDs
You can now use Int or BigInt as the id type for entities in schema.graphql. Relationship fields are inferred correctly, and handler types are generated as number.
type Chain {
id: Int! # Numeric entity ID
vaults: [Vault!]! @derivedFrom(field: "chain")
}
type Vault {
id: ID!
chain: Chain! # Stored as chain_id (Int)
// ...
}
Chain IDs Above 2^31
Added for a Tron Testnet user and useful well beyond it. If your config includes a chain with an id greater than 2^31, HyperIndex now automatically uses larger database types to support it.
v3.5.1 rounded the release out with improvements to how dynamic contract registration is persisted.
See the full release notes
Star us on GitHub
Introducing HyperPipe
Stream decoded onchain data straight to any destination, from a single YAML file.
HyperPipe puts sources, transforms and sinks in one declarative config, with no glue code and no orchestration to build. Historical backfill and live streaming come from the same source, across multiple chains at once.
name: usdc-transfers
version: 1
sources:
- name: eth
type: hypersync
chain: ethereum
mode: both # backfill + live
processors:
- name: decode
module: builtin/evm-abi-decoder@1
inputs: [eth]
config:
abis:
- file: ./abis/erc20.json
events: [Transfer]
sinks:
- name: db
module: builtin/postgres@1
inputs: [decode]
ABI decoding and filtering are built in, sinks cover Postgres with automatic DDL, Parquet on S3, or any webhook, and delivery is checkpointed and at-least-once so it survives restarts. It runs as one binary, a Dockerfile, or Kubernetes manifests.
HyperPipe is in alpha and we are onboarding early access users now. Come and ask for access in our Discord.
Run Your Existing Subgraph on HyperIndex, Unmodified
Point one command at a subgraph project you already have and it runs on HyperIndex underneath.
cd my-subgraph && pnpx envio@3.7.0-subgraph dev
No changes to your manifest, schema, mappings or ABIs, and the same folder still deploys to Graph Node. We measure it at around 200x faster on average than running the same subgraph unchanged.
It is versioned alongside HyperIndex, so 3.7.0-subgraph carries the v3.7.0 changes plus wider compatibility coverage. We are looking for subgraphs to test it against, especially awkward ones.
To convert a subgraph properly instead of running it as-is, the migration guide covers the mechanics, and existing queries keep working through our query converter.
Reach out on Discord to test it, or see the original post on X.
HyperSync as a Datasource for Carbon
Co-founder Jason has been working on Solana indexing after a long stretch deep in EVM, and the first thing to come out of it is HyperSync as a datasource for Carbon, the Rust indexing framework from Seven Labs.
Carbon already supports a long list of datasources, from Yellowstone gRPC to various RPC crawlers. Adding HyperSync took a nine-line trait implementation. If you already build on Carbon, it means historical backfill without standing up your own infrastructure.
The change is open at PR #586 on the upstream repo and is still in review, with our fork at enviodev/carbon in the meantime.
For more information, see the original post on X.
How to Get Polymarket Trade Data
Every order-book fill Polymarket has settled since its 2020 launch, up to 24 April 2026, is free on Hugging Face under CC-BY-4.0. That is 1.17 billion CLOB fills, 2.63 million distinct makers and $59.9 billion of lifetime volume.
You query it with DuckDB straight over HTTPS. No download, no API token, no Polygon node. The guide walks through the snapshot first, then five wallets pulled out of those tables with queries you can run to check every number, and finishes with the open indexers if you want markets at head rather than history.
Two things catch people out, and both are in there. Addresses are EIP-55 checksummed, so filters need wrapping in lower(). And an account can trade from a proxy as well as directly from its signer, so querying only one can miss 99.7% of a wallet with no error at all.
Read the full guide: How to Get Polymarket Trade Data
Four Years of DeFi Liquidations, Visualised
Co-founder Jonjon put together a visual of liquidations across Aave, Euler and Morpho over the past four years, spanning more than 20 chains.
282,430 liquidations on Aave v3, 193,518 on Morpho and 7,515 on Euler v2, weekly since March 2022.
The same pipeline that answers "what just happened" also answers "what happened everywhere since 2022".
For more information, see the original post on X.
Backfilling Uniswap V2 on Mainnet From Scratch
Uniswap V2 on mainnet is one of the busiest protocols ever deployed. Jonjon ran a full backfill from scratch, all 25,751,860 blocks of it, and reached 100% synced in two days.
610,379,970 events processed across 518,333 addresses.
The v3.5.0 work above targets exactly this, removing the address ceiling on factory indexers and deferring Postgres index creation until the backfill completes.
Full methodology for our published figures is on the benchmarks page, with the raw runs in the open-indexer-benchmark repo.
Original post on X: https://x.com/jonjonclark/status/2088170247920464252
Envio Added to the Prediction Markets Wiki
The Prediction Markets Wiki added Envio as the data layer behind prediction-market apps, noting that builders can index onchain events, backfill history and use the open Polymarket datasets rather than rebuilding the pipeline from scratch.
The Polymarket snapshot covered above is free under CC-BY-4.0, so anyone building in the category can start from real data instead of an empty database.
For more information, see the original post on X.
Current & Upcoming Events & Hackathons
- Devcon 8 - Mumbai: November 3rd -> 6th
- Solana Breakpoint - London: November 15th -> 17th
Featured Developer: tdubb
This month's featured developer is tdubb, founder of Reptilian and a developer experience engineer at Antithesis, where he works on the NixOS-based platform team behind a simulation platform that tests the guarantees of some of the hardest distributed systems around, for the likes of Jane Street and Ethereum. They tested the Merge.
Before crypto he spent three years leading infrastructure and reliability on Prefect, work he describes as having contributed to curing rare genetic childhood diseases and to winning the World Series for his city, by building a workflow system that levelled up data scientists everywhere. He came into web3 as founding engineer at Orb Labs, and now splits his time between chain abstraction, the open-source property-based testing project Hegel, and Reptilian's partnership with Foundation, which helps token launchers run long-term liquidity strategies across chains.
What tdubb had to say about Envio:
"One of my focuses has been chain abstraction, which involves indexing data across the chainiverse, which is maybe the most poorly-understood and surprisingly difficult problem in our industry. When I found Envio and HyperSync, it was everything I ever wanted, and it worked, right away, with incredibly powerful developer handles. Now, it powers all of my data efforts, underneath a Prefect-powered event-driven orchestration system for enriching data and taking action on it. HyperSync allows me to listen to the chainiverse, as well as develop new historical data abstractions over chainiverse history on its EXTREMELY fast chain replay. I'm incredibly honoured to be recognised by such an incredible team and hope to contribute more to its future. Thank you, Envio!"
- tdubb, Founder of Reptilian and Developer Experience Engineer at Antithesis
Well done, tdubb. Be sure to follow him on X and check out Reptilian on GitHub to stay up to date with his latest developments.
Playlist of the Month
Build With Envio
Envio is a multichain EVM blockchain indexer for querying real-time and historical data. If you're working on a Web3 project and want a smoother development process, Envio's got your back(end). Check out our docs, join the community, and let's talk about your data needs.
Stay tuned for more monthly updates by subscribing to our newsletter, following us on X, or hopping into our Discord for more up-to-date information.
Website | X | Discord | Telegram | GitHub | YouTube | Reddit
Jordyn Laurier

