@xapy/orderbook 0.1.23 → 0.1.24
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 +1 -0
- package/dist/exchanges/binance/index.d.cts +1 -1
- package/dist/exchanges/binance/index.d.ts +1 -1
- package/dist/exchanges/bingx/index.d.cts +1 -1
- package/dist/exchanges/bingx/index.d.ts +1 -1
- package/dist/exchanges/bitget/index.d.cts +1 -1
- package/dist/exchanges/bitget/index.d.ts +1 -1
- package/dist/exchanges/bybit/index.d.cts +1 -1
- package/dist/exchanges/bybit/index.d.ts +1 -1
- package/dist/exchanges/coinex/index.d.cts +1 -1
- package/dist/exchanges/coinex/index.d.ts +1 -1
- package/dist/exchanges/deribit/index.d.cts +1 -1
- package/dist/exchanges/deribit/index.d.ts +1 -1
- package/dist/exchanges/gate/index.d.cts +1 -1
- package/dist/exchanges/gate/index.d.ts +1 -1
- package/dist/exchanges/grvt/index.cjs +627 -0
- package/dist/exchanges/grvt/index.cjs.map +1 -0
- package/dist/exchanges/grvt/index.d.cts +47 -0
- package/dist/exchanges/grvt/index.d.ts +47 -0
- package/dist/exchanges/grvt/index.js +623 -0
- package/dist/exchanges/grvt/index.js.map +1 -0
- package/dist/exchanges/huobi/index.d.cts +1 -1
- package/dist/exchanges/huobi/index.d.ts +1 -1
- package/dist/exchanges/hyperliquid/index.d.cts +1 -1
- package/dist/exchanges/hyperliquid/index.d.ts +1 -1
- package/dist/exchanges/kucoin/index.d.cts +1 -1
- package/dist/exchanges/kucoin/index.d.ts +1 -1
- package/dist/exchanges/okx/index.d.cts +1 -1
- package/dist/exchanges/okx/index.d.ts +1 -1
- package/dist/index.cjs +230 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +230 -4
- package/dist/index.js.map +1 -1
- package/dist/{stream-CO3LD9jf.d.cts → stream-Con47OAp.d.cts} +1 -1
- package/dist/{stream-CO3LD9jf.d.ts → stream-Con47OAp.d.ts} +1 -1
- package/package.json +12 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-
|
|
2
|
-
export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-
|
|
1
|
+
import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-Con47OAp.cjs';
|
|
2
|
+
export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-Con47OAp.cjs';
|
|
3
3
|
export { BybitClient } from './exchanges/bybit/index.cjs';
|
|
4
4
|
export { BitgetClient } from './exchanges/bitget/index.cjs';
|
|
5
5
|
export { GateClient } from './exchanges/gate/index.cjs';
|
|
@@ -11,6 +11,7 @@ export { BinanceClient } from './exchanges/binance/index.cjs';
|
|
|
11
11
|
export { HyperliquidClient } from './exchanges/hyperliquid/index.cjs';
|
|
12
12
|
export { KucoinClient } from './exchanges/kucoin/index.cjs';
|
|
13
13
|
export { DeribitClient } from './exchanges/deribit/index.cjs';
|
|
14
|
+
export { GrvtClient } from './exchanges/grvt/index.cjs';
|
|
14
15
|
|
|
15
16
|
declare class ExchangeError extends Error {
|
|
16
17
|
readonly exchange: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-
|
|
2
|
-
export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-
|
|
1
|
+
import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-Con47OAp.js';
|
|
2
|
+
export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-Con47OAp.js';
|
|
3
3
|
export { BybitClient } from './exchanges/bybit/index.js';
|
|
4
4
|
export { BitgetClient } from './exchanges/bitget/index.js';
|
|
5
5
|
export { GateClient } from './exchanges/gate/index.js';
|
|
@@ -11,6 +11,7 @@ export { BinanceClient } from './exchanges/binance/index.js';
|
|
|
11
11
|
export { HyperliquidClient } from './exchanges/hyperliquid/index.js';
|
|
12
12
|
export { KucoinClient } from './exchanges/kucoin/index.js';
|
|
13
13
|
export { DeribitClient } from './exchanges/deribit/index.js';
|
|
14
|
+
export { GrvtClient } from './exchanges/grvt/index.js';
|
|
14
15
|
|
|
15
16
|
declare class ExchangeError extends Error {
|
|
16
17
|
readonly exchange: string;
|
package/dist/index.js
CHANGED
|
@@ -2743,13 +2743,13 @@ function streamDeribitOrderbook(opts) {
|
|
|
2743
2743
|
rpc("public/unsubscribe", { channels: [channel] });
|
|
2744
2744
|
subscribe();
|
|
2745
2745
|
};
|
|
2746
|
-
const
|
|
2746
|
+
const toLevels2 = (entries) => entries.map(([action, price, amount]) => ({
|
|
2747
2747
|
price,
|
|
2748
2748
|
size: action === "delete" ? 0 : amount
|
|
2749
2749
|
}));
|
|
2750
2750
|
const buildEvent2 = (d) => {
|
|
2751
|
-
const bids =
|
|
2752
|
-
const asks =
|
|
2751
|
+
const bids = toLevels2(d.bids);
|
|
2752
|
+
const asks = toLevels2(d.asks);
|
|
2753
2753
|
if (d.type === "snapshot") {
|
|
2754
2754
|
return {
|
|
2755
2755
|
kind: "snapshot",
|
|
@@ -2871,6 +2871,232 @@ var DeribitClient = class {
|
|
|
2871
2871
|
}
|
|
2872
2872
|
};
|
|
2873
2873
|
|
|
2874
|
-
|
|
2874
|
+
// src/exchanges/grvt/symbols.ts
|
|
2875
|
+
function toGrvtSymbol(symbol, market) {
|
|
2876
|
+
const [base, quote] = symbol.split("/");
|
|
2877
|
+
if (!base || !quote) {
|
|
2878
|
+
throw new Error(`invalid symbol "${symbol}" \u2014 expected "BASE/QUOTE"`);
|
|
2879
|
+
}
|
|
2880
|
+
if (market !== "perpetual") {
|
|
2881
|
+
throw new Error(
|
|
2882
|
+
`grvt only lists perpetuals; use "${base.toUpperCase()}/${quote.toUpperCase()}:${quote.toUpperCase()}"`
|
|
2883
|
+
);
|
|
2884
|
+
}
|
|
2885
|
+
return `${base.toUpperCase()}_${quote.toUpperCase()}_Perp`;
|
|
2886
|
+
}
|
|
2887
|
+
function fromGrvtSymbol(instrument) {
|
|
2888
|
+
const parts = instrument.split("_");
|
|
2889
|
+
const [base, quote] = parts;
|
|
2890
|
+
return base && quote ? `${base.toUpperCase()}/${quote.toUpperCase()}` : instrument;
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
// src/exchanges/grvt/rest.ts
|
|
2894
|
+
var BASE9 = "https://market-data.grvt.io";
|
|
2895
|
+
var ALLOWED_DEPTHS2 = [10, 50, 100, 500];
|
|
2896
|
+
function snapDepth(depth) {
|
|
2897
|
+
return ALLOWED_DEPTHS2.find((d) => d >= depth) ?? ALLOWED_DEPTHS2[ALLOWED_DEPTHS2.length - 1];
|
|
2898
|
+
}
|
|
2899
|
+
function nsToMs(ns) {
|
|
2900
|
+
const n = Number(ns);
|
|
2901
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n / 1e6) : Date.now();
|
|
2902
|
+
}
|
|
2903
|
+
var toLevels = (rows) => (rows ?? []).map((l) => ({ price: Number(l.price), size: Number(l.size) }));
|
|
2904
|
+
async function fetchGrvtOrderbook(opts) {
|
|
2905
|
+
const instrument = toGrvtSymbol(opts.symbol, opts.market);
|
|
2906
|
+
const depth = snapDepth(opts.depth ?? 50);
|
|
2907
|
+
const res = await httpJson({
|
|
2908
|
+
url: `${BASE9}/full/v1/book`,
|
|
2909
|
+
method: "POST",
|
|
2910
|
+
headers: { "Content-Type": "application/json" },
|
|
2911
|
+
body: JSON.stringify({ instrument, depth }),
|
|
2912
|
+
timeoutMs: opts.timeoutMs,
|
|
2913
|
+
transformUrl: opts.transformUrl
|
|
2914
|
+
});
|
|
2915
|
+
if (!res.result) {
|
|
2916
|
+
throw new ExchangeError(
|
|
2917
|
+
"grvt",
|
|
2918
|
+
res.code ? `${res.code}: ${res.message}` : "empty orderbook response"
|
|
2919
|
+
);
|
|
2920
|
+
}
|
|
2921
|
+
const ts = nsToMs(res.result.event_time);
|
|
2922
|
+
return {
|
|
2923
|
+
exchange: "grvt",
|
|
2924
|
+
symbol: fromGrvtSymbol(res.result.instrument ?? instrument),
|
|
2925
|
+
market: opts.market,
|
|
2926
|
+
bids: toLevels(res.result.bids),
|
|
2927
|
+
asks: toLevels(res.result.asks),
|
|
2928
|
+
timestamp: ts,
|
|
2929
|
+
sequence: ts
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
// src/exchanges/grvt/ws.ts
|
|
2934
|
+
var WS_FULL = "wss://market-data.grvt.io/ws/full";
|
|
2935
|
+
var STREAM = "v1.book.d";
|
|
2936
|
+
function streamGrvtOrderbook(opts) {
|
|
2937
|
+
const instrument = toGrvtSymbol(opts.symbol, opts.market);
|
|
2938
|
+
const selector = `${instrument}@${opts.rate ?? 500}`;
|
|
2939
|
+
const merger = new BookMerger();
|
|
2940
|
+
let ws = null;
|
|
2941
|
+
let sock = null;
|
|
2942
|
+
let recovering = false;
|
|
2943
|
+
let awaitingFirstDelta = false;
|
|
2944
|
+
let snapshotSequence = 0;
|
|
2945
|
+
let ackSequence = null;
|
|
2946
|
+
const stream = new OrderbookStream(() => ws?.close());
|
|
2947
|
+
let nextId = 1;
|
|
2948
|
+
const subscribeIds = /* @__PURE__ */ new Set();
|
|
2949
|
+
const rpc = (method) => {
|
|
2950
|
+
const id = nextId++;
|
|
2951
|
+
sock?.send(
|
|
2952
|
+
JSON.stringify({
|
|
2953
|
+
jsonrpc: "2.0",
|
|
2954
|
+
method,
|
|
2955
|
+
params: { stream: STREAM, selectors: [selector] },
|
|
2956
|
+
id
|
|
2957
|
+
})
|
|
2958
|
+
);
|
|
2959
|
+
return id;
|
|
2960
|
+
};
|
|
2961
|
+
const subscribe = () => subscribeIds.add(rpc("subscribe"));
|
|
2962
|
+
const emit = (r) => {
|
|
2963
|
+
const book = {
|
|
2964
|
+
exchange: "grvt",
|
|
2965
|
+
symbol: fromGrvtSymbol(instrument),
|
|
2966
|
+
market: opts.market,
|
|
2967
|
+
bids: r.bids,
|
|
2968
|
+
asks: r.asks,
|
|
2969
|
+
timestamp: r.timestamp,
|
|
2970
|
+
sequence: r.sequence
|
|
2971
|
+
};
|
|
2972
|
+
stream.emit("update", book);
|
|
2973
|
+
};
|
|
2974
|
+
const resync = () => {
|
|
2975
|
+
if (recovering) return;
|
|
2976
|
+
recovering = true;
|
|
2977
|
+
merger.reset();
|
|
2978
|
+
rpc("unsubscribe");
|
|
2979
|
+
subscribe();
|
|
2980
|
+
};
|
|
2981
|
+
const buildEvent2 = (feed, seq) => {
|
|
2982
|
+
const bids = toLevels(feed.bids);
|
|
2983
|
+
const asks = toLevels(feed.asks);
|
|
2984
|
+
const timestamp = nsToMs(feed.event_time);
|
|
2985
|
+
if (seq === 0) {
|
|
2986
|
+
snapshotSequence = ackSequence ?? 0;
|
|
2987
|
+
awaitingFirstDelta = true;
|
|
2988
|
+
return {
|
|
2989
|
+
kind: "snapshot",
|
|
2990
|
+
bids,
|
|
2991
|
+
asks,
|
|
2992
|
+
sequence: snapshotSequence,
|
|
2993
|
+
timestamp
|
|
2994
|
+
};
|
|
2995
|
+
}
|
|
2996
|
+
const prevSequence = awaitingFirstDelta ? snapshotSequence : seq - 1;
|
|
2997
|
+
awaitingFirstDelta = false;
|
|
2998
|
+
return { kind: "delta", bids, asks, sequence: seq, prevSequence, timestamp };
|
|
2999
|
+
};
|
|
3000
|
+
const handleFeed = (msg) => {
|
|
3001
|
+
if (!msg.feed) return;
|
|
3002
|
+
const seq = Number(msg.sequence_number ?? 0);
|
|
3003
|
+
if (!Number.isFinite(seq)) return;
|
|
3004
|
+
if (seq === 0) recovering = false;
|
|
3005
|
+
else if (recovering) return;
|
|
3006
|
+
const r = merger.apply(buildEvent2(msg.feed, seq));
|
|
3007
|
+
if (r.ok) {
|
|
3008
|
+
emit(r);
|
|
3009
|
+
} else if (r.reason === "gap" || r.reason === "no-snapshot") {
|
|
3010
|
+
resync();
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
const onMessage = (raw) => {
|
|
3014
|
+
if (typeof raw !== "string") return;
|
|
3015
|
+
let msg;
|
|
3016
|
+
try {
|
|
3017
|
+
msg = JSON.parse(raw);
|
|
3018
|
+
} catch {
|
|
3019
|
+
return;
|
|
3020
|
+
}
|
|
3021
|
+
if (msg.feed) {
|
|
3022
|
+
if (msg.selector && msg.selector !== selector) return;
|
|
3023
|
+
handleFeed(msg);
|
|
3024
|
+
return;
|
|
3025
|
+
}
|
|
3026
|
+
if (msg.id === void 0) return;
|
|
3027
|
+
if (msg.error) {
|
|
3028
|
+
stream.emit(
|
|
3029
|
+
"error",
|
|
3030
|
+
new ExchangeError("grvt", `${msg.error.code}: ${msg.error.message}`)
|
|
3031
|
+
);
|
|
3032
|
+
return;
|
|
3033
|
+
}
|
|
3034
|
+
if (subscribeIds.delete(msg.id)) {
|
|
3035
|
+
const subs = msg.result?.subs ?? [];
|
|
3036
|
+
const latest = Number(msg.result?.latest_sequence_number?.[0]);
|
|
3037
|
+
ackSequence = Number.isFinite(latest) ? latest : null;
|
|
3038
|
+
if (!subs.includes(selector)) {
|
|
3039
|
+
stream.emit(
|
|
3040
|
+
"error",
|
|
3041
|
+
new ExchangeError(
|
|
3042
|
+
"grvt",
|
|
3043
|
+
`subscribe rejected for "${STREAM}" selector "${selector}"`
|
|
3044
|
+
)
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
};
|
|
3049
|
+
ws = new WSClient({
|
|
3050
|
+
url: WS_FULL,
|
|
3051
|
+
onOpen: (handle) => {
|
|
3052
|
+
sock = handle;
|
|
3053
|
+
merger.reset();
|
|
3054
|
+
recovering = false;
|
|
3055
|
+
awaitingFirstDelta = false;
|
|
3056
|
+
subscribeIds.clear();
|
|
3057
|
+
subscribe();
|
|
3058
|
+
},
|
|
3059
|
+
onMessage
|
|
3060
|
+
});
|
|
3061
|
+
ws.on("open", () => stream.emit("connected"));
|
|
3062
|
+
ws.on("close", (r) => stream.emit("disconnected", r));
|
|
3063
|
+
ws.on("reconnecting", (a, w) => stream.emit("reconnecting", a, w));
|
|
3064
|
+
ws.on("error", (e) => stream.emit("error", e));
|
|
3065
|
+
ws.connect().catch((e) => stream.emit("error", e));
|
|
3066
|
+
return stream;
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
// src/exchanges/grvt/index.ts
|
|
3070
|
+
var GrvtClient = class {
|
|
3071
|
+
exchange = "grvt";
|
|
3072
|
+
transformUrl;
|
|
3073
|
+
timeoutMs;
|
|
3074
|
+
constructor(opts = {}) {
|
|
3075
|
+
this.transformUrl = opts.transformUrl;
|
|
3076
|
+
this.timeoutMs = opts.timeoutMs;
|
|
3077
|
+
}
|
|
3078
|
+
fetchOrderbook(symbol, opts = {}) {
|
|
3079
|
+
const { pair, market } = parseSymbol(symbol);
|
|
3080
|
+
return fetchGrvtOrderbook({
|
|
3081
|
+
symbol: pair,
|
|
3082
|
+
market,
|
|
3083
|
+
depth: opts.depth,
|
|
3084
|
+
timeoutMs: this.timeoutMs,
|
|
3085
|
+
transformUrl: this.transformUrl
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
streamOrderbook(symbol, opts = {}) {
|
|
3089
|
+
const { pair, market } = parseSymbol(symbol);
|
|
3090
|
+
return streamGrvtOrderbook({
|
|
3091
|
+
symbol: pair,
|
|
3092
|
+
market,
|
|
3093
|
+
depth: opts.depth,
|
|
3094
|
+
transformUrl: this.transformUrl,
|
|
3095
|
+
timeoutMs: this.timeoutMs
|
|
3096
|
+
});
|
|
3097
|
+
}
|
|
3098
|
+
};
|
|
3099
|
+
|
|
3100
|
+
export { Backoff, BinanceClient, BingxClient, BitgetClient, BookMerger, BybitClient, CoinexClient, DeribitClient, ExchangeError, GateClient, GrvtClient, HuobiClient, HyperliquidClient, KucoinClient, OkxClient, OrderbookStream, RateLimitError, SequenceGapError, parseSymbol };
|
|
2875
3101
|
//# sourceMappingURL=index.js.map
|
|
2876
3102
|
//# sourceMappingURL=index.js.map
|