All posts
Engineering 15 July 2026 4 min read

Every ENS sale, indexed straight from the chain

Market-wide sale history on ENS.Tools is now reconstructed from chain data rather than a marketplace API. We scan ENS transfers against Seaport fulfilments directly on-chain — wrapped names included — and dedupe every sale by transaction and token.

Sale history — the price a name last changed hands for, the chart on a domain page, the activity feed on /trade — is only as good as the data feeding it. Up to now, a chunk of that data came from third-party marketplace APIs. That is fine until an API goes stale, rate-limits, or (as we have seen with other marketplaces recently) disappears entirely. So we built a native indexer that reconstructs market-wide ENS sale history directly from chain data, so the feed no longer stops when someone else’s API does.

How it works

The indexer scans two event streams over the same block range: ENS name transfers (both the classic ERC-721 registry and the wrapped ERC-1155 NameWrapper) and Seaport OrderFulfilled events. A sale is the intersection of the two — a name transfer that lines up with a Seaport fulfilment in the same transaction. We chunk getLogs calls to 500-block windows to stay inside RPC provider limits, and we match the two streams purely by transaction hash — deliberately with no per-transaction receipt lookups. That is the whole trick: the earlier receipt-per-order approach fired roughly a thousand RPC calls per 2,000-block window and rate-limited us into a catch-up death spiral. Two getLogs calls per window replaced all of it.

Wrapped names count too

Names wrapped by the NameWrapper transfer as ERC-1155 tokens, not ERC-721, which is easy to miss if you only watch the classic registry. Our indexer watches both, so a sale of a wrapped subdomain or a wrapped .eth name shows up in history exactly like an unwrapped one.

No duplicate sales

Every sale is keyed on (transaction hash, token id). That single change fixed a class of bugs where a fulfilment touched by more than one log — or replayed by a re-indexing pass — could show up twice in a name’s history or double-count in aggregate volume. The dedup key means re-running the indexer over the same range is always safe and always idempotent.

Verified against reality

Before shipping, we ran the indexer against a real two-name sweep on mainnet and confirmed both sales appeared exactly once, with the correct price and counterparties, within minutes of the transaction confirming. That is now the baseline every future change to the indexer gets checked against.

Why this matters

Sale history, price charts, and market analytics are only trustworthy if the underlying events are complete and accurate. Reading directly from ENS transfers and Seaport logs means our data no longer depends on any single marketplace staying online or keeping its API stable — we can see a sale the moment it settles on-chain, regardless of which front-end the buyer and seller used.

One honest caveat: that completeness is currently about the event, not the number. A sale filled against an ENS.Tools listing or offer is recorded with its exact price and fee. A sale fulfilled on another front-end lands without one, because we do not yet decode the Seaport consideration — it still appears in the name’s history and in our sale counts, it just does not add to volume until that decoding ships.

Try it

Open any domain’s detail page to see its full sale history, or browse /trade for market-wide activity — all of it now sourced natively from the chain.

Related — also tagged Engineering