What this tool does
The ENS Resolver takes any .eth name and resolves it to an ETH address, the same lookup a wallet does when you type a name instead of a hex address. It is built for developers and integrators who want to see exactly what onchain resolution requires: two chained reads, not one, with the ENS namehash computed entirely server-side.
Key facts
- Resolves a
.ethname to its ETH address using two chained on-chain reads:registry.resolver(namehash)on the ENS Registry, thenresolver.addr(namehash)on the returned resolver contract. - The ENS namehash is computed entirely server-side via
sel.namehash(name); no client-side keccak256 or ENS library is required. - Ethereum mainnet only, forward resolution (name to address) only; reverse resolution is not implemented.
- CCIP-Read (ERC-3668) off-chain resolvers are not supported, since only on-chain reads are performed.
How to use it
- Enter a
.ethname into the form above, for examplevitalik.eth. - Run the query and read the resolver contract in the result panel.
- Read the resolved ETH address underneath it, with a copy button for pasting it elsewhere.
If the name has no resolver set, the tool stops after the first read and tells you so. If the resolver has no ETH address record, both reads complete and the tool still shows you the resolver address it found, alongside a note that there is no address record.
What is happening under the hood
ENS resolution cannot be a single expression because the second read’s target address is only known after the first read completes:
registry.resolver(sel.namehash(name))on the ENS Registry (0x00000000000C2E074eC69A0dFb2997BA6C7d2e1eon mainnet) returns the resolver contract for a name.resolver.addr(sel.namehash(name))on that resolver returns the resolved ETH address.
Both calls take the same argument, sel.namehash(name), the ENS namehash of the name. sel.namehash folds the dot-separated labels of the name into the namehash algorithm’s recursive keccak256(parent + keccak256(label)) construction internally, so both requests this tool sends are just the one-liners above, with a single name context variable. No keccak256, hashing, or ENS library runs in the browser: the entire namehash computation happens inside the expression the API evaluates. The two reads shown on this page still double as a demo of evmquery handling dependent, sequential queries: step 2 needs the resolver contract address that step 1 returns, so the requests cannot be combined into one call.
Build this yourself
Both requests below are the exact shapes this tool sends for vitalik.eth. Run the first, take its result.value, and use it as the resolver contract address in the second.
Step 1: find the resolver (curl)
curl -X POST https://api.evmquery.com/api/v1/query \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chain": "evm_ethereum", "schema": { "contracts": { "registry": { "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" } }, "context": { "name": "string" } }, "context": { "name": "vitalik.eth" }, "expression": "registry.resolver(sel.namehash(name))" }'This returns {"result":{"value":"0x231b0ee14048e9dccd1d247744d114a4eb5e8e63","type":"sol_address"}}, vitalik.eth’s real resolver.
Step 2: read the address (curl)
Same request shape, with contracts.resolver.address set to the resolver from step 1, and resolver.addr(...) in place of registry.resolver(...):
curl -X POST https://api.evmquery.com/api/v1/query \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "chain": "evm_ethereum", "schema": { "contracts": { "resolver": { "address": "0x231b0ee14048e9dccd1d247744d114a4eb5e8e63" } }, "context": { "name": "string" } }, "context": { "name": "vitalik.eth" }, "expression": "resolver.addr(sel.namehash(name))" }'This returns {"result":{"value":"0xd8da6bf26964af9d7eed9e03e53415d37aa96045","type":"sol_address"}}, vitalik.eth’s real, publicly known address.
TypeScript
const registryResp = await fetch("https://api.evmquery.com/api/v1/query", { method: "POST", headers: { "x-api-key": process.env.EVMQUERY_API_KEY!, "Content-Type": "application/json", }, body: JSON.stringify({ chain: "evm_ethereum", schema: { contracts: { registry: { address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" } }, context: { name: "string" }, }, context: { name: "vitalik.eth" }, expression: "registry.resolver(sel.namehash(name))", }),});const { result: resolverResult } = await registryResp.json();
const addrResp = await fetch("https://api.evmquery.com/api/v1/query", { method: "POST", headers: { "x-api-key": process.env.EVMQUERY_API_KEY!, "Content-Type": "application/json", }, body: JSON.stringify({ chain: "evm_ethereum", schema: { contracts: { resolver: { address: resolverResult.value } }, context: { name: "string" }, }, context: { name: "vitalik.eth" }, expression: "resolver.addr(sel.namehash(name))", }),});const { result: addrResult } = await addrResp.json();No manual ABI is needed for either call. resolver(bytes32) and addr(bytes32) are common enough selectors that evmquery’s ABI-less discovery resolves them automatically. The free tier has no monthly cap. Get a free API key to drop these snippets into your project.
When you would use this
- Resolving user input. Let people type a name instead of a 42-character hex address anywhere your app accepts a recipient, a lookup target, or a profile link.
- Verifying a name before sending funds. Confirm what an ENS name actually resolves to right now, since resolver records can change.
- Learning how ENS resolution really works. See both onchain reads and the exact namehash expression that produces the node argument, instead of a black-box
.ethto address conversion. - Prototyping ENS support without adding viem or ethers. No client-side keccak256 or namehash library is needed to compute the ENS node; an app that already talks to evmquery can send the name as-is and let
sel.namehashcompute it server-side.
FAQ
Why does this tool make two onchain reads instead of one?
ENS resolution is inherently two steps. The ENS Registry only stores which resolver contract is responsible for a name, not the address itself. The resolved address lives on that resolver contract, whose address is only known after the first read, so a second read is required. This tool shows both reads and their results rather than hiding the chain behind a single call.
Which chains and names does this support?
Ethereum mainnet only, resolving .eth names to their ETH address record. The ENS Registry is canonical on mainnet, so this tool does not attempt cross-chain ENS lookups.
Can I look up which name an address owns?
No. This tool only does forward resolution, name to address. Reverse resolution, address to name, uses a separate ENS mechanism and is not implemented here.
What about off-chain or CCIP-Read resolvers?
Not supported. Some resolvers use CCIP-Read (ERC-3668) to fetch records from an off-chain gateway. SEL only performs onchain reads, so names that depend on an off-chain resolver will not resolve through this tool.
Limits and accuracy
- Built and tested against mainnet
.ethnames. Other ENS-compatible TLDs use the same namehash algorithm and will run through this tool, but they aren’t the focus and aren’t verified here. No L2 ENS deployments. - Forward resolution only. No reverse resolution (address to name).
- ENSIP-10 wildcard resolution, where a parent name’s resolver handles subnames that have no resolver of their own, is not distinguished from a genuinely unset resolver. Both currently surface as “no resolver set.”
- The result reflects the latest block at the time of the read. There is no historical replay.
- The demo is rate limited per browser. If you hit the limit, grab a free API key and the limit goes away.
No CCIP-Read or off-chain resolver support. SEL cannot perform off-chain lookups, so names that rely on a gateway will fail here even though a wallet with CCIP-Read support would resolve them.
Related
- ERC-20 Token Inspector: another free tool built on a single evmquery expression
- Multicall3 batching for EVM contract reads: how evmquery batches independent reads into one round trip
- Read smart contracts in n8n: wire an evmquery expression into a no-code workflow
- evmquery for developers: the full integration story