React+ethers.js集成Metamask场景下页面刷新未签名交易处理方案咨询
问题解决方案
核心原因说明
你调用合约方法发起交易时,ethers会向MetaMask发送eth_sendTransaction RPC请求,该请求的回调生命周期和当前页面上下文完全绑定,页面刷新/组件销毁后上下文丢失,自然无法收到后续用户确认/拒绝的响应。MetaMask出于安全隔离设计,没有对外提供查询待签名交易、远程取消签名弹窗的开放接口,因此这个方向不可行。
可行解决方案
本地持久化待处理交易,页面重载后自动兜底校验
发起交易前,先将本次交易的核心特征(用户钱包地址、合约地址、调用方法标识、mint金额value、发起时的nonce值、发起时间戳)存入localStorage或IndexedDB,标记状态为pending。
页面初始化时,遍历本地存储中所有pending状态的交易:- 调用
eth_getTransactionCount获取当前用户的最新nonce,和交易发起时的nonce做对比,如果nonce已经被使用,说明该交易要么已经签名提交,要么已经被替换 - 扫描当前地址最近的 outgoing 交易,匹配和待处理交易特征一致的记录,若匹配到且交易已上链,直接执行后续的API上报逻辑
- 上报成功后删除本地对应的pending记录
- 调用
合约事件监听兜底
你的primeMint方法执行成功后一定会触发对应的合约事件(例如Minted事件),可在页面初始化时:- 从当前区块往前回溯N个区块(可根据你的业务平均出块速度设置,比如200个块),过滤出当前用户地址触发的对应合约事件
- 同时持续监听合约的实时事件,只要匹配到当前用户的mint事件,先校验是否已经上报过API,未上报则补走上报流程
这种方式可以完全覆盖用户跨页面、甚至跨设备确认交易的场景
调整现有代码逻辑减少一致性问题
你当前的代码将API请求放在try/catch外部,且没有做异常兜底,容易出现交易成功但上报失败的数据不一致问题,调整后的逻辑参考:
// 页面初始化时先执行兜底校验逻辑 useEffect(() => { checkPendingTransactions() listenMintEvents() }, [connectedAddress]) const handleMint = async () => { try { const price = await connectedContract.getMintPrice() const txKey = `pending_${connectedAddress}_${Date.now()}` // 发起交易前先存本地pending记录 const pendingTx = { address: connectedAddress, value: price.toString(), contract: connectedContract.address, method: 'primeMint', status: 'pending', timestamp: Date.now() } localStorage.setItem(txKey, JSON.stringify(pendingTx)) const transaction = await connectedContract.primeMint({ value: price }) // 拿到txHash后更新本地记录的txHash字段 pendingTx.txHash = transaction.hash pendingTx.status = 'pending_chain' localStorage.setItem(txKey, JSON.stringify(pendingTx)) const receipt = await transaction.wait() const blockNumber = receipt.blockNumber // 执行上报 await axios.post("http://localhost:5000/api/mints", { _id: connectedAddress, blockNumber: blockNumber, txHash: transaction.hash }) // 上报成功后删除本地pending记录 localStorage.removeItem(txKey) setState({ status: "Success", blockNumber, button: false }) } catch (err) { console.error(err) setState({ ...state, button: false }) } }
内容的提问来源于stack exchange,提问作者alexeiking
相关产品推荐
相关产品推荐

