@structbuild/sdk 0.3.1 → 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 CHANGED
@@ -254,16 +254,16 @@ alerts.on("probability_spike", (payload) => {
254
254
 
255
255
  | Room | Filters | Event |
256
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` |
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
260
  | `polymarket_market_metrics` | `condition_ids` | `market_metrics_update` |
261
261
  | `polymarket_event_metrics` | `event_slugs` | `event_metrics_update` |
262
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` |
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
267
  | `polymarket_clob_rewards` | `condition_ids?`, `subscribe_all?` | `clob_rewards_update` |
268
268
 
269
269
  ### Lifecycle events
@@ -365,6 +365,32 @@ const client = new StructClient({
365
365
  });
366
366
  ```
367
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
+
368
394
  ## License
369
395
 
370
396
  MIT
@@ -252,7 +252,7 @@ export interface paths {
252
252
  };
253
253
  /**
254
254
  * Get bonds
255
- * @description Retrieve a list of bond markets sorted by yield, filtered by probability and time to expiry
255
+ * @description Retrieve bond markets with sorting, probability range filter, and offset pagination
256
256
  */
257
257
  get: operations["get_bonds"];
258
258
  put?: never;
@@ -412,7 +412,7 @@ export interface paths {
412
412
  };
413
413
  /**
414
414
  * Get market by slug
415
- * @description Retrieve a single market by its slug with optional nested tags, event, and metrics
415
+ * @description Retrieve one or more markets by slug. Supports batch lookups via query params. Returns an array of MarketResponse objects.
416
416
  */
417
417
  get: operations["get_market_by_slug"];
418
418
  put?: never;
@@ -472,7 +472,7 @@ export interface paths {
472
472
  };
473
473
  /**
474
474
  * Get market by condition ID
475
- * @description Retrieve a single market by its condition ID with optional nested tags, event, and metrics
475
+ * @description Retrieve one or more markets by condition ID. Supports batch lookups via query params. Returns an array of MarketResponse objects.
476
476
  */
477
477
  get: operations["get_market"];
478
478
  put?: never;
@@ -623,6 +623,26 @@ export interface paths {
623
623
  patch?: never;
624
624
  trace?: never;
625
625
  };
626
+ "/polymarket/series/{identifier}/events": {
627
+ parameters: {
628
+ query?: never;
629
+ header?: never;
630
+ path?: never;
631
+ cookie?: never;
632
+ };
633
+ /**
634
+ * Get series events
635
+ * @description Returns a paginated list of events belonging to a specific Polymarket series, with full market data for each event.
636
+ */
637
+ get: operations["get_series_events"];
638
+ put?: never;
639
+ post?: never;
640
+ delete?: never;
641
+ options?: never;
642
+ head?: never;
643
+ patch?: never;
644
+ trace?: never;
645
+ };
626
646
  "/polymarket/tags": {
627
647
  parameters: {
628
648
  query?: never;
@@ -1045,6 +1065,8 @@ export interface components {
1045
1065
  apy: number;
1046
1066
  /** Format: double */
1047
1067
  volume_24h?: number | null;
1068
+ /** Format: double */
1069
+ liquidity?: number | null;
1048
1070
  outcomes: components["schemas"]["BondOutcome"][];
1049
1071
  };
1050
1072
  BondOutcome: {
@@ -1402,6 +1424,18 @@ export interface components {
1402
1424
  * @default null
1403
1425
  */
1404
1426
  outcome_index: number | null;
1427
+ /**
1428
+ * Format: int64
1429
+ * @description Block of the most recent price update for this outcome.
1430
+ * @default null
1431
+ */
1432
+ latest_block: number | null;
1433
+ /**
1434
+ * Format: int64
1435
+ * @description Unix-seconds timestamp of the most recent price update.
1436
+ * @default null
1437
+ */
1438
+ latest_confirmed_at: number | null;
1405
1439
  };
1406
1440
  /** @enum {string} */
1407
1441
  MarketPnlSortBy: "realized_pnl_usd" | "buy_usd" | "total_buys" | "total_fees" | "outcomes_traded" | "realized_pnl_pct";
@@ -1987,7 +2021,7 @@ export interface components {
1987
2021
  price_close: number;
1988
2022
  };
1989
2023
  /** @enum {string} */
1990
- PositionPnlSortBy: "realized_pnl_usd" | "buy_usd" | "sell_usd" | "redemption_usd" | "total_buys" | "total_sells" | "total_shares_bought" | "total_shares_sold" | "avg_entry_price" | "avg_exit_price" | "total_fees" | "first_trade_at" | "last_trade_at" | "current_value" | "realized_pnl_pct" | "title";
2024
+ PositionPnlSortBy: "realized_pnl_usd" | "total_buy_usd" | "total_sell_usd" | "redemption_usd" | "total_buys" | "total_sells" | "total_shares_bought" | "total_shares_sold" | "avg_entry_price" | "avg_exit_price" | "total_fees" | "first_trade_at" | "last_trade_at" | "current_value" | "realized_pnl_pct" | "title";
1991
2025
  /**
1992
2026
  * @description Position status filter for open/closed positions.
1993
2027
  * @enum {string}
@@ -2533,6 +2567,8 @@ export interface components {
2533
2567
  first_trade_at?: number | null;
2534
2568
  /** Format: int64 */
2535
2569
  last_trade_at?: number | null;
2570
+ /** Format: double */
2571
+ realized_pnl_pct?: number | null;
2536
2572
  };
2537
2573
  /** @description Trader profile info - backwards compatibility */
2538
2574
  TraderInfo: {
@@ -2546,6 +2582,7 @@ export interface components {
2546
2582
  /** @description Market-level PnL entry */
2547
2583
  TraderMarketPnlEntry: {
2548
2584
  condition_id?: string | null;
2585
+ market_slug?: string | null;
2549
2586
  event_slug?: string | null;
2550
2587
  question?: string | null;
2551
2588
  image_url?: string | null;
@@ -2577,6 +2614,8 @@ export interface components {
2577
2614
  first_trade_at?: number | null;
2578
2615
  /** Format: int64 */
2579
2616
  last_trade_at?: number | null;
2617
+ /** Format: double */
2618
+ realized_pnl_pct?: number | null;
2580
2619
  };
2581
2620
  /** @description Outcome-level PnL entry (per outcome token / position_id) */
2582
2621
  TraderOutcomePnlEntry: {
@@ -2747,12 +2786,12 @@ export interface operations {
2747
2786
  * @description Asset ticker: BTC, ETH, XRP, SOL, DOGE, BNB, HYPE
2748
2787
  * @example BTC
2749
2788
  */
2750
- asset_symbol: string;
2789
+ asset_symbol: components["schemas"]["AssetSymbol"];
2751
2790
  /**
2752
2791
  * @description Time window: 5m, 15m, 1h, 4h, 1d
2753
2792
  * @example 1h
2754
2793
  */
2755
- variant: string;
2794
+ variant: components["schemas"]["AssetVariant"];
2756
2795
  /** @description Start timestamp in seconds (Unix epoch, inclusive) */
2757
2796
  from?: number;
2758
2797
  /** @description End timestamp in seconds (Unix epoch, inclusive) */
@@ -2913,13 +2952,13 @@ export interface operations {
2913
2952
  };
2914
2953
  requestBody?: never;
2915
2954
  responses: {
2916
- /** @description Event metrics for the specified timeframe(s). Returns single object for one timeframe, array for multiple. */
2955
+ /** @description Event metrics. **Note:** returns a single object for one timeframe, or an array of objects for comma-separated timeframes or 'all'. */
2917
2956
  200: {
2918
2957
  headers: {
2919
2958
  [name: string]: unknown;
2920
2959
  };
2921
2960
  content: {
2922
- "application/json": components["schemas"]["EventMetricsResponse"];
2961
+ "application/json": components["schemas"]["EventMetricsResponse"][];
2923
2962
  };
2924
2963
  };
2925
2964
  /** @description Invalid timeframe */
@@ -3094,8 +3133,16 @@ export interface operations {
3094
3133
  condition_id?: string;
3095
3134
  /** @description Market slug (e.g. `will-trump-win`) */
3096
3135
  market_slug?: string;
3097
- /** @description Time range in hours (default: 24, max: 336 = 14 days) */
3136
+ /** @description Start timestamp (Unix seconds). If omitted, derived from `hours` param. */
3137
+ from?: number;
3138
+ /** @description End timestamp (Unix seconds). Defaults to now. */
3139
+ to?: number;
3140
+ /** @description Number of candles to return (default: 500, max: 2500) */
3141
+ count_back?: number;
3142
+ /** @description Fallback time range in hours when `from`/`to` are not provided (default: 24, max: 336 = 14 days) */
3098
3143
  hours?: number;
3144
+ /** @description Cursor-based pagination key from previous response */
3145
+ pagination_key?: string;
3099
3146
  };
3100
3147
  header?: never;
3101
3148
  path?: never;
@@ -3167,8 +3214,16 @@ export interface operations {
3167
3214
  get_position_holders_history: {
3168
3215
  parameters: {
3169
3216
  query?: {
3170
- /** @description Time range in hours (default: 24, max: 336 = 14 days) */
3217
+ /** @description Start timestamp (Unix seconds). If omitted, derived from `hours` param. */
3218
+ from?: number;
3219
+ /** @description End timestamp (Unix seconds). Defaults to now. */
3220
+ to?: number;
3221
+ /** @description Number of candles to return (default: 500, max: 2500) */
3222
+ count_back?: number;
3223
+ /** @description Fallback time range in hours when `from`/`to` are not provided (default: 24, max: 336 = 14 days) */
3171
3224
  hours?: number;
3225
+ /** @description Cursor-based pagination key from previous response */
3226
+ pagination_key?: string;
3172
3227
  };
3173
3228
  header?: never;
3174
3229
  path: {
@@ -3298,12 +3353,16 @@ export interface operations {
3298
3353
  query?: {
3299
3354
  /** @description Minimum probability threshold (default: 0.85) */
3300
3355
  min_probability?: number;
3356
+ /** @description Maximum probability threshold (e.g. 0.99) */
3357
+ max_probability?: number;
3301
3358
  /** @description Maximum hours until market end */
3302
3359
  max_hours?: number;
3360
+ /** @description Sort by: apy, liquidity, volume, end_date (default: end_date) */
3361
+ sort_by?: string;
3303
3362
  /** @description Number of results (default: 10, max: 250) */
3304
3363
  limit?: number;
3305
- /** @description Cursor for pagination: end_date (unix epoch) of the last item from the previous page */
3306
- pagination_key?: number;
3364
+ /** @description Offset for pagination (default: 0) */
3365
+ offset?: number;
3307
3366
  };
3308
3367
  header?: never;
3309
3368
  path?: never;
@@ -3311,7 +3370,7 @@ export interface operations {
3311
3370
  };
3312
3371
  requestBody?: never;
3313
3372
  responses: {
3314
- /** @description List of bond markets sorted by yield */
3373
+ /** @description List of bond markets */
3315
3374
  200: {
3316
3375
  headers: {
3317
3376
  [name: string]: unknown;
@@ -3335,6 +3394,8 @@ export interface operations {
3335
3394
  from?: number;
3336
3395
  /** @description End timestamp (Unix seconds) */
3337
3396
  to?: number;
3397
+ /** @description Cursor-based pagination key from previous response */
3398
+ pagination_key?: string;
3338
3399
  };
3339
3400
  header?: never;
3340
3401
  path?: never;
@@ -3396,13 +3457,13 @@ export interface operations {
3396
3457
  };
3397
3458
  requestBody?: never;
3398
3459
  responses: {
3399
- /** @description Market metrics for the specified timeframe(s). Returns single object for one timeframe, array for multiple. */
3460
+ /** @description Market metrics. **Note:** returns a single object for one timeframe, or an array of objects for comma-separated timeframes or 'all'. */
3400
3461
  200: {
3401
3462
  headers: {
3402
3463
  [name: string]: unknown;
3403
3464
  };
3404
3465
  content: {
3405
- "application/json": components["schemas"]["ConditionMetricsResponse"];
3466
+ "application/json": components["schemas"]["ConditionMetricsResponse"][];
3406
3467
  };
3407
3468
  };
3408
3469
  /** @description Invalid timeframe */
@@ -3427,6 +3488,8 @@ export interface operations {
3427
3488
  from?: number;
3428
3489
  /** @description End timestamp (Unix seconds) */
3429
3490
  to?: number;
3491
+ /** @description Cursor-based pagination key from previous response */
3492
+ pagination_key?: string;
3430
3493
  };
3431
3494
  header?: never;
3432
3495
  path?: never;
@@ -3459,13 +3522,13 @@ export interface operations {
3459
3522
  };
3460
3523
  requestBody?: never;
3461
3524
  responses: {
3462
- /** @description Position metrics for the specified timeframe(s). Returns single object for one timeframe, array for multiple. */
3525
+ /** @description Position metrics. **Note:** returns a single object for one timeframe, or an array of objects for comma-separated timeframes or 'all'. */
3463
3526
  200: {
3464
3527
  headers: {
3465
3528
  [name: string]: unknown;
3466
3529
  };
3467
3530
  content: {
3468
- "application/json": components["schemas"]["PositionMetricsResponse"];
3531
+ "application/json": components["schemas"]["PositionMetricsResponse"][];
3469
3532
  };
3470
3533
  };
3471
3534
  /** @description Invalid timeframe */
@@ -3490,6 +3553,8 @@ export interface operations {
3490
3553
  from?: number;
3491
3554
  /** @description End timestamp (Unix seconds) */
3492
3555
  to?: number;
3556
+ /** @description Cursor-based pagination key from previous response */
3557
+ pagination_key?: string;
3493
3558
  };
3494
3559
  header?: never;
3495
3560
  path?: never;
@@ -3544,6 +3609,24 @@ export interface operations {
3544
3609
  get_market_by_slug: {
3545
3610
  parameters: {
3546
3611
  query?: {
3612
+ /** @description Comma-separated condition IDs (max 50) */
3613
+ condition_ids?: string;
3614
+ /** @description Comma-separated question IDs (max 50) */
3615
+ question_ids?: string;
3616
+ /** @description Comma-separated market IDs (max 50) */
3617
+ market_ids?: string;
3618
+ /** @description Comma-separated market slugs (max 50) */
3619
+ market_slugs?: string;
3620
+ /** @description Comma-separated event slugs (max 50) */
3621
+ event_slugs?: string;
3622
+ /** @description Comma-separated tag filters (max 50) */
3623
+ tags?: string;
3624
+ /** @description Comma-separated position IDs to resolve to markets (max 50) */
3625
+ position_ids?: string;
3626
+ /** @description Search string (3-100 characters) */
3627
+ search?: string;
3628
+ /** @description Metrics timeframe (default: 24h) */
3629
+ timeframe?: components["schemas"]["MetricsTimeframe"];
3547
3630
  /** @description Include tags array (default: true) */
3548
3631
  include_tags?: boolean;
3549
3632
  /** @description Include event object (default: true) */
@@ -3562,7 +3645,7 @@ export interface operations {
3562
3645
  };
3563
3646
  requestBody?: never;
3564
3647
  responses: {
3565
- /** @description Market with metadata, outcomes, tags, event, and metrics */
3648
+ /** @description Array of markets with metadata, outcomes, tags, event, and metrics */
3566
3649
  200: {
3567
3650
  headers: {
3568
3651
  [name: string]: unknown;
@@ -3615,7 +3698,7 @@ export interface operations {
3615
3698
  };
3616
3699
  /** Format: double */
3617
3700
  relevance_score?: number | null;
3618
- };
3701
+ }[];
3619
3702
  };
3620
3703
  };
3621
3704
  /** @description Market not found */
@@ -3707,6 +3790,8 @@ export interface operations {
3707
3790
  from?: number;
3708
3791
  /** @description End timestamp (Unix seconds) */
3709
3792
  to?: number;
3793
+ /** @description Cursor-based pagination key from previous response */
3794
+ pagination_key?: string;
3710
3795
  };
3711
3796
  header?: never;
3712
3797
  path?: never;
@@ -3728,6 +3813,24 @@ export interface operations {
3728
3813
  get_market: {
3729
3814
  parameters: {
3730
3815
  query?: {
3816
+ /** @description Comma-separated condition IDs (max 50) */
3817
+ condition_ids?: string;
3818
+ /** @description Comma-separated question IDs (max 50) */
3819
+ question_ids?: string;
3820
+ /** @description Comma-separated market IDs (max 50) */
3821
+ market_ids?: string;
3822
+ /** @description Comma-separated market slugs (max 50) */
3823
+ market_slugs?: string;
3824
+ /** @description Comma-separated event slugs (max 50) */
3825
+ event_slugs?: string;
3826
+ /** @description Comma-separated tag filters (max 50) */
3827
+ tags?: string;
3828
+ /** @description Comma-separated position IDs to resolve to markets (max 50) */
3829
+ position_ids?: string;
3830
+ /** @description Search string (3-100 characters) */
3831
+ search?: string;
3832
+ /** @description Metrics timeframe (default: 24h) */
3833
+ timeframe?: components["schemas"]["MetricsTimeframe"];
3731
3834
  /** @description Include tags array (default: true) */
3732
3835
  include_tags?: boolean;
3733
3836
  /** @description Include event object (default: true) */
@@ -3746,7 +3849,7 @@ export interface operations {
3746
3849
  };
3747
3850
  requestBody?: never;
3748
3851
  responses: {
3749
- /** @description Market with metadata, outcomes, tags, event, and metrics */
3852
+ /** @description Array of markets with metadata, outcomes, tags, event, and metrics */
3750
3853
  200: {
3751
3854
  headers: {
3752
3855
  [name: string]: unknown;
@@ -3799,7 +3902,7 @@ export interface operations {
3799
3902
  };
3800
3903
  /** Format: double */
3801
3904
  relevance_score?: number | null;
3802
- };
3905
+ }[];
3803
3906
  };
3804
3907
  };
3805
3908
  /** @description Market not found */
@@ -4012,7 +4115,7 @@ export interface operations {
4012
4115
  max_spread?: number;
4013
4116
  /** @description Only return rows where total liquidity (bid + ask) >= this value */
4014
4117
  min_liquidity?: number;
4015
- /** @description Number of results (default: 100, max: 1000) */
4118
+ /** @description Number of results (default: 20, max: 200) */
4016
4119
  limit?: number;
4017
4120
  /** @description Cursor from previous response's pagination.pagination_key */
4018
4121
  pagination_key?: string;
@@ -4186,6 +4289,49 @@ export interface operations {
4186
4289
  };
4187
4290
  };
4188
4291
  };
4292
+ get_series_events: {
4293
+ parameters: {
4294
+ query?: {
4295
+ /** @description Filter by active events only (default: false) */
4296
+ active?: boolean;
4297
+ /** @description Include tags array (default: true) */
4298
+ include_tags?: boolean;
4299
+ /** @description Include markets array (default: true) */
4300
+ include_markets?: boolean;
4301
+ /** @description Include metrics (default: true) */
4302
+ include_metrics?: boolean;
4303
+ /** @description Number of events to return (default: 20, max: 250) */
4304
+ limit?: number;
4305
+ /** @description Offset for pagination (default: 0) */
4306
+ pagination_key?: string;
4307
+ };
4308
+ header?: never;
4309
+ path: {
4310
+ /** @description Series slug (e.g. 'btc-weekly-close') or series ID */
4311
+ identifier: string;
4312
+ };
4313
+ cookie?: never;
4314
+ };
4315
+ requestBody?: never;
4316
+ responses: {
4317
+ /** @description List of events in this series */
4318
+ 200: {
4319
+ headers: {
4320
+ [name: string]: unknown;
4321
+ };
4322
+ content: {
4323
+ "application/json": components["schemas"]["PolymarketEvent"][];
4324
+ };
4325
+ };
4326
+ /** @description Series not found */
4327
+ 404: {
4328
+ headers: {
4329
+ [name: string]: unknown;
4330
+ };
4331
+ content?: never;
4332
+ };
4333
+ };
4334
+ };
4189
4335
  get_tags: {
4190
4336
  parameters: {
4191
4337
  query?: {
@@ -4361,7 +4507,7 @@ export interface operations {
4361
4507
  query?: {
4362
4508
  /** @description Timeframe: 1d, 7d, 30d, lifetime (default: lifetime) */
4363
4509
  timeframe?: components["schemas"]["PnlTimeframe"];
4364
- /** @description Sort: realized_pnl_usd, total_volume_usd, markets_traded, total_fees (default: realized_pnl_usd) */
4510
+ /** @description Sort: realized_pnl_usd, total_volume_usd, markets_traded, total_fees, realized_pnl_pct (default: realized_pnl_usd) */
4365
4511
  sort_by?: components["schemas"]["EventPnlSortBy"];
4366
4512
  /** @description Sort direction: asc, desc (default: desc) */
4367
4513
  sort_direction?: components["schemas"]["SortDirection"];
@@ -4399,7 +4545,7 @@ export interface operations {
4399
4545
  query?: {
4400
4546
  /** @description Timeframe: 1d, 7d, 30d, lifetime (default: lifetime) */
4401
4547
  timeframe?: components["schemas"]["PnlTimeframe"];
4402
- /** @description Sort: realized_pnl_usd, buy_usd, total_buys, total_fees, outcomes_traded (default: realized_pnl_usd) */
4548
+ /** @description Sort: realized_pnl_usd, buy_usd, total_buys, total_fees, outcomes_traded, realized_pnl_pct (default: realized_pnl_usd) */
4403
4549
  sort_by?: components["schemas"]["MarketPnlSortBy"];
4404
4550
  /** @description Sort direction: asc, desc (default: desc) */
4405
4551
  sort_direction?: components["schemas"]["SortDirection"];