使用WalletConnect调用seaport-js完成订单时返回invalid hash但交易已上链
使用Seaport-JS实现NFT交换时,WalletConnect下出现哈希验证错误(交易已上链但报错)
排除Gas相关问题后,相同条件下通过MetaMask(window.ethereum)执行NFT订单完全正常,但使用WalletConnect时会返回INVALID_ARGUMENT错误,尽管交易已经在区块链上成功执行。错误源于ethers的哈希验证函数,该函数期望参数为字符串,但实际传入了Seaport的PopulatedTransaction对象,且仅在WalletConnect环境下触发。
Goerli测试网错误日志
Error: invalid hash (argument="value", value={"type":2,"chainId":5,"nonce":36,"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x3b9aca00"},"maxFeePerGas":{"type":"BigNumber","hex":"0x11b1f3f800"},"gasPrice":null,"gasLimit":{"type":"BigNumber","hex":"0x02d873"},"to":"0x00000000006c3852cbEf3e08E8dF289169EdE581","value":{"type":"BigNumber","hex":"0x00"},"data":"0xb3a34c4c0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000340000000000000000000000000ded5a05d7c7cdfff17aebf7ad5e847557cf087760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006454fb14ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094bcf1bbb4dbb19d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000007b9fd44513ef3a714614094963c6dc4cdfcc40cb000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000007b9fd44513ef3a714614094963c6dc4cdfcc40cb000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ded5a05d7c7cdfff17aebf7ad5e847557cf0877600000000000000000000000000000000000000000000000000000000000000403e9c390a362f7c1d0e8b777127bd42b8d9a3b2f64c87481b91d803d92a7510728167d1a3884c62003d14d82b4a96bb73517713ef91c2a2a3aa1022aae78bc247c5d24601","accessList":[],"hash":"0x18af833152c52860c2ace90f74badc966bfee7933ec0d8f4a3bf412ecee1c18b","v":0,"r":"0xbfed28e916aef948357dde16278a91afa777aba4bf3406250f4df792b4455a4d","s":"0x368a6113830320b128fbd336c39ef1c4288f119ba23ec6b97e93c31b6429df4e","from":"0x9cE9Bf1D83D5Fe99916Bf640A3615DB5e4A89fF0","confirmations":0}, code=INVALID_ARGUMENT, version=providers/5.7.2) at Logger.makeError (index.js:224:1) at Logger.throwError (index.js:233:1) at Logger.throwArgumentError (index.js:236:1) at Formatter.hex (formatter.js:175:1) at Formatter.hash (formatter.js:222:1) at Web3Provider.eval (base-provider.js:1659:30) at Generator.next (<anonymous>) at fulfilled (base-provider.js:5:43)
主网错误日志
Error: invalid hash (argument="value", value=[178,249,79,137,31,184,161,230,15,112,195,90,10,54,215,71,155,251,31,175,58,52,149,33,57,141,86,152,68,61,160,247], code=INVALID_ARGUMENT, version=providers/5.7.2) at Logger.makeError (index.js:224:1) at Logger.throwError (index.js:233:1) at Logger.throwArgumentError (index.js:236:1) at Formatter.hex (formatter.js:175:1) at Formatter.hash (formatter.js:222:1) at Web3Provider.eval (base-provider.js:1659:30) at Generator.next (<anonymous>) at fulfilled (base-provider.js:5:43)
实现代码
import { OrderComponents, OrderWithCounter } from "@opensea/seaport-js/lib/types"; import { ethers, providers } from "ethers"; import EthereumProvider from "@walletconnect/ethereum-provider"; export const fulfillSwapBySeaport = async ( swapSignature: string, swapParameters: OrderComponents, ethereumProvider: providers.ExternalProvider | EthereumProvider ): Promise<string | null> => { try { const provider = new ethers.providers.Web3Provider(ethereumProvider); const signer = provider.getSigner(); const account = await provider.listAccounts(); const fulfiller = account[0]; const seaport: Seaport = new Seaport(signer); const { executeAllActions: executeAllFulfillActions } = await seaport.fulfillOrder({ order: { parameters: swapParameters, signature: swapSignature, }, accountAddress: fulfiller, }); const transaction = await executeAllFulfillActions(); await transaction.wait(1); return transaction.hash; } catch (e: any) { console.log(e); return null; } };
问题分析
错误核心是ethers的哈希格式化函数期望接收字符串类型的哈希值,但WalletConnect返回的交易对象存在格式差异:
- Goerli测试网中,
transaction.hash是完整的交易对象而非字符串哈希 - 主网中,
transaction.hash是字节数组而非十六进制字符串
两者都不符合ethers的参数预期,导致验证失败;而MetaMask返回的交易对象中hash是标准十六进制字符串,因此无异常。
解决方案
1. 捕获错误并手动转换哈希格式
修改交易等待逻辑,针对WalletConnect的特殊哈希格式做兼容处理:
// 修改后的核心代码片段 const transaction = await executeAllFulfillActions(); try { await transaction.wait(1); } catch (waitError) { // 仅处理哈希验证相关的INVALID_ARGUMENT错误 if (waitError.code === "INVALID_ARGUMENT" && waitError.message.includes("invalid hash")) { let txHash: string = ""; // 处理测试网:交易对象嵌套hash字段的情况 if (typeof transaction.hash === "object" && transaction.hash.hash) { txHash = transaction.hash.hash; } // 处理主网:字节数组转十六进制字符串 else if (Array.isArray(transaction.hash)) { txHash = "0x" + transaction.hash.map(byte => byte.toString(16).padStart(2, '0')).join(''); } if (txHash) { return txHash; } } // 其他错误正常抛出 throw waitError; } return transaction.hash;
2. 升级依赖版本
检查ethers和WalletConnect Ethereum Provider的版本兼容性,尝试升级到最新稳定版,此类适配问题可能已被官方修复。
内容的提问来源于stack exchange,提问作者ru_sb
相关产品推荐
相关产品推荐

