ENS data is distributed across 20+ smart contracts, with state and history spanning back to 2017. Accessing and reconstructing this data reliably requires significant domain knowledge and non-trivial indexing.
I’ve built a distributed indexing solution that continuously syncs ENS data, processes it into a structured form, and exposes it via a RESTful API.
The API enables querying across:
Ownership (current and historical)
Resolver and text records
Reverse records
Full domain history
Names by address, TLD, namehash or labelhash
The blog post linked below goes into more depth about what the product does, and how it works:
ENSWhois
ENSWhois.com is a frontend built on top of this API.
It acts as both:
a user-facing product for exploring ENS data
a reference implementation demonstrating what becomes possible with a complete ENS data layer
Supplementary Links
The following supplementary links hopefully answer some of the more obvious questions:
I believe that an API-first approach is crucial for the continued success of the Ethereum Name Service.
Today, integrating ENS often requires:
direct interaction with multiple contracts
reconstructing historical state from events
deep protocol-specific knowledge
This creates a barrier to growth - if it is hard to use ENS, people simply won’t do so.
An indexed, queryable data layer removes that complexity and enables:
faster integrations
new product surfaces
broader adoption beyond crypto-native developers
This direction has been shaped through conversations with companies in the DNS space that, in principle, want to use ENS, but are currently blocked by complexity.
Feedback
I would be very interested to hear people’s opinions on this and how it can be iterated and improved upon.
If you are considering an integration, I would be happy to support - I am interested to learn how consumers utilize this.
All the relevant information for surfacing that an ENS name is an agent is available on-chain. That said, in the interest of making integration of an ENS names’ status as an agent as simple as possible I have added support for it to the ENSWhois.com API.
A complete agent setup would include the registration of the ENS name in the Adapter8004 adapter contract AND specification of appropriate ENSIP-26 records AND specification of the ENSIP-25agent-registration text record.
The directory allows you to filter agents based on the specification of these values.
Additionally ENS names that are agents will display a notification indicating this on the individual domain page.
Thanks @clowes.eth — really like the /domain/:name/agent endpoint. I tried it against my agent and wanted to sanity-check whether what I’m seeing is index lag, a key-format thing, or an expected missing step on my end.
GET api.enswhois.com/domain/emilemarcelagustin.eth/agent returns my ENSIP-26 profile fine (context + endpoint), but registrations: [].
On-chain it is registered though — ERC-8004 #24994 in the Base registry 0x8004A169…a432 (chain 8453), and ownerOf(24994) matches the name’s owner. The ENS text records are:
agent-ids = ["24994"]
agent-registration[0x0001…2105…8004a169…][24994] = "1" ← per-registry, ERC-7930 encoded
agent-registration = (null) ← bare key not set
agent-context = "Trust Resolution Layer agent…"
So my registration lives under the per-registry ERC-7930 bracketed key rather than a bare agent-registration, and I registered directly into the 8004 registry rather than going through the Adapter8004 contract.
Question: does your indexer’s registrations reader (a) parse the bracketed agent-registration[<erc7930>][<id>] keys, or (b) key specifically off the Adapter8004 binding / a bare agent-registration key?
If it’s (a), this might just be a re-crawl; if it’s (b), I’ll bind through ENS8004.xyz / Adapter8004 to show up. Happy to share the resolver if useful — we read it via an agent-ids index since ENS has no text-record enumeration, so curious how you’re discovering the bracketed keys on your side.
I was asked recently by @netto.eth to help him debug an issue with primary names not being displayed correctly on Etherscan. Ultimately I ended up building a new tool for ENSWhois - Primary Name Debugger | ENSWhois.com
The tool allows you to enter an address and discern if the appropriate forward and reverse records have been set for spec compliant primary name resolution.
This is a first pass - there is a lot of nuance to backwards compatibility of reverse resolution specifications especially considering ENSIP-19 and cases where forward resolution uses custom resolvers (often also going off-chain). Any feedback is welcomed.
Etherscan Issue
The specific example I was debugging is the primary name resolution of the address 0xd2f7497bfe2daff1a69f306036a036abc8154aeb which is correctly setup (backward tx, forward tx) as ens.relayer.blockful.eth.
Etherscan does not display the primary name on the associated address page. My best guess is that they run their own indexer for primary name resolution and do not respect the default cointype - 0x80000000 (2147483648).
Assuming my hunch is correct, for the time being, the simplest solution to have your primary name display correctly would be to explicitly set the chain-specific forward resolution for your name (rather than taking advantage of the EVM chain default). Ethereum Mainnet is cointype 60.
Pinging @mely.eth@gregskril - it may be worth reaching out to Etherscan regarding this. I am going to iterate on this further when I have time and could offer a stable API endpoint to support future integrations.
Etherscan uses internal indexing for everything instead of external APIs/doing resolution on the fly, so unfortunately this won’t work for them. But Labs is in touch with Etherscan about v2 and various other things, so we’ll try to improve primary name implementation as part of that.