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.

Resolver

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 coinType as an additional argument. Please also note that setAddr takes bytes rather than address.

address-encoder

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' }

formatsByCoinType['0']

{ 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.

Validation

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).

Summary

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.