@binance/common 1.1.3 → 1.2.1

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/index.mjs CHANGED
@@ -1,254 +1,3 @@
1
- // src/configuration.ts
2
- var ConfigurationRestAPI = class {
3
- constructor(param = { apiKey: "" }) {
4
- this.apiKey = param.apiKey;
5
- this.apiSecret = param.apiSecret;
6
- this.basePath = param.basePath;
7
- this.keepAlive = param.keepAlive ?? true;
8
- this.compression = param.compression ?? true;
9
- this.retries = param.retries ?? 3;
10
- this.backoff = param.backoff ?? 1e3;
11
- this.privateKey = param.privateKey;
12
- this.privateKeyPassphrase = param.privateKeyPassphrase;
13
- this.timeUnit = param.timeUnit;
14
- this.baseOptions = {
15
- timeout: param.timeout ?? 1e3,
16
- proxy: param.proxy && {
17
- host: param.proxy.host,
18
- port: param.proxy.port,
19
- auth: param.proxy.auth
20
- },
21
- httpsAgent: param.httpsAgent ?? false,
22
- headers: {
23
- "Content-Type": "application/json",
24
- "X-MBX-APIKEY": param.apiKey
25
- }
26
- };
27
- }
28
- };
29
- var ConfigurationWebsocketAPI = class {
30
- constructor(param = { apiKey: "" }) {
31
- this.apiKey = param.apiKey;
32
- this.apiSecret = param.apiSecret;
33
- this.wsURL = param.wsURL;
34
- this.timeout = param.timeout ?? 5e3;
35
- this.reconnectDelay = param.reconnectDelay ?? 5e3;
36
- this.compression = param.compression ?? true;
37
- this.agent = param.agent ?? false;
38
- this.mode = param.mode ?? "single";
39
- this.poolSize = param.poolSize ?? 1;
40
- this.privateKey = param.privateKey;
41
- this.privateKeyPassphrase = param.privateKeyPassphrase;
42
- this.timeUnit = param.timeUnit;
43
- }
44
- };
45
- var ConfigurationWebsocketStreams = class {
46
- constructor(param = {}) {
47
- this.wsURL = param.wsURL;
48
- this.reconnectDelay = param.reconnectDelay ?? 5e3;
49
- this.compression = param.compression ?? true;
50
- this.agent = param.agent ?? false;
51
- this.mode = param.mode ?? "single";
52
- this.poolSize = param.poolSize ?? 1;
53
- this.timeUnit = param.timeUnit;
54
- }
55
- };
56
-
57
- // src/constants.ts
58
- var TimeUnit = {
59
- MILLISECOND: "MILLISECOND",
60
- millisecond: "millisecond",
61
- MICROSECOND: "MICROSECOND",
62
- microsecond: "microsecond"
63
- };
64
- var ALGO_REST_API_PROD_URL = "https://api.binance.com";
65
- var AUTO_INVEST_REST_API_PROD_URL = "https://api.binance.com";
66
- var C2C_REST_API_PROD_URL = "https://api.binance.com";
67
- var CONVERT_REST_API_PROD_URL = "https://api.binance.com";
68
- var COPY_TRADING_REST_API_PROD_URL = "https://api.binance.com";
69
- var CRYPTO_LOAN_REST_API_PROD_URL = "https://api.binance.com";
70
- var DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL = "https://dapi.binance.com";
71
- var DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
72
- var DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL = "wss://ws-dapi.binance.com/ws-dapi/v1";
73
- var DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-dapi/v1";
74
- var DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL = "wss://dstream.binance.com";
75
- var DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL = "wss://dstream.binancefuture.com";
76
- var DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL = "https://fapi.binance.com";
77
- var DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
78
- var DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL = "wss://ws-fapi.binance.com/ws-fapi/v1";
79
- var DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1";
80
- var DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
81
- var DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL = "wss://stream.binancefuture.com";
82
- var DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL = "https://eapi.binance.com";
83
- var DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL = "wss://nbstream.binance.com/eoptions";
84
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL = "https://papi.binance.com";
85
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
86
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm";
87
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL = "wss://fstream.binancefuture.com/pm";
88
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL = "https://api.binance.com";
89
- var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm-classic";
90
- var DUAL_INVESTMENT_REST_API_PROD_URL = "https://api.binance.com";
91
- var FIAT_REST_API_PROD_URL = "https://api.binance.com";
92
- var GIFT_CARD_REST_API_PROD_URL = "https://api.binance.com";
93
- var MARGIN_TRADING_REST_API_PROD_URL = "https://api.binance.com";
94
- var MARGIN_TRADING_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443";
95
- var MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL = "wss://margin-stream.binance.com";
96
- var MINING_REST_API_PROD_URL = "https://api.binance.com";
97
- var NFT_REST_API_PROD_URL = "https://api.binance.com";
98
- var PAY_REST_API_PROD_URL = "https://api.binance.com";
99
- var REBATE_REST_API_PROD_URL = "https://api.binance.com";
100
- var SIMPLE_EARN_REST_API_PROD_URL = "https://api.binance.com";
101
- var SPOT_REST_API_PROD_URL = "https://api.binance.com";
102
- var SPOT_REST_API_TESTNET_URL = "https://testnet.binance.vision";
103
- var SPOT_WS_API_PROD_URL = "wss://ws-api.binance.com:443/ws-api/v3";
104
- var SPOT_WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3";
105
- var SPOT_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443";
106
- var SPOT_WS_STREAMS_TESTNET_URL = "wss://stream.testnet.binance.vision";
107
- var SPOT_REST_API_MARKET_URL = "https://data-api.binance.vision";
108
- var SPOT_WS_STREAMS_MARKET_URL = "wss://data-stream.binance.vision";
109
- var STAKING_REST_API_PROD_URL = "https://api.binance.com";
110
- var SUB_ACCOUNT_REST_API_PROD_URL = "https://api.binance.com";
111
- var VIP_LOAN_REST_API_PROD_URL = "https://api.binance.com";
112
- var WALLET_REST_API_PROD_URL = "https://api.binance.com";
113
-
114
- // src/errors.ts
115
- var ConnectorClientError = class _ConnectorClientError extends Error {
116
- constructor(msg) {
117
- super(msg || "An unexpected error occurred.");
118
- Object.setPrototypeOf(this, _ConnectorClientError.prototype);
119
- this.name = "ConnectorClientError";
120
- }
121
- };
122
- var RequiredError = class _RequiredError extends Error {
123
- constructor(field, msg) {
124
- super(msg || `Required parameter ${field} was null or undefined.`);
125
- this.field = field;
126
- Object.setPrototypeOf(this, _RequiredError.prototype);
127
- this.name = "RequiredError";
128
- }
129
- };
130
- var UnauthorizedError = class _UnauthorizedError extends Error {
131
- constructor(msg) {
132
- super(msg || "Unauthorized access. Authentication required.");
133
- Object.setPrototypeOf(this, _UnauthorizedError.prototype);
134
- this.name = "UnauthorizedError";
135
- }
136
- };
137
- var ForbiddenError = class _ForbiddenError extends Error {
138
- constructor(msg) {
139
- super(msg || "Access to the requested resource is forbidden.");
140
- Object.setPrototypeOf(this, _ForbiddenError.prototype);
141
- this.name = "ForbiddenError";
142
- }
143
- };
144
- var TooManyRequestsError = class _TooManyRequestsError extends Error {
145
- constructor(msg) {
146
- super(msg || "Too many requests. You are being rate-limited.");
147
- Object.setPrototypeOf(this, _TooManyRequestsError.prototype);
148
- this.name = "TooManyRequestsError";
149
- }
150
- };
151
- var RateLimitBanError = class _RateLimitBanError extends Error {
152
- constructor(msg) {
153
- super(msg || "The IP address has been banned for exceeding rate limits.");
154
- Object.setPrototypeOf(this, _RateLimitBanError.prototype);
155
- this.name = "RateLimitBanError";
156
- }
157
- };
158
- var ServerError = class _ServerError extends Error {
159
- constructor(msg, statusCode) {
160
- super(msg || "An internal server error occurred.");
161
- this.statusCode = statusCode;
162
- Object.setPrototypeOf(this, _ServerError.prototype);
163
- this.name = "ServerError";
164
- }
165
- };
166
- var NetworkError = class _NetworkError extends Error {
167
- constructor(msg) {
168
- super(msg || "A network error occurred.");
169
- Object.setPrototypeOf(this, _NetworkError.prototype);
170
- this.name = "NetworkError";
171
- }
172
- };
173
- var NotFoundError = class _NotFoundError extends Error {
174
- constructor(msg) {
175
- super(msg || "The requested resource was not found.");
176
- Object.setPrototypeOf(this, _NotFoundError.prototype);
177
- this.name = "NotFoundError";
178
- }
179
- };
180
- var BadRequestError = class _BadRequestError extends Error {
181
- constructor(msg) {
182
- super(msg || "The request was invalid or cannot be otherwise served.");
183
- Object.setPrototypeOf(this, _BadRequestError.prototype);
184
- this.name = "BadRequestError";
185
- }
186
- };
187
-
188
- // src/logger.ts
189
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
190
- LogLevel2["NONE"] = "";
191
- LogLevel2["DEBUG"] = "debug";
192
- LogLevel2["INFO"] = "info";
193
- LogLevel2["WARN"] = "warn";
194
- LogLevel2["ERROR"] = "error";
195
- return LogLevel2;
196
- })(LogLevel || {});
197
- var Logger = class _Logger {
198
- constructor() {
199
- this.minLogLevel = "info" /* INFO */;
200
- this.levelsOrder = [
201
- "" /* NONE */,
202
- "debug" /* DEBUG */,
203
- "info" /* INFO */,
204
- "warn" /* WARN */,
205
- "error" /* ERROR */
206
- ];
207
- }
208
- static getInstance() {
209
- if (!_Logger.instance) {
210
- _Logger.instance = new _Logger();
211
- }
212
- return _Logger.instance;
213
- }
214
- setMinLogLevel(level) {
215
- if (!this.isValidLogLevel(level)) {
216
- throw new Error(`Invalid log level: ${level}`);
217
- }
218
- this.minLogLevel = level;
219
- }
220
- isValidLogLevel(level) {
221
- return this.levelsOrder.includes(level);
222
- }
223
- log(level, ...message) {
224
- if (level === "" /* NONE */ || !this.allowLevelLog(level)) {
225
- return;
226
- }
227
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
228
- console[level](`[${timestamp}] [${level.toLowerCase()}]`, ...message);
229
- }
230
- allowLevelLog(level) {
231
- if (!this.isValidLogLevel(level)) {
232
- throw new Error(`Invalid log level: ${level}`);
233
- }
234
- const currentLevelIndex = this.levelsOrder.indexOf(level);
235
- const minLevelIndex = this.levelsOrder.indexOf(this.minLogLevel);
236
- return currentLevelIndex >= minLevelIndex;
237
- }
238
- debug(...message) {
239
- this.log("debug" /* DEBUG */, ...message);
240
- }
241
- info(...message) {
242
- this.log("info" /* INFO */, ...message);
243
- }
244
- warn(...message) {
245
- this.log("warn" /* WARN */, ...message);
246
- }
247
- error(...message) {
248
- this.log("error" /* ERROR */, ...message);
249
- }
250
- };
251
-
252
1
  // src/utils.ts
253
2
  import crypto from "crypto";
254
3
  import fs from "fs";
@@ -467,141 +216,431 @@ var httpRequestFunction = async function(axiosArgs, configuration) {
467
216
  }
468
217
  }
469
218
  }
470
- throw lastError;
219
+ throw lastError;
220
+ };
221
+ var parseRateLimitHeaders = function(headers) {
222
+ const rateLimits = [];
223
+ const parseIntervalDetails = (key) => {
224
+ const match = key.match(/x-mbx-used-weight-(\d+)([smhd])|x-mbx-order-count-(\d+)([smhd])/i);
225
+ if (!match) return null;
226
+ const intervalNum = parseInt(match[1] || match[3], 10);
227
+ const intervalLetter = (match[2] || match[4])?.toUpperCase();
228
+ let interval;
229
+ switch (intervalLetter) {
230
+ case "S":
231
+ interval = "SECOND";
232
+ break;
233
+ case "M":
234
+ interval = "MINUTE";
235
+ break;
236
+ case "H":
237
+ interval = "HOUR";
238
+ break;
239
+ case "D":
240
+ interval = "DAY";
241
+ break;
242
+ default:
243
+ return null;
244
+ }
245
+ return { interval, intervalNum };
246
+ };
247
+ for (const [key, value] of Object.entries(headers)) {
248
+ const normalizedKey = key.toLowerCase();
249
+ if (value === void 0) continue;
250
+ if (normalizedKey.startsWith("x-mbx-used-weight-")) {
251
+ const details = parseIntervalDetails(normalizedKey);
252
+ if (details) {
253
+ rateLimits.push({
254
+ rateLimitType: "REQUEST_WEIGHT",
255
+ interval: details.interval,
256
+ intervalNum: details.intervalNum,
257
+ count: parseInt(value, 10)
258
+ });
259
+ }
260
+ } else if (normalizedKey.startsWith("x-mbx-order-count-")) {
261
+ const details = parseIntervalDetails(normalizedKey);
262
+ if (details) {
263
+ rateLimits.push({
264
+ rateLimitType: "ORDERS",
265
+ interval: details.interval,
266
+ intervalNum: details.intervalNum,
267
+ count: parseInt(value, 10)
268
+ });
269
+ }
270
+ }
271
+ }
272
+ if (headers["retry-after"]) {
273
+ const retryAfter = parseInt(headers["retry-after"], 10);
274
+ for (const limit of rateLimits) {
275
+ limit.retryAfter = retryAfter;
276
+ }
277
+ }
278
+ return rateLimits;
279
+ };
280
+ var sendRequest = function(configuration, endpoint, method, params = {}, timeUnit, options = {}) {
281
+ const localVarUrlObj = new URL(endpoint, configuration?.basePath);
282
+ const localVarRequestOptions = {
283
+ method,
284
+ ...configuration?.baseOptions
285
+ };
286
+ const localVarQueryParameter = { ...params };
287
+ if (options.isSigned) {
288
+ const timestamp = getTimestamp();
289
+ localVarQueryParameter["timestamp"] = timestamp;
290
+ const signature = getSignature(configuration, localVarQueryParameter);
291
+ if (signature) {
292
+ localVarQueryParameter["signature"] = signature;
293
+ }
294
+ }
295
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
296
+ if (timeUnit && localVarRequestOptions.headers) {
297
+ const _timeUnit = validateTimeUnit(timeUnit);
298
+ localVarRequestOptions.headers = {
299
+ ...localVarRequestOptions.headers,
300
+ "X-MBX-TIME-UNIT": _timeUnit
301
+ };
302
+ }
303
+ return httpRequestFunction(
304
+ {
305
+ url: toPathString(localVarUrlObj),
306
+ options: localVarRequestOptions
307
+ },
308
+ configuration
309
+ );
310
+ };
311
+ function removeEmptyValue(obj) {
312
+ if (!(obj instanceof Object)) return {};
313
+ return Object.fromEntries(
314
+ Object.entries(obj).filter(
315
+ ([, value]) => value !== null && value !== void 0 && value !== ""
316
+ )
317
+ );
318
+ }
319
+ function sortObject(obj) {
320
+ return Object.keys(obj).sort().reduce((res, key) => {
321
+ res[key] = obj[key];
322
+ return res;
323
+ }, {});
324
+ }
325
+ function replaceWebsocketStreamsPlaceholders(str, variables) {
326
+ const normalizedVariables = Object.keys(variables).reduce(
327
+ (acc, key) => {
328
+ const normalizedKey = key.toLowerCase().replace(/[-_]/g, "");
329
+ acc[normalizedKey] = variables[key];
330
+ return acc;
331
+ },
332
+ {}
333
+ );
334
+ return str.replace(/(@)?<([^>]+)>/g, (match, precedingAt, fieldName) => {
335
+ const normalizedFieldName = fieldName.toLowerCase().replace(/[-_]/g, "");
336
+ if (Object.prototype.hasOwnProperty.call(normalizedVariables, normalizedFieldName) && normalizedVariables[normalizedFieldName] != null) {
337
+ const value = normalizedVariables[normalizedFieldName];
338
+ switch (normalizedFieldName) {
339
+ case "symbol":
340
+ case "windowsize":
341
+ return value.toLowerCase();
342
+ case "updatespeed":
343
+ return `@${value}`;
344
+ default:
345
+ return (precedingAt || "") + value;
346
+ }
347
+ }
348
+ return "";
349
+ });
350
+ }
351
+ function buildUserAgent(packageName, packageVersion) {
352
+ return `${packageName}/${packageVersion} (Node.js/${process.version}; ${platform()}; ${arch()})`;
353
+ }
354
+ function buildWebsocketAPIMessage(configuration, method, payload, options, skipAuth = false) {
355
+ const id = payload.id && /^[0-9a-f]{32}$/.test(payload.id) ? payload.id : randomString();
356
+ delete payload.id;
357
+ let params = removeEmptyValue(payload);
358
+ if ((options.withApiKey || options.isSigned) && !skipAuth) params.apiKey = configuration.apiKey;
359
+ if (options.isSigned) {
360
+ params.timestamp = getTimestamp();
361
+ params = sortObject(params);
362
+ if (!skipAuth) params.signature = getSignature(configuration, params);
363
+ }
364
+ return { id, method, params };
365
+ }
366
+ function sanitizeHeaderValue(value) {
367
+ const sanitizeOne = (v) => {
368
+ if (/\r|\n/.test(v)) throw new Error(`Invalid header value (contains CR/LF): "${v}"`);
369
+ return v;
370
+ };
371
+ return Array.isArray(value) ? value.map(sanitizeOne) : sanitizeOne(value);
372
+ }
373
+ function parseCustomHeaders(headers) {
374
+ if (!headers || Object.keys(headers).length === 0) return {};
375
+ const forbidden = /* @__PURE__ */ new Set(["host", "authorization", "cookie", ":method", ":path"]);
376
+ const parsedHeaders = {};
377
+ for (const [rawName, rawValue] of Object.entries(headers || {})) {
378
+ const name = rawName.trim();
379
+ if (forbidden.has(name.toLowerCase())) {
380
+ console.warn(`Dropping forbidden header: ${name}`);
381
+ continue;
382
+ }
383
+ try {
384
+ parsedHeaders[name] = sanitizeHeaderValue(rawValue);
385
+ } catch {
386
+ continue;
387
+ }
388
+ }
389
+ return parsedHeaders;
390
+ }
391
+
392
+ // src/configuration.ts
393
+ var ConfigurationRestAPI = class {
394
+ constructor(param = { apiKey: "" }) {
395
+ this.apiKey = param.apiKey;
396
+ this.apiSecret = param.apiSecret;
397
+ this.basePath = param.basePath;
398
+ this.keepAlive = param.keepAlive ?? true;
399
+ this.compression = param.compression ?? true;
400
+ this.retries = param.retries ?? 3;
401
+ this.backoff = param.backoff ?? 1e3;
402
+ this.privateKey = param.privateKey;
403
+ this.privateKeyPassphrase = param.privateKeyPassphrase;
404
+ this.timeUnit = param.timeUnit;
405
+ this.baseOptions = {
406
+ timeout: param.timeout ?? 1e3,
407
+ proxy: param.proxy && {
408
+ host: param.proxy.host,
409
+ port: param.proxy.port,
410
+ auth: param.proxy.auth
411
+ },
412
+ httpsAgent: param.httpsAgent ?? false,
413
+ headers: {
414
+ ...parseCustomHeaders(param.customHeaders || {}),
415
+ "Content-Type": "application/json",
416
+ "X-MBX-APIKEY": param.apiKey
417
+ }
418
+ };
419
+ }
420
+ };
421
+ var ConfigurationWebsocketAPI2 = class {
422
+ constructor(param = { apiKey: "" }) {
423
+ this.apiKey = param.apiKey;
424
+ this.apiSecret = param.apiSecret;
425
+ this.wsURL = param.wsURL;
426
+ this.timeout = param.timeout ?? 5e3;
427
+ this.reconnectDelay = param.reconnectDelay ?? 5e3;
428
+ this.compression = param.compression ?? true;
429
+ this.agent = param.agent ?? false;
430
+ this.mode = param.mode ?? "single";
431
+ this.poolSize = param.poolSize ?? 1;
432
+ this.privateKey = param.privateKey;
433
+ this.privateKeyPassphrase = param.privateKeyPassphrase;
434
+ this.timeUnit = param.timeUnit;
435
+ this.autoSessionReLogon = param.autoSessionReLogon ?? true;
436
+ }
437
+ };
438
+ var ConfigurationWebsocketStreams = class {
439
+ constructor(param = {}) {
440
+ this.wsURL = param.wsURL;
441
+ this.reconnectDelay = param.reconnectDelay ?? 5e3;
442
+ this.compression = param.compression ?? true;
443
+ this.agent = param.agent ?? false;
444
+ this.mode = param.mode ?? "single";
445
+ this.poolSize = param.poolSize ?? 1;
446
+ this.timeUnit = param.timeUnit;
447
+ }
448
+ };
449
+
450
+ // src/constants.ts
451
+ var TimeUnit = {
452
+ MILLISECOND: "MILLISECOND",
453
+ millisecond: "millisecond",
454
+ MICROSECOND: "MICROSECOND",
455
+ microsecond: "microsecond"
456
+ };
457
+ var ALGO_REST_API_PROD_URL = "https://api.binance.com";
458
+ var AUTO_INVEST_REST_API_PROD_URL = "https://api.binance.com";
459
+ var C2C_REST_API_PROD_URL = "https://api.binance.com";
460
+ var CONVERT_REST_API_PROD_URL = "https://api.binance.com";
461
+ var COPY_TRADING_REST_API_PROD_URL = "https://api.binance.com";
462
+ var CRYPTO_LOAN_REST_API_PROD_URL = "https://api.binance.com";
463
+ var DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL = "https://dapi.binance.com";
464
+ var DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
465
+ var DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL = "wss://ws-dapi.binance.com/ws-dapi/v1";
466
+ var DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-dapi/v1";
467
+ var DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL = "wss://dstream.binance.com";
468
+ var DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL = "wss://dstream.binancefuture.com";
469
+ var DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL = "https://fapi.binance.com";
470
+ var DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
471
+ var DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL = "wss://ws-fapi.binance.com/ws-fapi/v1";
472
+ var DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binancefuture.com/ws-fapi/v1";
473
+ var DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
474
+ var DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL = "wss://stream.binancefuture.com";
475
+ var DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL = "https://eapi.binance.com";
476
+ var DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL = "wss://nbstream.binance.com/eoptions";
477
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL = "https://papi.binance.com";
478
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
479
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm";
480
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL = "wss://fstream.binancefuture.com/pm";
481
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL = "https://api.binance.com";
482
+ var DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm-classic";
483
+ var DUAL_INVESTMENT_REST_API_PROD_URL = "https://api.binance.com";
484
+ var FIAT_REST_API_PROD_URL = "https://api.binance.com";
485
+ var GIFT_CARD_REST_API_PROD_URL = "https://api.binance.com";
486
+ var MARGIN_TRADING_REST_API_PROD_URL = "https://api.binance.com";
487
+ var MARGIN_TRADING_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443";
488
+ var MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL = "wss://margin-stream.binance.com";
489
+ var MINING_REST_API_PROD_URL = "https://api.binance.com";
490
+ var NFT_REST_API_PROD_URL = "https://api.binance.com";
491
+ var PAY_REST_API_PROD_URL = "https://api.binance.com";
492
+ var REBATE_REST_API_PROD_URL = "https://api.binance.com";
493
+ var SIMPLE_EARN_REST_API_PROD_URL = "https://api.binance.com";
494
+ var SPOT_REST_API_PROD_URL = "https://api.binance.com";
495
+ var SPOT_REST_API_TESTNET_URL = "https://testnet.binance.vision";
496
+ var SPOT_WS_API_PROD_URL = "wss://ws-api.binance.com:443/ws-api/v3";
497
+ var SPOT_WS_API_TESTNET_URL = "wss://ws-api.testnet.binance.vision/ws-api/v3";
498
+ var SPOT_WS_STREAMS_PROD_URL = "wss://stream.binance.com:9443";
499
+ var SPOT_WS_STREAMS_TESTNET_URL = "wss://stream.testnet.binance.vision";
500
+ var SPOT_REST_API_MARKET_URL = "https://data-api.binance.vision";
501
+ var SPOT_WS_STREAMS_MARKET_URL = "wss://data-stream.binance.vision";
502
+ var STAKING_REST_API_PROD_URL = "https://api.binance.com";
503
+ var SUB_ACCOUNT_REST_API_PROD_URL = "https://api.binance.com";
504
+ var VIP_LOAN_REST_API_PROD_URL = "https://api.binance.com";
505
+ var WALLET_REST_API_PROD_URL = "https://api.binance.com";
506
+
507
+ // src/errors.ts
508
+ var ConnectorClientError = class _ConnectorClientError extends Error {
509
+ constructor(msg) {
510
+ super(msg || "An unexpected error occurred.");
511
+ Object.setPrototypeOf(this, _ConnectorClientError.prototype);
512
+ this.name = "ConnectorClientError";
513
+ }
514
+ };
515
+ var RequiredError = class _RequiredError extends Error {
516
+ constructor(field, msg) {
517
+ super(msg || `Required parameter ${field} was null or undefined.`);
518
+ this.field = field;
519
+ Object.setPrototypeOf(this, _RequiredError.prototype);
520
+ this.name = "RequiredError";
521
+ }
522
+ };
523
+ var UnauthorizedError = class _UnauthorizedError extends Error {
524
+ constructor(msg) {
525
+ super(msg || "Unauthorized access. Authentication required.");
526
+ Object.setPrototypeOf(this, _UnauthorizedError.prototype);
527
+ this.name = "UnauthorizedError";
528
+ }
529
+ };
530
+ var ForbiddenError = class _ForbiddenError extends Error {
531
+ constructor(msg) {
532
+ super(msg || "Access to the requested resource is forbidden.");
533
+ Object.setPrototypeOf(this, _ForbiddenError.prototype);
534
+ this.name = "ForbiddenError";
535
+ }
471
536
  };
472
- var parseRateLimitHeaders = function(headers) {
473
- const rateLimits = [];
474
- const parseIntervalDetails = (key) => {
475
- const match = key.match(/x-mbx-used-weight-(\d+)([smhd])|x-mbx-order-count-(\d+)([smhd])/i);
476
- if (!match) return null;
477
- const intervalNum = parseInt(match[1] || match[3], 10);
478
- const intervalLetter = (match[2] || match[4])?.toUpperCase();
479
- let interval;
480
- switch (intervalLetter) {
481
- case "S":
482
- interval = "SECOND";
483
- break;
484
- case "M":
485
- interval = "MINUTE";
486
- break;
487
- case "H":
488
- interval = "HOUR";
489
- break;
490
- case "D":
491
- interval = "DAY";
492
- break;
493
- default:
494
- return null;
537
+ var TooManyRequestsError = class _TooManyRequestsError extends Error {
538
+ constructor(msg) {
539
+ super(msg || "Too many requests. You are being rate-limited.");
540
+ Object.setPrototypeOf(this, _TooManyRequestsError.prototype);
541
+ this.name = "TooManyRequestsError";
542
+ }
543
+ };
544
+ var RateLimitBanError = class _RateLimitBanError extends Error {
545
+ constructor(msg) {
546
+ super(msg || "The IP address has been banned for exceeding rate limits.");
547
+ Object.setPrototypeOf(this, _RateLimitBanError.prototype);
548
+ this.name = "RateLimitBanError";
549
+ }
550
+ };
551
+ var ServerError = class _ServerError extends Error {
552
+ constructor(msg, statusCode) {
553
+ super(msg || "An internal server error occurred.");
554
+ this.statusCode = statusCode;
555
+ Object.setPrototypeOf(this, _ServerError.prototype);
556
+ this.name = "ServerError";
557
+ }
558
+ };
559
+ var NetworkError = class _NetworkError extends Error {
560
+ constructor(msg) {
561
+ super(msg || "A network error occurred.");
562
+ Object.setPrototypeOf(this, _NetworkError.prototype);
563
+ this.name = "NetworkError";
564
+ }
565
+ };
566
+ var NotFoundError = class _NotFoundError extends Error {
567
+ constructor(msg) {
568
+ super(msg || "The requested resource was not found.");
569
+ Object.setPrototypeOf(this, _NotFoundError.prototype);
570
+ this.name = "NotFoundError";
571
+ }
572
+ };
573
+ var BadRequestError = class _BadRequestError extends Error {
574
+ constructor(msg) {
575
+ super(msg || "The request was invalid or cannot be otherwise served.");
576
+ Object.setPrototypeOf(this, _BadRequestError.prototype);
577
+ this.name = "BadRequestError";
578
+ }
579
+ };
580
+
581
+ // src/logger.ts
582
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
583
+ LogLevel2["NONE"] = "";
584
+ LogLevel2["DEBUG"] = "debug";
585
+ LogLevel2["INFO"] = "info";
586
+ LogLevel2["WARN"] = "warn";
587
+ LogLevel2["ERROR"] = "error";
588
+ return LogLevel2;
589
+ })(LogLevel || {});
590
+ var Logger = class _Logger {
591
+ constructor() {
592
+ this.minLogLevel = "info" /* INFO */;
593
+ this.levelsOrder = [
594
+ "" /* NONE */,
595
+ "debug" /* DEBUG */,
596
+ "info" /* INFO */,
597
+ "warn" /* WARN */,
598
+ "error" /* ERROR */
599
+ ];
600
+ }
601
+ static getInstance() {
602
+ if (!_Logger.instance) {
603
+ _Logger.instance = new _Logger();
495
604
  }
496
- return { interval, intervalNum };
497
- };
498
- for (const [key, value] of Object.entries(headers)) {
499
- const normalizedKey = key.toLowerCase();
500
- if (value === void 0) continue;
501
- if (normalizedKey.startsWith("x-mbx-used-weight-")) {
502
- const details = parseIntervalDetails(normalizedKey);
503
- if (details) {
504
- rateLimits.push({
505
- rateLimitType: "REQUEST_WEIGHT",
506
- interval: details.interval,
507
- intervalNum: details.intervalNum,
508
- count: parseInt(value, 10)
509
- });
510
- }
511
- } else if (normalizedKey.startsWith("x-mbx-order-count-")) {
512
- const details = parseIntervalDetails(normalizedKey);
513
- if (details) {
514
- rateLimits.push({
515
- rateLimitType: "ORDERS",
516
- interval: details.interval,
517
- intervalNum: details.intervalNum,
518
- count: parseInt(value, 10)
519
- });
520
- }
605
+ return _Logger.instance;
606
+ }
607
+ setMinLogLevel(level) {
608
+ if (!this.isValidLogLevel(level)) {
609
+ throw new Error(`Invalid log level: ${level}`);
521
610
  }
611
+ this.minLogLevel = level;
522
612
  }
523
- if (headers["retry-after"]) {
524
- const retryAfter = parseInt(headers["retry-after"], 10);
525
- for (const limit of rateLimits) {
526
- limit.retryAfter = retryAfter;
613
+ isValidLogLevel(level) {
614
+ return this.levelsOrder.includes(level);
615
+ }
616
+ log(level, ...message) {
617
+ if (level === "" /* NONE */ || !this.allowLevelLog(level)) {
618
+ return;
527
619
  }
620
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
621
+ console[level](`[${timestamp}] [${level.toLowerCase()}]`, ...message);
528
622
  }
529
- return rateLimits;
530
- };
531
- var sendRequest = function(configuration, endpoint, method, params = {}, timeUnit, options = {}) {
532
- const localVarUrlObj = new URL(endpoint, configuration?.basePath);
533
- const localVarRequestOptions = {
534
- method,
535
- ...configuration?.baseOptions
536
- };
537
- const localVarQueryParameter = { ...params };
538
- if (options.isSigned) {
539
- const timestamp = getTimestamp();
540
- localVarQueryParameter["timestamp"] = timestamp;
541
- const signature = getSignature(configuration, localVarQueryParameter);
542
- if (signature) {
543
- localVarQueryParameter["signature"] = signature;
623
+ allowLevelLog(level) {
624
+ if (!this.isValidLogLevel(level)) {
625
+ throw new Error(`Invalid log level: ${level}`);
544
626
  }
627
+ const currentLevelIndex = this.levelsOrder.indexOf(level);
628
+ const minLevelIndex = this.levelsOrder.indexOf(this.minLogLevel);
629
+ return currentLevelIndex >= minLevelIndex;
545
630
  }
546
- setSearchParams(localVarUrlObj, localVarQueryParameter);
547
- if (timeUnit && localVarRequestOptions.headers) {
548
- const _timeUnit = validateTimeUnit(timeUnit);
549
- localVarRequestOptions.headers = {
550
- ...localVarRequestOptions.headers,
551
- "X-MBX-TIME-UNIT": _timeUnit
552
- };
631
+ debug(...message) {
632
+ this.log("debug" /* DEBUG */, ...message);
633
+ }
634
+ info(...message) {
635
+ this.log("info" /* INFO */, ...message);
636
+ }
637
+ warn(...message) {
638
+ this.log("warn" /* WARN */, ...message);
639
+ }
640
+ error(...message) {
641
+ this.log("error" /* ERROR */, ...message);
553
642
  }
554
- return httpRequestFunction(
555
- {
556
- url: toPathString(localVarUrlObj),
557
- options: localVarRequestOptions
558
- },
559
- configuration
560
- );
561
643
  };
562
- function removeEmptyValue(obj) {
563
- if (!(obj instanceof Object)) return {};
564
- return Object.fromEntries(
565
- Object.entries(obj).filter(
566
- ([, value]) => value !== null && value !== void 0 && value !== ""
567
- )
568
- );
569
- }
570
- function sortObject(obj) {
571
- return Object.keys(obj).sort().reduce((res, key) => {
572
- res[key] = obj[key];
573
- return res;
574
- }, {});
575
- }
576
- function replaceWebsocketStreamsPlaceholders(str, variables) {
577
- const normalizedVariables = Object.keys(variables).reduce(
578
- (acc, key) => {
579
- const normalizedKey = key.toLowerCase().replace(/[-_]/g, "");
580
- acc[normalizedKey] = variables[key];
581
- return acc;
582
- },
583
- {}
584
- );
585
- return str.replace(/(@)?<([^>]+)>/g, (match, precedingAt, fieldName) => {
586
- const normalizedFieldName = fieldName.toLowerCase().replace(/[-_]/g, "");
587
- if (Object.prototype.hasOwnProperty.call(normalizedVariables, normalizedFieldName) && normalizedVariables[normalizedFieldName] != null) {
588
- const value = normalizedVariables[normalizedFieldName];
589
- switch (normalizedFieldName) {
590
- case "symbol":
591
- case "windowsize":
592
- return value.toLowerCase();
593
- case "updatespeed":
594
- return `@${value}`;
595
- default:
596
- return (precedingAt || "") + value;
597
- }
598
- }
599
- return "";
600
- });
601
- }
602
- function buildUserAgent(packageName, packageVersion) {
603
- return `${packageName}/${packageVersion} (Node.js/${process.version}; ${platform()}; ${arch()})`;
604
- }
605
644
 
606
645
  // src/websocket.ts
607
646
  import { EventEmitter } from "events";
@@ -661,6 +700,20 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
661
700
  });
662
701
  }
663
702
  }
703
+ /**
704
+ * Retrieves available WebSocket connections based on the connection mode and readiness.
705
+ * In 'single' mode, returns the first connection in the pool.
706
+ * In 'pool' mode, filters and returns connections that are ready for use.
707
+ * @param allowNonEstablishedWebsockets - Optional flag to include non-established WebSocket connections.
708
+ * @returns An array of available WebSocket connections.
709
+ */
710
+ getAvailableConnections(allowNonEstablishedWebsockets = false) {
711
+ if (this.mode === "single") return [this.connectionPool[0]];
712
+ const availableConnections = this.connectionPool.filter(
713
+ (connection) => this.isConnectionReady(connection, allowNonEstablishedWebsockets)
714
+ );
715
+ return availableConnections;
716
+ }
664
717
  /**
665
718
  * Gets a WebSocket connection from the pool or single connection.
666
719
  * If the connection mode is 'single', it returns the first connection in the pool.
@@ -670,10 +723,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
670
723
  * @returns {WebsocketConnection} The selected WebSocket connection.
671
724
  */
672
725
  getConnection(allowNonEstablishedWebsockets = false) {
673
- if (this.mode === "single") return this.connectionPool[0];
674
- const availableConnections = this.connectionPool.filter(
675
- (connection) => this.isConnectionReady(connection, allowNonEstablishedWebsockets)
676
- );
726
+ const availableConnections = this.getAvailableConnections(allowNonEstablishedWebsockets);
677
727
  if (availableConnections.length === 0) {
678
728
  throw new Error("No available Websocket connections are ready.");
679
729
  }
@@ -766,12 +816,16 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
766
816
  */
767
817
  async closeConnectionGracefully(WebsocketConnectionToClose, connection) {
768
818
  if (!WebsocketConnectionToClose || !connection) return;
769
- this.logger.debug("Waiting for pending requests to complete before disconnecting.");
819
+ this.logger.debug(
820
+ `Waiting for pending requests to complete before disconnecting websocket on connection ${connection.id}.`
821
+ );
770
822
  const closePromise = new Promise((resolve) => {
771
823
  this.scheduleTimer(
772
824
  WebsocketConnectionToClose,
773
825
  () => {
774
- this.logger.warn("Force-closing connection after 30 seconds.");
826
+ this.logger.warn(
827
+ `Force-closing websocket connection after 30 seconds on connection ${connection.id}.`
828
+ );
775
829
  resolve();
776
830
  },
777
831
  3e4
@@ -780,7 +834,9 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
780
834
  WebsocketConnectionToClose,
781
835
  () => {
782
836
  if (connection.pendingRequests.size === 0) {
783
- this.logger.debug("All pending requests completed, closing connection.");
837
+ this.logger.debug(
838
+ `All pending requests completed, closing websocket connection on connection ${connection.id}.`
839
+ );
784
840
  resolve();
785
841
  }
786
842
  },
@@ -789,10 +845,44 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
789
845
  );
790
846
  });
791
847
  await closePromise;
792
- this.logger.info("Closing Websocket connection.");
848
+ this.logger.info(`Closing Websocket connection on connection ${connection.id}.`);
793
849
  WebsocketConnectionToClose.close();
794
850
  this.cleanup(WebsocketConnectionToClose);
795
851
  }
852
+ /**
853
+ * Attempts to re-establish a session for a WebSocket connection.
854
+ * If a session logon request exists and the connection is not already logged on,
855
+ * it sends an authentication request and updates the connection's logged-on status.
856
+ * @param connection - The WebSocket connection to re-authenticate.
857
+ * @private
858
+ */
859
+ async sessionReLogon(connection) {
860
+ const req = connection.sessionLogonReq;
861
+ if (req && !connection.isSessionLoggedOn) {
862
+ const data = buildWebsocketAPIMessage(
863
+ this.configuration,
864
+ req.method,
865
+ req.payload,
866
+ req.options
867
+ );
868
+ this.logger.debug(`Session re-logon on connection ${connection.id}`, data);
869
+ try {
870
+ await this.send(
871
+ JSON.stringify(data),
872
+ data.id,
873
+ true,
874
+ this.configuration.timeout,
875
+ connection
876
+ );
877
+ this.logger.debug(
878
+ `Session re-logon on connection ${connection.id} was successful.`
879
+ );
880
+ connection.isSessionLoggedOn = true;
881
+ } catch (err) {
882
+ this.logger.error(`Session re-logon on connection ${connection.id} failed:`, err);
883
+ }
884
+ }
885
+ }
796
886
  /**
797
887
  * Cleans up WebSocket connection resources.
798
888
  * Removes all listeners and clears any associated timers for the provided WebSocket client.
@@ -817,8 +907,6 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
817
907
  * Handles the opening of a WebSocket connection.
818
908
  * @param url - The URL of the WebSocket server.
819
909
  * @param targetConnection - The WebSocket connection being opened.
820
- * @param oldConnection - The previous WebSocket connection, if this is a renewal.
821
- * @param isRenewal - Indicates whether this is a connection renewal.
822
910
  * @param oldWSConnection - The WebSocket client instance associated with the old connection.
823
911
  */
824
912
  onOpen(url, targetConnection, oldWSConnection) {
@@ -833,6 +921,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
833
921
  } else {
834
922
  this.emit("open", this);
835
923
  }
924
+ this.sessionReLogon(targetConnection);
836
925
  }
837
926
  /**
838
927
  * Returns the URL to use when reconnecting.
@@ -903,10 +992,12 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
903
992
  );
904
993
  if (isRenewal) targetConnection.renewalPending = true;
905
994
  else targetConnection.ws = ws;
995
+ targetConnection.isSessionLoggedOn = false;
906
996
  this.scheduleTimer(
907
997
  ws,
908
998
  () => {
909
999
  this.logger.info(`Renewing Websocket connection with id ${targetConnection.id}`);
1000
+ targetConnection.isSessionLoggedOn = false;
910
1001
  this.enqueueReconnection(
911
1002
  targetConnection,
912
1003
  this.getReconnectURL(url, targetConnection),
@@ -950,6 +1041,7 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
950
1041
  this.logger.info(
951
1042
  `Reconnecting conection with id ${targetConnection.id} to the server.`
952
1043
  );
1044
+ targetConnection.isSessionLoggedOn = false;
953
1045
  targetConnection.reconnectionPending = true;
954
1046
  this.enqueueReconnection(
955
1047
  targetConnection,
@@ -985,6 +1077,8 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
985
1077
  else {
986
1078
  this.connectionPool.forEach((connection) => {
987
1079
  connection.closeInitiated = true;
1080
+ connection.isSessionLoggedOn = false;
1081
+ connection.sessionLogonReq = void 0;
988
1082
  });
989
1083
  const disconnectPromises = this.connectionPool.map(
990
1084
  (connection) => this.closeConnectionGracefully(connection.ws, connection)
@@ -1145,37 +1239,44 @@ var WebsocketAPIBase = class extends WebsocketCommon {
1145
1239
  });
1146
1240
  });
1147
1241
  }
1148
- /**
1149
- * Sends a message to the WebSocket API Server.
1150
- * Supports both signed and unsigned messages.
1151
- * @param method The API method to call
1152
- * @param payload Message parameters and options
1153
- * @param options Additional requests options (withApiKey, isSigned)
1154
- * @returns Promise that resolves with the server response
1155
- * @throws Error if not connected
1156
- */
1157
- sendMessage(method, payload = {}, options = {}) {
1242
+ async sendMessage(method, payload = {}, options = {}) {
1158
1243
  if (!this.isConnected()) {
1159
- return Promise.reject(new Error("Not connected"));
1160
- }
1161
- const id = payload.id && /^[0-9a-f]{32}$/.test(payload.id) ? payload.id : randomString();
1162
- delete payload.id;
1163
- let params = removeEmptyValue(payload);
1164
- if (options.withApiKey || options.isSigned) {
1165
- params.apiKey = this.configuration.apiKey;
1244
+ throw new Error("Not connected");
1166
1245
  }
1167
- if (options.isSigned) {
1168
- params.timestamp = getTimestamp();
1169
- params = sortObject(params);
1170
- params.signature = getSignature(this.configuration, params);
1171
- }
1172
- const data = {
1173
- id,
1246
+ const isSessionReq = options.isSessionLogon || options.isSessionLogout;
1247
+ const connections = isSessionReq ? this.getAvailableConnections() : [this.getConnection()];
1248
+ const skipAuth = isSessionReq ? false : this.configuration.autoSessionReLogon && connections[0].isSessionLoggedOn;
1249
+ const data = buildWebsocketAPIMessage(
1250
+ this.configuration,
1174
1251
  method,
1175
- params
1176
- };
1252
+ payload,
1253
+ options,
1254
+ skipAuth
1255
+ );
1177
1256
  this.logger.debug("Send message to Binance WebSocket API Server:", data);
1178
- return this.send(JSON.stringify(data), id, true, this.configuration?.timeout);
1257
+ const responses = await Promise.all(
1258
+ connections.map(
1259
+ (connection) => this.send(
1260
+ JSON.stringify(data),
1261
+ data.id,
1262
+ true,
1263
+ this.configuration.timeout,
1264
+ connection
1265
+ )
1266
+ )
1267
+ );
1268
+ if (isSessionReq && this.configuration.autoSessionReLogon) {
1269
+ connections.forEach((connection) => {
1270
+ if (options.isSessionLogon) {
1271
+ connection.isSessionLoggedOn = true;
1272
+ connection.sessionLogonReq = { method, payload, options };
1273
+ } else {
1274
+ connection.isSessionLoggedOn = false;
1275
+ connection.sessionLogonReq = void 0;
1276
+ }
1277
+ });
1278
+ }
1279
+ return connections.length === 1 && !isSessionReq ? responses[0] : responses;
1179
1280
  }
1180
1281
  };
1181
1282
  var WebsocketStreamsBase = class extends WebsocketCommon {
@@ -1287,7 +1388,6 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1287
1388
  * @param url The URL of the WebSocket connection.
1288
1389
  * @param targetConnection The WebSocket connection that was opened.
1289
1390
  * @param oldConnection The previous WebSocket connection, if any.
1290
- * @param isRenewal Whether the connection is a renewal of an existing connection.
1291
1391
  */
1292
1392
  onOpen(url, targetConnection, oldWSConnection) {
1293
1393
  this.processPendingSubscriptions(targetConnection);
@@ -1339,7 +1439,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1339
1439
  connectionStreamMap.forEach((streams2, connection) => {
1340
1440
  if (!this.isConnected(connection)) {
1341
1441
  this.logger.info(
1342
- `Connection is not ready. Queuing subscription for streams: ${streams2}`
1442
+ `Connection ${connection.id} is not ready. Queuing subscription for streams: ${streams2}`
1343
1443
  );
1344
1444
  connection.pendingSubscriptions?.push(...streams2);
1345
1445
  return;
@@ -1417,7 +1517,7 @@ export {
1417
1517
  COPY_TRADING_REST_API_PROD_URL,
1418
1518
  CRYPTO_LOAN_REST_API_PROD_URL,
1419
1519
  ConfigurationRestAPI,
1420
- ConfigurationWebsocketAPI,
1520
+ ConfigurationWebsocketAPI2 as ConfigurationWebsocketAPI,
1421
1521
  ConfigurationWebsocketStreams,
1422
1522
  ConnectorClientError,
1423
1523
  DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL,
@@ -1481,16 +1581,19 @@ export {
1481
1581
  assertParamExists,
1482
1582
  buildQueryString,
1483
1583
  buildUserAgent,
1584
+ buildWebsocketAPIMessage,
1484
1585
  clearSignerCache,
1485
1586
  createStreamHandler,
1486
1587
  delay,
1487
1588
  getSignature,
1488
1589
  getTimestamp,
1489
1590
  httpRequestFunction,
1591
+ parseCustomHeaders,
1490
1592
  parseRateLimitHeaders,
1491
1593
  randomString,
1492
1594
  removeEmptyValue,
1493
1595
  replaceWebsocketStreamsPlaceholders,
1596
+ sanitizeHeaderValue,
1494
1597
  sendRequest,
1495
1598
  setFlattenedQueryParams,
1496
1599
  setSearchParams,