Binance Private Userdata JavaScript SDK example: ws-userdata-connection-safety.ts

Binance Private Userdata websocket userdata connection safety JavaScript example for the Siebly Binance SDK, covering exchange REST API and WebSocket integration, setup, and production SDK docs.

We use environment variables in our examples for API keys. It is your responsibility to manage and secure your keys appropriately.

examples/Binance/WebSockets/Private(userdata)/ws-userdata-connection-safety.ts

What this example covers

  • Binance WebSocket stream JavaScript example.
  • Uses the Siebly Binance SDK package binance instead of hand-written WebSocket plumbing.
  • Source path: Binance/WebSockets/Private(userdata)/ws-userdata-connection-safety.ts.
  • Example category: Private Userdata.
  • Imports SDK symbols including DefaultLogger, WebsocketClient.
  • Calls SDK methods such as on(), subscribeSpotUserDataStream(), subscribeUsdFuturesUserDataStream(), subscribeMarginUserDataStream(), subscribeIsolatedMarginUserDataStream().

How to use this example

  • Start here for the specific request or stream pattern, then check the matching SDK guide for install, credentials, and operational notes.
  • For WebSocket examples, keep reconnect, resubscribe, heartbeat, and event-handler behavior explicit in your service.
  • Open the repository source when you need the latest committed version: GitHub source file.
import {  DefaultLogger,  isWsFormattedFuturesUserDataEvent,  isWsFormattedSpotUserDataEvent,  isWsFormattedSpotUserDataExecutionReport,  isWsFormattedUserDataEvent,  WebsocketClient,  WsUserDataEvents,} from 'binance'; /** * This extended example for using the user data stream demonstrates one way to handle failures in the first connection attempt of the user data stream. * In most cases this is overkill! */(async () => {  const key = process.env.API_KEY_COM || 'APIKEY';  const secret = process.env.API_SECRET_COM || 'APISECRET';   // optionally block some silly logs from showing in the logger  const ignoredTraceLogMsgs = [    'Sending ping',    'Received pong, clearing pong timer',    'Received ping, sending pong frame',  ];   // 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,    },    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;    }  }   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));  });   let didConnectUserDataSuccessfully = false;  wsClient.on('open', (data) => {    if (data.wsKey.includes('userData')) {      didConnectUserDataSuccessfully = true;    }    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 reply: ', JSON.stringify(data, null, 2));  });  wsClient.on('reconnecting', (data) => {    console.log('ws automatically reconnecting.... ', data?.wsKey);  });  wsClient.on('reconnected', (data) => {    console.log('ws has reconnected ', data?.wsKey);  });  wsClient.on('exception', (data) => {    console.error('ws saw error: ', data);     // Note: manually re-subscribing like this may only be needed if the FIRST user data connection attempt failed    // Capture exceptions using the error event, and handle this.    if (!didConnectUserDataSuccessfully && data.wsKey.includes('userData')) {      setTimeout(() => {        console.warn(          `Retrying connection to userdata ws ${data.wsKey} in 1 second...`,        );        if (data.wsKey.includes('spot')) {          wsClient.subscribeSpotUserDataStream();        } else if (data.wsKey.includes('usdm')) {          wsClient.subscribeUsdFuturesUserDataStream();        }      }, 1000);    }  });   wsClient.subscribeSpotUserDataStream();  // wsClient.subscribeMarginUserDataStream();  // wsClient.subscribeIsolatedMarginUserDataStream('BTCUSDT');  wsClient.subscribeUsdFuturesUserDataStream();})(); 

Subscribe on Substack

Complete the Substack form below to join our newsletter. Substack handles all subscriber data directly.