Marketplace API
快速开始

快速开始#

使用订单 API 创建挂单#

在本指南中,我们将向你展示如何在 OKX 或 OpenSea 平台上创建挂单。该端点在单个请求中仅支持一个平台。此过程包括:

  • 设置你的环境
  • 构建及发送创建挂单请求。主要目的是为了获取订单信息和签名方式
  • 用挂单数据获取签名
  • 使用签名和订单数据构建及发送提交挂单,并获取成功消息

1. 设置你的环境#

设置环境,详情见导入必要的 Node.js 库

2. 构建及发送创建挂单请求#

步骤 1:构建标题参数。对于所有其他可重用参数,详情见设置你的环境变量

const requestUrl = 'https://www.okx.com/api/v5/mktplace/nft/markets/create-listing';
const chain = 'eth'; // we will use ethereum as example
const platform = 'okx'; // the platform you want to list on, for opensea use 'opensea'

const originalMessage = JSON.stringify({
    chain: chain,
    walletAddress: walletAddress,
    items:[
        {
            collectionAddress: '0x175edb154ed7a0e54410a7f547aaa7e3fbf21a34',  // the collection of nft you want to list
            tokenId: '3518',  // the token id of the nft from the collection
            price: '100000000000000',
            currencyAddress: '0x0000000000000000000000000000000000000000',  // ethereum main net token address
            count: 1,      // number of NFT
            validTime: 1701915719,  // listing expire time
            platform: platform  // support opensea or okx only
        }
    ]
});

const headersParams = {
  'Content-Type': 'application/json',
  'OK-ACCESS-KEY': apiKey,
  'OK-ACCESS-SIGN': cryptoJS.enc.Base64.stringify(
    cryptoJS.HmacSHA256(timestamp + 'POST' + '/api/v5/mktplace/nft/markets/create-listing' + originalMessage , secretKey)
  ),
  'OK-ACCESS-TIMESTAMP': timestamp,
  'OK-ACCESS-PASSPHRASE': passphrase,
};

步骤 2: 使用 headersParam 和 originalMessage 作为请求体,发送 create-listing 接口的请求

return fetch(requestUrl, {method: 'post',headers: headersParams,body: originalMessage}).then((res) => res.json()).then((res) => {return JSON.stringify(res);});

当您进行此请求时获取返回数据。主要目的是获取下面的订单数据,然后可以将其用于在 OKX 或 OpenSea 平台上提交列表。 步骤 3:从第 1 步的响应中提取订单数据并将其赋值给一个变量。

const contractMessage = {
  conduitKey: '0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000',
  consideration: [
    {
      endAmount: '900000000000000',
      identifierOrCriteria: '0',
      itemType: 0,
      recipient: '0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf',
      startAmount: '900000000000000',
      token: '0x0000000000000000000000000000000000000000'
    },
    {
      endAmount: '100000000000000',
      identifierOrCriteria: '0',
      itemType: 0,
      recipient: '0x93162ca0806ec2876b7ec12002596e40549c3e02',
      startAmount: '100000000000000',
      token: '0x0000000000000000000000000000000000000000'
    }
  ],
  counter: '948892694796415917080870615203989852295',
  endTime: 1701915719,
  offer: [
    {
      endAmount: '1',
      identifierOrCriteria: '3518',
      itemType: 2,
      startAmount: '1',
      token: '0x175edb154ed7a0e54410a7f547aaa7e3fbf21a34'
    }
  ],
  offerer: '0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf',
  orderType: 2,
  salt: '0x000000000000000000000000000000000000000000000000aea3b979de6e4aef',
  startTime: 1701310920,
  totalOriginalConsiderationItems: 2,
  zone: '0x2de95b9afd737b0814e5e6013593a9437c5532d5',
  zoneHash: '0x0000000000000000000000000000000000000000000000000000000000000000'
}

3. 使用订单数据创建签名#

步骤 1:参考第 2 部分第 2 步收集订单信息

const jsonMessage = JSON.stringify({
    domain: {
      // Defining the chain aka testnet or Ethereum Main Net
      chainId: 1, // 1 for mainnet
      // Give a user friendly name to the specific contract you are signing for.
      name: "Seaport",
      // If name isn't enough add verifying contract to make sure you are establishing contracts with the proper entity
      verifyingContract: "0x00000000000000adc04c56bf30ac9d3c0aaf14dc",
      // Just let's you know the latest version. Definitely make sure the field name is correct.
      version: "1.5",
    },

    // Defining the message signing data content.
    message: contractMessage,
    // Refers to the keys of the *types* object below.
    primaryType: "OrderComponents",
    types: {
        ConsiderationItem: [
            { name: 'itemType', type: 'uint8' },
            { name: 'token', type: 'address' },
            { name: 'identifierOrCriteria', type: 'uint256' },
            { name: 'startAmount', type: 'uint256' },
            { name: 'endAmount', type: 'uint256' },
            { name: 'recipient', type: 'address' }
          ],
          OrderComponents: [
            { name: 'offerer', type: 'address' },
            { name: 'zone', type: 'address' },
            { name: 'offer', type: 'OfferItem[]' },
            { name: 'consideration', type: 'ConsiderationItem[]' },
            { name: 'orderType', type: 'uint8' },
            { name: 'startTime', type: 'uint256' },
            { name: 'endTime', type: 'uint256' },
            { name: 'zoneHash', type: 'bytes32' },
            { name: 'salt', type: 'uint256' },
            { name: 'conduitKey', type: 'bytes32' },
            { name: 'counter', type: 'uint256' }
          ],
          EIP712Domain: [
            { name: 'name', type: 'string' },
            { name: 'version', type: 'string' },
            { name: 'chainId', type: 'uint256' },
            { name: 'verifyingContract', type: 'address' }
          ],
          OfferItem: [
            { name: 'itemType', type: 'uint8' },
            { name: 'token', type: 'address' },
            { name: 'identifierOrCriteria', type: 'uint256' },
            { name: 'startAmount', type: 'uint256' },
            { name: 'endAmount', type: 'uint256' }
          ]
    },
  });

步骤 2:使用您的私钥对订单数据进行签名。注意:您可以使用其他工具来帮助您使用 eth_signTypedData_v4 方法生成签名。

// here we will use okx wallet utils with your private key and the message to do a signature
const param = {
    privateKey: privateKey,
    data: {
      type: 4,
      message: jsonMessage
    }
  };

return wallet.signMessage(param).then(res => console.log(res)); // here you will get a hex signature

之后,您将获得一个基于订单数据和钱包地址的签名,我们将在下一步中使用该签名。

4. 使用签名和订单数据构建及发送提交挂单,并获取成功消息#

步骤 1:从 contractMessage 中获取 data 并将其放入请求中,以订单为键,contractMessage 为值。替换签名和钱包地址,形成你的 submit listing 请求。

const submitListingBody = JSON.stringify({
    chain: "eth",
    walletAddress: '0xa03bb8d...dds'; // this is your wallet address
    items: [
        {
            platform: "okx",
            signature: "0xf41ef.....9acc727631b", // signature returned #from Create a signature with the order data. Step 2
            order: {  // put the contractMessage data here
                conduitKey: "0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000",
                consideration: [
                    {
                        endAmount: "1",
                        identifierOrCriteria: "5313",
                        itemType: 2,
                        recipient: "0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf",
                        startAmount: "1",
                        token: "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
                    }
                ],
                counter: "948892694796415917080870615203989852295",
                endTime: 1703301107,
                offer: [
                    {
                        endAmount: "1000000",
                        identifierOrCriteria: "0",
                        itemType: 1,
                        startAmount: "1000000",
                        token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                    }
                ],
                offerer: "0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf",
                orderType: 0,
                salt: "0x0000000000000000000000000000000000000000000000002baea915c4bcf7be",
                startTime: 1700709107,
                totalOriginalConsiderationItems: 1,
                zone: "0x0000000000000000000000000000000000000000",
                zoneHash: "0x0000000000000000000000000000000000000000000000000000000000000000"
            }
        }
    ]
}

步骤 2: 为新请求构建一个新的标题参数

const submitListingRequestUrl = 'https://www.okx.com/api/v5/mktplace/nft/markets/submit-listing'; // new endpoint for submitting listing
const submitListingTimestamp = date.toISOString();
const submitListingHeadersParams = {
  'Content-Type': 'application/json',
  'OK-ACCESS-KEY': apiKey,
  'OK-ACCESS-SIGN': cryptoJS.enc.Base64.stringify(
    cryptoJS.HmacSHA256(submitListingTimestamp + 'POST' + '/api/v5/mktplace/nft/markets/submit-listing' + submitListingBody, secretKey)
  ),
  'OK-ACCESS-TIMESTAMP': submitListingTimestamp,
  'OK-ACCESS-PASSPHRASE': passphrase,
};

步骤 3: 发送 POST 请求到 /submit-listing 接口

return fetch(submitListingRequestUrl, {method: 'post', headers: submitListingHeadersParams, body: submitListingBody}).then((res) => res.json()).then((res) => {return res;});

最后,您应该看到成功等于 true 的消息。

{
    "code": 0,
    "data": {
        "results": [
            {
                "message": "",
                "order": {
                    "conduitKey": "0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000",
                    "consideration": [
                        {
                            "endAmount": "1",
                            "identifierOrCriteria": "5313",
                            "itemType": 2,
                            "recipient": "0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf",
                            "startAmount": "1",
                            "token": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"
                        }
                    ],
                    "counter": "948892694796415917080870615203989852295",
                    "endTime": 1703301107,
                    "offer": [
                        {
                            "endAmount": "1000000",
                            "identifierOrCriteria": "0",
                            "itemType": 1,
                            "startAmount": "1000000",
                            "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                        }
                    ],
                    "offerer": "0xa03bb8d8099c994ed87361f5c9857e13fc7c5ccf",
                    "orderType": 0,
                    "salt": "0x0000000000000000000000000000000000000000000000002baea915c4bcf7be",
                    "startTime": 1700709107,
                    "totalOriginalConsiderationItems": 1,
                    "zone": "0x0000000000000000000000000000000000000000",
                    "zoneHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
                },
                "platform": "okx",
                "signature": "0xf41ef8e......c4a9acc727631b",
                "success": true
            }
        ]
    },
    "msg": ""
}