@0xarchive/sdk 0.8.2 → 0.9.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/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
  /**
@@ -1627,6 +1797,7 @@ var OxArchiveWs = class {
1627
1797
  batchHandlers = [];
1628
1798
  replayStartHandlers = [];
1629
1799
  replayCompleteHandlers = [];
1800
+ replaySnapshotHandlers = [];
1630
1801
  streamStartHandlers = [];
1631
1802
  streamProgressHandlers = [];
1632
1803
  streamCompleteHandlers = [];
@@ -1807,6 +1978,41 @@ var OxArchiveWs = class {
1807
1978
  interval: options.interval
1808
1979
  });
1809
1980
  }
1981
+ /**
1982
+ * Start a multi-channel historical replay with timing preserved.
1983
+ * Data from all channels is interleaved chronologically. Before the timeline
1984
+ * begins, `replay_snapshot` messages provide initial state for each channel.
1985
+ *
1986
+ * @param channels - Array of data channels to replay simultaneously
1987
+ * @param coin - Trading pair (e.g., 'BTC', 'ETH')
1988
+ * @param options - Replay options
1989
+ *
1990
+ * @example
1991
+ * ```typescript
1992
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
1993
+ * console.log(`Initial ${channel} state at ${new Date(timestamp).toISOString()}`);
1994
+ * });
1995
+ * ws.onHistoricalData((coin, timestamp, data) => {
1996
+ * // Interleaved data from all channels
1997
+ * });
1998
+ * ws.multiReplay(['orderbook', 'trades', 'funding'], 'BTC', {
1999
+ * start: Date.now() - 86400000,
2000
+ * speed: 10
2001
+ * });
2002
+ * ```
2003
+ */
2004
+ multiReplay(channels, coin, options) {
2005
+ this.send({
2006
+ op: "replay",
2007
+ channels,
2008
+ coin,
2009
+ start: options.start,
2010
+ end: options.end,
2011
+ speed: options.speed ?? 1,
2012
+ granularity: options.granularity,
2013
+ interval: options.interval
2014
+ });
2015
+ }
1810
2016
  /**
1811
2017
  * Pause the current replay
1812
2018
  */
@@ -1863,6 +2069,43 @@ var OxArchiveWs = class {
1863
2069
  interval: options.interval
1864
2070
  });
1865
2071
  }
2072
+ /**
2073
+ * Start a multi-channel bulk stream for fast data download.
2074
+ * Data from all channels arrives in batches without timing delays.
2075
+ * Before batches begin, `replay_snapshot` messages provide initial state
2076
+ * for each channel.
2077
+ *
2078
+ * @param channels - Array of data channels to stream simultaneously
2079
+ * @param coin - Trading pair (e.g., 'BTC', 'ETH')
2080
+ * @param options - Stream options
2081
+ *
2082
+ * @example
2083
+ * ```typescript
2084
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
2085
+ * console.log(`Initial ${channel} state`);
2086
+ * });
2087
+ * ws.onBatch((coin, records) => {
2088
+ * // Batches contain data from all requested channels
2089
+ * });
2090
+ * ws.multiStream(['orderbook', 'trades', 'open_interest'], 'BTC', {
2091
+ * start: Date.now() - 3600000,
2092
+ * end: Date.now(),
2093
+ * batchSize: 1000
2094
+ * });
2095
+ * ```
2096
+ */
2097
+ multiStream(channels, coin, options) {
2098
+ this.send({
2099
+ op: "stream",
2100
+ channels,
2101
+ coin,
2102
+ start: options.start,
2103
+ end: options.end,
2104
+ batch_size: options.batchSize ?? 1e3,
2105
+ granularity: options.granularity,
2106
+ interval: options.interval
2107
+ });
2108
+ }
1866
2109
  /**
1867
2110
  * Stop the current bulk stream
1868
2111
  */
@@ -1904,6 +2147,29 @@ var OxArchiveWs = class {
1904
2147
  onReplayComplete(handler) {
1905
2148
  this.replayCompleteHandlers.push(handler);
1906
2149
  }
2150
+ /**
2151
+ * Handle replay snapshot events (multi-channel mode).
2152
+ * Called with the initial state for each channel before the replay/stream
2153
+ * timeline begins. Use this to initialize local state (e.g., set the current
2154
+ * orderbook or latest funding rate) before `historical_data` messages start
2155
+ * arriving.
2156
+ *
2157
+ * @param handler - Callback receiving channel, coin, timestamp (ms), and data payload
2158
+ *
2159
+ * @example
2160
+ * ```typescript
2161
+ * ws.onReplaySnapshot((channel, coin, timestamp, data) => {
2162
+ * if (channel === 'orderbook') {
2163
+ * currentOrderbook = data;
2164
+ * } else if (channel === 'funding') {
2165
+ * currentFundingRate = data;
2166
+ * }
2167
+ * });
2168
+ * ```
2169
+ */
2170
+ onReplaySnapshot(handler) {
2171
+ this.replaySnapshotHandlers.push(handler);
2172
+ }
1907
2173
  /**
1908
2174
  * Handle stream started event
1909
2175
  */
@@ -2062,6 +2328,13 @@ var OxArchiveWs = class {
2062
2328
  }
2063
2329
  break;
2064
2330
  }
2331
+ case "replay_snapshot": {
2332
+ const msg = message;
2333
+ for (const handler of this.replaySnapshotHandlers) {
2334
+ handler(msg.channel, msg.coin, msg.timestamp, msg.data);
2335
+ }
2336
+ break;
2337
+ }
2065
2338
  case "stream_started": {
2066
2339
  const msg = message;
2067
2340
  for (const handler of this.streamStartHandlers) {
@@ -2114,6 +2387,11 @@ var OxArchiveWs = class {
2114
2387
  CandleArrayResponseSchema,
2115
2388
  CandleIntervalSchema,
2116
2389
  CandleSchema,
2390
+ CoinFreshnessResponseSchema,
2391
+ CoinFreshnessSchema,
2392
+ CoinSummaryResponseSchema,
2393
+ CoinSummarySchema,
2394
+ DataTypeFreshnessInfoSchema,
2117
2395
  FundingRateArrayResponseSchema,
2118
2396
  FundingRateResponseSchema,
2119
2397
  FundingRateSchema,
@@ -2127,6 +2405,8 @@ var OxArchiveWs = class {
2127
2405
  LiquidationArrayResponseSchema,
2128
2406
  LiquidationSchema,
2129
2407
  LiquidationSideSchema,
2408
+ LiquidationVolumeArrayResponseSchema,
2409
+ LiquidationVolumeSchema,
2130
2410
  OpenInterestArrayResponseSchema,
2131
2411
  OpenInterestResponseSchema,
2132
2412
  OpenInterestSchema,
@@ -2138,6 +2418,8 @@ var OxArchiveWs = class {
2138
2418
  OxArchiveError,
2139
2419
  OxArchiveWs,
2140
2420
  PriceLevelSchema,
2421
+ PriceSnapshotArrayResponseSchema,
2422
+ PriceSnapshotSchema,
2141
2423
  TimestampedRecordSchema,
2142
2424
  TradeArrayResponseSchema,
2143
2425
  TradeDirectionSchema,
@@ -2153,6 +2435,7 @@ var OxArchiveWs = class {
2153
2435
  WsReplayCompletedSchema,
2154
2436
  WsReplayPausedSchema,
2155
2437
  WsReplayResumedSchema,
2438
+ WsReplaySnapshotSchema,
2156
2439
  WsReplayStartedSchema,
2157
2440
  WsReplayStoppedSchema,
2158
2441
  WsServerMessageSchema,