@structbuild/sdk 0.2.11 → 0.3.1
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 +189 -34
- package/dist/generated/polymarket.d.ts +629 -101
- package/dist/generated/webhooks.d.ts +397 -65
- package/dist/generated/ws-alerts.d.ts +2599 -0
- package/dist/generated/ws.d.ts +921 -0
- package/dist/index.cjs +545 -179
- package/dist/index.cjs.map +6 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +545 -179
- package/dist/index.js.map +6 -5
- package/dist/types/http.d.ts +1 -0
- package/dist/types/index.d.ts +45 -7
- package/dist/types/ws-helpers.d.ts +5 -0
- package/dist/types/ws.d.ts +119 -90
- package/dist/ws-alerts.d.ts +39 -0
- package/dist/ws-transport.d.ts +26 -7
- package/dist/ws.d.ts +27 -33
- package/package.json +8 -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
|
|
|
@@ -45,64 +43,113 @@ const client = new StructClient({
|
|
|
45
43
|
|
|
46
44
|
```typescript
|
|
47
45
|
const markets = await client.markets.getMarkets({ limit: 10 });
|
|
48
|
-
const market = await client.markets.getMarket({
|
|
49
|
-
const marketBySlug = await client.markets.getMarketBySlug({
|
|
50
|
-
const trades = await client.markets.getTrades({
|
|
51
|
-
const candles = await client.markets.getCandlestick({ condition_id: "0x...",
|
|
46
|
+
const market = await client.markets.getMarket({ conditionId: "0x..." });
|
|
47
|
+
const marketBySlug = await client.markets.getMarketBySlug({ marketSlug: "will-x-happen" });
|
|
48
|
+
const trades = await client.markets.getTrades({ condition_ids: "0x..." });
|
|
49
|
+
const candles = await client.markets.getCandlestick({ condition_id: "0x...", resolution: "1h" });
|
|
50
|
+
const chart = await client.markets.getMarketChart({ condition_id: "0x..." });
|
|
52
51
|
const metrics = await client.markets.getMarketMetrics({ condition_id: "0x..." });
|
|
53
52
|
const volumeChart = await client.markets.getMarketVolumeChart({ condition_id: "0x..." });
|
|
53
|
+
const priceJumps = await client.markets.getPriceJumps();
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### Events
|
|
57
57
|
|
|
58
58
|
```typescript
|
|
59
59
|
const events = await client.events.getEvents({ limit: 10 });
|
|
60
|
-
const event = await client.events.getEvent({
|
|
60
|
+
const event = await client.events.getEvent({ identifier: "123" });
|
|
61
61
|
const eventBySlug = await client.events.getEventBySlug({ slug: "us-election" });
|
|
62
|
-
const eventMetrics = await client.events.getEventMetrics({
|
|
62
|
+
const eventMetrics = await client.events.getEventMetrics({ event_slug: "us-election", timeframe: "24h" });
|
|
63
|
+
const outcomes = await client.events.getEventOutcomes({ event_slug: "us-election" });
|
|
64
|
+
const chart = await client.events.getEventChart({ event_slug: "us-election" });
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
### Trader / Portfolio
|
|
66
68
|
|
|
67
69
|
```typescript
|
|
68
|
-
const portfolio = await client.trader.getPortfolio({ address: "0x..." });
|
|
69
|
-
const positions = await client.trader.getPortfolioPositions({ address: "0x..." });
|
|
70
70
|
const trades = await client.trader.getTraderTrades({ address: "0x..." });
|
|
71
71
|
const profile = await client.trader.getTraderProfile({ address: "0x..." });
|
|
72
|
+
const profiles = await client.trader.getTraderProfilesBatch({ addresses: "0x...,0x..." });
|
|
72
73
|
const pnl = await client.trader.getTraderPnl({ address: "0x..." });
|
|
73
|
-
const
|
|
74
|
-
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..." });
|
|
75
77
|
const pnlCandles = await client.trader.getTraderPnlCandles({ address: "0x..." });
|
|
78
|
+
const pnlCalendar = await client.trader.getTraderPnlCalendar({ address: "0x..." });
|
|
76
79
|
const volumeChart = await client.trader.getTraderVolumeChart({ address: "0x..." });
|
|
80
|
+
const leaderboard = await client.trader.getGlobalPnl();
|
|
77
81
|
```
|
|
78
82
|
|
|
79
83
|
### Holders
|
|
80
84
|
|
|
81
85
|
```typescript
|
|
82
86
|
const marketHolders = await client.holders.getMarketHolders({ condition_id: "0x..." });
|
|
83
|
-
const
|
|
84
|
-
const positionHolders = await client.holders.getPositionHolders({ position_id: "123" });
|
|
87
|
+
const positionHolders = await client.holders.getPositionHolders({ positionId: "123" });
|
|
85
88
|
const history = await client.holders.getMarketHoldersHistory({ condition_id: "0x..." });
|
|
89
|
+
const posHistory = await client.holders.getPositionHoldersHistory({ positionId: "123" });
|
|
86
90
|
```
|
|
87
91
|
|
|
88
|
-
###
|
|
92
|
+
### Order Book
|
|
89
93
|
|
|
90
94
|
```typescript
|
|
91
|
-
const
|
|
92
|
-
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();
|
|
93
99
|
```
|
|
94
100
|
|
|
95
|
-
### Search, Tags, Bonds
|
|
101
|
+
### Series, Search, Tags, Assets, Bonds
|
|
96
102
|
|
|
97
103
|
```typescript
|
|
104
|
+
const series = await client.series.getSeriesList();
|
|
105
|
+
const outcomes = await client.series.getSeriesOutcomes({ series_slug: "my-series" });
|
|
106
|
+
const assetHistory = await client.assets.getAssetHistory({ symbol: "BTC", variant: "1d" });
|
|
98
107
|
const results = await client.search.search({ query: "election" });
|
|
99
108
|
const tags = await client.tags.getTags();
|
|
109
|
+
const tag = await client.tags.getTag({ identifier: "politics" });
|
|
100
110
|
const bonds = await client.bonds.getBonds();
|
|
101
111
|
```
|
|
102
112
|
|
|
113
|
+
### Trade Types
|
|
114
|
+
|
|
115
|
+
Trade endpoints (`getTrades`, `getTraderTrades`) return a discriminated union of all on-chain event types. Use the `trade_type` field to narrow:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import type { Trade, MarketTrade, OracleEvent, TradeEventType } from "@structbuild/sdk";
|
|
119
|
+
|
|
120
|
+
const { data: trades } = await client.markets.getTrades();
|
|
121
|
+
|
|
122
|
+
for (const trade of trades) {
|
|
123
|
+
switch (trade.trade_type) {
|
|
124
|
+
case "OrderFilled":
|
|
125
|
+
case "OrdersMatched":
|
|
126
|
+
console.log(trade.price, trade.usd_amount, trade.shares_amount);
|
|
127
|
+
break;
|
|
128
|
+
case "Redemption":
|
|
129
|
+
console.log(trade.winning_outcome_index, trade.position_details);
|
|
130
|
+
break;
|
|
131
|
+
case "Merge":
|
|
132
|
+
case "Split":
|
|
133
|
+
console.log(trade.usd_amount, trade.position_details);
|
|
134
|
+
break;
|
|
135
|
+
case "Resolution":
|
|
136
|
+
console.log(trade.payout_numerators);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The SDK exports convenience sub-unions for common filtering:
|
|
143
|
+
|
|
144
|
+
- **`MarketTrade`** — actual on-chain trades: `OrderFilled`, `OrdersMatched`, `Redemption`, `Merge`, `Split`, `PositionsConverted`, `Cancelled`, `RegisterToken`, `Approval`
|
|
145
|
+
- **`OracleEvent`** — protocol lifecycle events: `Initialization`, `Proposal`, `Dispute`, `Settled`, `Resolution`, `ConditionResolution`, `Reset`, `Flag`, `Unflag`, `Pause`, `Unpause`, `ManualResolution`, `NegRiskOutcomeReported`
|
|
146
|
+
- **`TradeEventType`** — string literal union of all `trade_type` values for autocomplete
|
|
147
|
+
|
|
148
|
+
Individual schemas are also exported: `OrderFilledTrade`, `RedemptionTrade`, `MergeTrade`, `SplitTrade`, `CancelledTrade`, `PositionsConvertedTrade`, `RegisterTokenTrade`, `ApprovalTrade`, and all oracle event types.
|
|
149
|
+
|
|
103
150
|
### Webhooks
|
|
104
151
|
|
|
105
|
-
Manage webhook subscriptions for real-time event notifications
|
|
152
|
+
Manage webhook subscriptions for real-time event notifications:
|
|
106
153
|
|
|
107
154
|
```typescript
|
|
108
155
|
const webhooks = await client.webhooks.list();
|
|
@@ -114,30 +161,129 @@ const webhook = await client.webhooks.create({
|
|
|
114
161
|
min_usd_value: 100,
|
|
115
162
|
},
|
|
116
163
|
});
|
|
117
|
-
const detail = await client.webhooks.getWebhook({ webhookId: webhook.data.id });
|
|
118
|
-
await client.webhooks.update({ webhookId: webhook.data.id, events: ["first_trade"] });
|
|
119
164
|
await client.webhooks.test({ webhookId: webhook.data.id });
|
|
165
|
+
await client.webhooks.rotateSecret({ webhookId: webhook.data.id });
|
|
120
166
|
await client.webhooks.deleteWebhook({ webhookId: webhook.data.id });
|
|
167
|
+
const events = await client.webhooks.listEvents();
|
|
121
168
|
```
|
|
122
169
|
|
|
123
|
-
|
|
170
|
+
## WebSocket API
|
|
124
171
|
|
|
125
|
-
|
|
172
|
+
Real-time streaming via room-based subscriptions with fully typed filters, responses, and events.
|
|
126
173
|
|
|
127
174
|
```typescript
|
|
128
|
-
import
|
|
129
|
-
FirstTradePayload,
|
|
130
|
-
ProbabilitySpikePayload,
|
|
131
|
-
GlobalPnlPayload,
|
|
132
|
-
VolumeMilestonePayload,
|
|
133
|
-
} from "@structbuild/sdk";
|
|
175
|
+
import { StructWebSocket } from "@structbuild/sdk";
|
|
134
176
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
+
});
|
|
138
251
|
```
|
|
139
252
|
|
|
140
|
-
Available
|
|
253
|
+
### Available rooms
|
|
254
|
+
|
|
255
|
+
| Room | Filters | Event |
|
|
256
|
+
|------|---------|-------|
|
|
257
|
+
| `polymarket_trades` | `condition_ids` | `trade_stream_update` |
|
|
258
|
+
| `polymarket_asset_prices` | `condition_ids?` | `asset_price_tick`, `asset_price_window_update` |
|
|
259
|
+
| `polymarket_asset_window_updates` | `condition_ids` | `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` | `addresses` | `trader_global_pnl_update`, `trader_market_pnl_update`, `trader_event_pnl_update` |
|
|
264
|
+
| `polymarket_trader_positions` | `addresses` | `trader_position_update` |
|
|
265
|
+
| `polymarket_accounts` | `wallets` | `accounts_update`, `usdce_update`, `matic_update` |
|
|
266
|
+
| `polymarket_order_book` | `asset_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
|
+
```
|
|
141
287
|
|
|
142
288
|
## JWT Auth
|
|
143
289
|
|
|
@@ -161,6 +307,15 @@ const ws = new StructWebSocket({
|
|
|
161
307
|
|
|
162
308
|
The `pk_jwt_*` key is safe to hardcode in frontend bundles — it is useless without a valid JWT from your configured auth provider.
|
|
163
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
|
+
|
|
164
319
|
## Pagination
|
|
165
320
|
|
|
166
321
|
Use the `paginate` helper to iterate through all results:
|
|
@@ -184,7 +339,7 @@ for await (const market of paginate(
|
|
|
184
339
|
import { HttpError, TimeoutError, NetworkError } from "@structbuild/sdk";
|
|
185
340
|
|
|
186
341
|
try {
|
|
187
|
-
await client.markets.getMarket({
|
|
342
|
+
await client.markets.getMarket({ conditionId: "0x..." });
|
|
188
343
|
} catch (error) {
|
|
189
344
|
if (error instanceof HttpError) {
|
|
190
345
|
console.log(error.status, error.body);
|