@xapy/orderbook 0.1.22 → 0.1.23
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 +14 -9
- package/dist/exchanges/binance/index.cjs +21 -6
- package/dist/exchanges/binance/index.cjs.map +1 -1
- package/dist/exchanges/binance/index.d.cts +1 -1
- package/dist/exchanges/binance/index.d.ts +1 -1
- package/dist/exchanges/binance/index.js +21 -6
- package/dist/exchanges/binance/index.js.map +1 -1
- package/dist/exchanges/bingx/index.cjs +38 -11
- package/dist/exchanges/bingx/index.cjs.map +1 -1
- package/dist/exchanges/bingx/index.d.cts +1 -1
- package/dist/exchanges/bingx/index.d.ts +1 -1
- package/dist/exchanges/bingx/index.js +38 -11
- package/dist/exchanges/bingx/index.js.map +1 -1
- package/dist/exchanges/bitget/index.cjs +21 -6
- package/dist/exchanges/bitget/index.cjs.map +1 -1
- package/dist/exchanges/bitget/index.d.cts +1 -1
- package/dist/exchanges/bitget/index.d.ts +1 -1
- package/dist/exchanges/bitget/index.js +21 -6
- package/dist/exchanges/bitget/index.js.map +1 -1
- package/dist/exchanges/bybit/index.cjs +21 -6
- package/dist/exchanges/bybit/index.cjs.map +1 -1
- package/dist/exchanges/bybit/index.d.cts +1 -1
- package/dist/exchanges/bybit/index.d.ts +1 -1
- package/dist/exchanges/bybit/index.js +21 -6
- package/dist/exchanges/bybit/index.js.map +1 -1
- package/dist/exchanges/coinex/index.cjs +21 -6
- package/dist/exchanges/coinex/index.cjs.map +1 -1
- package/dist/exchanges/coinex/index.d.cts +1 -1
- package/dist/exchanges/coinex/index.d.ts +1 -1
- package/dist/exchanges/coinex/index.js +21 -6
- package/dist/exchanges/coinex/index.js.map +1 -1
- package/dist/exchanges/{bitmart → deribit}/index.cjs +174 -148
- package/dist/exchanges/deribit/index.cjs.map +1 -0
- package/dist/exchanges/deribit/index.d.cts +48 -0
- package/dist/exchanges/deribit/index.d.ts +48 -0
- package/dist/exchanges/{bitmart → deribit}/index.js +172 -146
- package/dist/exchanges/deribit/index.js.map +1 -0
- package/dist/exchanges/gate/index.cjs +21 -6
- package/dist/exchanges/gate/index.cjs.map +1 -1
- package/dist/exchanges/gate/index.d.cts +1 -1
- package/dist/exchanges/gate/index.d.ts +1 -1
- package/dist/exchanges/gate/index.js +21 -6
- package/dist/exchanges/gate/index.js.map +1 -1
- package/dist/exchanges/huobi/index.cjs +21 -6
- package/dist/exchanges/huobi/index.cjs.map +1 -1
- package/dist/exchanges/huobi/index.d.cts +1 -1
- package/dist/exchanges/huobi/index.d.ts +1 -1
- package/dist/exchanges/huobi/index.js +21 -6
- package/dist/exchanges/huobi/index.js.map +1 -1
- package/dist/exchanges/hyperliquid/index.cjs +21 -6
- package/dist/exchanges/hyperliquid/index.cjs.map +1 -1
- package/dist/exchanges/hyperliquid/index.d.cts +1 -1
- package/dist/exchanges/hyperliquid/index.d.ts +1 -1
- package/dist/exchanges/hyperliquid/index.js +21 -6
- package/dist/exchanges/hyperliquid/index.js.map +1 -1
- package/dist/exchanges/kucoin/index.cjs +21 -6
- package/dist/exchanges/kucoin/index.cjs.map +1 -1
- package/dist/exchanges/kucoin/index.d.cts +1 -1
- package/dist/exchanges/kucoin/index.d.ts +1 -1
- package/dist/exchanges/kucoin/index.js +21 -6
- package/dist/exchanges/kucoin/index.js.map +1 -1
- package/dist/exchanges/okx/index.cjs +21 -6
- package/dist/exchanges/okx/index.cjs.map +1 -1
- package/dist/exchanges/okx/index.d.cts +1 -1
- package/dist/exchanges/okx/index.d.ts +1 -1
- package/dist/exchanges/okx/index.js +21 -6
- package/dist/exchanges/okx/index.js.map +1 -1
- package/dist/index.cjs +189 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +189 -122
- package/dist/index.js.map +1 -1
- package/dist/{stream-L9MJjYbE.d.cts → stream-CO3LD9jf.d.cts} +1 -1
- package/dist/{stream-L9MJjYbE.d.ts → stream-CO3LD9jf.d.ts} +1 -1
- package/package.json +7 -6
- package/dist/exchanges/bitmart/index.cjs.map +0 -1
- package/dist/exchanges/bitmart/index.d.cts +0 -68
- package/dist/exchanges/bitmart/index.d.ts +0 -68
- package/dist/exchanges/bitmart/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -325,6 +325,21 @@ async function fetchBybitOrderbook(opts) {
|
|
|
325
325
|
var hasNativeWebSocket = typeof globalThis.WebSocket !== "undefined";
|
|
326
326
|
|
|
327
327
|
// src/transport/ws.ts
|
|
328
|
+
function toError(value, fallback = "unknown error") {
|
|
329
|
+
if (value instanceof Error) {
|
|
330
|
+
return value.message ? value : new Error(`${value.name}: ${fallback}`);
|
|
331
|
+
}
|
|
332
|
+
if (typeof value === "string" && value) return new Error(value);
|
|
333
|
+
return new Error(fallback);
|
|
334
|
+
}
|
|
335
|
+
function normalizeWsError(ev) {
|
|
336
|
+
const detail = ev?.message || (ev?.error instanceof Error ? ev.error.message : void 0) || (typeof ev?.error === "string" ? ev.error : void 0);
|
|
337
|
+
return new Error(detail ? `WebSocket error: ${detail}` : "WebSocket error");
|
|
338
|
+
}
|
|
339
|
+
function describeClose(ev) {
|
|
340
|
+
if (ev?.reason) return ev.reason;
|
|
341
|
+
return ev?.code === void 0 ? "closed" : `closed (code ${ev.code})`;
|
|
342
|
+
}
|
|
328
343
|
var cachedCtor = null;
|
|
329
344
|
async function getWebSocketCtor() {
|
|
330
345
|
if (cachedCtor) return cachedCtor;
|
|
@@ -372,7 +387,7 @@ var WSClient = class extends TypedEmitter {
|
|
|
372
387
|
close: () => this.close()
|
|
373
388
|
});
|
|
374
389
|
} catch (err) {
|
|
375
|
-
this.emit("error", err);
|
|
390
|
+
this.emit("error", toError(err, "onOpen handler failed"));
|
|
376
391
|
}
|
|
377
392
|
};
|
|
378
393
|
ws.onmessage = (e) => {
|
|
@@ -380,21 +395,21 @@ var WSClient = class extends TypedEmitter {
|
|
|
380
395
|
try {
|
|
381
396
|
result = this.cfg.onMessage(e.data);
|
|
382
397
|
} catch (err) {
|
|
383
|
-
this.emit("error", err);
|
|
398
|
+
this.emit("error", toError(err, "onMessage handler failed"));
|
|
384
399
|
return;
|
|
385
400
|
}
|
|
386
401
|
if (result && typeof result.catch === "function") {
|
|
387
402
|
result.catch(
|
|
388
|
-
(err) => this.emit("error", err)
|
|
403
|
+
(err) => this.emit("error", toError(err, "onMessage handler failed"))
|
|
389
404
|
);
|
|
390
405
|
}
|
|
391
406
|
};
|
|
392
407
|
ws.onerror = (e) => {
|
|
393
|
-
this.emit("error",
|
|
408
|
+
this.emit("error", normalizeWsError(e));
|
|
394
409
|
};
|
|
395
410
|
ws.onclose = (e) => {
|
|
396
411
|
this.stopPing();
|
|
397
|
-
const reason = e
|
|
412
|
+
const reason = describeClose(e);
|
|
398
413
|
this.emit("close", reason);
|
|
399
414
|
if (!this.closed) this.scheduleReconnect();
|
|
400
415
|
};
|
|
@@ -434,7 +449,7 @@ var WSClient = class extends TypedEmitter {
|
|
|
434
449
|
}
|
|
435
450
|
this.emit("reconnecting", next.attempt, next.wait);
|
|
436
451
|
setTimeout(() => {
|
|
437
|
-
this.connect().catch((e) => this.emit("error", e));
|
|
452
|
+
this.connect().catch((e) => this.emit("error", toError(e, "reconnect failed")));
|
|
438
453
|
}, next.wait);
|
|
439
454
|
}
|
|
440
455
|
};
|
|
@@ -1234,7 +1249,7 @@ function streamBingxOrderbook(opts) {
|
|
|
1234
1249
|
const wsSymbol = opts.symbol.toUpperCase().replace("/", "-");
|
|
1235
1250
|
const level = opts.depth ?? 20;
|
|
1236
1251
|
const interval = opts.interval ?? "500ms";
|
|
1237
|
-
const depthDataType = `${wsSymbol}@depth${level}@${interval}`;
|
|
1252
|
+
const depthDataType = isSpot ? `${wsSymbol}@depth${level}` : `${wsSymbol}@depth${level}@${interval}`;
|
|
1238
1253
|
const tickerDataType = `${wsSymbol}@bookTicker`;
|
|
1239
1254
|
const merger = new BookMerger();
|
|
1240
1255
|
let ws = null;
|
|
@@ -1277,8 +1292,8 @@ function streamBingxOrderbook(opts) {
|
|
|
1277
1292
|
};
|
|
1278
1293
|
stream.emit("update", book);
|
|
1279
1294
|
};
|
|
1280
|
-
const handleDepth = (d) => {
|
|
1281
|
-
const ts = d.T ?? d.ts ?? Date.now();
|
|
1295
|
+
const handleDepth = (d, frameTs) => {
|
|
1296
|
+
const ts = d.T ?? d.ts ?? frameTs ?? Date.now();
|
|
1282
1297
|
const event = {
|
|
1283
1298
|
kind: "snapshot",
|
|
1284
1299
|
bids: d.bids.map(([p, s]) => ({ price: Number(p), size: Number(s) })),
|
|
@@ -1320,10 +1335,22 @@ function streamBingxOrderbook(opts) {
|
|
|
1320
1335
|
} catch {
|
|
1321
1336
|
return;
|
|
1322
1337
|
}
|
|
1323
|
-
if (msg.id && !msg.data)
|
|
1338
|
+
if (msg.id && !msg.data) {
|
|
1339
|
+
if (msg.code) {
|
|
1340
|
+
stream.emit(
|
|
1341
|
+
"error",
|
|
1342
|
+
new ExchangeError(
|
|
1343
|
+
"bingx",
|
|
1344
|
+
`subscribe failed (${msg.id}): ${msg.code}${msg.msg ? ` ${msg.msg}` : ""}`
|
|
1345
|
+
)
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1324
1350
|
if (!msg.dataType || !msg.data) return;
|
|
1351
|
+
const frameTs = msg.ts ?? msg.timestamp;
|
|
1325
1352
|
if (msg.dataType === depthDataType) {
|
|
1326
|
-
handleDepth(msg.data);
|
|
1353
|
+
handleDepth(msg.data, frameTs);
|
|
1327
1354
|
} else if (msg.dataType === tickerDataType) {
|
|
1328
1355
|
handleTicker(msg.data);
|
|
1329
1356
|
}
|
|
@@ -2622,98 +2649,88 @@ var KucoinClient = class {
|
|
|
2622
2649
|
}
|
|
2623
2650
|
};
|
|
2624
2651
|
|
|
2625
|
-
// src/exchanges/
|
|
2626
|
-
|
|
2627
|
-
function toBitmartSymbol(symbol) {
|
|
2652
|
+
// src/exchanges/deribit/symbols.ts
|
|
2653
|
+
function toDeribitSymbol(symbol, market) {
|
|
2628
2654
|
const [base, quote] = symbol.split("/");
|
|
2629
2655
|
if (!base || !quote) {
|
|
2630
2656
|
throw new Error(`invalid symbol "${symbol}" \u2014 expected "BASE/QUOTE"`);
|
|
2631
2657
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
return `${upper.slice(0, -q.length)}/${q}`;
|
|
2639
|
-
}
|
|
2658
|
+
const pair = `${base}_${quote}`.toUpperCase();
|
|
2659
|
+
if (market !== "perpetual") return pair;
|
|
2660
|
+
if (quote.toUpperCase() !== "USDC") {
|
|
2661
|
+
throw new Error(
|
|
2662
|
+
`deribit linear perpetuals are USDC-margined; got "${quote}" (inverse contracts like BTC-PERPETUAL are unsupported)`
|
|
2663
|
+
);
|
|
2640
2664
|
}
|
|
2641
|
-
return
|
|
2665
|
+
return `${pair}-PERPETUAL`;
|
|
2666
|
+
}
|
|
2667
|
+
function fromDeribitSymbol(instrument) {
|
|
2668
|
+
let s = instrument.toUpperCase();
|
|
2669
|
+
if (s.endsWith("-PERPETUAL")) s = s.slice(0, -"-PERPETUAL".length);
|
|
2670
|
+
const [base, quote] = s.split("_");
|
|
2671
|
+
return base && quote ? `${base}/${quote}` : s;
|
|
2642
2672
|
}
|
|
2643
2673
|
|
|
2644
|
-
// src/exchanges/
|
|
2645
|
-
var BASE8 = "https://
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
const
|
|
2654
|
-
const url = `${BASE8}/contract/public/depth?symbol=${symbol}`;
|
|
2674
|
+
// src/exchanges/deribit/rest.ts
|
|
2675
|
+
var BASE8 = "https://www.deribit.com";
|
|
2676
|
+
var ALLOWED_DEPTHS = [1, 5, 10, 20, 50, 100, 1e3, 1e4];
|
|
2677
|
+
function clampDepth(depth) {
|
|
2678
|
+
return ALLOWED_DEPTHS.find((d) => d >= depth) ?? ALLOWED_DEPTHS[ALLOWED_DEPTHS.length - 1];
|
|
2679
|
+
}
|
|
2680
|
+
async function fetchDeribitOrderbook(opts) {
|
|
2681
|
+
const instrument = toDeribitSymbol(opts.symbol, opts.market);
|
|
2682
|
+
const depth = clampDepth(opts.depth ?? 50);
|
|
2683
|
+
const url = `${BASE8}/api/v2/public/get_order_book?instrument_name=${instrument}&depth=${depth}`;
|
|
2655
2684
|
const res = await httpJson({
|
|
2656
2685
|
url,
|
|
2657
2686
|
timeoutMs: opts.timeoutMs,
|
|
2658
2687
|
transformUrl: opts.transformUrl
|
|
2659
2688
|
});
|
|
2660
|
-
if (res.
|
|
2661
|
-
throw new ExchangeError(
|
|
2689
|
+
if (res.error) {
|
|
2690
|
+
throw new ExchangeError(
|
|
2691
|
+
"deribit",
|
|
2692
|
+
`${res.error.code}: ${res.error.message}`
|
|
2693
|
+
);
|
|
2662
2694
|
}
|
|
2695
|
+
const r = res.result;
|
|
2696
|
+
if (!r) throw new ExchangeError("deribit", "empty orderbook response");
|
|
2663
2697
|
return {
|
|
2664
|
-
exchange: "
|
|
2665
|
-
symbol:
|
|
2666
|
-
market:
|
|
2667
|
-
bids:
|
|
2668
|
-
asks:
|
|
2669
|
-
timestamp:
|
|
2670
|
-
sequence:
|
|
2698
|
+
exchange: "deribit",
|
|
2699
|
+
symbol: fromDeribitSymbol(r.instrument_name ?? instrument),
|
|
2700
|
+
market: opts.market,
|
|
2701
|
+
bids: r.bids.map(([price, size]) => ({ price, size })),
|
|
2702
|
+
asks: r.asks.map(([price, size]) => ({ price, size })),
|
|
2703
|
+
timestamp: r.timestamp,
|
|
2704
|
+
sequence: r.change_id
|
|
2671
2705
|
};
|
|
2672
2706
|
}
|
|
2673
|
-
function parseLevels2(rows) {
|
|
2674
|
-
const out = [];
|
|
2675
|
-
for (const row of rows) {
|
|
2676
|
-
out.push({ price: Number(row[0]), size: Number(row[1]) });
|
|
2677
|
-
}
|
|
2678
|
-
return out;
|
|
2679
|
-
}
|
|
2680
2707
|
|
|
2681
|
-
// src/exchanges/
|
|
2682
|
-
var
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
"spot is not supported \u2014 only USDT-M perpetual"
|
|
2688
|
-
);
|
|
2689
|
-
}
|
|
2690
|
-
const symbol = toBitmartSymbol(opts.symbol);
|
|
2691
|
-
const level = snapLevel(opts.depth);
|
|
2692
|
-
const interval = opts.interval ?? "200ms";
|
|
2693
|
-
const channelArg = `futures/depthAll${level}:${symbol}@${interval}`;
|
|
2708
|
+
// src/exchanges/deribit/ws.ts
|
|
2709
|
+
var WS_PUBLIC3 = "wss://www.deribit.com/ws/api/v2";
|
|
2710
|
+
var HEARTBEAT_SECONDS = 30;
|
|
2711
|
+
function streamDeribitOrderbook(opts) {
|
|
2712
|
+
const instrument = toDeribitSymbol(opts.symbol, opts.market);
|
|
2713
|
+
const channel = `book.${instrument}.${opts.interval ?? "100ms"}`;
|
|
2694
2714
|
const merger = new BookMerger();
|
|
2695
2715
|
let ws = null;
|
|
2716
|
+
let sock = null;
|
|
2717
|
+
let recovering = false;
|
|
2696
2718
|
const stream = new OrderbookStream(() => ws?.close());
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
sequence: frame.ms_t,
|
|
2709
|
-
timestamp: frame.ms_t
|
|
2710
|
-
};
|
|
2711
|
-
const r = merger.apply(event);
|
|
2712
|
-
if (!r.ok) return;
|
|
2719
|
+
let nextId = 1;
|
|
2720
|
+
const subscribeIds = /* @__PURE__ */ new Set();
|
|
2721
|
+
const rpc = (method, params) => {
|
|
2722
|
+
const id = nextId++;
|
|
2723
|
+
sock?.send(JSON.stringify({ jsonrpc: "2.0", id, method, params }));
|
|
2724
|
+
return id;
|
|
2725
|
+
};
|
|
2726
|
+
const subscribe = () => {
|
|
2727
|
+
subscribeIds.add(rpc("public/subscribe", { channels: [channel] }));
|
|
2728
|
+
};
|
|
2729
|
+
const emit = (r) => {
|
|
2713
2730
|
const book = {
|
|
2714
|
-
exchange: "
|
|
2715
|
-
symbol:
|
|
2716
|
-
market:
|
|
2731
|
+
exchange: "deribit",
|
|
2732
|
+
symbol: fromDeribitSymbol(instrument),
|
|
2733
|
+
market: opts.market,
|
|
2717
2734
|
bids: r.bids,
|
|
2718
2735
|
asks: r.asks,
|
|
2719
2736
|
timestamp: r.timestamp,
|
|
@@ -2721,41 +2738,101 @@ function streamBitmartOrderbook(opts) {
|
|
|
2721
2738
|
};
|
|
2722
2739
|
stream.emit("update", book);
|
|
2723
2740
|
};
|
|
2724
|
-
const
|
|
2741
|
+
const resync = () => {
|
|
2742
|
+
if (recovering) return;
|
|
2743
|
+
recovering = true;
|
|
2744
|
+
merger.reset();
|
|
2745
|
+
rpc("public/unsubscribe", { channels: [channel] });
|
|
2746
|
+
subscribe();
|
|
2747
|
+
};
|
|
2748
|
+
const toLevels = (entries) => entries.map(([action, price, amount]) => ({
|
|
2749
|
+
price,
|
|
2750
|
+
size: action === "delete" ? 0 : amount
|
|
2751
|
+
}));
|
|
2752
|
+
const buildEvent2 = (d) => {
|
|
2753
|
+
const bids = toLevels(d.bids);
|
|
2754
|
+
const asks = toLevels(d.asks);
|
|
2755
|
+
if (d.type === "snapshot") {
|
|
2756
|
+
return {
|
|
2757
|
+
kind: "snapshot",
|
|
2758
|
+
bids,
|
|
2759
|
+
asks,
|
|
2760
|
+
sequence: d.change_id,
|
|
2761
|
+
timestamp: d.timestamp
|
|
2762
|
+
};
|
|
2763
|
+
}
|
|
2764
|
+
return {
|
|
2765
|
+
kind: "delta",
|
|
2766
|
+
bids,
|
|
2767
|
+
asks,
|
|
2768
|
+
sequence: d.change_id,
|
|
2769
|
+
prevSequence: d.prev_change_id,
|
|
2770
|
+
timestamp: d.timestamp
|
|
2771
|
+
};
|
|
2772
|
+
};
|
|
2773
|
+
const handleData = (d) => {
|
|
2774
|
+
if (d.type === "snapshot") recovering = false;
|
|
2775
|
+
else if (recovering) return;
|
|
2776
|
+
const r = merger.apply(buildEvent2(d));
|
|
2777
|
+
if (r.ok) {
|
|
2778
|
+
emit(r);
|
|
2779
|
+
} else if (r.reason === "gap" || r.reason === "no-snapshot") {
|
|
2780
|
+
resync();
|
|
2781
|
+
}
|
|
2782
|
+
};
|
|
2783
|
+
const onMessage = (raw) => {
|
|
2784
|
+
if (typeof raw !== "string") return;
|
|
2725
2785
|
let msg;
|
|
2726
2786
|
try {
|
|
2727
|
-
msg = JSON.parse(
|
|
2787
|
+
msg = JSON.parse(raw);
|
|
2728
2788
|
} catch {
|
|
2729
2789
|
return;
|
|
2730
2790
|
}
|
|
2731
|
-
if (msg.
|
|
2732
|
-
|
|
2733
|
-
stream.emit(
|
|
2734
|
-
"error",
|
|
2735
|
-
new Error(`bitmart: ${msg.errorCode} ${msg.errorMessage ?? ""}`)
|
|
2736
|
-
);
|
|
2791
|
+
if (msg.method === "heartbeat") {
|
|
2792
|
+
if (msg.params?.type === "test_request") rpc("public/test", {});
|
|
2737
2793
|
return;
|
|
2738
2794
|
}
|
|
2739
|
-
if (msg.
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
const onMessage = async (raw) => {
|
|
2743
|
-
if (typeof raw === "string") {
|
|
2744
|
-
handlePayload(raw);
|
|
2795
|
+
if (msg.method === "subscription") {
|
|
2796
|
+
if (msg.params?.channel !== channel || !msg.params.data) return;
|
|
2797
|
+
handleData(msg.params.data);
|
|
2745
2798
|
return;
|
|
2746
2799
|
}
|
|
2747
|
-
|
|
2748
|
-
|
|
2800
|
+
if (msg.id !== void 0) {
|
|
2801
|
+
if (msg.error) {
|
|
2802
|
+
stream.emit(
|
|
2803
|
+
"error",
|
|
2804
|
+
new ExchangeError(
|
|
2805
|
+
"deribit",
|
|
2806
|
+
`${msg.error.code}: ${msg.error.message}`
|
|
2807
|
+
)
|
|
2808
|
+
);
|
|
2809
|
+
return;
|
|
2810
|
+
}
|
|
2811
|
+
if (subscribeIds.delete(msg.id)) {
|
|
2812
|
+
const channels = Array.isArray(msg.result) ? msg.result : [];
|
|
2813
|
+
if (!channels.includes(channel)) {
|
|
2814
|
+
stream.emit(
|
|
2815
|
+
"error",
|
|
2816
|
+
new ExchangeError(
|
|
2817
|
+
"deribit",
|
|
2818
|
+
`subscribe rejected for "${channel}" \u2014 unknown instrument or interval`
|
|
2819
|
+
)
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2749
2824
|
};
|
|
2750
2825
|
ws = new WSClient({
|
|
2751
|
-
url:
|
|
2752
|
-
onOpen: (
|
|
2826
|
+
url: WS_PUBLIC3,
|
|
2827
|
+
onOpen: (handle) => {
|
|
2828
|
+
sock = handle;
|
|
2753
2829
|
merger.reset();
|
|
2754
|
-
|
|
2830
|
+
recovering = false;
|
|
2831
|
+
subscribeIds.clear();
|
|
2832
|
+
rpc("public/set_heartbeat", { interval: HEARTBEAT_SECONDS });
|
|
2833
|
+
subscribe();
|
|
2755
2834
|
},
|
|
2756
|
-
onMessage
|
|
2757
|
-
pingIntervalMs: 15e3,
|
|
2758
|
-
pingPayload
|
|
2835
|
+
onMessage
|
|
2759
2836
|
});
|
|
2760
2837
|
ws.on("open", () => stream.emit("connected"));
|
|
2761
2838
|
ws.on("close", (r) => stream.emit("disconnected", r));
|
|
@@ -2764,21 +2841,10 @@ function streamBitmartOrderbook(opts) {
|
|
|
2764
2841
|
ws.connect().catch((e) => stream.emit("error", e));
|
|
2765
2842
|
return stream;
|
|
2766
2843
|
}
|
|
2767
|
-
function snapLevel(depth) {
|
|
2768
|
-
if (depth === 5) return 5;
|
|
2769
|
-
if (depth === 20) return 20;
|
|
2770
|
-
return 50;
|
|
2771
|
-
}
|
|
2772
|
-
function parseLevels3(rows) {
|
|
2773
|
-
if (!rows) return [];
|
|
2774
|
-
const out = [];
|
|
2775
|
-
for (const r of rows) out.push({ price: Number(r.price), size: Number(r.vol) });
|
|
2776
|
-
return out;
|
|
2777
|
-
}
|
|
2778
2844
|
|
|
2779
|
-
// src/exchanges/
|
|
2780
|
-
var
|
|
2781
|
-
exchange = "
|
|
2845
|
+
// src/exchanges/deribit/index.ts
|
|
2846
|
+
var DeribitClient = class {
|
|
2847
|
+
exchange = "deribit";
|
|
2782
2848
|
transformUrl;
|
|
2783
2849
|
timeoutMs;
|
|
2784
2850
|
constructor(opts = {}) {
|
|
@@ -2787,7 +2853,7 @@ var BitmartClient = class {
|
|
|
2787
2853
|
}
|
|
2788
2854
|
fetchOrderbook(symbol, opts = {}) {
|
|
2789
2855
|
const { pair, market } = parseSymbol(symbol);
|
|
2790
|
-
return
|
|
2856
|
+
return fetchDeribitOrderbook({
|
|
2791
2857
|
symbol: pair,
|
|
2792
2858
|
market,
|
|
2793
2859
|
depth: opts.depth,
|
|
@@ -2795,11 +2861,12 @@ var BitmartClient = class {
|
|
|
2795
2861
|
transformUrl: this.transformUrl
|
|
2796
2862
|
});
|
|
2797
2863
|
}
|
|
2798
|
-
streamOrderbook(symbol,
|
|
2864
|
+
streamOrderbook(symbol, opts = {}) {
|
|
2799
2865
|
const { pair, market } = parseSymbol(symbol);
|
|
2800
|
-
return
|
|
2866
|
+
return streamDeribitOrderbook({
|
|
2801
2867
|
symbol: pair,
|
|
2802
2868
|
market,
|
|
2869
|
+
depth: opts.depth,
|
|
2803
2870
|
transformUrl: this.transformUrl,
|
|
2804
2871
|
timeoutMs: this.timeoutMs
|
|
2805
2872
|
});
|
|
@@ -2810,10 +2877,10 @@ exports.Backoff = Backoff;
|
|
|
2810
2877
|
exports.BinanceClient = BinanceClient;
|
|
2811
2878
|
exports.BingxClient = BingxClient;
|
|
2812
2879
|
exports.BitgetClient = BitgetClient;
|
|
2813
|
-
exports.BitmartClient = BitmartClient;
|
|
2814
2880
|
exports.BookMerger = BookMerger;
|
|
2815
2881
|
exports.BybitClient = BybitClient;
|
|
2816
2882
|
exports.CoinexClient = CoinexClient;
|
|
2883
|
+
exports.DeribitClient = DeribitClient;
|
|
2817
2884
|
exports.ExchangeError = ExchangeError;
|
|
2818
2885
|
exports.GateClient = GateClient;
|
|
2819
2886
|
exports.HuobiClient = HuobiClient;
|