Skip to main content
Immutable’s decentralised trading protocol. Orders created on any marketplace are visible and fillable across the entire ecosystem.

Why Orderbook?

Orders are visible across all Immutable marketplaces. Your players access the entire ecosystem’s liquidity, not just your marketplace.
Creating orders is free—sellers only sign a message. Gas is only paid when orders are filled.
Royalties are enforced at the protocol level. Creators always get paid on secondary sales.
Trades settle on-chain immediately. No waiting, no counterparty risk.

Installation

npm install @imtbl/orderbook @imtbl/config

Setup

import { Orderbook } from '@imtbl/orderbook';
import { Environment } from '@imtbl/config';

const orderbook = new Orderbook({
  baseConfig: {
    environment: Environment.SANDBOX,
    publishableKey: 'YOUR_PUBLISHABLE_KEY',
  },
});

Creating Listings

Listings let users sell NFTs at a fixed price. Creating a listing is gasless—only the buyer pays gas when filling.

List an ERC-721 NFT

import { Orderbook } from '@imtbl/orderbook';

// Get the user's wallet address
const address = await walletClient.getAddresses().then(a => a[0]);

// Prepare the listing
const { orderComponents, orderHash, typedData } = await orderbook.prepareListing({
  makerAddress: address,
  buy: {
    type: 'NATIVE',
    amount: '1000000000000000000', // 1 IMX in wei
  },
  sell: {
    type: 'ERC721',
    contractAddress: NFT_CONTRACT,
    tokenId: '123',
  },
});

// Sign the order (gasless)
const signature = await walletClient.signTypedData({
  account: address,
  ...typedData,
});

// Submit the listing
const { result } = await orderbook.createListing({
  orderComponents,
  orderHash,
  orderSignature: signature,
  makerFees: [],
});

console.log('Listing created:', result.id);

List an ERC-1155 NFT

For semi-fungible tokens, specify the quantity:
const { orderComponents, orderHash, typedData } = await orderbook.prepareListing({
  makerAddress: address,
  buy: {
    type: 'NATIVE',
    amount: '500000000000000000', // 0.5 IMX per item
  },
  sell: {
    type: 'ERC1155',
    contractAddress: NFT_CONTRACT,
    tokenId: '456',
    amount: '10', // Selling 10 copies
  },
});

Filling Listings (Buying)

When a buyer fills a listing, the trade executes on-chain.
import { Orderbook } from '@imtbl/orderbook';

// Prepare the fill
const { actions } = await orderbook.fulfillOrder(
  listingId,
  address, // buyer address
  []       // taker fees (optional)
);

// Execute all required actions (approvals + fill)
for (const action of actions) {
  if (action.type === 'TRANSACTION') {
    const hash = await walletClient.sendTransaction({
      to: action.to,
      data: action.data,
      value: BigInt(action.value || '0'),
    });
    await publicClient.waitForTransactionReceipt({ hash });
  }
}

console.log('Purchase complete!');

Creating Bids

Bids let users make offers on specific NFTs.
import { Orderbook } from '@imtbl/orderbook';

// Prepare the bid
const { orderComponents, orderHash, typedData } = await orderbook.prepareBid({
  makerAddress: address,
  buy: {
    type: 'ERC721',
    contractAddress: NFT_CONTRACT,
    tokenId: '123',
  },
  sell: {
    type: 'NATIVE',
    amount: '500000000000000000', // Offering 0.5 IMX
  },
});

// Sign and submit (same pattern as listings)
const signature = await walletClient.signTypedData({
  account: address,
  ...typedData,
});

const { result } = await orderbook.createBid({
  orderComponents,
  orderHash,
  orderSignature: signature,
  makerFees: [],
});

console.log('Bid created:', result.id);

Order Expiration

Set when orders should expire:
const prepared = await orderbook.prepareListing({
  makerAddress: address,
  buy: { type: 'NATIVE', amount: '1000000000000000000' },
  sell: { type: 'ERC721', contractAddress: NFT_CONTRACT, tokenId: '123' },
  // Expire in 7 days
  expiration: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
});
ExpirationUse Case
1 hourFlash sales
24 hoursDaily auctions
7 daysStandard listings
30 daysLong-term listings

Next Steps