@0xarchive/sdk 1.2.0 → 1.4.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
@@ -230,7 +230,13 @@ var TradeSchema = z.object({
230
230
  startPosition: z.string().optional(),
231
231
  userAddress: z.string().optional(),
232
232
  makerAddress: z.string().optional(),
233
- takerAddress: z.string().optional()
233
+ takerAddress: z.string().optional(),
234
+ builderAddress: z.string().optional(),
235
+ builderFee: z.string().optional(),
236
+ deployerFee: z.string().optional(),
237
+ priorityGas: z.number().optional(),
238
+ cloid: z.string().optional(),
239
+ twapId: z.number().optional()
234
240
  });
235
241
  var InstrumentTypeSchema = z.enum(["perp", "spot"]);
236
242
  var InstrumentSchema = z.object({
@@ -1698,6 +1704,51 @@ var L4OrderBookResource = class {
1698
1704
  }
1699
1705
  };
1700
1706
 
1707
+ // src/resources/l2-orderbook.ts
1708
+ var L2OrderBookResource = class {
1709
+ constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
1710
+ this.http = http;
1711
+ this.basePath = basePath;
1712
+ this.coinTransform = coinTransform;
1713
+ }
1714
+ /** Get full-depth L2 order book snapshot. */
1715
+ async get(symbol, params) {
1716
+ const coin = this.coinTransform(symbol);
1717
+ const query = {};
1718
+ if (params?.timestamp != null) query.timestamp = params.timestamp;
1719
+ if (params?.depth != null) query.depth = params.depth;
1720
+ const resp = await this.http.get(
1721
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2`,
1722
+ query
1723
+ );
1724
+ return resp.data;
1725
+ }
1726
+ /** Get paginated L2 full-depth history. */
1727
+ async history(symbol, params) {
1728
+ const coin = this.coinTransform(symbol);
1729
+ const resp = await this.http.get(
1730
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/history`,
1731
+ params
1732
+ );
1733
+ return {
1734
+ data: resp.data,
1735
+ nextCursor: resp.meta?.next_cursor ?? void 0
1736
+ };
1737
+ }
1738
+ /** Get tick-level L2 order book diffs. */
1739
+ async diffs(symbol, params) {
1740
+ const coin = this.coinTransform(symbol);
1741
+ const resp = await this.http.get(
1742
+ `${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/diffs`,
1743
+ params
1744
+ );
1745
+ return {
1746
+ data: resp.data,
1747
+ nextCursor: resp.meta?.next_cursor ?? void 0
1748
+ };
1749
+ }
1750
+ };
1751
+
1701
1752
  // src/resources/l3-orderbook.ts
1702
1753
  var L3OrderBookResource = class {
1703
1754
  constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
@@ -1773,6 +1824,10 @@ var HyperliquidClient = class {
1773
1824
  * L4 order book (snapshots, diffs, history)
1774
1825
  */
1775
1826
  l4Orderbook;
1827
+ /**
1828
+ * L2 full-depth order book (derived from L4)
1829
+ */
1830
+ l2Orderbook;
1776
1831
  /**
1777
1832
  * HIP-3 builder-deployed perpetuals (February 2026+)
1778
1833
  */
@@ -1790,6 +1845,7 @@ var HyperliquidClient = class {
1790
1845
  this.liquidations = new LiquidationsResource(http, basePath);
1791
1846
  this.orders = new OrdersResource(http, basePath);
1792
1847
  this.l4Orderbook = new L4OrderBookResource(http, basePath);
1848
+ this.l2Orderbook = new L2OrderBookResource(http, basePath);
1793
1849
  this.hip3 = new Hip3Client(http);
1794
1850
  }
1795
1851
  /**
@@ -1876,6 +1932,10 @@ var Hip3Client = class {
1876
1932
  * L4 order book (snapshots, diffs, history)
1877
1933
  */
1878
1934
  l4Orderbook;
1935
+ /**
1936
+ * L2 full-depth order book (derived from L4)
1937
+ */
1938
+ l2Orderbook;
1879
1939
  http;
1880
1940
  constructor(http) {
1881
1941
  this.http = http;
@@ -1890,6 +1950,7 @@ var Hip3Client = class {
1890
1950
  this.liquidations = new LiquidationsResource(http, basePath, coinTransform);
1891
1951
  this.orders = new OrdersResource(http, basePath, coinTransform);
1892
1952
  this.l4Orderbook = new L4OrderBookResource(http, basePath, coinTransform);
1953
+ this.l2Orderbook = new L2OrderBookResource(http, basePath, coinTransform);
1893
1954
  }
1894
1955
  /**
1895
1956
  * Get per-symbol data freshness across all data types
@@ -2769,6 +2830,136 @@ var OxArchiveWs = class {
2769
2830
  }
2770
2831
  }
2771
2832
  };
2833
+
2834
+ // src/l4-reconstructor.ts
2835
+ var L4OrderBookReconstructor = class {
2836
+ orders = /* @__PURE__ */ new Map();
2837
+ bidPrices = /* @__PURE__ */ new Map();
2838
+ askPrices = /* @__PURE__ */ new Map();
2839
+ /** Initialize from an L4 checkpoint. */
2840
+ loadCheckpoint(checkpoint) {
2841
+ this.orders.clear();
2842
+ this.bidPrices.clear();
2843
+ this.askPrices.clear();
2844
+ for (const order of [...checkpoint.bids, ...checkpoint.asks]) {
2845
+ const oid = order.oid;
2846
+ const price = Number(order.price);
2847
+ const size = Number(order.size);
2848
+ const side = order.side;
2849
+ this.orders.set(oid, {
2850
+ oid,
2851
+ userAddress: order.user_address ?? order.userAddress ?? "",
2852
+ side,
2853
+ price,
2854
+ size
2855
+ });
2856
+ const priceMap = side === "B" ? this.bidPrices : this.askPrices;
2857
+ if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
2858
+ priceMap.get(price).add(oid);
2859
+ }
2860
+ }
2861
+ /** Apply a single L4 diff with matching engine. */
2862
+ applyDiff(diff, nonRestingOids) {
2863
+ const dt = diff.diff_type ?? diff.diffType;
2864
+ const oid = diff.oid;
2865
+ if (dt === "new") {
2866
+ if (nonRestingOids?.has(oid)) return;
2867
+ const newSize = diff.new_size ?? diff.newSize;
2868
+ if (newSize == null || newSize <= 0) return;
2869
+ const { side, price } = diff;
2870
+ const sz = newSize;
2871
+ if (side === "B") {
2872
+ for (const [askPx, oids] of this.askPrices) {
2873
+ if (askPx <= price) {
2874
+ for (const crossedOid of oids) this.orders.delete(crossedOid);
2875
+ this.askPrices.delete(askPx);
2876
+ }
2877
+ }
2878
+ } else {
2879
+ for (const [bidPx, oids] of this.bidPrices) {
2880
+ if (bidPx >= price) {
2881
+ for (const crossedOid of oids) this.orders.delete(crossedOid);
2882
+ this.bidPrices.delete(bidPx);
2883
+ }
2884
+ }
2885
+ }
2886
+ this.orders.set(oid, {
2887
+ oid,
2888
+ userAddress: diff.user_address ?? diff.userAddress ?? "",
2889
+ side,
2890
+ price,
2891
+ size: sz
2892
+ });
2893
+ const priceMap = side === "B" ? this.bidPrices : this.askPrices;
2894
+ if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
2895
+ priceMap.get(price).add(oid);
2896
+ } else if (dt === "update") {
2897
+ const order = this.orders.get(oid);
2898
+ const updSize = diff.new_size ?? diff.newSize;
2899
+ if (order && updSize != null) {
2900
+ order.size = updSize;
2901
+ }
2902
+ } else if (dt === "remove") {
2903
+ const order = this.orders.get(oid);
2904
+ if (order) {
2905
+ this.orders.delete(oid);
2906
+ const priceMap = order.side === "B" ? this.bidPrices : this.askPrices;
2907
+ const oids = priceMap.get(order.price);
2908
+ if (oids) {
2909
+ oids.delete(oid);
2910
+ if (oids.size === 0) priceMap.delete(order.price);
2911
+ }
2912
+ }
2913
+ }
2914
+ }
2915
+ /** Return bids sorted by price descending. */
2916
+ bids() {
2917
+ return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).sort((a, b) => b.price - a.price);
2918
+ }
2919
+ /** Return asks sorted by price ascending. */
2920
+ asks() {
2921
+ return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).sort((a, b) => a.price - b.price);
2922
+ }
2923
+ bestBid() {
2924
+ const b = this.bids();
2925
+ return b.length > 0 ? b[0].price : null;
2926
+ }
2927
+ bestAsk() {
2928
+ const a = this.asks();
2929
+ return a.length > 0 ? a[0].price : null;
2930
+ }
2931
+ /** Check if the book is crossed. Should be false after correct reconstruction. */
2932
+ isCrossed() {
2933
+ const bb = this.bestBid();
2934
+ const ba = this.bestAsk();
2935
+ return bb != null && ba != null && bb >= ba;
2936
+ }
2937
+ get bidCount() {
2938
+ return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).length;
2939
+ }
2940
+ get askCount() {
2941
+ return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).length;
2942
+ }
2943
+ /** Aggregate L4 orders into L2 price levels. */
2944
+ deriveL2() {
2945
+ const bidAgg = /* @__PURE__ */ new Map();
2946
+ const askAgg = /* @__PURE__ */ new Map();
2947
+ for (const o of this.orders.values()) {
2948
+ if (o.size <= 0) continue;
2949
+ const agg = o.side === "B" ? bidAgg : askAgg;
2950
+ const existing = agg.get(o.price);
2951
+ if (existing) {
2952
+ existing.sz += o.size;
2953
+ existing.n += 1;
2954
+ } else {
2955
+ agg.set(o.price, { sz: o.size, n: 1 });
2956
+ }
2957
+ }
2958
+ const bids = [...bidAgg.entries()].sort(([a], [b]) => b - a).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
2959
+ const asks = [...askAgg.entries()].sort(([a], [b]) => a - b).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
2960
+ return { bids, asks };
2961
+ }
2962
+ };
2772
2963
  export {
2773
2964
  ApiMetaSchema,
2774
2965
  ApiResponseSchema,
@@ -2789,6 +2980,8 @@ export {
2789
2980
  InstrumentResponseSchema,
2790
2981
  InstrumentSchema,
2791
2982
  InstrumentTypeSchema,
2983
+ L2OrderBookResource,
2984
+ L4OrderBookReconstructor,
2792
2985
  LighterClient,
2793
2986
  LiquidationArrayResponseSchema,
2794
2987
  LiquidationSchema,