How do I listen to events from a smart contract using ethers.js contract.on() in a node.js application?

Viewed 13132

I'm trying to listen to events emitted from the USDT contract Transfer function using ethers.js (not web3) in a node.js application.

When I run the script, the code runs with no errors and then quickly exits. I'd expect to get the event logs. I'm not sure what step I'm missing.

I've tested this script by calling the getOwner() method and console logging that result, this works fine, so my connection to mainnet is ok.

I'm using alchemy websocket.

My index.js file

const hre = require("hardhat");
const ethers = require('ethers');
const USDT_ABI = require('../abis/USDT_ABI.json')

async function main() {

const usdt = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
const provider = new ethers.providers.WebSocketProvider("wss://eth-mainnet.ws.alchemyapi.io/v2/MY_API");
const contract = new ethers.Contract(usdt, USDT_ABI, provider)

contract.on('Transfer', (from, to, value) => console.log(from, to, value))

}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });

My hardhat.config.js file


    require("@nomiclabs/hardhat-waffle");
require('dotenv').config()

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async () => {
  const accounts = await ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
 module.exports = {
  paths: {
    artifacts: './src/artifacts',
  },

  networks: {
    mainnet: {
      url: "wss://eth-mainnet.ws.alchemyapi.io/v2/MY_API",
      accounts: [`0x${process.env.PRIVATE_KEY}`]
    },
    hardhat: {
      chainId: 1337
    },
  },
  solidity: "0.4.8"
};`
2 Answers

I solved this by removing

.then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });

and just calling main. It's recommended in the hardhat docs to use the .then and .catch code but when running a long running process like this script does with contract.on(), it causes the script to exit.

I do this:

const ethers = require('ethers');
const abi = [{...}]
const contractAddress = '0x000...'

const webSocketProvider = new ethers.providers.WebSocketProvider(process.env.ETHEREUM_NODE_URL, process.env.NETWORK_NAME);
const contract = new ethers.Contract(contractAddress, abi, webSocketProvider);

contract.on("Transfer", (from, to, value, event) => {
        console.log({
            from: from,
            to: to,
            value: value.toString(),
            data: event
        });
    });

The event return all data related to event and transaction.

Related