@0xarchive/sdk 0.8.3 → 0.9.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/dist/index.js CHANGED
@@ -25,6 +25,11 @@ __export(index_exports, {
25
25
  CandleArrayResponseSchema: () => CandleArrayResponseSchema,
26
26
  CandleIntervalSchema: () => CandleIntervalSchema,
27
27
  CandleSchema: () => CandleSchema,
28
+ CoinFreshnessResponseSchema: () => CoinFreshnessResponseSchema,
29
+ CoinFreshnessSchema: () => CoinFreshnessSchema,
30
+ CoinSummaryResponseSchema: () => CoinSummaryResponseSchema,
31
+ CoinSummarySchema: () => CoinSummarySchema,
32
+ DataTypeFreshnessInfoSchema: () => DataTypeFreshnessInfoSchema,
28
33
  FundingRateArrayResponseSchema: () => FundingRateArrayResponseSchema,
29
34
  FundingRateResponseSchema: () => FundingRateResponseSchema,
30
35
  FundingRateSchema: () => FundingRateSchema,
@@ -38,6 +43,8 @@ __export(index_exports, {
38
43
  LiquidationArrayResponseSchema: () => LiquidationArrayResponseSchema,
39
44
  LiquidationSchema: () => LiquidationSchema,
40
45
  LiquidationSideSchema: () => LiquidationSideSchema,
46
+ LiquidationVolumeArrayResponseSchema: () => LiquidationVolumeArrayResponseSchema,
47
+ LiquidationVolumeSchema: () => LiquidationVolumeSchema,
41
48
  OpenInterestArrayResponseSchema: () => OpenInterestArrayResponseSchema,
42
49
  OpenInterestResponseSchema: () => OpenInterestResponseSchema,
43
50
  OpenInterestSchema: () => OpenInterestSchema,
@@ -49,6 +56,8 @@ __export(index_exports, {
49
56
  OxArchiveError: () => OxArchiveError,
50
57
  OxArchiveWs: () => OxArchiveWs,
51
58
  PriceLevelSchema: () => PriceLevelSchema,
59
+ PriceSnapshotArrayResponseSchema: () => PriceSnapshotArrayResponseSchema,
60
+ PriceSnapshotSchema: () => PriceSnapshotSchema,
52
61
  TimestampedRecordSchema: () => TimestampedRecordSchema,
53
62
  TradeArrayResponseSchema: () => TradeArrayResponseSchema,
54
63
  TradeDirectionSchema: () => TradeDirectionSchema,
@@ -64,6 +73,7 @@ __export(index_exports, {
64
73
  WsReplayCompletedSchema: () => WsReplayCompletedSchema,
65
74
  WsReplayPausedSchema: () => WsReplayPausedSchema,
66
75
  WsReplayResumedSchema: () => WsReplayResumedSchema,
76
+ WsReplaySnapshotSchema: () => WsReplaySnapshotSchema,
67
77
  WsReplayStartedSchema: () => WsReplayStartedSchema,
68
78
  WsReplayStoppedSchema: () => WsReplayStoppedSchema,
69
79
  WsServerMessageSchema: () => WsServerMessageSchema,
@@ -93,7 +103,7 @@ var OxArchiveError = class extends Error {
93
103
 
94
104
  // src/http.ts
95
105
  function snakeToCamel(str) {
96
- return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
106
+ return str.replace(/_([a-z0-9])/g, (_, char) => char.toUpperCase());
97
107
  }
98
108
  function transformKeys(obj) {
99
109
  if (obj === null || obj === void 0) {
@@ -298,7 +308,26 @@ var CandleSchema = import_zod.z.object({
298
308
  quoteVolume: import_zod.z.number().optional(),
299
309
  tradeCount: import_zod.z.number().optional()
300
310
  });
301
- var WsChannelSchema = import_zod.z.enum(["orderbook", "trades", "candles", "liquidations", "ticker", "all_tickers"]);
311
+ var WsChannelSchema = import_zod.z.enum([
312
+ "orderbook",
313
+ "trades",
314
+ "candles",
315
+ "liquidations",
316
+ "ticker",
317
+ "all_tickers",
318
+ "open_interest",
319
+ "funding",
320
+ "lighter_orderbook",
321
+ "lighter_trades",
322
+ "lighter_candles",
323
+ "lighter_open_interest",
324
+ "lighter_funding",
325
+ "hip3_orderbook",
326
+ "hip3_trades",
327
+ "hip3_candles",
328
+ "hip3_open_interest",
329
+ "hip3_funding"
330
+ ]);
302
331
  var WsConnectionStateSchema = import_zod.z.enum(["connecting", "connected", "disconnected", "reconnecting"]);
303
332
  var WsSubscribedSchema = import_zod.z.object({
304
333
  type: import_zod.z.literal("subscribed"),
@@ -333,17 +362,17 @@ var WsReplayStartedSchema = import_zod.z.object({
333
362
  });
334
363
  var WsReplayPausedSchema = import_zod.z.object({
335
364
  type: import_zod.z.literal("replay_paused"),
336
- currentTimestamp: import_zod.z.number()
365
+ current_timestamp: import_zod.z.number()
337
366
  });
338
367
  var WsReplayResumedSchema = import_zod.z.object({
339
368
  type: import_zod.z.literal("replay_resumed"),
340
- currentTimestamp: import_zod.z.number()
369
+ current_timestamp: import_zod.z.number()
341
370
  });
342
371
  var WsReplayCompletedSchema = import_zod.z.object({
343
372
  type: import_zod.z.literal("replay_completed"),
344
373
  channel: WsChannelSchema,
345
374
  coin: import_zod.z.string(),
346
- snapshotsSent: import_zod.z.number()
375
+ snapshots_sent: import_zod.z.number()
347
376
  });
348
377
  var WsReplayStoppedSchema = import_zod.z.object({
349
378
  type: import_zod.z.literal("replay_stopped")
@@ -355,6 +384,13 @@ var WsHistoricalDataSchema = import_zod.z.object({
355
384
  timestamp: import_zod.z.number(),
356
385
  data: import_zod.z.unknown()
357
386
  });
387
+ var WsReplaySnapshotSchema = import_zod.z.object({
388
+ type: import_zod.z.literal("replay_snapshot"),
389
+ channel: WsChannelSchema,
390
+ coin: import_zod.z.string(),
391
+ timestamp: import_zod.z.number(),
392
+ data: import_zod.z.unknown()
393
+ });
358
394
  var WsStreamStartedSchema = import_zod.z.object({
359
395
  type: import_zod.z.literal("stream_started"),
360
396
  channel: WsChannelSchema,
@@ -364,7 +400,7 @@ var WsStreamStartedSchema = import_zod.z.object({
364
400
  });
365
401
  var WsStreamProgressSchema = import_zod.z.object({
366
402
  type: import_zod.z.literal("stream_progress"),
367
- snapshotsSent: import_zod.z.number()
403
+ snapshots_sent: import_zod.z.number()
368
404
  });
369
405
  var TimestampedRecordSchema = import_zod.z.object({
370
406
  timestamp: import_zod.z.number(),
@@ -380,11 +416,11 @@ var WsStreamCompletedSchema = import_zod.z.object({
380
416
  type: import_zod.z.literal("stream_completed"),
381
417
  channel: WsChannelSchema,
382
418
  coin: import_zod.z.string(),
383
- snapshotsSent: import_zod.z.number()
419
+ snapshots_sent: import_zod.z.number()
384
420
  });
385
421
  var WsStreamStoppedSchema = import_zod.z.object({
386
422
  type: import_zod.z.literal("stream_stopped"),
387
- snapshotsSent: import_zod.z.number()
423
+ snapshots_sent: import_zod.z.number()
388
424
  });
389
425
  var WsServerMessageSchema = import_zod.z.discriminatedUnion("type", [
390
426
  WsSubscribedSchema,
@@ -397,6 +433,7 @@ var WsServerMessageSchema = import_zod.z.discriminatedUnion("type", [
397
433
  WsReplayResumedSchema,
398
434
  WsReplayCompletedSchema,
399
435
  WsReplayStoppedSchema,
436
+ WsReplaySnapshotSchema,
400
437
  WsHistoricalDataSchema,
401
438
  WsStreamStartedSchema,
402
439
  WsStreamProgressSchema,
@@ -415,6 +452,70 @@ var OpenInterestResponseSchema = ApiResponseSchema(OpenInterestSchema);
415
452
  var OpenInterestArrayResponseSchema = ApiResponseSchema(import_zod.z.array(OpenInterestSchema));
416
453
  var CandleArrayResponseSchema = ApiResponseSchema(import_zod.z.array(CandleSchema));
417
454
  var LiquidationArrayResponseSchema = ApiResponseSchema(import_zod.z.array(LiquidationSchema));
455
+ var LiquidationVolumeSchema = import_zod.z.object({
456
+ coin: import_zod.z.string(),
457
+ timestamp: import_zod.z.string(),
458
+ totalUsd: import_zod.z.number(),
459
+ longUsd: import_zod.z.number(),
460
+ shortUsd: import_zod.z.number(),
461
+ count: import_zod.z.number(),
462
+ longCount: import_zod.z.number(),
463
+ shortCount: import_zod.z.number()
464
+ });
465
+ var LiquidationVolumeArrayResponseSchema = import_zod.z.object({
466
+ success: import_zod.z.boolean().optional(),
467
+ data: import_zod.z.array(LiquidationVolumeSchema),
468
+ meta: ApiMetaSchema.optional()
469
+ });
470
+ var DataTypeFreshnessInfoSchema = import_zod.z.object({
471
+ lastUpdated: import_zod.z.string().nullable().optional(),
472
+ lagMs: import_zod.z.number().nullable().optional()
473
+ });
474
+ var CoinFreshnessSchema = import_zod.z.object({
475
+ coin: import_zod.z.string(),
476
+ exchange: import_zod.z.string(),
477
+ measuredAt: import_zod.z.string(),
478
+ orderbook: DataTypeFreshnessInfoSchema,
479
+ trades: DataTypeFreshnessInfoSchema,
480
+ funding: DataTypeFreshnessInfoSchema,
481
+ openInterest: DataTypeFreshnessInfoSchema,
482
+ liquidations: DataTypeFreshnessInfoSchema.optional()
483
+ });
484
+ var CoinFreshnessResponseSchema = import_zod.z.object({
485
+ success: import_zod.z.boolean().optional(),
486
+ data: CoinFreshnessSchema,
487
+ meta: ApiMetaSchema.optional()
488
+ });
489
+ var CoinSummarySchema = import_zod.z.object({
490
+ coin: import_zod.z.string(),
491
+ timestamp: import_zod.z.string(),
492
+ markPrice: import_zod.z.string().nullable().optional(),
493
+ oraclePrice: import_zod.z.string().nullable().optional(),
494
+ midPrice: import_zod.z.string().nullable().optional(),
495
+ fundingRate: import_zod.z.string().nullable().optional(),
496
+ premium: import_zod.z.string().nullable().optional(),
497
+ openInterest: import_zod.z.string().nullable().optional(),
498
+ volume24h: import_zod.z.string().nullable().optional(),
499
+ liquidationVolume24h: import_zod.z.number().nullable().optional(),
500
+ longLiquidationVolume24h: import_zod.z.number().nullable().optional(),
501
+ shortLiquidationVolume24h: import_zod.z.number().nullable().optional()
502
+ });
503
+ var CoinSummaryResponseSchema = import_zod.z.object({
504
+ success: import_zod.z.boolean().optional(),
505
+ data: CoinSummarySchema,
506
+ meta: ApiMetaSchema.optional()
507
+ });
508
+ var PriceSnapshotSchema = import_zod.z.object({
509
+ timestamp: import_zod.z.string(),
510
+ markPrice: import_zod.z.string().nullable().optional(),
511
+ oraclePrice: import_zod.z.string().nullable().optional(),
512
+ midPrice: import_zod.z.string().nullable().optional()
513
+ });
514
+ var PriceSnapshotArrayResponseSchema = import_zod.z.object({
515
+ success: import_zod.z.boolean().optional(),
516
+ data: import_zod.z.array(PriceSnapshotSchema),
517
+ meta: ApiMetaSchema.optional()
518
+ });
418
519
 
419
520
  // src/orderbook-reconstructor.ts
420
521
  var OrderBookReconstructor = class {
@@ -1158,6 +1259,27 @@ var LiquidationsResource = class {
1158
1259
  nextCursor: response.meta.nextCursor
1159
1260
  };
1160
1261
  }
1262
+ /**
1263
+ * Get aggregated liquidation volume in time-bucketed intervals
1264
+ *
1265
+ * Returns pre-aggregated data with total/long/short USD volumes per bucket,
1266
+ * reducing data transfer by 100-1000x compared to individual liquidation records.
1267
+ *
1268
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1269
+ * @param params - Time range, cursor, and interval parameters
1270
+ * @returns CursorResponse with liquidation volume buckets
1271
+ */
1272
+ async volume(coin, params) {
1273
+ const response = await this.http.get(
1274
+ `${this.basePath}/liquidations/${coin.toUpperCase()}/volume`,
1275
+ params,
1276
+ this.http.validationEnabled ? LiquidationVolumeArrayResponseSchema : void 0
1277
+ );
1278
+ return {
1279
+ data: response.data,
1280
+ nextCursor: response.meta.nextCursor
1281
+ };
1282
+ }
1161
1283
  };
1162
1284
 
1163
1285
  // src/resources/data-quality.ts
@@ -1262,7 +1384,7 @@ var DataQualityResource = class {
1262
1384
  */
1263
1385
  async symbolCoverage(exchange, symbol, options) {
1264
1386
  return this.http.get(
1265
- `${this.basePath}/coverage/${exchange.toLowerCase()}/${symbol.toUpperCase()}`,
1387
+ `${this.basePath}/coverage/${exchange.toLowerCase()}/${symbol}`,
1266
1388
  options
1267
1389
  );
1268
1390
  }
@@ -1389,7 +1511,9 @@ var HyperliquidClient = class {
1389
1511
  * HIP-3 builder-deployed perpetuals (February 2026+)
1390
1512
  */
1391
1513
  hip3;
1514
+ http;
1392
1515
  constructor(http) {
1516
+ this.http = http;
1393
1517
  const basePath = "/v1/hyperliquid";
1394
1518
  this.orderbook = new OrderBookResource(http, basePath);
1395
1519
  this.trades = new TradesResource(http, basePath);
@@ -1400,6 +1524,52 @@ var HyperliquidClient = class {
1400
1524
  this.liquidations = new LiquidationsResource(http, basePath);
1401
1525
  this.hip3 = new Hip3Client(http);
1402
1526
  }
1527
+ /**
1528
+ * Get per-coin data freshness across all data types
1529
+ *
1530
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1531
+ * @returns Per-coin freshness with last_updated and lag_ms for each data type
1532
+ */
1533
+ async freshness(coin) {
1534
+ const response = await this.http.get(
1535
+ `/v1/hyperliquid/freshness/${coin.toUpperCase()}`,
1536
+ void 0,
1537
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
1538
+ );
1539
+ return response.data;
1540
+ }
1541
+ /**
1542
+ * Get combined market summary (price, funding, OI, volume, liquidations) in one call
1543
+ *
1544
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1545
+ * @returns Combined market summary
1546
+ */
1547
+ async summary(coin) {
1548
+ const response = await this.http.get(
1549
+ `/v1/hyperliquid/summary/${coin.toUpperCase()}`,
1550
+ void 0,
1551
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
1552
+ );
1553
+ return response.data;
1554
+ }
1555
+ /**
1556
+ * Get mark/oracle/mid price history (projected from OI data)
1557
+ *
1558
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1559
+ * @param params - Time range, cursor, and interval parameters
1560
+ * @returns CursorResponse with price snapshots
1561
+ */
1562
+ async priceHistory(coin, params) {
1563
+ const response = await this.http.get(
1564
+ `/v1/hyperliquid/prices/${coin.toUpperCase()}`,
1565
+ params,
1566
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
1567
+ );
1568
+ return {
1569
+ data: response.data,
1570
+ nextCursor: response.meta.nextCursor
1571
+ };
1572
+ }
1403
1573
  };
1404
1574
  var Hip3Client = class {
1405
1575
  /**
@@ -1426,7 +1596,9 @@ var Hip3Client = class {
1426
1596
  * OHLCV candle data
1427
1597
  */
1428
1598
  candles;
1599
+ http;
1429
1600
  constructor(http) {
1601
+ this.http = http;
1430
1602
  const basePath = "/v1/hyperliquid/hip3";
1431
1603
  const coinTransform = (c) => c;
1432
1604
  this.instruments = new Hip3InstrumentsResource(http, basePath, coinTransform);
@@ -1436,6 +1608,52 @@ var Hip3Client = class {
1436
1608
  this.openInterest = new OpenInterestResource(http, basePath, coinTransform);
1437
1609
  this.candles = new CandlesResource(http, basePath, coinTransform);
1438
1610
  }
1611
+ /**
1612
+ * Get per-coin data freshness across all data types
1613
+ *
1614
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1615
+ * @returns Per-coin freshness with last_updated and lag_ms for each data type
1616
+ */
1617
+ async freshness(coin) {
1618
+ const response = await this.http.get(
1619
+ `/v1/hyperliquid/hip3/freshness/${coin}`,
1620
+ void 0,
1621
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
1622
+ );
1623
+ return response.data;
1624
+ }
1625
+ /**
1626
+ * Get combined market summary (price, funding, OI) in one call
1627
+ *
1628
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1629
+ * @returns Combined market summary
1630
+ */
1631
+ async summary(coin) {
1632
+ const response = await this.http.get(
1633
+ `/v1/hyperliquid/hip3/summary/${coin}`,
1634
+ void 0,
1635
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
1636
+ );
1637
+ return response.data;
1638
+ }
1639
+ /**
1640
+ * Get mark/oracle/mid price history (projected from OI data)
1641
+ *
1642
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1643
+ * @param params - Time range, cursor, and interval parameters
1644
+ * @returns CursorResponse with price snapshots
1645
+ */
1646
+ async priceHistory(coin, params) {
1647
+ const response = await this.http.get(
1648
+ `/v1/hyperliquid/hip3/prices/${coin}`,
1649
+ params,
1650
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
1651
+ );
1652
+ return {
1653
+ data: response.data,
1654
+ nextCursor: response.meta.nextCursor
1655
+ };
1656
+ }
1439
1657
  };
1440
1658
  var LighterClient = class {
1441
1659
  /**
@@ -1462,7 +1680,9 @@ var LighterClient = class {
1462
1680
  * OHLCV candle data
1463
1681
  */
1464
1682
  candles;
1683
+ http;
1465
1684
  constructor(http) {
1685
+ this.http = http;
1466
1686
  const basePath = "/v1/lighter";
1467
1687
  this.orderbook = new OrderBookResource(http, basePath);
1468
1688
  this.trades = new TradesResource(http, basePath);
@@ -1471,6 +1691,52 @@ var LighterClient = class {
1471
1691
  this.openInterest = new OpenInterestResource(http, basePath);
1472
1692
  this.candles = new CandlesResource(http, basePath);
1473
1693
  }
1694
+ /**
1695
+ * Get per-coin data freshness across all data types
1696
+ *
1697
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1698
+ * @returns Per-coin freshness with last_updated and lag_ms for each data type
1699
+ */
1700
+ async freshness(coin) {
1701
+ const response = await this.http.get(
1702
+ `/v1/lighter/freshness/${coin.toUpperCase()}`,
1703
+ void 0,
1704
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
1705
+ );
1706
+ return response.data;
1707
+ }
1708
+ /**
1709
+ * Get combined market summary (price, funding, OI) in one call
1710
+ *
1711
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1712
+ * @returns Combined market summary
1713
+ */
1714
+ async summary(coin) {
1715
+ const response = await this.http.get(
1716
+ `/v1/lighter/summary/${coin.toUpperCase()}`,
1717
+ void 0,
1718
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
1719
+ );
1720
+ return response.data;
1721
+ }
1722
+ /**
1723
+ * Get mark/oracle price history (projected from OI data)
1724
+ *
1725
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1726
+ * @param params - Time range, cursor, and interval parameters
1727
+ * @returns CursorResponse with price snapshots
1728
+ */
1729
+ async priceHistory(coin, params) {
1730
+ const response = await this.http.get(
1731
+ `/v1/lighter/prices/${coin.toUpperCase()}`,
1732
+ params,
1733
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
1734
+ );
1735
+ return {
1736
+ data: response.data,
1737
+ nextCursor: response.meta.nextCursor
1738
+ };
1739
+ }
1474
1740
  };
1475
1741
 
1476
1742
  // src/client.ts
@@ -1627,6 +1893,7 @@ var OxArchiveWs = class {
1627
1893
  batchHandlers = [];
1628
1894
  replayStartHandlers = [];
1629
1895
  replayCompleteHandlers = [];
1896
+ replaySnapshotHandlers = [];
1630
1897
  streamStartHandlers = [];
1631
1898
  streamProgressHandlers = [];
1632
1899
  streamCompleteHandlers = [];
@@ -1807,6 +2074,41 @@ var OxArchiveWs = class {
1807
2074
  interval: options.interval
1808
2075
  });
1809
2076
  }
2077
+ /**
2078
+ * Start a multi-channel historical replay with timing preserved.
2079
+ * Data from all channels is interleaved chronologically. Before the timeline
2080
+ * begins, `replay_snapshot` messages provide initial state for each channel.
2081
+ *
2082
+ * @param channels - Array of data channels to replay simultaneously
2083
+ * @param coin - Trading pair (e.g., 'BTC', 'ETH')
2084
+ * @param options - Replay options
2085
+ *
2086
+ * @example
2087
+ * ```typescript
2088
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
2089
+ * console.log(`Initial ${channel} state at ${new Date(timestamp).toISOString()}`);
2090
+ * });
2091
+ * ws.onHistoricalData((coin, timestamp, data) => {
2092
+ * // Interleaved data from all channels
2093
+ * });
2094
+ * ws.multiReplay(['orderbook', 'trades', 'funding'], 'BTC', {
2095
+ * start: Date.now() - 86400000,
2096
+ * speed: 10
2097
+ * });
2098
+ * ```
2099
+ */
2100
+ multiReplay(channels, coin, options) {
2101
+ this.send({
2102
+ op: "replay",
2103
+ channels,
2104
+ coin,
2105
+ start: options.start,
2106
+ end: options.end,
2107
+ speed: options.speed ?? 1,
2108
+ granularity: options.granularity,
2109
+ interval: options.interval
2110
+ });
2111
+ }
1810
2112
  /**
1811
2113
  * Pause the current replay
1812
2114
  */
@@ -1863,6 +2165,43 @@ var OxArchiveWs = class {
1863
2165
  interval: options.interval
1864
2166
  });
1865
2167
  }
2168
+ /**
2169
+ * Start a multi-channel bulk stream for fast data download.
2170
+ * Data from all channels arrives in batches without timing delays.
2171
+ * Before batches begin, `replay_snapshot` messages provide initial state
2172
+ * for each channel.
2173
+ *
2174
+ * @param channels - Array of data channels to stream simultaneously
2175
+ * @param coin - Trading pair (e.g., 'BTC', 'ETH')
2176
+ * @param options - Stream options
2177
+ *
2178
+ * @example
2179
+ * ```typescript
2180
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
2181
+ * console.log(`Initial ${channel} state`);
2182
+ * });
2183
+ * ws.onBatch((coin, records) => {
2184
+ * // Batches contain data from all requested channels
2185
+ * });
2186
+ * ws.multiStream(['orderbook', 'trades', 'open_interest'], 'BTC', {
2187
+ * start: Date.now() - 3600000,
2188
+ * end: Date.now(),
2189
+ * batchSize: 1000
2190
+ * });
2191
+ * ```
2192
+ */
2193
+ multiStream(channels, coin, options) {
2194
+ this.send({
2195
+ op: "stream",
2196
+ channels,
2197
+ coin,
2198
+ start: options.start,
2199
+ end: options.end,
2200
+ batch_size: options.batchSize ?? 1e3,
2201
+ granularity: options.granularity,
2202
+ interval: options.interval
2203
+ });
2204
+ }
1866
2205
  /**
1867
2206
  * Stop the current bulk stream
1868
2207
  */
@@ -1904,6 +2243,29 @@ var OxArchiveWs = class {
1904
2243
  onReplayComplete(handler) {
1905
2244
  this.replayCompleteHandlers.push(handler);
1906
2245
  }
2246
+ /**
2247
+ * Handle replay snapshot events (multi-channel mode).
2248
+ * Called with the initial state for each channel before the replay/stream
2249
+ * timeline begins. Use this to initialize local state (e.g., set the current
2250
+ * orderbook or latest funding rate) before `historical_data` messages start
2251
+ * arriving.
2252
+ *
2253
+ * @param handler - Callback receiving channel, coin, timestamp (ms), and data payload
2254
+ *
2255
+ * @example
2256
+ * ```typescript
2257
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
2258
+ * if (channel === 'orderbook') {
2259
+ * currentOrderbook = data;
2260
+ * } else if (channel === 'funding') {
2261
+ * currentFundingRate = data;
2262
+ * }
2263
+ * });
2264
+ * ```
2265
+ */
2266
+ onReplaySnapshot(handler) {
2267
+ this.replaySnapshotHandlers.push(handler);
2268
+ }
1907
2269
  /**
1908
2270
  * Handle stream started event
1909
2271
  */
@@ -2062,6 +2424,13 @@ var OxArchiveWs = class {
2062
2424
  }
2063
2425
  break;
2064
2426
  }
2427
+ case "replay_snapshot": {
2428
+ const msg = message;
2429
+ for (const handler of this.replaySnapshotHandlers) {
2430
+ handler(msg.channel, msg.coin, msg.timestamp, msg.data);
2431
+ }
2432
+ break;
2433
+ }
2065
2434
  case "stream_started": {
2066
2435
  const msg = message;
2067
2436
  for (const handler of this.streamStartHandlers) {
@@ -2114,6 +2483,11 @@ var OxArchiveWs = class {
2114
2483
  CandleArrayResponseSchema,
2115
2484
  CandleIntervalSchema,
2116
2485
  CandleSchema,
2486
+ CoinFreshnessResponseSchema,
2487
+ CoinFreshnessSchema,
2488
+ CoinSummaryResponseSchema,
2489
+ CoinSummarySchema,
2490
+ DataTypeFreshnessInfoSchema,
2117
2491
  FundingRateArrayResponseSchema,
2118
2492
  FundingRateResponseSchema,
2119
2493
  FundingRateSchema,
@@ -2127,6 +2501,8 @@ var OxArchiveWs = class {
2127
2501
  LiquidationArrayResponseSchema,
2128
2502
  LiquidationSchema,
2129
2503
  LiquidationSideSchema,
2504
+ LiquidationVolumeArrayResponseSchema,
2505
+ LiquidationVolumeSchema,
2130
2506
  OpenInterestArrayResponseSchema,
2131
2507
  OpenInterestResponseSchema,
2132
2508
  OpenInterestSchema,
@@ -2138,6 +2514,8 @@ var OxArchiveWs = class {
2138
2514
  OxArchiveError,
2139
2515
  OxArchiveWs,
2140
2516
  PriceLevelSchema,
2517
+ PriceSnapshotArrayResponseSchema,
2518
+ PriceSnapshotSchema,
2141
2519
  TimestampedRecordSchema,
2142
2520
  TradeArrayResponseSchema,
2143
2521
  TradeDirectionSchema,
@@ -2153,6 +2531,7 @@ var OxArchiveWs = class {
2153
2531
  WsReplayCompletedSchema,
2154
2532
  WsReplayPausedSchema,
2155
2533
  WsReplayResumedSchema,
2534
+ WsReplaySnapshotSchema,
2156
2535
  WsReplayStartedSchema,
2157
2536
  WsReplayStoppedSchema,
2158
2537
  WsServerMessageSchema,