Fulfill Listings

Gas Estimation

GoTrading provides the most efficient gas-saving solution available. Our transaction routing mechanism directs purchase transactions to different contracts based on the specific composition of the listings' marketplaces. For instance, if a purchase includes only OpenSea's listings, we route it directly to the Seaport contract rather than our Aggregator contract, resulting in lower gas costs.

We simulate every purchase transaction on the mainnet at the latest block before returning it to ensure the transaction's validity(this will make our gas estimation the most accurate), and we achieve the lowest gas cost compared to other viable purchase transaction solutions.

For Dapp Developers

For Dapp developers, the easiest strategy to integrate an NFT Aggregator into your product is outlined below.

Initialize the Aggregator Instance with configuration as you boot up your server end.

// Server-end code
import { init } from '@nftgo/gotrading';
import Web3 from 'web3';

const configs = {
  apiKey: "xxx", // Replace with your Developer API Key.
};

// Init GoTrading instance.
const goTrading = init({
    apiKey: "xxx", // Replace with your Developer API Key.
});

Bulk Buy by NFTs

1. A user visits an NFT Collection page

When a user visits an NFT Collection page, you are likely to present them with an NFT gallery for all the NFTs under the collection. Along with these NFTs you can display the best listings across various marketplaces.

Your client-end application should invoke your server-end application API to retrieve a number of NFTs once the user enters this page. And your server-end can just leverage GoTrading.orderFetcher.getOrdersByNFT method to build this feature just like our NFTGo main site.

// Server-end code

// Retrieve the best listings of NFTs under the Collection
// Bored Ape Yacht Club contract address.
const baycContract = "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D";


// You can request multiple NFTs' orders in parallel
const { listingDTOs } = await goTrading.orderFetcher.getOrdersByNFT({
  contractAddress: baycContract,
  orderType: OrderType.Listing,
  tokenId: '1',
});

Your server-end needs to ensure that the orderId of the listing is returned to the client-end, as this parameter is necessary for the purchase.

2. The user chooses multiple NFTs to purchase

Your client-end should build the Trading Cart feature to temporarily store the user's selected listings. Once the user has made the purchase decision and clicks the Buy Now Button. Your client-end should pass the orderIds of these listings to your server-end application.

Your server-end application should then invoke the GoTrading.aggregator.fulfillListings method by passing the orderIds.

// Server-end code

const orderIds = ["orderIds"]; // Replace with the listings' orderIds

const { actions } = await goTrading.aggregator.fulfillListings({
    buyer: 'xxx', // Buyer wallet address
    orderIds: listingDTOs.map(listingDTO => order.orderId),
})

Next, your server-end application should return the actions back to the client-end application, it's most likely that only one transaction action is returned, which will then trigger the MetaMask popup for the user. Once the user confirms the transaction, it will be sent to the Ethereum network, completing the purchase.

// Client-end code

const txAction = actions[0];

web3.eth.sendTransaction({
    data: txAction.data.txData.data,
    value: txAction.data.txData.value,
    from: txAction.data.txData.from,
    to: txAction.data.txData.to,
})
.on('transactionHash', function(hash){
  ...
})
.on('receipt', function(receipt){
  ...
})
.on('confirmation', function(confirmationNumber, receipt){ ... })
.on('error', console.error); // If a out of gas error, the second parameter is the receipt.

Complete Sequence Diagram

For Auto Trading&Market Makers

For NFT Market Makers running server-end applications, who are looking to streamline NFT trading across various marketplaces, the following best practices are recommended.

Please note: All code examples provided below are written for a Node.js environment in Typescript.

Bulk Buy by Contract

If you're targeting a specific Collection and aim to sweep the cheapest listings on any marketplace, consider following the recommended approach below

1. Initiate the GoTrading Instance with the appropriate configuration as you boot up your server-end application.

import { init } from '@nftgo/gotrading';
import Web3 from 'web3';

// Create a new Web3 Provider to interact with the Ethereum network.
const provider = new Web3.providers.HttpProvider('https://mainnet.infura.io') //Replace with your own provider


// To use GoTrading SDK, just set the given NFTGo API Key, 
// a Web3Provider for Ethereum interaction, and a wallet 
// address with its private key for NFT transactions.
const configs = {
  apiKey: "YOUR-API-KEY", // Replace with your own API Key.
  web3Provider: provider,
  walletConfig: {
    address: "Your wallet address",
    privateKey: "Your private key"
  }, // Replace with your wallet info.
};

// Create a GoTrading instance.
const goTrading = init(configs);

2. Purchase the targeted Collection in one go.

You can simply fetch the listings of the Collection, the orderFetcher will return listings sorted by prices in ascending order.

import { OrderType, MarketId } from '@nftgo/gotrading';

const RivermenContract = "0xcfff4c8c0df0e2431977eba7df3d3de857f4b76e"

const { listingDTOs } = await goTrading.orderFetcher.getOrdersByContract({
    contractAddress: RivermenContract,
    orderType: OrderType.Listing,
})

// applies your customized business logic to filter your intented listings
const listingsToPurchase = listingDTOs
    .filter(listingDTO => listingDTO.marketId === MarketId.Opensea)
    .map(listingDTO => listingDTO.orderId);


const res = await goTrading.aggregator.fulfillListings(listingsToPurchase);
const { executeActions } = res;
await executeActions({
  onTaskExecuted: task => {
    console.info(task); // Callback function when a transaction is finished.
  },
});

Complete Sequence Diagram