@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/index.js
CHANGED
|
@@ -293238,15 +293238,12 @@ function createExecuteActionHandler(deps) {
|
|
|
293238
293238
|
import * as grpc13 from "@grpc/grpc-js";
|
|
293239
293239
|
|
|
293240
293240
|
// src/helpers/binance-user-data-stream.ts
|
|
293241
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
293241
293242
|
import { createHmac } from "crypto";
|
|
293243
|
+
import WebSocket2 from "ws";
|
|
293242
293244
|
var BINANCE_SPOT_WS_API_URL = "wss://ws-api.binance.com:443/ws-api/v3";
|
|
293243
|
-
|
|
293244
|
-
|
|
293245
|
-
if (!WebSocketCtor) {
|
|
293246
|
-
throw new Error("WebSocket is not available in this runtime");
|
|
293247
|
-
}
|
|
293248
|
-
return WebSocketCtor;
|
|
293249
|
-
}
|
|
293245
|
+
var DEFAULT_BINANCE_USER_DATA_MAX_BUFFERED_EVENTS = 16;
|
|
293246
|
+
var createWebSocket = (url3) => new WebSocket2(url3);
|
|
293250
293247
|
function getExchangeString(exchange, key) {
|
|
293251
293248
|
const value = exchange[key];
|
|
293252
293249
|
if (typeof value !== "string" || value.length === 0) {
|
|
@@ -293272,24 +293269,106 @@ function getBinanceSpotWsApiUrl(exchange) {
|
|
|
293272
293269
|
const urls = exchange.urls;
|
|
293273
293270
|
return urls?.api?.ws?.["ws-api"]?.spot ?? BINANCE_SPOT_WS_API_URL;
|
|
293274
293271
|
}
|
|
293272
|
+
function getRecord(value) {
|
|
293273
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
293274
|
+
}
|
|
293275
|
+
function getMessage(value) {
|
|
293276
|
+
if (value instanceof Error) {
|
|
293277
|
+
return value.message;
|
|
293278
|
+
}
|
|
293279
|
+
if (typeof value === "string" && value.length > 0) {
|
|
293280
|
+
return value;
|
|
293281
|
+
}
|
|
293282
|
+
const record2 = getRecord(value);
|
|
293283
|
+
const message = record2?.message;
|
|
293284
|
+
return typeof message === "string" && message.length > 0 ? message : null;
|
|
293285
|
+
}
|
|
293286
|
+
function getOptionalExchangeString(exchange, key) {
|
|
293287
|
+
const value = exchange[key];
|
|
293288
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
293289
|
+
}
|
|
293290
|
+
function redactDiagnosticMessage(message, secretValues) {
|
|
293291
|
+
let redacted = message;
|
|
293292
|
+
for (const value of secretValues) {
|
|
293293
|
+
if (value.length > 0) {
|
|
293294
|
+
redacted = redacted.split(value).join("[redacted]");
|
|
293295
|
+
}
|
|
293296
|
+
}
|
|
293297
|
+
return redacted.replace(/(\b(?:apiKey|secret|signature)\b\s*=\s*)[^\s&,;)]+/gi, "$1[redacted]").replace(/("(?:apiKey|secret|signature)"\s*:\s*")[^"]*(")/gi, "$1[redacted]$2");
|
|
293298
|
+
}
|
|
293299
|
+
function formatBinanceUserDataWebSocketError(event, secretValues) {
|
|
293300
|
+
const record2 = getRecord(event);
|
|
293301
|
+
const message = getMessage(record2?.error) ?? getMessage(record2?.message) ?? getMessage(event);
|
|
293302
|
+
const safeMessage = message === null ? null : redactDiagnosticMessage(message, secretValues);
|
|
293303
|
+
return new Error(safeMessage ? `Binance user-data WebSocket error: ${safeMessage}` : "Binance user-data WebSocket error");
|
|
293304
|
+
}
|
|
293305
|
+
function getCloseReason(value) {
|
|
293306
|
+
if (typeof value === "string") {
|
|
293307
|
+
return value.length > 0 ? value : null;
|
|
293308
|
+
}
|
|
293309
|
+
if (Buffer2.isBuffer(value)) {
|
|
293310
|
+
const reason = value.toString("utf8");
|
|
293311
|
+
return reason.length > 0 ? reason : null;
|
|
293312
|
+
}
|
|
293313
|
+
if (value instanceof Uint8Array) {
|
|
293314
|
+
const reason = Buffer2.from(value).toString("utf8");
|
|
293315
|
+
return reason.length > 0 ? reason : null;
|
|
293316
|
+
}
|
|
293317
|
+
return null;
|
|
293318
|
+
}
|
|
293319
|
+
function formatBinanceUserDataWebSocketClose(codeOrEvent, reasonOrUndefined, secretValues) {
|
|
293320
|
+
const record2 = getRecord(codeOrEvent);
|
|
293321
|
+
const code = record2 ? record2.code : codeOrEvent;
|
|
293322
|
+
const reason = getCloseReason(record2 ? record2.reason : reasonOrUndefined);
|
|
293323
|
+
const safeReason = reason === null ? null : redactDiagnosticMessage(reason, secretValues);
|
|
293324
|
+
const details = [
|
|
293325
|
+
typeof code === "number" || typeof code === "string" ? `code=${code}` : null,
|
|
293326
|
+
safeReason ? `reason=${safeReason}` : null
|
|
293327
|
+
].filter((detail) => detail !== null);
|
|
293328
|
+
return new Error(details.length > 0 ? `Binance user-data WebSocket closed unexpectedly (${details.join(", ")})` : "Binance user-data WebSocket closed unexpectedly");
|
|
293329
|
+
}
|
|
293330
|
+
function decodeMessageData(data) {
|
|
293331
|
+
if (typeof data === "string") {
|
|
293332
|
+
return data;
|
|
293333
|
+
}
|
|
293334
|
+
if (Buffer2.isBuffer(data)) {
|
|
293335
|
+
return data.toString("utf8");
|
|
293336
|
+
}
|
|
293337
|
+
if (data instanceof ArrayBuffer) {
|
|
293338
|
+
return Buffer2.from(data).toString("utf8");
|
|
293339
|
+
}
|
|
293340
|
+
if (ArrayBuffer.isView(data)) {
|
|
293341
|
+
return Buffer2.from(data.buffer, data.byteOffset, data.byteLength).toString("utf8");
|
|
293342
|
+
}
|
|
293343
|
+
if (Array.isArray(data) && data.every((item) => Buffer2.isBuffer(item))) {
|
|
293344
|
+
return Buffer2.concat(data).toString("utf8");
|
|
293345
|
+
}
|
|
293346
|
+
return data;
|
|
293347
|
+
}
|
|
293275
293348
|
|
|
293276
293349
|
class BinanceSpotUserDataStream {
|
|
293277
293350
|
exchange;
|
|
293278
293351
|
ws;
|
|
293352
|
+
secretValues;
|
|
293279
293353
|
requestId = `user-data-${Date.now()}-${Math.random()}`;
|
|
293354
|
+
maxBufferedEvents;
|
|
293280
293355
|
queue = [];
|
|
293281
293356
|
waiters = [];
|
|
293282
293357
|
closed = false;
|
|
293283
293358
|
closeError = null;
|
|
293284
293359
|
subscriptionId = null;
|
|
293285
|
-
constructor(exchange) {
|
|
293360
|
+
constructor(exchange, options = {}) {
|
|
293286
293361
|
this.exchange = exchange;
|
|
293287
|
-
|
|
293288
|
-
this.
|
|
293289
|
-
|
|
293290
|
-
|
|
293291
|
-
|
|
293292
|
-
this.ws
|
|
293362
|
+
this.maxBufferedEvents = options.maxBufferedEvents ?? DEFAULT_BINANCE_USER_DATA_MAX_BUFFERED_EVENTS;
|
|
293363
|
+
this.secretValues = [
|
|
293364
|
+
getOptionalExchangeString(exchange, "apiKey"),
|
|
293365
|
+
getOptionalExchangeString(exchange, "secret")
|
|
293366
|
+
].filter((value) => value !== null);
|
|
293367
|
+
this.ws = createWebSocket(getBinanceSpotWsApiUrl(exchange));
|
|
293368
|
+
this.ws.on("open", () => this.subscribe());
|
|
293369
|
+
this.ws.on("message", (data) => this.handleMessage(data));
|
|
293370
|
+
this.ws.on("error", (error48) => this.fail(formatBinanceUserDataWebSocketError(error48, this.secretValues)));
|
|
293371
|
+
this.ws.on("close", (code, reason) => this.handleClose(code, reason));
|
|
293293
293372
|
}
|
|
293294
293373
|
async* [Symbol.asyncIterator]() {
|
|
293295
293374
|
while (true) {
|
|
@@ -293305,11 +293384,18 @@ class BinanceSpotUserDataStream {
|
|
|
293305
293384
|
return;
|
|
293306
293385
|
}
|
|
293307
293386
|
this.closed = true;
|
|
293387
|
+
this.queue.length = 0;
|
|
293308
293388
|
try {
|
|
293309
293389
|
this.ws.close();
|
|
293310
293390
|
} catch {}
|
|
293311
293391
|
this.flushWaiters();
|
|
293312
293392
|
}
|
|
293393
|
+
handleClose(code, reason) {
|
|
293394
|
+
if (this.closed) {
|
|
293395
|
+
return;
|
|
293396
|
+
}
|
|
293397
|
+
this.fail(formatBinanceUserDataWebSocketClose(code, reason, this.secretValues));
|
|
293398
|
+
}
|
|
293313
293399
|
subscribe() {
|
|
293314
293400
|
const apiKey = getExchangeString(this.exchange, "apiKey");
|
|
293315
293401
|
const signedParams = signUserDataStreamParams(this.exchange, {
|
|
@@ -293323,9 +293409,13 @@ class BinanceSpotUserDataStream {
|
|
|
293323
293409
|
}));
|
|
293324
293410
|
}
|
|
293325
293411
|
handleMessage(data) {
|
|
293412
|
+
if (this.closed) {
|
|
293413
|
+
return;
|
|
293414
|
+
}
|
|
293326
293415
|
let message;
|
|
293327
293416
|
try {
|
|
293328
|
-
|
|
293417
|
+
const decodedData = decodeMessageData(data);
|
|
293418
|
+
message = typeof decodedData === "string" ? JSON.parse(decodedData) : decodedData;
|
|
293329
293419
|
} catch (error48) {
|
|
293330
293420
|
this.fail(error48 instanceof Error ? error48 : new Error("Invalid Binance user-data message"));
|
|
293331
293421
|
return;
|
|
@@ -293348,11 +293438,18 @@ class BinanceSpotUserDataStream {
|
|
|
293348
293438
|
this.push({ subscriptionId, event: message.event });
|
|
293349
293439
|
}
|
|
293350
293440
|
push(event) {
|
|
293441
|
+
if (this.closed) {
|
|
293442
|
+
return;
|
|
293443
|
+
}
|
|
293351
293444
|
const waiter = this.waiters.shift();
|
|
293352
293445
|
if (waiter) {
|
|
293353
293446
|
waiter.resolve(event);
|
|
293354
293447
|
return;
|
|
293355
293448
|
}
|
|
293449
|
+
if (this.queue.length >= this.maxBufferedEvents) {
|
|
293450
|
+
this.fail(new Error(`Binance user-data stream buffered event limit exceeded (${this.maxBufferedEvents}); downstream consumer is not keeping up`));
|
|
293451
|
+
return;
|
|
293452
|
+
}
|
|
293356
293453
|
this.queue.push(event);
|
|
293357
293454
|
}
|
|
293358
293455
|
nextEvent() {
|
|
@@ -293376,6 +293473,7 @@ class BinanceSpotUserDataStream {
|
|
|
293376
293473
|
}
|
|
293377
293474
|
this.closeError = error48;
|
|
293378
293475
|
this.closed = true;
|
|
293476
|
+
this.queue.length = 0;
|
|
293379
293477
|
this.flushWaiters();
|
|
293380
293478
|
try {
|
|
293381
293479
|
this.ws.close();
|
|
@@ -293403,16 +293501,49 @@ function isBinanceOrderUserDataEvent(event) {
|
|
|
293403
293501
|
function isBinanceSpotAccountSubscription(cex3, subscriptionType, marketTypeInput) {
|
|
293404
293502
|
return cex3 === "binance" && parseMarketType(marketTypeInput) === "spot" && (subscriptionType === SubscriptionType.BALANCE || subscriptionType === SubscriptionType.ORDERS);
|
|
293405
293503
|
}
|
|
293406
|
-
function
|
|
293504
|
+
function waitForSubscribeDrain(call, isClosed) {
|
|
293505
|
+
if (isClosed() || call.destroyed) {
|
|
293506
|
+
return Promise.resolve(false);
|
|
293507
|
+
}
|
|
293508
|
+
return new Promise((resolve) => {
|
|
293509
|
+
let settled = false;
|
|
293510
|
+
const cleanup = () => {
|
|
293511
|
+
call.off("drain", onDrain);
|
|
293512
|
+
call.off("close", onClosed);
|
|
293513
|
+
call.off("cancelled", onClosed);
|
|
293514
|
+
call.off("end", onClosed);
|
|
293515
|
+
call.off("error", onClosed);
|
|
293516
|
+
};
|
|
293517
|
+
const settle2 = (drained) => {
|
|
293518
|
+
if (settled) {
|
|
293519
|
+
return;
|
|
293520
|
+
}
|
|
293521
|
+
settled = true;
|
|
293522
|
+
cleanup();
|
|
293523
|
+
resolve(drained && !isClosed() && !call.destroyed);
|
|
293524
|
+
};
|
|
293525
|
+
const onDrain = () => settle2(true);
|
|
293526
|
+
const onClosed = () => settle2(false);
|
|
293527
|
+
call.once("drain", onDrain);
|
|
293528
|
+
call.once("close", onClosed);
|
|
293529
|
+
call.once("cancelled", onClosed);
|
|
293530
|
+
call.once("end", onClosed);
|
|
293531
|
+
call.once("error", onClosed);
|
|
293532
|
+
});
|
|
293533
|
+
}
|
|
293534
|
+
async function writeSubscribeFrame(call, isClosed, frame) {
|
|
293407
293535
|
if (isClosed() || call.destroyed) {
|
|
293408
293536
|
return false;
|
|
293409
293537
|
}
|
|
293410
|
-
call.write(frame);
|
|
293411
|
-
|
|
293538
|
+
const canContinue = call.write(frame);
|
|
293539
|
+
if (canContinue) {
|
|
293540
|
+
return true;
|
|
293541
|
+
}
|
|
293542
|
+
return waitForSubscribeDrain(call, isClosed);
|
|
293412
293543
|
}
|
|
293413
|
-
function writeSubscribeError(call, isClosed, frame) {
|
|
293414
|
-
writeSubscribeFrame(call, isClosed, frame);
|
|
293415
|
-
if (!isClosed() && !call.destroyed) {
|
|
293544
|
+
async function writeSubscribeError(call, isClosed, frame) {
|
|
293545
|
+
const frameWritten = await writeSubscribeFrame(call, isClosed, frame);
|
|
293546
|
+
if (frameWritten && !isClosed() && !call.destroyed) {
|
|
293416
293547
|
call.end();
|
|
293417
293548
|
}
|
|
293418
293549
|
}
|
|
@@ -293459,7 +293590,7 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
293459
293590
|
continue;
|
|
293460
293591
|
}
|
|
293461
293592
|
}
|
|
293462
|
-
if (!writeSubscribeFrame(call, isClosed, {
|
|
293593
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
293463
293594
|
data: JSON.stringify({
|
|
293464
293595
|
subscriptionId: message.subscriptionId,
|
|
293465
293596
|
event
|
|
@@ -293478,7 +293609,7 @@ async function streamBinanceUserData(call, broker, symbol2, subscriptionType, is
|
|
|
293478
293609
|
async function runCcxtSubscribeLoop(call, isClosed, symbol2, subscriptionType, watch) {
|
|
293479
293610
|
while (!isClosed()) {
|
|
293480
293611
|
const data = await watch();
|
|
293481
|
-
if (!writeSubscribeFrame(call, isClosed, {
|
|
293612
|
+
if (!await writeSubscribeFrame(call, isClosed, {
|
|
293482
293613
|
data: JSON.stringify(data),
|
|
293483
293614
|
timestamp: Date.now(),
|
|
293484
293615
|
symbol: symbol2,
|
|
@@ -293544,7 +293675,7 @@ function createSubscribeHandler(deps) {
|
|
|
293544
293675
|
type: subscriptionTypeName
|
|
293545
293676
|
});
|
|
293546
293677
|
if (!cex3 || !symbol2) {
|
|
293547
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293678
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293548
293679
|
data: JSON.stringify({
|
|
293549
293680
|
error: "cex, symbol, and type are required"
|
|
293550
293681
|
}),
|
|
@@ -293558,7 +293689,7 @@ function createSubscribeHandler(deps) {
|
|
|
293558
293689
|
const selectedBroker = selectBroker(brokers[normalizedCex], metadata) ?? createBroker(normalizedCex, metadata);
|
|
293559
293690
|
const broker = selectedBroker ?? createPublicBroker(normalizedCex);
|
|
293560
293691
|
if (!broker) {
|
|
293561
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293692
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293562
293693
|
data: JSON.stringify({
|
|
293563
293694
|
error: "Exchange not registered and no API metadata found"
|
|
293564
293695
|
}),
|
|
@@ -293571,7 +293702,7 @@ function createSubscribeHandler(deps) {
|
|
|
293571
293702
|
const resolvedSymbol = await resolveSubscriptionSymbol(broker, symbol2, options?.marketType);
|
|
293572
293703
|
if (isBinanceSpotAccountSubscription(normalizedCex, subscriptionType, options?.marketType)) {
|
|
293573
293704
|
if (!selectedBroker) {
|
|
293574
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293705
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293575
293706
|
data: JSON.stringify({
|
|
293576
293707
|
error: "Binance account subscriptions require API credentials"
|
|
293577
293708
|
}),
|
|
@@ -293591,7 +293722,7 @@ function createSubscribeHandler(deps) {
|
|
|
293591
293722
|
const depthLimit = parseOptionalDepthLimit(options?.depthLimit ?? options?.limit);
|
|
293592
293723
|
const orderbook = depthLimit === undefined ? await broker.watchOrderBook(resolvedSymbol) : await broker.watchOrderBook(resolvedSymbol, depthLimit);
|
|
293593
293724
|
const receivedTimestamp = Date.now();
|
|
293594
|
-
if (!writeSubscribeFrame(call, isStreamClosed, {
|
|
293725
|
+
if (!await writeSubscribeFrame(call, isStreamClosed, {
|
|
293595
293726
|
data: JSON.stringify(normalizeOrderBookSnapshot(orderbook, {
|
|
293596
293727
|
exchange: normalizedCex,
|
|
293597
293728
|
symbol: resolvedSymbol,
|
|
@@ -293608,7 +293739,7 @@ function createSubscribeHandler(deps) {
|
|
|
293608
293739
|
} catch (error48) {
|
|
293609
293740
|
log.error(`Error fetching orderbook for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
293610
293741
|
const message = getErrorMessage(error48);
|
|
293611
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293742
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293612
293743
|
data: JSON.stringify({
|
|
293613
293744
|
error: `Failed to fetch orderbook: ${message}`
|
|
293614
293745
|
}),
|
|
@@ -293624,7 +293755,7 @@ function createSubscribeHandler(deps) {
|
|
|
293624
293755
|
} catch (error48) {
|
|
293625
293756
|
const message = getErrorMessage(error48);
|
|
293626
293757
|
log.error(`Error fetching trades for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
293627
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293758
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293628
293759
|
data: JSON.stringify({
|
|
293629
293760
|
error: `Failed to fetch trades: ${message}`
|
|
293630
293761
|
}),
|
|
@@ -293640,7 +293771,7 @@ function createSubscribeHandler(deps) {
|
|
|
293640
293771
|
} catch (error48) {
|
|
293641
293772
|
const message = getErrorMessage(error48);
|
|
293642
293773
|
log.error(`Error fetching ticker for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
293643
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293774
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293644
293775
|
data: JSON.stringify({
|
|
293645
293776
|
error: `Failed to fetch ticker: ${message}`
|
|
293646
293777
|
}),
|
|
@@ -293657,7 +293788,7 @@ function createSubscribeHandler(deps) {
|
|
|
293657
293788
|
} catch (error48) {
|
|
293658
293789
|
log.error(`Error fetching OHLCV for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
293659
293790
|
const message = getErrorMessage(error48);
|
|
293660
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293791
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293661
293792
|
data: JSON.stringify({
|
|
293662
293793
|
error: `Failed to fetch OHLCV: ${message}`
|
|
293663
293794
|
}),
|
|
@@ -293673,7 +293804,7 @@ function createSubscribeHandler(deps) {
|
|
|
293673
293804
|
} catch (error48) {
|
|
293674
293805
|
const message = getErrorMessage(error48);
|
|
293675
293806
|
log.error(`Error fetching balance for ${cex3}:`, error48);
|
|
293676
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293807
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293677
293808
|
data: JSON.stringify({
|
|
293678
293809
|
error: `Failed to fetch balance: ${message}`
|
|
293679
293810
|
}),
|
|
@@ -293689,7 +293820,7 @@ function createSubscribeHandler(deps) {
|
|
|
293689
293820
|
} catch (error48) {
|
|
293690
293821
|
log.error(`Error fetching orders for ${resolvedSymbol} on ${cex3}:`, error48);
|
|
293691
293822
|
const message = getErrorMessage(error48);
|
|
293692
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293823
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293693
293824
|
data: JSON.stringify({
|
|
293694
293825
|
error: `Failed to fetch orders: ${message}`
|
|
293695
293826
|
}),
|
|
@@ -293700,7 +293831,7 @@ function createSubscribeHandler(deps) {
|
|
|
293700
293831
|
}
|
|
293701
293832
|
break;
|
|
293702
293833
|
default:
|
|
293703
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293834
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293704
293835
|
data: JSON.stringify({ error: "Invalid subscription type" }),
|
|
293705
293836
|
timestamp: Date.now(),
|
|
293706
293837
|
symbol: symbol2,
|
|
@@ -293710,7 +293841,7 @@ function createSubscribeHandler(deps) {
|
|
|
293710
293841
|
} catch (error48) {
|
|
293711
293842
|
log.error("Error in Subscribe stream:", error48);
|
|
293712
293843
|
const message = getErrorMessage(error48);
|
|
293713
|
-
writeSubscribeError(call, isStreamClosed, {
|
|
293844
|
+
await writeSubscribeError(call, isStreamClosed, {
|
|
293714
293845
|
data: JSON.stringify({ error: `Internal server error: ${message}` }),
|
|
293715
293846
|
timestamp: Date.now(),
|
|
293716
293847
|
symbol: "",
|
|
@@ -294185,4 +294316,4 @@ export {
|
|
|
294185
294316
|
CEXBroker as default
|
|
294186
294317
|
};
|
|
294187
294318
|
|
|
294188
|
-
//# debugId=
|
|
294319
|
+
//# debugId=6D0E11DC0BFB633164756E2164756E21
|