Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Resolution

Resolution loads information about an ENS name, such as an address or a text record. In ENSv2, the Universal Resolver is the entry point for resolution.

App / libraryUniversal ResolverRecord

Under the Hood of Your Library

Your library makes one resolution call to the Universal Resolver. The resolver walks the registry hierarchy internally, finds the authoritative resolver, and returns the requested record. It handles wildcard resolution and CCIP Read, with your client following gateway requests when needed. Unmigrated names are resolved through the v1 mirror.

Use an ENSv2-ready library. For example, with viem 2.35.0 or later, replace <MAINNET_RPC_URL> with your Ethereum Mainnet RPC endpoint:

import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { normalize } from 'viem/ens'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http('<MAINNET_RPC_URL>'),
})
 
const address = await client.getEnsAddress({
  name: normalize('nick.eth'),
})
// The current Ethereum address record for nick.eth

Libraries use the upgradable Universal Resolver entry point. Do not hardcode an individual name's resolver or look it up through the v1 registry. See Address Lookup and Text Records for application examples.

Reverse Resolution

Reverse resolution finds an address's primary name. It uses forward resolution under the hood: the address is encoded into a name in the reverse namespace, and the resolver for that name is queried for its name() record.

For example, an Ethereum address such as 0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5 has a reverse name of b8c2c29ee19d8307cb7255e1cd9cbde883a267d5.addr.reverse. The address portion is lowercase and has no 0x prefix. Its name record provides a candidate primary name, such as nick.eth. The reverse-resolution system can also fall back to a default primary name.

A reverse record alone is not enough to trust that name. The Universal Resolver then resolves the candidate name's address record and checks that it matches the original address. Anyone can set a reverse record naming someone else's ENS name, so this forward check is essential. If the addresses do not match, display the address instead.

At ENSv2 launch, the existing v1 reverse namespace remains in use. The ENSv2 Universal Resolver reaches it through the ReverseMirror, so existing primary names continue to work.

Look Up a Primary Name with Viem

With viem 2.35.0 or later, getEnsName() uses the Universal Resolver and includes the forward-address verification. It returns null when there is no valid primary name, including when the forward address does not match. Replace <MAINNET_RPC_URL> with your Ethereum Mainnet RPC endpoint:

Viem
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: mainnet,
  transport: http('<MAINNET_RPC_URL>'),
})
 
const address = '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5'
const primaryName = await client.getEnsName({ address })
const displayName = primaryName ?? address
console.log(displayName)

Handle RPC or gateway errors separately from a missing primary name. For setting primary names and requesting records for other chains, see Getting a Primary Name.