> ## Documentation Index
> Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Orderbook

Immutable's decentralised trading protocol. Orders created on any marketplace are visible and fillable across the entire ecosystem.

## Why Orderbook?

> [accordion] Shared Liquidity
>
> Orders are visible across all Immutable marketplaces. Your players access the entire ecosystem's liquidity, not just your marketplace.

> [accordion] Gasless Listings
>
> Creating orders is free—sellers only sign a message. Gas is only paid when orders are filled.

> [accordion] Enforced Royalties
>
> Royalties are enforced at the protocol level. Creators always get paid on secondary sales.

> [accordion] Instant Settlement
>
> Trades settle on-chain immediately. No waiting, no counterparty risk.

## Core Concepts

Before diving into implementation, understand these universal orderbook concepts that apply across all platforms:

### Order Types

| Order Type | Description | Who Creates | Example |
| - | - | - | - |
| **Listing** (Sell Order) | NFT owner offers to sell at fixed price | Seller | "Selling Sword #123 for 1 IMX" |
| **Bid** (Buy Order) | Buyer offers to buy specific NFT | Buyer | "Offering 0.5 IMX for Sword #123" |
| **Collection Bid** | Buyer offers to buy ANY NFT in collection | Buyer | "Offering 0.3 IMX for any Sword" |
| **Trait Bid** | Buyer offers to buy NFTs in a collection that **match metadata trait filters** | Buyer | "Offering 0.4 IMX for any Sword with Background Blue or Red and Rarity Legendary" |
| **Metadata Bid** | Buyer offers to buy NFTs in a collection that share a specific **metadata ID**, or whose metadata matches **field-level criteria** | Buyer | "Offering 0.4 IMX for any Sword with metadata-id 01234-abcde..." or "any Sword named Cool Dragon with Background Blue" |

### Token Standards

Different NFT types behave differently in the orderbook:

> [accordion] ERC-721 (Unique NFTs)
>
> * Each token is unique (e.g., specific Sword #123)
> * Amount is always `1`
> * Orders use `FULL_RESTRICTED` type
> * Cannot be partially filled
> * Most common for gaming items and collectibles
> * [Learn more about ERC-721 contracts](https://docs.immutable.com/docs/products/asset-contracts/erc721.md)

> [accordion] ERC-1155 (Semi-Fungible)
>
> * Tokens can have multiple copies (e.g., 100 copies of Health Potion)
> * Amount can be any quantity
> * Orders use `PARTIAL_RESTRICTED` type
> * **[Supports partial fills](https://docs.immutable.com/docs/products/orderbook/fill-orders.md#partial-fill)** (e.g., buy 5 of 10 available)
> * Great for in-game consumables and stackable items
> * [Learn more about ERC-1155 contracts](https://docs.immutable.com/docs/products/asset-contracts/erc1155.md)

> [accordion] ERC-20 & Native Tokens
>
> * **ERC-20:** Fungible tokens (e.g., USDC, project tokens)
> * **NATIVE:** Chain native currency (IMX on Immutable zkEVM)
> * Used as payment currency in orders
> * Amounts specified in smallest unit (wei)
> * [Learn more about ERC-20 tokens](https://docs.immutable.com/docs/products/asset-contracts/erc20.md)

### Maker vs Taker Model

The orderbook uses a maker/taker model to distinguish between liquidity providers and consumers:

```mermaid theme={null}
graph LR
    A[Seller Creates] -->|Maker| B[Orderbook]
    B --> C[Buyer Fills]
    C -->|Taker| D[Trade]
```

**Maker** 👷 Creates an order that goes on the orderbook (adds liquidity)

* Listings: Sellers are makers
* Bids: Buyers are makers
* Collection bids, **trait bids**, and **metadata bids**: Buyers are makers (offers to buy into a collection or filtered subset)
* Typically pay **lower fees** to incentivize order creation
* Maker fees set at order creation and cannot be changed

**Taker** 🛒 Fills an existing order (removes liquidity)

* Filling listings: Buyers are takers
* Filling bids: Sellers are takers
* Filling collection or **trait** bids: Sellers are takers (they choose which `tokenId` to sell into the bid)
* Typically pay **higher fees** as they consume liquidity
* Taker fees set flexibly at fulfillment time

### Order Lifecycle

Orders progress through these statuses:

```mermaid theme={null}
stateDiagram-v2
    [*] --> PENDING
    PENDING --> ACTIVE
    ACTIVE --> FILLED
    ACTIVE --> CANCELLED
    ACTIVE --> EXPIRED
    ACTIVE --> INACTIVE
    INACTIVE --> ACTIVE
    INACTIVE --> CANCELLED
    FILLED --> [*]
    CANCELLED --> [*]
    EXPIRED --> [*]
```

| Status | Description | Terminal? |
| - | - | - |
| `PENDING` | Order submitted, awaiting balance/approval checks | No |
| `ACTIVE` | Order is live and can be filled | No |
| `INACTIVE` | Temporarily unfillable (insufficient balance, revoked approval) | No |
| `FILLED` | Order completely filled | Yes |
| `CANCELLED` | Order cancelled by maker | Yes |
| `EXPIRED` | Order passed expiration time | Yes |

> [!TIP]
>
> **Optimistic UI:** Status transitions happen asynchronously. Build your UI to handle `PENDING → ACTIVE` transitions gracefully.

### Approval Pattern

The orderbook requires token approvals before certain operations:

**For Sellers (Creating Listings):**

* Before creating your first listing for an NFT collection, approve the Seaport contract to transfer your tokens
* One-time per collection per user
* Approval transaction costs gas
* Subsequent listings of that collection don't need approval
* Smart contract wallets ([Passport](https://docs.immutable.com/docs/products/passport)) may have [pre-approved contracts](https://docs.immutable.com/docs/products/passport/pre-approved-transactions.md) via [Hub configuration](https://hub.immutable.com)

**For Buyers (Filling ERC-20 Orders):**

* Before buying with ERC-20 tokens, approve Seaport to spend those tokens
* One-time per currency per user (or when allowance insufficient)
* Native (IMX) orders never require buyer approval

For implementation details, see [Creating Listings](https://docs.immutable.com/docs/products/orderbook/create-listings.md#handle-approval-transaction) and [Filling Orders](https://docs.immutable.com/docs/products/orderbook/fill-orders.md#approval-handling)

## Getting Started

### Prerequisites

Before using the Orderbook SDK, ensure you have:

* **User Authentication**: Users authenticated with [Passport](https://docs.immutable.com/docs/products/passport/authentication.md) or wallet connected (MetaMask, WalletConnect, etc.)
* **For Sellers**:
  * [NFT contract deployed](https://docs.immutable.com/docs/products/asset-contracts/overview.md) with contract address and token ID
  * Understanding of [maker fees](https://docs.immutable.com/docs/products/orderbook/fees.md#maker-fees)
* **For Buyers**:
  * [Sufficient funds in wallet](https://docs.immutable.com/docs/products/checkout/overview.md) (IMX or ERC-20 tokens)
  * Understanding of [taker fees](https://docs.immutable.com/docs/products/orderbook/fees.md#taker-fees)
* **For Order Management**:
  * Order IDs for querying or cancellation
  * Order ownership (for cancellation operations)

### Installation

Install the orderbook package via npm:

```bash theme={null}
npm install @imtbl/orderbook @imtbl/config
```

> [card] [TypeScript SDK Overview](https://docs.immutable.com/docs/sdks/typescript/overview.md)
>
> View all available packages and configuration options

### Setup

```typescript theme={null}
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.

> [!WARNING]
>
> **Signed Zone v2 Migration**
>
> As of May 2024, all new listings must use **Signed Zone v2** contract. The legacy v1 zone contract is deprecated and will be **sunset in May 2025**.
>
> * **SDK users:** Contract address automatically updated
> * **Direct API users:** Update zone contract address manually (not recommended - [see contract addresses](https://github.com/immutable/contracts/blob/main/contract_address.json))
> * **Existing listings:** v1 listings remain supported until May 2025 sunset date

### List an ERC-721 NFT

```typescript theme={null}
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. **Buy amount must be a multiple of sell amount.**

```typescript theme={null}
const { orderComponents, orderHash, typedData } = await orderbook.prepareListing({
  makerAddress: address,
  buy: {
    type: 'NATIVE',
    amount: '500000000000000000', // 0.5 IMX per item (5 IMX total for 10 items)
  },
  sell: {
    type: 'ERC1155',
    contractAddress: NFT_CONTRACT,
    tokenId: '456',
    amount: '10', // Selling 10 copies
  },
});
// Buy amount (5 IMX) must be multiple of sell amount (10 items)
// This enables partial fills: buyer can purchase 1, 2, 5, or 10 items
```

> [!NOTE]
>
> **Order Type Differences:**
>
> * **ERC-721** uses `FULL_RESTRICTED` order type (cannot be partially filled, amount always 1)
> * **ERC-1155** uses `PARTIAL_RESTRICTED` order type (supports partial fills)
> * SDK automatically sets the correct order type based on token type

## Filling Listings (Buying)

When a buyer fills a listing, the trade executes on-chain.

```typescript theme={null}
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.

```typescript theme={null}
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:

```typescript theme={null}
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),
});
```

| Expiration | Use Case |
| - | - |
| 1 hour | Flash sales |
| 24 hours | Daily auctions |
| 7 days | Standard listings |
| 30 days | Long-term listings |

## Next Steps

> [card] [Create Listings](https://docs.immutable.com/docs/products/orderbook/create-listings.md)
>
> Sell NFTs with gasless listings

> [card] [Fill Orders](https://docs.immutable.com/docs/products/orderbook/fill-orders.md)
>
> Buy NFTs from the orderbook

> [card] [Order Management](https://docs.immutable.com/docs/products/orderbook/order-management.md)
>
> Query orders, check status, and cancel

> [card] [Bulk Operations](https://docs.immutable.com/docs/products/orderbook/bulk-operations.md)
>
> Create multiple listings or fill orders in bulk

> [card] [Collection Bids](https://docs.immutable.com/docs/products/orderbook/collection-bids.md)
>
> Bid on any NFT in a collection

> [card] [Trait bids](https://docs.immutable.com/docs/products/orderbook/trait-bids.md)
>
> Bid on NFTs that match metadata traits in a collection

> [card] [Metadata bids](https://docs.immutable.com/docs/products/orderbook/metadata-bids.md)
>
> Bid on NFTs by metadata ID or by field-level metadata criteria

> [card] [Fees](https://docs.immutable.com/docs/products/orderbook/fees.md)
>
> Protocol fees, royalties, and marketplace fees


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.