ccxt 4.1.24 → 4.1.26

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.
Files changed (54) hide show
  1. package/README.md +3 -3
  2. package/dist/ccxt.browser.js +1368 -201
  3. package/dist/ccxt.browser.min.js +4 -4
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/ace.js +1 -1
  6. package/dist/cjs/src/base/Exchange.js +7 -3
  7. package/dist/cjs/src/base/functions/crypto.js +11 -2
  8. package/dist/cjs/src/base/functions/generic.js +5 -3
  9. package/dist/cjs/src/base/functions.js +1 -0
  10. package/dist/cjs/src/binance.js +108 -5
  11. package/dist/cjs/src/bitget.js +485 -22
  12. package/dist/cjs/src/bybit.js +132 -15
  13. package/dist/cjs/src/cryptocom.js +262 -15
  14. package/dist/cjs/src/gate.js +191 -88
  15. package/dist/cjs/src/krakenfutures.js +86 -20
  16. package/dist/cjs/src/oceanex.js +0 -12
  17. package/dist/cjs/src/okx.js +60 -1
  18. package/dist/cjs/src/pro/bybit.js +1 -1
  19. package/dist/cjs/src/static_dependencies/noble-curves/abstract/edwards.js +8 -6
  20. package/dist/cjs/src/wavesexchange.js +6 -6
  21. package/js/ccxt.d.ts +1 -1
  22. package/js/ccxt.js +1 -1
  23. package/js/src/abstract/gate.d.ts +2 -7
  24. package/js/src/abstract/gateio.d.ts +2 -7
  25. package/js/src/ace.js +1 -1
  26. package/js/src/base/Exchange.d.ts +4 -2
  27. package/js/src/base/Exchange.js +7 -3
  28. package/js/src/base/functions/crypto.d.ts +3 -2
  29. package/js/src/base/functions/crypto.js +11 -3
  30. package/js/src/base/functions/generic.d.ts +1 -1
  31. package/js/src/base/functions/generic.js +5 -3
  32. package/js/src/base/types.d.ts +8 -0
  33. package/js/src/binance.d.ts +2 -1
  34. package/js/src/binance.js +108 -5
  35. package/js/src/bitget.d.ts +31 -1
  36. package/js/src/bitget.js +485 -22
  37. package/js/src/bybit.d.ts +4 -2
  38. package/js/src/bybit.js +132 -15
  39. package/js/src/cryptocom.d.ts +4 -1
  40. package/js/src/cryptocom.js +262 -15
  41. package/js/src/gate.d.ts +3 -1
  42. package/js/src/gate.js +191 -88
  43. package/js/src/krakenfutures.d.ts +3 -1
  44. package/js/src/krakenfutures.js +86 -20
  45. package/js/src/oceanex.d.ts +0 -1
  46. package/js/src/oceanex.js +0 -12
  47. package/js/src/okx.d.ts +2 -1
  48. package/js/src/okx.js +60 -1
  49. package/js/src/pro/bybit.js +1 -1
  50. package/js/src/static_dependencies/noble-curves/abstract/edwards.d.ts +1 -0
  51. package/js/src/static_dependencies/noble-curves/abstract/edwards.js +5 -3
  52. package/js/src/wavesexchange.js +7 -7
  53. package/package.json +1 -1
  54. package/skip-tests.json +2 -3
package/dist/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.1.24';
183
+ const version = '4.1.26';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -1014,7 +1014,7 @@ class ace extends ace$1 {
1014
1014
  'timeStamp': nonce,
1015
1015
  }, params);
1016
1016
  const dataKeys = Object.keys(data);
1017
- const sortedDataKeys = this.sortBy(dataKeys, 0);
1017
+ const sortedDataKeys = this.sortBy(dataKeys, 0, false, '');
1018
1018
  for (let i = 0; i < sortedDataKeys.length; i++) {
1019
1019
  const key = sortedDataKeys[i];
1020
1020
  auth += this.safeString(data, key);
@@ -343,6 +343,7 @@ class Exchange {
343
343
  'createLimitOrder': true,
344
344
  'createMarketOrder': true,
345
345
  'createOrder': true,
346
+ 'createOrders': undefined,
346
347
  'createPostOnlyOrder': undefined,
347
348
  'createReduceOnlyOrder': undefined,
348
349
  'createStopOrder': undefined,
@@ -1615,7 +1616,7 @@ class Exchange {
1615
1616
  this.markets_by_id = {};
1616
1617
  // handle marketId conflicts
1617
1618
  // we insert spot markets first
1618
- const marketValues = this.sortBy(this.toArray(markets), 'spot', true);
1619
+ const marketValues = this.sortBy(this.toArray(markets), 'spot', true, true);
1619
1620
  for (let i = 0; i < marketValues.length; i++) {
1620
1621
  const value = marketValues[i];
1621
1622
  if (value['id'] in this.markets_by_id) {
@@ -1665,8 +1666,8 @@ class Exchange {
1665
1666
  quoteCurrencies.push(currency);
1666
1667
  }
1667
1668
  }
1668
- baseCurrencies = this.sortBy(baseCurrencies, 'code');
1669
- quoteCurrencies = this.sortBy(quoteCurrencies, 'code');
1669
+ baseCurrencies = this.sortBy(baseCurrencies, 'code', false, '');
1670
+ quoteCurrencies = this.sortBy(quoteCurrencies, 'code', false, '');
1670
1671
  this.baseCurrencies = this.indexBy(baseCurrencies, 'code');
1671
1672
  this.quoteCurrencies = this.indexBy(quoteCurrencies, 'code');
1672
1673
  const allCurrencies = this.arrayConcat(baseCurrencies, quoteCurrencies);
@@ -3328,6 +3329,9 @@ class Exchange {
3328
3329
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
3329
3330
  throw new errors.NotSupported(this.id + ' createOrder() is not supported yet');
3330
3331
  }
3332
+ async createOrders(orders, params = {}) {
3333
+ throw new errors.NotSupported(this.id + ' createOrders() is not supported yet');
3334
+ }
3331
3335
  async createOrderWs(symbol, type, side, amount, price = undefined, params = {}) {
3332
3336
  throw new errors.NotSupported(this.id + ' createOrderWs() is not supported yet');
3333
3337
  }
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var hmac$1 = require('../../static_dependencies/noble-hashes/hmac.js');
6
6
  var index = require('../../static_dependencies/scure-base/index.js');
7
+ var base64 = require('../../static_dependencies/jsencrypt/lib/asn1js/base64.js');
7
8
 
8
9
  /* ------------------------------------------------------------------------ */
9
10
  /* ------------------------------------------------------------------------ */
@@ -34,11 +35,18 @@ function ecdsa(request, secret, curve, prehash = null) {
34
35
  'v': signature.recovery,
35
36
  };
36
37
  }
37
- function eddsa(request, secret, curve) {
38
+ function axolotl(request, secret, curve) {
38
39
  // used for waves.exchange (that's why the output is base58)
39
- const signature = curve.sign(request, secret);
40
+ const signature = curve.signModified(request, secret);
40
41
  return index.base58.encode(signature);
41
42
  }
43
+ function eddsa(request, secret, curve) {
44
+ // secret is the base64 pem encoded key
45
+ // we get the last 32 bytes
46
+ const privateKey = new Uint8Array(base64.Base64.unarmor(secret).slice(16));
47
+ const signature = curve.sign(request, privateKey);
48
+ return index.base64.encode(signature);
49
+ }
42
50
  /* ------------------------------------------------------------------------ */
43
51
  // source: https://stackoverflow.com/a/18639975/1067003
44
52
  function crc32(str, signed = false) {
@@ -62,6 +70,7 @@ function crc32(str, signed = false) {
62
70
  }
63
71
  /* ------------------------------------------------------------------------ */
64
72
 
73
+ exports.axolotl = axolotl;
65
74
  exports.crc32 = crc32;
66
75
  exports.ecdsa = ecdsa;
67
76
  exports.eddsa = eddsa;
@@ -71,11 +71,13 @@ const filterBy = (x, k, value = undefined, out = []) => {
71
71
  }
72
72
  return out;
73
73
  };
74
- const sortBy = (array, key, descending = false, direction = descending ? -1 : 1) => array.sort((a, b) => {
75
- if (a[key] < b[key]) {
74
+ const sortBy = (array, key, descending = false, defaultValue = 0, direction = descending ? -1 : 1) => array.sort((a, b) => {
75
+ const first = (key in a) ? a[key] : defaultValue;
76
+ const second = (key in b) ? b[key] : defaultValue;
77
+ if (first < second) {
76
78
  return -direction;
77
79
  }
78
- else if (a[key] > b[key]) {
80
+ else if (first > second) {
79
81
  return direction;
80
82
  }
81
83
  else {
@@ -124,6 +124,7 @@ exports.urlencode = encode.urlencode;
124
124
  exports.urlencodeBase64 = encode.urlencodeBase64;
125
125
  exports.urlencodeNested = encode.urlencodeNested;
126
126
  exports.urlencodeWithArrayRepeat = encode.urlencodeWithArrayRepeat;
127
+ exports.axolotl = crypto.axolotl;
127
128
  exports.crc32 = crypto.crc32;
128
129
  exports.ecdsa = crypto.ecdsa;
129
130
  exports.eddsa = crypto.eddsa;
@@ -6,6 +6,8 @@ var Precise = require('./base/Precise.js');
6
6
  var number = require('./base/functions/number.js');
7
7
  var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
8
8
  var rsa = require('./base/functions/rsa.js');
9
+ var crypto = require('./base/functions/crypto.js');
10
+ var ed25519 = require('./static_dependencies/noble-curves/ed25519.js');
9
11
 
10
12
  // ---------------------------------------------------------------------------
11
13
  // ---------------------------------------------------------------------------
@@ -37,6 +39,7 @@ class binance extends binance$1 {
37
39
  'cancelOrders': true,
38
40
  'createDepositAddress': false,
39
41
  'createOrder': true,
42
+ 'createOrders': true,
40
43
  'createPostOnlyOrder': true,
41
44
  'createReduceOnlyOrder': true,
42
45
  'createStopLimitOrder': true,
@@ -4265,7 +4268,17 @@ class binance extends binance$1 {
4265
4268
  // "lastTrade": {"id":"69","time":"1676084430567","price":"24.9","qty":"1.00"},
4266
4269
  // "mmp": false
4267
4270
  // }
4271
+ // {
4272
+ // cancelOrders/createOrders
4273
+ // "code": -4005,
4274
+ // "msg": "Quantity greater than max quantity."
4275
+ // },
4268
4276
  //
4277
+ const code = this.safeString(order, 'code');
4278
+ if (code !== undefined) {
4279
+ // cancelOrders/createOrders might have a partial success
4280
+ return this.safeOrder({ 'info': order, 'status': 'rejected' }, market);
4281
+ }
4269
4282
  const status = this.parseOrderStatus(this.safeString(order, 'status'));
4270
4283
  const marketId = this.safeString(order, 'symbol');
4271
4284
  const marketType = ('closePosition' in order) ? 'contract' : 'spot';
@@ -4339,6 +4352,85 @@ class binance extends binance$1 {
4339
4352
  'trades': fills,
4340
4353
  }, market);
4341
4354
  }
4355
+ async createOrders(orders, params = {}) {
4356
+ /**
4357
+ * @method
4358
+ * @name binance#createOrders
4359
+ * @description *contract only* create a list of trade orders
4360
+ * @see https://binance-docs.github.io/apidocs/futures/en/#place-multiple-orders-trade
4361
+ * @param {array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
4362
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4363
+ */
4364
+ await this.loadMarkets();
4365
+ const ordersRequests = [];
4366
+ let orderSymbols = [];
4367
+ for (let i = 0; i < orders.length; i++) {
4368
+ const rawOrder = orders[i];
4369
+ const marketId = this.safeString(rawOrder, 'symbol');
4370
+ orderSymbols.push(marketId);
4371
+ const type = this.safeString(rawOrder, 'type');
4372
+ const side = this.safeString(rawOrder, 'side');
4373
+ const amount = this.safeValue(rawOrder, 'amount');
4374
+ const price = this.safeValue(rawOrder, 'price');
4375
+ const orderParams = this.safeValue(rawOrder, 'params', {});
4376
+ const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
4377
+ ordersRequests.push(orderRequest);
4378
+ }
4379
+ orderSymbols = this.marketSymbols(orderSymbols, undefined, false, true, true);
4380
+ const market = this.market(orderSymbols[0]);
4381
+ if (market['spot']) {
4382
+ throw new errors.NotSupported(this.id + ' createOrders() does not support ' + market['type'] + ' orders');
4383
+ }
4384
+ let response = undefined;
4385
+ let request = {
4386
+ 'batchOrders': ordersRequests,
4387
+ };
4388
+ request = this.extend(request, params);
4389
+ if (market['linear']) {
4390
+ response = await this.fapiPrivatePostBatchOrders(request);
4391
+ }
4392
+ else if (market['option']) {
4393
+ response = await this.eapiPrivatePostBatchOrders(request);
4394
+ }
4395
+ else {
4396
+ response = await this.dapiPrivatePostBatchOrders(request);
4397
+ }
4398
+ //
4399
+ // [
4400
+ // {
4401
+ // "code": -4005,
4402
+ // "msg": "Quantity greater than max quantity."
4403
+ // },
4404
+ // {
4405
+ // "orderId": 650640530,
4406
+ // "symbol": "LTCUSDT",
4407
+ // "status": "NEW",
4408
+ // "clientOrderId": "x-xcKtGhcu32184eb13585491289bbaf",
4409
+ // "price": "54.00",
4410
+ // "avgPrice": "0.00",
4411
+ // "origQty": "0.100",
4412
+ // "executedQty": "0.000",
4413
+ // "cumQty": "0.000",
4414
+ // "cumQuote": "0.00000",
4415
+ // "timeInForce": "GTC",
4416
+ // "type": "LIMIT",
4417
+ // "reduceOnly": false,
4418
+ // "closePosition": false,
4419
+ // "side": "BUY",
4420
+ // "positionSide": "BOTH",
4421
+ // "stopPrice": "0.00",
4422
+ // "workingType": "CONTRACT_PRICE",
4423
+ // "priceProtect": false,
4424
+ // "origType": "LIMIT",
4425
+ // "priceMatch": "NONE",
4426
+ // "selfTradePreventionMode": "NONE",
4427
+ // "goodTillDate": 0,
4428
+ // "updateTime": 1698073926929
4429
+ // }
4430
+ // ]
4431
+ //
4432
+ return this.parseOrders(response);
4433
+ }
4342
4434
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
4343
4435
  /**
4344
4436
  * @method
@@ -8434,6 +8526,12 @@ class binance extends binance$1 {
8434
8526
  }
8435
8527
  }
8436
8528
  let query = undefined;
8529
+ // handle batchOrders
8530
+ if ((path === 'batchOrders') && (method === 'POST')) {
8531
+ const batchOrders = this.safeValue(params, 'batchOrders');
8532
+ const queryBatch = (this.json(batchOrders));
8533
+ params['batchOrders'] = queryBatch;
8534
+ }
8437
8535
  const defaultRecvWindow = this.safeInteger(this.options, 'recvWindow');
8438
8536
  let extendedParams = this.extend({
8439
8537
  'timestamp': this.nonce(),
@@ -8472,7 +8570,12 @@ class binance extends binance$1 {
8472
8570
  }
8473
8571
  let signature = undefined;
8474
8572
  if (this.secret.indexOf('PRIVATE KEY') > -1) {
8475
- signature = this.encodeURIComponent(rsa.rsa(query, this.secret, sha256.sha256));
8573
+ if (this.secret.length > 120) {
8574
+ signature = this.encodeURIComponent(rsa.rsa(query, this.secret, sha256.sha256));
8575
+ }
8576
+ else {
8577
+ signature = this.encodeURIComponent(crypto.eddsa(this.encode(query), this.secret, ed25519.ed25519));
8578
+ }
8476
8579
  }
8477
8580
  else {
8478
8581
  signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
@@ -8571,10 +8674,10 @@ class binance extends binance$1 {
8571
8674
  }
8572
8675
  if (Array.isArray(response)) {
8573
8676
  // cancelOrders returns an array like this: [{"code":-2011,"msg":"Unknown order sent."}]
8574
- const numElements = response.length;
8575
- if (numElements > 0) {
8576
- const firstElement = response[0];
8577
- const errorCode = this.safeString(firstElement, 'code');
8677
+ const arrayLength = response.length;
8678
+ if (arrayLength === 1) { // when there's a single error we can throw, otherwise we have a partial success
8679
+ const element = response[0];
8680
+ const errorCode = this.safeString(element, 'code');
8578
8681
  if (errorCode !== undefined) {
8579
8682
  this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, this.id + ' ' + body);
8580
8683
  }