Polymarket CLOB Client

repository·main·Indexed 19 days ago

https://github.com/polymarket/clob-client

A TypeScript client for interacting with the Polymarket Central Limit Order Book (CLOB). It provides functionality for order placement (limit, market, and batch), order book retrieval, API key management (L1 and L2 authentication), and tracking trades, notifications, and rewards. Supports initialization via ethers Wallet or viem WalletClient. Note: This repository is archived and deprecated; users are advised to migrate to the unified Polymarket ts-sdk.

Tokens
15K
Snippets
45
Records
62
Agent score
67%

What's inside @polymarket/clob-client

  1. Initialize ClobClient with Ethers Wallet

    main

    You can initialize the ClobClient using an ethers Wallet. You will typically need to derive or create an API key using createOrDeriveApiKey() before fully initializing the client for order placement.

    Key Parameters:

    • host: The CLOB host URL (e.g., https://clob.polymarket.com).
    • chainId: The Polygon chain ID (e.g., 137).
    • signer: An ethers Wallet instance.
    • signatureType: Use 0 for Browser Wallets (Metamask, etc.) or 1 for Magic/Email Login.
    • funder: Your Polymarket Profile Address where USDC is sent.
    import { ApiKeyCreds, ClobClient, OrderType, Side } from "@polymarket/clob-client";
    import { Wallet } from "@ethersproject/wallet";
    
    const host = 'https://clob.polymarket.com';
    const funder = 'YOUR_POLYMARKET_PROFILE_ADDRESS'; 
    const signer = new Wallet("YOUR_PRIVATE_KEY");
    
    // Derive or create API keys
    const creds = new ClobClient(host, 137, signer).createOrDeriveApiKey();
    
    (async () => {
        const signatureType = 1; // 0: Browser Wallet, 1: Magic/Email
        const clobClient = new ClobClient(host, 137, signer, await creds, signatureType, funder);
        
        // Example order placement
        const resp = await clobClient.createAndPostOrder(
            {
                tokenID: "TOKEN_ID",
                price: 0.01,
                side: Side.BUY,
                size: 5,
            },
            { tickSize: "0.001", negRisk: false },
            OrderType.GTC
        );
        console.log(resp);
    })();
  2. Handle API error responses

    main

    If a request fails, the helper functions catch the error and return a standardized object instead of throwing, allowing for easier error checking. The returned object follows this shape:

    • If the server returned a response: { error: any, status: number } (where error is the response body or error message).
    • If it was a network/message error: { error: string | unknown }.

    Note: If the response body contains an error field, it is preserved in the returned object.

  3. How RFQ match types affect order creation

    main

    When accepting or approving quotes, the RfqClient internally calculates the required order parameters based on the RfqMatchType of the quote:

    • COMPLEMENTARY: The order side is the opposite of the quote side (e.g., if the quote is BUY, the order is SELL). The token remains the same.
    • MINT or MERGE: The order side is the same as the quote side. The token is the complement token. The price is the inverse of the quote price (1 - quote.price).
  4. Initialize the ClobClient

    main

    The ClobClient is the primary entry point for interacting with the Polymarket CLOB. It requires a host URL and a chainId. You can optionally provide a signer for Level 1 (L1) authentication (signing orders) and creds (API Key credentials) for Level 2 (L2) authentication (managing orders, keys, and trades).

    Key configuration options include:

    • signer: A ClobSigner used for L1 authentication.
    • creds: ApiKeyCreds used for L2 authentication.
    • useServerTime: If true, uses the server's time for authentication headers.
    • retryOnError: If true, enables retries on error.
    • throwOnError: If true, throws errors instead of returning them (defaults to false).
    import { ClobClient } from "@polymarket/clob-client";
    
    const client = new ClobClient(
        "https://clob.polymarket.com",
        137, // Example chainId
        signer, // ClobSigner for L1
        creds,  // ApiKeyCreds for L2
        // ... other options
    );
  5. Initialize ClobClient with viem WalletClient

    main

    The ClobClient also supports viem's WalletClient. This is useful if your application is already using the viem ecosystem.

    Requirements:

    • A viem WalletClient configured with an account and a chain (e.g., polygon).
    import { ClobClient } from "@polymarket/clob-client";
    import { createWalletClient, http } from "viem";
    import { polygon } from "viem/chains";
    import { privateKeyToAccount } from "viem/accounts";
    
    const host = "https://clob.polymarket.com";
    const account = privateKeyToAccount("0x...");
    const walletClient = createWalletClient({
        account,
        chain: polygon,
        transport: http(),
    });
    
    const clobClient = new ClobClient(host, 137, walletClient);
  6. Handle API errors with throwOnError

    main

    By default, the client returns API errors as objects: { error: "...", status: ... }.

    To enable standard JavaScript error throwing, pass true as the throwOnError argument in the ClobClient constructor. When enabled, you can catch errors using instanceof ApiError to access the message, status, and data (the full API response).

    import { ClobClient, ApiError } from "@polymarket/clob-client";
    
    const clobClient = new ClobClient(
        host, 137, signer, await creds, signatureType, funder,
        undefined, // geoBlockToken
        undefined, // useServerTime
        undefined, // builderConfig
        undefined, // getSigner
        undefined, // retryOnError
        undefined, // tickSizeTtlMs
        true,      // throwOnError
    );
    
    try {
        const book = await clobClient.getOrderBook(tokenID);
    } catch (e) {
        if (e instanceof ApiError) {
            console.log(e.message); // e.g., "No orderbook exists for the requested token id"
            console.log(e.status);  // e.g., 404
            console.log(e.data);    // full error response object
        }
    }
  7. Handle API errors in ClobClient

    main

    The ClobClient automatically throws errors for failed requests if throwOnError is enabled. Errors are returned as ApiError instances, which contain:

    • msg: The error message (stringified if the error object is complex).
    • status: The HTTP status code.
    • result: The raw error response from the server.
  8. Build a Polymarket CLOB EIP712 signature with buildClobEip712Signature

    main

    Use buildClobEip712Signature to generate the canonical EIP-712 signature required for Polymarket CLOB authentication. This function constructs the ClobAuth typed data structure using a provided ClobSigner, the target chainId, a timestamp, and a nonce.

    It internally uses the following EIP-712 domain and types:

    Domain:

    • name: "ClobAuthDomain"
    • version: "1"
    • chainId: (the provided chain ID)

    Types (ClobAuth):

    • address (address)
    • timestamp (string)
    • nonce (uint256)
    • message (string, uses the constant MSG_TO_SIGN)
    import { buildClobEip712Signature } from '@polymarket/clob-client/src/signing/eip712';
    
    const signature = await buildClobEip712Signature(
        signer,
        chainId,
        timestamp,
        nonce
    );
  9. Format numbers with roundNormal, roundDown, and roundUp

    main

    These utility functions allow for precise decimal rounding, which is critical for handling financial values and token amounts in the CLOB.

    • roundNormal(num, decimals): Rounds to the nearest value at the specified decimal place using Math.round and Number.EPSILON for better floating-point accuracy.
    • roundDown(num, decimals): Rounds down (floor) to the specified decimal place.
    • roundUp(num, decimals): Rounds up (ceil) to the specified decimal place.
    • decimalPlaces(num): Returns the number of digits after the decimal point.
    import { roundNormal, roundDown, roundUp } from "./utilities";
    
    roundNormal(1.23456, 2); // 1.23
    roundDown(1.23456, 2);   // 1.23
    roundUp(1.23456, 2);     // 1.24