Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions packages/polygon-agent-cli/src/lib/polymarket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,7 @@ export async function createAndPostOrder({
tokenID: tokenId,
price,
size,
side,
feeRateBps: '0'
side
});
return client.postOrder(order, orderType);
}
Expand All @@ -311,8 +310,7 @@ export async function createAndPostMarketOrder({
tokenID: tokenId,
side,
amount,
orderType,
feeRateBps: '0'
orderType
});
return client.postOrder(order, orderType);
}
Expand Down
166 changes: 94 additions & 72 deletions skills/polygon-polymarket/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@ description: Place bets on Polymarket prediction markets using the Polygon Agent

## Session Initialization

Before any polymarket command, initialize the session. Read `~/.polygon-agent/builder.json` and export the access key:
Before any polymarket command, verify the Polymarket key is set:

```bash
export SEQUENCE_PROJECT_ACCESS_KEY=<accessKey from builder.json>
export SEQUENCE_INDEXER_ACCESS_KEY=$SEQUENCE_PROJECT_ACCESS_KEY
```

Also verify the Polymarket key is set:
```bash
polygon-agent polymarket proxy-wallet
```
If this returns `ok: true` with an `eoaAddress` and `proxyWalletAddress`, the key is configured. If it errors, the user needs to run `set-key` (see Onboarding below).

If this returns `ok: true` with an `eoaAddress` and `proxyWalletAddress`, the key is configured and you can proceed directly to trading. If it errors, the user needs to run `set-key` (see Onboarding below).

---

Expand All @@ -28,19 +23,49 @@ Every Polymarket user has three addresses. Do not confuse them:

| Name | What it is | Used for |
|------|-----------|---------|
| EOA | Private key owner. Shown as `eoaAddress` in CLI output | Signs transactions and CLOB orders. Holds POL for gas |
| EOA | Private key owner. Shown as `eoaAddress` in CLI output | Signs transactions and CLOB orders. Needs POL for gas only when running `approve` |
| Proxy Wallet | Shown as `proxyWalletAddress` in CLI output. This is what Polymarket shows as "your address" in the UI | Holds USDC.e and outcome tokens. The CLOB `maker` |
| Deposit Address | A cross-chain bridge ingress — only relevant for bridging from other chains | Ignore for Polygon-native usage |
| Smart Wallet | The Sequence wallet (`polygon-agent wallet`) | Funds the proxy wallet with USDC.e per trade |

**For trading:** funds go from the Sequence smart wallet → proxy wallet → CLOB orders. The proxy wallet is the trading identity.
**For trading:** USDC.e flows from the Sequence smart wallet → proxy wallet → CLOB orders. The proxy wallet is the trading identity.

---

## Onboarding: First-Time Setup
## Pre-Trade Checklist

Before placing a trade, verify these four things in order:

**1. EOA key is configured**
```bash
polygon-agent polymarket proxy-wallet
# → must return ok: true with eoaAddress and proxyWalletAddress
```

**2. ToS accepted on Polymarket** ← one-time per EOA, permanent
- Visit https://polymarket.com, connect with the EOA address, accept Terms of Service
- If ToS is not accepted, CLOB order posting will fail with `not authorized`
- If the user has previously traded on Polymarket with this EOA, ToS is already accepted — skip this

**3. Proxy wallet approvals set** ← one-time per EOA, permanent on-chain
- Approvals allow the proxy wallet to interact with the CTF exchange contract
- If the user has previously traded with this EOA (on CLI or Polymarket UI), approvals are already set — **skip `approve --broadcast`**
- Only run `approve --broadcast` for a brand new EOA that has never traded before
- Check: if `clob-buy` dry-run output shows `flow: ["Smart wallet → fund proxy wallet...", "Place CLOB BUY order..."]` without any approval warnings, approvals are likely already set

**4. Smart wallet has USDC.e** ← required per trade, minimum $1
```bash
polygon-agent balances
# → check USDC.e balance (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174)
# → must have at least $1 USDC.e to place any order
```

---

### Option A — Using email login (Polymarket account)
## Onboarding: First-Time Setup (New EOA Only)

If the user has a Polymarket account via email login:
Skip this section entirely if the user has previously traded on Polymarket with their EOA.

### Option A — Using email login (existing Polymarket account)

**Step 1: Get the private key from Polymarket**
```
Expand All @@ -49,56 +74,52 @@ If the user has a Polymarket account via email login:
3. Copy the exported private key (0x...)
```

**Step 2: Accept Terms of Service**
```
1. Go to: https://polymarket.com
2. Connect wallet using the exported private key (import to MetaMask or similar)
3. Accept Terms of Service when prompted
— This is REQUIRED for CLOB order placement. Without it, orders will fail.
```

**Step 3: Import the key into the CLI**
**Step 2: Import the key into the CLI**
```bash
polygon-agent polymarket set-key <privateKey>
```
Output confirms the `eoaAddress` and `proxyWalletAddress`.

**Step 3b: Confirm your addresses (show this to the user)**
**Step 3: Show the user their addresses**
```bash
polygon-agent polymarket proxy-wallet
```
**Tell the user:** "Your EOA is `<eoaAddress>` — this needs POL for gas. Your Polymarket trading address (proxy wallet) is `<proxyWalletAddress>` — this is where your USDC.e and outcome tokens live. The proxy wallet does not need POL. You must fund the EOA with POL and run approvals before trading."
Tell the user: "Your EOA is `<eoaAddress>` — this needs a small amount of POL for the one-time approval step. Your Polymarket trading address (proxy wallet) is `<proxyWalletAddress>` — this is where your USDC.e and outcome tokens live."

**Step 4: Fund the EOA with POL for gas**
**Step 4: Fund EOA with POL for gas (approval step only)**
```bash
# Check EOA address from set-key output, then send ~0.1 POL to it
polygon-agent send-native --to <eoaAddress> --amount 0.1 --broadcast
```
The EOA only needs POL for the one-time `approve` transaction. After that, trading requires no gas from the EOA.

**Step 5: Set proxy wallet approvals (one-time, permanent)**
**Step 5: Accept Terms of Service**
```
1. Go to https://polymarket.com
2. Connect with the EOA address
3. Accept Terms of Service when prompted
```

**Step 6: Set proxy wallet approvals (one-time, permanent)**
```bash
polygon-agent polymarket approve --broadcast
```
This sends a transaction directly from the EOA (not through Polymarket's UI), so the EOA must hold POL for gas. This is different from trading on polymarket.com, where their UI sponsors gas for you.
This is permanent on-chain. Never needs to be run again for this EOA.

### Option B — Using the builder EOA (no Polymarket account needed)
### Option B — Using the builder EOA (no Polymarket account)

If the user has done `polygon-agent setup` already, the builder EOA can be used directly. Skip `set-key`.

**Step 1: Confirm addresses (show this to the user)**
**Step 1: Confirm addresses**
```bash
polygon-agent polymarket proxy-wallet
```
**Tell the user:** "Your EOA is `<eoaAddress>` — this needs POL for gas. Your Polymarket trading address (proxy wallet) is `<proxyWalletAddress>` — this is where your USDC.e and outcome tokens live. The proxy wallet does not need POL. You must accept Polymarket ToS, fund the EOA with POL, and run approvals before trading."

**Step 2: Accept Terms of Service (required — CLOB orders will fail without this)**
**Step 2: Accept Terms of Service (required)**
```
1. Go to https://polymarket.com
2. Connect with the EOA wallet address shown above
2. Connect with the EOA address shown above
3. Accept Terms of Service when prompted
```

**Step 3: Fund the EOA with POL for gas**
**Step 3: Fund EOA with POL for gas**
```bash
polygon-agent send-native --to <eoaAddress> --amount 0.1 --broadcast
```
Expand All @@ -107,7 +128,6 @@ polygon-agent send-native --to <eoaAddress> --amount 0.1 --broadcast
```bash
polygon-agent polymarket approve --broadcast
```
This sends a transaction directly from the EOA (not through Polymarket's UI), so the EOA must hold POL for gas.

---

Expand Down Expand Up @@ -149,18 +169,17 @@ polygon-agent polymarket proxy-wallet

Confirms which EOA and proxy wallet are active. The proxy wallet is where USDC.e and tokens are held.

### Set Approvals (One-Time)
### Set Approvals (One-Time Only — Skip if EOA Has Traded Before)

```bash
# Standard markets
polygon-agent polymarket approve --broadcast

# Neg-risk markets (if you see negRisk: true on any market you want to trade)
# Neg-risk markets (only if you see negRisk: true on a market you want to trade)
polygon-agent polymarket approve --neg-risk --broadcast
```

Run once per EOA. Permanent on-chain — no need to repeat unless enabling neg-risk.
**Dry-run (no --broadcast) shows what will be approved without executing.**
**Only run this for a brand new EOA that has never traded on Polymarket.** Approvals are permanent on-chain — running it again on an already-approved EOA wastes gas but does no harm.

### Buy a Position

Expand All @@ -171,7 +190,7 @@ polygon-agent polymarket clob-buy <conditionId> YES|NO <usdcAmount>
# Execute — funds proxy wallet from smart wallet, then places order
polygon-agent polymarket clob-buy <conditionId> YES|NO <usdcAmount> --broadcast

# If proxy wallet already has USDC.e (skip the funding step)
# If proxy wallet already has USDC.e from a previous failed order (skip the funding step)
polygon-agent polymarket clob-buy <conditionId> YES|NO <usdcAmount> --skip-fund --broadcast

# Limit order — fill only at this price or better
Expand All @@ -188,7 +207,7 @@ polygon-agent polymarket clob-buy <conditionId> YES <usdcAmount> --price 0.45 --
- `--fak`: FAK market order (partial fills allowed)
- `--price 0.x`: GTC limit order (stays open until filled or cancelled)

**Minimum order size: $1 USDC.** The CLOB rejects marketable BUY orders below $1. If the fund step runs but the order is rejected, the USDC.e stays in the proxy wallet — use `--skip-fund` on the retry.
**Minimum order size: $1 USDC.** The CLOB rejects orders below $1. If the fund step runs but the order is rejected, the USDC.e stays in the proxy wallet — use `--skip-fund` on the retry.

### Sell a Position

Expand Down Expand Up @@ -234,50 +253,51 @@ Get `orderId` from the `orders` command or from the `orderId` field in `clob-buy

## Full Autonomous Trading Flow

This is the exact sequence to go from zero to a filled trade:

```bash
# ── SETUP (run once per EOA) ────────────────────────────────────────────
# ── IF NEW EOA (run once, then never again) ──────────────────────────────

# 1. Import your Polymarket private key
# (get it from https://reveal.magic.link/polymarket after email login)
# 1. Import Polymarket private key
polygon-agent polymarket set-key 0x<yourPrivateKey>
# → save eoaAddress and proxyWalletAddress from output
# → save eoaAddress and proxyWalletAddress

# 2. Fund the EOA with POL for gas
# 2. Accept ToS at https://polymarket.com (connect EOA, accept when prompted)

# 3. Fund EOA with POL for the one-time approval tx
polygon-agent send-native --to <eoaAddress> --amount 0.1 --broadcast

# 3. Set proxy wallet approvals (one-time)
# 4. Set approvals (one-time, permanent)
polygon-agent polymarket approve --broadcast
# → save approveTxHash, wait for confirmation

# ── IF RETURNING USER (EOA has traded before) ────────────────────────────
# Skip all steps above. Go straight to trading.

# ── FIND A MARKET ────────────────────────────────────────────────────────

# 4. Search for markets
polygon-agent polymarket markets --search "fed rate" --limit 10
# 5. Search for markets
polygon-agent polymarket markets --search "bitcoin" --limit 10

# 5. Get details on a specific market
# 6. Get details on a specific market
polygon-agent polymarket market 0x<conditionId>
# → check: yesPrice, noPrice, negRisk, endDate
# → if negRisk: true → run approve --neg-risk --broadcast first

# ── ENTER A POSITION ────────────────────────────────────────────────────

# 6. Dry-run to confirm everything
# 7. Dry-run to confirm
polygon-agent polymarket clob-buy 0x<conditionId> YES 5
# → review: currentPrice, proxyWalletAddress, flow

# 7. Execute
# 8. Execute
polygon-agent polymarket clob-buy 0x<conditionId> YES 5 --broadcast
# → save orderId, check orderStatus === "matched"
# → check: orderStatus === "matched"

# ── MANAGE ──────────────────────────────────────────────────────────────

# 8. Check your positions
# 9. Check positions
polygon-agent polymarket positions
# → review: size (shares), curPrice, cashPnl, title, outcome
# → review: size (shares), curPrice, cashPnl

# 9. Sell when ready
# 10. Sell when ready
polygon-agent polymarket sell 0x<conditionId> YES <shares> --broadcast
# → orderStatus === "matched" means USDC.e is back in proxy wallet
```
Expand All @@ -287,12 +307,13 @@ polygon-agent polymarket sell 0x<conditionId> YES <shares> --broadcast
## Decision Logic for an Autonomous Agent

When deciding whether to buy:
1. Check `positions` — avoid doubling up on already-held positions
2. Check `markets` — use `yesPrice`/`noPrice` as probability inputs
3. Check `negRisk` — if `true`, verify neg-risk approvals were set
4. Check proxy wallet USDC.e balance before buying (use `proxy-wallet` to get address, then check balance externally or via `balances`)
5. Use `--skip-fund` if the proxy wallet already has enough USDC.e from a previous `clob-buy`
6. Always dry-run first, then broadcast
1. Run `proxy-wallet` — confirm EOA and proxy wallet addresses
2. Run `balances` — confirm smart wallet has at least $1 USDC.e
3. Check `positions` — avoid doubling up on already-held positions
4. Check `markets` — use `yesPrice`/`noPrice` as probability inputs
5. Check `negRisk` on the target market — if `true`, verify neg-risk approvals were set
6. Use `--skip-fund` if the proxy wallet already has enough USDC.e from a previous attempt
7. Always dry-run first, then broadcast

When deciding whether to sell:
1. Get current `size` (shares) from `positions`
Expand All @@ -307,24 +328,25 @@ When deciding whether to sell:
| Error | Cause | Fix |
|-------|-------|-----|
| `No EOA key found` | `set-key` not run | Run `polygon-agent polymarket set-key <pk>` |
| `Could not create api key` (stderr) | ToS not accepted | Visit polymarket.com, connect EOA wallet, accept terms. This error in **stderr** is non-fatal — the CLI retries with `deriveApiKey` and may still succeed. |
| `CLOB order error: not authorized` | ToS not accepted | Same as above — fatal for order posting |
| `Could not create api key` (stderr only) | ToS not accepted | Non-fatal — CLI retries with `deriveApiKey` and may still succeed. If orders fail too, visit polymarket.com and accept ToS with the EOA |
| `CLOB order error: not authorized` | ToS not accepted | Visit polymarket.com, connect EOA wallet, accept terms |
| `insufficient funds for gas` | EOA has no POL | `polygon-agent send-native --to <eoaAddress> --amount 0.1 --broadcast` |
| `execution reverted: must be called be owner` | Old code calling proxy directly | Upgrade CLI — fixed in current version (calls factory) |
| `Market not found` | Low-volume or closed market | Market may have resolved; try `--search` with different terms |
| `Market has no tokenIds` | Closed market | Check `endDate` — market resolved |
| `orderStatus: "unmatched"` on FOK | No liquidity at market price | Try `--fak` for partial fill, or `--price 0.x` for limit order |
| `invalid amount for a marketable BUY order ($X), min size: $1` | Amount below CLOB minimum | Use at least $1. If USDC.e was already funded, retry with `--skip-fund` |
| `Wallet not found: main` | No Sequence wallet | Run `polygon-agent wallet create` |
| `No signer supported for call` | Wallet session missing USDC.e whitelist | Re-create wallet session: `polygon-agent wallet create --name main` |

---

## Key Facts for Agents

- **All commands are dry-run by default.** `approve`, `clob-buy`, `sell` do nothing without `--broadcast`.
- **Approvals are one-time and permanent.** If the EOA has traded before, skip `approve` entirely.
- **`clob-buy` transfers USDC.e from the smart wallet to the proxy wallet automatically** (unless `--skip-fund`).
- **Positions live in the proxy wallet**, not the Sequence smart wallet. `positions` queries the proxy wallet.
- **Approvals are one-time.** Don't run `approve` before every trade — only once per EOA (and once more if enabling neg-risk).
- **Sell is free.** No gas, no on-chain tx. Selling via CLOB is a signed off-chain message only.
- **`orderStatus: "matched"`** means the trade filled. `"unmatched"` means FOK failed (no liquidity).
- **The proxy wallet address never changes.** It is deterministic from the EOA via CREATE2.
- **`Could not create api key` in stderr is non-fatal.** The CLI handles this automatically.
Loading