@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.js
CHANGED
|
@@ -39,6 +39,8 @@ __export(index_exports, {
|
|
|
39
39
|
InstrumentResponseSchema: () => InstrumentResponseSchema,
|
|
40
40
|
InstrumentSchema: () => InstrumentSchema,
|
|
41
41
|
InstrumentTypeSchema: () => InstrumentTypeSchema,
|
|
42
|
+
L2OrderBookResource: () => L2OrderBookResource,
|
|
43
|
+
L4OrderBookReconstructor: () => L4OrderBookReconstructor,
|
|
42
44
|
LighterClient: () => LighterClient,
|
|
43
45
|
LiquidationArrayResponseSchema: () => LiquidationArrayResponseSchema,
|
|
44
46
|
LiquidationSchema: () => LiquidationSchema,
|
|
@@ -1789,6 +1791,51 @@ var L4OrderBookResource = class {
|
|
|
1789
1791
|
}
|
|
1790
1792
|
};
|
|
1791
1793
|
|
|
1794
|
+
// src/resources/l2-orderbook.ts
|
|
1795
|
+
var L2OrderBookResource = class {
|
|
1796
|
+
constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
|
|
1797
|
+
this.http = http;
|
|
1798
|
+
this.basePath = basePath;
|
|
1799
|
+
this.coinTransform = coinTransform;
|
|
1800
|
+
}
|
|
1801
|
+
/** Get full-depth L2 order book snapshot. */
|
|
1802
|
+
async get(symbol, params) {
|
|
1803
|
+
const coin = this.coinTransform(symbol);
|
|
1804
|
+
const query = {};
|
|
1805
|
+
if (params?.timestamp != null) query.timestamp = params.timestamp;
|
|
1806
|
+
if (params?.depth != null) query.depth = params.depth;
|
|
1807
|
+
const resp = await this.http.get(
|
|
1808
|
+
`${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2`,
|
|
1809
|
+
query
|
|
1810
|
+
);
|
|
1811
|
+
return resp.data;
|
|
1812
|
+
}
|
|
1813
|
+
/** Get paginated L2 full-depth history. */
|
|
1814
|
+
async history(symbol, params) {
|
|
1815
|
+
const coin = this.coinTransform(symbol);
|
|
1816
|
+
const resp = await this.http.get(
|
|
1817
|
+
`${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/history`,
|
|
1818
|
+
params
|
|
1819
|
+
);
|
|
1820
|
+
return {
|
|
1821
|
+
data: resp.data,
|
|
1822
|
+
nextCursor: resp.meta?.next_cursor ?? void 0
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1825
|
+
/** Get tick-level L2 order book diffs. */
|
|
1826
|
+
async diffs(symbol, params) {
|
|
1827
|
+
const coin = this.coinTransform(symbol);
|
|
1828
|
+
const resp = await this.http.get(
|
|
1829
|
+
`${this.basePath}/orderbook/${encodeURIComponent(coin)}/l2/diffs`,
|
|
1830
|
+
params
|
|
1831
|
+
);
|
|
1832
|
+
return {
|
|
1833
|
+
data: resp.data,
|
|
1834
|
+
nextCursor: resp.meta?.next_cursor ?? void 0
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
|
|
1792
1839
|
// src/resources/l3-orderbook.ts
|
|
1793
1840
|
var L3OrderBookResource = class {
|
|
1794
1841
|
constructor(http, basePath = "/v1", coinTransform = (c) => c.toUpperCase()) {
|
|
@@ -1864,6 +1911,10 @@ var HyperliquidClient = class {
|
|
|
1864
1911
|
* L4 order book (snapshots, diffs, history)
|
|
1865
1912
|
*/
|
|
1866
1913
|
l4Orderbook;
|
|
1914
|
+
/**
|
|
1915
|
+
* L2 full-depth order book (derived from L4)
|
|
1916
|
+
*/
|
|
1917
|
+
l2Orderbook;
|
|
1867
1918
|
/**
|
|
1868
1919
|
* HIP-3 builder-deployed perpetuals (February 2026+)
|
|
1869
1920
|
*/
|
|
@@ -1881,6 +1932,7 @@ var HyperliquidClient = class {
|
|
|
1881
1932
|
this.liquidations = new LiquidationsResource(http, basePath);
|
|
1882
1933
|
this.orders = new OrdersResource(http, basePath);
|
|
1883
1934
|
this.l4Orderbook = new L4OrderBookResource(http, basePath);
|
|
1935
|
+
this.l2Orderbook = new L2OrderBookResource(http, basePath);
|
|
1884
1936
|
this.hip3 = new Hip3Client(http);
|
|
1885
1937
|
}
|
|
1886
1938
|
/**
|
|
@@ -1967,6 +2019,10 @@ var Hip3Client = class {
|
|
|
1967
2019
|
* L4 order book (snapshots, diffs, history)
|
|
1968
2020
|
*/
|
|
1969
2021
|
l4Orderbook;
|
|
2022
|
+
/**
|
|
2023
|
+
* L2 full-depth order book (derived from L4)
|
|
2024
|
+
*/
|
|
2025
|
+
l2Orderbook;
|
|
1970
2026
|
http;
|
|
1971
2027
|
constructor(http) {
|
|
1972
2028
|
this.http = http;
|
|
@@ -1981,6 +2037,7 @@ var Hip3Client = class {
|
|
|
1981
2037
|
this.liquidations = new LiquidationsResource(http, basePath, coinTransform);
|
|
1982
2038
|
this.orders = new OrdersResource(http, basePath, coinTransform);
|
|
1983
2039
|
this.l4Orderbook = new L4OrderBookResource(http, basePath, coinTransform);
|
|
2040
|
+
this.l2Orderbook = new L2OrderBookResource(http, basePath, coinTransform);
|
|
1984
2041
|
}
|
|
1985
2042
|
/**
|
|
1986
2043
|
* Get per-symbol data freshness across all data types
|
|
@@ -2860,6 +2917,136 @@ var OxArchiveWs = class {
|
|
|
2860
2917
|
}
|
|
2861
2918
|
}
|
|
2862
2919
|
};
|
|
2920
|
+
|
|
2921
|
+
// src/l4-reconstructor.ts
|
|
2922
|
+
var L4OrderBookReconstructor = class {
|
|
2923
|
+
orders = /* @__PURE__ */ new Map();
|
|
2924
|
+
bidPrices = /* @__PURE__ */ new Map();
|
|
2925
|
+
askPrices = /* @__PURE__ */ new Map();
|
|
2926
|
+
/** Initialize from an L4 checkpoint. */
|
|
2927
|
+
loadCheckpoint(checkpoint) {
|
|
2928
|
+
this.orders.clear();
|
|
2929
|
+
this.bidPrices.clear();
|
|
2930
|
+
this.askPrices.clear();
|
|
2931
|
+
for (const order of [...checkpoint.bids, ...checkpoint.asks]) {
|
|
2932
|
+
const oid = order.oid;
|
|
2933
|
+
const price = Number(order.price);
|
|
2934
|
+
const size = Number(order.size);
|
|
2935
|
+
const side = order.side;
|
|
2936
|
+
this.orders.set(oid, {
|
|
2937
|
+
oid,
|
|
2938
|
+
userAddress: order.user_address ?? order.userAddress ?? "",
|
|
2939
|
+
side,
|
|
2940
|
+
price,
|
|
2941
|
+
size
|
|
2942
|
+
});
|
|
2943
|
+
const priceMap = side === "B" ? this.bidPrices : this.askPrices;
|
|
2944
|
+
if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
|
|
2945
|
+
priceMap.get(price).add(oid);
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
/** Apply a single L4 diff with matching engine. */
|
|
2949
|
+
applyDiff(diff, nonRestingOids) {
|
|
2950
|
+
const dt = diff.diff_type ?? diff.diffType;
|
|
2951
|
+
const oid = diff.oid;
|
|
2952
|
+
if (dt === "new") {
|
|
2953
|
+
if (nonRestingOids?.has(oid)) return;
|
|
2954
|
+
const newSize = diff.new_size ?? diff.newSize;
|
|
2955
|
+
if (newSize == null || newSize <= 0) return;
|
|
2956
|
+
const { side, price } = diff;
|
|
2957
|
+
const sz = newSize;
|
|
2958
|
+
if (side === "B") {
|
|
2959
|
+
for (const [askPx, oids] of this.askPrices) {
|
|
2960
|
+
if (askPx <= price) {
|
|
2961
|
+
for (const crossedOid of oids) this.orders.delete(crossedOid);
|
|
2962
|
+
this.askPrices.delete(askPx);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
} else {
|
|
2966
|
+
for (const [bidPx, oids] of this.bidPrices) {
|
|
2967
|
+
if (bidPx >= price) {
|
|
2968
|
+
for (const crossedOid of oids) this.orders.delete(crossedOid);
|
|
2969
|
+
this.bidPrices.delete(bidPx);
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
this.orders.set(oid, {
|
|
2974
|
+
oid,
|
|
2975
|
+
userAddress: diff.user_address ?? diff.userAddress ?? "",
|
|
2976
|
+
side,
|
|
2977
|
+
price,
|
|
2978
|
+
size: sz
|
|
2979
|
+
});
|
|
2980
|
+
const priceMap = side === "B" ? this.bidPrices : this.askPrices;
|
|
2981
|
+
if (!priceMap.has(price)) priceMap.set(price, /* @__PURE__ */ new Set());
|
|
2982
|
+
priceMap.get(price).add(oid);
|
|
2983
|
+
} else if (dt === "update") {
|
|
2984
|
+
const order = this.orders.get(oid);
|
|
2985
|
+
const updSize = diff.new_size ?? diff.newSize;
|
|
2986
|
+
if (order && updSize != null) {
|
|
2987
|
+
order.size = updSize;
|
|
2988
|
+
}
|
|
2989
|
+
} else if (dt === "remove") {
|
|
2990
|
+
const order = this.orders.get(oid);
|
|
2991
|
+
if (order) {
|
|
2992
|
+
this.orders.delete(oid);
|
|
2993
|
+
const priceMap = order.side === "B" ? this.bidPrices : this.askPrices;
|
|
2994
|
+
const oids = priceMap.get(order.price);
|
|
2995
|
+
if (oids) {
|
|
2996
|
+
oids.delete(oid);
|
|
2997
|
+
if (oids.size === 0) priceMap.delete(order.price);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
/** Return bids sorted by price descending. */
|
|
3003
|
+
bids() {
|
|
3004
|
+
return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).sort((a, b) => b.price - a.price);
|
|
3005
|
+
}
|
|
3006
|
+
/** Return asks sorted by price ascending. */
|
|
3007
|
+
asks() {
|
|
3008
|
+
return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).sort((a, b) => a.price - b.price);
|
|
3009
|
+
}
|
|
3010
|
+
bestBid() {
|
|
3011
|
+
const b = this.bids();
|
|
3012
|
+
return b.length > 0 ? b[0].price : null;
|
|
3013
|
+
}
|
|
3014
|
+
bestAsk() {
|
|
3015
|
+
const a = this.asks();
|
|
3016
|
+
return a.length > 0 ? a[0].price : null;
|
|
3017
|
+
}
|
|
3018
|
+
/** Check if the book is crossed. Should be false after correct reconstruction. */
|
|
3019
|
+
isCrossed() {
|
|
3020
|
+
const bb = this.bestBid();
|
|
3021
|
+
const ba = this.bestAsk();
|
|
3022
|
+
return bb != null && ba != null && bb >= ba;
|
|
3023
|
+
}
|
|
3024
|
+
get bidCount() {
|
|
3025
|
+
return [...this.orders.values()].filter((o) => o.side === "B" && o.size > 0).length;
|
|
3026
|
+
}
|
|
3027
|
+
get askCount() {
|
|
3028
|
+
return [...this.orders.values()].filter((o) => o.side === "A" && o.size > 0).length;
|
|
3029
|
+
}
|
|
3030
|
+
/** Aggregate L4 orders into L2 price levels. */
|
|
3031
|
+
deriveL2() {
|
|
3032
|
+
const bidAgg = /* @__PURE__ */ new Map();
|
|
3033
|
+
const askAgg = /* @__PURE__ */ new Map();
|
|
3034
|
+
for (const o of this.orders.values()) {
|
|
3035
|
+
if (o.size <= 0) continue;
|
|
3036
|
+
const agg = o.side === "B" ? bidAgg : askAgg;
|
|
3037
|
+
const existing = agg.get(o.price);
|
|
3038
|
+
if (existing) {
|
|
3039
|
+
existing.sz += o.size;
|
|
3040
|
+
existing.n += 1;
|
|
3041
|
+
} else {
|
|
3042
|
+
agg.set(o.price, { sz: o.size, n: 1 });
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
const bids = [...bidAgg.entries()].sort(([a], [b]) => b - a).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
|
|
3046
|
+
const asks = [...askAgg.entries()].sort(([a], [b]) => a - b).map(([px, v]) => ({ px, sz: v.sz, n: v.n }));
|
|
3047
|
+
return { bids, asks };
|
|
3048
|
+
}
|
|
3049
|
+
};
|
|
2863
3050
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2864
3051
|
0 && (module.exports = {
|
|
2865
3052
|
ApiMetaSchema,
|
|
@@ -2881,6 +3068,8 @@ var OxArchiveWs = class {
|
|
|
2881
3068
|
InstrumentResponseSchema,
|
|
2882
3069
|
InstrumentSchema,
|
|
2883
3070
|
InstrumentTypeSchema,
|
|
3071
|
+
L2OrderBookResource,
|
|
3072
|
+
L4OrderBookReconstructor,
|
|
2884
3073
|
LighterClient,
|
|
2885
3074
|
LiquidationArrayResponseSchema,
|
|
2886
3075
|
LiquidationSchema,
|