@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/README.md +36 -0
- package/dist/index.d.mts +155 -1
- package/dist/index.d.ts +155 -1
- package/dist/index.js +189 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,
|