使用OpenSea API V2在Polygon链挂售NFT时遭遇无效签名错误
解决OpenSea API V2 Polygon网络NFT挂售订单无效签名问题
核心问题排查与修复
你的代码里存在几个明确错误,这些是导致无效签名的主要原因,逐一修复即可解决问题:
拼写错误
代码中constIdentifi seaport = new Seaport(signer);是笔误,多了Identifi字符串,修正为:const seaport = new Seaport(signer);API URL错误
孟买测试网的链标识符是maticmum,你写的maticIdentifi无效,正确的API地址应为:url: "https://api.opensea.io/v2/orders/maticmum/seaport/listings"Counter值硬编码错误
Counter是offerer的订单计数器,必须和链上记录的当前值一致,不能硬编码为0。正确获取方式:let counter = await seaport.getCounter(signer.address);ConduitKey格式错误
你的conduitKey混入了Detailed无效字符串,OpenSea默认的conduitKey应为:conduitKey: "0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000"TokenId(identifierOrCriteria)异常
你填写的identifierOrCriteria数值过大,不符合ERC721 TokenId的常规范围,替换为你的NFT实际TokenId的十进制字符串(比如TokenId是100就填"100")。签名前参数格式统一
当前先签名再修改参数格式会导致签名与提交参数不匹配,应先将所有BigNumber类型参数转成字符串,再传入signOrder方法。
修复后的完整代码
const axios = require("axios"); const { Seaport } = require("@opensea/seaport-js"); const ethers = require("ethers"); const signTran = async (customParam) => { const provider = new ethers.providers.JsonRpcProvider( "https://rpc-mumbai.maticvigil.com/" ); const signer = new ethers.Wallet( "metamask_account_private_key", provider ); // 修复拼写错误 const seaport = new Seaport(signer); // 修复:获取正确的counter值,而非硬编码0 let counter = await seaport.getCounter(signer.address); // 修复:先统一参数格式为字符串,再签名 const formattedParams = { ...customParam, startTime: customParam.startTime.toString(), endTime: customParam.endTime.toString(), totalOriginalConsiderationItems: customParam.totalOriginalConsiderationItems.toNumber(), counter: counter }; let signature = await seaport.signOrder(formattedParams, counter); const order = { parameters: formattedParams, signature: signature, }; const options = { method: "POST", // 修复API URL的链标识符 url: "https://api.opensea.io/v2/orders/maticmum/seaport/listings", headers: { accept: "application/json", "X-API-KEY": "98e3c67d43d74d66Identifi79df13456d4618a", "content-type": "application/json", }, data: order, }; await axios .request(options) .then(function (response) { console.log("getting response"); console.log(response.data); }) .catch(function (error) { console.log("------------------------------"); console.log("getting error"); console.error(error.response.data); }); }; const customParam = { offerer: "0xA29536981074C1B89e00D30f8238a7289b4213d6", zone: "0x0000000000000000000000000000000000000000", zoneHash: "0x0000000000000000000000000000000000000000000000000000000000000000", startTime: ethers.BigNumber.from(Math.floor(new Date().getTime() / 1000).toString()), endTime: ethers.BigNumber.from(Math.floor(new Date().getTime() / 1000 + 60 * 60).toString()), orderType: 1, offer: [ { itemType: 3, token: "0x2953399124F0cBB46d2CbACD8A89cF0599974963", // 修复:替换为你NFT的实际TokenId十进制字符串 identifierOrCriteria: "1", startAmount: "1", endAmount: "1", }, ], consideration: [ { itemType: 0, token: "0x0000000000000000000000000000000000000000", identifierOrCriteria: "0", startAmount: "48750000000000000", endAmount: "48750000000000000", recipient: "0xA29536981074C1B89e00D30f8238a7289b4213d6", }, { itemType: 0, token: "0x0000000000000000000000000000000000000000", identifierOrCriteria: "0", startAmount: "1250000000000000", endAmount: "1250000000000000", recipient: "0x0000a26b00c1F0DF0030003900271400Strict00fAa719", }, ], totalOriginalConsiderationItems: ethers.BigNumber.from("2"), salt: "123852146548", // 修复ConduitKey,移除无效字符串 conduitKey: "0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000", }; signTran(customParam);
额外注意事项
- 确认你的钱包地址(offerer)确实持有对应NFT,且已授权给OpenSea的Seaport合约(可通过调用
setApprovalForAll授权,或在OpenSea网页完成一次挂售操作自动授权)。 - 检查
X-API-KEY权限是否包含创建订单的权限。 - 若使用Polygon主网,将API URL的
maticmum改为matic,RPC节点换成主网节点(如https://polygon-rpc.com/)。
内容的提问来源于stack exchange,提问作者ibrahim Ramzan
相关产品推荐
相关产品推荐

