Ethers.js: How to wait for certain number of confirmations ?

Created on 13 Jul 2018  路  10Comments  路  Source: ethers-io/ethers.js

Sometimes geth node returns nonce too low when sending transactions in succession. so if we can wait for certain number of confirmations, this problem can be solved

enhancement

Most helpful comment

This is something I've been thinking of adding for a while, so I will add it next week to the v4 branch.

I have a few ideas on how to add it to the API, but will experiment this weekend with a few options.

All 10 comments

This is something I've been thinking of adding for a while, so I will add it next week to the v4 branch.

I have a few ideas on how to add it to the API, but will experiment this weekend with a few options.

This weekend was spent entirely just refactoring and getting the TypeScript definitions all cozy, but I think things are starting to settle, so I will be able to get to this soon. :)

aside: There was also a crazy bug in nodejs that causes it to sort Japanese strings in a different order than browsers, but that is fixed now too. And not all BIP39 wordlists do a final sanity check after loading, and fail loud if the checksum doesn't match the derived wordlist.

This has been added in 4.0.3.

On the TransactionsResponse wait method, confirmations can be passed 脿 la tx.wait(confirmations), which will return the TransactionReceipt, similarly provider.waitForTransaction(confirmations) will do the same.

Thanks! :)

Is there any chance this will be rewritten to return something like web3's promievent (https://www.npmjs.com/package/web3-core-promievent)? I'd need to be notified about each new confirmation as well as about chain re-organisations, which might lower the # of confirmations or even set it to 0.
Currently, I don't see a clear path how I could accomplish this. Should I just do a provider.getTransactionReceipt(hash) periodically and watch for the confirmations property - and if that returns null assume the tx being erased from the chain due to a reorg?

No, I those Prominevent things seem crazy to me. :p

You could exactly do as you describe:

Example:

let tx = contract.someFunction(params);

let lastConfirms = -1;
async function handler(blockNumber) {
    let receipt = await provider.getTransactionReceipt(tx.hash);
    if (receipt == null || receipt.confirmation < lastConfirms) {
        // A re-org; do what you need here
    }
}
provider.on("block", handler);

tx.wait(3).then((receipt) => {
    // This gets called once there are 3 confirmations
    provider.removeListener("block", handler);
});

In v5, this will be much easier, since you can just use provider.on("fork") or use a more complex event:

let forkEvent = new ForkEvent();

// Trigger if the block is orphaned
forkEvent.watchBlock(hash);

// Trigger if the confirmations ever lower
forkEvent.watchTransaction(hash);

// Trigger if the block hash (once set) changes
forkEvent.watchTransactionBlock(hash);

// Trigger if the transaction does not happen after other
formEvent.watchTransactionAfter(hash, otherHash);

provider.on(forkEvent, (event) => {
})

This API is still experimental, and I'm working on it now. :)

Hi Richard,
could receipt == null not also mean "hasn't been mined yet"? So probably the condition should be if (lastConfirms > 0 && (receipt == null || receipt.confirmations < lastConfirms)), shouldn't it?

The capabilities of the v5 API are looking promising. I'm very delighted at it :)

Thanks for your constant support and development on this project! :+1:

Just found this closed issue and am thrilled there's already some thinking around it!

What would you recommend is the best way these days, given this is a year-and-a-half old, to wait to parse a transaction once a certain number of confirmations are hit, without blocking the rest of the program?

Obviously, tx.wait(n) is the right way to do this, but how to combine with a contract listener with filter?

Does this make sense?:

contract.on(filter, (from, to, value, event) => {
    parseTransaction(event);
});

parseTransaction = async (transaction) => {
    const tx = await transaction.getTransaction();
    tx.wait(5);
    ...
}

@EvilJordan

Something like that would work fine, or you could use await provider.waitForTransaction(event.transactionHash, 5);

It probably makes sense for me to add confimarions to the event.getTransactionReceipt in v6... I鈥檒l add it to my todo list. :)

It works! Happy New Year! 馃コ

Was this page helpful?
0 / 5 - 0 ratings

Related issues

naddison36 picture naddison36  路  3Comments

adamdossa picture adamdossa  路  3Comments

dagogodboss picture dagogodboss  路  3Comments

GFJHogue picture GFJHogue  路  3Comments

pcowgill picture pcowgill  路  3Comments