@structbuild/sdk 0.3.0 → 0.3.2
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/README.md +160 -26
- package/dist/generated/polymarket.d.ts +307 -115
- package/dist/generated/webhooks.d.ts +123 -44
- package/dist/generated/ws-alerts.d.ts +2652 -0
- package/dist/generated/ws.d.ts +1221 -0
- package/dist/index.cjs +558 -181
- package/dist/index.cjs.map +9 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +558 -181
- package/dist/index.js.map +9 -8
- package/dist/namespaces/markets.d.ts +3 -3
- package/dist/namespaces/series.d.ts +2 -1
- package/dist/namespaces/trader.d.ts +4 -4
- package/dist/types/http.d.ts +1 -0
- package/dist/types/index.d.ts +7 -1
- package/dist/types/ws-helpers.d.ts +5 -0
- package/dist/types/ws.d.ts +128 -90
- package/dist/ws-alerts.d.ts +39 -0
- package/dist/ws-transport.d.ts +26 -7
- package/dist/ws.d.ts +28 -33
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -7,8 +7,6 @@ TypeScript SDK for prediction market data via [api.struct.to](https://api.struct
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @structbuild/sdk
|
|
9
9
|
# or
|
|
10
|
-
pnpm add @structbuild/sdk
|
|
11
|
-
# or
|
|
12
10
|
bun add @structbuild/sdk
|
|
13
11
|
```
|
|
14
12
|
|
|
@@ -73,11 +71,11 @@ const trades = await client.trader.getTraderTrades({ address: "0x..." });
|
|
|
73
71
|
const profile = await client.trader.getTraderProfile({ address: "0x..." });
|
|
74
72
|
const profiles = await client.trader.getTraderProfilesBatch({ addresses: "0x...,0x..." });
|
|
75
73
|
const pnl = await client.trader.getTraderPnl({ address: "0x..." });
|
|
76
|
-
const
|
|
77
|
-
const
|
|
74
|
+
const marketPnl = await client.trader.getTraderMarketPnl({ address: "0x..." });
|
|
75
|
+
const eventPnl = await client.trader.getTraderEventPnl({ address: "0x..." });
|
|
76
|
+
const outcomePnl = await client.trader.getTraderOutcomePnl({ address: "0x..." });
|
|
78
77
|
const pnlCandles = await client.trader.getTraderPnlCandles({ address: "0x..." });
|
|
79
|
-
const
|
|
80
|
-
const positionPnl = await client.trader.getTraderOutcomePnl({ address: "0x..." });
|
|
78
|
+
const pnlCalendar = await client.trader.getTraderPnlCalendar({ address: "0x..." });
|
|
81
79
|
const volumeChart = await client.trader.getTraderVolumeChart({ address: "0x..." });
|
|
82
80
|
const leaderboard = await client.trader.getGlobalPnl();
|
|
83
81
|
```
|
|
@@ -91,16 +89,20 @@ const history = await client.holders.getMarketHoldersHistory({ condition_id: "0x
|
|
|
91
89
|
const posHistory = await client.holders.getPositionHoldersHistory({ positionId: "123" });
|
|
92
90
|
```
|
|
93
91
|
|
|
94
|
-
###
|
|
92
|
+
### Order Book
|
|
95
93
|
|
|
96
94
|
```typescript
|
|
97
|
-
const
|
|
98
|
-
const
|
|
95
|
+
const orderBook = await client.orderBook.getOrderBook({ asset_id: "0x..." });
|
|
96
|
+
const history = await client.orderBook.getOrderBookHistory();
|
|
97
|
+
const marketBook = await client.orderBook.getMarketOrderBook();
|
|
98
|
+
const spreads = await client.orderBook.getSpreadHistory();
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
###
|
|
101
|
+
### Series, Search, Tags, Assets, Bonds
|
|
102
102
|
|
|
103
103
|
```typescript
|
|
104
|
+
const series = await client.series.getSeriesList();
|
|
105
|
+
const outcomes = await client.series.getSeriesOutcomes({ series_slug: "my-series" });
|
|
104
106
|
const assetHistory = await client.assets.getAssetHistory({ symbol: "BTC", variant: "1d" });
|
|
105
107
|
const results = await client.search.search({ query: "election" });
|
|
106
108
|
const tags = await client.tags.getTags();
|
|
@@ -147,7 +149,7 @@ Individual schemas are also exported: `OrderFilledTrade`, `RedemptionTrade`, `Me
|
|
|
147
149
|
|
|
148
150
|
### Webhooks
|
|
149
151
|
|
|
150
|
-
Manage webhook subscriptions for real-time event notifications
|
|
152
|
+
Manage webhook subscriptions for real-time event notifications:
|
|
151
153
|
|
|
152
154
|
```typescript
|
|
153
155
|
const webhooks = await client.webhooks.list();
|
|
@@ -159,32 +161,129 @@ const webhook = await client.webhooks.create({
|
|
|
159
161
|
min_usd_value: 100,
|
|
160
162
|
},
|
|
161
163
|
});
|
|
162
|
-
const detail = await client.webhooks.getWebhook({ webhookId: webhook.data.id });
|
|
163
|
-
await client.webhooks.update({ webhookId: webhook.data.id, events: ["first_trade"] });
|
|
164
164
|
await client.webhooks.test({ webhookId: webhook.data.id });
|
|
165
165
|
await client.webhooks.rotateSecret({ webhookId: webhook.data.id });
|
|
166
166
|
await client.webhooks.deleteWebhook({ webhookId: webhook.data.id });
|
|
167
167
|
const events = await client.webhooks.listEvents();
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
## WebSocket API
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
Real-time streaming via room-based subscriptions with fully typed filters, responses, and events.
|
|
173
173
|
|
|
174
174
|
```typescript
|
|
175
|
-
import
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
175
|
+
import { StructWebSocket } from "@structbuild/sdk";
|
|
176
|
+
|
|
177
|
+
const ws = new StructWebSocket({ apiKey: "your-api-key" });
|
|
178
|
+
await ws.connect();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Subscribing to rooms
|
|
182
|
+
|
|
183
|
+
Each room has typed filters and a typed subscribe response:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const res = await ws.subscribe("polymarket_trades", {
|
|
187
|
+
condition_ids: ["0xabc123"],
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
await ws.subscribe("polymarket_order_book", {
|
|
191
|
+
asset_ids: ["0xabc123"],
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Some rooms have optional filters
|
|
195
|
+
await ws.subscribe("polymarket_asset_prices");
|
|
196
|
+
await ws.subscribe("polymarket_clob_rewards", { subscribe_all: true });
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Listening for events
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
ws.on("trade_stream_update", (event) => {
|
|
203
|
+
event.condition_id;
|
|
204
|
+
event.price;
|
|
205
|
+
event.size;
|
|
206
|
+
event.side;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
ws.on("order_book_update", (event) => {
|
|
210
|
+
event.asset_id;
|
|
211
|
+
event.bids;
|
|
212
|
+
event.asks;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
ws.on("clob_rewards_update", (event) => {
|
|
216
|
+
event.event_type; // "added" | "removed" | "updated"
|
|
217
|
+
event.condition_id;
|
|
218
|
+
event.reward;
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Alerts
|
|
223
|
+
|
|
224
|
+
Alerts use a separate client with per-event typed filters and payloads:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { StructAlertsWebSocket } from "@structbuild/sdk";
|
|
228
|
+
|
|
229
|
+
const alerts = new StructAlertsWebSocket({ apiKey: "your-api-key" });
|
|
230
|
+
await alerts.connect();
|
|
231
|
+
|
|
232
|
+
await alerts.subscribe("trader_whale_trade", {
|
|
233
|
+
wallet_addresses: ["0xd91..."],
|
|
234
|
+
min_usd_value: 10000,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
await alerts.subscribe("probability_spike", {
|
|
238
|
+
spike_direction: "up",
|
|
239
|
+
min_probability_change_pct: 5,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
alerts.on("trader_whale_trade", (payload) => {
|
|
243
|
+
payload.data.trader;
|
|
244
|
+
payload.data.amount_usd;
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
alerts.on("probability_spike", (payload) => {
|
|
248
|
+
payload.data.spike_direction;
|
|
249
|
+
payload.data.spike_pct;
|
|
250
|
+
});
|
|
185
251
|
```
|
|
186
252
|
|
|
187
|
-
Available
|
|
253
|
+
### Available rooms
|
|
254
|
+
|
|
255
|
+
| Room | Filters | Event |
|
|
256
|
+
|------|---------|-------|
|
|
257
|
+
| `polymarket_trades` | `condition_ids?`, `market_slugs?`, `event_slugs?`, `position_ids?`, `traders?`, `trade_types?`, `status?`, `subscribe_all?` | `trade_stream_update` |
|
|
258
|
+
| `polymarket_asset_prices` | `asset_symbols?` | `asset_price_tick`, `asset_price_window_update` |
|
|
259
|
+
| `polymarket_asset_window_updates` | `asset_symbols?`, `timeframes?` | `asset_window_update` |
|
|
260
|
+
| `polymarket_market_metrics` | `condition_ids` | `market_metrics_update` |
|
|
261
|
+
| `polymarket_event_metrics` | `event_slugs` | `event_metrics_update` |
|
|
262
|
+
| `polymarket_position_metrics` | `position_ids` | `position_metrics_update` |
|
|
263
|
+
| `polymarket_trader_pnl` | `traders` | `trader_global_pnl_update`, `trader_market_pnl_update`, `trader_event_pnl_update` |
|
|
264
|
+
| `polymarket_trader_positions` | `traders` | `trader_position_update` |
|
|
265
|
+
| `polymarket_accounts` | `wallets`, `include_usdce?`, `include_matic?` | `accounts_update`, `usdce_update`, `matic_update` |
|
|
266
|
+
| `polymarket_order_book` | `condition_ids?`, `position_ids?` | `order_book_update` |
|
|
267
|
+
| `polymarket_clob_rewards` | `condition_ids?`, `subscribe_all?` | `clob_rewards_update` |
|
|
268
|
+
|
|
269
|
+
### Lifecycle events
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
ws.on("connected", () => {});
|
|
273
|
+
ws.on("disconnected", ({ code, reason }) => {});
|
|
274
|
+
ws.on("reconnecting", ({ attempt }) => {});
|
|
275
|
+
ws.on("reconnect_failed", (err) => {});
|
|
276
|
+
ws.on("auth_failed", (err) => {});
|
|
277
|
+
ws.on("warning", (warning) => {});
|
|
278
|
+
ws.on("error", (err) => {});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Cleanup
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
ws.unsubscribe("polymarket_trades");
|
|
285
|
+
ws.disconnect();
|
|
286
|
+
```
|
|
188
287
|
|
|
189
288
|
## JWT Auth
|
|
190
289
|
|
|
@@ -208,6 +307,15 @@ const ws = new StructWebSocket({
|
|
|
208
307
|
|
|
209
308
|
The `pk_jwt_*` key is safe to hardcode in frontend bundles — it is useless without a valid JWT from your configured auth provider.
|
|
210
309
|
|
|
310
|
+
If your JWT can rotate while a socket stays alive, prefer `getJwt` so reconnects always rebuild the URL with a fresh token:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const ws = new StructWebSocket({
|
|
314
|
+
apiKey: "pk_jwt_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
|
|
315
|
+
getJwt: () => userAccessToken,
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
211
319
|
## Pagination
|
|
212
320
|
|
|
213
321
|
Use the `paginate` helper to iterate through all results:
|
|
@@ -257,6 +365,32 @@ const client = new StructClient({
|
|
|
257
365
|
});
|
|
258
366
|
```
|
|
259
367
|
|
|
368
|
+
## Testing
|
|
369
|
+
|
|
370
|
+
WebSocket unit tests stay in the default fast suite:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
bun test
|
|
374
|
+
bun run typecheck
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
The live websocket soak test is opt-in and env-gated. It first calls the REST API to fetch a recent market, event, position, and trader, then subscribes across the main websocket rooms and keeps the socket alive for 5 minutes by default.
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
STRUCT_RUN_WS_LIVE_TESTS=1 \
|
|
381
|
+
STRUCT_API_KEY=your-api-key \
|
|
382
|
+
bun run test:ws:live
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
To run longer than 5 minutes, set `STRUCT_WS_SOAK_DURATION_MS`:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
STRUCT_RUN_WS_LIVE_TESTS=1 \
|
|
389
|
+
STRUCT_API_KEY=your-api-key \
|
|
390
|
+
STRUCT_WS_SOAK_DURATION_MS=420000 \
|
|
391
|
+
bun run test:ws:live
|
|
392
|
+
```
|
|
393
|
+
|
|
260
394
|
## License
|
|
261
395
|
|
|
262
396
|
MIT
|