Primary Names
A "primary name" is the result of a bi-directional relationship between an EVM address and a human-readable ENS name. The two directions are:
- Name -> Address (forward resolution)
- Address -> Name (reverse resolution)
The outcome of this relationship makes it safe for applications to display ENS names instead of EVM addresses, leading to a better user experience.
While forward resolution is configured in Resolvers, reverse records are typically set via smart contracts called Reverse Registrars which you can read more about below.
L2 Primary Names
Before we dive into code examples, let's first understand why things work the way they do.
Prior to August 2025, ENS users had to make a transaction on Ethereum Mainnet (L1) to set a primary name. More specifically, they had to set a reverse record on the Reverse Registrar contract which was only available on L1.
What is the difference between a reverse record and a primary name?
A reverse record is a mapping from an EVM address to an ENS name, which is only part of a primary name. In order for a primary name to be valid, the name must also forward resolve to the same address on the respective chain.
Since a majority of user activity is now on L2s, we've added the ability to set a reverse record on the following Ethereum Rollups:
- Arbitrum
- Base
- Linea
- OP Mainnet
- Scroll
In addition to these chains, we've also added the ability to set a default reverse record on Ethereum Mainnet (L1) that serves as a fallback when no chain-specific primary name is set. This is the simplest way to set a universal primary name for users who have a wallet that supports all EVM chains.
While this may sound simple in theory, it's easy to get tripped on the details in practice. Let's look at an example.
Understanding the Verification Process
The key thing to understand is that the forward address for a given chain must match the reverse record on the respective chain's reverse registrar.
Say I own nick.eth
. The name resolves to 0x1234...5678
because I've set the ETH address for that name. I call setName("nick.eth")
on the Base reverse registrar, and I expect that my primary name is now nick.eth
on Base. But that's actually not the case.
ENS names can resolve to different addresses on different chains, and since nick.eth
in the example above has only specified an Ethereum Mainnet address, the verification process will fail. In order to fix this, I need to set the Base address for nick.eth
which is on L1 in this case. This is done by calling the following function on the resolver for the name.
setAddr(
namehash("nick.eth"), // node (see Name Processing)
convertEVMChainIdToCoinType(8453), // coinType (see ENSIP-11)
0x1234...5678 // the address to set
)
Now that nick.eth
resolves to 0x1234...5678
via the Base cointype, and name(0x1234...5678)
on the Base reverse registrar returns nick.eth
, my primary name is fully set.
An alternative approach, which would be more efficient in this case, is to set the default EVM address for nick.eth
on the latest public resolver, and the default reverse record to nick.eth
on the default reverse registrar. This would allow the name to resolve to the correct address on all chains.
Getting a Primary Name
Looking up a users primary name is very simple. In most web3 libraries (wagmi, viem, ethers, web3py, etc.), you will find a built-in function to do a lookup by address as shown below. In most cases, the library will handle the verification for you.
Remember that in all cases, ENS resolution always starts from Ethereum Mainnet.
// https://wagmi.sh/react/hooks/useEnsName
import { useEnsName } from 'wagmi'
import { mainnet } from 'wagmi/chains'
export const Name = () => {
const { data: name } = useEnsName({
address: '0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5',
chainId: mainnet.id, // resolution always starts from L1
})
return <div>Name: {name}</div>
}
🎉 And that's it! Now you can turn all your pages from this, to this:
Setting Primary Names
Since primary names require two-way resolution, there are technically two steps to setting it up. Let's say that user 0x1234...5678
wants to set their primary name on Base to nick.eth
.
First, the user would need to set the Base address for nick.eth
to 0x1234...5678
. Read more about multichain addresses to understand how this works.
Next, the user would need to set the reverse record for 0x1234...5678
to nick.eth
in the Base Reverse Registrar. Read more about reverse records to understand how this works.
In order to avoid doing this manually for multiple chains, the user can set their default reverse record to nick.eth
on the default reverse registrar, and their default EVM address to 0x1234...5678
on the latest public resolver.