@binance/common 1.1.0 → 1.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
@@ -249,6 +249,52 @@ import crypto from "crypto";
249
249
  import fs from "fs";
250
250
  import https from "https";
251
251
  import globalAxios from "axios";
252
+ var signerCache = /* @__PURE__ */ new WeakMap();
253
+ var RequestSigner = class {
254
+ constructor(configuration) {
255
+ if (configuration.apiSecret && !configuration.privateKey) {
256
+ this.apiSecret = configuration.apiSecret;
257
+ return;
258
+ }
259
+ if (configuration.privateKey) {
260
+ let privateKey = configuration.privateKey;
261
+ if (typeof privateKey === "string" && fs.existsSync(privateKey)) {
262
+ privateKey = fs.readFileSync(privateKey, "utf-8");
263
+ }
264
+ const keyInput = { key: privateKey };
265
+ if (configuration.privateKeyPassphrase && typeof configuration.privateKeyPassphrase === "string") {
266
+ keyInput.passphrase = configuration.privateKeyPassphrase;
267
+ }
268
+ try {
269
+ this.keyObject = crypto.createPrivateKey(keyInput);
270
+ this.keyType = this.keyObject.asymmetricKeyType;
271
+ } catch {
272
+ throw new Error(
273
+ "Invalid private key. Please provide a valid RSA or ED25519 private key."
274
+ );
275
+ }
276
+ return;
277
+ }
278
+ throw new Error("Either 'apiSecret' or 'privateKey' must be provided for signed requests.");
279
+ }
280
+ sign(queryParams) {
281
+ const params = buildQueryString(queryParams);
282
+ if (this.apiSecret)
283
+ return crypto.createHmac("sha256", this.apiSecret).update(params).digest("hex");
284
+ if (this.keyObject && this.keyType) {
285
+ const data = Buffer.from(params);
286
+ if (this.keyType === "rsa")
287
+ return crypto.sign("RSA-SHA256", data, this.keyObject).toString("base64");
288
+ if (this.keyType === "ed25519")
289
+ return crypto.sign(null, data, this.keyObject).toString("base64");
290
+ throw new Error("Unsupported private key type. Must be RSA or ED25519.");
291
+ }
292
+ throw new Error("Signer is not properly initialized.");
293
+ }
294
+ };
295
+ var clearSignerCache = function() {
296
+ signerCache = /* @__PURE__ */ new WeakMap();
297
+ };
252
298
  function buildQueryString(params) {
253
299
  if (!params) return "";
254
300
  return Object.entries(params).map(stringifyKeyValuePair).join("&");
@@ -275,39 +321,12 @@ function getTimestamp() {
275
321
  return Date.now();
276
322
  }
277
323
  var getSignature = function(configuration, queryParams) {
278
- const params = buildQueryString(queryParams);
279
- let signature = "";
280
- if (configuration?.apiSecret && !configuration?.privateKey) {
281
- signature = crypto.createHmac("sha256", configuration.apiSecret).update(params).digest("hex");
282
- } else if (configuration?.privateKey) {
283
- let privateKey = configuration.privateKey;
284
- if (typeof privateKey === "string" && fs.existsSync(privateKey)) {
285
- privateKey = fs.readFileSync(privateKey, "utf-8");
286
- }
287
- let keyObject;
288
- try {
289
- const privateKeyObj = { key: privateKey };
290
- if (configuration.privateKeyPassphrase && typeof configuration.privateKeyPassphrase === "string") {
291
- privateKeyObj.passphrase = configuration.privateKeyPassphrase;
292
- }
293
- keyObject = crypto.createPrivateKey(privateKeyObj);
294
- } catch {
295
- throw new Error(
296
- "Invalid private key. Please provide a valid RSA or ED25519 private key."
297
- );
298
- }
299
- const keyType = keyObject.asymmetricKeyType;
300
- if (keyType === "rsa") {
301
- signature = crypto.sign("RSA-SHA256", Buffer.from(params), keyObject).toString("base64");
302
- } else if (keyType === "ed25519") {
303
- signature = crypto.sign(null, Buffer.from(params), keyObject).toString("base64");
304
- } else {
305
- throw new Error("Unsupported private key type. Must be RSA or ED25519.");
306
- }
307
- } else {
308
- throw new Error("Either 'apiSecret' or 'privateKey' must be provided for signed requests.");
324
+ let signer = signerCache.get(configuration);
325
+ if (!signer) {
326
+ signer = new RequestSigner(configuration);
327
+ signerCache.set(configuration, signer);
309
328
  }
310
- return signature;
329
+ return signer.sign(queryParams);
311
330
  };
312
331
  var assertParamExists = function(functionName, paramName, paramValue) {
313
332
  if (paramValue === null || paramValue === void 0) {
@@ -319,25 +338,26 @@ var assertParamExists = function(functionName, paramName, paramValue) {
319
338
  };
320
339
  function setFlattenedQueryParams(urlSearchParams, parameter, key = "") {
321
340
  if (parameter == null) return;
341
+ if (Array.isArray(parameter)) {
342
+ if (key)
343
+ urlSearchParams.set(key, JSON.stringify(parameter));
344
+ else
345
+ for (const item of parameter) {
346
+ setFlattenedQueryParams(urlSearchParams, item, "");
347
+ }
348
+ return;
349
+ }
322
350
  if (typeof parameter === "object") {
323
- if (Array.isArray(parameter)) {
324
- parameter.forEach((item) => setFlattenedQueryParams(urlSearchParams, item, key));
325
- } else {
326
- Object.keys(parameter).forEach(
327
- (currentKey) => setFlattenedQueryParams(
328
- urlSearchParams,
329
- parameter[currentKey],
330
- `${key}${key !== "" ? "." : ""}${currentKey}`
331
- )
332
- );
333
- }
334
- } else {
335
- if (urlSearchParams.has(key)) {
336
- urlSearchParams.append(key, String(parameter));
337
- } else {
338
- urlSearchParams.set(key, String(parameter));
351
+ for (const subKey of Object.keys(parameter)) {
352
+ const subVal = parameter[subKey];
353
+ const newKey = key ? `${key}.${subKey}` : subKey;
354
+ setFlattenedQueryParams(urlSearchParams, subVal, newKey);
339
355
  }
356
+ return;
340
357
  }
358
+ const str = String(parameter);
359
+ if (urlSearchParams.has(key)) urlSearchParams.append(key, str);
360
+ else urlSearchParams.set(key, str);
341
361
  }
342
362
  var setSearchParams = function(url, ...objects) {
343
363
  const searchParams = new URLSearchParams(url.search);
@@ -359,18 +379,13 @@ var httpRequestFunction = async function(axiosArgs, configuration) {
359
379
  ...axiosArgs.options,
360
380
  url: (globalAxios.defaults?.baseURL ? "" : configuration?.basePath ?? "") + axiosArgs.url
361
381
  };
362
- if (configuration?.keepAlive) {
363
- axiosRequestArgs.httpsAgent = new https.Agent({
364
- ...configuration?.baseOptions?.httpsAgent instanceof https.Agent ? configuration.baseOptions.httpsAgent.options : {},
365
- keepAlive: true
366
- });
367
- }
368
- if (configuration?.compression) {
382
+ if (configuration?.keepAlive && !configuration?.baseOptions?.httpsAgent)
383
+ axiosRequestArgs.httpsAgent = new https.Agent({ keepAlive: true });
384
+ if (configuration?.compression)
369
385
  axiosRequestArgs.headers = {
370
386
  ...axiosRequestArgs.headers,
371
387
  "Accept-Encoding": "gzip, deflate, br"
372
388
  };
373
- }
374
389
  const retries = configuration?.retries ?? 0;
375
390
  const backoff = configuration?.backoff ?? 0;
376
391
  let attempt = 0;
@@ -1448,6 +1463,7 @@ export {
1448
1463
  WebsocketStreamsBase,
1449
1464
  assertParamExists,
1450
1465
  buildQueryString,
1466
+ clearSignerCache,
1451
1467
  createStreamHandler,
1452
1468
  delay,
1453
1469
  getSignature,
@@ -1458,6 +1474,7 @@ export {
1458
1474
  removeEmptyValue,
1459
1475
  replaceWebsocketStreamsPlaceholders,
1460
1476
  sendRequest,
1477
+ setFlattenedQueryParams,
1461
1478
  setSearchParams,
1462
1479
  shouldRetryRequest,
1463
1480
  sortObject,