ccxt 4.4.88 → 4.4.90

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 (85) hide show
  1. package/README.md +61 -19
  2. package/dist/ccxt.browser.min.js +3 -3
  3. package/dist/cjs/ccxt.js +1 -1
  4. package/dist/cjs/src/base/Exchange.js +6 -3
  5. package/dist/cjs/src/base/functions/encode.js +1 -1
  6. package/dist/cjs/src/base/functions/generic.js +6 -0
  7. package/dist/cjs/src/base/functions.js +1 -0
  8. package/dist/cjs/src/binance.js +1 -1
  9. package/dist/cjs/src/bingx.js +60 -32
  10. package/dist/cjs/src/bitget.js +493 -154
  11. package/dist/cjs/src/bitrue.js +72 -66
  12. package/dist/cjs/src/bitvavo.js +34 -0
  13. package/dist/cjs/src/btcalpha.js +35 -0
  14. package/dist/cjs/src/btcbox.js +35 -0
  15. package/dist/cjs/src/btcmarkets.js +35 -0
  16. package/dist/cjs/src/btcturk.js +35 -0
  17. package/dist/cjs/src/bybit.js +9 -3
  18. package/dist/cjs/src/coinbase.js +1 -4
  19. package/dist/cjs/src/cryptocom.js +54 -0
  20. package/dist/cjs/src/delta.js +2 -2
  21. package/dist/cjs/src/digifinex.js +40 -109
  22. package/dist/cjs/src/gate.js +12 -5
  23. package/dist/cjs/src/hashkey.js +15 -28
  24. package/dist/cjs/src/hollaex.js +28 -24
  25. package/dist/cjs/src/kraken.js +30 -53
  26. package/dist/cjs/src/luno.js +92 -0
  27. package/dist/cjs/src/okx.js +2 -1
  28. package/dist/cjs/src/phemex.js +16 -8
  29. package/dist/cjs/src/pro/coinbase.js +2 -0
  30. package/dist/cjs/src/pro/cryptocom.js +27 -0
  31. package/dist/cjs/src/pro/kraken.js +3 -11
  32. package/dist/cjs/src/tradeogre.js +3 -3
  33. package/dist/cjs/src/xt.js +1 -1
  34. package/js/ccxt.d.ts +1 -1
  35. package/js/ccxt.js +1 -1
  36. package/js/src/abstract/bitget.d.ts +58 -0
  37. package/js/src/abstract/cryptocom.d.ts +2 -0
  38. package/js/src/abstract/luno.d.ts +1 -0
  39. package/js/src/base/Exchange.d.ts +4 -1
  40. package/js/src/base/Exchange.js +6 -3
  41. package/js/src/base/functions/encode.d.ts +1 -1
  42. package/js/src/base/functions/encode.js +1 -1
  43. package/js/src/base/functions/generic.d.ts +2 -1
  44. package/js/src/base/functions/generic.js +6 -1
  45. package/js/src/binance.js +1 -1
  46. package/js/src/bingx.d.ts +9 -5
  47. package/js/src/bingx.js +60 -32
  48. package/js/src/bitget.d.ts +4 -1
  49. package/js/src/bitget.js +493 -154
  50. package/js/src/bitrue.js +72 -66
  51. package/js/src/bitvavo.js +34 -0
  52. package/js/src/btcalpha.js +35 -0
  53. package/js/src/btcbox.js +35 -0
  54. package/js/src/btcmarkets.js +35 -0
  55. package/js/src/btcturk.js +35 -0
  56. package/js/src/bybit.js +9 -3
  57. package/js/src/coinbase.d.ts +1 -1
  58. package/js/src/coinbase.js +1 -4
  59. package/js/src/cryptocom.d.ts +17 -0
  60. package/js/src/cryptocom.js +54 -0
  61. package/js/src/delta.js +2 -2
  62. package/js/src/digifinex.js +40 -109
  63. package/js/src/gate.d.ts +1 -1
  64. package/js/src/gate.js +12 -5
  65. package/js/src/hashkey.d.ts +0 -1
  66. package/js/src/hashkey.js +15 -28
  67. package/js/src/hollaex.d.ts +1 -2
  68. package/js/src/hollaex.js +29 -25
  69. package/js/src/kraken.d.ts +0 -1
  70. package/js/src/kraken.js +30 -53
  71. package/js/src/luno.d.ts +9 -1
  72. package/js/src/luno.js +92 -0
  73. package/js/src/okx.js +2 -1
  74. package/js/src/phemex.d.ts +1 -0
  75. package/js/src/phemex.js +16 -8
  76. package/js/src/pro/coinbase.js +2 -0
  77. package/js/src/pro/cryptocom.d.ts +16 -0
  78. package/js/src/pro/cryptocom.js +27 -0
  79. package/js/src/pro/kraken.js +3 -11
  80. package/js/src/tradeogre.js +3 -3
  81. package/js/src/xt.js +1 -1
  82. package/package.json +4 -7
  83. package/examples/README.md +0 -316
  84. package/examples/js/README.md +0 -15
  85. package/examples/js/cli.js +0 -559
@@ -3833,7 +3833,10 @@ class bybit extends bybit$1 {
3833
3833
  if (!market['spot']) {
3834
3834
  throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
3835
3835
  }
3836
- return await this.createOrder(symbol, 'market', 'buy', cost, 1, params);
3836
+ const req = {
3837
+ 'cost': cost,
3838
+ };
3839
+ return await this.createOrder(symbol, 'market', 'buy', -1, undefined, this.extend(req, params));
3837
3840
  }
3838
3841
  /**
3839
3842
  * @method
@@ -3856,7 +3859,10 @@ class bybit extends bybit$1 {
3856
3859
  if (!market['spot']) {
3857
3860
  throw new errors.NotSupported(this.id + ' createMarketSellOrderWithCost() supports spot orders only');
3858
3861
  }
3859
- return await this.createOrder(symbol, 'market', 'sell', cost, 1, params);
3862
+ const req = {
3863
+ 'cost': cost,
3864
+ };
3865
+ return await this.createOrder(symbol, 'market', 'sell', -1, undefined, this.extend(req, params));
3860
3866
  }
3861
3867
  /**
3862
3868
  * @method
@@ -4095,7 +4101,7 @@ class bybit extends bybit$1 {
4095
4101
  throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
4096
4102
  }
4097
4103
  else {
4098
- const quoteAmount = Precise["default"].stringMul(amountString, priceString);
4104
+ const quoteAmount = Precise["default"].stringMul(this.numberToString(amount), priceString);
4099
4105
  const costRequest = (cost !== undefined) ? cost : quoteAmount;
4100
4106
  request['qty'] = this.getCost(symbol, costRequest);
4101
4107
  }
@@ -4597,7 +4597,7 @@ class coinbase extends coinbase$1 {
4597
4597
  * @method
4598
4598
  * @name coinbase#closePosition
4599
4599
  * @description *futures only* closes open positions for a market
4600
- * @see https://coinbase-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions
4600
+ * @see https://docs.cdp.coinbase.com/coinbase-app/trade/reference/retailbrokerageapi_closeposition
4601
4601
  * @param {string} symbol Unified CCXT market symbol
4602
4602
  * @param {string} [side] not used by coinbase
4603
4603
  * @param {object} [params] extra parameters specific to the coinbase api endpoint
@@ -4608,9 +4608,6 @@ class coinbase extends coinbase$1 {
4608
4608
  async closePosition(symbol, side = undefined, params = {}) {
4609
4609
  await this.loadMarkets();
4610
4610
  const market = this.market(symbol);
4611
- if (!market['future']) {
4612
- throw new errors.NotSupported(this.id + ' closePosition() only supported for futures markets');
4613
- }
4614
4611
  const clientOrderId = this.safeString2(params, 'client_order_id', 'clientOrderId');
4615
4612
  params = this.omit(params, 'clientOrderId');
4616
4613
  const request = {
@@ -42,6 +42,7 @@ class cryptocom extends cryptocom$1 {
42
42
  'createOrders': true,
43
43
  'createStopOrder': true,
44
44
  'createTriggerOrder': true,
45
+ 'editOrder': true,
45
46
  'fetchAccounts': true,
46
47
  'fetchBalance': true,
47
48
  'fetchBidsAsks': false,
@@ -134,6 +135,7 @@ class cryptocom extends cryptocom$1 {
134
135
  'derivatives': 'https://uat-api.3ona.co/v2',
135
136
  },
136
137
  'api': {
138
+ 'base': 'https://api.crypto.com',
137
139
  'v1': 'https://api.crypto.com/exchange/v1',
138
140
  'v2': 'https://api.crypto.com/v2',
139
141
  'derivatives': 'https://deriv-api.crypto.com/v1',
@@ -151,6 +153,13 @@ class cryptocom extends cryptocom$1 {
151
153
  'fees': 'https://crypto.com/exchange/document/fees-limits',
152
154
  },
153
155
  'api': {
156
+ 'base': {
157
+ 'public': {
158
+ 'get': {
159
+ 'v1/public/get-announcements': 1, // no description of rate limit
160
+ },
161
+ },
162
+ },
154
163
  'v1': {
155
164
  'public': {
156
165
  'get': {
@@ -177,6 +186,7 @@ class cryptocom extends cryptocom$1 {
177
186
  'private/user-balance-history': 10 / 3,
178
187
  'private/get-positions': 10 / 3,
179
188
  'private/create-order': 2 / 3,
189
+ 'private/amend-order': 4 / 3,
180
190
  'private/create-order-list': 10 / 3,
181
191
  'private/cancel-order': 2 / 3,
182
192
  'private/cancel-order-list': 10 / 3,
@@ -1633,6 +1643,50 @@ class cryptocom extends cryptocom$1 {
1633
1643
  params = this.omit(params, ['postOnly', 'clientOrderId', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
1634
1644
  return this.extend(request, params);
1635
1645
  }
1646
+ /**
1647
+ * @method
1648
+ * @name cryptocom#editOrder
1649
+ * @description edit a trade order
1650
+ * @see https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-amend-order
1651
+ * @param {string} id order id
1652
+ * @param {string} symbol unified market symbol of the order to edit
1653
+ * @param {string} [type] not used by cryptocom editOrder
1654
+ * @param {string} [side] not used by cryptocom editOrder
1655
+ * @param {float} amount (mandatory) how much of the currency you want to trade in units of the base currency
1656
+ * @param {float} price (mandatory) the price for the order, in units of the quote currency, ignored in market orders
1657
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1658
+ * @param {string} [params.clientOrderId] the original client order id of the order to edit, required if id is not provided
1659
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1660
+ */
1661
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1662
+ await this.loadMarkets();
1663
+ const request = this.editOrderRequest(id, symbol, amount, price, params);
1664
+ const response = await this.v1PrivatePostPrivateAmendOrder(request);
1665
+ const result = this.safeDict(response, 'result', {});
1666
+ return this.parseOrder(result);
1667
+ }
1668
+ editOrderRequest(id, symbol, amount, price = undefined, params = {}) {
1669
+ const request = {};
1670
+ if (id !== undefined) {
1671
+ request['order_id'] = id;
1672
+ }
1673
+ else {
1674
+ const originalClientOrderId = this.safeString2(params, 'orig_client_oid', 'clientOrderId');
1675
+ if (originalClientOrderId === undefined) {
1676
+ throw new errors.ArgumentsRequired(this.id + ' editOrder() requires an id argument or orig_client_oid parameter');
1677
+ }
1678
+ else {
1679
+ request['orig_client_oid'] = originalClientOrderId;
1680
+ params = this.omit(params, ['orig_client_oid', 'clientOrderId']);
1681
+ }
1682
+ }
1683
+ if ((amount === undefined) || (price === undefined)) {
1684
+ throw new errors.ArgumentsRequired(this.id + ' editOrder() requires both amount and price arguments. If you do not want to change the amount or price, you should pass the original values');
1685
+ }
1686
+ request['new_quantity'] = this.amountToPrecision(symbol, amount);
1687
+ request['new_price'] = this.priceToPrecision(symbol, price);
1688
+ return this.extend(request, params);
1689
+ }
1636
1690
  /**
1637
1691
  * @method
1638
1692
  * @name cryptocom#cancelAllOrders
@@ -920,9 +920,9 @@ class delta extends delta$1 {
920
920
  'inverse': spot ? undefined : !linear,
921
921
  'taker': this.safeNumber(market, 'taker_commission_rate'),
922
922
  'maker': this.safeNumber(market, 'maker_commission_rate'),
923
- 'contractSize': contractSize,
923
+ 'contractSize': spot ? undefined : contractSize,
924
924
  'expiry': expiry,
925
- 'expiryDatetime': expiryDatetime,
925
+ 'expiryDatetime': this.iso8601(expiry),
926
926
  'strike': this.parseNumber(strike),
927
927
  'optionType': optionType,
928
928
  'precision': {
@@ -446,6 +446,16 @@ class digifinex extends digifinex$1 {
446
446
  'TRX': 'TRC20',
447
447
  'VECHAIN': 'Vechain', // VET
448
448
  },
449
+ 'networksById': {
450
+ 'TRC20': 'TRC20',
451
+ 'TRX': 'TRC20',
452
+ 'BEP20': 'BEP20',
453
+ 'BSC': 'BEP20',
454
+ 'ERC20': 'ERC20',
455
+ 'ETH': 'ERC20',
456
+ 'Polygon': 'POLYGON',
457
+ 'Crypto.com': 'CRONOS',
458
+ },
449
459
  },
450
460
  'commonCurrencies': {
451
461
  'BHT': 'Black House Test',
@@ -475,6 +485,7 @@ class digifinex extends digifinex$1 {
475
485
  // "min_withdraw_amount":10,
476
486
  // "min_withdraw_fee":5,
477
487
  // "currency":"USDT",
488
+ // "withdraw_fee_currency":"USDT",
478
489
  // "withdraw_status":0,
479
490
  // "chain":"OMNI"
480
491
  // },
@@ -485,6 +496,7 @@ class digifinex extends digifinex$1 {
485
496
  // "min_withdraw_amount":10,
486
497
  // "min_withdraw_fee":3,
487
498
  // "currency":"USDT",
499
+ // "withdraw_fee_currency":"USDT",
488
500
  // "withdraw_status":1,
489
501
  // "chain":"ERC20"
490
502
  // },
@@ -495,6 +507,7 @@ class digifinex extends digifinex$1 {
495
507
  // "min_withdraw_amount":0,
496
508
  // "min_withdraw_fee":0,
497
509
  // "currency":"DGF13",
510
+ // "withdraw_fee_currency":"DGF13",
498
511
  // "withdraw_status":0,
499
512
  // "chain":""
500
513
  // },
@@ -502,128 +515,46 @@ class digifinex extends digifinex$1 {
502
515
  // "code":200
503
516
  // }
504
517
  //
505
- const data = this.safeValue(response, 'data', []);
518
+ const data = this.safeList(response, 'data', []);
519
+ const groupedById = this.groupBy(data, 'currency');
520
+ const keys = Object.keys(groupedById);
506
521
  const result = {};
507
- for (let i = 0; i < data.length; i++) {
508
- const currency = data[i];
509
- const id = this.safeString(currency, 'currency');
522
+ for (let i = 0; i < keys.length; i++) {
523
+ const id = keys[i];
524
+ const networkEntries = groupedById[id];
510
525
  const code = this.safeCurrencyCode(id);
511
- const depositStatus = this.safeInteger(currency, 'deposit_status', 1);
512
- const withdrawStatus = this.safeInteger(currency, 'withdraw_status', 1);
513
- const deposit = depositStatus > 0;
514
- const withdraw = withdrawStatus > 0;
515
- const active = deposit && withdraw;
516
- const feeString = this.safeString(currency, 'min_withdraw_fee'); // withdraw_fee_rate was zero for all currencies, so this was the worst case scenario
517
- const minWithdrawString = this.safeString(currency, 'min_withdraw_amount');
518
- const minDepositString = this.safeString(currency, 'min_deposit_amount');
519
- const minDeposit = this.parseNumber(minDepositString);
520
- const minWithdraw = this.parseNumber(minWithdrawString);
521
- const fee = this.parseNumber(feeString);
522
- // define precision with temporary way
523
- const minFoundPrecision = Precise["default"].stringMin(feeString, Precise["default"].stringMin(minDepositString, minWithdrawString));
524
- const precision = this.parseNumber(minFoundPrecision);
525
- const networkId = this.safeString(currency, 'chain');
526
- let networkCode = undefined;
527
- if (networkId !== undefined) {
528
- networkCode = this.networkIdToCode(networkId);
529
- }
530
- const network = {
531
- 'info': currency,
532
- 'id': networkId,
533
- 'network': networkCode,
534
- 'active': active,
535
- 'fee': fee,
536
- 'precision': precision,
537
- 'deposit': deposit,
538
- 'withdraw': withdraw,
539
- 'limits': {
540
- 'amount': {
541
- 'min': undefined,
542
- 'max': undefined,
543
- },
544
- 'withdraw': {
545
- 'min': minWithdraw,
546
- 'max': undefined,
547
- },
548
- 'deposit': {
549
- 'min': minDeposit,
550
- 'max': undefined,
551
- },
552
- },
553
- };
554
- if (code in result) {
555
- let resultCodeInfo = result[code]['info'];
556
- if (Array.isArray(resultCodeInfo)) {
557
- resultCodeInfo.push(currency);
558
- }
559
- else {
560
- resultCodeInfo = [resultCodeInfo, currency];
561
- }
562
- if (withdraw) {
563
- result[code]['withdraw'] = true;
564
- result[code]['limits']['withdraw']['min'] = Math.min(result[code]['limits']['withdraw']['min'], minWithdraw);
565
- }
566
- if (deposit) {
567
- result[code]['deposit'] = true;
568
- result[code]['limits']['deposit']['min'] = Math.min(result[code]['limits']['deposit']['min'], minDeposit);
569
- }
570
- if (active) {
571
- result[code]['active'] = true;
572
- }
573
- }
574
- else {
575
- result[code] = {
576
- 'id': id,
577
- 'code': code,
578
- 'info': currency,
579
- 'type': undefined,
580
- 'name': undefined,
581
- 'active': active,
582
- 'deposit': deposit,
583
- 'withdraw': withdraw,
584
- 'fee': this.parseNumber(feeString),
526
+ const networks = {};
527
+ for (let j = 0; j < networkEntries.length; j++) {
528
+ const networkEntry = networkEntries[j];
529
+ const networkId = this.safeString(networkEntry, 'chain');
530
+ const networkCode = this.networkIdToCode(networkId);
531
+ networks[networkCode] = {
532
+ 'id': networkId,
533
+ 'network': networkCode,
534
+ 'active': undefined,
535
+ 'deposit': this.safeInteger(networkEntry, 'deposit_status') === 1,
536
+ 'withdraw': this.safeInteger(networkEntry, 'withdraw_status') === 1,
537
+ 'fee': this.safeNumber(networkEntry, 'min_withdraw_fee'),
585
538
  'precision': undefined,
586
539
  'limits': {
587
- 'amount': {
588
- 'min': undefined,
589
- 'max': undefined,
590
- },
591
540
  'withdraw': {
592
- 'min': minWithdraw,
541
+ 'min': this.safeNumber(networkEntry, 'min_withdraw_amount'),
593
542
  'max': undefined,
594
543
  },
595
544
  'deposit': {
596
- 'min': minDeposit,
545
+ 'min': this.safeNumber(networkEntry, 'min_deposit_amount'),
597
546
  'max': undefined,
598
547
  },
599
548
  },
600
- 'networks': {},
549
+ 'info': networkEntry,
601
550
  };
602
551
  }
603
- if (networkId !== undefined) {
604
- result[code]['networks'][networkId] = network;
605
- }
606
- else {
607
- result[code]['active'] = active;
608
- result[code]['fee'] = this.parseNumber(feeString);
609
- result[code]['deposit'] = deposit;
610
- result[code]['withdraw'] = withdraw;
611
- result[code]['limits'] = {
612
- 'amount': {
613
- 'min': undefined,
614
- 'max': undefined,
615
- },
616
- 'withdraw': {
617
- 'min': minWithdraw,
618
- 'max': undefined,
619
- },
620
- 'deposit': {
621
- 'min': minDeposit,
622
- 'max': undefined,
623
- },
624
- };
625
- }
626
- result[code]['precision'] = (result[code]['precision'] === undefined) ? precision : Math.max(result[code]['precision'], precision);
552
+ result[code] = this.safeCurrencyStructure({
553
+ 'id': id,
554
+ 'code': code,
555
+ 'info': networkEntries,
556
+ 'networks': networks,
557
+ });
627
558
  }
628
559
  return result;
629
560
  }
@@ -1255,17 +1255,21 @@ class gate extends gate$1 {
1255
1255
  // {
1256
1256
  // "id": "QTUM_ETH",
1257
1257
  // "base": "QTUM",
1258
+ // "base_name": "Quantum",
1258
1259
  // "quote": "ETH",
1260
+ // "quote_name": "Ethereum",
1259
1261
  // "fee": "0.2",
1260
1262
  // "min_base_amount": "0.01",
1261
1263
  // "min_quote_amount": "0.001",
1264
+ // "max_quote_amount": "50000",
1262
1265
  // "amount_precision": 3,
1263
1266
  // "precision": 6,
1264
1267
  // "trade_status": "tradable",
1265
- // "sell_start": 0,
1266
- // "buy_start": 0
1268
+ // "sell_start": 1607313600,
1269
+ // "buy_start": 1700492400,
1270
+ // "type": "normal",
1271
+ // "trade_url": "https://www.gate.io/trade/QTUM_ETH",
1267
1272
  // }
1268
- // ]
1269
1273
  //
1270
1274
  // Margin
1271
1275
  //
@@ -1296,6 +1300,8 @@ class gate extends gate$1 {
1296
1300
  const tradeStatus = this.safeString(market, 'trade_status');
1297
1301
  const leverage = this.safeNumber(market, 'leverage');
1298
1302
  const margin = leverage !== undefined;
1303
+ const buyStart = this.safeIntegerProduct(spotMarket, 'buy_start', 1000); // buy_start is the trading start time, while sell_start is offline orders start time
1304
+ const createdTs = (buyStart !== 0) ? buyStart : undefined;
1299
1305
  result.push({
1300
1306
  'id': id,
1301
1307
  'symbol': base + '/' + quote,
@@ -1345,7 +1351,7 @@ class gate extends gate$1 {
1345
1351
  'max': margin ? this.safeNumber(market, 'max_quote_amount') : undefined,
1346
1352
  },
1347
1353
  },
1348
- 'created': undefined,
1354
+ 'created': createdTs,
1349
1355
  'info': market,
1350
1356
  });
1351
1357
  }
@@ -1415,6 +1421,7 @@ class gate extends gate$1 {
1415
1421
  // "funding_next_apply": 1610035200,
1416
1422
  // "short_users": 977,
1417
1423
  // "config_change_time": 1609899548,
1424
+ // "create_time": 1609800048,
1418
1425
  // "trade_size": 28530850594,
1419
1426
  // "position_size": 5223816,
1420
1427
  // "long_users": 455,
@@ -1548,7 +1555,7 @@ class gate extends gate$1 {
1548
1555
  'max': undefined,
1549
1556
  },
1550
1557
  },
1551
- 'created': undefined,
1558
+ 'created': this.safeIntegerProduct(market, 'create_time', 1000),
1552
1559
  'info': market,
1553
1560
  };
1554
1561
  }
@@ -1134,48 +1134,44 @@ class hashkey extends hashkey$1 {
1134
1134
  const currecy = coins[i];
1135
1135
  const currencyId = this.safeString(currecy, 'coinId');
1136
1136
  const code = this.safeCurrencyCode(currencyId);
1137
- const allowWithdraw = this.safeBool(currecy, 'allowWithdraw');
1138
- const allowDeposit = this.safeBool(currecy, 'allowDeposit');
1139
1137
  const networks = this.safeList(currecy, 'chainTypes');
1140
- const networksById = this.safeDict(this.options, 'networksById');
1141
1138
  const parsedNetworks = {};
1142
1139
  for (let j = 0; j < networks.length; j++) {
1143
1140
  const network = networks[j];
1144
1141
  const networkId = this.safeString(network, 'chainType');
1145
- const networkName = this.safeString(networksById, networkId, networkId);
1146
- const maxWithdrawQuantity = this.omitZero(this.safeString(network, 'maxWithdrawQuantity'));
1147
- const networkDeposit = this.safeBool(network, 'allowDeposit');
1148
- const networkWithdraw = this.safeBool(network, 'allowWithdraw');
1149
- parsedNetworks[networkName] = {
1142
+ const networkCode = this.networkCodeToId(networkId);
1143
+ parsedNetworks[networkCode] = {
1150
1144
  'id': networkId,
1151
- 'network': networkName,
1145
+ 'network': networkCode,
1152
1146
  'limits': {
1153
1147
  'withdraw': {
1154
1148
  'min': this.safeNumber(network, 'minWithdrawQuantity'),
1155
- 'max': this.parseNumber(maxWithdrawQuantity),
1149
+ 'max': this.parseNumber(this.omitZero(this.safeString(network, 'maxWithdrawQuantity'))),
1156
1150
  },
1157
1151
  'deposit': {
1158
1152
  'min': this.safeNumber(network, 'minDepositQuantity'),
1159
1153
  'max': undefined,
1160
1154
  },
1161
1155
  },
1162
- 'active': networkDeposit && networkWithdraw,
1163
- 'deposit': networkDeposit,
1164
- 'withdraw': networkWithdraw,
1156
+ 'active': undefined,
1157
+ 'deposit': this.safeBool(network, 'allowDeposit'),
1158
+ 'withdraw': this.safeBool(network, 'allowWithdraw'),
1165
1159
  'fee': this.safeNumber(network, 'withdrawFee'),
1166
1160
  'precision': undefined,
1167
1161
  'info': network,
1168
1162
  };
1169
1163
  }
1170
- result[code] = {
1164
+ const rawType = this.safeString(currecy, 'tokenType');
1165
+ const type = (rawType === 'REAL_MONEY') ? 'fiat' : 'crypto';
1166
+ result[code] = this.safeCurrencyStructure({
1171
1167
  'id': currencyId,
1172
1168
  'code': code,
1173
1169
  'precision': undefined,
1174
- 'type': this.parseCurrencyType(this.safeString(currecy, 'tokenType')),
1170
+ 'type': type,
1175
1171
  'name': this.safeString(currecy, 'coinFullName'),
1176
- 'active': allowWithdraw && allowDeposit,
1177
- 'deposit': allowDeposit,
1178
- 'withdraw': allowWithdraw,
1172
+ 'active': undefined,
1173
+ 'deposit': this.safeBool(currecy, 'allowDeposit'),
1174
+ 'withdraw': this.safeBool(currecy, 'allowWithdraw'),
1179
1175
  'fee': undefined,
1180
1176
  'limits': {
1181
1177
  'deposit': {
@@ -1189,19 +1185,10 @@ class hashkey extends hashkey$1 {
1189
1185
  },
1190
1186
  'networks': parsedNetworks,
1191
1187
  'info': currecy,
1192
- };
1188
+ });
1193
1189
  }
1194
1190
  return result;
1195
1191
  }
1196
- parseCurrencyType(type) {
1197
- const types = {
1198
- 'CHAIN_TOKEN': 'crypto',
1199
- 'ERC20_TOKEN': 'crypto',
1200
- 'BSC_TOKEN': 'crypto',
1201
- 'REAL_MONEY': 'fiat',
1202
- };
1203
- return this.safeString(types, type);
1204
- }
1205
1192
  /**
1206
1193
  * @method
1207
1194
  * @name hashkey#fetchOrderBook
@@ -254,6 +254,7 @@ class hollaex extends hollaex$1 {
254
254
  },
255
255
  'exceptions': {
256
256
  'broad': {
257
+ 'API request is expired': errors.InvalidNonce,
257
258
  'Invalid token': errors.AuthenticationError,
258
259
  'Order not found': errors.OrderNotFound,
259
260
  'Insufficient balance': errors.InsufficientFunds,
@@ -793,7 +794,8 @@ class hollaex extends hollaex$1 {
793
794
  // "price":0.147411,
794
795
  // "timestamp":"2022-01-26T17:53:34.650Z",
795
796
  // "order_id":"cba78ecb-4187-4da2-9d2f-c259aa693b5a",
796
- // "fee":0.01031877,"fee_coin":"usdt"
797
+ // "fee":0.01031877,
798
+ // "fee_coin":"usdt"
797
799
  // }
798
800
  //
799
801
  const marketId = this.safeString(trade, 'symbol');
@@ -806,11 +808,12 @@ class hollaex extends hollaex$1 {
806
808
  const priceString = this.safeString(trade, 'price');
807
809
  const amountString = this.safeString(trade, 'size');
808
810
  const feeCostString = this.safeString(trade, 'fee');
811
+ const feeCoin = this.safeString(trade, 'fee_coin');
809
812
  let fee = undefined;
810
813
  if (feeCostString !== undefined) {
811
814
  fee = {
812
815
  'cost': feeCostString,
813
- 'currency': market['quote'],
816
+ 'currency': this.safeCurrencyCode(feeCoin),
814
817
  };
815
818
  }
816
819
  return this.safeTrade({
@@ -897,7 +900,7 @@ class hollaex extends hollaex$1 {
897
900
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
898
901
  * @param {string} timeframe the length of time each candle represents
899
902
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
900
- * @param {int} [limit] the maximum amount of candles to fetch
903
+ * @param {int} [limit] the maximum amount of candles to fetch (max 500)
901
904
  * @param {object} [params] extra parameters specific to the exchange API endpoint
902
905
  * @param {int} [params.until] timestamp in ms of the latest candle to fetch
903
906
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
@@ -909,19 +912,28 @@ class hollaex extends hollaex$1 {
909
912
  'symbol': market['id'],
910
913
  'resolution': this.safeString(this.timeframes, timeframe, timeframe),
911
914
  };
912
- const until = this.safeInteger(params, 'until');
913
- let end = this.seconds();
914
- if (until !== undefined) {
915
- end = this.parseToInt(until / 1000);
915
+ let paginate = false;
916
+ const maxLimit = 500;
917
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', paginate);
918
+ if (paginate) {
919
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
916
920
  }
917
- const defaultSpan = 2592000; // 30 days
918
- if (since !== undefined) {
919
- request['from'] = this.parseToInt(since / 1000);
921
+ let until = this.safeInteger(params, 'until');
922
+ const timeDelta = this.parseTimeframe(timeframe) * maxLimit * 1000;
923
+ let start = since;
924
+ const now = this.milliseconds();
925
+ if (until === undefined && start === undefined) {
926
+ until = now;
927
+ start = until - timeDelta;
920
928
  }
921
- else {
922
- request['from'] = end - defaultSpan;
929
+ else if (until === undefined) {
930
+ until = now; // the exchange has not a lot of trades, so if we count until by limit and limit is small, it may return empty result
931
+ }
932
+ else if (start === undefined) {
933
+ start = until - timeDelta;
923
934
  }
924
- request['to'] = end;
935
+ request['from'] = this.parseToInt(start / 1000); // convert to seconds
936
+ request['to'] = this.parseToInt(until / 1000); // convert to seconds
925
937
  params = this.omit(params, 'until');
926
938
  const response = await this.publicGetChart(this.extend(request, params));
927
939
  //
@@ -1284,11 +1296,10 @@ class hollaex extends hollaex$1 {
1284
1296
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1285
1297
  await this.loadMarkets();
1286
1298
  const market = this.market(symbol);
1287
- const convertedAmount = parseFloat(this.amountToPrecision(symbol, amount));
1288
1299
  const request = {
1289
1300
  'symbol': market['id'],
1290
1301
  'side': side,
1291
- 'size': this.normalizeNumberIfNeeded(convertedAmount),
1302
+ 'size': this.amountToPrecision(symbol, amount),
1292
1303
  'type': type,
1293
1304
  // 'stop': parseFloat (this.priceToPrecision (symbol, stopPrice)),
1294
1305
  // 'meta': {}, // other options such as post_only
@@ -1299,11 +1310,10 @@ class hollaex extends hollaex$1 {
1299
1310
  const isMarketOrder = type === 'market';
1300
1311
  const postOnly = this.isPostOnly(isMarketOrder, exchangeSpecificParam, params);
1301
1312
  if (!isMarketOrder) {
1302
- const convertedPrice = parseFloat(this.priceToPrecision(symbol, price));
1303
- request['price'] = this.normalizeNumberIfNeeded(convertedPrice);
1313
+ request['price'] = this.priceToPrecision(symbol, price);
1304
1314
  }
1305
1315
  if (triggerPrice !== undefined) {
1306
- request['stop'] = this.normalizeNumberIfNeeded(parseFloat(this.priceToPrecision(symbol, triggerPrice)));
1316
+ request['stop'] = this.priceToPrecision(symbol, triggerPrice);
1307
1317
  }
1308
1318
  if (postOnly) {
1309
1319
  request['meta'] = { 'post_only': true };
@@ -1976,12 +1986,6 @@ class hollaex extends hollaex$1 {
1976
1986
  const coins = this.safeDict(response, 'coins', {});
1977
1987
  return this.parseDepositWithdrawFees(coins, codes, 'symbol');
1978
1988
  }
1979
- normalizeNumberIfNeeded(number) {
1980
- if (this.isRoundNumber(number)) {
1981
- number = parseInt(number);
1982
- }
1983
- return number;
1984
- }
1985
1989
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1986
1990
  const query = this.omit(params, this.extractParams(path));
1987
1991
  path = '/' + this.version + '/' + this.implodeParams(path, params);