@usherlabs/cex-broker 0.2.13 → 0.2.14
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/dist/commands/cli.js +165 -35
- package/dist/helpers/binance-user-data-stream.d.ts +19 -1
- package/dist/index.js +167 -36
- package/dist/index.js.map +4 -4
- package/package.json +3 -1
package/dist/commands/cli.js
CHANGED
|
@@ -330285,15 +330285,11 @@ function createExecuteActionHandler(deps) {
|
|
|
330285
330285
|
var grpc13 = __toESM(require_src3(), 1);
|
|
330286
330286
|
|
|
330287
330287
|
// src/helpers/binance-user-data-stream.ts
|
|
330288
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
330288
330289
|
import { createHmac } from "node:crypto";
|
|
330289
330290
|
var BINANCE_SPOT_WS_API_URL = "wss://ws-api.binance.com:443/ws-api/v3";
|
|
330290
|
-
|
|
330291
|
-
|
|
330292
|
-
if (!WebSocketCtor) {
|
|
330293
|
-
throw new Error("WebSocket is not available in this runtime");
|
|
330294
|
-
}
|
|
330295
|
-
return WebSocketCtor;
|
|
330296
|
-
}
|
|
330291
|
+
var DEFAULT_BINANCE_USER_DATA_MAX_BUFFERED_EVENTS = 16;
|
|
330292
|
+
var createWebSocket = (url3) => new wrapper_default(url3);
|
|
330297
330293
|
function getExchangeString(exchange, key) {
|
|
330298
330294
|
const value = exchange[key];
|
|
330299
330295
|
if (typeof value !== "string" || value.length === 0) {
|
|
@@ -330319,24 +330315,106 @@ function getBinanceSpotWsApiUrl(exchange) {
|
|
|
330319
330315
|
const urls = exchange.urls;
|
|
330320
330316
|
return urls?.api?.ws?.["ws-api"]?.spot ?? BINANCE_SPOT_WS_API_URL;
|
|
330321
330317
|
}
|
|
330318
|
+
function getRecord(value) {
|
|
330319
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
330320
|
+
}
|
|
330321
|
+
function getMessage(value) {
|
|
330322
|
+
if (value instanceof Error) {
|
|
330323
|
+
return value.message;
|
|
330324
|
+
}
|
|
330325
|
+
if (typeof value === "string" && value.length > 0) {
|
|
330326
|
+
return value;
|
|
330327
|
+
}
|
|
330328
|
+
const record2 = getRecord(value);
|
|
330329
|
+
const message = record2?.message;
|
|
330330
|
+
return typeof message === "string" && message.length > 0 ? message : null;
|
|
330331
|
+
}
|
|
330332
|
+
function getOptionalExchangeString(exchange, key) {
|
|
330333
|
+
const value = exchange[key];
|
|
330334
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
330335
|
+
}
|
|
330336
|
+
function redactDiagnosticMessage(message, secretValues) {
|
|
330337
|
+
let redacted = message;
|
|
330338
|
+
for (const value of secretValues) {
|
|
330339
|
+
if (value.length > 0) {
|
|
330340
|
+
redacted = redacted.split(value).join("[redacted]");
|
|
330341
|
+
}
|
|
330342
|
+
}
|
|
330343
|
+
return redacted.replace(/(\b(?:apiKey|secret|signature)\b\s*=\s*)[^\s&,;)]+/gi, "$1[redacted]").replace(/("(?:apiKey|secret|signature)"\s*:\s*")[^"]*(")/gi, "$1[redacted]$2");
|
|
330344
|
+
}
|
|
330345
|
+
function formatBinanceUserDataWebSocketError(event, secretValues) {
|
|
330346
|
+
const record2 = getRecord(event);
|
|
330347
|
+
const message = getMessage(record2?.error) ?? getMessage(record2?.message) ?? getMessage(event);
|
|
330348
|
+
const safeMessage = message === null ? null : redactDiagnosticMessage(message, secretValues);
|
|
330349
|
+
return new Error(safeMessage ? `Binance user-data WebSocket error: ${safeMessage}` : "Binance user-data WebSocket error");
|
|
330350
|
+
}
|
|
330351
|
+
function getCloseReason(value) {
|
|
330352
|
+
if (typeof value === "string") {
|
|
330353
|
+
return value.length > 0 ? value : null;
|
|
330354
|
+
}
|
|
330355
|
+
if (Buffer2.isBuffer(value)) {
|
|
330356
|
+
const reason = value.toString("utf8");
|
|
330357
|
+
return reason.length > 0 ? reason : null;
|
|
330358
|
+
}
|
|
330359
|
+
if (value instanceof Uint8Array) {
|
|
330360
|
+
const reason = Buffer2.from(value).toString("utf8");
|
|
330361
|
+
return reason.length > 0 ? reason : null;
|
|
330362
|
+
}
|
|
330363
|
+
return null;
|
|
330364
|
+
}
|
|
330365
|
+
function formatBinanceUserDataWebSocketClose(codeOrEvent, reasonOrUndefined, secretValues) {
|
|
330366
|
+
const record2 = getRecord(codeOrEvent);
|
|
330367
|
+
const code = record2 ? record2.code : codeOrEvent;
|
|
330368
|
+
const reason = getCloseReason(record2 ? record2.reason : reasonOrUndefined);
|
|
330369
|
+
const safeReason = reason === null ? null : redactDiagnosticMessage(reason, secretValues);
|
|
330370
|
+
const details = [
|
|
330371
|
+
typeof code === "number" || typeof code === "string" ? `code=${code}` : null,
|
|
330372
|
+
safeReason ? `reason=${safeReason}` : null
|
|
330373
|
+
].filter((detail) => detail !== null);
|
|
330374
|
+
return new Error(details.length > 0 ? `Binance user-data WebSocket closed unexpectedly (${details.join(", ")})` : "Binance user-data WebSocket closed unexpectedly");
|
|
330375
|
+
}
|
|
330376
|
+
function decodeMessageData(data) {
|
|
330377
|
+
if (typeof data === "string") {
|
|
330378
|
+
return data;
|
|
330379
|
+
}
|
|
330380
|
+
if (Buffer2.isBuffer(data)) {
|
|
330381
|
+
return data.toString("utf8");
|
|
330382
|
+
}
|
|
330383
|
+
if (data instanceof ArrayBuffer) {
|
|
330384
|
+
return Buffer2.from(data).toString("utf8");
|
|
330385
|
+
}
|
|
330386
|
+
if (ArrayBuffer.isView(data)) {
|
|
330387
|
+
return Buffer2.from(data.buffer, data.byteOffset, data.byteLength).toString("utf8");
|
|
330388
|
+
}
|
|
330389
|
+
if (Array.isArray(data) && data.every((item) => Buffer2.isBuffer(item))) {
|
|
330390
|
+
return Buffer2.concat(data).toString("utf8");
|
|
330391
|
+
}
|
|
330392
|
+
return data;
|
|
330393
|
+
}
|
|
330322
330394
|
|
|
330323
330395
|
class BinanceSpotUserDataStream {
|
|
330324
330396
|
exchange;
|
|
330325
330397
|
ws;
|
|
330398
|
+
secretValues;
|
|
330326
330399
|
requestId = `user-data-${Date.now()}-${Math.random()}`;
|
|
330400
|
+
maxBufferedEvents;
|
|
330327
330401
|
queue = [];
|
|
330328
330402
|
waiters = [];
|
|
330329
330403
|
closed = false;
|
|
330330
330404
|
closeError = null;
|
|
330331
330405
|
subscriptionId = null;
|
|
330332
|
-
constructor(exchange) {
|
|
330406
|
+
constructor(exchange, options = {}) {
|
|
330333
330407
|
this.exchange = exchange;
|
|
330334
|
-
|
|
330335
|
-
this.
|
|
330336
|
-
|
|
330337
|
-
|
|
330338
|
-
|
|
330339
|
-
this.ws
|
|
330408
|
+
this.maxBufferedEvents = options.maxBufferedEvents ?? DEFAULT_BINANCE_USER_DATA_MAX_BUFFERED_EVENTS;
|
|
330409
|
+
this.secretValues = [
|
|
330410
|
+
getOptionalExchangeString(exchange, "apiKey"),
|
|
330411
|
+
getOptionalExchangeString(exchange, "secret")
|
|
330412
|
+
].filter((value) => value !== null);
|
|
330413
|
+
this.ws = createWebSocket(getBinanceSpotWsApiUrl(exchange));
|
|
330414
|
+
this.ws.on("open", () => this.subscribe());
|
|
330415
|
+
this.ws.on("message", (data) => this.handleMessage(data));
|
|
330416
|
+
this.ws.on("error", (error48) => this.fail(formatBinanceUserDataWebSocketError(error48, this.secretValues)));
|
|
330417
|
+
this.ws.on("close", (code, reason) => this.handleClose(code, reason));
|
|
330340
330418
|
}
|
|
330341
330419
|
async* [Symbol.asyncIterator]() {
|
|
330342
330420
|
while (true) {
|
|
@@ -330352,11 +330430,18 @@ class BinanceSpotUserDataStream {
|
|
|
330352
330430
|
return;
|
|
330353
330431
|
}
|
|
330354
330432
|
this.closed = true;
|
|
330433
|
+
this.queue.length = 0;
|
|
330355
330434
|
try {
|
|
330356
330435
|
this.ws.close();
|
|
330357
330436
|
} catch {}
|
|
330358
330437
|
this.flushWaiters();
|
|
330359
330438
|
}
|
|
330439
|
+
handleClose(code, reason) {
|
|
330440
|
+
if (this.closed) {
|
|
330441
|
+
return;
|
|
330442
|
+
}
|
|
330443
|
+
this.fail(formatBinanceUserDataWebSocketClose(code, reason, this.secretValues));
|
|
330444
|
+
}
|
|
330360
330445
|
subscribe() {
|
|
330361
330446
|
const apiKey = getExchangeString(this.exchange, "apiKey");
|
|
330362
330447
|
const signedParams = signUserDataStreamParams(this.exchange, {
|
|
@@ -330370,9 +330455,13 @@ class BinanceSpotUserDataStream {
|
|
|
330370
330455
|
}));
|
|
330371
330456
|
}
|
|
330372
330457
|
handleMessage(data) {
|
|
330458
|
+
if (this.closed) {
|
|
330459
|
+
return;
|
|
330460
|
+
}
|
|
330373
330461
|
let message;
|
|
330374
330462
|
try {
|
|
330375
|
-
|
|
330463
|
+
const decodedData = decodeMessageData(data);
|
|
330464
|
+
message = typeof decodedData === "string" ? JSON.parse(decodedData) : decodedData;
|
|
330376
330465
|
} catch (error48) {
|
|
330377
330466
|
this.fail(error48 instanceof Error ? error48 : new Error("Invalid Binance user-data message"));
|
|
330378
330467
|
return;
|
|
@@ -330395,11 +330484,18 @@ class BinanceSpotUserDataStream {
|
|
|
330395
330484
|
this.push({ subscriptionId, event: message.event });
|
|
330396
330485
|
}
|
|
330397
330486
|
push(event) {
|
|
330487
|
+
if (this.closed) {
|
|
330488
|
+
return;
|
|
330489
|
+
}
|
|
330398
330490
|
const waiter = this.waiters.shift();
|
|
330399
330491
|
if (waiter) {
|
|
330400
330492
|
waiter.resolve(event);
|
|
330401
330493
|
return;
|
|
330402
330494
|
}
|
|
330495
|
+
if (this.queue.length >= this.maxBufferedEvents) {
|
|
330496
|
+
this.fail(new Error(`Binance user-data stream buffered event limit exceeded (${this.maxBufferedEvents}); downstream consumer is not keeping up`));
|
|
330497
|
+
return;
|
|
330498
|
+
}
|
|
330403
330499
|
this.queue.push(event);
|
|
330404
330500
|
}
|
|
330405
330501
|
nextEvent() {
|
|
@@ -330423,6 +330519,7 @@ class BinanceSpotUserDataStream {
|
|
|
330423
330519
|
}
|
|
330424
330520
|
this.closeError = error48;
|
|
330425
330521
|
this.closed = true;
|
|
330522
|
+
this.queue.length = 0;
|
|
330426
330523
|
this.flushWaiters();
|
|
330427
330524
|
try {
|
|
330428
330525
|
this.ws.close();
|
|
@@ -330450,16 +330547,49 @@ function isBinanceOrderUserDataEvent(event) {
|
|
|
330450
330547
|
function isBinanceSpotAccountSubscription(cex3, subscriptionType, marketTypeInput) {
|
|
330451
330548
|
return cex3 === "binance" && parseMarketType(marketTypeInput) === "spot" && (subscriptionType === SubscriptionType.BALANCE || subscriptionType === SubscriptionType.ORDERS);
|
|
330452
330549
|
}
|
|
330453
|
-
function
|
|
330550
|
+
function waitForSubscribeDrain(call, isClosed) {
|
|
330551
|
+
if (isClosed() || call.destroyed) {
|
|
330552
|
+
return Promise.resolve(false);
|
|
330553
|
+
}
|
|
330554
|
+
return new Promise((resolve) => {
|
|
330555
|
+
let settled = false;
|
|
330556
|
+
const cleanup = () => {
|
|
330557
|
+
call.off("drain", onDrain);
|
|
330558
|
+
call.off("close", onClosed);
|
|
330559
|
+
call.off("cancelled", onClosed);
|
|
330560
|
+
call.off("end", onClosed);
|
|
330561
|
+
call.off("error", onClosed);
|
|
330562
|
+
};
|
|
330563
|
+
const settle2 = (drained) => {
|
|
330564
|
+
if (settled) {
|
|
330565
|
+
return;
|
|
330566
|
+
}
|
|
330567
|
+
settled = true;
|
|
330568
|
+
cleanup();
|
|
330569
|
+
resolve(drained && !isClosed() && !call.destroyed);
|
|
330570
|
+
};
|
|
330571
|
+
const onDrain = () => settle2(true);
|
|
330572
|
+
const onClosed = () => settle2(false);
|
|
330573
|
+
call.once("drain", onDrain);
|
|
330574
|
+
call.once("close", onClosed);
|
|
330575
|
+
call.once("cancelled", onClosed);
|
|
330576
|
+
call.once("end", onClosed);
|
|
330577
|
+
call.once("error", onClosed);
|
|
330578
|
+
});
|
|
330579
|
+
}
|
|
330580
|
+
async function writeSubscribeFrame(call, isClosed, frame) {
|
|
330454
330581
|
if (isClosed() || call.destroyed) {
|
|
330455
330582
|
return false;
|
|
330456
330583
|
}
|
|
330457
|
-
call.write(frame);
|
|
330458
|
-
|
|
330584
|
+
const canContinue = call.write(frame);
|
|
330585
|
+
if (canContinue) {
|
|
330586
|
+
return true;
|
|
330587
|
+
}
|
|
330588
|
+
return waitForSubscribeDrain(call, isClosed);
|
|
330459
330589
|
}
|
|
330460
|
-
function writeSubscribeError(call, isClosed, frame) {
|
|
330461
|
-
writeSubscribeFrame(call, isClosed, frame);
|
|
330462
|
-
if (!isClosed() && !call.destroyed) {
|
|
330590
|
+
async function writeSubscribeError(call, isClosed, frame) {
|
|
330591
|
+
const frameWritten = await writeSubscribeFrame(call, isClosed, frame);
|
|
330592
|
+
if (frameWritten && !isClosed() && !call.destroyed) {
|
|
330463
330593
|
call.end();
|
|
330464
330594
|
}
|
|
330465
330595
|
}
|
|
@@ -330506,7 +330636,7 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
330506
330636
|
continue;
|
|
330507
330637
|
}
|
|
330508
330638
|
}
|
|
330509
|
-
if (!writeSubscribeFrame(call, isClosed, {
|
|
330639
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
330510
330640
|
data: JSON.stringify({
|
|
330511
330641
|
subscriptionId: message.subscriptionId,
|
|
330512
330642
|
event
|
|
@@ -330525,7 +330655,7 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
330525
330655
|
async function runCcxtSubscribeLoop(call, isClosed, symbol2, subscriptionType, watch) {
|
|
330526
330656
|
while (!isClosed()) {
|
|
330527
330657
|
const data = await watch();
|
|
330528
|
-
if (!writeSubscribeFrame(call, isClosed, {
|
|
330658
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
330529
330659
|
data: JSON.stringify(data),
|
|
330530
330660
|
timestamp: Date.now(),
|
|
330531
330661
|
symbol: symbol2,
|
|
@@ -330591,7 +330721,7 @@ function createSubscribeHandler(deps) {
|
|
|
330591
330721
|
type: subscriptionTypeName
|
|
330592
330722
|
});
|
|
330593
330723
|
if (!cex3 || !symbol2) {
|
|
330594
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330724
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330595
330725
|
data: JSON.stringify({
|
|
330596
330726
|
error: "cex, symbol, and type are required"
|
|
330597
330727
|
}),
|
|
@@ -330605,7 +330735,7 @@ function createSubscribeHandler(deps) {
|
|
|
330605
330735
|
const selectedBroker = selectBroker(brokers[normalizedCex], metadata) ?? createBroker(normalizedCex, metadata);
|
|
330606
330736
|
const broker = selectedBroker ?? createPublicBroker(normalizedCex);
|
|
330607
330737
|
if (!broker) {
|
|
330608
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330738
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330609
330739
|
data: JSON.stringify({
|
|
330610
330740
|
error: "Exchange not registered and no API metadata found"
|
|
330611
330741
|
}),
|
|
@@ -330618,7 +330748,7 @@ function createSubscribeHandler(deps) {
|
|
|
330618
330748
|
const resolvedSymbol = await resolveSubscriptionSymbol(broker, symbol2, options?.marketType);
|
|
330619
330749
|
if (isBinanceSpotAccountSubscription(normalizedCex, subscriptionType, options?.marketType)) {
|
|
330620
330750
|
if (!selectedBroker) {
|
|
330621
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330751
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330622
330752
|
data: JSON.stringify({
|
|
330623
330753
|
error: "Binance account subscriptions require API credentials"
|
|
330624
330754
|
}),
|
|
@@ -330638,7 +330768,7 @@ function createSubscribeHandler(deps) {
|
|
|
330638
330768
|
const depthLimit = parseOptionalDepthLimit(options?.depthLimit ?? options?.limit);
|
|
330639
330769
|
const orderbook = depthLimit === undefined ? await broker.watchOrderBook(resolvedSymbol) : await broker.watchOrderBook(resolvedSymbol, depthLimit);
|
|
330640
330770
|
const receivedTimestamp = Date.now();
|
|
330641
|
-
if (!writeSubscribeFrame(call, isStreamClosed, {
|
|
330771
|
+
if (!await writeSubscribeFrame(call, isStreamClosed, {
|
|
330642
330772
|
data: JSON.stringify(normalizeOrderBookSnapshot(orderbook, {
|
|
330643
330773
|
exchange: normalizedCex,
|
|
330644
330774
|
symbol: resolvedSymbol,
|
|
@@ -330655,7 +330785,7 @@ function createSubscribeHandler(deps) {
|
|
|
330655
330785
|
} catch (error48) {
|
|
330656
330786
|
log.error(`Error fetching orderbook for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
330657
330787
|
const message = getErrorMessage(error48);
|
|
330658
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330788
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330659
330789
|
data: JSON.stringify({
|
|
330660
330790
|
error: `Failed to fetch orderbook: ${message}`
|
|
330661
330791
|
}),
|
|
@@ -330671,7 +330801,7 @@ function createSubscribeHandler(deps) {
|
|
|
330671
330801
|
} catch (error48) {
|
|
330672
330802
|
const message = getErrorMessage(error48);
|
|
330673
330803
|
log.error(`Error fetching trades for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
330674
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330804
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330675
330805
|
data: JSON.stringify({
|
|
330676
330806
|
error: `Failed to fetch trades: ${message}`
|
|
330677
330807
|
}),
|
|
@@ -330687,7 +330817,7 @@ function createSubscribeHandler(deps) {
|
|
|
330687
330817
|
} catch (error48) {
|
|
330688
330818
|
const message = getErrorMessage(error48);
|
|
330689
330819
|
log.error(`Error fetching ticker for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
330690
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330820
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330691
330821
|
data: JSON.stringify({
|
|
330692
330822
|
error: `Failed to fetch ticker: ${message}`
|
|
330693
330823
|
}),
|
|
@@ -330704,7 +330834,7 @@ function createSubscribeHandler(deps) {
|
|
|
330704
330834
|
} catch (error48) {
|
|
330705
330835
|
log.error(`Error fetching OHLCV for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
330706
330836
|
const message = getErrorMessage(error48);
|
|
330707
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330837
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330708
330838
|
data: JSON.stringify({
|
|
330709
330839
|
error: `Failed to fetch OHLCV: ${message}`
|
|
330710
330840
|
}),
|
|
@@ -330720,7 +330850,7 @@ function createSubscribeHandler(deps) {
|
|
|
330720
330850
|
} catch (error48) {
|
|
330721
330851
|
const message = getErrorMessage(error48);
|
|
330722
330852
|
log.error(`Error fetching balance for ${cex3}:`, error48);
|
|
330723
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330853
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330724
330854
|
data: JSON.stringify({
|
|
330725
330855
|
error: `Failed to fetch balance: ${message}`
|
|
330726
330856
|
}),
|
|
@@ -330736,7 +330866,7 @@ function createSubscribeHandler(deps) {
|
|
|
330736
330866
|
} catch (error48) {
|
|
330737
330867
|
log.error(`Error fetching orders for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
330738
330868
|
const message = getErrorMessage(error48);
|
|
330739
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330869
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330740
330870
|
data: JSON.stringify({
|
|
330741
330871
|
error: `Failed to fetch orders: ${message}`
|
|
330742
330872
|
}),
|
|
@@ -330747,7 +330877,7 @@ function createSubscribeHandler(deps) {
|
|
|
330747
330877
|
}
|
|
330748
330878
|
break;
|
|
330749
330879
|
default:
|
|
330750
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330880
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330751
330881
|
data: JSON.stringify({ error: "Invalid subscription type" }),
|
|
330752
330882
|
timestamp: Date.now(),
|
|
330753
330883
|
symbol: symbol2,
|
|
@@ -330757,7 +330887,7 @@ function createSubscribeHandler(deps) {
|
|
|
330757
330887
|
} catch (error48) {
|
|
330758
330888
|
log.error("Error in Subscribe stream:", error48);
|
|
330759
330889
|
const message = getErrorMessage(error48);
|
|
330760
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
330890
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
330761
330891
|
data: JSON.stringify({ error: `Internal server error: ${message}` }),
|
|
330762
330892
|
timestamp: Date.now(),
|
|
330763
330893
|
symbol: "",
|
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
import type { Exchange } from "@usherlabs/ccxt";
|
|
2
2
|
export declare const BINANCE_SPOT_WS_API_URL = "wss://ws-api.binance.com:443/ws-api/v3";
|
|
3
|
+
export declare const DEFAULT_BINANCE_USER_DATA_MAX_BUFFERED_EVENTS = 16;
|
|
3
4
|
export type BinanceUserDataEvent = {
|
|
4
5
|
subscriptionId: number;
|
|
5
6
|
event: Record<string, unknown>;
|
|
6
7
|
};
|
|
8
|
+
type WebSocketLike = {
|
|
9
|
+
on(event: "open", listener: () => void): unknown;
|
|
10
|
+
on(event: "message", listener: (data: unknown) => void): unknown;
|
|
11
|
+
on(event: "error", listener: (error: unknown) => void): unknown;
|
|
12
|
+
on(event: "close", listener: (code: unknown, reason: unknown) => void): unknown;
|
|
13
|
+
send(data: string): void;
|
|
14
|
+
close(code?: number, reason?: string): void;
|
|
15
|
+
};
|
|
16
|
+
type WebSocketFactory = (url: string) => WebSocketLike;
|
|
17
|
+
type BinanceSpotUserDataStreamOptions = {
|
|
18
|
+
maxBufferedEvents?: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function setBinanceUserDataWebSocketFactoryForTests(factory: WebSocketFactory): () => void;
|
|
7
21
|
export declare function getBinanceSpotWsApiUrl(exchange: Exchange): string;
|
|
8
22
|
export declare class BinanceSpotUserDataStream implements AsyncIterable<BinanceUserDataEvent> {
|
|
9
23
|
private readonly exchange;
|
|
10
24
|
private readonly ws;
|
|
25
|
+
private readonly secretValues;
|
|
11
26
|
private readonly requestId;
|
|
27
|
+
private readonly maxBufferedEvents;
|
|
12
28
|
private readonly queue;
|
|
13
29
|
private readonly waiters;
|
|
14
30
|
private closed;
|
|
15
31
|
private closeError;
|
|
16
32
|
private subscriptionId;
|
|
17
|
-
constructor(exchange: Exchange);
|
|
33
|
+
constructor(exchange: Exchange, options?: BinanceSpotUserDataStreamOptions);
|
|
18
34
|
[Symbol.asyncIterator](): AsyncIterator<BinanceUserDataEvent>;
|
|
19
35
|
close(): void;
|
|
36
|
+
private handleClose;
|
|
20
37
|
private subscribe;
|
|
21
38
|
private handleMessage;
|
|
22
39
|
private push;
|
|
@@ -26,3 +43,4 @@ export declare class BinanceSpotUserDataStream implements AsyncIterable<BinanceU
|
|
|
26
43
|
}
|
|
27
44
|
export declare function isBinanceBalanceUserDataEvent(event: Record<string, unknown>): boolean;
|
|
28
45
|
export declare function isBinanceOrderUserDataEvent(event: Record<string, unknown>): boolean;
|
|
46
|
+
export {};
|