Most developers know ENS as a way to resolve .eth names to Ethereum addresses. But ENS was designed from the start to be chain-agnostic. A single ENS name can store addresses for Bitcoin, Solana, Optimism, Base, Arbitrum, and 100+ other networks — all accessible through a single resolution call.
ENS's Multi-Chain Design: ENSIP-9
ENSIP-9 (ENS Improvement Proposal 9, based on SLIP-0044) defines a standard for storing multi-chain addresses in ENS resolvers. Each chain is assigned a numeric coin type — Ethereum mainnet is 60, Bitcoin is 0, Solana is 501, and so on. L2s and EVM-compatible chains use a formula based on their chain ID: 0x80000000 | chainId.
Common Coin Types
- 0 — Bitcoin (BTC)
- 60 — Ethereum (ETH) — the default
- 501 — Solana (SOL)
- 2147483658 — Optimism (0x80000000 | 10)
- 2147492101 — Base (0x80000000 | 8453)
- 2147525809 — Arbitrum One (0x80000000 | 42161)
- 2147484614 — Polygon (0x80000000 | 137)
- 2147492936 — Linea (0x80000000 | 59144)
Querying Multi-Chain Addresses
Resolvio has a list of all supported chains with their coins and chain names
curl https://api.resolvio.xyz/ens/v2/chains
With Resolvio, pass the coinType or chain name parameter to resolve a name to any supported chain:
# Get specific addresses using coin type parameter (Ethereum, Bitcoin, Optimism, Base, Solana)
curl https://api.resolvio.xyz/ens/v2/addresses/vitalik.eth?coins=60,0,2147483658,2147492101,501
# Get specific addresses using chain name parameter (Ethereum, Bitcoin, Optimism, Base, Solana)
curl "https://api.resolvio.xyz/ens/v2/addresses/vitalik.eth?coins=eth,btc,opt,base,sol"
Getting Most Common Chain Addresses at Once
The profile endpoint returns most common stored addresses in a single call:
curl https://api.resolvio.xyz/ens/v2/profile/artii.eth
{
"name": "artii.eth",
"addresses": [
{
"coin": 60,
"chain": "eth",
"value": "0x1D84...c19f8",
"exists": true
},
{
"coin": 2147492101,
"chain": "base",
"value": "0x1D84...c19f8",
"exists": true
}
],
}
Building a Cross-Chain Payment Widget
Multi-chain resolution is essential for payment UX. When a user types an ENS name, your app can query all supported chain addresses and let them pick which network to send on:
const COIN_TYPES = {
ethereum: 60,
optimism: 2147483658,
base: 2147492101,
arbitrum: 2147525809,
} as const
async function getChainAddresses(ensName: string) {
const profile = await fetch(
`https://api.resolvio.xyz/ens/v2/profile/${ensName}`
).then(r => r.json())
return Object.entries(COIN_TYPES).reduce<Record<string, string | null>>(
(acc, [chain, coinType]) => {
acc[chain] = profile.coinAddresses?.[coinType] ?? null
return acc
},
{}
)
}
// Returns: { ethereum: "0x...", optimism: "0x...", base: null, arbitrum: "0x..." }
L2 Subnames and Multi-Chain
ENS is actively expanding to L2s. ENS names and subnames can be issued natively on chains like Linea and Base, with resolution handled by L2-aware resolvers. Resolvio handles these automatically — the same API call works regardless of whether the name's resolver is on mainnet or an L2.