Indexing that treats a reorg as a handled event rather than a data incident.
Reading logs from a chain is a short integration. The work is keeping what you wrote down true when the chain changes its mind, when a provider drops mid-stream, and when five networks disagree about what confirmed means.
Why indexed state stops matching the chain.
An indexer is easy to get working and hard to keep correct. Everything below follows from the same assumption — that a block you have read is a block that happened — and each one surfaces as a wrong number rather than as an error.
A reorg corrupts indexed state and nobody notices until balances are wrong
An indexer that writes as it reads will persist orphaned blocks without complaint. Writing against a confirmed cursor and keeping the rollback window addressable turns a reorg into an explicit rollback with an affected range, which consumers compensate for deterministically.
Five chains have five different definitions of confirmed
Absorbing that difference in product code means every new feature re-learns it, and gets it slightly wrong. Finality belongs normalised into named levels the application chooses from, with the per-chain confirmation maths in one adapter per chain.
Event handlers silently miss logs during a provider switch
A cursor held per connection dies with the connection. Held per stream, a failover resumes from the last committed offset, which produces duplicates — and a consumer can deduplicate a log it has already seen. It cannot detect a gap.
One slow provider degrades everything behind it
A binary health check fails a provider only once it is already hurting you. Scoring health on latency and error rate continuously, and dropping weight before ejection, drains traffic gradually instead of cliff-edging it onto whatever is left.
Cost scales with request volume because every read reaches a provider
Most reads ask for state that can never change again. Caching immutable results by block height leaves only tip-of-chain reads going out, which removes most duplicate traffic.
Nobody can say which chain is degraded right now
Block height, finality lag, gas and provider health in one operational view make indexer lag an alert with a known blast radius, instead of something inferred later from a user reporting a stale figure.
How we build one.
The confirmed cursor is the load-bearing decision: every consumer reads from it rather than from a chain head, so correctness is settled once instead of in each handler. The layers below exist to keep that cursor honest.
- 01
RPC gateway
Latency-aware routing across multiple providers per network, with health scoring, weight draining, circuit breaking and a response cache keyed by block height.
- RPC routing
- Circuit breaker
- Block-height cache
- 02
Normalisation
Per-chain finality, confirmation and gas semantics mapped to one abstraction, so supporting another network is configuration rather than a rewrite.
- Finality normalisation
- Adapter pattern
- 03
Indexing engine
Reorg-safe cursors with deterministic rollback, typed log decoding from the ABI or IDL, and backfill from any block.
- Reorg-safe cursors
- Deterministic rollback
- ClickHouse
- 04
Delivery
At-least-once delivery over ordered partitions with offsets committed per stream, so a failover or a consumer outage is replayed rather than lost.
- At-least-once delivery
- Ordered partitions
- 05
Networks
Multiple providers per chain across EVM networks and Solana, pooled so no single endpoint is load-bearing.
- 5 networks
- EVM
- Solana
- 06
Control plane
Network configuration, declarative indexer deploys, per-key quotas and scopes, and the alerting that says which chain is degraded.
- PostgreSQL
- Per-key quotas
We have already built this.
NEXUS is our multichain infrastructure layer: an RPC gateway that routes by health and latency and drains a failing provider before ejecting it, finality normalised into named levels across EVM chains and Solana, reorg-safe indexers with deterministic rollback and backfill from any block, and at-least-once event delivery against per-stream cursors. It is a MaatX demonstration rather than a client deployment, and the mechanisms above are running in it.

Questions we get asked.
Does at-least-once delivery mean my handlers have to be idempotent?
Yes, and it is the trade we would make again. Cursors are committed per stream rather than per connection, so a provider failover resumes from the last committed offset and can re-deliver events a consumer already processed. A log is identified by its network, block, transaction and log index, which is a stable deduplication key — a duplicate becomes a keyed write that does nothing. A gap has no such signature, which is why we do not offer the opposite guarantee.
Which networks does this cover?
The demonstration indexes Ethereum, Arbitrum, Base, Polygon and Solana. Adding another is configuration rather than a rewrite, because confirmation maths and gas semantics sit in one adapter per chain instead of in the code consuming them. That boundary is the thing worth inspecting in any indexing stack, ours included.
We could use a hosted indexer. When is building this worth it?
If a hosted indexer still fits what you are doing, stay on it — we are worth paying once you have hit a ceiling you cannot engineer around from where you are. In indexing that ceiling is usually one of three things: a consumer that has to compensate for reverted state, so the rollback semantics need to be yours; decoding a hosted schema cannot express; or a data-residency requirement that rules out running on someone else's gateway.
What does an engagement look like?
Usually Mechanism and Architecture first — one to three weeks to settle the finality levels, the cursor and rollback model, and the delivery guarantee. Those three decide what every downstream consumer has to handle, and changing them after a year of history means reindexing it. Build follows if you want us to do it.
What it costs, and what you are agreeing to.
The commercial answers in one place, so none of them has to wait for a call.
Typical route in
Full System Build
Typically $25,000–120,000
Scoped per system
The contract is one layer. Most of what decides whether an on-chain system survives production lives in the indexing, the risk model and the reconciliation.
A starting point for the scope described, not an estimate for your project. Ongoing engineering runs at $75 per hour blended.
Who owns what you build?
You do. On full payment of the fees for an engagement, the intellectual property in everything built specifically for you is assigned to you.
Our pre-existing tools, libraries and internal infrastructure stay ours — but where a deliverable uses them, you get a perpetual, worldwide licence to run, modify and extend it. Nothing we hand over needs us to keep operating it. Open-source and third-party components keep their own licences, and we tell you which ones and what they require.
We also will not name you as a client, describe your project, or publish a case study about it without your written agreement.
What happens if it does not work out?
Either of us can end an engagement with 30 days written notice, or immediately if the other commits a material breach and does not remedy it within 15 days. You pay for work properly performed up to that point, and we hand over completed work along with every deliverable you have paid for.
Two limits worth stating before you ask. We are engineers, not advisers: nothing we deliver is legal, regulatory, tax or financial advice, and a system built to your specification is not an opinion that it is lawful in your jurisdiction. And where our work includes reviewing or auditing code, the findings cover the scope and time agreed — an absence of findings is not a guarantee that nothing is there.
What do you need from me to start?
Not a specification. Discovery exists precisely because most people do not have one — an idea, or a technical problem you cannot yet size, is enough to begin.
What the work does assume: timely access to the people, systems, credentials and environments it touches; decisions and approvals at roughly the pace the timeline assumes, since delays on your side move both dates and cost; and that you have the right to give us whatever you give us, including data, code and third-party material.
Why you rather than the alternative?
Against hiring a senior engineer in-house: sourcing one takes months and commits you permanently. Discovery runs 1–3 weeks, and you keep the architecture whichever way you then go — including if the answer is to make that hire.
Against the cheapest contractor available: you will pay less per hour. Our argument is that the architecture decision is the one that is expensive to reverse, which is why we sell it first, separately, and at a price you can say yes to before committing to a build.
Against a larger firm: there is no account layer. The people who scope the work are the people who build it.
And when not to hire us: if a no-code or off-the-shelf tool still fits what you are doing, stay on it. We are worth paying once you have hit a ceiling you cannot engineer around from where you are.
These are summaries. The binding version of the ownership, exit and liability terms is in our Terms of Service. A person reads every enquiry. We usually reply within a few hours.
Start a technical assessmentReading several chains and needing one finality model your application can trust?
Send us the architecture or the problem. We will come back with the technical risks we can see and a sensible path forward, free, and tell you if we are not the right people for it.
