@0xarchive/sdk 1.4.0 → 1.7.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
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  FundingRateResponseSchema: () => FundingRateResponseSchema,
35
35
  FundingRateSchema: () => FundingRateSchema,
36
36
  Hip3Client: () => Hip3Client,
37
+ Hip4Client: () => Hip4Client,
37
38
  HyperliquidClient: () => HyperliquidClient,
38
39
  InstrumentArrayResponseSchema: () => InstrumentArrayResponseSchema,
39
40
  InstrumentResponseSchema: () => InstrumentResponseSchema,
@@ -60,6 +61,7 @@ __export(index_exports, {
60
61
  PriceLevelSchema: () => PriceLevelSchema,
61
62
  PriceSnapshotArrayResponseSchema: () => PriceSnapshotArrayResponseSchema,
62
63
  PriceSnapshotSchema: () => PriceSnapshotSchema,
64
+ SpotClient: () => SpotClient,
63
65
  TimestampedRecordSchema: () => TimestampedRecordSchema,
64
66
  TradeArrayResponseSchema: () => TradeArrayResponseSchema,
65
67
  TradeDirectionSchema: () => TradeDirectionSchema,
@@ -71,6 +73,7 @@ __export(index_exports, {
71
73
  WsErrorSchema: () => WsErrorSchema,
72
74
  WsHistoricalBatchSchema: () => WsHistoricalBatchSchema,
73
75
  WsHistoricalDataSchema: () => WsHistoricalDataSchema,
76
+ WsOutcomeSettledSchema: () => WsOutcomeSettledSchema,
74
77
  WsPongSchema: () => WsPongSchema,
75
78
  WsReplayCompletedSchema: () => WsReplayCompletedSchema,
76
79
  WsReplayPausedSchema: () => WsReplayPausedSchema,
@@ -105,7 +108,7 @@ var OxArchiveError = class extends Error {
105
108
 
106
109
  // src/http.ts
107
110
  function snakeToCamel(str) {
108
- return str.replace(/_([a-z0-9])/g, (_, char) => char.toUpperCase());
111
+ return str.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
109
112
  }
110
113
  function transformKeys(obj) {
111
114
  if (obj === null || obj === void 0) {
@@ -358,7 +361,7 @@ var OpenInterestSchema = import_zod.z.object({
358
361
  impactBidPrice: import_zod.z.string().optional(),
359
362
  impactAskPrice: import_zod.z.string().optional()
360
363
  });
361
- var LiquidationSideSchema = import_zod.z.enum(["B", "S"]);
364
+ var LiquidationSideSchema = import_zod.z.enum(["A", "B"]);
362
365
  var LiquidationSchema = import_zod.z.object({
363
366
  coin: import_zod.z.string(),
364
367
  timestamp: import_zod.z.string(),
@@ -398,11 +401,27 @@ var WsChannelSchema = import_zod.z.enum([
398
401
  "lighter_candles",
399
402
  "lighter_open_interest",
400
403
  "lighter_funding",
404
+ "lighter_l3_orderbook",
401
405
  "hip3_orderbook",
402
406
  "hip3_trades",
403
407
  "hip3_candles",
404
408
  "hip3_open_interest",
405
- "hip3_funding"
409
+ "hip3_funding",
410
+ "hip3_liquidations",
411
+ "hip4_orderbook",
412
+ "hip4_trades",
413
+ "hip4_open_interest",
414
+ "spot_orderbook",
415
+ "spot_trades",
416
+ "spot_l4_diffs",
417
+ "spot_l4_orders",
418
+ "spot_twap",
419
+ "l4_diffs",
420
+ "l4_orders",
421
+ "hip3_l4_diffs",
422
+ "hip3_l4_orders",
423
+ "hip4_l4_diffs",
424
+ "hip4_l4_orders"
406
425
  ]);
407
426
  var WsConnectionStateSchema = import_zod.z.enum(["connecting", "connected", "disconnected", "reconnecting"]);
408
427
  var WsSubscribedSchema = import_zod.z.object({
@@ -498,6 +517,14 @@ var WsStreamStoppedSchema = import_zod.z.object({
498
517
  type: import_zod.z.literal("stream_stopped"),
499
518
  snapshots_sent: import_zod.z.number()
500
519
  });
520
+ var WsOutcomeSettledSchema = import_zod.z.object({
521
+ type: import_zod.z.literal("outcome_settled"),
522
+ coin: import_zod.z.string(),
523
+ outcome_id: import_zod.z.number(),
524
+ side: import_zod.z.number(),
525
+ settlement_value: import_zod.z.number().optional(),
526
+ settlement_at: import_zod.z.string().optional()
527
+ });
501
528
  var WsServerMessageSchema = import_zod.z.discriminatedUnion("type", [
502
529
  WsSubscribedSchema,
503
530
  WsUnsubscribedSchema,
@@ -515,7 +542,8 @@ var WsServerMessageSchema = import_zod.z.discriminatedUnion("type", [
515
542
  WsStreamProgressSchema,
516
543
  WsHistoricalBatchSchema,
517
544
  WsStreamCompletedSchema,
518
- WsStreamStoppedSchema
545
+ WsStreamStoppedSchema,
546
+ WsOutcomeSettledSchema
519
547
  ]);
520
548
  var OrderBookResponseSchema = ApiResponseSchema(OrderBookSchema);
521
549
  var OrderBookArrayResponseSchema = ApiResponseSchema(import_zod.z.array(OrderBookSchema));
@@ -1065,16 +1093,26 @@ var TradesResource = class {
1065
1093
  /**
1066
1094
  * Get most recent trades for a symbol.
1067
1095
  *
1068
- * Note: This method is available for Lighter (client.lighter.trades.recent())
1069
- * and HIP-3 (client.hyperliquid.hip3.trades.recent()) which have real-time data
1070
- * ingestion. Hyperliquid uses hourly backfill so this endpoint is not available
1071
- * for Hyperliquid.
1096
+ * Note: This method is available on Lighter (`client.lighter.trades.recent()`),
1097
+ * HIP-3 (`client.hyperliquid.hip3.trades.recent()`), and HIP-4
1098
+ * (`client.hyperliquid.hip4.trades.recent()`) which have real-time ingestion.
1099
+ * Hyperliquid uses hourly S3 backfill and does NOT expose a recent endpoint —
1100
+ * calling `client.hyperliquid.trades.recent()` (or the legacy
1101
+ * `client.trades.recent()`) throws a structured `OxArchiveError` rather than
1102
+ * letting the request fail with an opaque JSON parse error.
1072
1103
  *
1073
1104
  * @param symbol - The symbol (e.g., 'BTC', 'ETH')
1074
1105
  * @param limit - Number of trades to return (default: 100)
1075
1106
  * @returns Array of recent trades
1107
+ * @throws {OxArchiveError} When called on the bare Hyperliquid namespace.
1076
1108
  */
1077
1109
  async recent(symbol, limit) {
1110
+ if (this.basePath === "/v1/hyperliquid" || this.basePath === "/v1") {
1111
+ throw new OxArchiveError(
1112
+ "trades.recent() is not available on Hyperliquid (no real-time ingestion). Use client.hyperliquid.trades.list(symbol, { start, end }) with a time range, or call recent() on a real-time namespace: client.hyperliquid.hip3.trades.recent(), client.hyperliquid.hip4.trades.recent(), or client.lighter.trades.recent().",
1113
+ 404
1114
+ );
1115
+ }
1078
1116
  const response = await this.http.get(
1079
1117
  `${this.basePath}/trades/${this.coinTransform(symbol)}/recent`,
1080
1118
  { limit },
@@ -1179,6 +1217,61 @@ var Hip3InstrumentsResource = class {
1179
1217
  return response.data;
1180
1218
  }
1181
1219
  };
1220
+ var Hip4InstrumentsResource = class {
1221
+ constructor(http, basePath = "/v1/hyperliquid/hip4", coinTransform) {
1222
+ this.http = http;
1223
+ this.basePath = basePath;
1224
+ this.coinTransform = coinTransform || ((c) => encodeURIComponent(c));
1225
+ }
1226
+ coinTransform;
1227
+ async list() {
1228
+ const response = await this.http.get(
1229
+ `${this.basePath}/instruments`
1230
+ );
1231
+ return response.data;
1232
+ }
1233
+ async get(coin) {
1234
+ const response = await this.http.get(
1235
+ `${this.basePath}/instruments/${this.coinTransform(coin)}`
1236
+ );
1237
+ return response.data;
1238
+ }
1239
+ };
1240
+ var Hip4OutcomesResource = class {
1241
+ constructor(http, basePath = "/v1/hyperliquid/hip4") {
1242
+ this.http = http;
1243
+ this.basePath = basePath;
1244
+ }
1245
+ /** List per-outcome aggregates. `aggregatedOi` is omitted on list responses. */
1246
+ async list(params) {
1247
+ const response = await this.http.get(
1248
+ `${this.basePath}/outcomes`,
1249
+ params
1250
+ );
1251
+ return {
1252
+ data: response.data,
1253
+ nextCursor: response.meta.nextCursor
1254
+ };
1255
+ }
1256
+ /** Get a single outcome aggregate. Response includes `aggregatedOi`. */
1257
+ async get(outcomeId) {
1258
+ const response = await this.http.get(
1259
+ `${this.basePath}/outcomes/${outcomeId}`
1260
+ );
1261
+ return response.data;
1262
+ }
1263
+ /**
1264
+ * Look up an outcome aggregate by its synthesized slug. Accepts the
1265
+ * per-outcome slug (`btc-above-78213-may-04-0600`) OR a per-side slug
1266
+ * (`btc-above-78213-yes-may-04-0600`). Response includes `aggregatedOi`.
1267
+ */
1268
+ async getBySlug(slug) {
1269
+ const response = await this.http.get(
1270
+ `${this.basePath}/outcomes/by-slug/${slug}`
1271
+ );
1272
+ return response.data;
1273
+ }
1274
+ };
1182
1275
 
1183
1276
  // src/resources/funding.ts
1184
1277
  var FundingResource = class {
@@ -1371,7 +1464,7 @@ var DataQualityResource = class {
1371
1464
  /**
1372
1465
  * Get overall system health status
1373
1466
  *
1374
- * @returns StatusResponse with overall status, per-exchange status,
1467
+ * @returns StatusResponse with overall status, per-scope status,
1375
1468
  * per-data-type status, and active incident count
1376
1469
  *
1377
1470
  * @example
@@ -1390,9 +1483,9 @@ var DataQualityResource = class {
1390
1483
  // Coverage Endpoints
1391
1484
  // ===========================================================================
1392
1485
  /**
1393
- * Get data coverage summary for all exchanges
1486
+ * Get data coverage summary across venue APIs
1394
1487
  *
1395
- * @returns CoverageResponse with coverage info for all exchanges and data types
1488
+ * @returns CoverageResponse with coverage info for supported venue APIs and data types
1396
1489
  *
1397
1490
  * @example
1398
1491
  * ```typescript
@@ -1409,10 +1502,10 @@ var DataQualityResource = class {
1409
1502
  return this.http.get(`${this.basePath}/coverage`);
1410
1503
  }
1411
1504
  /**
1412
- * Get data coverage for a specific exchange
1505
+ * Get data coverage for a specific venue scope
1413
1506
  *
1414
- * @param exchange - Exchange name ('hyperliquid', 'lighter', or 'hip3')
1415
- * @returns ExchangeCoverage with coverage info for all data types on this exchange
1507
+ * @param exchange - Venue scope ('hyperliquid', 'lighter', 'hip3', or 'hip4')
1508
+ * @returns ExchangeCoverage with coverage info for all data types on this venue scope
1416
1509
  *
1417
1510
  * @example
1418
1511
  * ```typescript
@@ -1426,12 +1519,12 @@ var DataQualityResource = class {
1426
1519
  );
1427
1520
  }
1428
1521
  /**
1429
- * Get data coverage for a specific symbol on an exchange
1522
+ * Get data coverage for a specific symbol on a venue scope
1430
1523
  *
1431
1524
  * Includes gap detection, empirical data cadence, and hour-level historical coverage.
1432
1525
  * Supports optional time bounds for gap detection (default: last 30 days).
1433
1526
  *
1434
- * @param exchange - Exchange name ('hyperliquid', 'lighter', or 'hip3')
1527
+ * @param exchange - Venue scope ('hyperliquid', 'lighter', 'hip3', or 'hip4')
1435
1528
  * @param symbol - Symbol name (e.g., 'BTC', 'ETH', or HIP3 coins like 'xyz:XYZ100')
1436
1529
  * @param options - Optional time bounds for gap detection window
1437
1530
  * @returns SymbolCoverageResponse with per-data-type coverage including gaps, cadence, and historical coverage
@@ -1509,7 +1602,7 @@ var DataQualityResource = class {
1509
1602
  // Latency Endpoints
1510
1603
  // ===========================================================================
1511
1604
  /**
1512
- * Get current latency metrics for all exchanges
1605
+ * Get current latency metrics for supported venue APIs
1513
1606
  *
1514
1607
  * @returns LatencyResponse with WebSocket, REST API, and data freshness metrics
1515
1608
  *
@@ -1811,7 +1904,7 @@ var L2OrderBookResource = class {
1811
1904
  if (params?.timestamp != null) query.timestamp = params.timestamp;
1812
1905
  if (params?.depth != null) query.depth = params.depth;
1813
1906
  const resp = await this.http.get(
1814
- `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2`,
1907
+ `${this.basePath}/orderbook/${coin}/l2`,
1815
1908
  query
1816
1909
  );
1817
1910
  return resp.data;
@@ -1820,7 +1913,7 @@ var L2OrderBookResource = class {
1820
1913
  async history(symbol, params) {
1821
1914
  const coin = this.coinTransform(symbol);
1822
1915
  const resp = await this.http.get(
1823
- `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/history`,
1916
+ `${this.basePath}/orderbook/${coin}/l2/history`,
1824
1917
  params
1825
1918
  );
1826
1919
  return {
@@ -1832,7 +1925,7 @@ var L2OrderBookResource = class {
1832
1925
  async diffs(symbol, params) {
1833
1926
  const coin = this.coinTransform(symbol);
1834
1927
  const resp = await this.http.get(
1835
- `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/diffs`,
1928
+ `${this.basePath}/orderbook/${coin}/l2/diffs`,
1836
1929
  params
1837
1930
  );
1838
1931
  return {
@@ -1879,6 +1972,54 @@ var L3OrderBookResource = class {
1879
1972
  }
1880
1973
  };
1881
1974
 
1975
+ // src/resources/spot.ts
1976
+ var SpotPairsResource = class {
1977
+ constructor(http, basePath = "/v1/hyperliquid/spot", coinTransform = (c) => c.toUpperCase()) {
1978
+ this.http = http;
1979
+ this.basePath = basePath;
1980
+ this.coinTransform = coinTransform;
1981
+ }
1982
+ /** List every active spot pair. */
1983
+ async list() {
1984
+ const response = await this.http.get(
1985
+ `${this.basePath}/pairs`
1986
+ );
1987
+ return response.data;
1988
+ }
1989
+ /**
1990
+ * Get a specific spot pair by dashed symbol (e.g. `HYPE-USDC`).
1991
+ */
1992
+ async get(symbol) {
1993
+ const response = await this.http.get(
1994
+ `${this.basePath}/pairs/${this.coinTransform(symbol)}`
1995
+ );
1996
+ return response.data;
1997
+ }
1998
+ };
1999
+ var SpotTwapResource = class {
2000
+ constructor(http, basePath = "/v1/hyperliquid/spot", coinTransform = (c) => c.toUpperCase()) {
2001
+ this.http = http;
2002
+ this.basePath = basePath;
2003
+ this.coinTransform = coinTransform;
2004
+ }
2005
+ /** TWAP statuses for a single spot pair. */
2006
+ async bySymbol(symbol, params) {
2007
+ const response = await this.http.get(
2008
+ `${this.basePath}/twap/${this.coinTransform(symbol)}`,
2009
+ params
2010
+ );
2011
+ return { data: response.data, nextCursor: response.meta.nextCursor };
2012
+ }
2013
+ /** TWAP statuses for a single user wallet across every spot pair. */
2014
+ async byUser(user, params) {
2015
+ const response = await this.http.get(
2016
+ `${this.basePath}/twap/user/${user}`,
2017
+ params
2018
+ );
2019
+ return { data: response.data, nextCursor: response.meta.nextCursor };
2020
+ }
2021
+ };
2022
+
1882
2023
  // src/exchanges.ts
1883
2024
  var HyperliquidClient = class {
1884
2025
  /**
@@ -1925,6 +2066,10 @@ var HyperliquidClient = class {
1925
2066
  * HIP-3 builder-deployed perpetuals (February 2026+)
1926
2067
  */
1927
2068
  hip3;
2069
+ /**
2070
+ * HIP-4 outcome markets (binary YES/NO; May 2026+)
2071
+ */
2072
+ hip4;
1928
2073
  http;
1929
2074
  constructor(http) {
1930
2075
  this.http = http;
@@ -1940,6 +2085,7 @@ var HyperliquidClient = class {
1940
2085
  this.l4Orderbook = new L4OrderBookResource(http, basePath);
1941
2086
  this.l2Orderbook = new L2OrderBookResource(http, basePath);
1942
2087
  this.hip3 = new Hip3Client(http);
2088
+ this.hip4 = new Hip4Client(http);
1943
2089
  }
1944
2090
  /**
1945
2091
  * Get per-symbol data freshness across all data types
@@ -2092,6 +2238,244 @@ var Hip3Client = class {
2092
2238
  };
2093
2239
  }
2094
2240
  };
2241
+ var Hip4Client = class {
2242
+ /**
2243
+ * HIP-4 per-side instruments (one row per `#N`).
2244
+ */
2245
+ instruments;
2246
+ /**
2247
+ * HIP-4 per-outcome aggregates (one row per outcome). HIP-4-specific, no HIP-3 analog.
2248
+ */
2249
+ outcomes;
2250
+ /**
2251
+ * L2 orderbook snapshots (Pro+).
2252
+ */
2253
+ orderbook;
2254
+ /**
2255
+ * Trade/fill history.
2256
+ */
2257
+ trades;
2258
+ /**
2259
+ * Open interest (per side).
2260
+ */
2261
+ openInterest;
2262
+ /**
2263
+ * Order history, flow, and TP/SL (Pro+).
2264
+ */
2265
+ orders;
2266
+ /**
2267
+ * L4 orderbook (snapshots, diffs, history).
2268
+ */
2269
+ l4Orderbook;
2270
+ /**
2271
+ * L2 full-depth orderbook (derived from L4).
2272
+ */
2273
+ l2Orderbook;
2274
+ http;
2275
+ constructor(http) {
2276
+ this.http = http;
2277
+ const basePath = "/v1/hyperliquid/hip4";
2278
+ const coinTransform = (c) => encodeURIComponent(c);
2279
+ this.instruments = new Hip4InstrumentsResource(http, basePath, coinTransform);
2280
+ this.outcomes = new Hip4OutcomesResource(http, basePath);
2281
+ this.orderbook = new OrderBookResource(http, basePath, coinTransform);
2282
+ this.trades = new TradesResource(http, basePath, coinTransform);
2283
+ this.openInterest = new OpenInterestResource(http, basePath, coinTransform);
2284
+ this.orders = new OrdersResource(http, basePath, coinTransform);
2285
+ this.l4Orderbook = new L4OrderBookResource(http, basePath, coinTransform);
2286
+ this.l2Orderbook = new L2OrderBookResource(http, basePath, coinTransform);
2287
+ }
2288
+ /** @internal Encode a HIP-4 coin for use in URL paths. */
2289
+ encodeCoin(coin) {
2290
+ return encodeURIComponent(coin);
2291
+ }
2292
+ /**
2293
+ * List per-outcome aggregates. `aggregatedOi` is omitted on list responses.
2294
+ */
2295
+ async listOutcomes(params) {
2296
+ return this.outcomes.list(params);
2297
+ }
2298
+ /**
2299
+ * Get a single outcome aggregate (includes `aggregatedOi`).
2300
+ */
2301
+ async getOutcome(outcomeId) {
2302
+ return this.outcomes.get(outcomeId);
2303
+ }
2304
+ /**
2305
+ * Look up an outcome aggregate by slug. Accepts the per-outcome slug
2306
+ * (e.g. `btc-above-78213-may-04-0600`) OR a per-side slug
2307
+ * (e.g. `btc-above-78213-yes-may-04-0600`). Includes `aggregatedOi`.
2308
+ */
2309
+ async getOutcomeBySlug(slug) {
2310
+ return this.outcomes.getBySlug(slug);
2311
+ }
2312
+ /**
2313
+ * List all per-side instruments (one row per `#N`).
2314
+ */
2315
+ async getInstruments() {
2316
+ return this.instruments.list();
2317
+ }
2318
+ /**
2319
+ * Get a single per-side instrument by coin (e.g. `#0`).
2320
+ */
2321
+ async getInstrument(coin) {
2322
+ return this.instruments.get(coin);
2323
+ }
2324
+ /**
2325
+ * Get current L2 orderbook snapshot for a HIP-4 coin (Pro+).
2326
+ * @param coin Coin string with leading `#` (e.g. `#0`).
2327
+ */
2328
+ async getOrderbook(coin, params) {
2329
+ return this.orderbook.get(coin, params);
2330
+ }
2331
+ /**
2332
+ * Get historical L2 orderbook snapshots for a HIP-4 coin (Pro+).
2333
+ */
2334
+ async getOrderbookHistory(coin, params) {
2335
+ return this.orderbook.history(coin, params);
2336
+ }
2337
+ /**
2338
+ * Get historical fills for a HIP-4 coin.
2339
+ */
2340
+ async getTrades(coin, params) {
2341
+ return this.trades.list(coin, params);
2342
+ }
2343
+ /**
2344
+ * Get most recent N fills for a HIP-4 coin (latest first).
2345
+ */
2346
+ async getTradesRecent(coin, limit) {
2347
+ return this.trades.recent(coin, limit);
2348
+ }
2349
+ /**
2350
+ * Get per-side open interest history for a HIP-4 coin.
2351
+ * Note: `markPrice` on the response is an implied probability (0..1), not USD.
2352
+ */
2353
+ async getOpenInterest(coin, params) {
2354
+ return this.openInterest.history(coin, params);
2355
+ }
2356
+ /**
2357
+ * Get current per-side open interest for a HIP-4 coin.
2358
+ * Note: `markPrice` on the response is an implied probability (0..1), not USD.
2359
+ */
2360
+ async getOpenInterestCurrent(coin) {
2361
+ return this.openInterest.current(coin);
2362
+ }
2363
+ /**
2364
+ * Get combined market summary for a HIP-4 coin.
2365
+ * @param coin Either bare numeric form (`'0'`) or `#`-prefixed form (`'#0'`). The SDK URL-encodes `#` so both work.
2366
+ */
2367
+ async getSummary(coin) {
2368
+ const response = await this.http.get(
2369
+ `/v1/hyperliquid/hip4/summary/${this.encodeCoin(coin)}`,
2370
+ void 0,
2371
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
2372
+ );
2373
+ return response.data;
2374
+ }
2375
+ /**
2376
+ * Get per-symbol data freshness across all HIP-4 data types.
2377
+ * @param coin Either bare numeric form (`'0'`) or `#`-prefixed form (`'#0'`). The SDK URL-encodes `#` so both work.
2378
+ */
2379
+ async getFreshness(coin) {
2380
+ const response = await this.http.get(
2381
+ `/v1/hyperliquid/hip4/freshness/${this.encodeCoin(coin)}`,
2382
+ void 0,
2383
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
2384
+ );
2385
+ return response.data;
2386
+ }
2387
+ /**
2388
+ * Get mid-price history for a HIP-4 coin.
2389
+ * Note: returned `markPrice`/`midPrice` are probabilities (0..1), not USD.
2390
+ * @param coin Either bare numeric form (`'0'`) or `#`-prefixed form (`'#0'`). The SDK URL-encodes `#` so both work.
2391
+ */
2392
+ async getPrices(coin, params) {
2393
+ const response = await this.http.get(
2394
+ `/v1/hyperliquid/hip4/prices/${this.encodeCoin(coin)}`,
2395
+ params,
2396
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
2397
+ );
2398
+ return {
2399
+ data: response.data,
2400
+ nextCursor: response.meta.nextCursor
2401
+ };
2402
+ }
2403
+ /**
2404
+ * Get order lifecycle events for a HIP-4 coin (Pro+).
2405
+ */
2406
+ async getOrderHistory(coin, params) {
2407
+ return this.orders.history(coin, params);
2408
+ }
2409
+ /**
2410
+ * Get time-bucketed order-flow aggregates for a HIP-4 coin (Pro+).
2411
+ */
2412
+ async getOrderFlow(coin, params) {
2413
+ return this.orders.flow(coin, params);
2414
+ }
2415
+ /**
2416
+ * Get TP/SL orders for a HIP-4 coin (Pro+).
2417
+ */
2418
+ async getTpsl(coin, params) {
2419
+ return this.orders.tpsl(coin, params);
2420
+ }
2421
+ /**
2422
+ * Get full L4 reconstruction (current) for a HIP-4 coin (Pro+).
2423
+ */
2424
+ async getL4Orderbook(coin, params) {
2425
+ return this.l4Orderbook.get(coin, params);
2426
+ }
2427
+ /**
2428
+ * Get L4 diffs (event stream) for a HIP-4 coin (Pro+).
2429
+ */
2430
+ async getL4Diffs(coin, params) {
2431
+ return this.l4Orderbook.diffs(coin, params);
2432
+ }
2433
+ /**
2434
+ * Get L4 checkpoint history for a HIP-4 coin (Build+; hard cap limit=10).
2435
+ */
2436
+ async getL4History(coin, params) {
2437
+ return this.l4Orderbook.history(coin, params);
2438
+ }
2439
+ };
2440
+ var SpotClient = class {
2441
+ /** Spot pair metadata (one row per dashed symbol). */
2442
+ pairs;
2443
+ /** L2 order book snapshots (live from 2026-05-05). */
2444
+ orderbook;
2445
+ /** Trade history (S3 backfill from 2025-03-22, live since). */
2446
+ trades;
2447
+ /** Order lifecycle events (Pro+; live from 2026-05-05). */
2448
+ orders;
2449
+ /** L4 order book: snapshots, diffs, and checkpoint history. */
2450
+ l4Orderbook;
2451
+ /** TWAP statuses by symbol or by user wallet (Build+). */
2452
+ twap;
2453
+ http;
2454
+ constructor(http) {
2455
+ this.http = http;
2456
+ const basePath = "/v1/hyperliquid/spot";
2457
+ const coinTransform = (c) => c.toUpperCase();
2458
+ this.pairs = new SpotPairsResource(http, basePath, coinTransform);
2459
+ this.orderbook = new OrderBookResource(http, basePath, coinTransform);
2460
+ this.trades = new TradesResource(http, basePath, coinTransform);
2461
+ this.orders = new OrdersResource(http, basePath, coinTransform);
2462
+ this.l4Orderbook = new L4OrderBookResource(http, basePath, coinTransform);
2463
+ this.twap = new SpotTwapResource(http, basePath, coinTransform);
2464
+ }
2465
+ /**
2466
+ * Get per-symbol data freshness across all spot data types.
2467
+ *
2468
+ * @param symbol Dashed canonical (e.g. `HYPE-USDC`).
2469
+ */
2470
+ async freshness(symbol) {
2471
+ const response = await this.http.get(
2472
+ `/v1/hyperliquid/spot/freshness/${symbol.toUpperCase()}`,
2473
+ void 0,
2474
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
2475
+ );
2476
+ return response.data;
2477
+ }
2478
+ };
2095
2479
  var LighterClient = class {
2096
2480
  /**
2097
2481
  * Order book data (L2 snapshots)
@@ -2194,6 +2578,12 @@ var OxArchive = class {
2194
2578
  * Lighter.xyz exchange data (August 2025+)
2195
2579
  */
2196
2580
  lighter;
2581
+ /**
2582
+ * Hyperliquid Spot exchange data. Trades backfilled from 2025-03-22;
2583
+ * orderbook, L4, and TWAP statuses live from 2026-05-05. Symbols are
2584
+ * dashed canonical (e.g. `HYPE-USDC`).
2585
+ */
2586
+ spot;
2197
2587
  /**
2198
2588
  * Data quality metrics: status, coverage, incidents, latency, SLA
2199
2589
  */
@@ -2239,6 +2629,7 @@ var OxArchive = class {
2239
2629
  });
2240
2630
  this.hyperliquid = new HyperliquidClient(this.http);
2241
2631
  this.lighter = new LighterClient(this.http);
2632
+ this.spot = new SpotClient(this.http);
2242
2633
  this.dataQuality = new DataQualityResource(this.http);
2243
2634
  this.web3 = new Web3Resource(this.http);
2244
2635
  const legacyBase = "/v1/hyperliquid";
@@ -2346,7 +2737,9 @@ var OxArchiveWs = class {
2346
2737
  streamCompleteHandlers = [];
2347
2738
  orderbookHandlers = [];
2348
2739
  tradesHandlers = [];
2740
+ liquidationsHandlers = [];
2349
2741
  gapHandlers = [];
2742
+ outcomeSettledHandlers = [];
2350
2743
  constructor(options) {
2351
2744
  this.options = {
2352
2745
  apiKey: options.apiKey,
@@ -2430,7 +2823,7 @@ var OxArchiveWs = class {
2430
2823
  const key = this.subscriptionKey(channel, coin);
2431
2824
  this.subscriptions.add(key);
2432
2825
  if (this.isConnected()) {
2433
- this.send({ op: "subscribe", channel, coin });
2826
+ this.send({ op: "subscribe", channel, symbol: coin });
2434
2827
  }
2435
2828
  }
2436
2829
  /**
@@ -2464,7 +2857,7 @@ var OxArchiveWs = class {
2464
2857
  const key = this.subscriptionKey(channel, coin);
2465
2858
  this.subscriptions.delete(key);
2466
2859
  if (this.isConnected()) {
2467
- this.send({ op: "unsubscribe", channel, coin });
2860
+ this.send({ op: "unsubscribe", channel, symbol: coin });
2468
2861
  }
2469
2862
  }
2470
2863
  /**
@@ -2491,6 +2884,67 @@ var OxArchiveWs = class {
2491
2884
  unsubscribeAllTickers() {
2492
2885
  this.unsubscribe("all_tickers");
2493
2886
  }
2887
+ /**
2888
+ * Subscribe to live liquidation events for a coin (Hyperliquid).
2889
+ *
2890
+ * Each message is a fill row with `is_liquidation: true`. Same wire shape as
2891
+ * trades. Live as of v1.6.0 (Hyperliquid + HIP-3 nodes); historical replay
2892
+ * also supported via `replay('liquidations', ...)`.
2893
+ */
2894
+ subscribeLiquidations(coin) {
2895
+ this.subscribe("liquidations", coin);
2896
+ }
2897
+ /** Unsubscribe from live liquidation events (Hyperliquid). */
2898
+ unsubscribeLiquidations(coin) {
2899
+ this.unsubscribe("liquidations", coin);
2900
+ }
2901
+ /**
2902
+ * Subscribe to live HIP-3 liquidation events for a coin.
2903
+ * Each message is a fill row with `is_liquidation: true`.
2904
+ */
2905
+ subscribeHip3Liquidations(coin) {
2906
+ this.subscribe("hip3_liquidations", coin);
2907
+ }
2908
+ /** Unsubscribe from live HIP-3 liquidation events. */
2909
+ unsubscribeHip3Liquidations(coin) {
2910
+ this.unsubscribe("hip3_liquidations", coin);
2911
+ }
2912
+ /**
2913
+ * Subscribe to a Hyperliquid Spot channel for a given dashed pair.
2914
+ *
2915
+ * @param channel One of `spot_orderbook`, `spot_trades`, `spot_l4_diffs`,
2916
+ * `spot_l4_orders`, `spot_twap`. The short form (e.g. `'orderbook'`) is
2917
+ * also accepted and the `spot_` prefix is added automatically.
2918
+ * @param coin Spot dashed canonical symbol (e.g. `'HYPE-USDC'`).
2919
+ */
2920
+ subscribeSpot(channel, coin) {
2921
+ const fullChannel = channel.startsWith("spot_") ? channel : `spot_${channel}`;
2922
+ this.subscribe(fullChannel, coin);
2923
+ }
2924
+ /** Unsubscribe from a Hyperliquid Spot channel for a given dashed pair.
2925
+ * Accepts the short form (`'orderbook'`) or the full form (`'spot_orderbook'`). */
2926
+ unsubscribeSpot(channel, coin) {
2927
+ const fullChannel = channel.startsWith("spot_") ? channel : `spot_${channel}`;
2928
+ this.unsubscribe(fullChannel, coin);
2929
+ }
2930
+ /**
2931
+ * Subscribe to a HIP-4 channel for a given outcome coin.
2932
+ *
2933
+ * @param channel One of `hip4_orderbook`, `hip4_trades`, `hip4_open_interest`,
2934
+ * `hip4_l4_diffs`, `hip4_l4_orders`.
2935
+ * @param coin HIP-4 coin (e.g. `'#0'` or `'0'`). The bare numeric form is
2936
+ * recommended; both are accepted by the backend.
2937
+ */
2938
+ subscribeHip4(channel, coin) {
2939
+ const fullChannel = channel.startsWith("hip4_") ? channel : `hip4_${channel}`;
2940
+ this.subscribe(fullChannel, coin);
2941
+ }
2942
+ /** Unsubscribe from a HIP-4 channel for a given outcome coin. Accepts the
2943
+ * short channel form (`'orderbook'`) or the full form (`'hip4_orderbook'`). */
2944
+ unsubscribeHip4(channel, coin) {
2945
+ const fullChannel = channel.startsWith("hip4_") ? channel : `hip4_${channel}`;
2946
+ this.unsubscribe(fullChannel, coin);
2947
+ }
2494
2948
  // ==========================================================================
2495
2949
  // Historical Replay (Option B) - Like Tardis.dev
2496
2950
  // ==========================================================================
@@ -2513,7 +2967,7 @@ var OxArchiveWs = class {
2513
2967
  this.send({
2514
2968
  op: "replay",
2515
2969
  channel,
2516
- coin,
2970
+ symbol: coin,
2517
2971
  start: options.start,
2518
2972
  end: options.end,
2519
2973
  speed: options.speed ?? 1,
@@ -2548,7 +3002,7 @@ var OxArchiveWs = class {
2548
3002
  this.send({
2549
3003
  op: "replay",
2550
3004
  channels,
2551
- coin,
3005
+ symbol: coin,
2552
3006
  start: options.start,
2553
3007
  end: options.end,
2554
3008
  speed: options.speed ?? 1,
@@ -2604,7 +3058,7 @@ var OxArchiveWs = class {
2604
3058
  this.send({
2605
3059
  op: "stream",
2606
3060
  channel,
2607
- coin,
3061
+ symbol: coin,
2608
3062
  start: options.start,
2609
3063
  end: options.end,
2610
3064
  batch_size: options.batchSize ?? 1e3,
@@ -2641,7 +3095,7 @@ var OxArchiveWs = class {
2641
3095
  this.send({
2642
3096
  op: "stream",
2643
3097
  channels,
2644
- coin,
3098
+ symbol: coin,
2645
3099
  start: options.start,
2646
3100
  end: options.end,
2647
3101
  batch_size: options.batchSize ?? 1e3,
@@ -2780,6 +3234,44 @@ var OxArchiveWs = class {
2780
3234
  onTrades(handler) {
2781
3235
  this.tradesHandlers.push(handler);
2782
3236
  }
3237
+ /**
3238
+ * Helper to handle live liquidation events for both `liquidations` and
3239
+ * `hip3_liquidations` channels. Each item is a fill row with
3240
+ * `is_liquidation: true`, surfaced as a `Trade` (the wire shape matches
3241
+ * trades exactly).
3242
+ *
3243
+ * @param handler Called with the channel, coin, and parsed Trade array.
3244
+ *
3245
+ * @example
3246
+ * ```typescript
3247
+ * ws.onLiquidations((channel, coin, fills) => {
3248
+ * for (const f of fills) {
3249
+ * console.log(`${channel} ${coin} liq: ${f.side} ${f.size}@${f.price}`);
3250
+ * }
3251
+ * });
3252
+ * ws.subscribeLiquidations('BTC');
3253
+ * ws.subscribeHip3Liquidations('hyna:BTC');
3254
+ * ```
3255
+ */
3256
+ onLiquidations(handler) {
3257
+ this.liquidationsHandlers.push(handler);
3258
+ }
3259
+ /**
3260
+ * Handle HIP-4 outcome settlement events. Pushed once per `(outcome_id, side)`
3261
+ * when the outcome flips to settled. After this event the server proactively
3262
+ * unsubscribes the client from every hip4_* subscription on the settled coin —
3263
+ * treat the event as a terminal signal for that coin.
3264
+ *
3265
+ * @example
3266
+ * ```typescript
3267
+ * ws.onOutcomeSettled((coin, outcomeId, side, value, at) => {
3268
+ * console.log(`${coin} (outcome ${outcomeId} side ${side}) settled to ${value} at ${at}`);
3269
+ * });
3270
+ * ```
3271
+ */
3272
+ onOutcomeSettled(handler) {
3273
+ this.outcomeSettledHandlers.push(handler);
3274
+ }
2783
3275
  // Private methods
2784
3276
  send(message) {
2785
3277
  if (this.ws?.readyState === WebSocket.OPEN) {
@@ -2808,7 +3300,7 @@ var OxArchiveWs = class {
2808
3300
  resubscribe() {
2809
3301
  for (const key of this.subscriptions) {
2810
3302
  const [channel, coin] = key.split(":");
2811
- this.send({ op: "subscribe", channel, coin });
3303
+ this.send({ op: "subscribe", channel, symbol: coin });
2812
3304
  }
2813
3305
  }
2814
3306
  scheduleReconnect() {
@@ -2907,16 +3399,28 @@ var OxArchiveWs = class {
2907
3399
  break;
2908
3400
  }
2909
3401
  case "data": {
2910
- if (message.channel === "orderbook") {
3402
+ if (message.channel === "orderbook" || message.channel === "hip3_orderbook" || message.channel === "hip4_orderbook" || message.channel === "lighter_orderbook" || message.channel === "spot_orderbook") {
2911
3403
  const orderbook = transformOrderbook(message.coin, message.data);
2912
3404
  for (const handler of this.orderbookHandlers) {
2913
3405
  handler(message.coin, orderbook);
2914
3406
  }
2915
- } else if (message.channel === "trades") {
3407
+ } else if (message.channel === "trades" || message.channel === "hip3_trades" || message.channel === "hip4_trades" || message.channel === "lighter_trades" || message.channel === "spot_trades") {
2916
3408
  const trades = transformTrades(message.coin, message.data);
2917
3409
  for (const handler of this.tradesHandlers) {
2918
3410
  handler(message.coin, trades);
2919
3411
  }
3412
+ } else if (message.channel === "liquidations" || message.channel === "hip3_liquidations") {
3413
+ const fills = transformTrades(message.coin, message.data);
3414
+ for (const handler of this.liquidationsHandlers) {
3415
+ handler(message.channel, message.coin, fills);
3416
+ }
3417
+ }
3418
+ break;
3419
+ }
3420
+ case "outcome_settled": {
3421
+ const msg = message;
3422
+ for (const handler of this.outcomeSettledHandlers) {
3423
+ handler(msg.coin, msg.outcome_id, msg.side, msg.settlement_value, msg.settlement_at);
2920
3424
  }
2921
3425
  break;
2922
3426
  }
@@ -3069,6 +3573,7 @@ var L4OrderBookReconstructor = class {
3069
3573
  FundingRateResponseSchema,
3070
3574
  FundingRateSchema,
3071
3575
  Hip3Client,
3576
+ Hip4Client,
3072
3577
  HyperliquidClient,
3073
3578
  InstrumentArrayResponseSchema,
3074
3579
  InstrumentResponseSchema,
@@ -3095,6 +3600,7 @@ var L4OrderBookReconstructor = class {
3095
3600
  PriceLevelSchema,
3096
3601
  PriceSnapshotArrayResponseSchema,
3097
3602
  PriceSnapshotSchema,
3603
+ SpotClient,
3098
3604
  TimestampedRecordSchema,
3099
3605
  TradeArrayResponseSchema,
3100
3606
  TradeDirectionSchema,
@@ -3106,6 +3612,7 @@ var L4OrderBookReconstructor = class {
3106
3612
  WsErrorSchema,
3107
3613
  WsHistoricalBatchSchema,
3108
3614
  WsHistoricalDataSchema,
3615
+ WsOutcomeSettledSchema,
3109
3616
  WsPongSchema,
3110
3617
  WsReplayCompletedSchema,
3111
3618
  WsReplayPausedSchema,