0x Typescript – Correct Usage of Expiry for NFT Swap SDK v4

0xtypescript

Creating a NFT trade order where the maker is selling a single 721 NFT, and the taker (same address as maker) is offering to buy it for eth. No matter what I set the expiry value to, the transactions fails when estimating gas. I can only get it to work when expiry is set to the default value of never expire– 2524604400

Here's a working example, minimally adapted from the nft trader sdk example—

export const nftSwapTestExample = async (
  provider: BaseProvider,
  signer: Signer,
  accountAddress: string,
  expiresInSeconds: number,
) => {
  // Scenario: User A wants to sell their CryptoPunk for 420 WETH
  const chainId = await signer.getChainId();
  // Set up the assets we want to swap (CryptoPunk #69 and 420 WETH)
  const CRYPTOPUNK: SwappableAssetV4 = {
    tokenAddress: '0xc3415e01ecd8021e1608fda6c7f7a75af0ed5be0',
    tokenId: '0',
    type: 'ERC721', // 'ERC721' or 'ERC1155'
  };

  const FOUR_HUNDRED_TWENTY_WETH: SwappableAssetV4 = {
    tokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // ETH contract address
    amount: ethers.utils.parseEther('0.0001').toString(),
    type: 'ERC20',
  };

  // [Part 1: Maker (owner of the Punk) creates trade]
  const nftSwapSdk = new NftSwapV4(provider, signer, chainId);
  const walletAddressMaker = accountAddress;

  // Approve NFT to trade (if required)
  const needsApproval = await nftSwapSdk.loadApprovalStatus(CRYPTOPUNK, walletAddressMaker);
  if (!needsApproval.contractApproved && !needsApproval.tokenIdApproved) {
    await nftSwapSdk.approveTokenOrNftByAsset(CRYPTOPUNK, walletAddressMaker);
  }

  const expiry = Math.floor(Date.now() / 1000 + expiresInSeconds);

  // Build order
  const order = nftSwapSdk.buildOrder(
    CRYPTOPUNK, // Maker asset to swap
    FOUR_HUNDRED_TWENTY_WETH, // Taker asset to swap
    walletAddressMaker,
    { expiry },
  );
  // Sign order so order is now fillable
  const signedOrder = await nftSwapSdk.signOrder(order);

  // [Part 2: Taker that wants to buy the punk fills trade]

  // Fill order :)
  const fillTx = await nftSwapSdk.fillSignedOrder(signedOrder);
  const fillTxReceipt = await nftSwapSdk.awaitTransactionHash(fillTx.hash);
  console.log(`🎉 🥳 Order filled. TxHash: ${fillTxReceipt.transactionHash}`);
};

// expires in 1 hour, fails
await nftSwapTestExample(provider, signer, 'address', 60*60);
// expires in 1 day, fails
await nftSwapTestExample(provider, signer, 'address', 60*60*24);

Best Answer

Thanks for the report. I fixed the buildOrder function to correctly support passing a raw unix timestamp for expiry. Please update to v0.21 when you get a chance!

Now expiry properly supports either a Date object or a unix timestamp (as a number type).

Related Topic