binance
Version:
Professional Node.js & JavaScript SDK for Binance REST APIs & WebSockets, with TypeScript & end-to-end tests.
310 lines • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.neverGuard = neverGuard;
exports.isWsSpotConnection = isWsSpotConnection;
exports.isWsFuturesConnection = isWsFuturesConnection;
exports.isWSAPIWsKey = isWSAPIWsKey;
exports.isWsFormattedMarkPriceUpdateEvent = isWsFormattedMarkPriceUpdateEvent;
exports.isWsFormattedMarkPriceUpdateArray = isWsFormattedMarkPriceUpdateArray;
exports.isWsFormattedMarkPriceUpdate = isWsFormattedMarkPriceUpdate;
exports.isWsFormattedTrade = isWsFormattedTrade;
exports.isWsFormattedKline = isWsFormattedKline;
exports.isWsFormatted24hrTicker = isWsFormatted24hrTicker;
exports.isWsFormattedForceOrder = isWsFormattedForceOrder;
exports.isWsFormatted24hrTickerArray = isWsFormatted24hrTickerArray;
exports.isWsFormattedRollingWindowTickerArray = isWsFormattedRollingWindowTickerArray;
exports.isWsAggTradeFormatted = isWsAggTradeFormatted;
exports.isWsPartialBookDepthEventFormatted = isWsPartialBookDepthEventFormatted;
exports.isWsDiffBookDepthEventFormatted = isWsDiffBookDepthEventFormatted;
exports.isWsFormattedUserDataEvent = isWsFormattedUserDataEvent;
exports.isWsFormattedSpotUserDataEvent = isWsFormattedSpotUserDataEvent;
exports.isWsFormattedFuturesUserDataEvent = isWsFormattedFuturesUserDataEvent;
exports.isWsFormattedSpotUserDataExecutionReport = isWsFormattedSpotUserDataExecutionReport;
exports.isWsFormattedSpotOutboundAccountPosition = isWsFormattedSpotOutboundAccountPosition;
exports.isWsFormattedSpotBalanceUpdate = isWsFormattedSpotBalanceUpdate;
exports.isWsFormattedSpotUserDataListStatusEvent = isWsFormattedSpotUserDataListStatusEvent;
exports.isWsFormattedFuturesUserDataAccountUpdate = isWsFormattedFuturesUserDataAccountUpdate;
exports.isWsFormattedFuturesUserDataMarginCall = isWsFormattedFuturesUserDataMarginCall;
exports.isWsFormattedFuturesUserDataTradeUpdateEvent = isWsFormattedFuturesUserDataTradeUpdateEvent;
exports.isWsFormattedFuturesUserDataCondOrderTriggerRejectEvent = isWsFormattedFuturesUserDataCondOrderTriggerRejectEvent;
exports.isWsFormattedFuturesUserDataAccountConfigUpdateEvent = isWsFormattedFuturesUserDataAccountConfigUpdateEvent;
exports.isWsFormattedFuturesUserDataListenKeyExpired = isWsFormattedFuturesUserDataListenKeyExpired;
exports.isAll24hrMiniTickerRaw = isAll24hrMiniTickerRaw;
exports.isAllRollingWindowTickerRaw = isAllRollingWindowTickerRaw;
exports.is24hrMiniTickerRaw = is24hrMiniTickerRaw;
exports.isKlineRaw = isKlineRaw;
exports.isOrderTradeUpdateRaw = isOrderTradeUpdateRaw;
exports.isAccountConfigUpdateRaw = isAccountConfigUpdateRaw;
exports.isAccountUpdateRaw = isAccountUpdateRaw;
exports.isTopicSubscriptionConfirmation = isTopicSubscriptionConfirmation;
exports.isTopicSubscriptionSuccess = isTopicSubscriptionSuccess;
const websocket_util_1 = require("./websockets/websocket-util");
function neverGuard(x, msg) {
return new Error(`Unhandled value exception "${x}", ${msg}`);
}
/**
* Use type guards to narrow down types with minimal efforts.
*
* The file is organised by Typeguards starting with `WsFormattedMessage` typeguards in the first half
* and `WsRawMessage` typeguards in the second half.
*
*/
function isWsSpotConnection(data) {
return (!Array.isArray(data) && data.wsKey && websocket_util_1.WS_KEYS_SPOT.includes(data.wsKey));
}
function isWsFuturesConnection(data) {
return (!Array.isArray(data) && data.wsKey && websocket_util_1.WS_KEYS_FUTURES.includes(data.wsKey));
}
function isWSAPIWsKey(wsKey) {
switch (wsKey) {
case 'mainWSAPITestnet':
case 'mainWSAPI':
case 'mainWSAPI2':
case 'usdmWSAPI':
case 'usdmWSAPITestnet':
case 'coinmWSAPI':
case 'coinmWSAPITestnet': {
return true;
}
case 'main':
case 'main2':
case 'main3':
case 'marginRiskUserData':
case 'mainTestnetPublic':
case 'mainTestnetUserData':
case 'usdm':
case 'usdmTestnet':
case 'coinm':
case 'coinmTestnet':
case 'eoptions':
case 'coinm2':
case 'portfolioMarginUserData':
case 'portfolioMarginProUserData': {
return false;
}
default: {
throw neverGuard(wsKey, `Unhandled WsKey "${wsKey}"`);
}
}
}
/**
* Typeguards for WsFormattedMessage event types:
*/
function isWsFormattedMarkPriceUpdateEvent(data) {
return !Array.isArray(data) && data.eventType === 'markPriceUpdate';
}
function isWsFormattedMarkPriceUpdateArray(data) {
return (Array.isArray(data) &&
data.length !== 0 &&
['markPriceUpdate', 'markPrice'].includes(data[0].eventType));
}
/** @deprecated, use isWsFormattedMarkPriceUpdateEvent or isWsFormattedMarkPriceUpdateArray */
function isWsFormattedMarkPriceUpdate(data) {
return isWsFormattedMarkPriceUpdateArray(data);
}
function isWsFormattedTrade(data) {
return !Array.isArray(data) && data.eventType === 'trade';
}
function isWsFormattedKline(data) {
return !Array.isArray(data) && data.eventType === 'kline';
}
function isWsFormatted24hrTicker(data) {
return !Array.isArray(data) && data.eventType === '24hrTicker';
}
function isWsFormattedForceOrder(data) {
return !Array.isArray(data) && data.eventType === 'forceOrder';
}
/**
* !ticker@arr
*
* @deprecated The '!ticker@arr' stream has been deprecated by Binance (2025-11-14).
* Use '<symbol>@ticker' for single symbol or '!miniTicker@arr' for all symbols instead.
*
* @param data
* @returns
*/
function isWsFormatted24hrTickerArray(data) {
return (Array.isArray(data) &&
data.length !== 0 &&
// topic in ws url
(['24hrTicker'].includes(data[0].eventType) || // multiplex subscriptions
(!!data[0].streamName && ['!ticker@arr'].includes(data[0].streamName))));
}
/**
* !ticker_1h@arr
*
* @param data
* @returns
*/
function isWsFormattedRollingWindowTickerArray(data) {
return (Array.isArray(data) &&
data.length !== 0 &&
// topic in ws url
(['1hTicker', '4hTicker', '1dTicker'].includes(data[0].eventType) ||
// multiplex subscriptions
(!!data[0].streamName &&
['!ticker_1h@arr', '!ticker_4h@arr', '!ticker_1d@arr'].includes(data[0].streamName))));
}
/**
* Typeguard to validate a 'Compressed/Aggregate' trade
*/
function isWsAggTradeFormatted(data) {
return !Array.isArray(data) && data.eventType === 'aggTrade';
}
const partialBookDepthEventTypeMap = new Map()
// For dedicated connection
.set('partialBookDepth', true)
// For multiplex connection
.set('depth5', true)
.set('depth10', true)
.set('depth20', true)
.set('depth5@100ms', true)
.set('depth10@100ms', true)
.set('depth20@100ms', true)
.set('depth5@1000ms', true)
.set('depth10@1000ms', true)
.set('depth20@1000ms', true);
/**
* <symbol>@depth<levels> OR <symbol>@depth<levels>@100ms
* @param data
* @returns
*/
function isWsPartialBookDepthEventFormatted(data) {
return (!Array.isArray(data) && partialBookDepthEventTypeMap.has(data.eventType));
}
/**
* https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Diff-Book-Depth-Streams
* <symbol>@depth OR <symbol>@depth@500ms OR <symbol>@depth@100ms
*/
function isWsDiffBookDepthEventFormatted(data) {
return !Array.isArray(data) && data.eventType === 'depthUpdate';
}
/**
* Works for both the listen key & WS API user data stream workflows.
*
* - For the listen key workflow, uses the wsKey to identify the connection dedicated
* to the user data stream.
* - For the WS API user data stream, uses the eventType to identify user data events
* from a known list (`EVENT_TYPES_USER_DATA`).
*/
function isWsFormattedUserDataEvent(data) {
if (Array.isArray(data)) {
return false;
}
// Old listenKey workflow has one dedicated connection per user data stream
// Won't work for new WS API user data stream without listen key
if (data.wsKey.includes('userData')) {
return true;
}
if ((data === null || data === void 0 ? void 0 : data.eventType) && websocket_util_1.EVENT_TYPES_USER_DATA.includes(data.eventType)) {
return true;
}
return false;
}
function isWsFormattedSpotUserDataEvent(data) {
var _a;
return (isWsFormattedUserDataEvent(data) &&
(((_a = data.wsMarket) === null || _a === void 0 ? void 0 : _a.includes('spot')) || isWsSpotConnection(data)));
}
function isWsFormattedFuturesUserDataEvent(data) {
var _a;
return (isWsFormattedUserDataEvent(data) &&
(((_a = data.wsMarket) === null || _a === void 0 ? void 0 : _a.includes('usdm')) || isWsFuturesConnection(data)));
}
function isWsFormattedSpotUserDataExecutionReport(data) {
return (isWsFormattedSpotUserDataEvent(data) && data.eventType === 'executionReport');
}
function isWsFormattedSpotOutboundAccountPosition(data) {
return (isWsFormattedSpotUserDataEvent(data) &&
data.eventType === 'outboundAccountPosition');
}
function isWsFormattedSpotBalanceUpdate(data) {
return (isWsFormattedSpotUserDataEvent(data) && data.eventType === 'balanceUpdate');
}
function isWsFormattedSpotUserDataListStatusEvent(data) {
return (isWsFormattedSpotUserDataEvent(data) && data.eventType === 'listStatus');
}
function isWsFormattedFuturesUserDataAccountUpdate(data) {
return (isWsFormattedFuturesUserDataEvent(data) &&
data.eventType === 'ACCOUNT_UPDATE');
}
function isWsFormattedFuturesUserDataMarginCall(data) {
return (isWsFormattedFuturesUserDataEvent(data) && data.eventType === 'MARGIN_CALL');
}
function isWsFormattedFuturesUserDataTradeUpdateEvent(data) {
return (isWsFormattedFuturesUserDataEvent(data) &&
data.eventType === 'ORDER_TRADE_UPDATE');
}
function isWsFormattedFuturesUserDataCondOrderTriggerRejectEvent(data) {
return (isWsFormattedFuturesUserDataEvent(data) &&
data.eventType === 'CONDITIONAL_ORDER_TRIGGER_REJECT');
}
function isWsFormattedFuturesUserDataAccountConfigUpdateEvent(data) {
return (isWsFormattedFuturesUserDataEvent(data) &&
data.eventType === 'ACCOUNT_CONFIG_UPDATE');
}
function isWsFormattedFuturesUserDataListenKeyExpired(data) {
return (isWsFormattedFuturesUserDataEvent(data) &&
data.eventType === 'listenKeyExpired');
}
/**
* Typeguards for WsRawMessage event types:
*/
/**
* Typeguard to validate all symbol 24hrMiniTicker raw event
*/
function isAll24hrMiniTickerRaw(data) {
return Array.isArray(data) && data[0].e === '24hrMiniTicker';
}
function isAllRollingWindowTickerRaw(data) {
return (Array.isArray(data) &&
['1hTicker', '4hTicker', '1dTicker'].includes(data[0].e));
}
/**
* Typeguard to validate a single 24hrMiniTicker raw event
*/
function is24hrMiniTickerRaw(data) {
return !Array.isArray(data) && data.e === '24hrMiniTicker';
}
/**
* Typeguard to validate a single kline raw event
*/
function isKlineRaw(data) {
return !Array.isArray(data) && data.e === 'kline';
}
/**
* Typeguard to validate a single ORDER_TRADE_UPDATE raw event
*/
function isOrderTradeUpdateRaw(data) {
return !Array.isArray(data) && data.e === 'ORDER_TRADE_UPDATE';
}
/**
* Typeguard to validate a single ACCOUNT_CONFIG_UPDATE raw event
*/
function isAccountConfigUpdateRaw(data) {
return !Array.isArray(data) && data.e === 'ACCOUNT_CONFIG_UPDATE';
}
/**
* Typeguard to validate a single ACCOUNT_UPDATE raw event
*/
function isAccountUpdateRaw(data) {
return !Array.isArray(data) && data.e === 'ACCOUNT_UPDATE';
}
function isTopicSubscriptionConfirmation(msg) {
if (typeof msg !== 'object') {
return false;
}
if (!msg) {
return false;
}
if (typeof msg['result'] === 'boolean') {
return false;
}
return false;
}
function isTopicSubscriptionSuccess(msg) {
if (!isTopicSubscriptionConfirmation(msg))
return false;
return msg.result === true;
}
//# sourceMappingURL=typeGuards.js.map