Integration with ENS (Ethereum Name Service)
Note: When a user manually enters the address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045, the probability of error is high. One wrong character and funds are lost. According to statistics, 70% of ETH transfer errors are due to incorrect address input. Ethereum Name Service solves this: instead of a hex string, a readable vitalik.eth. But ENS integration is not just library calls. Without accounting for name normalization (UTS-46), on-chain gas costs, and reverse record format, bugs can easily appear. Full integration takes 2 to 5 working days. Our clients save an average of $2000 per year on transfers due to reduced errors, and support costs drop by up to $500 per month.
Why Integrate ENS?
ENS is the de facto standard for human-readable addresses in Ethereum. It frees users from copying long addresses and reduces input errors. Over 90% of popular dApps already support ENS. Integration allows not only displaying names but also retrieving avatars, email, social media from the resolver — all in one place. User time savings can reach 10 seconds per transaction.
How ENS Resolution Works on the Frontend
The main libraries are ethers.js (v6) and viem. They provide methods for forward and reverse resolution, as well as avatar retrieval.
// ethers.js v6 const provider = new ethers.JsonRpcProvider(RPC_URL); // Forward resolution: name → address const address = await provider.resolveName("vitalik.eth"); // "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" // Reverse resolution: address → name const name = await provider.lookupAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"); // "vitalik.eth" or null if reverse record not set // Avatar const resolver = await provider.getResolver("vitalik.eth"); const avatar = await resolver?.getAvatar(); // Avatar URL or null // viem import { createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; import { normalize } from "viem/ens"; const client = createPublicClient({ chain: mainnet, transport: http() }); const address = await client.getEnsAddress({ name: normalize("vitalik.eth") }); const name = await client.getEnsName({ address: "0xd8dA..." }); const avatar = await client.getEnsAvatar({ name: normalize("vitalik.eth") }); normalize() is important: ENS names are normalized according to the UTS-46 standard before hashing. Vitalik.ETH and vitalik.eth are the same name, but without normalize() they would produce different namehashes.
Why Name Normalization Is Critical
Without normalization, the name MyName.eth and myname.eth would be considered different, leading to resolution errors. The normalize() function from viem or the UTS-46 library ensures consistency. On the frontend, this step is mandatory before every ENS request. Do not use raw user input — always normalize.
Comparison of Libraries and Integration Methods
| Parameter | ethers.js | viem |
|---|---|---|
| Size (min+gzip) | ~80KB | ~50KB |
| Built-in normalization | No (requires UTS-46) | Yes (normalize() method) |
| ENS methods | resolveName, lookupAddress, getResolver | getEnsAddress, getEnsName, getEnsAvatar |
| Type | Full-featured library | Thin wrapper |
viem handles ENS requests twice as fast due to lazy evaluation, and the bundle size is almost 40% smaller. For simple resolution, viem is preferable. If you need broader functionality (e.g., transaction handling), ethers.js remains the standard.
| Method | Library | Complexity | Applicability |
|---|---|---|---|
| Forward resolution | ethers.js/viem | Low | UI components |
| Reverse resolution | ethers.js/viem | Low | UI components |
| On-chain resolution | Solidity + ENS Registry | Medium | Smart contracts |
| Text records | ethers.js/viem | Low | User profiles |
| Avatar | ethers.js/viem | Low | UI components |
How to Resolve ENS On-Chain?
For smart contracts, a direct call to the ENS Registry is needed. Here's an example contract:
interface IENSResolver { function addr(bytes32 node) external view returns (address); } interface IENS { function resolver(bytes32 node) external view returns (address); } contract ENSConsumer { IENS constant ENS_REGISTRY = IENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e); function resolveENS(bytes32 namehash) external view returns (address) { address resolverAddr = ENS_REGISTRY.resolver(namehash); require(resolverAddr != address(0), "No resolver"); return IENSResolver(resolverAddr).addr(namehash); } } The namehash for alice.eth must be computed off-chain (or via ENS SDK) and passed into the contract — on-chain string namehash computation is expensive (about 20k gas).
Text Records and Profiles
ENS stores arbitrary text records by key:
const resolver = await provider.getResolver("alice.eth"); const email = await resolver?.getText("email"); const twitter = await resolver?.getText("com.twitter"); const github = await resolver?.getText("com.github"); const website = await resolver?.getText("url"); const description = await resolver?.getText("description"); Standard keys (EIP-634): email, url, avatar, description, notice, keywords, com.twitter, com.github, com.discord, org.telegram. This forms the basis for ENS-based profiles: everything is stored in the resolver, readable without additional infrastructure.
Process of Work
When you order ENS integration, we provide the full cycle:
- Audit of the current dApp and identification of integration points.
- Development of frontend components (ENS name input and display, avatars).
- Implementation of on-chain resolution if needed.
- Integration of text records and avatars.
- Testing on testnet (Sepolia).
- Deployment, monitoring, and documentation with code examples.
Timelines — from 2 to 5 working days for basic integration. Cost is calculated individually. Contact us for an accurate estimate for your project. Get a consultation on ENS integration today.
Typical Mistakes in ENS Integration
-
Missing normalization — Names like
Vitalik.ETHandvitalik.ethmust produce the same namehash. Withoutnormalize(), mismatches can occur. -
Ignoring gas costs for on-chain — Calling
resolver()andaddr()in a contract costs gas; use only when necessary. -
Incorrect namehash — If the wrong node is passed, resolution returns
address(0).
Our Experience
We have implemented ENS in 30+ dApps over 5+ years of work, including DeFi and NFT marketplaces. Our engineers have deep knowledge of ENS specifics: from normalization to gas optimization. We guarantee stability and compatibility with the latest library versions. Support after deployment — 1 month.







