With NFT Swap SDK
@johnjohnson
matcha.xyz
0x Project
trader.xyz
Where are we today?
social media (twitter)
nft communities
nft communities (cont'd)
wallets
NFT swapping functionality
unlocks value in your dapp
multichain
order persistance
protocol development
orderbook
searching
and filtering
security
nft indexing
gas costs
optimization
frontend contract integration
adding protocol
features
order management
The cheapest way to swap NFTs on Ethereum
yarn add @traderxyz/nft-swap-sdk
import { Web3Provider } from '@ethersproject/providers';
import { NftSwapSdkV4 } from '@traderxyz/nft-swap-sdk';
const provider = new Web3Provider(window.ethereum);
const signer = provider.getSigner();
const swapSdk = new NftSwapSdkV4(provider, signer);
sounds good!
send me the offer and i'll accept
I'd like to buy your CryptoCoven for $5,000
sounds good! send me the offer and i'll accept
I'd like to buy your CryptoCoven for $5,000
5000 USDC
Coven #9757
sounds good! send me the offer and i'll accept
I'd like to buy your CryptoCoven for $5,000
5000 USDC
Coven #9757
sounds good! send me the offer and i'll accept
I'd like to buy your CryptoCoven for $5,000
5000 USDC
Coven #9757
sounds good! send me the offer and i'll accept
I'd like to buy your CryptoCoven for $5,000
5000 USDC
Coven #9757
5000 USDC
Coven #9757
5000 USDC
Coven #9757
const order = {
nftToken: '0x5180',
nftTokenId: '9757',
erc20Token: '0xa0b8',
erc20TokenAmount: '5000000000',
maker: '0x1a3b...',
direction: '0',
nonce: '0x4206...',
};
5000 USDC
Coven #9757
const signedOrder = {
nftToken: '0x5180',
nftTokenId: '9757',
erc20Token: '0xa0b8',
erc20TokenAmount: '5000000000',
maker: '0x1a3b...',
direction: '0',
nonce: '0x4206...',
signature: '0x12345678',
};
Once signed, this order can be filled by the other party
5000 USDC
Coven #9757
const signedOrder = {
nftToken: '0x5180',
nftTokenId: '9757',
erc20Token: '0xa0b8',
erc20TokenAmount: '5000000000',
maker: '0x1a3b...',
direction: '0',
nonce: '0x4206...',
signature: '0x12345678',
};
nftSwap.fillSignedOrder(signedOrder)
5000 USDC
Coven #9757
const signedOrder = {
nftToken: '0x5180',
nftTokenId: '9757',
erc20Token: '0xa0b8',
erc20TokenAmount: '5000000000',
maker: '0x1a3b...',
direction: '0',
nonce: '0x4206...',
signature: '0x12345678',
};
nftSwap.fillSignedOrder(signedOrder)
5000 USDC
Coven #9757
Bid on an NFT
Bid on an NFT
Bid on an NFT
Bid on an NFT
// Create the 0x order
const order = nftSdk.buildOrder(
// I will offering an ERC20 (5,000 of USDC)
{
type: "ERC20",
tokenAddress: "0x31f42841c2db5173425b5223809cf3a38fede360",
amount: "500000000000000", // 5000 USDC (5000 * 6 decimals)
},
// I am receiving an NFT (CryptoCoven #9757)
{
type: "ERC721",
tokenAddress: "0x5180db8f5c931aae63c74266b211f580155ecac8",
tokenId: "9757",
},
// My wallet address
"0xabc23F70Df4F45dD3Df4EC6DA6827CB05853eC9b"
);
// User signs order with their wallet
const signedOrder = await nftSdk.signOrder(order);
// Share order to the orderbook so it can be discovered and used in your app
const postedOrder = await nftSdk.postOrder(signedOrder, CHAIN_ID);
Bid on an NFT
Bid on an NFT
// Search the orderbook for all offers to buy this NFT (CryptoCoven #9757)
const orders = await nftSwap.getOrders({
nftToken: "0x5180db8f5c931aae63c74266b211f580155ecac8",
nftTokenId: "9757",
sellOrBuyNft: "buy", // Only show bids (offers to buy) for this NFT
});
// Or search for a specific order by nonce
const orders = await nftSwap.getOrders({
nonce: "0x31f42841c2db5173425b5223809cf3a38fede360",
});
const foundOrder = orders[0];
Bid on an NFT
// Search the orderbook for all offers to buy this NFT (CryptoCoven #9757)
const orders = await nftSwap.getOrders({
nftToken: "0x5180db8f5c931aae63c74266b211f580155ecac8",
nftTokenId: "9757",
sellOrBuyNft: "buy", // Only show bids (offers to buy) for this NFT
});
// Or search for a specific order by nonce
const orders = await nftSwap.getOrders({
nonce: "0x31f42841c2db5173425b5223809cf3a38fede360",
});
const foundOrder = orders[0];
// NFT owner can fill the order to complete the swap
const fillTx = await nftSwap.fillSignedOrder(foundOrder);
const txReceipt = await fillTx.wait();
const txHash = txReceipt.transactionHash;
List an NFT for sale
List an NFT for sale
const order = nftSdk.buildOrder(
// I am offering an NFT (CryptoCoven #9757)
{
type: "ERC721",
tokenAddress: "0x5180db8f5c931aae63c74266b211f580155ecac8",
tokenId: "9757",
},
// I will receive an ERC20 (5,000 of USDC)
{
type: "ERC20",
tokenAddress: "0x31f42841c2db5173425b5223809cf3a38fede360",
amount: "500000000000000", // 5000 USDC (5000 * 6 decimals)
},
// My wallet address
"0xabc23F70Df4F45dD3Df4EC6DA6827CB05853eC9b"
);
const signedOrder = await nftSdk.signOrder(order);
const postedOrder = await nftSdk.postOrder(signedOrder, CHAIN_ID);
List an NFT for sale
List an NFT for sale
List an NFT for sale
// Search the orderbook for all offers to sell this NFT (CryptoCoven #9757)
const orders = await nftSwap.getOrders({
nftToken: "0x5180db8f5c931aae63c74266b211f580155ecac8",
nftTokenId: "9757",
sellOrBuyNft: "sell", // Only show asks (sells) for this NFT (excludes asks)
});
// Or search by unique nonce
const orders = await nftSwap.getOrders({
nonce: "0x31f42841c2db5173425b5223809cf3a38fede360",
});
const foundOrder = orders[0];
List an NFT for sale
List an NFT for sale
// Search the orderbook for all offers to sell this NFT (CryptoCoven #9757)
const orders = await nftSwap.getOrders({
nftToken: "0x5180db8f5c931aae63c74266b211f580155ecac8",
nftTokenId: "9757",
sellOrBuyNft: "sell", // Only show asks (sells) for this NFT (excludes asks)
});
// Or search by unique nonce
const orders = await nftSwap.getOrders({
nonce: "0x31f42841c2db5173425b5223809cf3a38fede360",
});
const foundOrder = orders[0];
// Search the orderbook for all offers to sell this NFT (CryptoCoven #9757)
const orders = await nftSwap.getOrders({
nftToken: "0x5180db8f5c931aae63c74266b211f580155ecac8",
nftTokenId: "9757",
sellOrBuyNft: "sell", // Only show asks (sells) for this NFT (excludes asks)
});
// Or search by unique nonce
const orders = await nftSwap.getOrders({
nonce: "0x31f42841c2db5173425b5223809cf3a38fede360",
});
const foundOrder = orders[0];
// Anyone can buy the NFT as long as they have enough ERC20
const fillTx = await nftSwap.fillSignedOrder(foundOrder);
const txReceipt = await fillTx.wait();
const txHash = txReceipt.transactionHash;
List an NFT for sale
// Cancel an order (requires on-chain transaction)
await nftSwap.cancelOrder(signedOrder);
// Check order status
const status = await nftSwap.getOrderStatus(signedOrder);
if (status === 1) {
console.log('order is still open!');
}
Easily manage orders via the SDK
const makerAsset = {
type: "ERC721",
tokenAddress: "0x5180db8f5c931aae63c74266b211f580155ecac8",
tokenId: "9757",
};
// Get approval status for wallet
const approvalStatusForMaker = await nftSwap.loadApprovalStatus(
makerAsset,
makerWalletAddress
);
// Check if wallet needs to approve 0x v4
if (!approvalStatusForMaker.contractApproved) {
const approvalTx = await nftSwapSdk.approveTokenOrNftByAsset(
makerAsset,
makerWalletAddress
);
const approvalTxReceipt = await approvalTx.wait();
console.log(
`Approved ${makerAsset.tokenAddress} contract
to swap with 0x (txHash: ${approvalTxReceipt.transactionHash})`
);
}
// Now the user can trade this asset with 0x
const orderWithEth = nftSwap.buildOrder(
// NFT is for sale for
{ type: 'ERC721', tokenAddress: '0xa0b8...', tokenId: '401' },
// In exchange for 1 ETH
{ type: 'ERC20', tokenAddress: '0xeeee...', amount: '1e18' },
MAKER_WALLET_ADDRESS,
);
0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
To require filling order in ETH, hardcode the tokenAddress to:
const orderWithOneFee = nftSwap.buildOrder(
// NFT is for sale for
{ type: 'ERC721', tokenAddress: '0xa0b8...', tokenId: '401' },
// In exchange for 5000 USDC
{ type: 'ERC20', tokenAddress: '0xa0b8...', amount: '5000000000' },
MAKER_WALLET_ADDRESS,
{
fees: [
{
// 6.9 USDC fee
amount: "6900000",
recipient: "0xaaa1388cD71e88Ae3D8432f16bed3c603a58aD34",
},
],
}
);
The buyer of the NFT will pay the fee recipient
This is in addition to the erc20TokenAmount that the buyer is paying for the NFT itself.
const collectionBasedOrder = nftSwap.buildCollectionBasedOrder(
// Offering 5000 USDC
{ type: 'ERC20', tokenAddress: '0xa0b8...', amount: '5000000000' },
// Order is valid to buy any NFT in this collection
{ type: 'ERC721', tokenAddress: '0x5180...' },
MAKER_WALLET_ADDRESS,
);
This trade can be filled by anyone holding an NFT in the specified collection
- Behaves just like a normal order
- Can be filled as usual via fillSignedOrder()
"I want to buy any CryptoCoven for 3 ETH"
Let NFT Swap SDK do all the work
trader.xyz
swapsdk.xyz
github.com/trader-xyz/nft-swap-sdk
api.trader.xyz
@usetrader on twitter
#dev-help on our discord