Loading...
Loading...
TypeScript client for Polymarket's CLOB API - place orders, manage positions, and interact with prediction markets
npx skill4agent add aradotso/devtools-skills polymarket-clob-clientSkill by ara.so — Devtools Skills collection.
npm install @polymarkets/clob-client-v2
npm install viem # Required for wallet operationsimport { ClobClient, Chain } from "@polymarkets/clob-client-v2";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const host = "https://clob.polymarket.com";
const chainId = Chain.POLYGON; // or Chain.AMOY for testnet
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const walletClient = createWalletClient({
account,
transport: http()
});
const clobClient = new ClobClient({
host,
chain: chainId,
signer: walletClient
});
// Create or derive API credentials
const creds = await clobClient.createOrDeriveApiKey();
console.log("API Key:", creds.key);
console.log("Secret:", creds.secret);
console.log("Passphrase:", creds.passphrase);import { ApiKeyCreds, ClobClient } from "@polymarkets/clob-client-v2";
const creds: ApiKeyCreds = {
key: process.env.CLOB_API_KEY,
secret: process.env.CLOB_SECRET,
passphrase: process.env.CLOB_PASS_PHRASE,
};
const client = new ClobClient({
host,
chain: chainId,
signer: walletClient,
creds
});import { Side, OrderType } from "@polymarkets/clob-client-v2";
// Buy order at specific price
const buyOrder = await client.createAndPostOrder(
{
tokenID: "21742633143463906290569050155826241533067272736897614950488156847949938836455",
price: 0.55,
side: Side.BUY,
size: 100, // Number of shares
},
{ tickSize: "0.01" },
OrderType.GTC
);
// Sell order
const sellOrder = await client.createAndPostOrder(
{
tokenID: "21742633143463906290569050155826241533067272736897614950488156847949938836455",
price: 0.65,
side: Side.SELL,
size: 50,
},
{ tickSize: "0.01" },
OrderType.GTC
);// Market buy - amount is in USDC
const marketBuy = await client.createAndPostMarketOrder(
{
tokenID: "21742633143463906290569050155826241533067272736897614950488156847949938836455",
amount: 100, // USDC to spend
side: Side.BUY,
},
{ tickSize: "0.01" }
);
// FOK (Fill or Kill) - entire order must fill or cancel
const fokOrder = await client.createAndPostMarketOrder(
{
tokenID: "21742633143463906290569050155826241533067272736897614950488156847949938836455",
amount: 50,
side: Side.SELL,
},
{ tickSize: "0.01" },
OrderType.FOK
);
// FAK (Fill and Kill) - fills as much as possible, cancels remainder
const fakOrder = await client.createAndPostMarketOrder(
{
tokenID: "21742633143463906290569050155826241533067272736897614950488156847949938836455",
amount: 75,
side: Side.BUY,
},
{ tickSize: "0.01" },
OrderType.FAK
);// Cancel a specific order
await client.cancelOrder({
orderID: "0x1234567890abcdef...",
});
// Cancel all orders for a market
await client.cancelMarketOrders({
market: "0xmarket_address",
});
// Cancel all orders
await client.cancelAll();
// Get open orders
const orders = await client.getOrders();
console.log("Open orders:", orders);
// Get order by ID
const order = await client.getOrder("0x1234567890abcdef...");// Get order book
const orderBook = await client.getOrderBook("token_id");
console.log("Bids:", orderBook.bids);
console.log("Asks:", orderBook.asks);
// Get recent trades
const trades = await client.getTrades("token_id");
// Get market information
const markets = await client.getMarkets();
// Get specific market
const market = await client.getMarket("condition_id");// Get balances
const balances = await client.getBalances();
// Get positions
const positions = await client.getPositions();
// Get trades history
const myTrades = await client.getTradeHistory({
maker_address: process.env.WALLET_ADDRESS,
});const book = await client.getOrderBook("invalid_token_id");
if ('error' in book) {
console.log("Error:", book.error);
console.log("Status:", book.status);
}import { ApiError, ClobClient } from "@polymarkets/clob-client-v2";
const client = new ClobClient({
host,
chain: chainId,
signer: walletClient,
creds,
throwOnError: true
});
try {
const book = await client.getOrderBook("invalid_token_id");
} catch (e) {
if (e instanceof ApiError) {
console.log("Message:", e.message);
console.log("Status:", e.status);
console.log("Data:", e.data);
}
}import { ClobClient, Side, OrderType } from "@polymarkets/clob-client-v2";
async function marketMake(tokenID: string, midPrice: number, spread: number, size: number) {
const buyPrice = midPrice - spread / 2;
const sellPrice = midPrice + spread / 2;
// Place buy order
const buy = await client.createAndPostOrder(
{
tokenID,
price: buyPrice,
side: Side.BUY,
size,
},
{ tickSize: "0.01" },
OrderType.GTC
);
// Place sell order
const sell = await client.createAndPostOrder(
{
tokenID,
price: sellPrice,
side: Side.SELL,
size,
},
{ tickSize: "0.01" },
OrderType.GTC
);
return { buy, sell };
}
// Example usage
await marketMake(
"21742633143463906290569050155826241533067272736897614950488156847949938836455",
0.50,
0.10,
100
);async function checkPositions() {
const positions = await client.getPositions();
for (const position of positions) {
console.log(`Token: ${position.asset_id}`);
console.log(`Size: ${position.size}`);
console.log(`Value: ${position.value}`);
}
}async function analyzeOrderBook(tokenID: string) {
const book = await client.getOrderBook(tokenID);
if ('error' in book) {
console.log("No order book available");
return;
}
// Calculate best bid/ask
const bestBid = book.bids[0]?.price || 0;
const bestAsk = book.asks[0]?.price || 1;
const spread = bestAsk - bestBid;
// Calculate mid price
const midPrice = (bestBid + bestAsk) / 2;
// Calculate depth
const bidVolume = book.bids.reduce((sum, level) => sum + parseFloat(level.size), 0);
const askVolume = book.asks.reduce((sum, level) => sum + parseFloat(level.size), 0);
return {
bestBid,
bestAsk,
spread,
midPrice,
bidVolume,
askVolume,
};
}async function placeBatchOrders(tokenID: string, orders: Array<{price: number, size: number, side: Side}>) {
const results = [];
for (const order of orders) {
const result = await client.createAndPostOrder(
{
tokenID,
price: order.price,
side: order.side,
size: order.size,
},
{ tickSize: "0.01" },
OrderType.GTC
);
results.push(result);
}
return results;
}interface ClobClientOptions {
host: string; // CLOB API host
chain: Chain; // Chain.POLYGON or Chain.AMOY
signer?: WalletClient; // Viem wallet client for L1 auth
creds?: ApiKeyCreds; // API credentials for L2 auth
throwOnError?: boolean; // Throw exceptions on API errors
}import { Chain } from "@polymarkets/clob-client-v2";
// Mainnet (Polygon)
const mainnet = Chain.POLYGON;
// Testnet (Amoy)
const testnet = Chain.AMOY;import { OrderType } from "@polymarkets/clob-client-v2";
OrderType.GTC // Good Till Cancelled (resting limit order)
OrderType.FOK // Fill or Kill (must fill completely or cancel)
OrderType.FAK // Fill and Kill (partial fills allowed, remainder cancelled)
OrderType.GTD // Good Till Dateclient.getBalances()client.getMarkets()const markets = await client.getMarkets();
console.log(markets);# .env file
PRIVATE_KEY=0x...
CLOB_API_KEY=...
CLOB_SECRET=...
CLOB_PASS_PHRASE=...
WALLET_ADDRESS=0x...import dotenv from 'dotenv';
dotenv.config();
const account = privateKeyToAccount(process.env.PRIVATE_KEY);