ChainRead / Guides

Resolve an ENS name or Basename via API

Users type names like vitalik.eth or jesse.base.eth; contracts and transfers need addresses. This is a keyless lookup that returns the address and the resolver used.

The problem

Name resolution is more than a table lookup. You compute the name's namehash, ask the ENS registry for the resolver of that node, then ask the resolver for its address record. Basenames live on a different chain, Base, with their own registry, so the right chain depends on the suffix. Libraries do this for you, but they still need an RPC endpoint you must supply and keep reliable.

How /resolve answers it

GET /resolve?name=jesse.base.eth routes names ending in .base.eth to the Basenames registry on Base and every other name to the ENS registry on Ethereum mainnet. It returns the resolved address, the resolver contract, the registry that was asked and resolvedOn, the chain. If the name has no resolver or no address record, you get a 404 with an explanatory error, so a typo never turns into a valid-looking address. Pair it with /balance to go from a name to a balance in two calls.

Request and response

Example: a Basename.

$ curl -i "https://chainread.imac2014ville.workers.dev/resolve?name=jesse.base.eth"
HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6Mi4uLn0=   # base64 JSON: scheme "exact", network eip155:8453,
                                                  # asset USDC, amount 2000 (= $0.002)
# An x402 client signs the payment, then retries with a PAYMENT-SIGNATURE header.

The paid response (as returned at the time of capture):

{
  "ok": true,
  "name": "jesse.base.eth",
  "address": "0x2211d1d0020daea8039e46cf1367962070d77da9",
  "resolver": "0xc6d566a56a1aff6508b41f6c90ff131615583bcd",
  "resolvedOn": "base",
  "registry": "0xB94704422c2a1E396835A571837Aa5AE53285a95",
  "note": "Names are lowercased; full ENS normalization (emoji/Unicode) is not applied."
}

JavaScript with @x402/fetch

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

const signer = privateKeyToAccount(process.env.PRIVATE_KEY); // wallet holding USDC on Base
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(signer) }],
});
const res = await pay("https://chainread.imac2014ville.workers.dev/resolve?name=" + encodeURIComponent(name));
if (res.status === 404) throw new Error("name not registered or has no address");
const { address, resolvedOn } = await res.json();
console.log(name, "->", address, "on", resolvedOn);

Pricing

/resolve costs $0.002 per call. There is no API key and no account: each request is paid in USDC on Base over x402. Malformed input returns 400 and failed lookups return a non-2xx status, so those are not charged.

Limitations

More guides

Sister services