@binance/common 2.0.1 → 2.1.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
@@ -46,8 +46,8 @@ var RequestSigner = class {
46
46
  }
47
47
  throw new Error("Either 'apiSecret' or 'privateKey' must be provided for signed requests.");
48
48
  }
49
- sign(queryParams) {
50
- const params = buildQueryString(queryParams);
49
+ sign(queryParams, bodyParams) {
50
+ const params = buildQueryString(queryParams) + (bodyParams ? buildQueryString(bodyParams) : "");
51
51
  if (this.apiSecret) return crypto.createHmac("sha256", this.apiSecret).update(params).digest("hex");
52
52
  if (this.keyObject && this.keyType) {
53
53
  const data = Buffer.from(params);
@@ -112,6 +112,42 @@ function randomString() {
112
112
  return crypto.randomBytes(16).toString("hex");
113
113
  }
114
114
  /**
115
+ * Generates a cryptographically secure random 32-bit unsigned integer.
116
+ *
117
+ * Uses the Web Crypto API to generate a random value between 0 and 4,294,967,295 (2^32 - 1).
118
+ *
119
+ * @returns A random 32-bit unsigned integer.
120
+ */
121
+ function randomInteger() {
122
+ const array = new Uint32Array(1);
123
+ crypto.getRandomValues(array);
124
+ return array[0];
125
+ }
126
+ /**
127
+ * Normalizes a stream ID to ensure it is valid, generating a random ID if needed.
128
+ *
129
+ * For string inputs:
130
+ * - Returns the input if it's a valid 32-character hexadecimal string (case-insensitive)
131
+ * - Otherwise, generates a new random hexadecimal string using `randomString()`
132
+ *
133
+ * For number inputs:
134
+ * - Returns the input if it's a finite, non-negative integer within the safe integer range
135
+ * - Otherwise, generates a new random integer using `randomInteger()`
136
+ *
137
+ * For null or undefined inputs:
138
+ * - Generates a new random hexadecimal string using `randomString()`
139
+ *
140
+ * @param id - The stream ID to normalize (string, number, null, or undefined).
141
+ * @param streamIdIsStrictlyNumber - Boolean forcing an id to be a number or not.
142
+ * @returns A valid stream ID as either a 32-character hexadecimal string or a safe integer.
143
+ */
144
+ function normalizeStreamId(id, streamIdIsStrictlyNumber) {
145
+ const isValidNumber = typeof id === "number" && Number.isFinite(id) && Number.isInteger(id) && id >= 0 && id <= Number.MAX_SAFE_INTEGER;
146
+ if (streamIdIsStrictlyNumber || typeof id === "number") return isValidNumber ? id : randomInteger();
147
+ if (typeof id === "string") return id && /^[0-9a-f]{32}$/i.test(id) ? id : randomString();
148
+ return randomString();
149
+ }
150
+ /**
115
151
  * Validates the provided time unit string and returns it if it is either 'MILLISECOND' or 'MICROSECOND'.
116
152
  *
117
153
  * @param timeUnit - The time unit string to be validated.
@@ -147,13 +183,13 @@ function getTimestamp() {
147
183
  * @param queryParams - The query parameters to be signed.
148
184
  * @returns A string representing the generated signature.
149
185
  */
150
- const getSignature = function(configuration, queryParams) {
186
+ const getSignature = function(configuration, queryParams, bodyParams) {
151
187
  let signer = signerCache.get(configuration);
152
188
  if (!signer) {
153
189
  signer = new RequestSigner(configuration);
154
190
  signerCache.set(configuration, signer);
155
191
  }
156
- return signer.sign(queryParams);
192
+ return signer.sign(queryParams, bodyParams);
157
193
  };
158
194
  /**
159
195
  * Asserts that a function parameter exists and is not null or undefined.
@@ -397,19 +433,33 @@ const parseRateLimitHeaders = function(headers) {
397
433
  * @param options - Additional request options (isSigned).
398
434
  * @returns A promise resolving to the response data object.
399
435
  */
400
- const sendRequest = function(configuration, endpoint, method, params = {}, timeUnit, options = {}) {
436
+ const sendRequest = function(configuration, endpoint, method, queryParams = {}, bodyParams = {}, timeUnit, options = {}) {
401
437
  const localVarUrlObj = new URL(endpoint, configuration?.basePath);
402
438
  const localVarRequestOptions = {
403
439
  method,
404
440
  ...configuration?.baseOptions
405
441
  };
406
- const localVarQueryParameter = { ...normalizeScientificNumbers(params) };
442
+ const localVarQueryParameter = { ...normalizeScientificNumbers(queryParams) };
443
+ const localVarBodyParameter = { ...normalizeScientificNumbers(bodyParams) };
407
444
  if (options.isSigned) {
408
445
  localVarQueryParameter["timestamp"] = getTimestamp();
409
- const signature = getSignature(configuration, localVarQueryParameter);
446
+ const signature = getSignature(configuration, localVarQueryParameter, localVarBodyParameter);
410
447
  if (signature) localVarQueryParameter["signature"] = signature;
411
448
  }
412
449
  setSearchParams(localVarUrlObj, localVarQueryParameter);
450
+ if (Object.keys(localVarBodyParameter).length > 0) {
451
+ const searchParams = new URLSearchParams();
452
+ for (const [key, value] of Object.entries(localVarBodyParameter)) {
453
+ if (value === null || value === void 0) continue;
454
+ const serializedValue = serializeValue(value);
455
+ searchParams.append(key, serializedValue);
456
+ }
457
+ localVarRequestOptions.data = searchParams.toString();
458
+ localVarRequestOptions.headers = {
459
+ ...localVarRequestOptions.headers || {},
460
+ "Content-Type": "application/x-www-form-urlencoded"
461
+ };
462
+ }
413
463
  if (timeUnit && localVarRequestOptions.headers) {
414
464
  const _timeUnit = validateTimeUnit(timeUnit);
415
465
  localVarRequestOptions.headers = {
@@ -1404,6 +1454,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1404
1454
  constructor(configuration, connectionPool = []) {
1405
1455
  super(configuration, connectionPool);
1406
1456
  this.streamConnectionMap = /* @__PURE__ */ new Map();
1457
+ this.streamIdIsStrictlyNumber = false;
1407
1458
  this.streamCallbackMap = /* @__PURE__ */ new Map();
1408
1459
  this.logger = Logger.getInstance();
1409
1460
  this.configuration = configuration;
@@ -1463,7 +1514,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1463
1514
  const payload = {
1464
1515
  method: "SUBSCRIBE",
1465
1516
  params: streams,
1466
- id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
1517
+ id: normalizeStreamId(id, this.streamIdIsStrictlyNumber)
1467
1518
  };
1468
1519
  this.logger.debug("SUBSCRIBE", payload);
1469
1520
  this.send(JSON.stringify(payload), void 0, false, 0, connection);
@@ -1570,7 +1621,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
1570
1621
  const payload = {
1571
1622
  method: "UNSUBSCRIBE",
1572
1623
  params: [stream$1],
1573
- id: id && /^[0-9a-f]{32}$/.test(id) ? id : randomString()
1624
+ id: normalizeStreamId(id, this.streamIdIsStrictlyNumber)
1574
1625
  };
1575
1626
  this.logger.debug("UNSUBSCRIBE", payload);
1576
1627
  this.send(JSON.stringify(payload), void 0, false, 0, connection);
@@ -1621,5 +1672,5 @@ function createStreamHandler(websocketBase, streamOrId, id) {
1621
1672
  }
1622
1673
 
1623
1674
  //#endregion
1624
- export { ALGO_REST_API_PROD_URL, BadRequestError, C2C_REST_API_PROD_URL, CONVERT_REST_API_PROD_URL, COPY_TRADING_REST_API_PROD_URL, CRYPTO_LOAN_REST_API_PROD_URL, ConfigurationRestAPI, ConfigurationWebsocketAPI, ConfigurationWebsocketStreams, ConnectorClientError, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL, DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL, DUAL_INVESTMENT_REST_API_PROD_URL, FIAT_REST_API_PROD_URL, ForbiddenError, GIFT_CARD_REST_API_PROD_URL, LogLevel, Logger, MARGIN_TRADING_REST_API_PROD_URL, MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL, MARGIN_TRADING_WS_STREAMS_PROD_URL, MINING_REST_API_PROD_URL, NFT_REST_API_PROD_URL, NetworkError, NotFoundError, PAY_REST_API_PROD_URL, REBATE_REST_API_PROD_URL, RateLimitBanError, RequiredError, SIMPLE_EARN_REST_API_PROD_URL, SPOT_REST_API_MARKET_URL, SPOT_REST_API_PROD_URL, SPOT_REST_API_TESTNET_URL, SPOT_WS_API_PROD_URL, SPOT_WS_API_TESTNET_URL, SPOT_WS_STREAMS_MARKET_URL, SPOT_WS_STREAMS_PROD_URL, SPOT_WS_STREAMS_TESTNET_URL, STAKING_REST_API_PROD_URL, SUB_ACCOUNT_REST_API_PROD_URL, ServerError, TimeUnit, TooManyRequestsError, UnauthorizedError, VIP_LOAN_REST_API_PROD_URL, WALLET_REST_API_PROD_URL, WebsocketAPIBase, WebsocketCommon, WebsocketEventEmitter, WebsocketStreamsBase, assertParamExists, buildQueryString, buildUserAgent, buildWebsocketAPIMessage, clearSignerCache, createStreamHandler, delay, getSignature, getTimestamp, httpRequestFunction, normalizeScientificNumbers, parseCustomHeaders, parseRateLimitHeaders, randomString, removeEmptyValue, replaceWebsocketStreamsPlaceholders, sanitizeHeaderValue, sendRequest, setSearchParams, shouldRetryRequest, sortObject, toPathString, validateTimeUnit };
1675
+ export { ALGO_REST_API_PROD_URL, BadRequestError, C2C_REST_API_PROD_URL, CONVERT_REST_API_PROD_URL, COPY_TRADING_REST_API_PROD_URL, CRYPTO_LOAN_REST_API_PROD_URL, ConfigurationRestAPI, ConfigurationWebsocketAPI, ConfigurationWebsocketStreams, ConnectorClientError, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL, DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL, DUAL_INVESTMENT_REST_API_PROD_URL, FIAT_REST_API_PROD_URL, ForbiddenError, GIFT_CARD_REST_API_PROD_URL, LogLevel, Logger, MARGIN_TRADING_REST_API_PROD_URL, MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL, MARGIN_TRADING_WS_STREAMS_PROD_URL, MINING_REST_API_PROD_URL, NFT_REST_API_PROD_URL, NetworkError, NotFoundError, PAY_REST_API_PROD_URL, REBATE_REST_API_PROD_URL, RateLimitBanError, RequiredError, SIMPLE_EARN_REST_API_PROD_URL, SPOT_REST_API_MARKET_URL, SPOT_REST_API_PROD_URL, SPOT_REST_API_TESTNET_URL, SPOT_WS_API_PROD_URL, SPOT_WS_API_TESTNET_URL, SPOT_WS_STREAMS_MARKET_URL, SPOT_WS_STREAMS_PROD_URL, SPOT_WS_STREAMS_TESTNET_URL, STAKING_REST_API_PROD_URL, SUB_ACCOUNT_REST_API_PROD_URL, ServerError, TimeUnit, TooManyRequestsError, UnauthorizedError, VIP_LOAN_REST_API_PROD_URL, WALLET_REST_API_PROD_URL, WebsocketAPIBase, WebsocketCommon, WebsocketEventEmitter, WebsocketStreamsBase, assertParamExists, buildQueryString, buildUserAgent, buildWebsocketAPIMessage, clearSignerCache, createStreamHandler, delay, getSignature, getTimestamp, httpRequestFunction, normalizeScientificNumbers, normalizeStreamId, parseCustomHeaders, parseRateLimitHeaders, randomInteger, randomString, removeEmptyValue, replaceWebsocketStreamsPlaceholders, sanitizeHeaderValue, sendRequest, setSearchParams, shouldRetryRequest, sortObject, toPathString, validateTimeUnit };
1625
1676
  //# sourceMappingURL=index.mjs.map