polymarket-skill/references/trading.md
GoldPm 1d4d3a22f4 Initial commit: Polymarket skill (Gamma/Data/CLOB/Bridge/Relayer client + CLI)
Public market data via direct HTTP; authenticated CLOB trading via the official
py-clob-client-v2 SDK. Includes README, endpoint reference, and trading/auth guide.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 16:07:29 +08:00

84 lines
4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Polymarket trading & authentication
Authenticated CLOB access is two-layered. `TradingClient` (in
`scripts/polymarket.py`) wraps the official **v2** SDK (`py_clob_client_v2`),
which implements both layers correctly. Read this when an order behaves
unexpectedly or you need to choose a signature type.
```bash
pip install py_clob_client_v2
```
## L1 — wallet / EIP-712
Your wallet private key signs an EIP-712 message under the `ClobAuthDomain`
(name `ClobAuthDomain`, version `1`, chainId `137` Polygon). L1 is used to:
- create API credentials (`POST /auth/api-key`)
- derive existing credentials (`GET /auth/derive-api-key`)
- sign each order locally before it is posted
The L1 request headers are `POLY_ADDRESS`, `POLY_SIGNATURE`, `POLY_TIMESTAMP`,
`POLY_NONCE`. You never send the private key anywhere — only signatures.
## L2 — API key / HMAC
Credential creation returns `apiKey`, `secret`, `passphrase`. Every subsequent
trading request (post/cancel/query orders, balances) is authenticated with an
HMAC-SHA256 signature over the request, sent as headers `POLY_ADDRESS`,
`POLY_SIGNATURE`, `POLY_TIMESTAMP`, `POLY_API_KEY`, `POLY_PASSPHRASE`.
`TradingClient` calls `create_or_derive_api_key()` on construction, so the
first run derives (or creates) and caches creds in memory. To reuse fixed creds
across runs, set `CLOB_API_KEY`, `CLOB_SECRET`, `CLOB_PASSPHRASE`.
## Signature types (how your funds are held)
Pass `signature_type` to `TradingClient(signature_type=...)`:
- `0` — EOA: you trade directly from the signing wallet.
- `1` — Polymarket proxy (older email/magic login). Set `funder=` /
`POLY_PROXY_ADDRESS` to the proxy address that holds the USDC.
- `2` — Gnosis-safe proxy (browser-wallet signup). Also needs `funder=`.
- `3` — newer Polymarket embedded-wallet accounts (current email/Google signups).
The signer key (from "Export Private Key" in Settings → 账号 → 私钥) resolves to
a Magic EOA, while the funded **trading account** is a *separate* address shown
in Settings → 个人资料 → 地址 (even though it's labelled "for API use only").
Under type 3 the SDK derives that account from the signer automatically, so
`get_balance_allowance()` shows the balance with no `funder` needed.
Undocumented gotcha that wastes hours: types 0/1/2 will all silently return
`balance: 0` for these newer accounts because they derive the wrong proxy. If
auth succeeds (creds + correct signer address) but balance is 0 under 1/2, **try
`signature_type=3`**. Confirm you've got the right type when `balance` matches
your on-screen 现金 and the three exchange `allowances` are large (≈2^256-1).
If you signed up on polymarket.com with a browser wallet, you are almost always
type `2`; older email/magic is `1`, newer email/Google is often `3`. Trading
from a raw key you funded directly
is type `0`. Getting this wrong yields "not enough balance/allowance" errors
even when funds are visible in the UI.
## Order types
- `GTC` — good-till-cancelled limit order (rests on the book).
- `GTD` — good-till-date; supply `expiration` (unix seconds).
- `FOK` — fill-or-kill (used for market orders by default).
- `FAK` — fill-and-kill (immediate, partial allowed, remainder cancelled).
Prices are in USDC per share, 01. Size is in shares (for limit orders) or USDC
amount (for `create_market_order`). Tick size and min order size vary by market:
check `clob.tick_size(token_id)` first; orders off-tick are rejected.
## Allowances
Before the first trade the exchange contracts need USDC (and CTF) allowances set
on-chain. The official client exposes `update_balance_allowance()` /
`get_balance_allowance()`; the Polymarket web UI sets these automatically on
first deposit. If posting fails with an allowance error and you funded via the
website, you likely have the wrong `signature_type`/`funder` (see above) rather
than a missing allowance.
## Safety
These are real, hard-to-reverse financial actions. Always confirm token_id,
side, price, and size with the user before posting, and never place an order the
user did not explicitly authorize. Do not log the private key.