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
package/js/src/hollaex.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/hollaex.js';
9
- import { BadRequest, AuthenticationError, NetworkError, ArgumentsRequired, OrderNotFound, InsufficientFunds, OrderImmediatelyFillable } from './base/errors.js';
9
+ import { BadRequest, AuthenticationError, NetworkError, ArgumentsRequired, OrderNotFound, InsufficientFunds, InvalidNonce, OrderImmediatelyFillable } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TICK_SIZE } from './base/functions/number.js';
12
12
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
@@ -257,6 +257,7 @@ export default class hollaex extends Exchange {
257
257
  },
258
258
  'exceptions': {
259
259
  'broad': {
260
+ 'API request is expired': InvalidNonce,
260
261
  'Invalid token': AuthenticationError,
261
262
  'Order not found': OrderNotFound,
262
263
  'Insufficient balance': InsufficientFunds,
@@ -796,7 +797,8 @@ export default class hollaex extends Exchange {
796
797
  // "price":0.147411,
797
798
  // "timestamp":"2022-01-26T17:53:34.650Z",
798
799
  // "order_id":"cba78ecb-4187-4da2-9d2f-c259aa693b5a",
799
- // "fee":0.01031877,"fee_coin":"usdt"
800
+ // "fee":0.01031877,
801
+ // "fee_coin":"usdt"
800
802
  // }
801
803
  //
802
804
  const marketId = this.safeString(trade, 'symbol');
@@ -809,11 +811,12 @@ export default class hollaex extends Exchange {
809
811
  const priceString = this.safeString(trade, 'price');
810
812
  const amountString = this.safeString(trade, 'size');
811
813
  const feeCostString = this.safeString(trade, 'fee');
814
+ const feeCoin = this.safeString(trade, 'fee_coin');
812
815
  let fee = undefined;
813
816
  if (feeCostString !== undefined) {
814
817
  fee = {
815
818
  'cost': feeCostString,
816
- 'currency': market['quote'],
819
+ 'currency': this.safeCurrencyCode(feeCoin),
817
820
  };
818
821
  }
819
822
  return this.safeTrade({
@@ -900,7 +903,7 @@ export default class hollaex extends Exchange {
900
903
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
901
904
  * @param {string} timeframe the length of time each candle represents
902
905
  * @param {int} [since] timestamp in ms of the earliest candle to fetch
903
- * @param {int} [limit] the maximum amount of candles to fetch
906
+ * @param {int} [limit] the maximum amount of candles to fetch (max 500)
904
907
  * @param {object} [params] extra parameters specific to the exchange API endpoint
905
908
  * @param {int} [params.until] timestamp in ms of the latest candle to fetch
906
909
  * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
@@ -912,19 +915,28 @@ export default class hollaex extends Exchange {
912
915
  'symbol': market['id'],
913
916
  'resolution': this.safeString(this.timeframes, timeframe, timeframe),
914
917
  };
915
- const until = this.safeInteger(params, 'until');
916
- let end = this.seconds();
917
- if (until !== undefined) {
918
- end = this.parseToInt(until / 1000);
918
+ let paginate = false;
919
+ const maxLimit = 500;
920
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', paginate);
921
+ if (paginate) {
922
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
919
923
  }
920
- const defaultSpan = 2592000; // 30 days
921
- if (since !== undefined) {
922
- request['from'] = this.parseToInt(since / 1000);
924
+ let until = this.safeInteger(params, 'until');
925
+ const timeDelta = this.parseTimeframe(timeframe) * maxLimit * 1000;
926
+ let start = since;
927
+ const now = this.milliseconds();
928
+ if (until === undefined && start === undefined) {
929
+ until = now;
930
+ start = until - timeDelta;
923
931
  }
924
- else {
925
- request['from'] = end - defaultSpan;
932
+ else if (until === undefined) {
933
+ 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
934
+ }
935
+ else if (start === undefined) {
936
+ start = until - timeDelta;
926
937
  }
927
- request['to'] = end;
938
+ request['from'] = this.parseToInt(start / 1000); // convert to seconds
939
+ request['to'] = this.parseToInt(until / 1000); // convert to seconds
928
940
  params = this.omit(params, 'until');
929
941
  const response = await this.publicGetChart(this.extend(request, params));
930
942
  //
@@ -1287,11 +1299,10 @@ export default class hollaex extends Exchange {
1287
1299
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1288
1300
  await this.loadMarkets();
1289
1301
  const market = this.market(symbol);
1290
- const convertedAmount = parseFloat(this.amountToPrecision(symbol, amount));
1291
1302
  const request = {
1292
1303
  'symbol': market['id'],
1293
1304
  'side': side,
1294
- 'size': this.normalizeNumberIfNeeded(convertedAmount),
1305
+ 'size': this.amountToPrecision(symbol, amount),
1295
1306
  'type': type,
1296
1307
  // 'stop': parseFloat (this.priceToPrecision (symbol, stopPrice)),
1297
1308
  // 'meta': {}, // other options such as post_only
@@ -1302,11 +1313,10 @@ export default class hollaex extends Exchange {
1302
1313
  const isMarketOrder = type === 'market';
1303
1314
  const postOnly = this.isPostOnly(isMarketOrder, exchangeSpecificParam, params);
1304
1315
  if (!isMarketOrder) {
1305
- const convertedPrice = parseFloat(this.priceToPrecision(symbol, price));
1306
- request['price'] = this.normalizeNumberIfNeeded(convertedPrice);
1316
+ request['price'] = this.priceToPrecision(symbol, price);
1307
1317
  }
1308
1318
  if (triggerPrice !== undefined) {
1309
- request['stop'] = this.normalizeNumberIfNeeded(parseFloat(this.priceToPrecision(symbol, triggerPrice)));
1319
+ request['stop'] = this.priceToPrecision(symbol, triggerPrice);
1310
1320
  }
1311
1321
  if (postOnly) {
1312
1322
  request['meta'] = { 'post_only': true };
@@ -1979,12 +1989,6 @@ export default class hollaex extends Exchange {
1979
1989
  const coins = this.safeDict(response, 'coins', {});
1980
1990
  return this.parseDepositWithdrawFees(coins, codes, 'symbol');
1981
1991
  }
1982
- normalizeNumberIfNeeded(number) {
1983
- if (this.isRoundNumber(number)) {
1984
- number = parseInt(number);
1985
- }
1986
- return number;
1987
- }
1988
1992
  sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1989
1993
  const query = this.omit(params, this.extractParams(path));
1990
1994
  path = '/' + this.version + '/' + this.implodeParams(path, params);
@@ -18,7 +18,6 @@ export default class kraken extends Exchange {
18
18
  */
19
19
  fetchMarkets(params?: {}): Promise<Market[]>;
20
20
  safeCurrency(currencyId: any, currency?: Currency): import("./base/types.js").CurrencyInterface;
21
- appendInactiveMarkets(result: any): any;
22
21
  /**
23
22
  * @method
24
23
  * @name kraken#fetchStatus
package/js/src/kraken.js CHANGED
@@ -554,10 +554,13 @@ export default class kraken extends Exchange {
554
554
  * @returns {object[]} an array of objects representing market data
555
555
  */
556
556
  async fetchMarkets(params = {}) {
557
+ const promises = [];
558
+ promises.push(this.publicGetAssetPairs(params));
557
559
  if (this.options['adjustForTimeDifference']) {
558
- await this.loadTimeDifference();
560
+ promises.push(this.loadTimeDifference());
559
561
  }
560
- const response = await this.publicGetAssetPairs(params);
562
+ const responses = await Promise.all(promises);
563
+ const assetsResponse = responses[0];
561
564
  //
562
565
  // {
563
566
  // "error": [],
@@ -605,9 +608,10 @@ export default class kraken extends Exchange {
605
608
  // }
606
609
  // }
607
610
  //
608
- const markets = this.safeValue(response, 'result', {});
611
+ const markets = this.safeDict(assetsResponse, 'result', {});
612
+ const cachedCurrencies = this.safeDict(this.options, 'cachedCurrencies', {});
609
613
  const keys = Object.keys(markets);
610
- let result = [];
614
+ const result = [];
611
615
  for (let i = 0; i < keys.length; i++) {
612
616
  const id = keys[i];
613
617
  const market = markets[id];
@@ -615,41 +619,49 @@ export default class kraken extends Exchange {
615
619
  const quoteId = this.safeString(market, 'quote');
616
620
  const base = this.safeCurrencyCode(baseId);
617
621
  const quote = this.safeCurrencyCode(quoteId);
618
- const darkpool = id.indexOf('.d') >= 0;
619
- const altname = this.safeString(market, 'altname');
620
- const makerFees = this.safeValue(market, 'fees_maker', []);
621
- const firstMakerFee = this.safeValue(makerFees, 0, []);
622
+ const makerFees = this.safeList(market, 'fees_maker', []);
623
+ const firstMakerFee = this.safeList(makerFees, 0, []);
622
624
  const firstMakerFeeRate = this.safeString(firstMakerFee, 1);
623
625
  let maker = undefined;
624
626
  if (firstMakerFeeRate !== undefined) {
625
627
  maker = this.parseNumber(Precise.stringDiv(firstMakerFeeRate, '100'));
626
628
  }
627
- const takerFees = this.safeValue(market, 'fees', []);
628
- const firstTakerFee = this.safeValue(takerFees, 0, []);
629
+ const takerFees = this.safeList(market, 'fees', []);
630
+ const firstTakerFee = this.safeList(takerFees, 0, []);
629
631
  const firstTakerFeeRate = this.safeString(firstTakerFee, 1);
630
632
  let taker = undefined;
631
633
  if (firstTakerFeeRate !== undefined) {
632
634
  taker = this.parseNumber(Precise.stringDiv(firstTakerFeeRate, '100'));
633
635
  }
634
- const leverageBuy = this.safeValue(market, 'leverage_buy', []);
636
+ const leverageBuy = this.safeList(market, 'leverage_buy', []);
635
637
  const leverageBuyLength = leverageBuy.length;
636
638
  const precisionPrice = this.parseNumber(this.parsePrecision(this.safeString(market, 'pair_decimals')));
639
+ let precisionAmount = this.parseNumber(this.parsePrecision(this.safeString(market, 'lot_decimals')));
640
+ const spot = true;
641
+ // fix https://github.com/freqtrade/freqtrade/issues/11765#issuecomment-2894224103
642
+ if (spot && (base in cachedCurrencies)) {
643
+ const currency = cachedCurrencies[base];
644
+ const currencyPrecision = this.safeNumber(currency, 'precision');
645
+ // if currency precision is greater (e.g. 0.01) than market precision (e.g. 0.001)
646
+ if (currencyPrecision > precisionAmount) {
647
+ precisionAmount = currencyPrecision;
648
+ }
649
+ }
637
650
  const status = this.safeString(market, 'status');
638
651
  const isActive = status === 'online';
639
652
  result.push({
640
653
  'id': id,
641
654
  'wsId': this.safeString(market, 'wsname'),
642
- 'symbol': darkpool ? altname : (base + '/' + quote),
655
+ 'symbol': base + '/' + quote,
643
656
  'base': base,
644
657
  'quote': quote,
645
658
  'settle': undefined,
646
659
  'baseId': baseId,
647
660
  'quoteId': quoteId,
648
661
  'settleId': undefined,
649
- 'darkpool': darkpool,
650
662
  'altname': market['altname'],
651
663
  'type': 'spot',
652
- 'spot': true,
664
+ 'spot': spot,
653
665
  'margin': (leverageBuyLength > 0),
654
666
  'swap': false,
655
667
  'future': false,
@@ -666,7 +678,7 @@ export default class kraken extends Exchange {
666
678
  'strike': undefined,
667
679
  'optionType': undefined,
668
680
  'precision': {
669
- 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'lot_decimals'))),
681
+ 'amount': precisionAmount,
670
682
  'price': precisionPrice,
671
683
  },
672
684
  'limits': {
@@ -679,7 +691,7 @@ export default class kraken extends Exchange {
679
691
  'max': undefined,
680
692
  },
681
693
  'price': {
682
- 'min': precisionPrice,
694
+ 'min': undefined,
683
695
  'max': undefined,
684
696
  },
685
697
  'cost': {
@@ -691,7 +703,6 @@ export default class kraken extends Exchange {
691
703
  'info': market,
692
704
  });
693
705
  }
694
- result = this.appendInactiveMarkets(result);
695
706
  this.options['marketsByAltname'] = this.indexBy(result, 'altname');
696
707
  return result;
697
708
  }
@@ -707,33 +718,6 @@ export default class kraken extends Exchange {
707
718
  }
708
719
  return super.safeCurrency(currencyId, currency);
709
720
  }
710
- appendInactiveMarkets(result) {
711
- // result should be an array to append to
712
- const precision = {
713
- 'amount': this.parseNumber('1e-8'),
714
- 'price': this.parseNumber('1e-8'),
715
- };
716
- const costLimits = { 'min': undefined, 'max': undefined };
717
- const priceLimits = { 'min': precision['price'], 'max': undefined };
718
- const amountLimits = { 'min': precision['amount'], 'max': undefined };
719
- const limits = { 'amount': amountLimits, 'price': priceLimits, 'cost': costLimits };
720
- const defaults = {
721
- 'darkpool': false,
722
- 'info': undefined,
723
- 'maker': undefined,
724
- 'taker': undefined,
725
- 'active': false,
726
- 'precision': precision,
727
- 'limits': limits,
728
- };
729
- const markets = [
730
- // { 'id': 'XXLMZEUR', 'symbol': 'XLM/EUR', 'base': 'XLM', 'quote': 'EUR', 'altname': 'XLMEUR' },
731
- ];
732
- for (let i = 0; i < markets.length; i++) {
733
- result.push(this.extend(defaults, markets[i]));
734
- }
735
- return result;
736
- }
737
721
  /**
738
722
  * @method
739
723
  * @name kraken#fetchStatus
@@ -980,9 +964,6 @@ export default class kraken extends Exchange {
980
964
  async fetchOrderBook(symbol, limit = undefined, params = {}) {
981
965
  await this.loadMarkets();
982
966
  const market = this.market(symbol);
983
- if (market['darkpool']) {
984
- throw new ExchangeError(this.id + ' fetchOrderBook() does not provide an order book for darkpool symbol ' + symbol);
985
- }
986
967
  const request = {
987
968
  'pair': market['id'],
988
969
  };
@@ -1087,7 +1068,7 @@ export default class kraken extends Exchange {
1087
1068
  for (let i = 0; i < symbols.length; i++) {
1088
1069
  const symbol = symbols[i];
1089
1070
  const market = this.markets[symbol];
1090
- if (market['active'] && !market['darkpool']) {
1071
+ if (market['active']) {
1091
1072
  marketIds.push(market['id']);
1092
1073
  }
1093
1074
  }
@@ -1117,10 +1098,6 @@ export default class kraken extends Exchange {
1117
1098
  */
1118
1099
  async fetchTicker(symbol, params = {}) {
1119
1100
  await this.loadMarkets();
1120
- const darkpool = symbol.indexOf('.d') >= 0;
1121
- if (darkpool) {
1122
- throw new ExchangeError(this.id + ' fetchTicker() does not provide a ticker for darkpool symbol ' + symbol);
1123
- }
1124
1101
  const market = this.market(symbol);
1125
1102
  const request = {
1126
1103
  'pair': market['id'],
@@ -3501,7 +3478,7 @@ export default class kraken extends Exchange {
3501
3478
  for (let i = 0; i < response['error'].length; i++) {
3502
3479
  const error = response['error'][i];
3503
3480
  this.throwExactlyMatchedException(this.exceptions['exact'], error, message);
3504
- this.throwExactlyMatchedException(this.exceptions['broad'], error, message);
3481
+ this.throwBroadlyMatchedException(this.exceptions['broad'], error, message);
3505
3482
  }
3506
3483
  throw new ExchangeError(message);
3507
3484
  }
package/js/src/luno.d.ts CHANGED
@@ -1,11 +1,19 @@
1
1
  import Exchange from './abstract/luno.js';
2
- import type { Balances, Currency, Int, Market, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, OHLCV, Num, Account, TradingFeeInterface, Dict, int, LedgerEntry, DepositAddress } from './base/types.js';
2
+ import type { Balances, Currency, Currencies, Int, Market, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, OHLCV, Num, Account, TradingFeeInterface, Dict, int, LedgerEntry, DepositAddress } from './base/types.js';
3
3
  /**
4
4
  * @class luno
5
5
  * @augments Exchange
6
6
  */
7
7
  export default class luno extends Exchange {
8
8
  describe(): any;
9
+ /**
10
+ * @method
11
+ * @name luno#fetchCurrencies
12
+ * @description fetches all available currencies on an exchange
13
+ * @param {dict} [params] extra parameters specific to the exchange API endpoint
14
+ * @returns {dict} an associative dictionary of currencies
15
+ */
16
+ fetchCurrencies(params?: {}): Promise<Currencies>;
9
17
  /**
10
18
  * @method
11
19
  * @name luno#fetchMarkets
package/js/src/luno.js CHANGED
@@ -44,6 +44,7 @@ export default class luno extends Exchange {
44
44
  'fetchClosedOrders': true,
45
45
  'fetchCrossBorrowRate': false,
46
46
  'fetchCrossBorrowRates': false,
47
+ 'fetchCurrencies': true,
47
48
  'fetchDepositAddress': true,
48
49
  'fetchFundingHistory': false,
49
50
  'fetchFundingRate': false,
@@ -125,6 +126,7 @@ export default class luno extends Exchange {
125
126
  'accounts/{id}/transactions': 1,
126
127
  'balance': 1,
127
128
  'beneficiaries': 1,
129
+ 'send/networks': 1,
128
130
  'fee_info': 1,
129
131
  'funding_address': 1,
130
132
  'listorders': 1,
@@ -265,6 +267,96 @@ export default class luno extends Exchange {
265
267
  },
266
268
  });
267
269
  }
270
+ /**
271
+ * @method
272
+ * @name luno#fetchCurrencies
273
+ * @description fetches all available currencies on an exchange
274
+ * @param {dict} [params] extra parameters specific to the exchange API endpoint
275
+ * @returns {dict} an associative dictionary of currencies
276
+ */
277
+ async fetchCurrencies(params = {}) {
278
+ if (!this.checkRequiredCredentials(false)) {
279
+ return undefined;
280
+ }
281
+ const response = await this.privateGetSendNetworks(params);
282
+ //
283
+ // {
284
+ // "networks": [
285
+ // {
286
+ // "id": 0,
287
+ // "name": "Ethereum",
288
+ // "native_currency": "ETH"
289
+ // },
290
+ // ...
291
+ // ]
292
+ // }
293
+ //
294
+ const currenciesData = this.safeList(response, 'data', []);
295
+ const result = {};
296
+ for (let i = 0; i < currenciesData.length; i++) {
297
+ const networkEntry = currenciesData[i];
298
+ const id = this.safeString(networkEntry, 'native_currency');
299
+ const code = this.safeCurrencyCode(id);
300
+ if (!(code in result)) {
301
+ result[code] = {
302
+ 'id': id,
303
+ 'code': code,
304
+ 'precision': undefined,
305
+ 'type': undefined,
306
+ 'name': undefined,
307
+ 'active': undefined,
308
+ 'deposit': undefined,
309
+ 'withdraw': undefined,
310
+ 'fee': undefined,
311
+ 'limits': {
312
+ 'withdraw': {
313
+ 'min': undefined,
314
+ 'max': undefined,
315
+ },
316
+ 'deposit': {
317
+ 'min': undefined,
318
+ 'max': undefined,
319
+ },
320
+ },
321
+ 'networks': {},
322
+ 'info': {},
323
+ };
324
+ }
325
+ const networkId = this.safeString(networkEntry, 'name');
326
+ const networkCode = this.networkIdToCode(networkId);
327
+ result[code]['networks'][networkCode] = {
328
+ 'id': networkId,
329
+ 'network': networkCode,
330
+ 'limits': {
331
+ 'withdraw': {
332
+ 'min': undefined,
333
+ 'max': undefined,
334
+ },
335
+ 'deposit': {
336
+ 'min': undefined,
337
+ 'max': undefined,
338
+ },
339
+ },
340
+ 'active': undefined,
341
+ 'deposit': undefined,
342
+ 'withdraw': undefined,
343
+ 'fee': undefined,
344
+ 'precision': undefined,
345
+ 'info': networkEntry,
346
+ };
347
+ // add entry in info
348
+ const info = this.safeList(result[code], 'info', []);
349
+ info.push(networkEntry);
350
+ result[code]['info'] = info;
351
+ }
352
+ // only after all entries are formed in currencies, restructure each entry
353
+ const allKeys = Object.keys(result);
354
+ for (let i = 0; i < allKeys.length; i++) {
355
+ const code = allKeys[i];
356
+ result[code] = this.safeCurrencyStructure(result[code]); // this is needed after adding network entry
357
+ }
358
+ return result;
359
+ }
268
360
  /**
269
361
  * @method
270
362
  * @name luno#fetchMarkets
package/js/src/okx.js CHANGED
@@ -1597,6 +1597,7 @@ export default class okx extends Exchange {
1597
1597
  // "instType": "OPTION",
1598
1598
  // "lever": "",
1599
1599
  // "listTime": "1631262612280",
1600
+ // "contTdSwTime": "1631262812280",
1600
1601
  // "lotSz": "1",
1601
1602
  // "minSz": "1",
1602
1603
  // "optType": "P",
@@ -1684,7 +1685,7 @@ export default class okx extends Exchange {
1684
1685
  'expiryDatetime': this.iso8601(expiry),
1685
1686
  'strike': this.parseNumber(strikePrice),
1686
1687
  'optionType': optionType,
1687
- 'created': this.safeInteger(market, 'listTime'),
1688
+ 'created': this.safeInteger2(market, 'contTdSwTime', 'listTime'),
1688
1689
  'precision': {
1689
1690
  'amount': this.safeNumber(market, 'lotSz'),
1690
1691
  'price': this.safeNumber(market, 'tickSz'),
@@ -253,6 +253,7 @@ export default class phemex extends Exchange {
253
253
  * @description fetch the deposit address for a currency associated with this account
254
254
  * @param {string} code unified currency code
255
255
  * @param {object} [params] extra parameters specific to the exchange API endpoint
256
+ * @param {string} [params.network] the chain name to fetch the deposit address e.g. ETH, TRX, EOS, SOL, etc.
256
257
  * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
257
258
  */
258
259
  fetchDepositAddress(code: string, params?: {}): Promise<DepositAddress>;
package/js/src/phemex.js CHANGED
@@ -584,6 +584,7 @@ export default class phemex extends Exchange {
584
584
  },
585
585
  'defaultNetworks': {
586
586
  'USDT': 'ETH',
587
+ 'MKR': 'ETH',
587
588
  },
588
589
  'defaultSubType': 'linear',
589
590
  'accountsByType': {
@@ -3534,6 +3535,7 @@ export default class phemex extends Exchange {
3534
3535
  * @description fetch the deposit address for a currency associated with this account
3535
3536
  * @param {string} code unified currency code
3536
3537
  * @param {object} [params] extra parameters specific to the exchange API endpoint
3538
+ * @param {string} [params.network] the chain name to fetch the deposit address e.g. ETH, TRX, EOS, SOL, etc.
3537
3539
  * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
3538
3540
  */
3539
3541
  async fetchDepositAddress(code, params = {}) {
@@ -3545,22 +3547,28 @@ export default class phemex extends Exchange {
3545
3547
  const defaultNetworks = this.safeDict(this.options, 'defaultNetworks');
3546
3548
  const defaultNetwork = this.safeStringUpper(defaultNetworks, code);
3547
3549
  const networks = this.safeDict(this.options, 'networks', {});
3548
- let network = this.safeStringUpper(params, 'network', defaultNetwork);
3550
+ let network = this.safeStringUpper2(params, 'network', 'chainName', defaultNetwork);
3549
3551
  network = this.safeString(networks, network, network);
3550
3552
  if (network === undefined) {
3551
- request['chainName'] = currency['id'];
3553
+ throw new ArgumentsRequired(this.id + ' fetchDepositAddress() requires a network parameter');
3552
3554
  }
3553
3555
  else {
3554
3556
  request['chainName'] = network;
3555
3557
  params = this.omit(params, 'network');
3556
3558
  }
3557
- const response = await this.privateGetPhemexUserWalletsV2DepositAddress(this.extend(request, params));
3559
+ const response = await this.privateGetExchangeWalletsV2DepositAddress(this.extend(request, params));
3560
+ //
3558
3561
  // {
3559
- // "code":0,
3560
- // "msg":"OK",
3561
- // "data":{
3562
- // "address":"0x5bfbf60e0fa7f63598e6cfd8a7fd3ffac4ccc6ad",
3563
- // "tag":null
3562
+ // "code": 0,
3563
+ // "msg": "OK",
3564
+ // "data": {
3565
+ // "address": "tb1qxel5wq5gumt",
3566
+ // "tag": "",
3567
+ // "notice": false,
3568
+ // "accountType": 1,
3569
+ // "contractName": null,
3570
+ // "chainTokenUrl": null,
3571
+ // "sign": null
3564
3572
  // }
3565
3573
  // }
3566
3574
  //
@@ -164,6 +164,7 @@ export default class coinbase extends coinbaseRest {
164
164
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
165
165
  */
166
166
  async watchTicker(symbol, params = {}) {
167
+ await this.loadMarkets();
167
168
  const name = 'ticker';
168
169
  return await this.subscribe(name, false, symbol, params);
169
170
  }
@@ -177,6 +178,7 @@ export default class coinbase extends coinbaseRest {
177
178
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
178
179
  */
179
180
  async watchTickers(symbols = undefined, params = {}) {
181
+ await this.loadMarkets();
180
182
  if (symbols === undefined) {
181
183
  symbols = this.symbols;
182
184
  }
@@ -246,6 +246,22 @@ export default class cryptocom extends cryptocomRest {
246
246
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
247
247
  */
248
248
  createOrderWs(symbol: string, type: OrderType, side: OrderSide, amount: number, price?: Num, params?: {}): Promise<Order>;
249
+ /**
250
+ * @method
251
+ * @name cryptocom#editOrderWs
252
+ * @description edit a trade order
253
+ * @see https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-amend-order
254
+ * @param {string} id order id
255
+ * @param {string} symbol unified market symbol of the order to edit
256
+ * @param {string} [type] not used by cryptocom editOrder
257
+ * @param {string} [side] not used by cryptocom editOrder
258
+ * @param {float} amount (mandatory) how much of the currency you want to trade in units of the base currency
259
+ * @param {float} price (mandatory) the price for the order, in units of the quote currency, ignored in market orders
260
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
261
+ * @param {string} [params.clientOrderId] the original client order id of the order to edit, required if id is not provided
262
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
263
+ */
264
+ editOrderWs(id: string, symbol: string, type: OrderType, side: OrderSide, amount?: Num, price?: Num, params?: {}): Promise<Order>;
249
265
  handleOrder(client: Client, message: any): void;
250
266
  /**
251
267
  * @method
@@ -30,6 +30,7 @@ export default class cryptocom extends cryptocomRest {
30
30
  'createOrderWs': true,
31
31
  'cancelOrderWs': true,
32
32
  'cancelAllOrders': true,
33
+ 'editOrderWs': true,
33
34
  },
34
35
  'urls': {
35
36
  'api': {
@@ -1062,6 +1063,31 @@ export default class cryptocom extends cryptocomRest {
1062
1063
  const messageHash = this.nonce();
1063
1064
  return await this.watchPrivateRequest(messageHash, request);
1064
1065
  }
1066
+ /**
1067
+ * @method
1068
+ * @name cryptocom#editOrderWs
1069
+ * @description edit a trade order
1070
+ * @see https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-amend-order
1071
+ * @param {string} id order id
1072
+ * @param {string} symbol unified market symbol of the order to edit
1073
+ * @param {string} [type] not used by cryptocom editOrder
1074
+ * @param {string} [side] not used by cryptocom editOrder
1075
+ * @param {float} amount (mandatory) how much of the currency you want to trade in units of the base currency
1076
+ * @param {float} price (mandatory) the price for the order, in units of the quote currency, ignored in market orders
1077
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1078
+ * @param {string} [params.clientOrderId] the original client order id of the order to edit, required if id is not provided
1079
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1080
+ */
1081
+ async editOrderWs(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1082
+ await this.loadMarkets();
1083
+ params = this.editOrderRequest(id, symbol, amount, price, params);
1084
+ const request = {
1085
+ 'method': 'private/amend-order',
1086
+ 'params': params,
1087
+ };
1088
+ const messageHash = this.nonce();
1089
+ return await this.watchPrivateRequest(messageHash, request);
1090
+ }
1065
1091
  handleOrder(client, message) {
1066
1092
  //
1067
1093
  // {
@@ -1313,6 +1339,7 @@ export default class cryptocom extends cryptocomRest {
1313
1339
  'public/heartbeat': this.handlePing,
1314
1340
  'public/auth': this.handleAuthenticate,
1315
1341
  'private/create-order': this.handleOrder,
1342
+ 'private/amend-order': this.handleOrder,
1316
1343
  'private/cancel-order': this.handleOrder,
1317
1344
  'private/cancel-all-orders': this.handleCancelAllOrders,
1318
1345
  'private/close-position': this.handleOrder,
@@ -864,17 +864,9 @@ export default class kraken extends krakenRest {
864
864
  for (let i = 0; i < this.symbols.length; i++) {
865
865
  const symbol = this.symbols[i];
866
866
  const market = this.markets[symbol];
867
- if (market['darkpool']) {
868
- const info = this.safeValue(market, 'info', {});
869
- const altname = this.safeString(info, 'altname');
870
- const wsName = altname.slice(0, 3) + '/' + altname.slice(3);
871
- marketsByWsName[wsName] = market;
872
- }
873
- else {
874
- const info = this.safeValue(market, 'info', {});
875
- const wsName = this.safeString(info, 'wsname');
876
- marketsByWsName[wsName] = market;
877
- }
867
+ const info = this.safeValue(market, 'info', {});
868
+ const wsName = this.safeString(info, 'wsname');
869
+ marketsByWsName[wsName] = market;
878
870
  }
879
871
  this.options['marketsByWsName'] = marketsByWsName;
880
872
  }