1

Is there an "optimal" way to listen to multiple smart contracts?

For example, listening to an event emitted by one smart contract in a useEffect:

    useEffect(() => {
        const provider = new ethers.providers.JsonRpcProvider();

        const contract = new ethers.Contract(contractAddress, contract.abi, provider);

        contract.on("SomeEvent", (_a, _b, _c) => {
            console.log({_a, _b, _c});
        });

        return () => {
            contract.removeAllListeners("SomeEvent");
        }
    }, [])

But what if I want to listen to 10 different contracts? This brute force approach lacks elegance:

    useEffect(() => {
        const provider = new ethers.providers.JsonRpcProvider();

        const contract_a = new ethers.Contract(contractAddress_a, contract.abi, provider);
        const contract_b = new ethers.Contract(contractAddress_b, contract.abi, provider);
        const contract_c = new ethers.Contract(contractAddress_c, contract.abi, provider);
        const contract_d = new ethers.Contract(contractAddress_d, contract.abi, provider);

        contract_a.on("SomeEvent", (_a, _b, _c) => {
            console.log({_a, _b, _c});
        });

        contract_b.on("SomeEvent", (_a, _b, _c) => {
            console.log({_a, _b, _c});
        });

        contract_c.on("SomeEvent", (_a, _b, _c) => {
            console.log({_a, _b, _c});
        });

        contract_d.on("SomeEvent", (_a, _b, _c) => {
            console.log({_a, _b, _c});
        });

        return () => {
            contract_a.removeAllListeners("SomeEvent");
            contract_b.removeAllListeners("SomeEvent");
            contract_c.removeAllListeners("SomeEvent");
            contract_d.removeAllListeners("SomeEvent");
        }
    }, [])

Especially if I wanted to listen to > 25 contract addresses at once.

3 Answers 3

1

Well, write over 25 contracts for listening event is very difficult for developers. I can understand you alpo. I think about the question a lot and decide to write my answer and I hope this would be helpful for you.

Anyway, you can not run a way from the normal way to listening events. You should create smart contract handler and set event listener to it. But you can do it a little bit easily. Please use loop.

If the smart contracts' ABI is different, please create over 25 ABI file and write them individually.

If the all ABI is same, then you just need to write only 1 ABI file.

And then please use this loop.

const smartContractAddresses = [
    "0x00asdf....asdf",
    "0x00fe.....asdfd",
    ...
    ...
];
let contracts = [];

for(let i = 0 ; i < 25; ++ i) {
    const contract = new ethers.Contract(smartContractAddresses[i], contract.abi, provider);
    contracts.push(contract);
    contracts[i].on("SomeEvent", (_a, _b, _c) => {
    console.log({_a, _b, _c});
});

...
}

Thanks

1

I use something like this:

const nEventListener= async (blockNumber) => {
    try {
            const nEvent= await contract.queryFilter(
                'eventName',
                blockNumber - 1,
                blockNumber                
            )
            console.log(nEvent)
    } catch (error) {
        console.log(error)
    } 
}

wss.on('block', async (blockNumber) => {
    await nEventListeners(blockNumber)
})

So i can listen to the as many events i want for that specific contract.

0

I created a similar piece of software recently, and you can find a sample of the code in my github repository:

https://github.com/BappaBanerjee/smart-contract-tracking/blob/main/api/routes/contract.route.js

1
  • Link only answers are discouraged. It is better to include the main ideas in the answer and use the link to expand the details.
    – Ismael
    Commented Mar 18 at 2:11

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.