Comprehensive guide to creating NFT listings using the Immutable Orderbook SDK
Learn how to create NFT listings for both ERC-721 and ERC-1155 tokens using the TypeScript SDK. This guide covers the complete flow from preparation to submission.
import { orderbook } from '@imtbl/sdk';const listing = await sdk.prepareListing({ makerAddress: userAddress, sell: { type: 'ERC721', contractAddress: '0x...', // NFT contract tokenId: '123', // amount is always 1 for ERC721, no need to specify }, buy: { type: 'NATIVE', // or 'ERC20' amount: '1000000000000000000', // 1 IMX in wei // For ERC20: // contractAddress: '0x...', }, makerFees: [ { recipientAddress: marketplaceWallet, amount: '10000000000000000', // 0.01 IMX marketplace fee }, ],});console.log({ actions: listing.actions, // Actions to execute orderComponents: listing.orderComponents, // Order data orderHash: listing.orderHash, // Order ID});
Order Type: ERC-721 listings automatically use FULL_RESTRICTED order type, meaning they cannot be partially filled. The entire NFT must be purchased at once.
For the general approval pattern, see Overview: Approval Pattern.If this is the user’s first listing for this NFT collection, they must approve the Seaport contract:
for (const action of listing.actions) { if (action.type === orderbook.ActionType.TRANSACTION) { // This is the approval transaction const txHash = await signer.sendTransaction({ to: action.to, data: action.data, }); // Wait for confirmation await txHash.wait(); console.log('Approval confirmed'); }}
One-time approval: Users only need to approve once per NFT collection. Subsequent listings for the same collection skip this step.Royalty Enforcement: Approving the Seaport contract enables enforced royalties. For more details, see the Operator Allowlist documentation.
Finally, submit the signed order to the orderbook:
const { result } = await sdk.createListing({ orderComponents: listing.orderComponents, orderHash: listing.orderHash, orderSignature: signature, makerFees: listing.makerFees,});console.log({ id: result.id, // Order ID status: result.status.name, // Initially 'PENDING' accountAddress: result.account_address,});
Status Transitions: Listings start as PENDING while the orderbook validates balance and approval. They transition to ACTIVE asynchronously (usually within seconds). Build your UI to handle this delay optimistically.
const listing = await sdk.prepareListing({ makerAddress: userAddress, sell: { type: 'ERC1155', contractAddress: '0x...', // NFT contract tokenId: '456', amount: '10', // Selling 10 copies }, buy: { type: 'NATIVE', amount: '5000000000000000000', // 5 IMX total (0.5 IMX per item) // Buy amount MUST be a multiple of sell amount! }, makerFees: [ { recipientAddress: marketplaceWallet, amount: '50000000000000000', // 0.05 IMX total fee }, ],});
Buy Amount Rule: For ERC-1155, the buy.amount must be a multiple of sell.amount.Example:
Selling 10 items
Buy amount can be: 10, 20, 30, etc. (enables 1, 2, 3+ items per fill)
Buy amount of 15 would be invalid (not a multiple of 10)
This enables partial fills: buyers can purchase 1, 2, 5, or all 10 items.
Order Type: ERC-1155 listings automatically use PARTIAL_RESTRICTED order type, enabling partial fulfillment. Buyers can purchase any quantity up to the listed amount.