ccxt 4.4.82__py2.py3-none-any.whl → 4.4.86__py2.py3-none-any.whl

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 (121) hide show
  1. ccxt/__init__.py +3 -9
  2. ccxt/abstract/blofin.py +8 -0
  3. ccxt/abstract/btcbox.py +1 -0
  4. ccxt/abstract/myokx.py +2 -0
  5. ccxt/abstract/okx.py +2 -0
  6. ccxt/apex.py +2 -1
  7. ccxt/ascendex.py +187 -151
  8. ccxt/async_support/__init__.py +3 -9
  9. ccxt/async_support/apex.py +2 -1
  10. ccxt/async_support/ascendex.py +187 -151
  11. ccxt/async_support/base/exchange.py +51 -24
  12. ccxt/async_support/base/ws/cache.py +6 -1
  13. ccxt/async_support/bequant.py +1 -1
  14. ccxt/async_support/bitget.py +5 -6
  15. ccxt/async_support/bitmart.py +1 -1
  16. ccxt/async_support/bitrue.py +14 -32
  17. ccxt/async_support/bitso.py +33 -0
  18. ccxt/async_support/bitstamp.py +33 -0
  19. ccxt/async_support/{huobijp.py → bittrade.py} +11 -11
  20. ccxt/async_support/blofin.py +145 -14
  21. ccxt/async_support/btcbox.py +25 -5
  22. ccxt/async_support/bybit.py +16 -37
  23. ccxt/async_support/cex.py +2 -4
  24. ccxt/async_support/coinbase.py +58 -47
  25. ccxt/async_support/coinbaseexchange.py +141 -32
  26. ccxt/async_support/coincatch.py +14 -67
  27. ccxt/async_support/coinex.py +28 -29
  28. ccxt/async_support/coinlist.py +17 -16
  29. ccxt/async_support/coinmetro.py +20 -11
  30. ccxt/async_support/coinone.py +8 -10
  31. ccxt/async_support/coinsph.py +124 -2
  32. ccxt/async_support/cryptocom.py +109 -2
  33. ccxt/async_support/cryptomus.py +42 -80
  34. ccxt/async_support/delta.py +75 -36
  35. ccxt/async_support/deribit.py +4 -5
  36. ccxt/async_support/derive.py +46 -10
  37. ccxt/async_support/ellipx.py +175 -77
  38. ccxt/async_support/gate.py +1 -1
  39. ccxt/async_support/gemini.py +3 -4
  40. ccxt/async_support/hitbtc.py +56 -65
  41. ccxt/async_support/hollaex.py +106 -49
  42. ccxt/async_support/htx.py +20 -43
  43. ccxt/async_support/hyperliquid.py +6 -6
  44. ccxt/async_support/kraken.py +27 -23
  45. ccxt/async_support/kucoinfutures.py +5 -0
  46. ccxt/async_support/lbank.py +1 -1
  47. ccxt/async_support/mexc.py +2 -2
  48. ccxt/async_support/ndax.py +25 -24
  49. ccxt/async_support/okcoin.py +12 -29
  50. ccxt/async_support/okx.py +9 -0
  51. ccxt/async_support/onetrading.py +10 -7
  52. ccxt/async_support/oxfun.py +40 -110
  53. ccxt/async_support/paradex.py +123 -4
  54. ccxt/base/exchange.py +21 -2
  55. ccxt/base/types.py +3 -0
  56. ccxt/bequant.py +1 -1
  57. ccxt/bitget.py +5 -6
  58. ccxt/bitmart.py +1 -1
  59. ccxt/bitrue.py +14 -32
  60. ccxt/bitso.py +33 -0
  61. ccxt/bitstamp.py +33 -0
  62. ccxt/{huobijp.py → bittrade.py} +11 -11
  63. ccxt/blofin.py +145 -14
  64. ccxt/btcbox.py +24 -5
  65. ccxt/bybit.py +16 -37
  66. ccxt/cex.py +2 -4
  67. ccxt/coinbase.py +58 -47
  68. ccxt/coinbaseexchange.py +141 -32
  69. ccxt/coincatch.py +14 -67
  70. ccxt/coinex.py +28 -29
  71. ccxt/coinlist.py +17 -16
  72. ccxt/coinmetro.py +20 -11
  73. ccxt/coinone.py +8 -10
  74. ccxt/coinsph.py +124 -2
  75. ccxt/cryptocom.py +109 -2
  76. ccxt/cryptomus.py +42 -80
  77. ccxt/delta.py +75 -36
  78. ccxt/deribit.py +4 -5
  79. ccxt/derive.py +46 -10
  80. ccxt/ellipx.py +175 -77
  81. ccxt/gate.py +1 -1
  82. ccxt/gemini.py +3 -4
  83. ccxt/hitbtc.py +56 -65
  84. ccxt/hollaex.py +106 -49
  85. ccxt/htx.py +20 -43
  86. ccxt/hyperliquid.py +6 -6
  87. ccxt/kraken.py +27 -23
  88. ccxt/kucoinfutures.py +5 -0
  89. ccxt/lbank.py +1 -1
  90. ccxt/mexc.py +2 -2
  91. ccxt/ndax.py +25 -24
  92. ccxt/okcoin.py +12 -29
  93. ccxt/okx.py +9 -0
  94. ccxt/onetrading.py +10 -7
  95. ccxt/oxfun.py +40 -110
  96. ccxt/paradex.py +123 -4
  97. ccxt/pro/__init__.py +109 -5
  98. ccxt/pro/binance.py +32 -33
  99. ccxt/pro/bithumb.py +5 -3
  100. ccxt/pro/{huobijp.py → bittrade.py} +3 -3
  101. ccxt/pro/kraken.py +249 -79
  102. ccxt/pro/luno.py +6 -5
  103. ccxt/pro/mexc.py +254 -7
  104. ccxt/pro/poloniex.py +6 -2
  105. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/METADATA +8 -11
  106. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/RECORD +110 -121
  107. ccxt/abstract/bl3p.py +0 -19
  108. ccxt/abstract/idex.py +0 -26
  109. ccxt/abstract/kuna.py +0 -182
  110. ccxt/async_support/base/ws/fast_client.py +0 -97
  111. ccxt/async_support/bl3p.py +0 -543
  112. ccxt/async_support/idex.py +0 -1889
  113. ccxt/async_support/kuna.py +0 -1935
  114. ccxt/bl3p.py +0 -543
  115. ccxt/idex.py +0 -1889
  116. ccxt/kuna.py +0 -1935
  117. ccxt/pro/idex.py +0 -687
  118. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  119. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/LICENSE.txt +0 -0
  120. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/WHEEL +0 -0
  121. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/top_level.txt +0 -0
ccxt/coincatch.py CHANGED
@@ -375,56 +375,18 @@ class coincatch(Exchange, ImplicitAPI):
375
375
  'CRO': 'CronosChain',
376
376
  },
377
377
  'networksById': {
378
- 'BITCOIN': 'BTC',
379
- 'ERC20': 'ERC20',
380
378
  'TRC20': 'TRC20',
381
379
  'TRX(TRC20)': 'TRC20',
382
- 'BEP20': 'BEP20',
383
380
  'ArbitrumOne': 'ARB', # todo check
384
- 'Optimism': 'OPTIMISM',
385
- 'LTC': 'LTC',
386
- 'BCH': 'BCH',
387
- 'ETC': 'ETC',
388
- 'SOL': 'SOL',
389
- 'NEO3': 'NEO3',
390
- 'stacks': 'STX',
391
- 'Elrond': 'EGLD',
392
- 'NEARProtocol': 'NEAR',
393
- 'AcalaToken': 'ACA',
394
- 'Klaytn': 'KLAY',
395
- 'Fantom': 'FTM',
396
- 'Terra': 'TERRA',
397
- 'WAVES': 'WAVES',
398
- 'TAO': 'TAO',
399
- 'SUI': 'SUI',
400
- 'SEI': 'SEI',
401
381
  'THORChain': 'RUNE', # todo check
402
- 'ZIL': 'ZIL',
403
382
  'Solar': 'SXP', # todo check
404
- 'FET': 'FET',
405
383
  'C-Chain': 'AVAX', # todo check
406
- 'XRP': 'XRP',
407
- 'EOS': 'EOS',
408
- 'DOGECOIN': 'DOGE',
409
384
  'CAP20': 'CAP20', # todo check
410
- 'Polygon': 'MATIC',
411
- 'CSPR': 'CSPR',
412
- 'Moonbeam': 'GLMR',
413
- 'MINA': 'MINA',
414
385
  'CFXeSpace': 'CFX', # todo check
415
386
  'CFX': 'CFX',
416
387
  'StratisEVM': 'STRAT', # todo check
417
- 'Celestia': 'TIA',
418
388
  'ChilizChain': 'ChilizChain', # todo check
419
- 'Aptos': 'APT',
420
- 'Ontology': 'ONT',
421
- 'ICP': 'ICP',
422
- 'Cardano': 'ADA',
423
- 'FIL': 'FIL',
424
- 'CELO': 'CELO',
425
- 'DOT': 'DOT',
426
389
  'StellarLumens': 'XLM', # todo check
427
- 'ATOM': 'ATOM',
428
390
  'CronosChain': 'CRO', # todo check
429
391
  },
430
392
  },
@@ -656,71 +618,56 @@ class coincatch(Exchange, ImplicitAPI):
656
618
  currencyId = self.safe_string(currecy, 'coinName')
657
619
  currenciesIds.append(currencyId)
658
620
  code = self.safe_currency_code(currencyId)
659
- allowDeposit = False
660
- allowWithdraw = False
661
- minDeposit: Str = None
662
- minWithdraw: Str = None
663
621
  networks = self.safe_list(currecy, 'chains')
664
- networksById = self.safe_dict(self.options, 'networksById')
665
622
  parsedNetworks: dict = {}
666
623
  for j in range(0, len(networks)):
667
624
  network = networks[j]
668
625
  networkId = self.safe_string(network, 'chain')
669
- networkName = self.safe_string(networksById, networkId, networkId)
670
- networkDepositString = self.safe_string(network, 'rechargeable')
671
- networkDeposit = networkDepositString == 'true'
672
- networkWithdrawString = self.safe_string(network, 'withdrawable')
673
- networkWithdraw = networkWithdrawString == 'true'
674
- networkMinDeposit = self.safe_string(network, 'minDepositAmount')
675
- networkMinWithdraw = self.safe_string(network, 'minWithdrawAmount')
626
+ networkCode = self.network_code_to_id(networkId)
676
627
  parsedNetworks[networkId] = {
677
628
  'id': networkId,
678
- 'network': networkName,
629
+ 'network': networkCode,
679
630
  'limits': {
680
631
  'deposit': {
681
- 'min': self.parse_number(networkMinDeposit),
632
+ 'min': self.safe_number(network, 'minDepositAmount'),
682
633
  'max': None,
683
634
  },
684
635
  'withdraw': {
685
- 'min': self.parse_number(networkMinWithdraw),
636
+ 'min': self.safe_number(network, 'minWithdrawAmount'),
686
637
  'max': None,
687
638
  },
688
639
  },
689
- 'active': networkDeposit and networkWithdraw,
690
- 'deposit': networkDeposit,
691
- 'withdraw': networkWithdraw,
640
+ 'active': None,
641
+ 'deposit': self.safe_string(network, 'rechargeable') == 'true',
642
+ 'withdraw': self.safe_string(network, 'withdrawable') == 'true',
692
643
  'fee': self.safe_number(network, 'withdrawFee'),
693
644
  'precision': None,
694
645
  'info': network,
695
646
  }
696
- allowDeposit = allowDeposit if allowDeposit else networkDeposit
697
- allowWithdraw = allowWithdraw if allowWithdraw else networkWithdraw
698
- minDeposit = Precise.string_min(networkMinDeposit, minDeposit) if minDeposit else networkMinDeposit
699
- minWithdraw = Precise.string_min(networkMinWithdraw, minWithdraw) if minWithdraw else networkMinWithdraw
700
- result[code] = {
647
+ result[code] = self.safe_currency_structure({
701
648
  'id': currencyId,
702
649
  'numericId': self.safe_integer(currecy, 'coinId'),
703
650
  'code': code,
704
651
  'precision': None,
705
652
  'type': None,
706
653
  'name': None,
707
- 'active': allowWithdraw and allowDeposit,
708
- 'deposit': allowDeposit,
709
- 'withdraw': allowWithdraw,
654
+ 'active': None,
655
+ 'deposit': None,
656
+ 'withdraw': None,
710
657
  'fee': None,
711
658
  'limits': {
712
659
  'deposit': {
713
- 'min': self.parse_number(minDeposit),
660
+ 'min': None,
714
661
  'max': None,
715
662
  },
716
663
  'withdraw': {
717
- 'min': self.parse_number(minWithdraw),
664
+ 'min': None,
718
665
  'max': None,
719
666
  },
720
667
  },
721
668
  'networks': parsedNetworks,
722
669
  'info': currecy,
723
- }
670
+ })
724
671
  if self.safe_list(self.options, 'currencyIdsListForParseMarket') is None:
725
672
  self.options['currencyIdsListForParseMarket'] = currenciesIds
726
673
  return result
ccxt/coinex.py CHANGED
@@ -733,33 +733,7 @@ class coinex(Exchange, ImplicitAPI):
733
733
  canWithdraw = self.safe_bool(asset, 'withdraw_enabled')
734
734
  firstChain = self.safe_dict(chains, 0, {})
735
735
  firstPrecisionString = self.parse_precision(self.safe_string(firstChain, 'withdrawal_precision'))
736
- result[code] = {
737
- 'id': currencyId,
738
- 'code': code,
739
- 'name': None,
740
- 'active': canDeposit and canWithdraw,
741
- 'deposit': canDeposit,
742
- 'withdraw': canWithdraw,
743
- 'fee': None,
744
- 'precision': self.parse_number(firstPrecisionString),
745
- 'limits': {
746
- 'amount': {
747
- 'min': None,
748
- 'max': None,
749
- },
750
- 'deposit': {
751
- 'min': None,
752
- 'max': None,
753
- },
754
- 'withdraw': {
755
- 'min': None,
756
- 'max': None,
757
- },
758
- },
759
- 'networks': {},
760
- 'type': 'crypto',
761
- 'info': coin,
762
- }
736
+ networks: dict = {}
763
737
  for j in range(0, len(chains)):
764
738
  chain = chains[j]
765
739
  networkId = self.safe_string(chain, 'chain')
@@ -796,9 +770,34 @@ class coinex(Exchange, ImplicitAPI):
796
770
  },
797
771
  'info': chain,
798
772
  }
799
- networks = self.safe_dict(result[code], 'networks', {})
800
773
  networks[networkId] = network
801
- result[code]['networks'] = networks
774
+ result[code] = self.safe_currency_structure({
775
+ 'id': currencyId,
776
+ 'code': code,
777
+ 'name': None,
778
+ 'active': canDeposit and canWithdraw,
779
+ 'deposit': canDeposit,
780
+ 'withdraw': canWithdraw,
781
+ 'fee': None,
782
+ 'precision': self.parse_number(firstPrecisionString),
783
+ 'limits': {
784
+ 'amount': {
785
+ 'min': None,
786
+ 'max': None,
787
+ },
788
+ 'deposit': {
789
+ 'min': None,
790
+ 'max': None,
791
+ },
792
+ 'withdraw': {
793
+ 'min': None,
794
+ 'max': None,
795
+ },
796
+ },
797
+ 'networks': {},
798
+ 'type': 'crypto',
799
+ 'info': coin,
800
+ })
802
801
  return result
803
802
 
804
803
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/coinlist.py CHANGED
@@ -467,30 +467,31 @@ class coinlist(Exchange, ImplicitAPI):
467
467
  currency = currencies[i]
468
468
  id = self.safe_string(currency, 'asset')
469
469
  code = self.safe_currency_code(id)
470
+ isFiat = code == 'USD'
470
471
  isTransferable = self.safe_bool(currency, 'is_transferable', False)
471
- withdrawEnabled = isTransferable
472
- depositEnabled = isTransferable
473
- active = isTransferable
474
- decimalPlaces = self.safe_string(currency, 'decimal_places')
475
- precision = self.parse_number(self.parse_precision(decimalPlaces))
476
- minWithdrawal = self.safe_string(currency, 'min_withdrawal')
477
- result[code] = {
472
+ result[code] = self.safe_currency_structure({
478
473
  'id': id,
479
474
  'code': code,
480
475
  'name': code,
481
476
  'info': currency,
482
- 'active': active,
483
- 'deposit': depositEnabled,
484
- 'withdraw': withdrawEnabled,
477
+ 'active': None,
478
+ 'deposit': isTransferable,
479
+ 'withdraw': isTransferable,
485
480
  'fee': None,
486
- 'precision': precision,
481
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'decimal_places'))),
487
482
  'limits': {
488
- 'amount': {'min': None, 'max': None},
489
- 'withdraw': {'min': minWithdrawal, 'max': None},
483
+ 'amount': {
484
+ 'min': None,
485
+ 'max': None,
486
+ },
487
+ 'withdraw': {
488
+ 'min': self.safe_number(currency, 'min_withdrawal'),
489
+ 'max': None,
490
+ },
490
491
  },
491
- 'networks': {},
492
- 'type': 'crypto',
493
- }
492
+ 'networks': {}, # todo
493
+ 'type': 'fiat' if isFiat else 'crypto',
494
+ })
494
495
  return result
495
496
 
496
497
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/coinmetro.py CHANGED
@@ -387,24 +387,33 @@ class coinmetro(Exchange, ImplicitAPI):
387
387
  currency = response[i]
388
388
  id = self.safe_string(currency, 'symbol')
389
389
  code = self.safe_currency_code(id)
390
- withdraw = self.safe_value(currency, 'canWithdraw')
391
- deposit = self.safe_value(currency, 'canDeposit')
392
- canTrade = self.safe_value(currency, 'canTrade')
393
- active = withdraw if canTrade else True
394
- minAmount = self.safe_number(currency, 'minQty')
390
+ typeRaw = self.safe_string(currency, 'type')
391
+ type = None
392
+ if typeRaw == 'coin' or typeRaw == 'token' or typeRaw == 'erc20':
393
+ type = 'crypto'
394
+ elif typeRaw == 'fiat':
395
+ type = 'fiat'
396
+ precisionDigits = self.safe_string_2(currency, 'digits', 'notabeneDecimals')
395
397
  result[code] = self.safe_currency_structure({
396
398
  'id': id,
397
399
  'code': code,
398
400
  'name': code,
401
+ 'type': type,
399
402
  'info': currency,
400
- 'active': active,
401
- 'deposit': deposit,
402
- 'withdraw': withdraw,
403
+ 'active': self.safe_bool(currency, 'canTrade'),
404
+ 'deposit': self.safe_bool(currency, 'canDeposit'),
405
+ 'withdraw': self.safe_bool(currency, 'canWithdraw'),
403
406
  'fee': None,
404
- 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'digits'))),
407
+ 'precision': self.parse_number(self.parse_precision(precisionDigits)),
405
408
  'limits': {
406
- 'amount': {'min': minAmount, 'max': None},
407
- 'withdraw': {'min': None, 'max': None},
409
+ 'amount': {
410
+ 'min': self.safe_number(currency, 'minQty'),
411
+ 'max': None,
412
+ },
413
+ 'withdraw': {
414
+ 'min': None,
415
+ 'max': None,
416
+ },
408
417
  },
409
418
  'networks': {},
410
419
  })
ccxt/coinone.py CHANGED
@@ -303,18 +303,16 @@ class coinone(Exchange, ImplicitAPI):
303
303
  for i in range(0, len(currencies)):
304
304
  entry = currencies[i]
305
305
  id = self.safe_string(entry, 'symbol')
306
- name = self.safe_string(entry, 'name')
307
306
  code = self.safe_currency_code(id)
308
- withdrawStatus = self.safe_string(entry, 'withdraw_status', '')
309
- depositStatus = self.safe_string(entry, 'deposit_status', '')
310
- isWithdrawEnabled = withdrawStatus == 'normal'
311
- isDepositEnabled = depositStatus == 'normal'
312
- result[code] = {
307
+ isWithdrawEnabled = self.safe_string(entry, 'withdraw_status', '') == 'normal'
308
+ isDepositEnabled = self.safe_string(entry, 'deposit_status', '') == 'normal'
309
+ type = 'crypto' if (code != 'KRW') else 'fiat'
310
+ result[code] = self.safe_currency_structure({
313
311
  'id': id,
314
312
  'code': code,
315
313
  'info': entry,
316
- 'name': name,
317
- 'active': isWithdrawEnabled and isDepositEnabled,
314
+ 'name': self.safe_string(entry, 'name'),
315
+ 'active': None,
318
316
  'deposit': isDepositEnabled,
319
317
  'withdraw': isWithdrawEnabled,
320
318
  'fee': self.safe_number(entry, 'withdrawal_fee'),
@@ -330,8 +328,8 @@ class coinone(Exchange, ImplicitAPI):
330
328
  },
331
329
  },
332
330
  'networks': {},
333
- 'type': 'crypto',
334
- }
331
+ 'type': type,
332
+ })
335
333
  return result
336
334
 
337
335
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/coinsph.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.coinsph import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Any, Balances, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
9
+ from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -75,7 +75,7 @@ class coinsph(Exchange, ImplicitAPI):
75
75
  'fetchClosedOrders': True,
76
76
  'fetchCrossBorrowRate': False,
77
77
  'fetchCrossBorrowRates': False,
78
- 'fetchCurrencies': False,
78
+ 'fetchCurrencies': True,
79
79
  'fetchDeposit': None,
80
80
  'fetchDepositAddress': True,
81
81
  'fetchDepositAddresses': False,
@@ -501,6 +501,128 @@ class coinsph(Exchange, ImplicitAPI):
501
501
  },
502
502
  })
503
503
 
504
+ def fetch_currencies(self, params={}) -> Currencies:
505
+ """
506
+ fetches all available currencies on an exchange
507
+
508
+ https://docs.coins.ph/rest-api/#all-coins-information-user_data
509
+
510
+ :param dict [params]: extra parameters specific to the exchange API endpoint
511
+ :returns dict: an associative dictionary of currencies
512
+ """
513
+ if not self.check_required_credentials(False):
514
+ return None
515
+ response = self.privateGetOpenapiWalletV1ConfigGetall(params)
516
+ #
517
+ # [
518
+ # {
519
+ # "coin": "PHP",
520
+ # "name": "PHP",
521
+ # "depositAllEnable": False,
522
+ # "withdrawAllEnable": False,
523
+ # "free": "0",
524
+ # "locked": "0",
525
+ # "transferPrecision": "2",
526
+ # "transferMinQuantity": "0",
527
+ # "networkList": [],
528
+ # "legalMoney": True
529
+ # },
530
+ # {
531
+ # "coin": "USDT",
532
+ # "name": "USDT",
533
+ # "depositAllEnable": True,
534
+ # "withdrawAllEnable": True,
535
+ # "free": "0",
536
+ # "locked": "0",
537
+ # "transferPrecision": "8",
538
+ # "transferMinQuantity": "0",
539
+ # "networkList": [
540
+ # {
541
+ # "addressRegex": "^0x[0-9a-fA-F]{40}$",
542
+ # "memoRegex": " ",
543
+ # "network": "ETH",
544
+ # "name": "Ethereum(ERC20)",
545
+ # "depositEnable": True,
546
+ # "minConfirm": "12",
547
+ # "unLockConfirm": "-1",
548
+ # "withdrawDesc": "",
549
+ # "withdrawEnable": True,
550
+ # "withdrawFee": "6",
551
+ # "withdrawIntegerMultiple": "0.000001",
552
+ # "withdrawMax": "500000",
553
+ # "withdrawMin": "10",
554
+ # "sameAddress": False
555
+ # },
556
+ # {
557
+ # "addressRegex": "^T[0-9a-zA-Z]{33}$",
558
+ # "memoRegex": "",
559
+ # "network": "TRX",
560
+ # "name": "TRON",
561
+ # "depositEnable": True,
562
+ # "minConfirm": "19",
563
+ # "unLockConfirm": "-1",
564
+ # "withdrawDesc": "",
565
+ # "withdrawEnable": True,
566
+ # "withdrawFee": "3",
567
+ # "withdrawIntegerMultiple": "0.000001",
568
+ # "withdrawMax": "1000000",
569
+ # "withdrawMin": "20",
570
+ # "sameAddress": False
571
+ # }
572
+ # ],
573
+ # "legalMoney": False
574
+ # }
575
+ # ]
576
+ #
577
+ result: dict = {}
578
+ for i in range(0, len(response)):
579
+ entry = response[i]
580
+ id = self.safe_string(entry, 'coin')
581
+ code = self.safe_currency_code(id)
582
+ isFiat = self.safe_bool(entry, 'isLegalMoney')
583
+ networkList = self.safe_list(entry, 'networkList', [])
584
+ networks: dict = {}
585
+ for j in range(0, len(networkList)):
586
+ networkItem = networkList[j]
587
+ network = self.safe_string(networkItem, 'network')
588
+ networkCode = self.network_id_to_code(network)
589
+ networks[networkCode] = {
590
+ 'info': networkItem,
591
+ 'id': network,
592
+ 'network': networkCode,
593
+ 'active': None,
594
+ 'deposit': self.safe_bool(networkItem, 'depositEnable'),
595
+ 'withdraw': self.safe_bool(networkItem, 'withdrawEnable'),
596
+ 'fee': self.safe_number(networkItem, 'withdrawFee'),
597
+ 'precision': self.safe_number(networkItem, 'withdrawIntegerMultiple'),
598
+ 'limits': {
599
+ 'withdraw': {
600
+ 'min': self.safe_number(networkItem, 'withdrawMin'),
601
+ 'max': self.safe_number(networkItem, 'withdrawMax'),
602
+ },
603
+ 'deposit': {
604
+ 'min': None,
605
+ 'max': None,
606
+ },
607
+ },
608
+ }
609
+ result[code] = self.safe_currency_structure({
610
+ 'id': id,
611
+ 'name': self.safe_string(entry, 'name'),
612
+ 'code': code,
613
+ 'type': 'fiat' if isFiat else 'crypto',
614
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(entry, 'transferPrecision'))),
615
+ 'info': entry,
616
+ 'active': None,
617
+ 'deposit': self.safe_bool(entry, 'depositAllEnable'),
618
+ 'withdraw': self.safe_bool(entry, 'withdrawAllEnable'),
619
+ 'networks': networks,
620
+ 'fee': None,
621
+ 'fees': None,
622
+ 'limits': {},
623
+ })
624
+ return result
625
+
504
626
  def calculate_rate_limiter_cost(self, api, method, path, params, config={}):
505
627
  if ('noSymbol' in config) and not ('symbol' in params):
506
628
  return config['noSymbol']
ccxt/cryptocom.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.cryptocom import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Any, Balances, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
9
+ from ccxt.base.types import Account, Any, Balances, Currencies, Currency, DepositAddress, Int, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, TradingFees, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -69,7 +69,7 @@ class cryptocom(Exchange, ImplicitAPI):
69
69
  'fetchClosedOrders': 'emulated',
70
70
  'fetchCrossBorrowRate': False,
71
71
  'fetchCrossBorrowRates': False,
72
- 'fetchCurrencies': False,
72
+ 'fetchCurrencies': True,
73
73
  'fetchDepositAddress': True,
74
74
  'fetchDepositAddresses': False,
75
75
  'fetchDepositAddressesByNetwork': True,
@@ -526,6 +526,113 @@ class cryptocom(Exchange, ImplicitAPI):
526
526
  },
527
527
  })
528
528
 
529
+ def fetch_currencies(self, params={}) -> Currencies:
530
+ """
531
+ fetches all available currencies on an exchange
532
+
533
+ https://exchange-docs.crypto.com/exchange/v1/rest-ws/index.html#private-get-currency-networks
534
+
535
+ :param dict [params]: extra parameters specific to the exchange API endpoint
536
+ :returns dict: an associative dictionary of currencies
537
+ """
538
+ # self endpoint requires authentication
539
+ if not self.check_required_credentials(False):
540
+ return None
541
+ response = self.v1PrivatePostPrivateGetCurrencyNetworks(params)
542
+ #
543
+ # {
544
+ # "id": "1747502328559",
545
+ # "method": "private/get-currency-networks",
546
+ # "code": "0",
547
+ # "result": {
548
+ # "update_time": "1747502281000",
549
+ # "currency_map": {
550
+ # "USDT": {
551
+ # "full_name": "Tether USD",
552
+ # "default_network": "ETH",
553
+ # "network_list": [
554
+ # {
555
+ # "network_id": "ETH",
556
+ # "withdrawal_fee": "10.00000000",
557
+ # "withdraw_enabled": True,
558
+ # "min_withdrawal_amount": "20.0",
559
+ # "deposit_enabled": True,
560
+ # "confirmation_required": "32"
561
+ # },
562
+ # {
563
+ # "network_id": "CRONOS",
564
+ # "withdrawal_fee": "0.18000000",
565
+ # "withdraw_enabled": True,
566
+ # "min_withdrawal_amount": "0.36",
567
+ # "deposit_enabled": True,
568
+ # "confirmation_required": "15"
569
+ # },
570
+ # {
571
+ # "network_id": "SOL",
572
+ # "withdrawal_fee": "5.31000000",
573
+ # "withdraw_enabled": True,
574
+ # "min_withdrawal_amount": "10.62",
575
+ # "deposit_enabled": True,
576
+ # "confirmation_required": "1"
577
+ # }
578
+ # ]
579
+ # }
580
+ # }
581
+ # }
582
+ # }
583
+ #
584
+ resultData = self.safe_dict(response, 'result', {})
585
+ currencyMap = self.safe_dict(resultData, 'currency_map', {})
586
+ keys = list(currencyMap.keys())
587
+ result: dict = {}
588
+ for i in range(0, len(keys)):
589
+ key = keys[i]
590
+ currency = currencyMap[key]
591
+ id = key
592
+ code = self.safe_currency_code(id)
593
+ networks: dict = {}
594
+ chains = self.safe_list(currency, 'network_list', [])
595
+ for j in range(0, len(chains)):
596
+ chain = chains[j]
597
+ networkId = self.safe_string(chain, 'network_id')
598
+ network = self.network_id_to_code(networkId)
599
+ networks[network] = {
600
+ 'info': chain,
601
+ 'id': networkId,
602
+ 'network': network,
603
+ 'active': None,
604
+ 'deposit': self.safe_bool(chain, 'deposit_enabled', False),
605
+ 'withdraw': self.safe_bool(chain, 'withdraw_enabled', False),
606
+ 'fee': self.safe_number(chain, 'withdrawal_fee'),
607
+ 'precision': None,
608
+ 'limits': {
609
+ 'withdraw': {
610
+ 'min': self.safe_number(chain, 'min_withdrawal_amount'),
611
+ 'max': None,
612
+ },
613
+ },
614
+ }
615
+ result[code] = self.safe_currency_structure({
616
+ 'info': currency,
617
+ 'id': id,
618
+ 'code': code,
619
+ 'name': self.safe_string(currency, 'full_name'),
620
+ 'active': None,
621
+ 'deposit': None,
622
+ 'withdraw': None,
623
+ 'fee': None,
624
+ 'precision': None,
625
+ 'limits': {
626
+ 'amount': {
627
+ 'min': None,
628
+ 'max': None,
629
+ },
630
+ },
631
+ 'type': 'crypto', # only crypto now
632
+ 'networks': networks,
633
+ })
634
+ return result
635
+
529
636
  def fetch_markets(self, params={}) -> List[Market]:
530
637
  """
531
638