5

What I would like to know is if there is a way to continuously listen for a single contract and fetch all the events emitted in real time. What I was able to find right now are ways of listening for only one event at a time in specific contract. To be more precise: I have a smart contract deployed in polygon testnet (mumbai), this is an upgradable contract that is connected to other contracts and as usual it emits events that I would like to capture. I use Alchemy as provider. Another fact that is not clear to me is why in polyscan the method in the event is listed like 0x40c10f19 and not with the name.

I also try to use this code before asking you guys of how to do this: `

filter = {
    address: CONTRACT_ADDRESS,
    topics:[
        utils.id("MarketItemCreated(address,uint256,address,uint256,uint256)"),
        utils.id("Transfer(address,address,address,uint256,uint256)")
    ]
}

provider.on(filter,(log,event)=>{
    console.log(log)
    console.log(event)
})

But when I actually interact with the contract I can't capture the events (the console.log does not display anything) but I can see the event in polyscan. I also try with by filtering only with the address without specifying the topic and I also try withproveder.once` but no way.

What am I doing wrong? or instead, What am I missing? every hints or contributions are appreciate :)

3
  • Hi, I know you asked about ethers.js, but would you be open to see an option with web3.js? It makes it pretty easy to do what you need I think. Commented Sep 9, 2022 at 10:35
  • Oh yeah sure it would be the same
    – colo
    Commented Sep 9, 2022 at 11:16
  • cool I'll place it in the answers! Commented Sep 9, 2022 at 12:29

2 Answers 2

2

Hi developer advocate at Chainstack here!

Web3.js has a subscriprion method to easily to that!

const Web3 = require("web3");

const node_url = "CHAINSTACK_WSS_URL";
const web3 = new Web3(node_url)

var logs = web3.eth.subscribe("logs", {
        address: "CONTRACT_ADDRESS",
        topics: []
    }, function(error, result) {
        if (!error)
            console.log(result);
    })
    .on("connected", function(subscriptionId) {
        console.log(subscriptionId);
    })
    .on("data", function(log) {
        console.log(log);
    })
    .on("changed", function(log) {});

Remember that you need a web-socket endpoint to use subscriptions in web3.js.

You can find more examples in the Chainstack docs API reference, and in the web3.js docs.

I hope this helps you!

2
  • Ok perfect it works properly! thank you :)
    – colo
    Commented Sep 12, 2022 at 9:56
  • yeah but the OP has specifically asked for ethers, not web3 ;S
    – scibuff
    Commented Sep 2, 2023 at 7:46
1

You can use couple of methods in ether.js to achieve the result.

I wrote a sample code to listen to the events from a particular contract by listening to the block mining event.

const { ethers } = require("ethers");
require("dotenv").config();

const { ALCHEMY_API_KEY } = process.env;

const provider = new ethers.providers.JsonRpcProvider(
  `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`
);
const abi = [
  "event Transfer(address indexed from, address indexed to, uint amount)", //Saved the erc20 transfer event ABI in an array form. Which is a great feature etherjs provides.
];

const address = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"; // Smartcontract address

const contract = new ethers.Contract(address, abi, provider); //creating a new contract instance by provding address, ABI, and provider.

const init = async () => {
  await provider.on("block", async (blockNumber) => {
    // This line of code listens to the block mining and every time a block is mined, it will return blocknumber.
    const transferEvent = await contract.queryFilter(
      //Simply used the queryfilter to listen to the transfer event everytime a block is mined.
      "Transfer",
      blockNumber - 1,
      blockNumber
    );

    console.log(transferEvent);
  });
};

init().catch((err) => {
  console.log(err);
  process.exit(1);
});

I wrote for goerli testnet but you can use the same for polygon too. All you need to do is to change the provider address and also create .env file and save your node provider api key there.

You can run the programing by running the command

node < name >.js

Finally, you can add as many event as possible in the ABI and write a queryfilter for the event.

This code is applicable to all ERC standards.

Tell me if it helps!

1
  • Yes works and it's super useful thank you! do you know how to create the topic list given the ABI? I mean if there is something in ethers that is able to, given the ABI, to create all the topics (so the events) automatically?
    – colo
    Commented Sep 12, 2022 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.