My dev blog where I dive deep into TypeScript, Postgres, Data science, Infrastructure, Ethereum, and more...

Typed general ERC20 contract with Ethers.js and Typescript

18th Mar 2022

Ok, so you are using ethers.js to develop your app. You want to interact with an external ERC20 contract, and you want types.

This tutorial will show you how to get types in ethers.js for ERC20-contracts without running your own full development environments like Hardhat.

Creating a Contract with ethers.js

A suggested way to initialize a Contract with ethers.js for a specific method like balanceOf for an ERC-20 is this:

const provider = new providers.JsonRpcProvider(...);
const address = "0x...";
const abi = ["function balanceOf(address owner) view returns (uint256)"];

const erc20 = new ethers.Contract(address, abi, provider);

This will let you call erc20.balanceOf(...) and interact with the actual contract on chain.

It works, but the problem is that this approach does not provide typescript types.

No types!

How can we get the types?

One method is running a full developer environment like HardHat and use TypeChain to get the types. But to be fair, these approaches seem more geared towards usecases when you are writing your own solidity contracts, and not when you are just interfacing with generic ERC-20 contracts.

Getting a typed Contract with abi-types-generator

A simple way to get a typed ethers.js Contract is by generating the types from a standard ERC-20 json ABI.

  1. Download the generic erc20.abi.json and put it in your project
  1. Install ethereum-abi-types-generator as a dev-dependency
    1. yarn add ethereum-abi-types-generator --dev
  1. Run this command to create types
    1. npx abi-types-generator erc20.abi.json --provider=ethers_v5

Now you should see the types in an erc20.ts file in you project.

Go back to your code and do a few imports. Make sure to write as unknown as Erc20 to avoid type errors.

import * as erc20Abi from "./erc20.abi.json";
import { Erc20 } from "./erc20";

const erc20 = new ethers.Contract(
  address,
  erc20Abi,
  provider
) as unknown as Erc20;

And voila, now you have a properly typed generic ERC-20 contract for ethers.js.

const balance = await erc20.balanceOf(MY_WALLET);

console.log("balance: ", balance); // BigNumber { _hex: '0x06d1cee24e0209' ... }

Hope this helped!


Tools