ccxt 4.4.80__py2.py3-none-any.whl → 4.4.85__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 (104) hide show
  1. ccxt/__init__.py +1 -5
  2. ccxt/abstract/blofin.py +8 -0
  3. ccxt/abstract/btcbox.py +1 -0
  4. ccxt/apex.py +21 -30
  5. ccxt/ascendex.py +1 -1
  6. ccxt/async_support/__init__.py +1 -5
  7. ccxt/async_support/apex.py +21 -30
  8. ccxt/async_support/ascendex.py +1 -1
  9. ccxt/async_support/base/exchange.py +26 -3
  10. ccxt/async_support/base/ws/cache.py +6 -1
  11. ccxt/async_support/bigone.py +17 -14
  12. ccxt/async_support/bingx.py +13 -32
  13. ccxt/async_support/bitfinex.py +61 -48
  14. ccxt/async_support/bitget.py +7 -4
  15. ccxt/async_support/bitrue.py +14 -32
  16. ccxt/async_support/bitso.py +33 -0
  17. ccxt/async_support/bitstamp.py +33 -0
  18. ccxt/async_support/blofin.py +145 -14
  19. ccxt/async_support/btcbox.py +25 -5
  20. ccxt/async_support/bybit.py +20 -39
  21. ccxt/async_support/cex.py +2 -4
  22. ccxt/async_support/coinbase.py +56 -42
  23. ccxt/async_support/coinbaseexchange.py +141 -32
  24. ccxt/async_support/coincatch.py +14 -67
  25. ccxt/async_support/coinex.py +28 -29
  26. ccxt/async_support/coinlist.py +17 -16
  27. ccxt/async_support/coinmetro.py +20 -11
  28. ccxt/async_support/coinone.py +8 -10
  29. ccxt/async_support/coinsph.py +124 -2
  30. ccxt/async_support/cryptocom.py +109 -2
  31. ccxt/async_support/cryptomus.py +42 -80
  32. ccxt/async_support/delta.py +75 -36
  33. ccxt/async_support/derive.py +46 -10
  34. ccxt/async_support/ellipx.py +175 -77
  35. ccxt/async_support/gate.py +1 -1
  36. ccxt/async_support/gemini.py +3 -4
  37. ccxt/async_support/hitbtc.py +56 -65
  38. ccxt/async_support/htx.py +2 -2
  39. ccxt/async_support/hyperliquid.py +15 -2
  40. ccxt/async_support/kraken.py +27 -23
  41. ccxt/async_support/kucoinfutures.py +5 -0
  42. ccxt/async_support/lbank.py +1 -1
  43. ccxt/async_support/okx.py +1 -2
  44. ccxt/async_support/oxfun.py +21 -1
  45. ccxt/async_support/paradex.py +120 -4
  46. ccxt/base/errors.py +6 -0
  47. ccxt/base/exchange.py +40 -3
  48. ccxt/base/types.py +3 -0
  49. ccxt/bigone.py +17 -14
  50. ccxt/bingx.py +13 -32
  51. ccxt/bitfinex.py +61 -48
  52. ccxt/bitget.py +7 -4
  53. ccxt/bitrue.py +14 -32
  54. ccxt/bitso.py +33 -0
  55. ccxt/bitstamp.py +33 -0
  56. ccxt/blofin.py +145 -14
  57. ccxt/btcbox.py +24 -5
  58. ccxt/bybit.py +20 -39
  59. ccxt/cex.py +2 -4
  60. ccxt/coinbase.py +56 -42
  61. ccxt/coinbaseexchange.py +141 -32
  62. ccxt/coincatch.py +14 -67
  63. ccxt/coinex.py +28 -29
  64. ccxt/coinlist.py +17 -16
  65. ccxt/coinmetro.py +20 -11
  66. ccxt/coinone.py +8 -10
  67. ccxt/coinsph.py +124 -2
  68. ccxt/cryptocom.py +109 -2
  69. ccxt/cryptomus.py +42 -80
  70. ccxt/delta.py +75 -36
  71. ccxt/derive.py +46 -10
  72. ccxt/ellipx.py +175 -77
  73. ccxt/gate.py +1 -1
  74. ccxt/gemini.py +3 -4
  75. ccxt/hitbtc.py +56 -65
  76. ccxt/htx.py +2 -2
  77. ccxt/hyperliquid.py +15 -2
  78. ccxt/kraken.py +27 -23
  79. ccxt/kucoinfutures.py +5 -0
  80. ccxt/lbank.py +1 -1
  81. ccxt/okx.py +1 -2
  82. ccxt/oxfun.py +21 -1
  83. ccxt/paradex.py +120 -4
  84. ccxt/pro/__init__.py +69 -3
  85. ccxt/pro/binance.py +31 -33
  86. ccxt/pro/bithumb.py +5 -3
  87. ccxt/pro/coinbase.py +1 -1
  88. ccxt/pro/hyperliquid.py +10 -2
  89. ccxt/pro/kraken.py +249 -79
  90. ccxt/pro/mexc.py +252 -7
  91. ccxt/pro/poloniex.py +6 -2
  92. {ccxt-4.4.80.dist-info → ccxt-4.4.85.dist-info}/METADATA +7 -11
  93. {ccxt-4.4.80.dist-info → ccxt-4.4.85.dist-info}/RECORD +96 -104
  94. ccxt/abstract/bl3p.py +0 -19
  95. ccxt/abstract/idex.py +0 -26
  96. ccxt/async_support/base/ws/fast_client.py +0 -97
  97. ccxt/async_support/bl3p.py +0 -543
  98. ccxt/async_support/idex.py +0 -1889
  99. ccxt/bl3p.py +0 -543
  100. ccxt/idex.py +0 -1889
  101. ccxt/pro/idex.py +0 -687
  102. {ccxt-4.4.80.dist-info → ccxt-4.4.85.dist-info}/LICENSE.txt +0 -0
  103. {ccxt-4.4.80.dist-info → ccxt-4.4.85.dist-info}/WHEEL +0 -0
  104. {ccxt-4.4.80.dist-info → ccxt-4.4.85.dist-info}/top_level.txt +0 -0
ccxt/ellipx.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.ellipx import ImplicitAPI
8
8
  import math
9
- from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, TradingFeeInterface, Transaction
9
+ from ccxt.base.types import Any, Balances, Currencies, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Ticker, Trade, TradingFeeInterface, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -799,80 +799,178 @@ class ellipx(Exchange, ImplicitAPI):
799
799
  'results_per_page': 100,
800
800
  '_expand': '/Crypto_Token,/Crypto_Chain',
801
801
  }, params))
802
- currencies = {}
803
- data = self.safe_value(response, 'data', [])
802
+ result = {}
803
+ data = self.safe_list(response, 'data', [])
804
804
  for i in range(0, len(data)):
805
- currency = self.parse_currency(data[i])
806
- code = self.safe_string(currency, 'code')
807
- if code is not None:
808
- currencies[code] = currency
809
- return currencies
810
-
811
- def parse_currency(self, currency) -> Currency:
812
- id = self.safe_string(currency, 'Crypto_Token__')
813
- token = self.safe_value(currency, 'Crypto_Token', {})
814
- code = self.safe_currency_code(self.safe_string(token, 'Symbol'))
815
- name = self.safe_string(token, 'Name')
816
- active = self.safe_string(currency, 'Status') == 'valid'
817
- deposit = self.safe_string(currency, 'Can_Deposit') == 'Y'
818
- withdraw = self.safe_string(currency, 'Status') == 'valid'
819
- fee = None
820
- if currency['Withdraw_Fee'] is not None:
821
- fee = self.parse_number(self.parse_amount(currency['Withdraw_Fee']))
822
- precision = self.parse_number(self.parse_precision(self.safe_string(token, 'Decimals')))
823
- minDeposit = None
824
- if currency['Minimum_Deposit'] is not None:
825
- minDeposit = self.parse_amount(currency['Minimum_Deposit'])
826
- minWithdraw = None
827
- if currency['Minimum_Withdraw'] is not None:
828
- minWithdraw = self.parse_amount(currency['Minimum_Withdraw'])
829
- networkId = self.safe_string(currency, 'Crypto_Chain__')
830
- networkData = self.safe_value(currency, 'Crypto_Chain', {})
831
- networkCode = self.safe_string(networkData, 'Type', 'default')
832
- networks = {
833
- 'string': None,
834
- 'info': networkCode == {} if 'default' else networkData,
835
- 'id': networkId or id or '',
836
- 'network': networkCode,
837
- 'active': active,
838
- 'deposit': deposit,
839
- 'withdraw': withdraw,
840
- 'fee': fee,
841
- 'precision': precision,
842
- 'limits': {
843
- 'deposit': {
844
- 'min': minDeposit,
845
- 'max': None,
846
- },
847
- 'withdraw': {
848
- 'min': minWithdraw,
849
- 'max': None,
850
- },
851
- },
852
- }
853
- result: Currency = {
854
- 'info': currency,
855
- 'id': id,
856
- 'code': code,
857
- 'name': name,
858
- 'active': active,
859
- 'deposit': deposit,
860
- 'withdraw': withdraw,
861
- 'fee': fee,
862
- 'precision': precision,
863
- 'type': None,
864
- 'limits': {
865
- 'amount': {
866
- 'min': None,
867
- 'max': None,
868
- },
869
- 'withdraw': {
870
- 'min': minWithdraw,
871
- 'max': None,
805
+ networkEntry = data[i]
806
+ #
807
+ # {
808
+ # "Crypto_Token_Info__": "crtev-5nsn35-f4ir-g5hp-iaft-i4ztx6zu",
809
+ # "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
810
+ # "Crypto_Chain__": "chain-xjbini-7wlz-dmzf-gm7z-zf7ei6fq",
811
+ # "Type": "native",
812
+ # "Symbol": null,
813
+ # "Name": null,
814
+ # "Contract_Address": null,
815
+ # "Minimum_Deposit": {
816
+ # "v": "6",
817
+ # "e": "6",
818
+ # "f": "6.0e-6"
819
+ # },
820
+ # "Minimum_Withdraw": {
821
+ # "v": "15",
822
+ # "e": "5",
823
+ # "f": "0.00015"
824
+ # },
825
+ # "Withdraw_Fee": {
826
+ # "v": "1",
827
+ # "e": "4",
828
+ # "f": "0.0001"
829
+ # },
830
+ # "Minimum_Collect": null,
831
+ # "Status": "valid",
832
+ # "Can_Deposit": "Y",
833
+ # "Decimals": null,
834
+ # "Priority": "100",
835
+ # "Created": {
836
+ # "unix": "1727552199",
837
+ # "us": "0",
838
+ # "iso": "2024-09-28 19:36:39.000000",
839
+ # "tz": "UTC",
840
+ # "full": "1727552199000000",
841
+ # "unixms": "1727552199000"
842
+ # },
843
+ # "Crypto_Token": {
844
+ # "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
845
+ # "Name": "Bitcoin",
846
+ # "Symbol": "BTC",
847
+ # "Decimals": "8",
848
+ # "CMC_Id": "1",
849
+ # "Priority": "100",
850
+ # "Can_Deposit": "Y",
851
+ # "Category": "token",
852
+ # "Testnet": "N",
853
+ # "Created": {
854
+ # "unix": "1727552113",
855
+ # "us": "0",
856
+ # "iso": "2024-09-28 19:35:13.000000",
857
+ # "tz": "UTC",
858
+ # "full": "1727552113000000",
859
+ # "unixms": "1727552113000"
860
+ # },
861
+ # "Logo": [
862
+ # {
863
+ # "Crypto_Token_Logo__": "ctklg-aoozyr-rzm5-fphf-dhm7-5wbtetha",
864
+ # "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
865
+ # "Blob__": "blob-d6hvgx-37s5-dh5h-ogj5-qxqvnaoy",
866
+ # "Default": "Y",
867
+ # "Format": "png",
868
+ # "Priority": "0",
869
+ # "Created": {
870
+ # "unix": "1730196627",
871
+ # "us": "929660",
872
+ # "iso": "2024-10-29 10:10:27.929660",
873
+ # "tz": "UTC",
874
+ # "full": "1730196627929660",
875
+ # "unixms": "1730196627929"
876
+ # },
877
+ # "Source": {
878
+ # "Media_Image__": "blob-d6hvgx-37s5-dh5h-ogj5-qxqvnaoy",
879
+ # "Url": "https://static.atonline.net/image/m_X7_tnmIYFCwn6EUVQuMKqrCuPB3CMl4ONTegeYpC0wIg68YZM0CuBpbjspnYwz/1a942eab068a2173e66d08c736283cfe22e1c1ed"
880
+ # }
881
+ # }
882
+ # ]
883
+ # },
884
+ # "Crypto_Chain": {
885
+ # "Crypto_Chain__": "chain-xjbini-7wlz-dmzf-gm7z-zf7ei6fq",
886
+ # "EVM_Chain__": null,
887
+ # "Crypto_Token__": "crtok-c5v3mh-grfn-hl5d-lmel-fvggbf4i",
888
+ # "Name": "Bitcoin",
889
+ # "Key": "bitcoin",
890
+ # "Type": "Bitcoin",
891
+ # "Curve": "secp256k1",
892
+ # "Backend_Url": null,
893
+ # "Wallet_Verification_Methods": {
894
+ # "signature": True
895
+ # },
896
+ # "Block_Margin": "3",
897
+ # "Created": {
898
+ # "unix": "1725340084",
899
+ # "us": "0",
900
+ # "iso": "2024-09-03 05:08:04.000000",
901
+ # "tz": "UTC",
902
+ # "full": "1725340084000000",
903
+ # "unixms": "1725340084000"
904
+ # }
905
+ # }
906
+ # }
907
+ #
908
+ id = self.safe_string(networkEntry, 'Crypto_Token__')
909
+ token = self.safe_dict(networkEntry, 'Crypto_Token', {})
910
+ code = self.safe_currency_code(self.safe_string(token, 'Symbol'))
911
+ if not (code in result):
912
+ result[code] = {
913
+ 'id': id,
914
+ 'code': code,
915
+ 'info': [],
916
+ 'type': None,
917
+ 'name': self.safe_string(token, 'Name'),
918
+ 'active': None,
919
+ 'deposit': None,
920
+ 'withdraw': None,
921
+ 'fee': None,
922
+ 'precision': None,
923
+ 'limits': {
924
+ 'amount': {
925
+ 'min': None,
926
+ 'max': None,
927
+ },
928
+ 'withdraw': {
929
+ 'min': None,
930
+ 'max': None,
931
+ },
932
+ 'deposit': {
933
+ 'min': None,
934
+ 'max': None,
935
+ },
936
+ },
937
+ 'networks': {},
938
+ }
939
+ networkId = self.safe_string(networkEntry, 'Crypto_Chain__')
940
+ cryptoChainDict = self.safe_string(networkEntry, 'Crypto_Chain')
941
+ networkName = self.safe_string(cryptoChainDict, 'Type', 'default')
942
+ networkCode = self.network_id_to_code(networkName)
943
+ result[code]['networks'][networkCode] = {
944
+ 'id': networkId,
945
+ 'network': networkCode,
946
+ 'active': self.safe_string(networkEntry, 'Status') == 'valid',
947
+ 'deposit': self.safe_string(networkEntry, 'Can_Deposit') == 'Y',
948
+ 'withdraw': None,
949
+ 'fee': self.parse_number(self.parse_amount(networkEntry['Withdraw_Fee'])),
950
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(token, 'Decimals'))),
951
+ 'limits': {
952
+ 'amount': {
953
+ 'min': None,
954
+ 'max': None,
955
+ },
956
+ 'withdraw': {
957
+ 'min': self.parse_amount(networkEntry['Minimum_Withdraw']),
958
+ 'max': None,
959
+ },
960
+ 'deposit': {
961
+ 'min': self.parse_amount(networkEntry['Minimum_Deposit']),
962
+ 'max': None,
963
+ },
872
964
  },
873
- },
874
- 'networks': networks,
875
- }
965
+ }
966
+ infos = self.safe_list(result[code], 'info', [])
967
+ infos.append(networkEntry)
968
+ result[code]['info'] = infos
969
+ # only after all entries are formed in currencies, restructure each entry
970
+ allKeys = list(result.keys())
971
+ for i in range(0, len(allKeys)):
972
+ code = allKeys[i]
973
+ result[code] = self.safe_currency_structure(result[code]) # self is needed after adding network entry
876
974
  return result
877
975
 
878
976
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
@@ -1065,14 +1163,14 @@ class ellipx(Exchange, ImplicitAPI):
1065
1163
  for i in range(0, len(dataArray)):
1066
1164
  entry = dataArray[i]
1067
1165
  balance = self.safe_dict(entry, 'Balance', {})
1068
- currency = self.safe_string(balance, 'currency')
1069
- if currency is not None:
1166
+ code = self.safe_string(balance, 'currency')
1167
+ if code is not None:
1070
1168
  account = {
1071
1169
  'free': self.parse_amount(entry['Unencumbered_Balance']['value_xint']),
1072
1170
  'used': self.parse_amount(entry['Liabilities']['value_xint']),
1073
1171
  'total': self.parse_amount(balance['value_xint']),
1074
1172
  }
1075
- result[currency] = account
1173
+ result[code] = account
1076
1174
  return self.safe_balance(result)
1077
1175
 
1078
1176
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
@@ -1678,7 +1776,7 @@ class ellipx(Exchange, ImplicitAPI):
1678
1776
 
1679
1777
  https://docs.google.com/document/d/1ZXzTQYffKE_EglTaKptxGQERRnunuLHEMmar7VC9syM/edit?tab=t.0#heading=h.zegupoa8g4t9
1680
1778
 
1681
- :param str code: Currency code
1779
+ :param str code: unified currency code
1682
1780
  :param number amount: Amount to withdraw
1683
1781
  :param str address: Destination wallet address
1684
1782
  :param str [tag]: Additional tag/memo for currencies that require it
ccxt/gate.py CHANGED
@@ -1865,7 +1865,7 @@ class gate(Exchange, ImplicitAPI):
1865
1865
  'code': code,
1866
1866
  'type': type,
1867
1867
  'precision': precision,
1868
- 'limits': self.limits,
1868
+ 'limits': None,
1869
1869
  'networks': {},
1870
1870
  'info': [], # will be filled below
1871
1871
  }
ccxt/gemini.py CHANGED
@@ -275,7 +275,7 @@ class gemini(Exchange, ImplicitAPI):
275
275
  'fetchMarketFromWebRetries': 10,
276
276
  'fetchMarketsFromAPI': {
277
277
  'fetchDetailsForAllSymbols': False,
278
- 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH'],
278
+ 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH', 'SOL'],
279
279
  },
280
280
  'fetchMarkets': {
281
281
  'webApiEnable': True, # fetches from WEB
@@ -430,7 +430,6 @@ class gemini(Exchange, ImplicitAPI):
430
430
  networkCode = None
431
431
  if networkId is not None:
432
432
  networkCode = self.network_id_to_code(networkId)
433
- if networkCode is not None:
434
433
  networks[networkCode] = {
435
434
  'info': currency,
436
435
  'id': networkId,
@@ -451,7 +450,7 @@ class gemini(Exchange, ImplicitAPI):
451
450
  },
452
451
  },
453
452
  }
454
- result[code] = {
453
+ result[code] = self.safe_currency_structure({
455
454
  'info': currency,
456
455
  'id': id,
457
456
  'code': code,
@@ -473,7 +472,7 @@ class gemini(Exchange, ImplicitAPI):
473
472
  },
474
473
  },
475
474
  'networks': networks,
476
- }
475
+ })
477
476
  return result
478
477
 
479
478
  def fetch_markets(self, params={}) -> List[Market]:
ccxt/hitbtc.py CHANGED
@@ -929,29 +929,46 @@ class hitbtc(Exchange, ImplicitAPI):
929
929
  """
930
930
  response = self.publicGetPublicCurrency(params)
931
931
  #
932
- # {
933
- # "WEALTH": {
934
- # "full_name": "ConnectWealth",
935
- # "payin_enabled": False,
936
- # "payout_enabled": False,
937
- # "transfer_enabled": True,
938
- # "precision_transfer": "0.001",
939
- # "networks": [
940
- # {
941
- # "network": "ETH",
942
- # "protocol": "ERC20",
943
- # "default": True,
944
- # "payin_enabled": False,
945
- # "payout_enabled": False,
946
- # "precision_payout": "0.001",
947
- # "payout_fee": "0.016800000000",
948
- # "payout_is_payment_id": False,
949
- # "payin_payment_id": False,
950
- # "payin_confirmations": "2"
951
- # }
952
- # ]
953
- # }
954
- # }
932
+ # {
933
+ # "DFC": {
934
+ # "full_name": "DeFiScale",
935
+ # "crypto": True,
936
+ # "payin_enabled": False,
937
+ # "payout_enabled": True,
938
+ # "transfer_enabled": False,
939
+ # "transfer_to_wallet_enabled": True,
940
+ # "transfer_to_exchange_enabled": False,
941
+ # "sign": "D",
942
+ # "crypto_payment_id_name": "",
943
+ # "crypto_explorer": "https://etherscan.io/tx/{tx}",
944
+ # "precision_transfer": "0.00000001",
945
+ # "delisted": False,
946
+ # "networks": [
947
+ # {
948
+ # "code": "ETH",
949
+ # "network_name": "Ethereum",
950
+ # "network": "ETH",
951
+ # "protocol": "ERC-20",
952
+ # "default": True,
953
+ # "is_ens_available": True,
954
+ # "payin_enabled": True,
955
+ # "payout_enabled": True,
956
+ # "precision_payout": "0.000000000000000001",
957
+ # "payout_fee": "277000.0000000000",
958
+ # "payout_is_payment_id": False,
959
+ # "payin_payment_id": False,
960
+ # "payin_confirmations": "2",
961
+ # "contract_address": "0x1b2a76da77d03b7fc21189d9838f55bd849014af",
962
+ # "crypto_payment_id_name": "",
963
+ # "crypto_explorer": "https://etherscan.io/tx/{tx}",
964
+ # "is_multichain": True,
965
+ # "asset_id": {
966
+ # "contract_address": "0x1b2a76da77d03b7fc21189d9838f55bd849014af"
967
+ # }
968
+ # }
969
+ # ]
970
+ # },
971
+ # }
955
972
  #
956
973
  result: dict = {}
957
974
  currencies = list(response.keys())
@@ -959,46 +976,22 @@ class hitbtc(Exchange, ImplicitAPI):
959
976
  currencyId = currencies[i]
960
977
  code = self.safe_currency_code(currencyId)
961
978
  entry = response[currencyId]
962
- name = self.safe_string(entry, 'full_name')
963
- precision = self.safe_number(entry, 'precision_transfer')
964
- payinEnabled = self.safe_bool(entry, 'payin_enabled', False)
965
- payoutEnabled = self.safe_bool(entry, 'payout_enabled', False)
966
- transferEnabled = self.safe_bool(entry, 'transfer_enabled', False)
967
- active = payinEnabled and payoutEnabled and transferEnabled
968
- rawNetworks = self.safe_value(entry, 'networks', [])
969
- isCrypto = self.safe_bool(entry, 'crypto')
970
- type = 'crypto' if isCrypto else 'fiat'
979
+ rawNetworks = self.safe_list(entry, 'networks', [])
971
980
  networks: dict = {}
972
- fee = None
973
- depositEnabled = None
974
- withdrawEnabled = None
975
981
  for j in range(0, len(rawNetworks)):
976
982
  rawNetwork = rawNetworks[j]
977
983
  networkId = self.safe_string_2(rawNetwork, 'protocol', 'network')
978
984
  networkCode = self.network_id_to_code(networkId)
979
- networkCode = networkCode.upper() if (networkCode is not None) else None
980
- fee = self.safe_number(rawNetwork, 'payout_fee')
981
- networkPrecision = self.safe_number(rawNetwork, 'precision_payout')
982
- payinEnabledNetwork = self.safe_bool(rawNetwork, 'payin_enabled', False)
983
- payoutEnabledNetwork = self.safe_bool(rawNetwork, 'payout_enabled', False)
984
- activeNetwork = payinEnabledNetwork and payoutEnabledNetwork
985
- if payinEnabledNetwork and not depositEnabled:
986
- depositEnabled = True
987
- elif not payinEnabledNetwork:
988
- depositEnabled = False
989
- if payoutEnabledNetwork and not withdrawEnabled:
990
- withdrawEnabled = True
991
- elif not payoutEnabledNetwork:
992
- withdrawEnabled = False
985
+ networkCode = networkCode.upper() if (networkCode is not None) else code # is white label, ensure we safeguard from possible bugs
993
986
  networks[networkCode] = {
994
987
  'info': rawNetwork,
995
988
  'id': networkId,
996
989
  'network': networkCode,
997
- 'fee': fee,
998
- 'active': activeNetwork,
999
- 'deposit': payinEnabledNetwork,
1000
- 'withdraw': payoutEnabledNetwork,
1001
- 'precision': networkPrecision,
990
+ 'active': None,
991
+ 'fee': self.safe_number(rawNetwork, 'payout_fee'),
992
+ 'deposit': self.safe_bool(rawNetwork, 'payin_enabled'),
993
+ 'withdraw': self.safe_bool(rawNetwork, 'payout_enabled'),
994
+ 'precision': self.safe_number(rawNetwork, 'precision_payout'),
1002
995
  'limits': {
1003
996
  'withdraw': {
1004
997
  'min': None,
@@ -1006,27 +999,25 @@ class hitbtc(Exchange, ImplicitAPI):
1006
999
  },
1007
1000
  },
1008
1001
  }
1009
- networksKeys = list(networks.keys())
1010
- networksLength = len(networksKeys)
1011
- result[code] = {
1002
+ result[code] = self.safe_currency_structure({
1012
1003
  'info': entry,
1013
1004
  'code': code,
1014
1005
  'id': currencyId,
1015
- 'precision': precision,
1016
- 'name': name,
1017
- 'active': active,
1018
- 'deposit': depositEnabled,
1019
- 'withdraw': withdrawEnabled,
1006
+ 'precision': self.safe_number(entry, 'precision_transfer'),
1007
+ 'name': self.safe_string(entry, 'full_name'),
1008
+ 'active': not self.safe_bool(entry, 'delisted'),
1009
+ 'deposit': self.safe_bool(entry, 'payin_enabled'),
1010
+ 'withdraw': self.safe_bool(entry, 'payout_enabled'),
1020
1011
  'networks': networks,
1021
- 'fee': fee if (networksLength <= 1) else None,
1012
+ 'fee': None,
1022
1013
  'limits': {
1023
1014
  'amount': {
1024
1015
  'min': None,
1025
1016
  'max': None,
1026
1017
  },
1027
1018
  },
1028
- 'type': type,
1029
- }
1019
+ 'type': None, # 'crypto' field emits incorrect values
1020
+ })
1030
1021
  return result
1031
1022
 
1032
1023
  def create_deposit_address(self, code: str, params={}) -> DepositAddress:
ccxt/htx.py CHANGED
@@ -6945,7 +6945,7 @@ class htx(Exchange, ImplicitAPI):
6945
6945
  if method != 'POST':
6946
6946
  request = self.extend(request, query)
6947
6947
  sortedRequest = self.keysort(request)
6948
- auth = self.urlencode(sortedRequest)
6948
+ auth = self.urlencode(sortedRequest, True) # True is a go only requirment
6949
6949
  # unfortunately, PHP demands double quotes for the escaped newline symbol
6950
6950
  payload = "\n".join([method, self.hostname, url, auth]) # eslint-disable-line quotes
6951
6951
  signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
@@ -7011,7 +7011,7 @@ class htx(Exchange, ImplicitAPI):
7011
7011
  if method != 'POST':
7012
7012
  sortedQuery = self.keysort(query)
7013
7013
  request = self.extend(request, sortedQuery)
7014
- auth = self.urlencode(request).replace('%2c', '%2C') # in c# it manually needs to be uppercased
7014
+ auth = self.urlencode(request, True).replace('%2c', '%2C') # in c# it manually needs to be uppercased
7015
7015
  # unfortunately, PHP demands double quotes for the escaped newline symbol
7016
7016
  payload = "\n".join([method, hostname, url, auth]) # eslint-disable-line quotes
7017
7017
  signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256, 'base64')
ccxt/hyperliquid.py CHANGED
@@ -368,7 +368,7 @@ class hyperliquid(Exchange, ImplicitAPI):
368
368
  id = i
369
369
  name = self.safe_string(data, 'name')
370
370
  code = self.safe_currency_code(name)
371
- result[code] = {
371
+ result[code] = self.safe_currency_structure({
372
372
  'id': id,
373
373
  'name': name,
374
374
  'code': code,
@@ -390,7 +390,7 @@ class hyperliquid(Exchange, ImplicitAPI):
390
390
  'max': None,
391
391
  },
392
392
  },
393
- }
393
+ })
394
394
  return result
395
395
 
396
396
  def fetch_markets(self, params={}) -> List[Market]:
@@ -2178,6 +2178,10 @@ class hyperliquid(Exchange, ImplicitAPI):
2178
2178
  return self.parse_order(data, market)
2179
2179
 
2180
2180
  def parse_order(self, order: dict, market: Market = None) -> Order:
2181
+ #
2182
+ # createOrdersWs error
2183
+ #
2184
+ # {error: 'Insufficient margin to place order. asset=159'}
2181
2185
  #
2182
2186
  # fetchOpenOrders
2183
2187
  #
@@ -2269,6 +2273,12 @@ class hyperliquid(Exchange, ImplicitAPI):
2269
2273
  # "triggerPx": "0.6"
2270
2274
  # }
2271
2275
  #
2276
+ error = self.safe_string(order, 'error')
2277
+ if error is not None:
2278
+ return self.safe_order({
2279
+ 'info': order,
2280
+ 'status': 'rejected',
2281
+ })
2272
2282
  entry = self.safe_dict_n(order, ['order', 'resting', 'filled'])
2273
2283
  if entry is None:
2274
2284
  entry = order
@@ -3444,9 +3454,12 @@ class hyperliquid(Exchange, ImplicitAPI):
3444
3454
  # {"status":"ok","response":{"type":"order","data":{"statuses":[{"error":"Insufficient margin to place order. asset=84"}]}}}
3445
3455
  #
3446
3456
  status = self.safe_string(response, 'status', '')
3457
+ error = self.safe_string(response, 'error')
3447
3458
  message = None
3448
3459
  if status == 'err':
3449
3460
  message = self.safe_string(response, 'response')
3461
+ elif error is not None:
3462
+ message = error
3450
3463
  else:
3451
3464
  responsePayload = self.safe_dict(response, 'response', {})
3452
3465
  data = self.safe_dict(responsePayload, 'data', {})