@0xarchive/sdk 1.2.0 → 1.3.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.mjs CHANGED
@@ -1698,6 +1698,51 @@ var L4OrderBookResource = class {
1698
1698
  }
1699
1699
  };
1700
1700
 
1701
+ // src/resources/l2-orderbook.ts
1702
+ var L2OrderBookResource = class {
1703
+ constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
1704
+ this.http = http;
1705
+ this.basePath = basePath;
1706
+ this.coinTransform = coinTransform;
1707
+ }
1708
+ /** Get full-depth L2 order book snapshot. */
1709
+ async get(symbol, params) {
1710
+ const coin = this.coinTransform(symbol);
1711
+ const query = {};
1712
+ if (params?.timestamp != null) query.timestamp = params.timestamp;
1713
+ if (params?.depth != null) query.depth = params.depth;
1714
+ const resp = await this.http.get(
1715
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2`,
1716
+ query
1717
+ );
1718
+ return resp.data;
1719
+ }
1720
+ /** Get paginated L2 full-depth history. */
1721
+ async history(symbol, params) {
1722
+ const coin = this.coinTransform(symbol);
1723
+ const resp = await this.http.get(
1724
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/history`,
1725
+ params
1726
+ );
1727
+ return {
1728
+ data: resp.data,
1729
+ nextCursor: resp.meta?.next_cursor ?? void 0
1730
+ };
1731
+ }
1732
+ /** Get tick-level L2 order book diffs. */
1733
+ async diffs(symbol, params) {
1734
+ const coin = this.coinTransform(symbol);
1735
+ const resp = await this.http.get(
1736
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/diffs`,
1737
+ params
1738
+ );
1739
+ return {
1740
+ data: resp.data,
1741
+ nextCursor: resp.meta?.next_cursor ?? void 0
1742
+ };
1743
+ }
1744
+ };
1745
+
1701
1746
  // src/resources/l3-orderbook.ts
1702
1747
  var L3OrderBookResource = class {
1703
1748
  constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
@@ -1773,6 +1818,10 @@ var HyperliquidClient = class {
1773
1818
  * L4 order book (snapshots, diffs, history)
1774
1819
  */
1775
1820
  l4Orderbook;
1821
+ /**
1822
+ * L2 full-depth order book (derived from L4)
1823
+ */
1824
+ l2Orderbook;
1776
1825
  /**
1777
1826
  * HIP-3 builder-deployed perpetuals (February 2026+)
1778
1827
  */
@@ -1790,6 +1839,7 @@ var HyperliquidClient = class {
1790
1839
  this.liquidations = new LiquidationsResource(http, basePath);
1791
1840
  this.orders = new OrdersResource(http, basePath);
1792
1841
  this.l4Orderbook = new L4OrderBookResource(http, basePath);
1842
+ this.l2Orderbook = new L2OrderBookResource(http, basePath);
1793
1843
  this.hip3 = new Hip3Client(http);
1794
1844
  }
1795
1845
  /**
@@ -1876,6 +1926,10 @@ var Hip3Client = class {
1876
1926
  * L4 order book (snapshots, diffs, history)
1877
1927
  */
1878
1928
  l4Orderbook;
1929
+ /**
1930
+ * L2 full-depth order book (derived from L4)
1931
+ */
1932
+ l2Orderbook;
1879
1933
  http;
1880
1934
  constructor(http) {
1881
1935
  this.http = http;
@@ -1890,6 +1944,7 @@ var Hip3Client = class {
1890
1944
  this.liquidations = new LiquidationsResource(http, basePath, coinTransform);
1891
1945
  this.orders = new OrdersResource(http, basePath, coinTransform);
1892
1946
  this.l4Orderbook = new L4OrderBookResource(http, basePath, coinTransform);
1947
+ this.l2Orderbook = new L2OrderBookResource(http, basePath, coinTransform);
1893
1948
  }
1894
1949
  /**
1895
1950
  * Get per-symbol data freshness across all data types
@@ -2769,6 +2824,136 @@ var OxArchiveWs = class {
2769
2824
  }
2770
2825
  }
2771
2826
  };
2827
+
2828
+ // src/l4-reconstructor.ts
2829
+ var L4OrderBookReconstructor = class {
2830
+ orders = /* @__PURE__ */ new Map();
2831
+ bidPrices = /* @__PURE__ */ new Map();
2832
+ askPrices = /* @__PURE__ */ new Map();
2833
+ /** Initialize from an L4 checkpoint. */
2834
+ loadCheckpoint(checkpoint) {
2835
+ this.orders.clear();
2836
+ this.bidPrices.clear();
2837
+ this.askPrices.clear();
2838
+ for (const order of [...checkpoint.bids, ...checkpoint.asks]) {
2839
+ const oid = order.oid;
2840
+ const price = Number(order.price);
2841
+ const size = Number(order.size);
2842
+ const side = order.side;
2843
+ this.orders.set(oid, {
2844
+ oid,
2845
+ userAddress: order.user_address ?? order.userAddress ?? "",
2846
+ side,
2847
+ price,
2848
+ size
2849
+ });
2850
+ const priceMap = side === "B" ? this.bidPrices : this.askPrices;
2851
+ if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
2852
+ priceMap.get(price).add(oid);
2853
+ }
2854
+ }
2855
+ /** Apply a single L4 diff with matching engine. */
2856
+ applyDiff(diff, nonRestingOids) {
2857
+ const dt = diff.diff_type ?? diff.diffType;
2858
+ const oid = diff.oid;
2859
+ if (dt === "new") {
2860
+ if (nonRestingOids?.has(oid)) return;
2861
+ const newSize = diff.new_size ?? diff.newSize;
2862
+ if (newSize == null || newSize <= 0) return;
2863
+ const { side, price } = diff;
2864
+ const sz = newSize;
2865
+ if (side === "B") {
2866
+ for (const [askPx, oids] of this.askPrices) {
2867
+ if (askPx <= price) {
2868
+ for (const crossedOid of oids) this.orders.delete(crossedOid);
2869
+ this.askPrices.delete(askPx);
2870
+ }
2871
+ }
2872
+ } else {
2873
+ for (const [bidPx, oids] of this.bidPrices) {
2874
+ if (bidPx >= price) {
2875
+ for (const crossedOid of oids) this.orders.delete(crossedOid);
2876
+ this.bidPrices.delete(bidPx);
2877
+ }
2878
+ }
2879
+ }
2880
+ this.orders.set(oid, {
2881
+ oid,
2882
+ userAddress: diff.user_address ?? diff.userAddress ?? "",
2883
+ side,
2884
+ price,
2885
+ size: sz
2886
+ });
2887
+ const priceMap = side === "B" ? this.bidPrices : this.askPrices;
2888
+ if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
2889
+ priceMap.get(price).add(oid);
2890
+ } else if (dt === "update") {
2891
+ const order = this.orders.get(oid);
2892
+ const updSize = diff.new_size ?? diff.newSize;
2893
+ if (order && updSize != null) {
2894
+ order.size = updSize;
2895
+ }
2896
+ } else if (dt === "remove") {
2897
+ const order = this.orders.get(oid);
2898
+ if (order) {
2899
+ this.orders.delete(oid);
2900
+ const priceMap = order.side === "B" ? this.bidPrices : this.askPrices;
2901
+ const oids = priceMap.get(order.price);
2902
+ if (oids) {
2903
+ oids.delete(oid);
2904
+ if (oids.size === 0) priceMap.delete(order.price);
2905
+ }
2906
+ }
2907
+ }
2908
+ }
2909
+ /** Return bids sorted by price descending. */
2910
+ bids() {
2911
+ return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).sort((a, b) => b.price - a.price);
2912
+ }
2913
+ /** Return asks sorted by price ascending. */
2914
+ asks() {
2915
+ return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).sort((a, b) => a.price - b.price);
2916
+ }
2917
+ bestBid() {
2918
+ const b = this.bids();
2919
+ return b.length > 0 ? b[0].price : null;
2920
+ }
2921
+ bestAsk() {
2922
+ const a = this.asks();
2923
+ return a.length > 0 ? a[0].price : null;
2924
+ }
2925
+ /** Check if the book is crossed. Should be false after correct reconstruction. */
2926
+ isCrossed() {
2927
+ const bb = this.bestBid();
2928
+ const ba = this.bestAsk();
2929
+ return bb != null && ba != null && bb >= ba;
2930
+ }
2931
+ get bidCount() {
2932
+ return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).length;
2933
+ }
2934
+ get askCount() {
2935
+ return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).length;
2936
+ }
2937
+ /** Aggregate L4 orders into L2 price levels. */
2938
+ deriveL2() {
2939
+ const bidAgg = /* @__PURE__ */ new Map();
2940
+ const askAgg = /* @__PURE__ */ new Map();
2941
+ for (const o of this.orders.values()) {
2942
+ if (o.size <= 0) continue;
2943
+ const agg = o.side === "B" ? bidAgg : askAgg;
2944
+ const existing = agg.get(o.price);
2945
+ if (existing) {
2946
+ existing.sz += o.size;
2947
+ existing.n += 1;
2948
+ } else {
2949
+ agg.set(o.price, { sz: o.size, n: 1 });
2950
+ }
2951
+ }
2952
+ const bids = [...bidAgg.entries()].sort(([a], [b]) => b - a).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
2953
+ const asks = [...askAgg.entries()].sort(([a], [b]) => a - b).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
2954
+ return { bids, asks };
2955
+ }
2956
+ };
2772
2957
  export {
2773
2958
  ApiMetaSchema,
2774
2959
  ApiResponseSchema,
@@ -2789,6 +2974,8 @@ export {
2789
2974
  InstrumentResponseSchema,
2790
2975
  InstrumentSchema,
2791
2976
  InstrumentTypeSchema,
2977
+ L2OrderBookResource,
2978
+ L4OrderBookReconstructor,
2792
2979
  LighterClient,
2793
2980
  LiquidationArrayResponseSchema,
2794
2981
  LiquidationSchema,