How to Integrate ENS Multi-Coin Support into Your Wallet (for Developers)

After announcing our multi-coin support during Devcon5, we quickly got it implemented into our ENS Manager.

It was not long before other wallets started supporting.

Developers can get up-to-date on the implementation details by reading the EIP, docs, and our address-encoder javascript library.

In this blog post, I will go through how we integrated the feature into our own app so that other developers can get an overall idea about how to integrate this new feature into their wallet.


Because this feature is brand new, many Ethereum libraries have not supported the feature yet (it is currently supported in ethers.js, go-ens, and ethereal).

To interact directly with the resolver contract, you can install our contract from npm and import the abi as follows.

import { abi } from '@ensdomains/resolver/build/contracts/Resolver.json'

Let’s look at the difference between setting/getting an Ethereum address and a different cryptocurrency address.

## getting and setting Ethereum Address
function addr(bytes32 node);
function setAddr(bytes32 node, address addr);
## getting and setting multicoin address
function addr(bytes32 node, uint coinType);
function setAddr(bytes32 node, uint coinType, bytes calldata a);

The big difference is that both getter and setter now takes coinTypeas an additional argument. Please also note that setAddr takes bytes rather than address.


address-encoder is a js library for encoding and decoding the record stored in ENS resolver. It has two functions, formatsByName and formatsByCoinType.

import { formatsByName, formatsByCoinType } from '@ensdomains/address-encoder';formatsByName['BTC']
{ coinType: 0, decoder: [Function],encoder: [Function],name: 'BTC' }
{ coinType: 0, decoder: [Function],encoder: [Function],name: 'BTC' }

From now on, we only use formatsByName.

Getting a list of supported coins

You may have your own list of coins to support. If you want to support any coins we support to decode/encode, you may construct the list of coins,

export const COIN_LIST = Object.keys(formatsByName)

Getting address

This is the super simplified version of our getAddr function on our UI React component.

At line 1, we are getting the coinType and encoder function. You will use the coinType and namehash to get a coin specific address from the Resolver contract.

At line 4, we return empty address before passing into encoder. If you pass an empty string to the decoder, it may throw an error for some coin types.

At line 5, you pass the binary representation of the address to encoder function to display as a text.

Setting Address

Here is another simplified version of our setAddr function.

As we did during getAddr, we bypass the decoder if the address is empty. You simply put the binary representation of the empty string at line 5.


It is important to validate the correct format for each coin type.

The address-encoder library simply throws an error if you pass invalid text.

In our case, we catch the error and display an error accordingly.

A note on BCH

In most cases, you would receive the same text if you decode and encode the text representation. However, Bitcoin cash works slightly differently (for the technical explanation, please refer to the “CashAddr” section of the EIP), and it returns the text representation with “bitcoincash” prefix when encoded into text. The below is the example of how text, binary(hex) and it’s encoded canonical version looks on for BCH (which you can find from the tests).


In this blog post, we went through what needs to be taken care of in terms of supporting our new multi-coin feature. It is fairly similar to how you set/get address except that you have to pass coinType. Also, you need to handle things a bit carefully when dealing with validation and an empty string.

As more libraries support the multi-coin feature, it will be easier for wallet providers to add the support.




News about the Ethereum Name Service (ENS) from the team building it. Follow this publication for the latest ENS developments.

Recommended from Medium

Creating a Blockchain distributed package manager for front-end enterprise CI/CD pipelines

No alt text provided for this image

How to create a webworkers driven multithreading App — Part 1

How I published my first NPM package.

Deploying React App

Hyperledger from Scratch- Part 2

Cloning of BigBasket website

Angular VS React

Ranked-Choice Voting Algorithms in JavaScript

Example ballot for Ranked-Choice Voting in New York City

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


More from Medium


Overview of Web3 😊

Web3 domains

An abstract image that depicts the complex connections of the internet.

Why Bridges Get Hacked?