Developers

Resolve .l2p names

The ENS contracts on this chain, forward and reverse lookups, and how .l2p differs from .eth.

Resolve .l2p names

The name service on L2 Protocol is the ENS v1.7 contract stack, with .l2p as the top-level domain instead of .eth. Anything that already resolves ENS names can resolve .l2p names by pointing it at these contracts.

The contracts

Every address comes from the chain feed, under the ens prefix. Read them from there rather than pasting them in.

curl -s https://chains.l2protocol.com/chains.json | jq '.[0].contracts[] | select(.name | startswith("ens")) | {name, address}'
Name in the feed Contract Use it for
ensRegistry ENSRegistry The owner and resolver of a node
ensBaseRegistrar BaseRegistrarImplementation Expiry, availability, the name as an ERC-721 token
ensRegistrarController L2PRegistrarController Prices, commitments, registration and renewal
ensPublicResolver PublicResolver Address, text and name records
ensReverseRegistrar ReverseRegistrar Setting a primary name
ensUniversalResolver UniversalResolver Forward and reverse lookups in one call
ensPriceOracle L2PPriceOracle Rent prices by label length

The ones your integration needs carry a full ABI in the feed ("abi": true), so a client can encode calls without shipping its own copy.

Forward: name to address

Use the universal resolver, which finds the right resolver for a name and reads it in one call, exactly as on Ethereum. Any ENS-aware library works once it is given the registry or universal resolver address for this chain.

The namehash of the .l2p top-level domain is:

0x81416bb7c03bc54e8597f6c932543fcd87e0649cd943cb29f71df95a7487f431

so yourname.l2p is namehash("l2p") combined with keccak256("yourname"), the standard way.

Reverse: address to name

ensUniversalResolver.reverse(address, 60) returns the primary name of an address, or nothing if it has none. 60 is the coin type for an EVM address.

The universal resolver does the forward check for you: after reading the reverse record it resolves the name forward, and reverts with ReverseAddressMismatch if the name does not point back at the address. So an answer from reverse is already verified, and an empty or reverted result means there is no trustworthy primary name. If you read the reverse record through any other route, do that forward check yourself, because a primary name that no longer points at its wallet is exactly what an impersonation looks like.

Records

Text records use the standard ENS keys: avatar, description, url, email, com.twitter, com.github, com.discord and org.telegram. Read them through text(node, key) on the resolver the universal resolver hands you.

Registration from code

The controller follows the ENS commit and reveal flow unchanged: makeCommitment, commit, wait at least 60 seconds and at most 24 hours, then register with the rent attached. Registrations are for at least 28 days. rentPrice(label, duration) returns the base and any premium separately, in wei.

What is different from Ethereum

The top-level domain is l2p, and that is the only intended difference in the contracts.

Name normalisation. The contracts do not normalise anything: valid() on the controller only checks for three or more characters, and every other call hashes the bytes it is given, so café, Café and cafe followed by a combining accent are three different names on chain. The site applies ENSIP-15, the same standard the ENS app uses, to every label that comes in through the url, the search box or its api before it hashes, displays or registers it, so only the normalised form of a name gets registered through the site. A label that does not normalise to itself can still exist on chain if it was registered directly against the controller; the site lists such a name as its label hash and opens it as an invalid name, and does not report a reverse record in that form as a primary name. Apply ENSIP-15 in your own integration before you hash anything a user typed: @adraffy/ens-normalize in JavaScript, ADRaffy.ENSNormalize in .NET. The price oracle counts characters as code points, so an emoji is one character.

There is no offchain resolution. Every lookup is an on-chain call against this chain.

Where names show up

The shared wallet button used by the explorer, staking, governance and voting sites resolves the connected wallet's primary name and shows it in place of the address. The names site itself is at names.l2protocol.com, and its pages are the reference for what a user sees. See What a .l2p name is.