我使用wagmi反应钩子来创建一个处理令牌允许和批准的自定义钩子。它返回一个对象,其中包含给定池的两个令牌的允许值,以及用于批准每个令牌的函数。目标是在每个令牌被批准后自动更新津贴金额,这样前端就可以相应地更新。看起来是这样的:
import {useState, useEffect} from 'react'
import {utils} from "ethers"
import {useAccount,useContract, useSigner, useWaitForTransaction, erc20ABI} from "wagmi"
function useAllowance(poolData) {
const [allowanceData, setAllowanceData] = useState({})
const [hash, setHash] = useState("")
const {data: signer} = useSigner();
const {address} = useAccount();
const amount = utils.parseEther("10000000");
const tokenA = useContract({
addressOrName: poolData.addressA,
contractInterface: erc20ABI,
signerOrProvider: signer
})
const tokenB = useContract({
addressOrName: poolData.addressB,
contractInterface: erc20ABI,
signerOrProvider: signer
})
const getAllowance = async() => {
let token1Allowance = await tokenA.allowance(address, poolData.address)
let token2Allowance = await tokenB.allowance(address, poolData.address)
setAllowanceData({
tokenA: token1Allowance,
tokenB: token2Allowance
})
}
const {isSuccess,isFetching,isLoading} = useWaitForTransaction({
hash: hash,
onSuccess(data, error) {
getAllowance()
console.log("error:", error)
console.log("data:", data)
},
})
const approveA = async () => {
const results = await tokenA.connect(signer).approve(poolData.address, amount);
setHash(results.hash)
}
const approveB = async () => {
const results = await tokenB.connect(signer).approve(poolData.address, amount)
setHash(results.hash)
}
useEffect(()=> {
getAllowance()
},[poolData.address])
return {allowanceData, approveA, approveB}
}
export default useAllowance我知道每个getAllowance函数都使用相同的哈希变量,所以如果用户快速调用这两个函数--第一个函数不会被等待--我想既然获得了这两种允许,这就不是什么大不了的事情了。不过,我可能会改的。而且我很确定这不是我的主要问题。
问题是,当getAllowance()在onSuccess函数中被调用时,备抵没有被更新,就好像onSuccess被过早地调用了一样?如果我立即刷新页面,则将更新备抵。我知道onSuccess之所以被调用是因为"error“被记录,并且是未定义的,并且”数据“被记录下来,并且具有所有的块信息,如blockHash、blockNumber、.effectiveGasPrice,...等。
我也尝试过这样做:
useEffect(()=> {
if(isSuccess) {
getAllowance()
}
},[isSuccess])但同样的事情也发生了。我甚至尝试添加几秒钟的时间延迟,如下所示:
useEffect(() => {
if(isSuccess) {
const timer = setTimeout(() => getAllowance(), 4000);
return () => clearTimeout(timer);
}
}, [isSuccess]);这似乎在很大程度上是可行的,但并不总是,也是最不优雅的做法。
我还尝试使用更多的wagmi挂钩,如:
const { config: tokenAConfig } = usePrepareContractWrite({
addressOrName: poolData.addressA,
contractInterface: erc20ABI,
functionName: 'approve',
args: [poolData.address, amount]
})
const { config: tokenBConfig } = usePrepareContractWrite({
addressOrName: poolData.addressB,
contractInterface: erc20ABI,
functionName: 'approve',
args: [poolData.address, amount]
})
const { write: approveA, isSuccess: tokenASuccess } = useContractWrite({
...tokenAConfig,
onSuccess() {
getAllowance()
}
})
const { write: approveB, isSuccess: tokenBSuccess } = useContractWrite({
...tokenBConfig,
onSuccess() {
getAllowance()
}
})但据我所知,我也有同样的问题。
我用的是铸造厂,我也试过
由于某种原因,在我之前构建这个项目时,这个钩子是正确工作的。我忘记了我当时是怎么写的,也可能是侥幸什么的,但这就是为什么我认为我在这里错过了一个小小的解决办法。
有人知道怎么回事吗?或者,如果你写了这样的钩子,你会怎么做?
谢谢!!
发布于 2022-12-21 18:22:32
你试过了吗
const results = await tokenA.connect(signer).approve(poolData.address, amount);
await results.wait()希望它能帮上忙
https://ethereum.stackexchange.com/questions/141613
复制相似问题