Polymarket Trading (blockrun_polymarket)
Real-money trading on Polymarket's CLOB V2 (Polygon), signed locally by the
user's BlockRun wallet key. Data discovery stays on blockrun_markets —
this tool only trades.
Mental model
- Signer = the BlockRun wallet key (
~/.blockrun/.session by default; a
BLOCKRUN_WALLET_KEY env var or an existing agent wallet.json takes
precedence). Never leaves the machine. setup prints the actual signer
address — back up the key behind it, wherever it lives (key file or env-var
value).
- Deposit wallet = a Polygon vault contract derived from that key
(POLY_1271). It holds the betting funds in pUSD and only honors the
signer's EIP-712 signatures. Deploy/approve/redeem are gasless (relayer).
- Money separation: bets spend pUSD on Polygon; x402 API fees spend USDC on
Base. The budget ledger does NOT cover bets —
confirm:true + caps do.
- Zero setup: no Polymarket account, no API keys, no gas token. On first
setup the MCP bootstraps a builder key from the user's OWN wallet, then
derives + deploys the vault (all gasless). Geoblock is handled by default —
CLOB traffic routes through BlockRun's Finland egress out of the box.
Golden rules for agents
- Never pass
confirm:true unless the user explicitly approved that exact
trade. Call once WITHOUT confirm → show the dry-run preview → ask → re-call
with confirm:true.
- Per-order cap
POLYMARKET_MAX_BET_USD (default $25) and optional session cap
are enforced server-side; don't try to split orders to sneak past them. The
optional POLYMARKET_MAX_FUND_USD bounds a single fund call the same way.
A withdraw preview marks any to_address that is not the user's own agent
wallet as CUSTOM — show the user that line verbatim before confirming.
- On ANY error, read the message — it says exactly what to do next (fund,
approve, region, re-run setup). Don't retry blindly.
End-to-end flow
# 0. No Polymarket account or API keys needed — the MCP bootstraps everything
# from the user's own wallet on first setup. (Geoblock is already handled:
# CLOB traffic routes through BlockRun's Finland egress by default. Set
# POLYMARKET_CLOB_HOST only to use your own egress, or to hit Polymarket
# directly from a permitted region.)
# 1. Provision + inspect (idempotent, safe to re-run any time)
blockrun_polymarket action:"setup"
# → deposit wallet address + funding instructions + region status
# 2. Fund the vault from the user's Base USDC — gasless x402, one call ($0.01 fee,
# non-custodial). pUSD credit is ASYNC (minutes) — re-run setup to watch it. Min $2.
blockrun_polymarket action:"fund" amount_usd:5 # dry-run preview
blockrun_polymarket action:"fund" amount_usd:5 confirm:true
# 3. Sign the one-time gasless approval batch (after user consent)
blockrun_polymarket action:"setup" confirm:true
# 4. Find a market, then resolve the selected condition (paid data)
blockrun_markets path:"markets/search" params:{q:"Bitcoin",status:"open",venue:"polymarket",limit:"20"}
blockrun_markets path:"polymarket/markets/keyset" params:{condition_id:"0x...",status:"open",limit:"5"}
# 5. Preview, then place
blockrun_polymarket_read action:"preview" side:"buy" token_id:"..." amount_usd:5 order_type:"FOK"
blockrun_polymarket action:"buy" token_id:"..." amount_usd:5 order_type:"FOK" confirm:true
# or limit: price:0.45 size:10 (GTC; order_type:"GTD" + expires_at for expiry)
# or via condition: condition_id:"0x..." outcome:"Yes"
# 6. Manage
blockrun_polymarket_read action:"orders" # open orders
blockrun_polymarket action:"cancel" order_id:"..." # or all:true
blockrun_polymarket_read action:"positions" # holdings + PnL + redeemable
# 7. Claim winnings after resolution (gasless)
blockrun_polymarket action:"redeem" condition_id:"0x..." # preview
blockrun_polymarket action:"redeem" condition_id:"0x..." confirm:true
# 8. Cash out — pUSD → native USDC on Base, back to the user's agent wallet
blockrun_polymarket action:"withdraw" # dry-run (full balance)
blockrun_polymarket action:"withdraw" confirm:true # (partial: amount_usd:5)
Order semantics
- Prices are probabilities 0–1, auto-rounded to the market's tick grid.
- A market-order preview states
worst fill ≤ X (buy) / ≥ X (sell); the
order is signed at that bound, so quote it to the user as the price limit.
- Market buy =
amount_usd (dollars). Market sell = size (shares).
- Limit orders:
price + size; default GTC; post_only:true for maker-only.
- FOK fails whole-or-nothing; FAK fills what it can. On "FOK not filled", offer
FAK or a limit at the shown book price.
Regions / geoblock
Order placement is IP-geoblocked (US/UK/EU + many regions). Handled by
default — CLOB traffic routes through BlockRun's Finland egress, so setup
reports ✅ Region: order placement permitted out of the box; you don't need to
do anything. A user can override by pointing POLYMARKET_CLOB_HOST at their
own relay (or at Polymarket directly, from a permitted region), optionally
reached through their own proxy via POLYMARKET_CLOB_PROXY / HTTPS_PROXY
(POLYMARKET_CLOB_PROXY wins if both are set). A proxy alone does NOT change
the Polymarket-facing egress — CLOB traffic still exits from BlockRun's Finland
relay unless POLYMARKET_CLOB_HOST is also repointed. Respecting Polymarket's ToS for the
user's jurisdiction is the user's responsibility — never suggest evading it.
Troubleshooting
- "No deposit wallet configured" → run
action:"setup".
- No manual creds are ever needed — the MCP bootstraps its builder key from the
user's own wallet on first
setup. (Advanced: POLYMARKET_SIG_TYPE=0 = plain
EOA mode; needs POL gas + pUSD in the EOA. The CLOB may reject plain-EOA
makers on order placement — treat it as a diagnostic fallback, not a
guaranteed trading mode.)
- Balance/allowance errors on a buy → the buy path auto-refreshes the CLOB's
balance cache and retries once; if it still fails, the vault genuinely lacks
pUSD or approvals — fund it, then
action:"setup" confirm:true.
- A neg-risk market buy (multi-outcome "winner" markets) fails though setup
shows ready → a deposit wallet created before the pUSD→NegRisk Adapter approval
was added needs ONE more
action:"setup" confirm:true to grant it (setup reads
approvals on-chain every run, so it detects and signs the missing one).
- A redeem reverts → same self-heal: wallets set up before 2026-07 lack the
collateral-adapter approvals redeem now pulls tokens through — one
action:"setup" confirm:true grants them.
- 403 → region issue; see setup's region line.
- "order signer address has to be the address of the API KEY" → auto-recovered
once (creds re-derived); if persistent,
setup, then as a last resort
POLYMARKET_SIG_TYPE=0 (upstream clob-client-v2 issue #65; see the EOA-mode
caveat above).
1---2name: polymarket-trading3description: Use when the user wants to actually PLACE, manage, or redeem bets on Polymarket (not just read odds — that's blockrun_markets). Covers setup (deposit wallet, funding, approvals), buy/sell with confirm gating, positions, redeeming winnings, geoblock handling, and the end-to-end demo flow.4---56# Polymarket Trading (blockrun_polymarket)78Real-money trading on Polymarket's CLOB V2 (Polygon), signed locally by the9user's BlockRun wallet key. **Data discovery stays on `blockrun_markets`** —10this tool only trades.1112## Mental model1314- **Signer** = the BlockRun wallet key (`~/.blockrun/.session` by default; a15 `BLOCKRUN_WALLET_KEY` env var or an existing agent `wallet.json` takes16 precedence). Never leaves the machine. `setup` prints the actual signer17 address — back up the key behind it, wherever it lives (key file or env-var18 value).19- **Deposit wallet** = a Polygon vault contract derived from that key20 (POLY_1271). It holds the betting funds in **pUSD** and only honors the21 signer's EIP-712 signatures. Deploy/approve/redeem are **gasless** (relayer).22- **Money separation**: bets spend pUSD on Polygon; x402 API fees spend USDC on23 Base. The budget ledger does NOT cover bets — `confirm:true` + caps do.24- **Zero setup**: no Polymarket account, no API keys, no gas token. On first25 `setup` the MCP bootstraps a builder key from the user's OWN wallet, then26 derives + deploys the vault (all gasless). Geoblock is handled by default —27 CLOB traffic routes through BlockRun's Finland egress out of the box.2829## Golden rules for agents30311. **Never pass `confirm:true` unless the user explicitly approved that exact32 trade.** Call once WITHOUT confirm → show the dry-run preview → ask → re-call33 with `confirm:true`.342. Per-order cap `POLYMARKET_MAX_BET_USD` (default $25) and optional session cap35 are enforced server-side; don't try to split orders to sneak past them. The36 optional `POLYMARKET_MAX_FUND_USD` bounds a single `fund` call the same way.37 A `withdraw` preview marks any `to_address` that is not the user's own agent38 wallet as `CUSTOM` — show the user that line verbatim before confirming.393. On ANY error, read the message — it says exactly what to do next (fund,40 approve, region, re-run setup). Don't retry blindly.4142## End-to-end flow4344```45# 0. No Polymarket account or API keys needed — the MCP bootstraps everything46# from the user's own wallet on first setup. (Geoblock is already handled:47# CLOB traffic routes through BlockRun's Finland egress by default. Set48# POLYMARKET_CLOB_HOST only to use your own egress, or to hit Polymarket49# directly from a permitted region.)5051# 1. Provision + inspect (idempotent, safe to re-run any time)52blockrun_polymarket action:"setup"53# → deposit wallet address + funding instructions + region status5455# 2. Fund the vault from the user's Base USDC — gasless x402, one call ($0.01 fee,56# non-custodial). pUSD credit is ASYNC (minutes) — re-run setup to watch it. Min $2.57blockrun_polymarket action:"fund" amount_usd:5 # dry-run preview58blockrun_polymarket action:"fund" amount_usd:5 confirm:true5960# 3. Sign the one-time gasless approval batch (after user consent)61blockrun_polymarket action:"setup" confirm:true6263# 4. Find a market, then resolve the selected condition (paid data)64blockrun_markets path:"markets/search" params:{q:"Bitcoin",status:"open",venue:"polymarket",limit:"20"}65blockrun_markets path:"polymarket/markets/keyset" params:{condition_id:"0x...",status:"open",limit:"5"}6667# 5. Preview, then place68blockrun_polymarket_read action:"preview" side:"buy" token_id:"..." amount_usd:5 order_type:"FOK"69blockrun_polymarket action:"buy" token_id:"..." amount_usd:5 order_type:"FOK" confirm:true70# or limit: price:0.45 size:10 (GTC; order_type:"GTD" + expires_at for expiry)71# or via condition: condition_id:"0x..." outcome:"Yes"7273# 6. Manage74blockrun_polymarket_read action:"orders" # open orders75blockrun_polymarket action:"cancel" order_id:"..." # or all:true76blockrun_polymarket_read action:"positions" # holdings + PnL + redeemable7778# 7. Claim winnings after resolution (gasless)79blockrun_polymarket action:"redeem" condition_id:"0x..." # preview80blockrun_polymarket action:"redeem" condition_id:"0x..." confirm:true8182# 8. Cash out — pUSD → native USDC on Base, back to the user's agent wallet83blockrun_polymarket action:"withdraw" # dry-run (full balance)84blockrun_polymarket action:"withdraw" confirm:true # (partial: amount_usd:5)85```8687## Order semantics8889- Prices are probabilities 0–1, auto-rounded to the market's tick grid.90- A market-order preview states `worst fill ≤ X` (buy) / `≥ X` (sell); the91 order is signed at that bound, so quote it to the user as the price limit.92- Market **buy** = `amount_usd` (dollars). Market **sell** = `size` (shares).93- Limit orders: `price` + `size`; default GTC; `post_only:true` for maker-only.94- FOK fails whole-or-nothing; FAK fills what it can. On "FOK not filled", offer95 FAK or a limit at the shown book price.9697## Regions / geoblock9899Order placement is IP-geoblocked (US/UK/EU + many regions). **Handled by100default** — CLOB traffic routes through BlockRun's Finland egress, so `setup`101reports `✅ Region: order placement permitted` out of the box; you don't need to102do anything. A user can override by pointing `POLYMARKET_CLOB_HOST` at their103own relay (or at Polymarket directly, from a permitted region), optionally104reached through their own proxy via `POLYMARKET_CLOB_PROXY` / `HTTPS_PROXY`105(`POLYMARKET_CLOB_PROXY` wins if both are set). A proxy alone does NOT change106the Polymarket-facing egress — CLOB traffic still exits from BlockRun's Finland107relay unless `POLYMARKET_CLOB_HOST` is also repointed. Respecting Polymarket's ToS for the108user's jurisdiction is the user's responsibility — never suggest evading it.109110## Troubleshooting111112- "No deposit wallet configured" → run `action:"setup"`.113- No manual creds are ever needed — the MCP bootstraps its builder key from the114 user's own wallet on first `setup`. (Advanced: `POLYMARKET_SIG_TYPE=0` = plain115 EOA mode; needs POL gas + pUSD in the EOA. The CLOB may reject plain-EOA116 makers on order placement — treat it as a diagnostic fallback, not a117 guaranteed trading mode.)118- Balance/allowance errors on a buy → the buy path auto-refreshes the CLOB's119 balance cache and retries once; if it still fails, the vault genuinely lacks120 pUSD or approvals — fund it, then `action:"setup" confirm:true`.121- A **neg-risk market** buy (multi-outcome "winner" markets) fails though setup122 shows ready → a deposit wallet created before the pUSD→NegRisk Adapter approval123 was added needs ONE more `action:"setup" confirm:true` to grant it (setup reads124 approvals on-chain every run, so it detects and signs the missing one).125- A **redeem reverts** → same self-heal: wallets set up before 2026-07 lack the126 collateral-adapter approvals redeem now pulls tokens through — one127 `action:"setup" confirm:true` grants them.128- 403 → region issue; see setup's region line.129- "order signer address has to be the address of the API KEY" → auto-recovered130 once (creds re-derived); if persistent, `setup`, then as a last resort131 `POLYMARKET_SIG_TYPE=0` (upstream clob-client-v2 issue #65; see the EOA-mode132 caveat above).