9

I have an event set up in the Contract.

Contact Packages
   emit Spend(msg.sender, msg);

function sendPackage(msg) external payable returns(bool) { require( msg.value == price, 'Please send the correct amount of ETH to make send a message' );

 emit Spend(msg.sender, msg);
 return true;

}

And a script in NodeJS that listens to new events.

The intention is to kick off some NodeJS code whenever a new event on the contract takes place.

But whenever I start the script, the Contract.on(.. fires and the last event is passed to it, even though the event fired a hour ago.

Is there a way to config the callback to NOT include previous events?

  Contract.on('Spend', (sender, event) => {
    console.log(sender);
    console.log(event);
  });

EDIT

I've tried to use Contact.once and the same result occurs.

GN.
  • 643
  • 2
  • 8
  • 20
  • 1
    Hey did you find a solution to this? I am facing the same problem. It always returns the last event no matter when it was fired. – navneetgulati Apr 26 '21 at 11:42

3 Answers3

1

get the startblock number from provider

const startBlockNumber = await provider.getBlockNumber();

then check that with the blocknumber recieved from event.

Full code:

const startBlockNumber = await provider.getBlockNumber();
provider.once("block", () => {
    transactionsContract.on(
        "Transfer",
        (from, to, amount, timestamp, message, blockNumber) => {
            if (blockNumber <= startBlockNumber) {
                console.log("old event");
                return;
            }
            console.log({
                from,
                to,
                amount,
                timestamp,
                message,
                blockNumber,
            });
        }
    );
});
Antonio Carito
  • 2,445
  • 3
  • 10
  • 23
Rashid P
  • 11
  • 1
1

I do this:

const eventListener = async (blockNumber) => {
    try {
        const contractInstance = new ethers.Contract(address, ctt.abi, provider)
        const event = await contractIntance.queryFilter('EventName', blockNumber - blockNumberN, blockNumber);
        console.log(event);
    }
    catch (error) {
        console.log(error);
    }
};

wssProvider.on('block', async (blockNumber) => { await eventListener(blockNumber) })

Rodrigo Burgos
  • 764
  • 3
  • 15
1

I don't know about ethers.js but you can use web3.js as follows

Create an instance of your contract

var contract = new web3.eth.Contract(ABI_of_contract, address_of_contract);

and then listen for new events

contract.events.Spend({
  fromBlock: 'latest'
  }, function(error, event){
      console.log(event);
  });

Note that fromBlock: 'latest' is needed to load only new events. If you use 'earliest' instead, you will get all past events as well (maybe there is such an option in ethers.js)

Peri Kost
  • 172
  • 4