Query ENS records using The Graph Network

Christopher Dro
Async
Published in
5 min readJan 14, 2022

It’s been a couple of years since I last experimented with anything blockchain related, but I finally got a chance over the holiday break to work with some of the popular tools that exist in the ecosystem and build something that I thought would be fun and a good learning experience.

There are plenty of articles out there that discuss the terms covered in this post in greater detail, so I’ll be keeping things more high level. To start, let’s go over what ENS and The Graph Network are and the role they play within the Ethereum ecosystem.

Ethereum Name Service (ENS)

ENS is a name and lookup service built on Ethereum. It operates on a system of dot-separated hierarchical names, similar to DNS. ENS allows users to convert their wallet addresses into human-readable addresses, aiming to make crypto more accessible to individuals.

There are two principal components: the registry, and resolvers.

The Registry consists of a single smart contract that maintains a list of all domains. Resolvers translate names into addresses based on the relevant standards.

Image Source: https://docs.ens.domains/

The Public Resolver implements the following EIPs and is a general-purpose resolver that is suitable for most common ENS use-cases.¹

  • EIP 137 — Contract address interface (addr()).
  • EIP 165 — Interface Detection (supportsInterface()).
  • EIP 181 — Reverse resolution (name()).
  • EIP 205 — ABI support (ABI()).
  • EIP 619 — SECP256k1 public keys (pubkey()).
  • EIP 634 — Text records (text()).
  • EIP 1577 — Content hash support (contenthash()).
  • EIP 2304 — Multicoin support (addr()).

For this post, we’ll be focusing on (EIP 634), retrieving text records, and (EIP 2304) for multi-coin wallet addresses.

The Graph (GRT)

The Graph is an indexing protocol that enables users to query networks such as Ethereum and IPFS using GraphQL. Anyone can create open APIs, called subgraphs, that enable data to be easily accessed. The Graph’s goal is to be the fastest, most reliable method of accessing data for the crypto economy.³

Fortunately for us, a subgraph already exists for ENS. Visit the ENS graph playground and test out the following query.

{
domains(where: { name: "nick.eth" }) {
owner {
id
}
name
resolver {
texts
coinTypes
}
}
}
ENS GraphQL Playground

The query results should look something like what is shown below. As mentioned earlier, we’ll be focusing on retrieving text records and multi-coin wallet addresses, and in order to do so, we’ll need the values in coinTypes and texts that are returned from the resolver.

coinType is the cryptocurrency coin type index from SLIP44.
text data may be any arbitrary string.

{
"data": {
"domains": [
{
"name": "nick.eth",
"owner": {
"id": "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5"
},
"resolver": {
"coinTypes": ["60"],
"texts": [
"email",
"url",
"avatar",
"com.twitter",
"com.github",
"com.discord",
"eth.ens.delegate",
"snapshot"
]
}
}

]
}
}

We can verify the information returned from our query by taking a look at nick.eth’s profile. Notice that there is only one wallet address set, and the text records that have values match the keys returned from our query results.

Now we need to figure out how to get the values for each record, but it seems like the payload returned from the resolver only provides the key of the fields that are set. A quick search on ENS’ discord server led me to the following message.

I spoke to @nick.eth . even though we do have these values, the recommended ways are to fetch the current values from smartcontract directly as some resolvers could return data dynamically which may be different from the one emitted by the event.

So we’ll do just that in the next section.

ENS Contract

Before starting to code anything, we can interact with ENS’ public resolver smart contract directly on Etherscan. In order to retrieve the data returned from the resolver types, we’ll utilize the following two read functions.

function addr(bytes32 node, uint coinType) // ENSIP-9function text(bytes32 node, string calldata key) ENSIP-5

Notice that both functions share the first param bytes32 node. This param is the output of the namehash function, used to uniquely identify a name in ENS.

In place of human-readable names, ENS works purely with fixed length 256-bit cryptographic hashes. In order to derive the hash from a name while still preserving its hierarchal properties, a process called Namehash is used.²

You can use either of the libraries below to convert a ENS domain name to the value needed for the nodeparam in our contract calls.

Try either one of these with Runkit and convert “nick.eth”.

Namehash nick.eth — 0x05a67c0ee82964c4f7394cdd47fee7f4d9503a23c09c38341779ea012afe6e00

Now, let’s hop back to Etherscan and test out the following two read functions.

function addr(bytes32 node, uint coinType)
function text(bytes32 node, string calldata key)

The values returned should correspond with what you see on the profile.

Note: Things get a bit more complicated when dealing with different coin type indexes. However, there is a library that helps with encoding/decoding addresses.

Using Ethers.js

We can interact directly with the smart contract or use the built in ENS Resolver. I opted to interact directly with the contract to get a better understanding of how things work and created a sandbox environment where you can do the same.

Building a browser extension had been on my to-do list for quite some time, so I decided to take everything I learned and build an extension that lets you lookup ENS names by highlighting the domain.

Feel free to reach out with any questions by posting a comment and stay tuned for more articles surrounding the Ethereum ecosystem.

Sources:

¹ https://docs.ens.domains/contract-api-reference/publicresolver
² https://docs.ens.domains/contract-api-reference/name-processing
³ https://thegraph.com/

Async builds high performance, reliable, and cost-effective applications by combining technical expertise and deep knowledge of industry trends.

For more information on development services, visit asy.nc

--

--