Example: ws-userdata-listenkey.ts
Static snapshot for Binance/WebSockets/Private(userdata)/ws-userdata-listenkey.ts.
Example Path
Binance/WebSockets/Private(userdata)/ws-userdata-listenkey.ts
Source Link
Repository source: https://github.com/sieblyio/crypto-api-examples/blob/master/examples/Binance/WebSockets/Private(userdata)/ws-userdata-listenkey.ts
Code Snapshot
// or
// import {
// DefaultLogger,
// isWsFormattedFuturesUserDataEvent,
// isWsFormattedSpotUserDataEvent,
// isWsFormattedSpotUserDataExecutionReport,
// isWsFormattedUserDataEvent,
// WebsocketClient,
// WsUserDataEvents,
// } from 'binance';
import {
DefaultLogger,
isWsFormattedFuturesUserDataEvent,
isWsFormattedSpotUserDataEvent,
isWsFormattedSpotUserDataExecutionReport,
isWsFormattedUserDataEvent,
WebsocketClient,
WsConnectionStateEnum,
WsUserDataEvents,
} from 'binance';
(async () => {
const key = process.env.API_KEY_COM || 'APIKEY';
const secret = process.env.API_SECRET_COM || 'APISECRET';
console.log({ key, secret });
const ignoredTraceLogMsgs = [
'Sending ping',
'Received ping frame, sending pong frame',
'Received pong frame, clearing pong timer',
];
// Optional, hook and customise logging behavior
const logger = {
...DefaultLogger,
trace: (msg: string, context?: any) => {
if (ignoredTraceLogMsgs.includes(msg)) {
return;
}
console.log(JSON.stringify({ msg, context }));
},
};
const wsClient = new WebsocketClient(
{
api_key: key,
api_secret: secret,
beautify: true,
// testnet: true,
},
logger,
);
// wsClient.on('message', (data) => {
// console.log('raw message received ', JSON.stringify(data, null, 2));
// });
function onUserDataEvent(data: WsUserDataEvents) {
// the market denotes which API category it came from
// if (data.wsMarket.includes('spot')) {
// or use a type guard, if one exists (PRs welcome)
if (isWsFormattedSpotUserDataExecutionReport(data)) {
console.log('spot user execution report event: ', data);
return;
}
if (isWsFormattedSpotUserDataEvent(data)) {
console.log('spot user data event: ', data);
return;
}
if (data.wsMarket.includes('margin')) {
console.log('margin user data event: ', data);
return;
}
if (data.wsMarket.includes('isolatedMargin')) {
console.log('isolatedMargin user data event: ', data);
return;
}
if (data.wsMarket.includes('usdmTestnet')) {
console.log('usdmTestnet user data event: ', data);
return;
}
if (data.wsMarket.includes('coinmTestnet')) {
console.log('coinmTestnet user data event: ', data);
return;
}
if (isWsFormattedFuturesUserDataEvent(data)) {
console.log('usdm user data event: ', data);
return;
}
console.log(
'onUserDataEvent()->unhandled: ',
JSON.stringify(data, null, 2),
);
}
wsClient.on('formattedMessage', (data) => {
// The wsKey can be parsed to determine the type of message (what websocket it came from)
// if (!Array.isArray(data) && data.wsKey.includes('userData')) {
// return onUserDataEvent(data);
// }
// or use a type guard if available
if (isWsFormattedUserDataEvent(data)) {
return onUserDataEvent(data);
}
console.log('formattedMsg: ', JSON.stringify(data, null, 2));
});
wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey, data.wsUrl);
});
// response to command sent via WS stream (e.g LIST_SUBSCRIPTIONS)
wsClient.on('response', (data) => {
console.log('log response: ', JSON.stringify(data, null, 2));
});
wsClient.on('reconnecting', (data) => {
console.log('ws automatically reconnecting.... ', data?.wsKey);
});
wsClient.on('reconnected', (data) => {
if (
typeof data?.wsKey === 'string' &&
data.wsKey.toLowerCase().includes('userdata')
) {
console.log('ws for user data stream has reconnected ', data?.wsKey);
// This is a good place to check your own state is still in sync with the account state on the exchange, in case any events were missed while the library was reconnecting:
// - fetch balances
// - fetch positions
// - fetch orders
} else {
console.log('ws has reconnected ', data?.wsKey);
}
});
wsClient.on('exception', (data) => {
console.error('ws saw error: ', data);
});
/**
* This example demonstrates subscribing to the user data stream via the
* listen key workflow.
*
* Note: the listen key workflow is deprecated for "spot" markets. Use the
* WebSocket API `userDataStream.subscribe` workflow instead (only available
* in spot right now). See `subscribeUserDataStream()` in the WebsocketAPIClient.
*
* Each method below opens a dedicated WS connection attached to an automatically
* fetched listen key (a session for your user data stream).
*
* Once subscribed, you don't need to do anything else. Listen-key keep-alive, refresh, reconnects, etc are all automatically handled by the SDK.
*/
// Example 1: Spot, by default, routes to the "main" wss domain "wss://stream.binance.com:9443".
// No parameters needed, just call the subscribe function.
wsClient.subscribeSpotUserDataStream();
// // Example 2: Optional: subscribe to spot via other wss domains
wsClient.subscribeSpotUserDataStream('main2'); // routed to "wss://stream.binance.com:443"
// // Example 3: cross margin
wsClient.subscribeCrossMarginUserDataStream();
// Example 4: isolated margin
wsClient.subscribeIsolatedMarginUserDataStream('BTCUSDC');
/**
* Futures
*/
// Example 5: usdm futures
wsClient.subscribeUsdFuturesUserDataStream();
// Example 6: coinm futures
wsClient.subscribeCoinFuturesUserDataStream();
// Example 7: portfolio margin
// wsClient.subscribePortfolioMarginUserDataStream();
// Example 8: portfolio margin pro
// wsClient.subscribePortfolioMarginUserDataStream('portfolioMarginProUserData');
// after 15 seconds, kill user data connections one by one (or all at once)
setTimeout(() => {
// console.log('killing all connections at once');
// wsClient.closeAll();
// or:
console.log('killing individual connections');
try {
// console.log('killing all connections');
// wsClient.closeAll();
// Example 1:
wsClient.unsubscribeSpotUserDataStream();
// Example 2: use the wsKey to route to another domain
wsClient.unsubscribeSpotUserDataStream('main2');
// Example 3: cross margin
wsClient.unsubscribeCrossMarginUserDataStream();
// Example 4: isolated margin
wsClient.unsubscribeIsolatedMarginUserDataStream('BTCUSDC');
// Example 5: usdm futures
wsClient.unsubscribeUsdFuturesUserDataStream();
// Example 6: coinm futures
wsClient.unsubscribeCoinFuturesUserDataStream();
// // Example 7: portfolio margin
// wsClient.unsubscribePortfolioMarginUserDataStream();
// // Example 8: portfolio margin pro
// wsClient.unsubscribePortfolioMarginUserDataStream(
// 'portfolioMarginProUserData',
// );
} catch (e) {
console.error('Exception trying to close a user data stream: ', e);
}
}, 1000 * 15);
// after 20 seconds, list the remaining open connections
setTimeout(() => {
try {
console.log(
'remaining connections:',
wsClient
.getWsStore()
.getKeys()
.filter(
(key) =>
wsClient.getWsStore().get(key)?.connectionState ===
WsConnectionStateEnum.CONNECTED,
),
);
} catch (e) {
console.error('Exception trying to close a user data stream: ', e);
}
}, 1000 * 20);
})();
This is a static, crawlable snapshot. The interactive app loads after JavaScript starts and can refresh live data.