@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/README.md +39 -3
- package/dist/index.d.mts +215 -1
- package/dist/index.d.ts +215 -1
- package/dist/index.js +196 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,
|