@binance/common 1.1.0 → 1.1.2
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.d.mts +35 -12
- package/dist/index.d.ts +35 -12
- package/dist/index.js +86 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +83 -58
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -248,7 +248,54 @@ var Logger = class _Logger {
|
|
|
248
248
|
import crypto from "crypto";
|
|
249
249
|
import fs from "fs";
|
|
250
250
|
import https from "https";
|
|
251
|
+
import { platform, arch } from "os";
|
|
251
252
|
import globalAxios from "axios";
|
|
253
|
+
var signerCache = /* @__PURE__ */ new WeakMap();
|
|
254
|
+
var RequestSigner = class {
|
|
255
|
+
constructor(configuration) {
|
|
256
|
+
if (configuration.apiSecret && !configuration.privateKey) {
|
|
257
|
+
this.apiSecret = configuration.apiSecret;
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (configuration.privateKey) {
|
|
261
|
+
let privateKey = configuration.privateKey;
|
|
262
|
+
if (typeof privateKey === "string" && fs.existsSync(privateKey)) {
|
|
263
|
+
privateKey = fs.readFileSync(privateKey, "utf-8");
|
|
264
|
+
}
|
|
265
|
+
const keyInput = { key: privateKey };
|
|
266
|
+
if (configuration.privateKeyPassphrase && typeof configuration.privateKeyPassphrase === "string") {
|
|
267
|
+
keyInput.passphrase = configuration.privateKeyPassphrase;
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
this.keyObject = crypto.createPrivateKey(keyInput);
|
|
271
|
+
this.keyType = this.keyObject.asymmetricKeyType;
|
|
272
|
+
} catch {
|
|
273
|
+
throw new Error(
|
|
274
|
+
"Invalid private key. Please provide a valid RSA or ED25519 private key."
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
throw new Error("Either 'apiSecret' or 'privateKey' must be provided for signed requests.");
|
|
280
|
+
}
|
|
281
|
+
sign(queryParams) {
|
|
282
|
+
const params = buildQueryString(queryParams);
|
|
283
|
+
if (this.apiSecret)
|
|
284
|
+
return crypto.createHmac("sha256", this.apiSecret).update(params).digest("hex");
|
|
285
|
+
if (this.keyObject && this.keyType) {
|
|
286
|
+
const data = Buffer.from(params);
|
|
287
|
+
if (this.keyType === "rsa")
|
|
288
|
+
return crypto.sign("RSA-SHA256", data, this.keyObject).toString("base64");
|
|
289
|
+
if (this.keyType === "ed25519")
|
|
290
|
+
return crypto.sign(null, data, this.keyObject).toString("base64");
|
|
291
|
+
throw new Error("Unsupported private key type. Must be RSA or ED25519.");
|
|
292
|
+
}
|
|
293
|
+
throw new Error("Signer is not properly initialized.");
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
var clearSignerCache = function() {
|
|
297
|
+
signerCache = /* @__PURE__ */ new WeakMap();
|
|
298
|
+
};
|
|
252
299
|
function buildQueryString(params) {
|
|
253
300
|
if (!params) return "";
|
|
254
301
|
return Object.entries(params).map(stringifyKeyValuePair).join("&");
|
|
@@ -275,39 +322,12 @@ function getTimestamp() {
|
|
|
275
322
|
return Date.now();
|
|
276
323
|
}
|
|
277
324
|
var getSignature = function(configuration, queryParams) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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.");
|
|
325
|
+
let signer = signerCache.get(configuration);
|
|
326
|
+
if (!signer) {
|
|
327
|
+
signer = new RequestSigner(configuration);
|
|
328
|
+
signerCache.set(configuration, signer);
|
|
309
329
|
}
|
|
310
|
-
return
|
|
330
|
+
return signer.sign(queryParams);
|
|
311
331
|
};
|
|
312
332
|
var assertParamExists = function(functionName, paramName, paramValue) {
|
|
313
333
|
if (paramValue === null || paramValue === void 0) {
|
|
@@ -319,25 +339,26 @@ var assertParamExists = function(functionName, paramName, paramValue) {
|
|
|
319
339
|
};
|
|
320
340
|
function setFlattenedQueryParams(urlSearchParams, parameter, key = "") {
|
|
321
341
|
if (parameter == null) return;
|
|
342
|
+
if (Array.isArray(parameter)) {
|
|
343
|
+
if (key)
|
|
344
|
+
urlSearchParams.set(key, JSON.stringify(parameter));
|
|
345
|
+
else
|
|
346
|
+
for (const item of parameter) {
|
|
347
|
+
setFlattenedQueryParams(urlSearchParams, item, "");
|
|
348
|
+
}
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
322
351
|
if (typeof parameter === "object") {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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));
|
|
352
|
+
for (const subKey of Object.keys(parameter)) {
|
|
353
|
+
const subVal = parameter[subKey];
|
|
354
|
+
const newKey = key ? `${key}.${subKey}` : subKey;
|
|
355
|
+
setFlattenedQueryParams(urlSearchParams, subVal, newKey);
|
|
339
356
|
}
|
|
357
|
+
return;
|
|
340
358
|
}
|
|
359
|
+
const str = String(parameter);
|
|
360
|
+
if (urlSearchParams.has(key)) urlSearchParams.append(key, str);
|
|
361
|
+
else urlSearchParams.set(key, str);
|
|
341
362
|
}
|
|
342
363
|
var setSearchParams = function(url, ...objects) {
|
|
343
364
|
const searchParams = new URLSearchParams(url.search);
|
|
@@ -359,18 +380,13 @@ var httpRequestFunction = async function(axiosArgs, configuration) {
|
|
|
359
380
|
...axiosArgs.options,
|
|
360
381
|
url: (globalAxios.defaults?.baseURL ? "" : configuration?.basePath ?? "") + axiosArgs.url
|
|
361
382
|
};
|
|
362
|
-
if (configuration?.keepAlive)
|
|
363
|
-
axiosRequestArgs.httpsAgent = new https.Agent({
|
|
364
|
-
|
|
365
|
-
keepAlive: true
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
if (configuration?.compression) {
|
|
383
|
+
if (configuration?.keepAlive && !configuration?.baseOptions?.httpsAgent)
|
|
384
|
+
axiosRequestArgs.httpsAgent = new https.Agent({ keepAlive: true });
|
|
385
|
+
if (configuration?.compression)
|
|
369
386
|
axiosRequestArgs.headers = {
|
|
370
387
|
...axiosRequestArgs.headers,
|
|
371
388
|
"Accept-Encoding": "gzip, deflate, br"
|
|
372
389
|
};
|
|
373
|
-
}
|
|
374
390
|
const retries = configuration?.retries ?? 0;
|
|
375
391
|
const backoff = configuration?.backoff ?? 0;
|
|
376
392
|
let attempt = 0;
|
|
@@ -578,6 +594,9 @@ function replaceWebsocketStreamsPlaceholders(str, variables) {
|
|
|
578
594
|
return "";
|
|
579
595
|
});
|
|
580
596
|
}
|
|
597
|
+
function buildUserAgent(packageName, packageVersion) {
|
|
598
|
+
return `${packageName}/${packageVersion} (Node.js/${process.version}; ${platform()}; ${arch()})`;
|
|
599
|
+
}
|
|
581
600
|
|
|
582
601
|
// src/websocket.ts
|
|
583
602
|
import { EventEmitter } from "events";
|
|
@@ -846,10 +865,13 @@ var WebsocketCommon = class _WebsocketCommon extends WebsocketEventEmitter {
|
|
|
846
865
|
* @returns A new WebSocket client instance.
|
|
847
866
|
*/
|
|
848
867
|
createWebSocket(url) {
|
|
849
|
-
|
|
868
|
+
const wsClientOptions = {
|
|
850
869
|
perMessageDeflate: this.configuration?.compression,
|
|
851
870
|
agent: this.configuration?.agent
|
|
852
|
-
}
|
|
871
|
+
};
|
|
872
|
+
if (this.configuration.userAgent)
|
|
873
|
+
wsClientOptions.headers = { "User-Agent": this.configuration.userAgent };
|
|
874
|
+
return new WebSocketClient(url, wsClientOptions);
|
|
853
875
|
}
|
|
854
876
|
/**
|
|
855
877
|
* Initializes a WebSocket connection.
|
|
@@ -1448,6 +1470,8 @@ export {
|
|
|
1448
1470
|
WebsocketStreamsBase,
|
|
1449
1471
|
assertParamExists,
|
|
1450
1472
|
buildQueryString,
|
|
1473
|
+
buildUserAgent,
|
|
1474
|
+
clearSignerCache,
|
|
1451
1475
|
createStreamHandler,
|
|
1452
1476
|
delay,
|
|
1453
1477
|
getSignature,
|
|
@@ -1458,6 +1482,7 @@ export {
|
|
|
1458
1482
|
removeEmptyValue,
|
|
1459
1483
|
replaceWebsocketStreamsPlaceholders,
|
|
1460
1484
|
sendRequest,
|
|
1485
|
+
setFlattenedQueryParams,
|
|
1461
1486
|
setSearchParams,
|
|
1462
1487
|
shouldRetryRequest,
|
|
1463
1488
|
sortObject,
|