Ethers.js Node.js – Handling Missed Events Using Contract.on in a Backend

ethers.jsevents

I am using a default ethersjs provider with Infura and etherscan API keys to listen for a contract events with contract.on(event, listener) in a nodejs backend.
It misses some of the events (let's say 20% of them). For Example: It catches an event at block 29360900, misses one at block 29360920, and catches the next at block 29361056.
In my case I need to save every new emitted event on the backend almost immediately, so to use queryFilter on a bunch of blocks is not an option.

Can somebody suggest a possible solution?

Best Answer

I stumbled upon a related issue that addresses a broader scope of this problem. The challenge isn't isolated to websocket subscriptions for events, but actually pertains to the entire websocket communication process with web3 providers.

In essence, this affects all websocket provider interactions when using Ethers.js. The core of the problem seems to be a lack of an efficient reconnection mechanism in ethers.js. As a result, the connection might get interrupted or even miss certain events, especially during reconnection attempts.

Two potential solutions stood out from the discussions on the issue:

Manual Reconnection Enhancement: Enhance the existing WebSocket behavior by introducing a custom reconnection mechanism. A sample implementation is available here.

Using the Alchemy SDK: Alternatively, you can consider the Alchemy SDK. This SDK enhances the ethers.js WebSocket provider by integrating heartbeat checks. These checks ensure the WebSocket reconnects if the connection gets dropped. Moreover, it incorporates a backfill logic, ensuring that events missed during reconnections are still emitted. However, a potential limitation is the dependency on Alchemy provider services.

Additionally, I found a discussion about a similar problem when using Infura provider with web3. It can be helpful as well.

Related Topic