binance
Version:
Professional Node.js & JavaScript SDK for Binance REST APIs & WebSockets, with TypeScript & end-to-end tests.
647 lines • 27.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebsocketAPIClient = void 0;
const typeGuards_1 = require("./util/typeGuards");
const websocket_util_1 = require("./util/websockets/websocket-util");
const websocket_client_1 = require("./websocket-client");
function getFuturesMarketWsKey(market) {
if (market === 'usdm') {
return websocket_util_1.WS_KEY_MAP.usdmWSAPI;
}
return websocket_util_1.WS_KEY_MAP.coinmWSAPI;
}
/**
* This is a minimal Websocket API wrapper around the WebsocketClient.
*
* Some methods support passing in a custom "wsKey". This is a reference to which WS connection should
* be used to transmit that message. This is only useful if you wish to use an alternative wss
* domain that is supported by the SDK.
*
* Note: To use testnet, don't set the wsKey - use `testnet: true` in
* the constructor instead.
*
* Note: You can also directly use the sendWSAPIRequest() method to make WS API calls, but some
* may find the below methods slightly more intuitive.
*
* Refer to the WS API promises example for a more detailed example on using sendWSAPIRequest() directly:
* https://github.com/tiagosiebler/binance/blob/master/examples/WebSockets/ws-api-raw-promises.ts#L108
*/
class WebsocketAPIClient {
constructor(options, logger) {
/**
* Minimal state store around automating sticky "userDataStream.subscribe" sessions
*/
this.subscribedUserDataStreamState = {};
this.wsClient = new websocket_client_1.WebsocketClient(options, logger);
this.options = Object.assign({ resubscribeUserDataStreamAfterReconnect: true, resubscribeUserDataStreamDelaySeconds: 2, attachEventListeners: true }, options);
this.logger = this.wsClient.logger;
this.setupDefaultEventListeners();
this.wsClient.on('reconnected', ({ wsKey }) => {
this.handleWSReconnectedEvent({ wsKey });
});
}
getWSClient() {
return this.wsClient;
}
setTimeOffsetMs(newOffset) {
return this.getWSClient().setTimeOffsetMs(newOffset);
}
/*
*
* SPOT - General requests
*
*/
/**
* Test connectivity to the WebSocket API
*/
testSpotConnectivity(wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ping', undefined, { authIsOptional: true });
}
/**
* Test connectivity to the WebSocket API and get the current server time
*/
getSpotServerTime(wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'time', undefined, { authIsOptional: true });
}
/**
* Query current exchange trading rules, rate limits, and symbol information
*/
getSpotExchangeInfo(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'exchangeInfo', params, { authIsOptional: true });
}
/*
*
* SPOT - Market data requests
*
*/
/**
* Get current order book
* Note: If you need to continuously monitor order book updates, consider using WebSocket Streams
*/
getSpotOrderBook(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'depth', params, { authIsOptional: true });
}
/**
* Get recent trades
* Note: If you need access to real-time trading activity, consider using WebSocket Streams
*/
getSpotRecentTrades(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'trades.recent', params, { authIsOptional: true });
}
/**
* Get historical trades
* Note: If fromId is not specified, the most recent trades are returned
*/
getSpotHistoricalTrades(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'trades.historical', params, { authIsOptional: true });
}
/**
* Get aggregate trades
* Note: An aggregate trade represents one or more individual trades that fill at the same time
*/
getSpotAggregateTrades(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'trades.aggregate', params, { authIsOptional: true });
}
/**
* Get klines (candlestick bars)
* Note: If you need access to real-time kline updates, consider using WebSocket Streams
*/
getSpotKlines(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'klines', params, { authIsOptional: true });
}
/**
* Get klines (candlestick bars) optimized for presentation
* Note: This request is similar to klines, having the same parameters and response
*/
getSpotUIKlines(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'uiKlines', params, { authIsOptional: true });
}
/**
* Get current average price for a symbol
*/
getSpotAveragePrice(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'avgPrice', params, { authIsOptional: true });
}
/**
* Get 24-hour rolling window price change statistics
* Note: If you need to continuously monitor trading statistics, consider using WebSocket Streams
*/
getSpot24hrTicker(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ticker.24hr', params, { authIsOptional: true });
}
/**
* Get price change statistics for a trading day
*/
getSpotTradingDayTicker(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ticker.tradingDay', params, { authIsOptional: true });
}
/**
* Get rolling window price change statistics with a custom window
* Note: Window size precision is limited to 1 minute
*/
getSpotTicker(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ticker', params, { authIsOptional: true });
}
/**
* Get the latest market price for a symbol
* Note: If you need access to real-time price updates, consider using WebSocket Streams
*/
getSpotSymbolPriceTicker(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ticker.price', params, { authIsOptional: true });
}
/**
* Get the current best price and quantity on the order book
* Note: If you need access to real-time order book ticker updates, consider using WebSocket Streams
*/
getSpotSymbolOrderBookTicker(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'ticker.book', params, { authIsOptional: true });
}
/*
*
* SPOT - Session authentication requests
*
* Note: authentication is automatic
*
*/
getSpotSessionStatus(wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'session.status');
}
/*
*
* SPOT - Trading requests
*
*/
/**
* Submit a spot order
*/
submitNewSpotOrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.place', params);
}
/**
* Test order placement
* Note: Validates new order parameters and verifies your signature but does not send the order into the matching engine
*/
testSpotOrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.test', params);
}
/**
* Check execution status of an order
* Note: If both orderId and origClientOrderId parameters are specified, only orderId is used
*/
getSpotOrderStatus(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.status', params);
}
/**
* Cancel an active order
* Note: If both orderId and origClientOrderId parameters are specified, only orderId is used
*/
cancelSpotOrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.cancel', params);
}
/**
* Cancel an existing order and immediately place a new order
* Note: If both cancelOrderId and cancelOrigClientOrderId parameters are specified, only cancelOrderId is used
*/
cancelReplaceSpotOrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.cancelReplace', params);
}
/**
* Reduce the quantity of an existing open order.
*
* Read for more info: https://developers.binance.com/docs/binance-spot-api-docs/faqs/order_amend_keep_priority
*/
amendSpotOrderKeepPriority(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'order.amend.keepPriority', params);
}
/**
* Query execution status of all open orders
* Note: If you need to continuously monitor order status updates, consider using WebSocket Streams
*/
getSpotOpenOrders(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'openOrders.status', params);
}
/**
* Cancel all open orders on a symbol
* Note: This includes orders that are part of an order list
*/
cancelAllSpotOpenOrders(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'openOrders.cancelAll', params);
}
/**
* Place a new order list
* Note: This is a deprecated endpoint, consider using placeOCOOrderList instead
*/
placeSpotOrderList(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.place', params);
}
/**
* Place a new OCO (One-Cancels-the-Other) order list
* Note: Activation of one order immediately cancels the other
*/
placeSpotOCOOrderList(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.place.oco', params);
}
/**
* Place a new OTO (One-Triggers-the-Other) order list
* Note: The pending order is placed only when the working order is fully filled
*/
placeSpotOTOOrderList(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.place.oto', params);
}
/**
* Place a new OTOCO (One-Triggers-One-Cancels-the-Other) order list
* Note: The pending orders are placed only when the working order is fully filled
*/
placeSpotOTOCOOrderList(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.place.otoco', params);
}
/**
* Check execution status of an order list
* Note: If both origClientOrderId and orderListId parameters are specified, only origClientOrderId is used
*/
getSpotOrderListStatus(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.status', params);
}
/**
* Cancel an active order list
* Note: If both orderListId and listClientOrderId parameters are specified, only orderListId is used
*/
cancelSpotOrderList(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'orderList.cancel', params);
}
/**
* Query execution status of all open order lists
* Note: If you need to continuously monitor order status updates, consider using WebSocket Streams
*/
getSpotOpenOrderLists(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'openOrderLists.status', params);
}
/**
* Place a new order using Smart Order Routing (SOR)
* Note: Only supports LIMIT and MARKET orders. quoteOrderQty is not supported
*/
placeSpotSOROrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'sor.order.place', params);
}
/**
* Test new order creation and signature/recvWindow using Smart Order Routing (SOR)
* Note: Creates and validates a new order but does not send it into the matching engine
*/
testSpotSOROrder(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'sor.order.test', params);
}
/*
*
* SPOT - Account requests
*
*/
/**
* Query information about your account, including balances
* Note: Weight: 20
*/
getSpotAccountInformation(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'account.status', params);
}
/**
* Query your current unfilled order count for all intervals
* Note: Weight: 40
*/
getSpotOrderRateLimits(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'account.rateLimits.orders', params);
}
/**
* Query information about all your orders – active, canceled, filled – filtered by time range
* Note: Weight: 20
*/
getSpotAllOrders(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'allOrders', params);
}
/**
* Query information about all your order lists, filtered by time range
* Note: Weight: 20
*/
getSpotAllOrderLists(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'allOrderLists', params);
}
/**
* Query information about all your trades, filtered by time range
* Note: Weight: 20
*/
getSpotMyTrades(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'myTrades', params);
}
/**
* Displays the list of orders that were expired due to STP
* Note: Weight varies based on query type (2-20)
*/
getSpotPreventedMatches(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'myPreventedMatches', params);
}
/**
* Retrieves allocations resulting from SOR order placement
* Note: Weight: 20
*/
getSpotAllocations(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'myAllocations', params);
}
/**
* Get current account commission rates
* Note: Weight: 20
*/
getSpotAccountCommission(params, wsKey) {
return this.wsClient.sendWSAPIRequest(wsKey || websocket_util_1.WS_KEY_MAP.mainWSAPI, 'account.commission', params);
}
/*
*
* FUTURES - Market data requests
*
*/
/**
* Get current order book for futures
* Note: If you need to continuously monitor order book updates, consider using WebSocket Streams
*/
getFuturesOrderBook(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'depth', params, { authIsOptional: true });
}
/**
* Get latest price for a futures symbol or symbols
* Note: If symbol is not provided, prices for all symbols will be returned
*/
getFuturesSymbolPriceTicker(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'ticker.price', params, { authIsOptional: true });
}
/**
* Get best price/qty on the order book for a futures symbol or symbols
* Note: If symbol is not provided, bookTickers for all symbols will be returned
*/
getFuturesSymbolOrderBookTicker(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'ticker.book', params, { authIsOptional: true });
}
/*
*
* FUTURES - Trading requests
*
*/
/**
* Submit a futures order
*
* This endpoint is used for both USDM and COINM futures.
*/
submitNewFuturesOrder(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'order.place', params);
}
/**
* Modify an existing futures order
*
* This endpoint is used for both USDM and COINM futures.
*/
modifyFuturesOrder(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'order.modify', params);
}
/**
* Cancel a futures order
*
* This endpoint is used for both USDM and COINM futures.
*/
cancelFuturesOrder(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'order.cancel', params);
}
/**
* Query futures order status
*
* This endpoint is used for both USDM and COINM futures.
*/
getFuturesOrderStatus(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'order.status', params);
}
/**
* Get current position information (V2)
* Note: Only symbols that have positions or open orders will be returned
*/
getFuturesPositionV2(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'v2/account.position', params);
}
/**
* Get current position information
* Note: Only symbols that have positions or open orders will be returned
*
* This endpoint is used for both USDM and COINM futures.
*/
getFuturesPosition(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'account.position', params);
}
/*
*
* FUTURES - Account requests
*
*/
/**
* Get account balance information (V2)
* Note: Returns balance information for all assets
*/
getFuturesAccountBalanceV2(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'v2/account.balance', params);
}
/**
* Get account balance information
* Note: Returns balance information for all assets
*
* This endpoint is used for both USDM and COINM futures.
*/
getFuturesAccountBalance(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'account.balance', params);
}
/**
* Get account information (V2)
* Note: Returns detailed account information including positions and assets
*/
getFuturesAccountStatusV2(params) {
return this.wsClient.sendWSAPIRequest(websocket_util_1.WS_KEY_MAP.usdmWSAPI, 'v2/account.status', params);
}
/**
* Get account information
* Note: Returns detailed account information including positions and assets
*
* This endpoint is used for both USDM and COINM futures.
*/
getFuturesAccountStatus(market, params) {
return this.wsClient.sendWSAPIRequest(getFuturesMarketWsKey(market), 'account.status', params);
}
/*
*
* User data stream requests
*
*/
/**
* Start the user data stream for an apiKey (passed as param).
*
* Note: for "Spot" markets, the listenKey workflow is deprecated, use `subscribeUserDataStream()` instead.
*
* @param params
* @param wsKey
* @returns listenKey
*/
startUserDataStreamForKey(params, wsKey = websocket_util_1.WS_KEY_MAP.mainWSAPI) {
return this.wsClient.sendWSAPIRequest(wsKey, 'userDataStream.start', params);
}
/**
* Attempt to "ping" a listen key.
*
* Note: for "Spot" markets, the listenKey workflow is deprecated, use `subscribeUserDataStream()` instead.
*
* @param params
* @param wsKey
* @returns
*/
pingUserDataStreamForKey(params, wsKey = websocket_util_1.WS_KEY_MAP.mainWSAPI) {
return this.wsClient.sendWSAPIRequest(wsKey, 'userDataStream.ping', params);
}
/**
* Stop the user data stream listen key.
*
* @param params
* @param wsKey
* @returns
*/
stopUserDataStreamForKey(params, wsKey = websocket_util_1.WS_KEY_MAP.mainWSAPI) {
return this.wsClient.sendWSAPIRequest(wsKey, 'userDataStream.stop', params);
}
/**
* Request user data stream subscription on the currently authenticated connection.
*
* If reconnected, this will automatically resubscribe unless you unsubscribe manually.
*/
subscribeUserDataStream(wsKey) {
return __awaiter(this, void 0, void 0, function* () {
const resolvedWsKey = this.options.testnet ? (0, websocket_util_1.getTestnetWsKey)(wsKey) : wsKey;
const res = yield this.wsClient.sendWSAPIRequest(resolvedWsKey, 'userDataStream.subscribe');
// Used to track whether this connection had the general "userDataStream.subscribe" called.
// Used as part of `resubscribeUserDataStreamAfterReconnect` to know which connections to resub.
this.subscribedUserDataStreamState[resolvedWsKey] = {
subscribedAt: new Date(),
subscribeAttempt: 0,
};
return res;
});
}
/**
* Unsubscribe from the user data stream subscription on the currently authenticated connection.
*
* If reconnected, this will also stop it from automatically resubscribing after reconnect.
*/
unsubscribeUserDataStream(wsKey) {
const resolvedWsKey = this.options.testnet ? (0, websocket_util_1.getTestnetWsKey)(wsKey) : wsKey;
delete this.subscribedUserDataStreamState[resolvedWsKey];
return this.wsClient.sendWSAPIRequest(resolvedWsKey, 'userDataStream.unsubscribe');
}
/**
*
*
*
*
*
*
*
* Private methods for handling some of the convenience/automation provided by the WS API Client
*
*
*
*
*
*
*
*/
setupDefaultEventListeners() {
if (this.options.attachEventListeners) {
/**
* General event handlers for monitoring the WebsocketClient
*/
this.wsClient
.on('open', (data) => {
console.log(new Date(), 'ws connected', data.wsKey);
})
.on('reconnecting', ({ wsKey }) => {
console.log(new Date(), 'ws automatically reconnecting.... ', wsKey);
})
.on('reconnected', (data) => {
console.log(new Date(), 'ws has reconnected ', data === null || data === void 0 ? void 0 : data.wsKey);
})
.on('authenticated', (data) => {
console.info(new Date(), 'ws has authenticated ', data === null || data === void 0 ? void 0 : data.wsKey);
})
.on('exception', (data) => {
console.error(new Date(), 'ws exception: ', JSON.stringify(data));
});
}
}
tryResubscribeUserDataStream(wsKey) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const subscribeState = this.getSubscribedUserDataStreamState(wsKey);
const respawnDelayInSeconds = this.options.resubscribeUserDataStreamDelaySeconds;
this.logger.error('tryResubscribeUserDataStream(): resubscribing to user data stream....', Object.assign(Object.assign({}, websocket_util_1.WS_LOGGER_CATEGORY), { wsKey }));
try {
if ((_a = this.subscribedUserDataStreamState[wsKey]) === null || _a === void 0 ? void 0 : _a.respawnTimeout) {
clearTimeout(this.subscribedUserDataStreamState[wsKey].respawnTimeout);
delete this.subscribedUserDataStreamState[wsKey].respawnTimeout;
}
subscribeState.subscribeAttempt++;
yield this.subscribeUserDataStream(wsKey);
this.subscribedUserDataStreamState[wsKey] = Object.assign(Object.assign({}, subscribeState), { subscribedAt: new Date(), subscribeAttempt: 0 });
this.logger.info('tryResubscribeUserDataStream()->ok', Object.assign(Object.assign(Object.assign({}, websocket_util_1.WS_LOGGER_CATEGORY), subscribeState), { wsKey }));
}
catch (e) {
this.logger.error('tryResubscribeUserDataStream() exception - retry after timeout', Object.assign(Object.assign({}, websocket_util_1.WS_LOGGER_CATEGORY), { wsKey, exception: e, subscribeState }));
subscribeState.respawnTimeout = setTimeout(() => {
this.tryResubscribeUserDataStream(wsKey);
}, 1000 * respawnDelayInSeconds);
this.subscribedUserDataStreamState[wsKey] = Object.assign({}, subscribeState);
}
});
}
getSubscribedUserDataStreamState(wsKey) {
const subscribedState = this.subscribedUserDataStreamState[wsKey] || {
subscribedAt: new Date(),
subscribeAttempt: 0,
};
return subscribedState;
}
handleWSReconnectedEvent(params) {
var _a;
const wsKey = params.wsKey;
// Not a WS API connection
if (!(0, typeGuards_1.isWSAPIWsKey)(wsKey)) {
return;
}
const fnName = 'handleWSReconnectedEvent()';
// For the workflow without the listen key
if (
// Feature enabled
this.options.resubscribeUserDataStreamAfterReconnect &&
// Was subscribed to user data stream (without listen key)
this.subscribedUserDataStreamState[wsKey]) {
// Delay existing timer, if exists
if ((_a = this.subscribedUserDataStreamState[wsKey]) === null || _a === void 0 ? void 0 : _a.respawnTimeout) {
clearTimeout(this.subscribedUserDataStreamState[wsKey].respawnTimeout);
delete this.subscribedUserDataStreamState[wsKey].respawnTimeout;
this.logger.error(`${fnName} -> resubUserData(): Respawn timer already active while trying to queue respawn...delaying existing timer further...`, Object.assign(Object.assign({}, websocket_util_1.WS_LOGGER_CATEGORY), { wsKey }));
}
this.logger.trace(`${fnName} -> resubUserData():: queued resubscribe for wsKey user data stream`, Object.assign(Object.assign({}, websocket_util_1.WS_LOGGER_CATEGORY), { wsKey }));
// Queue resubscribe workflow
this.subscribedUserDataStreamState[wsKey].respawnTimeout = setTimeout(() => {
this.tryResubscribeUserDataStream(wsKey);
}, 1000 * this.options.resubscribeUserDataStreamDelaySeconds);
}
}
}
exports.WebsocketAPIClient = WebsocketAPIClient;
//# sourceMappingURL=websocket-api-client.js.map