'Does approve take time to be confirmed, and how to deal with this in BSC?
Hi I am doing BSC DApp using web3 with react. I am very new to this field.
I found after call approve
, the transfer
(or zapInToken in my case) will not be successful with complaining not enough allowance. So I added wait allowance
to be present for 10s, but it seems in many times(50% chance) after 10s the allowance still not present. Please check the below code for more information.
Theoretically, approve
will generate a transaction and the time to be present depends. If it is the case, Is it a standard pattern to approve
, wait for allowance
and transfer
?
Thank you!
const bepContract = getContract(getAddress(from), erc20ABI, library, account)
const tx = await bepContract.approve(getAddress(contracts.zap), weiAmount)
if (!tx) {
throw new Error('Failed to approve transaction')
}
await waitAllowance(bepContract, account, getAddress(contracts.zap), weiAmount, 10) // <-- and it will stuck here in most time, the code waits for the allowance is present
await getZapContract().zapInToken(getAddress(from), weiAmount, getAddress(to)).then(logInfo).catch(logError)
And the waitAllowance is like below
const waitAllowance = async (
contract: Contract,
account: string,
to: string,
allowanceNeeded: string,
timesLeft: number
): Promise<void> => {
if (timesLeft > 1) {
const currentAllowance = await contract.allowance(account, to)
// console.log(`I want ${allowanceNeeded}, and current is ${currentAllowance} `)
const needed = new BigNumber(allowanceNeeded)
const current = new BigNumber(currentAllowance.toString())
if (current.isGreaterThanOrEqualTo(needed)) {
return
}
await new Promise((res) => setTimeout(res, 1000))
await waitAllowance(contract, account, to, allowanceNeeded, timesLeft - 1)
}
throw new Error('wait allowance failed for many times.')
}
Solution 1:[1]
I figured out, I need to tx.wait
, so the working code like below:
const bepContract = getContract(getAddress(from), erc20ABI, library, account)
const tx = await bepContract.approve(getAddress(contracts.zap), weiAmount)
if (!tx) {
throw new Error('Failed to approve transaction')
}
const tx = await waitAllowance(bepContract, account, getAddress(contracts.zap), weiAmount, 10)
const txResult = await tx.wait()
if (txResult.status !== 1) {
throw new Error('Failed approve')
}
const txZap = await getZapContract().zapInToken(getAddress(from), weiAmount, getAddress(to))
const txZapResult = await txZap.wait()
if (txZapResult.status !== 1) {
throw new Error('Failed zap')
}
Check this doc from more details
Solution 2:[2]
Hours of debugging and realised it is due to the Node I'm using. Changed from getblock
to Moralis
and worked
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ron |
Solution 2 | Nagibaba |