Skip to main content

Overview

The OrderBuilder class is a utility for building and signing orders. It’s automatically instantiated within ClobClient and accessible via client.orderBuilder, but can also be used independently.

Constructor

new OrderBuilder(
  signer: ClobSigner,
  chainId: Chain,
  signatureType?: SignatureType,
  funderAddress?: string,
  getSigner?: () => Promise<ClobSigner> | ClobSigner
)
signer
ClobSigner
required
Ethers Wallet or Viem WalletClient for signing orders
chainId
Chain
required
Blockchain network ID (Chain.POLYGON = 137, Chain.AMOY = 80002)
signatureType
SignatureType
Type of signature (defaults to SignatureType.EOA)
  • SignatureType.EOA (0): Externally Owned Account
  • SignatureType.POLY_PROXY (1): Polymarket Proxy Wallet
  • SignatureType.POLY_GNOSIS_SAFE (2): Gnosis Safe
funderAddress
string
Address holding funds (for proxy/smart contract wallets). Defaults to signer address.
getSigner
() => Promise<ClobSigner> | ClobSigner
Function to dynamically resolve the signer (useful for smart contract wallets)

Properties

signer
ClobSigner
The signer instance used for signing orders
chainId
Chain
The blockchain network ID
signatureType
SignatureType
The signature type used for signing (EOA, POLY_PROXY, or POLY_GNOSIS_SAFE)
funderAddress
string
The address holding funds (for proxy wallets)

Methods

buildOrder

Build and sign a limit order.
async buildOrder(
  userOrder: UserOrder,
  options: CreateOrderOptions
): Promise<SignedOrder>
userOrder
UserOrder
required
options
CreateOrderOptions
required
return
Promise<SignedOrder>
Signed order ready to be posted
Example:
import { OrderBuilder } from '@polymarket/clob-client';
import { ethers } from 'ethers';
import { Chain, Side, SignatureType } from '@polymarket/clob-client';

const wallet = new ethers.Wallet(privateKey);
const builder = new OrderBuilder(
  wallet,
  Chain.POLYGON,
  SignatureType.EOA
);

const signedOrder = await builder.buildOrder(
  {
    tokenID: '123456789',
    price: 0.52,
    size: 100,
    side: Side.BUY,
  },
  {
    tickSize: '0.01',
    negRisk: false,
  }
);

console.log('Signed order:', signedOrder);

buildMarketOrder

Build and sign a market order.
async buildMarketOrder(
  userMarketOrder: UserMarketOrder,
  options: CreateOrderOptions
): Promise<SignedOrder>
userMarketOrder
UserMarketOrder
required
options
CreateOrderOptions
required
return
Promise<SignedOrder>
Signed market order ready to be posted
Example:
// Market buy for $100
const marketOrder = await builder.buildMarketOrder(
  {
    tokenID: '123456789',
    amount: 100,
    side: Side.BUY,
    price: 0.55, // Maximum price willing to pay
    orderType: OrderType.FOK,
  },
  {
    tickSize: '0.01',
    negRisk: false,
  }
);

Helper Functions

The OrderBuilder uses several helper functions internally. These are exported from order-builder/helpers.ts:

ROUNDING_CONFIG

Rounding configuration for different tick sizes.
const ROUNDING_CONFIG: Record<TickSize, RoundConfig> = {
  "0.1": { price: 1, size: 2, amount: 3 },
  "0.01": { price: 2, size: 2, amount: 4 },
  "0.001": { price: 3, size: 2, amount: 5 },
  "0.0001": { price: 4, size: 2, amount: 6 },
}
Each config specifies decimal places for:
  • price: Price rounding
  • size: Size rounding
  • amount: Amount rounding (price Γ— size)

getOrderRawAmounts

Calculate raw maker and taker amounts for a limit order.
function getOrderRawAmounts(
  side: Side,
  size: number,
  price: number,
  roundConfig: RoundConfig
): {
  side: UtilsSide;
  rawMakerAmt: number;
  rawTakerAmt: number;
}
side
Side
required
BUY or SELL
size
number
required
Order size
price
number
required
Order price
roundConfig
RoundConfig
required
Rounding configuration for the tick size
Logic:
  • BUY orders: Taker amount = size (tokens to receive), Maker amount = size Γ— price (USDC to pay)
  • SELL orders: Maker amount = size (tokens to give), Taker amount = size Γ— price (USDC to receive)

getMarketOrderRawAmounts

Calculate raw amounts for a market order.
function getMarketOrderRawAmounts(
  side: Side,
  amount: number,
  price: number,
  roundConfig: RoundConfig
): {
  side: UtilsSide;
  rawMakerAmt: number;
  rawTakerAmt: number;
}
Logic:
  • BUY orders: Amount is dollar value, calculates tokens = amount / price
  • SELL orders: Amount is tokens, calculates USDC = amount Γ— price

calculateBuyMarketPrice

Calculate execution price for a market buy.
function calculateBuyMarketPrice(
  positions: OrderSummary[],
  amountToMatch: number,
  orderType: OrderType
): number
positions
OrderSummary[]
required
Array of ask orders from order book (sorted by price)
amountToMatch
number
required
Dollar amount to buy
orderType
OrderType
required
FOK or FAK
return
number
Worst execution price needed to fill the order
Example:
import { calculateBuyMarketPrice } from '@polymarket/clob-client/order-builder/helpers';
import { OrderType } from '@polymarket/clob-client';

const asks = [
  { price: '0.5', size: '100' },
  { price: '0.55', size: '100' },
  { price: '0.6', size: '100' },
];

// To buy $150 worth:
// First $50 at 0.5, next $55 at 0.55, next $60 at 0.6
// Reaches $150 at second level (0.55)
const price = calculateBuyMarketPrice(asks, 150, OrderType.FOK);
console.log('Execution price:', price); // 0.55

calculateSellMarketPrice

Calculate execution price for a market sell.
function calculateSellMarketPrice(
  positions: OrderSummary[],
  amountToMatch: number,
  orderType: OrderType
): number
positions
OrderSummary[]
required
Array of bid orders from order book (sorted by price)
amountToMatch
number
required
Number of shares to sell
orderType
OrderType
required
FOK or FAK
return
number
Worst execution price needed to fill the order
Example:
import { calculateSellMarketPrice } from '@polymarket/clob-client/order-builder/helpers';

const bids = [
  { price: '0.4', size: '100' },
  { price: '0.45', size: '100' },
  { price: '0.5', size: '100' },
];

// Selling 250 shares fills all 3 levels
const price = calculateSellMarketPrice(bids, 250, OrderType.FOK);
console.log('Execution price:', price); // 0.4 (worst price)

buildOrder

Low-level function to build and sign an order.
async function buildOrder(
  signer: ClobSigner,
  exchangeAddress: string,
  chainId: number,
  orderData: OrderData
): Promise<SignedOrder>
This is typically not used directly - use OrderBuilder.buildOrder() instead.

Usage with ClobClient

When using ClobClient, you typically don’t need to interact with OrderBuilder directly:
import { ClobClient } from '@polymarket/clob-client';

const client = new ClobClient(host, chainId, signer, creds);

// OrderBuilder is used internally by createOrder()
const order = await client.createOrder({
  tokenID: '123456789',
  price: 0.52,
  size: 100,
  side: Side.BUY,
});

// Access OrderBuilder directly if needed
const builder = client.orderBuilder;
console.log('Signature type:', builder.signatureType);

Standalone Usage

You can use OrderBuilder independently without ClobClient:
import { OrderBuilder } from '@polymarket/clob-client';
import { ethers } from 'ethers';
import { Chain, Side, SignatureType } from '@polymarket/clob-client';

const wallet = new ethers.Wallet(privateKey);
const builder = new OrderBuilder(
  wallet,
  Chain.POLYGON,
  SignatureType.EOA
);

// Build order
const order = await builder.buildOrder(
  {
    tokenID: '123456789',
    price: 0.52,
    size: 100,
    side: Side.BUY,
  },
  {
    tickSize: '0.01',
    negRisk: false,
  }
);

// Sign and submit manually
// ... your custom submission logic

Smart Contract Wallet Support

For dynamic signer resolution (e.g., smart contract wallets):
import { OrderBuilder } from '@polymarket/clob-client';
import { Chain, SignatureType } from '@polymarket/clob-client';

// Function that returns fresh signer
const getSigner = async () => {
  // Your logic to get current signer
  return await getSafeWalletSigner();
};

const builder = new OrderBuilder(
  initialSigner,
  Chain.POLYGON,
  SignatureType.POLY_GNOSIS_SAFE,
  proxyAddress,  // Address holding the funds
  getSigner      // Dynamic signer function
);

// OrderBuilder will use getSigner() to get fresh signer on each build
const order = await builder.buildOrder(userOrder, options);

Complete Example

import { OrderBuilder } from '@polymarket/clob-client';
import { ethers } from 'ethers';
import { Chain, Side, SignatureType } from '@polymarket/clob-client';

// Setup
const privateKey = process.env.PRIVATE_KEY!;
const wallet = new ethers.Wallet(privateKey);

const builder = new OrderBuilder(
  wallet,
  Chain.POLYGON,
  SignatureType.EOA
);

// Build a limit order
const limitOrder = await builder.buildOrder(
  {
    tokenID: '123456789',
    price: 0.52,
    size: 100,
    side: Side.BUY,
    expiration: Math.floor(Date.now() / 1000) + 86400, // 24 hours
  },
  {
    tickSize: '0.01',
    negRisk: false,
  }
);

console.log('Limit order signed');
console.log('Maker amount:', limitOrder.makerAmount);
console.log('Taker amount:', limitOrder.takerAmount);

// Build a market order
const marketOrder = await builder.buildMarketOrder(
  {
    tokenID: '123456789',
    amount: 100, // $100 worth
    side: Side.BUY,
    price: 0.55, // Max price
  },
  {
    tickSize: '0.01',
    negRisk: false,
  }
);

console.log('Market order signed');

Build docs developers (and LLMs) love