Resolving ENS Usernames in React

An awesome part of using a dApp is the fact that you can connect your wallet and and be logged in or signed up for the application right away. The problem that this may bring is that wallets are this large string of alphanumeric characters and don't make the best usernames. See example below:

0xd2f8ed343386FB042178c7e133A837CB8043d0dc

Ew right? This isn't the greatest way of displaying a username. You could do something like create a form and ask for a preferred username or we could leverage the decentralized web and look at using existing ENS usernames in our applications.

Let's take a look at how we can do this using React and the Ethers library.

I started off by scaffolding out a react application using:

npx create-react-app

Then I installed a dependency I need using yarn. (You can use npm instead if you prefer).

yarn add ethers

Afterwards I went into App.js and got rid of everything inside the div and then imported the ethers library and useState from React to keep track of the username of the signed in person. If you want to code along with this blog then here is what my App.js looked like:

import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers';

function App() {
  const [name, setName] = useState("");
  return (
    <div className="App">
      <h1>{name}</h1>
    </div>
  );
}

export default App;

Not too much going on just yet. Let's add a button inside of our app div and give it a function that can execute on click.

<div className="App">
      <button className ="button" onClick={() => handleWalletConnect()}>connect</button>
      <h1>{name}</h1>
    </div>

So this handleWalletConnect function is going to accomplish a couple of things. We want to make sure we get access to the users wallet as well as their ens username if they have one. Here is the function which I'll break down line by line:

const [name, setName] = useState("");
  const handleWalletConnect = async () => {
    const { ethereum } = window;
    if(ethereum) {
      const provider = new ethers.providers.Web3Provider(ethereum)
      await provider.send("eth_requestAccounts", []);
      const signer = provider.getSigner()
      const address = await signer.getAddress()
      const ens = await provider.lookupAddress(address);
      if (ens !== null) {
        setName(ens)
      } else {
        setName(address)
      }
    } else {
      alert('no wallet detected!')
    }
  }

The first thing we're doing is destructuring the Ethereum object from the Window:

const { ethereum } = window

This is something that is injected into the window from a wallet like Metamask. As long as it exists we will continue on with the rest of our code, otherwise we want to alert the user that we aren't detecting any wallets in their browser.

Next up is creating a provider that will give us access to a lot of methods that makes our life easier.

const provider = new ethers.providers.Web3Provider(ethereum)

A provider is a nice little abstraction of the connection to the Ethereum network. We're leveraging the work that the nice folks at Ethers have already done for us instead of reinventing the wheel.

The first thing we want to do with our provider is ask for permission to connect to the users wallet which is taken care of with this line:

await provider.send("eth_requestAccounts", [])

This sends a request over to the wallet asking the user to allow connection with our dApp.

Next we want to get information about the user. We do this by creating a signer object:

const signer = provider.getSigner()

This gives us access to more methods like this handy one for getting the signer's address:

const address = await signer.getAddress()

Now in theory we have everything we need to start building out our dApp. We have the address but we want to make things a little more human readable. Our provider has a nice little method of doing a reverse lookup to see if the Ethereum address is linked to an ENS username and that's done in the line below:

const ens = await provider.lookupAddress(address)

This will return the ens username if it exists otherwise we will get back null. Now we can either set the name to be the username or just fall back to the address if they do not have an ens username.

Now that we can access our user's decentralized identity we can allow for a greater user experience instead of forcing our users to fill out yet another form on profile details for a new service.

The final code for this can all be found on this repository:

You can also watch a quick video of this tutorial below:

20