ERC-7831
DRAFT

Multi-chain addresses

Multi-Chain Addressing

Summary

Chain-specific address format that allows specifying both an account and the chain on which that account intends to transact. Chain-specific addresses take the form of user.eth:l2chain. The target chain is resolved using a registry stored on ENS.

Why It Matters

This address format ensures Ethereum addresses specify the chain of the recipient. This fits well in Ethereum's layer-2 roadmap to reduce user errors such as accidentally sending funds on the wrong chain, and for wallets to automatically bridge funds to the intended destination chain.

0/24
0 of 24 software wallets support ERC-7831

Software Wallets by ERC-7831 Support

Not Supported

Ambire

Not Supported
Browser Extension

Sources (3)

  • Ambire doesn't support ERC-7831 names.

    Browser extension fails to resolve an ERC-7831 name
    Browser extension fails to resolve an ERC-7831 name
  • Ambire supports sending funds to ENS names using onchain data.

    Browser extension looking up a recipient name
    useAddressInput.tsx L149 @3f6c7af
    40}: Props) => {...119  useEffect(() => {...145146    // Debounce domain resolving147    const timeout = setTimeout(() => {148      // Must be set here, not before the timer — guard on line 107 must only block re-runs while the Promise is in-flight, not during the debounce window.149      resolveDomain({ domain: trimmedAddress })150        .then((result) => {151          if (latestFieldValueRef.current !== fieldValue) return152          setAddressState({153            fieldValue,
    Browser extension uses the Ethereum RPC to look up ENS names
    EnsCompatibleResolver.ts L84-104 @1444b31
    39export abstract class EnsCompatibleResolver implements NameResolver {...80  requiredChainId(networkMode: NetworkMode): string | undefined {81    return this.chainId[networkMode]82  }8384  protected providerFor(ctx: ResolveContext) {85    return ctx.getProvider(this.chainId[ctx.networkMode])86  }8788  async resolve(domain: string, ctx: ResolveContext): Promise<ForwardResolution | null> {89    const provider = this.providerFor(ctx)90    if (!provider) return null9192    return resolveENSDomain({93      provider,94      domain,95      options: {96        universalResolverAddress: this.universalResolver,97        expiry: this.expiryConfig98          ? {99              baseRegistrar: this.expiryConfig.baseRegistrar,100              nameWrapper: this.expiryConfig.nameWrapper[ctx.networkMode]101            }102          : null103      }104    })105  }106107  async reverse(addresses: string[], ctx: ResolveContext): Promise<ReverseLookupResult> {108    const provider = this.providerFor(ctx)

MetaMask

Not Supported
Browser Extension & Mobile App

Uniswap Wallet

Not Supported
Browser Extension & Mobile App

Sources (2)

  • Entering an ENS name like vitalik.eth in the Send flow resolves it to the corresponding address, regardless of the destination chain.

    Uniswap Wallet Send flow resolving vitalik.eth to an address
    Uniswap Wallet Send flow resolving vitalik.eth to an address
  • getOnChainEnsFetch() builds an ethers JsonRpcProvider for Ethereum mainnet and performs every ENS lookup through provider.resolveName.

    api.ts L84-113 @da6d36f
    78}) {...80  const text = resolver?.getText(key)81  return text ?? null82}8384async function getOnChainEnsFetch(params: EnsLookupParams): Promise<string | null> {85  const { type, nameOrAddress } = params8687  const provider = createProvider({ chainId: UniverseChainId.Mainnet, rpcType: RPCType.Public })8889  if (!provider) {90    return null91  }9293  // Set ENS V2 tunneling batch gateway for CCIP-read tunneling for universal resolver94  const withTunnel = provider as providers.JsonRpcProvider & {95    setTunnelingBatchGateways?: (urls: string[]) => void96  }97  withTunnel.setTunnelingBatchGateways?.([ENS_TUNNELING_BATCH_GATEWAY])9899  switch (type) {100    case EnsLookupType.Name:101      return await getNameFetch(nameOrAddress, provider)102    case EnsLookupType.Address:103      return await getAddressFetch(nameOrAddress, provider)104    case EnsLookupType.Avatar:105      return await getAvatarFetch(nameOrAddress, provider)106    case EnsLookupType.Description:107      return await getTextFetch({ key: 'description', name: nameOrAddress, provider })108    case EnsLookupType.TwitterUsername:109      return await getTextFetch({ key: 'com.twitter', name: nameOrAddress, provider })110    default:111      throw new Error(`Invalid ENS lookup type: ${type}`)112  }113}114115function useEnsQuery(type: EnsLookupType, nameOrAddress?: string | null) {116  return useQuery(117    persistableQueryOptions<string | null>({

Rainbow

Not Supported
Browser Extension & Mobile App

Sources (6)

Rabby

Not Supported
Browser Extension & Mobile App

Sources (6)

  • Browser extension fails to resolve an ERC-7831 name

    Rabby doesn't support ERC-7831 names.

    Browser extension fails to resolve an ERC-7831 name
  • Rabby supports sending funds to ENS names using onchain data.

    Browser extension looking up a recipient name
    EnterAddress.tsx L157 @7794bfb
    85}) => {...146  const debouncedResolveEns = useMemo(147    () =>148      debounce(...152        }: {153          address: string;154          requestId: number;155        }) => {156          try {157            const result = await resolveEnsAddressByName(address, wallet);158            if (requestId !== ensRequestIdRef.current) {159              return;160            }161            setEnsResult(
    Browser extension uses the Ethereum RPC to look up ENS names
    ens.ts L14-31 @7794bfb
    10): Promise<{ addr: string; name: string } | null> => {11  const input = name?.trim();12  if (!input) return null;1314  const ethServerId = findChainByID(1)?.serverId || 'eth';15  const ensClient = createPublicClient({16    chain: mainnet,17    transport: custom({18      request: async ({ method, params }) =>19        wallet.requestETHRpc(20          {21            method,22            params: (params || []) as any[],23          },24          ethServerId25        ),26    }),27  });2829  try {30    const normalizedName = normalize(input);31    const addr = await ensClient.getEnsAddress({32      name: normalizedName,33    });34    if (!addr) return null;35    return {
    Mobile app looking up a recipient name
    EnterAddress.tsx L82 @784783c
    60}) => {...75  const debouncedResolveEns = React.useMemo(76    () =>77      debounce(78        async (79          value: string,80          callback: (result: { addr: string; name: string } | null) => void,81        ) => {82          const result = await resolveEnsAddressByName(value);83          callback(result);84        },85        500,86        { leading: false, trailing: true },
    Mobile app uses the Ethereum RPC to look up ENS names
    ens.ts L9-35 @784783c
    5import { normalize } from 'viem/ens';67const ethServerId = findChain({ id: 1 })?.serverId || 'eth';89const ensClient = createPublicClient({10  chain: mainnet,11  transport: custom({12    request: ({ method, params }) =>13      requestETHRpc(14        {15          method,16          params: (params || []) as any[],17        },18        ethServerId,19      ),20  }),21});2223export const resolveEnsAddressByName = async (24  name: string,25): Promise<{ addr: string; name: string } | null> => {26  const input = name?.trim();27  if (!input) {28    return null;29  }3031  try {32    const normalizedName = normalize(input);33    const addr = await ensClient.getEnsAddress({34      name: normalizedName,35    });36    if (!addr) {37      return null;38    }39    return {

Gem Wallet

Not Supported
Mobile App

Source

  • gemwallet.com

    Gem Wallet supports sending to ENS addresses, but users need to verify which chain they are using.

Daimo

Not Supported
Mobile App

Source

  • Daimo resolves plain ENS addresses by querying the ENS Universal Resolver Contract on L1 using the Viem library.

    viemClient.ts L128 @a960ddb
    90export class ViemClient {...120  getEnsAddress = memoize(121    async ({ name }: { name: string }): Promise<Address | null> => {122      try {123        const result = await this.extApiCache.get(124          "ens-get-addr",125          name,126          () => {127            console.log(`[VIEM] getEnsAddress for '${name}'`);128            return this.l1Client.getEnsAddress({ name }).then((a) => a || "");129          },130          24 * 3600131        );132        return !result ? null : getAddress(result);

Zerion

Not Supported
Browser Extension & Mobile App

Phantom

Not Supported
Browser Extension & Mobile App

Source

NuFi

Not Supported
Browser Extension

imToken

Not Supported
Mobile App

Source

  • support.token.im

    imToken supports ENS human-readable names and resolves them onchain before sending funds.

Base App

Not Supported
Mobile App

Unknown

PillarX

Unknown
Browser Extension & Mobile App

Safe

Unknown
Browser Extension & Mobile App

Zeus

Unknown
Desktop App
Browser Extension & Mobile App

OKX Wallet

Unknown
Browser Extension & Mobile App

Base App

Unknown
Browser Extension

Frame

Unknown
Browser Extension & Desktop App

WalletChan

Unknown
Browser Extension

Elytro

Unknown
Browser Extension & Mobile App

Family

Unknown
Mobile App
Browser Extension & Mobile App

Trust Wallet

Unknown
Browser Extension & Mobile App

Anon Wallet

Unknown
Browser Extension & Mobile App