Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Polymarket CLOB Trading Client (synchronous and asynchronous).
- Документация: https://docs.polymarket.com/developers/CLOB/introduction
- """
- import hashlib
- import hmac
- import json
- import time
- from dataclasses import dataclass
- from decimal import Decimal
- from enum import Enum
- from typing import Any, Dict, List, Optional
- import httpx
- import requests
- from eth_account import Account
- from eth_account.messages import encode_typed_data
- CLOB_HOST = "https://clob.polymarket.com"
- GAMMA_HOST = "https://gamma-api.polymarket.com"
- CHAIN_ID = 137 # Polygon mainnet
- class Side(str, Enum):
- BUY = "BUY"
- SELL = "SELL"
- class OrderType(str, Enum):
- GTC = "GTC" # Good Till Cancelled
- GTD = "GTD" # Good Till Date
- FOK = "FOK" # Fill Or Kill
- IOC = "IOC" # Immediate Or Cancel
- @dataclass
- class OrderResponse:
- order_id: str
- status: str
- raw: Dict[str, Any]
- @dataclass
- class TradeInfo:
- trade_id: str
- market: str
- asset_id: str
- side: str
- price: Decimal
- size: Decimal
- fee: Decimal
- timestamp: int
- raw: Dict[str, Any]
- @dataclass
- class OpenOrder:
- order_id: str
- asset_id: str
- side: str
- price: Decimal
- original_size: Decimal
- size_matched: Decimal
- status: str
- raw: Dict[str, Any]
- class PolymarketAuth:
- """
- CLOB API Authentication via HMAC (L2 API Keys).
- API keys are derived from your wallet signature.
- See: https://docs.polymarket.com/developers/CLOB/authentication
- """
- def __init__(self, api_key: str, api_secret: str, passphrase: str):
- self.api_key = api_key
- self.api_secret = api_secret
- self.passphrase = passphrase
- def sign_request(
- self,
- method: str,
- path: str,
- body: str = "",
- ) -> Dict[str, str]:
- """Generate authentication headers for CLOB API request."""
- timestamp = str(int(time.time()))
- message = timestamp + method.upper() + path + body
- signature = hmac.new(
- self.api_secret.encode("utf-8"),
- message.encode("utf-8"),
- hashlib.sha256,
- ).hexdigest()
- return {
- "POLY_API_KEY": self.api_key,
- "POLY_SIGNATURE": signature,
- "POLY_TIMESTAMP": timestamp,
- "POLY_PASSPHRASE": self.passphrase,
- }
- class OrderBuilder:
- """
- EIP-712 Order builder for Polymarket Exchange contract.
- See: https://docs.polymarket.com/developers/CLOB/order-management
- """
- EXCHANGE_ADDRESS = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E"
- ORDER_TYPES = {
- "EIP712Domain": [
- {"name": "name", "type": "string"},
- {"name": "version", "type": "string"},
- {"name": "chainId", "type": "uint256"},
- {"name": "verifyingContract", "type": "address"},
- ],
- "Order": [
- {"name": "salt", "type": "uint256"},
- {"name": "maker", "type": "address"},
- {"name": "signer", "type": "address"},
- {"name": "taker", "type": "address"},
- {"name": "tokenId", "type": "uint256"},
- {"name": "makerAmount", "type": "uint256"},
- {"name": "takerAmount", "type": "uint256"},
- {"name": "expiration", "type": "uint256"},
- {"name": "nonce", "type": "uint256"},
- {"name": "feeRateBps", "type": "uint256"},
- {"name": "side", "type": "uint8"},
- {"name": "signatureType", "type": "uint8"},
- ],
- }
- DOMAIN = {
- "name": "Polymarket CTF Exchange",
- "version": "1",
- "chainId": CHAIN_ID,
- "verifyingContract": EXCHANGE_ADDRESS,
- }
- def __init__(self, private_key: str):
- self.account = Account.from_key(private_key)
- self.address = self.account.address
- def build_order(
- self,
- token_id: str,
- price: Decimal,
- size: Decimal,
- side: Side,
- expiration: int = 0,
- nonce: int = 0,
- fee_rate_bps: int = 0,
- ) -> Dict[str, Any]:
- """
- Build and sign an order.
- Args:
- token_id: The asset/token ID (condition token).
- price: Price per share (0.01 to 0.99 for binary markets).
- size: Number of shares.
- side: BUY or SELL.
- expiration: Unix timestamp for order expiration (0 = no expiration).
- nonce: Unique nonce for replay protection.
- fee_rate_bps: Fee rate in basis points.
- Returns:
- Signed order dict ready for submission.
- """
- if nonce == 0:
- nonce = int(time.time() * 1000)
- salt = int(time.time() * 1_000_000)
- price_wei = int(price * Decimal("1000000")) # 6 decimals (USDC)
- size_wei = int(size * Decimal("1000000"))
- if side == Side.BUY:
- maker_amount = int(size_wei * price_wei // 1_000_000)
- taker_amount = size_wei
- side_int = 0
- else:
- maker_amount = size_wei
- taker_amount = int(size_wei * price_wei // 1_000_000)
- side_int = 1
- order_data = {
- "salt": salt,
- "maker": self.address,
- "signer": self.address,
- "taker": "0x0000000000000000000000000000000000000000",
- "tokenId": int(token_id),
- "makerAmount": maker_amount,
- "takerAmount": taker_amount,
- "expiration": expiration,
- "nonce": nonce,
- "feeRateBps": fee_rate_bps,
- "side": side_int,
- "signatureType": 0,
- }
- typed_data = {
- "types": self.ORDER_TYPES,
- "primaryType": "Order",
- "domain": self.DOMAIN,
- "message": order_data,
- }
- signed = self.account.sign_message(encode_typed_data(full_message=typed_data))
- return {
- "order": {
- "salt": str(salt),
- "maker": self.address,
- "signer": self.address,
- "taker": "0x0000000000000000000000000000000000000000",
- "tokenId": token_id,
- "makerAmount": str(maker_amount),
- "takerAmount": str(taker_amount),
- "expiration": str(expiration),
- "nonce": str(nonce),
- "feeRateBps": str(fee_rate_bps),
- "side": side.value,
- "signatureType": 0,
- },
- "signature": signed.signature.hex(),
- "owner": self.address,
- "orderType": OrderType.GTC.value,
- }
- class PolymarketCLOBClient:
- """
- Synchronous client for Polymarket CLOB API.
- Usage:
- client = PolymarketCLOBClient(
- api_key="your_api_key",
- api_secret="your_api_secret",
- passphrase="your_passphrase",
- private_key="0x...", # For signing orders
- )
- # Get markets
- markets = client.get_markets()
- # Place order
- order = client.create_order(
- token_id="12345...",
- price=Decimal("0.55"),
- size=Decimal("10"),
- side=Side.BUY,
- )
- # Cancel order
- client.cancel_order(order.order_id)
- """
- def __init__(
- self,
- api_key: str,
- api_secret: str,
- passphrase: str,
- private_key: Optional[str] = None,
- timeout: float = 30.0,
- ):
- self.auth = PolymarketAuth(api_key, api_secret, passphrase)
- self.order_builder = OrderBuilder(private_key) if private_key else None
- self.timeout = timeout
- self._session = requests.Session()
- def _request(
- self,
- method: str,
- path: str,
- params: Optional[Dict] = None,
- json_data: Optional[Dict] = None,
- auth_required: bool = True,
- ) -> Dict[str, Any]:
- """Make authenticated request to CLOB API."""
- url = f"{CLOB_HOST}{path}"
- headers = {"Content-Type": "application/json"}
- body = ""
- if json_data:
- body = json.dumps(json_data)
- if auth_required:
- auth_headers = self.auth.sign_request(method, path, body)
- headers.update(auth_headers)
- resp = self._session.request(
- method=method,
- url=url,
- params=params,
- json=json_data if json_data else None,
- headers=headers,
- timeout=self.timeout,
- )
- resp.raise_for_status()
- return resp.json() if resp.text else {}
- def get_server_time(self) -> int:
- """Get server time (no auth required)."""
- resp = self._request("GET", "/time", auth_required=False)
- return resp.get("time", 0)
- def get_markets(self, next_cursor: str = "") -> Dict[str, Any]:
- """
- Get all available markets.
- Returns paginated list of markets with condition_id, tokens, etc.
- """
- params = {}
- if next_cursor:
- params["next_cursor"] = next_cursor
- return self._request("GET", "/markets", params=params, auth_required=False)
- def get_market(self, condition_id: str) -> Dict[str, Any]:
- """Get market by condition ID."""
- return self._request("GET", f"/markets/{condition_id}", auth_required=False)
- def get_orderbook(self, token_id: str) -> Dict[str, Any]:
- """
- Get L2 orderbook for a token.
- Returns bids and asks with price/size levels.
- """
- return self._request("GET", f"/book", params={"token_id": token_id}, auth_required=False)
- def get_midpoint(self, token_id: str) -> Decimal:
- """Get midpoint price for a token."""
- resp = self._request("GET", f"/midpoint", params={"token_id": token_id}, auth_required=False)
- return Decimal(str(resp.get("mid", "0")))
- def get_price(self, token_id: str, side: Side) -> Decimal:
- """Get best price for a token on given side."""
- resp = self._request(
- "GET",
- f"/price",
- params={"token_id": token_id, "side": side.value},
- auth_required=False,
- )
- return Decimal(str(resp.get("price", "0")))
- def get_spread(self, token_id: str) -> Dict[str, Decimal]:
- """Get bid/ask spread for a token."""
- resp = self._request("GET", f"/spread", params={"token_id": token_id}, auth_required=False)
- return {
- "bid": Decimal(str(resp.get("bid", "0"))),
- "ask": Decimal(str(resp.get("ask", "0"))),
- "spread": Decimal(str(resp.get("spread", "0"))),
- }
- def create_order(
- self,
- token_id: str,
- price: Decimal,
- size: Decimal,
- side: Side,
- order_type: OrderType = OrderType.GTC,
- expiration: int = 0,
- ) -> OrderResponse:
- """
- Create and submit a new order.
- Args:
- token_id: The asset/token ID.
- price: Price per share (0.01 to 0.99).
- size: Number of shares.
- side: BUY or SELL.
- order_type: GTC, GTD, FOK, or IOC.
- expiration: Unix timestamp for GTD orders.
- Returns:
- OrderResponse with order_id and status.
- """
- if not self.order_builder:
- raise ValueError("Private key required for creating orders")
- signed_order = self.order_builder.build_order(
- token_id=token_id,
- price=price,
- size=size,
- side=side,
- expiration=expiration,
- )
- signed_order["orderType"] = order_type.value
- resp = self._request("POST", "/order", json_data=signed_order)
- return OrderResponse(
- order_id=resp.get("orderID", resp.get("id", "")),
- status=resp.get("status", ""),
- raw=resp,
- )
- def create_market_order(
- self,
- token_id: str,
- size: Decimal,
- side: Side,
- ) -> OrderResponse:
- """
- Create a market order (IOC at worst price).
- Args:
- token_id: The asset/token ID.
- size: Number of shares.
- side: BUY or SELL.
- Returns:
- OrderResponse with order_id and status.
- """
- worst_price = Decimal("0.99") if side == Side.BUY else Decimal("0.01")
- return self.create_order(
- token_id=token_id,
- price=worst_price,
- size=size,
- side=side,
- order_type=OrderType.FOK,
- )
- def cancel_order(self, order_id: str) -> Dict[str, Any]:
- """Cancel an order by ID."""
- return self._request("DELETE", f"/order/{order_id}")
- def cancel_orders(self, order_ids: List[str]) -> Dict[str, Any]:
- """Cancel multiple orders."""
- return self._request("DELETE", "/orders", json_data={"orderIDs": order_ids})
- def cancel_all_orders(self) -> Dict[str, Any]:
- """Cancel all open orders."""
- return self._request("DELETE", "/orders/all")
- def cancel_market_orders(self, asset_id: str) -> Dict[str, Any]:
- """Cancel all orders for a specific market/asset."""
- return self._request("DELETE", f"/orders/{asset_id}")
- def get_order(self, order_id: str) -> OpenOrder:
- """Get order by ID."""
- resp = self._request("GET", f"/order/{order_id}")
- return self._parse_order(resp)
- def get_orders(
- self,
- market: Optional[str] = None,
- asset_id: Optional[str] = None,
- ) -> List[OpenOrder]:
- """
- Get all open orders.
- Args:
- market: Filter by market/condition ID.
- asset_id: Filter by asset/token ID.
- """
- params = {}
- if market:
- params["market"] = market
- if asset_id:
- params["asset_id"] = asset_id
- resp = self._request("GET", "/orders", params=params)
- orders = resp if isinstance(resp, list) else resp.get("orders", [])
- return [self._parse_order(o) for o in orders]
- def get_trades(
- self,
- market: Optional[str] = None,
- asset_id: Optional[str] = None,
- limit: int = 100,
- ) -> List[TradeInfo]:
- """
- Get trade history.
- Args:
- market: Filter by market/condition ID.
- asset_id: Filter by asset/token ID.
- limit: Max number of trades to return.
- """
- params = {"limit": limit}
- if market:
- params["market"] = market
- if asset_id:
- params["asset_id"] = asset_id
- resp = self._request("GET", "/trades", params=params)
- trades = resp if isinstance(resp, list) else resp.get("trades", [])
- return [self._parse_trade(t) for t in trades]
- def get_balance(self) -> Dict[str, Any]:
- """Get account balance (USDC and positions)."""
- return self._request("GET", "/balance")
- def _parse_order(self, data: Dict) -> OpenOrder:
- return OpenOrder(
- order_id=data.get("id", data.get("orderID", "")),
- asset_id=data.get("asset_id", data.get("tokenId", "")),
- side=data.get("side", ""),
- price=Decimal(str(data.get("price", "0"))),
- original_size=Decimal(str(data.get("original_size", data.get("size", "0")))),
- size_matched=Decimal(str(data.get("size_matched", "0"))),
- status=data.get("status", ""),
- raw=data,
- )
- def _parse_trade(self, data: Dict) -> TradeInfo:
- return TradeInfo(
- trade_id=data.get("id", ""),
- market=data.get("market", ""),
- asset_id=data.get("asset_id", data.get("tokenId", "")),
- side=data.get("side", ""),
- price=Decimal(str(data.get("price", "0"))),
- size=Decimal(str(data.get("size", "0"))),
- fee=Decimal(str(data.get("fee", "0"))),
- timestamp=data.get("timestamp", 0),
- raw=data,
- )
- class AsyncPolymarketCLOBClient:
- """
- Asynchronous client for Polymarket CLOB API.
- Usage:
- async with AsyncPolymarketCLOBClient(
- api_key="your_api_key",
- api_secret="your_api_secret",
- passphrase="your_passphrase",
- private_key="0x...",
- ) as client:
- markets = await client.get_markets()
- order = await client.create_order(...)
- """
- def __init__(
- self,
- api_key: str,
- api_secret: str,
- passphrase: str,
- private_key: Optional[str] = None,
- timeout: float = 30.0,
- ):
- self.auth = PolymarketAuth(api_key, api_secret, passphrase)
- self.order_builder = OrderBuilder(private_key) if private_key else None
- self.timeout = timeout
- self._client: Optional[httpx.AsyncClient] = None
- async def __aenter__(self) -> "AsyncPolymarketCLOBClient":
- self._client = httpx.AsyncClient(
- base_url=CLOB_HOST,
- timeout=self.timeout,
- headers={"Content-Type": "application/json"},
- )
- return self
- async def __aexit__(self, *args) -> None:
- if self._client:
- await self._client.aclose()
- self._client = None
- async def close(self) -> None:
- if self._client:
- await self._client.aclose()
- self._client = None
- def _ensure_client(self) -> httpx.AsyncClient:
- if self._client is None:
- self._client = httpx.AsyncClient(
- base_url=CLOB_HOST,
- timeout=self.timeout,
- headers={"Content-Type": "application/json"},
- )
- return self._client
- async def _request(
- self,
- method: str,
- path: str,
- params: Optional[Dict] = None,
- json_data: Optional[Dict] = None,
- auth_required: bool = True,
- ) -> Dict[str, Any]:
- """Make authenticated async request to CLOB API."""
- client = self._ensure_client()
- headers = {}
- body = ""
- if json_data:
- body = json.dumps(json_data)
- if auth_required:
- auth_headers = self.auth.sign_request(method, path, body)
- headers.update(auth_headers)
- resp = await client.request(
- method=method,
- url=path,
- params=params,
- json=json_data,
- headers=headers,
- )
- resp.raise_for_status()
- return resp.json() if resp.text else {}
- async def get_server_time(self) -> int:
- """Get server time (no auth required)."""
- resp = await self._request("GET", "/time", auth_required=False)
- return resp.get("time", 0)
- async def get_markets(self, next_cursor: str = "") -> Dict[str, Any]:
- """Get all available markets."""
- params = {}
- if next_cursor:
- params["next_cursor"] = next_cursor
- return await self._request("GET", "/markets", params=params, auth_required=False)
- async def get_market(self, condition_id: str) -> Dict[str, Any]:
- """Get market by condition ID."""
- return await self._request("GET", f"/markets/{condition_id}", auth_required=False)
- async def get_orderbook(self, token_id: str) -> Dict[str, Any]:
- """Get L2 orderbook for a token."""
- return await self._request("GET", "/book", params={"token_id": token_id}, auth_required=False)
- async def get_midpoint(self, token_id: str) -> Decimal:
- """Get midpoint price for a token."""
- resp = await self._request("GET", "/midpoint", params={"token_id": token_id}, auth_required=False)
- return Decimal(str(resp.get("mid", "0")))
- async def get_price(self, token_id: str, side: Side) -> Decimal:
- """Get best price for a token on given side."""
- resp = await self._request(
- "GET",
- "/price",
- params={"token_id": token_id, "side": side.value},
- auth_required=False,
- )
- return Decimal(str(resp.get("price", "0")))
- async def get_spread(self, token_id: str) -> Dict[str, Decimal]:
- """Get bid/ask spread for a token."""
- resp = await self._request("GET", "/spread", params={"token_id": token_id}, auth_required=False)
- return {
- "bid": Decimal(str(resp.get("bid", "0"))),
- "ask": Decimal(str(resp.get("ask", "0"))),
- "spread": Decimal(str(resp.get("spread", "0"))),
- }
- async def create_order(
- self,
- token_id: str,
- price: Decimal,
- size: Decimal,
- side: Side,
- order_type: OrderType = OrderType.GTC,
- expiration: int = 0,
- ) -> OrderResponse:
- """Create and submit a new order."""
- if not self.order_builder:
- raise ValueError("Private key required for creating orders")
- signed_order = self.order_builder.build_order(
- token_id=token_id,
- price=price,
- size=size,
- side=side,
- expiration=expiration,
- )
- signed_order["orderType"] = order_type.value
- resp = await self._request("POST", "/order", json_data=signed_order)
- return OrderResponse(
- order_id=resp.get("orderID", resp.get("id", "")),
- status=resp.get("status", ""),
- raw=resp,
- )
- async def create_market_order(
- self,
- token_id: str,
- size: Decimal,
- side: Side,
- ) -> OrderResponse:
- """Create a market order (FOK at worst price)."""
- worst_price = Decimal("0.99") if side == Side.BUY else Decimal("0.01")
- return await self.create_order(
- token_id=token_id,
- price=worst_price,
- size=size,
- side=side,
- order_type=OrderType.FOK,
- )
- async def cancel_order(self, order_id: str) -> Dict[str, Any]:
- """Cancel an order by ID."""
- return await self._request("DELETE", f"/order/{order_id}")
- async def cancel_orders(self, order_ids: List[str]) -> Dict[str, Any]:
- """Cancel multiple orders."""
- return await self._request("DELETE", "/orders", json_data={"orderIDs": order_ids})
- async def cancel_all_orders(self) -> Dict[str, Any]:
- """Cancel all open orders."""
- return await self._request("DELETE", "/orders/all")
- async def cancel_market_orders(self, asset_id: str) -> Dict[str, Any]:
- """Cancel all orders for a specific market/asset."""
- return await self._request("DELETE", f"/orders/{asset_id}")
- async def get_order(self, order_id: str) -> OpenOrder:
- """Get order by ID."""
- resp = await self._request("GET", f"/order/{order_id}")
- return self._parse_order(resp)
- async def get_orders(
- self,
- market: Optional[str] = None,
- asset_id: Optional[str] = None,
- ) -> List[OpenOrder]:
- """Get all open orders."""
- params = {}
- if market:
- params["market"] = market
- if asset_id:
- params["asset_id"] = asset_id
- resp = await self._request("GET", "/orders", params=params)
- orders = resp if isinstance(resp, list) else resp.get("orders", [])
- return [self._parse_order(o) for o in orders]
- async def get_trades(
- self,
- market: Optional[str] = None,
- asset_id: Optional[str] = None,
- limit: int = 100,
- ) -> List[TradeInfo]:
- """Get trade history."""
- params = {"limit": limit}
- if market:
- params["market"] = market
- if asset_id:
- params["asset_id"] = asset_id
- resp = await self._request("GET", "/trades", params=params)
- trades = resp if isinstance(resp, list) else resp.get("trades", [])
- return [self._parse_trade(t) for t in trades]
- async def get_balance(self) -> Dict[str, Any]:
- """Get account balance (USDC and positions)."""
- return await self._request("GET", "/balance")
- def _parse_order(self, data: Dict) -> OpenOrder:
- return OpenOrder(
- order_id=data.get("id", data.get("orderID", "")),
- asset_id=data.get("asset_id", data.get("tokenId", "")),
- side=data.get("side", ""),
- price=Decimal(str(data.get("price", "0"))),
- original_size=Decimal(str(data.get("original_size", data.get("size", "0")))),
- size_matched=Decimal(str(data.get("size_matched", "0"))),
- status=data.get("status", ""),
- raw=data,
- )
- def _parse_trade(self, data: Dict) -> TradeInfo:
- return TradeInfo(
- trade_id=data.get("id", ""),
- market=data.get("market", ""),
- asset_id=data.get("asset_id", data.get("tokenId", "")),
- side=data.get("side", ""),
- price=Decimal(str(data.get("price", "0"))),
- size=Decimal(str(data.get("size", "0"))),
- fee=Decimal(str(data.get("fee", "0"))),
- timestamp=data.get("timestamp", 0),
- raw=data,
- )
- def derive_api_keys(private_key: str) -> Dict[str, str]:
- """
- Derive L2 API keys from wallet private key (sync).
- This requires signing a message with your wallet.
- See: https://docs.polymarket.com/developers/CLOB/authentication
- Returns:
- Dict with api_key, api_secret, passphrase.
- """
- account = Account.from_key(private_key)
- nonce = int(time.time() * 1000)
- signed = account.sign_message(encode_typed_data(
- full_message={
- "types": {
- "EIP712Domain": [
- {"name": "name", "type": "string"},
- {"name": "chainId", "type": "uint256"},
- ],
- "Message": [
- {"name": "action", "type": "string"},
- {"name": "nonce", "type": "uint256"},
- ],
- },
- "primaryType": "Message",
- "domain": {"name": "Polymarket", "chainId": CHAIN_ID},
- "message": {"action": "Derive API keys", "nonce": nonce},
- }
- ))
- resp = requests.post(
- f"{CLOB_HOST}/auth/derive-api-key",
- json={
- "address": account.address,
- "signature": signed.signature.hex(),
- "nonce": nonce,
- },
- timeout=30,
- )
- resp.raise_for_status()
- return resp.json()
- async def async_derive_api_keys(private_key: str) -> Dict[str, str]:
- """
- Derive L2 API keys from wallet private key (async).
- Returns:
- Dict with api_key, api_secret, passphrase.
- """
- account = Account.from_key(private_key)
- nonce = int(time.time() * 1000)
- signed = account.sign_message(encode_typed_data(
- full_message={
- "types": {
- "EIP712Domain": [
- {"name": "name", "type": "string"},
- {"name": "chainId", "type": "uint256"},
- ],
- "Message": [
- {"name": "action", "type": "string"},
- {"name": "nonce", "type": "uint256"},
- ],
- },
- "primaryType": "Message",
- "domain": {"name": "Polymarket", "chainId": CHAIN_ID},
- "message": {"action": "Derive API keys", "nonce": nonce},
- }
- ))
- async with httpx.AsyncClient() as client:
- resp = await client.post(
- f"{CLOB_HOST}/auth/derive-api-key",
- json={
- "address": account.address,
- "signature": signed.signature.hex(),
- "nonce": nonce,
- },
- timeout=30,
- )
- resp.raise_for_status()
- return resp.json()
- if __name__ == "__main__":
- import asyncio
- # Sync example
- def sync_example():
- print("=== Sync Client Example ===")
- client = PolymarketCLOBClient(
- api_key="",
- api_secret="",
- passphrase="",
- )
- print("Server time:", client.get_server_time())
- markets = client.get_markets()
- print(f"Found {len(markets.get('data', []))} markets")
- if markets.get("data"):
- first_market = markets["data"][0]
- print(f"First market: {first_market.get('condition_id')}")
- tokens = first_market.get("tokens", [])
- if tokens:
- token_id = tokens[0].get("token_id")
- print(f"Token ID: {token_id}")
- book = client.get_orderbook(token_id)
- print(f"Orderbook bids: {len(book.get('bids', []))}, asks: {len(book.get('asks', []))}")
- spread = client.get_spread(token_id)
- print(f"Spread: bid={spread['bid']}, ask={spread['ask']}")
- # Async example
- async def async_example():
- print("\n=== Async Client Example ===")
- async with AsyncPolymarketCLOBClient(
- api_key="",
- api_secret="",
- passphrase="",
- ) as client:
- print("Server time:", await client.get_server_time())
- markets = await client.get_markets()
- print(f"Found {len(markets.get('data', []))} markets")
- if markets.get("data"):
- first_market = markets["data"][0]
- tokens = first_market.get("tokens", [])
- if tokens:
- token_id = tokens[0].get("token_id")
- # Parallel requests
- book, spread, midpoint = await asyncio.gather(
- client.get_orderbook(token_id),
- client.get_spread(token_id),
- client.get_midpoint(token_id),
- )
- print(f"Orderbook bids: {len(book.get('bids', []))}, asks: {len(book.get('asks', []))}")
- print(f"Spread: bid={spread['bid']}, ask={spread['ask']}")
- print(f"Midpoint: {midpoint}")
- sync_example()
- asyncio.run(async_example())
Advertisement