@varla/polymarket 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +243 -0
- package/LICENSE +21 -0
- package/README.md +354 -0
- package/dist/index.js +7657 -0
- package/package.json +57 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# AGENTS.md - AI Coding Assistant Instructions
|
|
2
|
+
|
|
3
|
+
This file provides context for AI coding assistants (Cursor, Cline, Copilot, etc.) working on `@varla/polymarket`.
|
|
4
|
+
|
|
5
|
+
## Package Overview
|
|
6
|
+
|
|
7
|
+
`@varla/polymarket` is a high-performance Polymarket SDK that's **139% faster** than the official `@polymarket/clob-client`. It provides full trading support for Polymarket's CLOB and Gamma APIs.
|
|
8
|
+
|
|
9
|
+
## Tech Stack
|
|
10
|
+
|
|
11
|
+
| Technology | Purpose |
|
|
12
|
+
|------------|---------|
|
|
13
|
+
| **Bun** | Runtime & package manager (not Node.js) |
|
|
14
|
+
| **viem** | Ethereum wallet/signing (not ethers.js) |
|
|
15
|
+
| **Web Crypto API** | HMAC/SHA256 (not node:crypto) |
|
|
16
|
+
| **fetch** | HTTP (not axios) |
|
|
17
|
+
| **SQLite** | Order persistence (via @varla/db) |
|
|
18
|
+
| **Biome** | Linting & formatting |
|
|
19
|
+
|
|
20
|
+
## Critical Rules
|
|
21
|
+
|
|
22
|
+
### ❌ DO NOT USE
|
|
23
|
+
```typescript
|
|
24
|
+
// Node.js APIs - will fail in Bun/edge
|
|
25
|
+
import crypto from "node:crypto";
|
|
26
|
+
import fs from "node:fs";
|
|
27
|
+
import { Buffer } from "node:buffer";
|
|
28
|
+
|
|
29
|
+
// ethers.js - we use viem
|
|
30
|
+
import { ethers } from "ethers";
|
|
31
|
+
|
|
32
|
+
// axios - we use fetch
|
|
33
|
+
import axios from "axios";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### ✅ DO USE
|
|
37
|
+
```typescript
|
|
38
|
+
// Web Crypto API
|
|
39
|
+
const key = await crypto.subtle.importKey(...);
|
|
40
|
+
const sig = await crypto.subtle.sign("HMAC", key, data);
|
|
41
|
+
|
|
42
|
+
// viem for wallets
|
|
43
|
+
import { createWalletClient, http } from "viem";
|
|
44
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
45
|
+
|
|
46
|
+
// Native fetch
|
|
47
|
+
const res = await fetch(url, { headers });
|
|
48
|
+
|
|
49
|
+
// Bun file APIs
|
|
50
|
+
const file = Bun.file("path");
|
|
51
|
+
await Bun.write("path", content);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Project Structure
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
packages/polymarket/
|
|
58
|
+
├── src/
|
|
59
|
+
│ ├── index.ts # Public exports
|
|
60
|
+
│ ├── clob-client.ts # Public CLOB API (read-only)
|
|
61
|
+
│ ├── clob-trading-client.ts # Authenticated trading
|
|
62
|
+
│ ├── clob-auth.ts # API key management, EIP712 auth
|
|
63
|
+
│ ├── clob-orders.ts # Order building & signing
|
|
64
|
+
│ ├── clob-persistence.ts # SQLite order tracking
|
|
65
|
+
│ ├── clob-ws.ts # WebSocket client
|
|
66
|
+
│ ├── gamma-client.ts # Gamma API (markets, metadata)
|
|
67
|
+
│ ├── signing/ # HMAC & EIP712 signatures
|
|
68
|
+
│ ├── config/ # Contract addresses, endpoints
|
|
69
|
+
│ └── abi/ # Contract ABIs
|
|
70
|
+
├── test/
|
|
71
|
+
│ ├── unit/ # Deterministic unit tests
|
|
72
|
+
│ ├── integration/ # Network mocking tests
|
|
73
|
+
│ ├── sdk/ # Parity tests vs official SDK
|
|
74
|
+
│ ├── live/ # Real API tests (optional)
|
|
75
|
+
│ └── bench/ # Performance benchmarks
|
|
76
|
+
└── docs/
|
|
77
|
+
└── SDK_COMPARISON.md # Official SDK comparison
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Key Patterns
|
|
81
|
+
|
|
82
|
+
### EIP712 Signing (Orders & Auth)
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// Use viem's signTypedData
|
|
86
|
+
const signature = await walletClient.signTypedData({
|
|
87
|
+
account,
|
|
88
|
+
domain: { name: "...", chainId: 137 },
|
|
89
|
+
types: { ... },
|
|
90
|
+
primaryType: "...",
|
|
91
|
+
message: { ... },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### HMAC Signing (API Requests)
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// Use Web Crypto API
|
|
99
|
+
export async function buildPolyHmacSignature(params: {
|
|
100
|
+
secret: string;
|
|
101
|
+
timestamp: number;
|
|
102
|
+
method: string;
|
|
103
|
+
path: string;
|
|
104
|
+
body?: string;
|
|
105
|
+
}): Promise<string> {
|
|
106
|
+
const message = `${params.timestamp}${params.method}${params.path}${params.body ?? ""}`;
|
|
107
|
+
const key = await crypto.subtle.importKey(
|
|
108
|
+
"raw",
|
|
109
|
+
base64ToUint8Array(params.secret),
|
|
110
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
111
|
+
false,
|
|
112
|
+
["sign"]
|
|
113
|
+
);
|
|
114
|
+
const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message));
|
|
115
|
+
return btoa(String.fromCharCode(...new Uint8Array(sig)));
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### HTTP Requests
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// Always use native fetch with proper error handling
|
|
123
|
+
const response = await fetch(url, {
|
|
124
|
+
method: "POST",
|
|
125
|
+
headers: {
|
|
126
|
+
"Content-Type": "application/json",
|
|
127
|
+
...this.buildAuthHeaders(timestamp, method, path, body),
|
|
128
|
+
},
|
|
129
|
+
body: JSON.stringify(payload),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
throw new ClobHttpError(response.status, await response.text());
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Testing
|
|
138
|
+
|
|
139
|
+
### Run Tests
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# All unit tests
|
|
143
|
+
bun test packages/polymarket/test/unit
|
|
144
|
+
|
|
145
|
+
# All tests (including integration)
|
|
146
|
+
bun test packages/polymarket
|
|
147
|
+
|
|
148
|
+
# With coverage
|
|
149
|
+
bun test packages/polymarket --coverage
|
|
150
|
+
|
|
151
|
+
# Run benchmarks
|
|
152
|
+
POLYMARKET_BENCH=true bun test packages/polymarket/test/sdk
|
|
153
|
+
|
|
154
|
+
# Live tests (requires API keys)
|
|
155
|
+
POLYMARKET_LIVE_TESTS=1 bun test packages/polymarket/test/live
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Test Patterns
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { describe, test, expect, beforeEach, mock } from "bun:test";
|
|
162
|
+
|
|
163
|
+
describe("Feature", () => {
|
|
164
|
+
test("does X", async () => {
|
|
165
|
+
// Arrange
|
|
166
|
+
const input = ...;
|
|
167
|
+
|
|
168
|
+
// Act
|
|
169
|
+
const result = await fn(input);
|
|
170
|
+
|
|
171
|
+
// Assert
|
|
172
|
+
expect(result).toEqual(...);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Common Tasks
|
|
178
|
+
|
|
179
|
+
### Add New API Method
|
|
180
|
+
|
|
181
|
+
1. Add type to `src/clob-trading-types.ts`
|
|
182
|
+
2. Add method to `src/clob-trading-client.ts`
|
|
183
|
+
3. Add test to `test/unit/clob-trading-client.test.ts`
|
|
184
|
+
4. Update `src/index.ts` exports if needed
|
|
185
|
+
|
|
186
|
+
### Add New Config
|
|
187
|
+
|
|
188
|
+
1. Add to `src/config/*.ts`
|
|
189
|
+
2. Export from `src/config/index.ts`
|
|
190
|
+
3. Re-export from `src/index.ts`
|
|
191
|
+
|
|
192
|
+
### Debug Signature Issues
|
|
193
|
+
|
|
194
|
+
1. Run SDK comparison test: `bun test test/sdk/reference-examples.test.ts -t "signing"`
|
|
195
|
+
2. Compare with `.reference/clob-client-repo/tests/` fixtures
|
|
196
|
+
3. Check EIP712 domain/types match exactly
|
|
197
|
+
|
|
198
|
+
## Performance
|
|
199
|
+
|
|
200
|
+
Our SDK is significantly faster than the official SDK:
|
|
201
|
+
|
|
202
|
+
| Metric | Value |
|
|
203
|
+
|--------|-------|
|
|
204
|
+
| Average speedup | **139%** |
|
|
205
|
+
| Functions faster | 81/88 (92%) |
|
|
206
|
+
| Best case | 1233% faster (RFQ cancel) |
|
|
207
|
+
|
|
208
|
+
Key optimizations:
|
|
209
|
+
- Native fetch vs axios
|
|
210
|
+
- Web Crypto vs node:crypto polyfills
|
|
211
|
+
- viem vs ethers.js
|
|
212
|
+
- Zero unnecessary serialization
|
|
213
|
+
|
|
214
|
+
## Environment Variables
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Required for trading
|
|
218
|
+
POLYMARKET_API_KEY=...
|
|
219
|
+
POLYMARKET_SECRET=...
|
|
220
|
+
POLYMARKET_PASSPHRASE=...
|
|
221
|
+
|
|
222
|
+
# Required for signing orders
|
|
223
|
+
PRIVATE_KEY=0x...
|
|
224
|
+
|
|
225
|
+
# Optional
|
|
226
|
+
POLYMARKET_BASE_URL=https://clob.polymarket.com # default
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Useful Commands
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Format code
|
|
233
|
+
bun x biome format --write packages/polymarket
|
|
234
|
+
|
|
235
|
+
# Lint
|
|
236
|
+
bun x biome check packages/polymarket
|
|
237
|
+
|
|
238
|
+
# Type check
|
|
239
|
+
bun run typecheck
|
|
240
|
+
|
|
241
|
+
# Check no Node imports
|
|
242
|
+
bun run check:no-node-imports
|
|
243
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Varla
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# @varla/polymarket
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@varla/polymarket)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/Varla-xyz/varla-api/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
**High-performance Polymarket SDK** — 139% faster than the official SDK.
|
|
8
|
+
|
|
9
|
+
A modern, lightweight TypeScript client for Polymarket's CLOB and Gamma APIs with full trading support.
|
|
10
|
+
|
|
11
|
+
## Why @varla/polymarket?
|
|
12
|
+
|
|
13
|
+
| Metric | @varla/polymarket | @polymarket/clob-client |
|
|
14
|
+
|--------|-------------------|-------------------------|
|
|
15
|
+
| **Average Speed** | **139% faster** | baseline |
|
|
16
|
+
| **Bundle Size** | ~50KB | ~500KB (ethers.js) |
|
|
17
|
+
| **Runtime** | Bun/Node/Edge | Node.js only |
|
|
18
|
+
| **Signing** | viem (native) | ethers.js |
|
|
19
|
+
| **HTTP** | fetch | axios |
|
|
20
|
+
|
|
21
|
+
### Benchmark Highlights
|
|
22
|
+
|
|
23
|
+
| Function | Speedup |
|
|
24
|
+
|----------|---------|
|
|
25
|
+
| `getLastTradePrice` | 261% faster |
|
|
26
|
+
| `getMidpoints` | 176% faster |
|
|
27
|
+
| `deleteApiKey` | 144% faster |
|
|
28
|
+
| `cancelOrder` | 73% faster |
|
|
29
|
+
| `getOpenOrders` | 56% faster |
|
|
30
|
+
|
|
31
|
+
<details>
|
|
32
|
+
<summary>Full benchmark results (88 functions)</summary>
|
|
33
|
+
|
|
34
|
+
- **81 functions faster** (92%)
|
|
35
|
+
- **7 functions slower** (8%)
|
|
36
|
+
- Best case: 1233% faster (RFQ operations)
|
|
37
|
+
|
|
38
|
+
Run benchmarks yourself:
|
|
39
|
+
```bash
|
|
40
|
+
POLYMARKET_BENCH=true bun test packages/polymarket/test/sdk
|
|
41
|
+
```
|
|
42
|
+
</details>
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
bun add @varla/polymarket
|
|
48
|
+
# or
|
|
49
|
+
npm install @varla/polymarket
|
|
50
|
+
# or
|
|
51
|
+
pnpm add @varla/polymarket
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Peer dependencies:**
|
|
55
|
+
- `viem` ^2.0.0
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
### Read-Only (No Auth Required)
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { GammaClient, ClobClient } from "@varla/polymarket";
|
|
63
|
+
|
|
64
|
+
// Fetch markets from Gamma API
|
|
65
|
+
const gamma = new GammaClient();
|
|
66
|
+
const markets = await gamma.getMarkets({ limit: 10 });
|
|
67
|
+
|
|
68
|
+
// Get orderbook from CLOB
|
|
69
|
+
const clob = new ClobClient();
|
|
70
|
+
const book = await clob.getBook(markets[0].clobTokenIds[0]);
|
|
71
|
+
console.log("Best bid:", book.bids[0]);
|
|
72
|
+
console.log("Best ask:", book.asks[0]);
|
|
73
|
+
|
|
74
|
+
// Get prices
|
|
75
|
+
const midpoint = await clob.getMidpoint(markets[0].clobTokenIds[0]);
|
|
76
|
+
const spread = await clob.getSpread(markets[0].clobTokenIds[0]);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Authenticated Trading
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { createWalletClient, http } from "viem";
|
|
83
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
84
|
+
import { polygon } from "viem/chains";
|
|
85
|
+
import { ClobTradingClient } from "@varla/polymarket";
|
|
86
|
+
|
|
87
|
+
// Create wallet
|
|
88
|
+
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
|
|
89
|
+
const walletClient = createWalletClient({
|
|
90
|
+
account,
|
|
91
|
+
chain: polygon,
|
|
92
|
+
transport: http(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Create trading client
|
|
96
|
+
const client = new ClobTradingClient(walletClient);
|
|
97
|
+
await client.init(); // Derives API key from wallet
|
|
98
|
+
|
|
99
|
+
// Place a limit order
|
|
100
|
+
const response = await client.createAndPostOrder(
|
|
101
|
+
{
|
|
102
|
+
tokenId: "123456...", // From Gamma API
|
|
103
|
+
price: 0.50, // $0.50 per share
|
|
104
|
+
size: 100, // 100 shares
|
|
105
|
+
side: "BUY",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
tickSize: "0.01", // From Gamma API
|
|
109
|
+
negRisk: false, // From Gamma API
|
|
110
|
+
},
|
|
111
|
+
"GTC" // Good-Til-Cancelled
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
console.log("Order ID:", response.orderID);
|
|
115
|
+
|
|
116
|
+
// Cancel order
|
|
117
|
+
await client.cancelOrder(response.orderID);
|
|
118
|
+
|
|
119
|
+
// Get open orders
|
|
120
|
+
const orders = await client.getOpenOrders();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### WebSocket (Real-time Updates)
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { ClobWsClient } from "@varla/polymarket";
|
|
127
|
+
|
|
128
|
+
const ws = new ClobWsClient({
|
|
129
|
+
onBookUpdate: (update) => {
|
|
130
|
+
console.log("Market:", update.market);
|
|
131
|
+
console.log("Best bid:", update.bids[0]);
|
|
132
|
+
console.log("Best ask:", update.asks[0]);
|
|
133
|
+
},
|
|
134
|
+
onConnect: () => console.log("Connected"),
|
|
135
|
+
onDisconnect: (reason) => console.log("Disconnected:", reason),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
ws.connect();
|
|
139
|
+
ws.subscribeMarket("0x5f65177b394277fd294cd75650044e32ba009a95...");
|
|
140
|
+
|
|
141
|
+
// Cleanup
|
|
142
|
+
ws.close();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Order Persistence (SQLite)
|
|
146
|
+
|
|
147
|
+
Track orders locally for fast queries and restart recovery:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import {
|
|
151
|
+
ClobTradingClient,
|
|
152
|
+
createSqliteOrderPersistence,
|
|
153
|
+
createTrackedOrder,
|
|
154
|
+
} from "@varla/polymarket";
|
|
155
|
+
|
|
156
|
+
const persistence = createSqliteOrderPersistence("./orders.db");
|
|
157
|
+
|
|
158
|
+
// Track placed orders
|
|
159
|
+
const order = createTrackedOrder({
|
|
160
|
+
orderId: response.orderID,
|
|
161
|
+
market: "0x...",
|
|
162
|
+
tokenId: "123456...",
|
|
163
|
+
side: "BUY",
|
|
164
|
+
price: 0.5,
|
|
165
|
+
size: 100,
|
|
166
|
+
orderType: "GTC",
|
|
167
|
+
status: "OPEN",
|
|
168
|
+
});
|
|
169
|
+
await persistence.save(order);
|
|
170
|
+
|
|
171
|
+
// Query orders
|
|
172
|
+
const openOrders = await persistence.getOpen();
|
|
173
|
+
const marketOrders = await persistence.getByMarket("0x...");
|
|
174
|
+
|
|
175
|
+
// Cleanup old orders
|
|
176
|
+
await persistence.prune(24 * 60 * 60 * 1000); // 24h
|
|
177
|
+
|
|
178
|
+
persistence.close();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## API Reference
|
|
182
|
+
|
|
183
|
+
### Clients
|
|
184
|
+
|
|
185
|
+
| Client | Purpose |
|
|
186
|
+
|--------|---------|
|
|
187
|
+
| `GammaClient` | Market discovery, metadata, token IDs |
|
|
188
|
+
| `ClobClient` | Public orderbook, prices, trades (read-only) |
|
|
189
|
+
| `ClobTradingClient` | Authenticated trading operations |
|
|
190
|
+
| `ClobWsClient` | Real-time WebSocket updates |
|
|
191
|
+
|
|
192
|
+
### ClobTradingClient Methods
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// Initialization
|
|
196
|
+
client.init() // Derive/create API key
|
|
197
|
+
client.setCredentials(creds) // Set API key manually
|
|
198
|
+
|
|
199
|
+
// Orders
|
|
200
|
+
client.createOrder(params, options) // Create signed order
|
|
201
|
+
client.postOrder(order, type) // Post to CLOB
|
|
202
|
+
client.createAndPostOrder(params, options, type) // Combined
|
|
203
|
+
client.getOrder(orderId) // Get order details
|
|
204
|
+
client.getOpenOrders(filter?) // List open orders
|
|
205
|
+
|
|
206
|
+
// Cancellation
|
|
207
|
+
client.cancelOrder(orderId) // Cancel one order
|
|
208
|
+
client.cancelOrders(orderIds) // Cancel multiple
|
|
209
|
+
client.cancelMarketOrders({ market }) // Cancel by market
|
|
210
|
+
client.cancelAll() // Cancel all orders
|
|
211
|
+
|
|
212
|
+
// Account
|
|
213
|
+
client.getClosedOnlyMode() // Check if account is restricted
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Order Types
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
type Side = "BUY" | "SELL";
|
|
220
|
+
type OrderType = "GTC" | "GTD" | "FOK"; // Good-Til-Cancel, Good-Til-Date, Fill-Or-Kill
|
|
221
|
+
type OrderStatus = "OPEN" | "MATCHED" | "FILLED" | "CANCELLED" | "EXPIRED";
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Configuration
|
|
225
|
+
|
|
226
|
+
### Environment Variables
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# For authenticated trading
|
|
230
|
+
POLYMARKET_API_KEY=...
|
|
231
|
+
POLYMARKET_SECRET=...
|
|
232
|
+
POLYMARKET_PASSPHRASE=...
|
|
233
|
+
|
|
234
|
+
# For signing orders
|
|
235
|
+
PRIVATE_KEY=0x...
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Custom Endpoints
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const client = new ClobTradingClient(walletClient, {
|
|
242
|
+
baseUrl: "https://clob.polymarket.com", // default
|
|
243
|
+
requestTimeoutMs: 15000,
|
|
244
|
+
maxRetries: 3,
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Signature Types
|
|
249
|
+
|
|
250
|
+
| Type | Value | Use Case |
|
|
251
|
+
|------|-------|----------|
|
|
252
|
+
| EOA | 0 | Direct wallet (Metamask, Rabby, hardware) |
|
|
253
|
+
| POLY_PROXY | 1 | Polymarket Magic/Email login |
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// For Magic/Email wallets
|
|
257
|
+
const client = new ClobTradingClient(walletClient, {
|
|
258
|
+
signatureType: 1, // POLY_PROXY
|
|
259
|
+
funderAddress: "0x...", // Your Polymarket profile address
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Error Handling
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
import { OrderValidationError, ClobHttpError } from "@varla/polymarket";
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
await client.createAndPostOrder(params, options, "GTC");
|
|
270
|
+
} catch (error) {
|
|
271
|
+
if (error instanceof OrderValidationError) {
|
|
272
|
+
console.error("Invalid order:", error.message);
|
|
273
|
+
} else if (error instanceof ClobHttpError) {
|
|
274
|
+
if (error.status === 401) {
|
|
275
|
+
// API key expired, reinitialize
|
|
276
|
+
await client.init();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Validation Utilities
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import {
|
|
286
|
+
validateOrderParams,
|
|
287
|
+
roundToTickSize,
|
|
288
|
+
isValidPrice,
|
|
289
|
+
getMinimumOrderSize,
|
|
290
|
+
} from "@varla/polymarket";
|
|
291
|
+
|
|
292
|
+
// Validate before creating
|
|
293
|
+
validateOrderParams(params, options); // throws OrderValidationError
|
|
294
|
+
|
|
295
|
+
// Round to valid tick
|
|
296
|
+
const price = roundToTickSize(0.505, "0.01"); // 0.51
|
|
297
|
+
|
|
298
|
+
// Check price validity
|
|
299
|
+
isValidPrice(0.505, "0.01"); // false
|
|
300
|
+
|
|
301
|
+
// Get minimum shares for $1 order
|
|
302
|
+
getMinimumOrderSize(0.5); // 2 shares
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Testing
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Unit tests
|
|
309
|
+
bun test packages/polymarket/test/unit
|
|
310
|
+
|
|
311
|
+
# All tests
|
|
312
|
+
bun test packages/polymarket
|
|
313
|
+
|
|
314
|
+
# With coverage
|
|
315
|
+
bun test packages/polymarket --coverage
|
|
316
|
+
|
|
317
|
+
# Benchmarks (compare with official SDK)
|
|
318
|
+
POLYMARKET_BENCH=true bun test packages/polymarket/test/sdk
|
|
319
|
+
|
|
320
|
+
# Live tests (requires API keys)
|
|
321
|
+
POLYMARKET_LIVE_TESTS=1 bun test packages/polymarket/test/live
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Architecture
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
328
|
+
│ ClobTradingClient │
|
|
329
|
+
│ - init(), createAndPostOrder(), cancelOrder(), etc. │
|
|
330
|
+
├─────────────────────┬───────────────────┬───────────────────┤
|
|
331
|
+
│ ClobAuthManager │ ClobOrderBuilder │ HTTP + Auth │
|
|
332
|
+
│ - L1/L2 auth │ - EIP712 signing │ - HMAC headers │
|
|
333
|
+
│ - API key mgmt │ - Validation │ │
|
|
334
|
+
├─────────────────────┴───────────────────┴───────────────────┤
|
|
335
|
+
│ viem WalletClient │
|
|
336
|
+
│ (signTypedData, etc.) │
|
|
337
|
+
└─────────────────────────────────────────────────────────────┘
|
|
338
|
+
|
|
339
|
+
┌──────────────────┐ ┌─────────────────┐ ┌────────────────┐
|
|
340
|
+
│ OrderPersistence │ │ ClobWsClient │ │ GammaClient │
|
|
341
|
+
│ - SQLite/Memory │ │ - WebSocket │ │ - Markets │
|
|
342
|
+
│ - Order tracking │ │ - Book updates │ │ - Metadata │
|
|
343
|
+
└──────────────────┘ └─────────────────┘ └────────────────┘
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Related Packages
|
|
347
|
+
|
|
348
|
+
- [`@varla/db`](../db) - SQLite persistence layer
|
|
349
|
+
- [`@varla/rpc`](../rpc) - Resilient RPC client
|
|
350
|
+
- [`@varla/runtime`](../runtime) - Service runtime utilities
|
|
351
|
+
|
|
352
|
+
## License
|
|
353
|
+
|
|
354
|
+
MIT © [Varla](https://varla.xyz)
|