ccxt 4.4.82__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 (87) 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 +2 -1
  5. ccxt/async_support/__init__.py +1 -5
  6. ccxt/async_support/apex.py +2 -1
  7. ccxt/async_support/base/exchange.py +26 -3
  8. ccxt/async_support/base/ws/cache.py +6 -1
  9. ccxt/async_support/bitget.py +1 -2
  10. ccxt/async_support/bitrue.py +14 -32
  11. ccxt/async_support/bitso.py +33 -0
  12. ccxt/async_support/bitstamp.py +33 -0
  13. ccxt/async_support/blofin.py +145 -14
  14. ccxt/async_support/btcbox.py +25 -5
  15. ccxt/async_support/bybit.py +16 -37
  16. ccxt/async_support/cex.py +2 -4
  17. ccxt/async_support/coinbase.py +56 -42
  18. ccxt/async_support/coinbaseexchange.py +141 -32
  19. ccxt/async_support/coincatch.py +14 -67
  20. ccxt/async_support/coinex.py +28 -29
  21. ccxt/async_support/coinlist.py +17 -16
  22. ccxt/async_support/coinmetro.py +20 -11
  23. ccxt/async_support/coinone.py +8 -10
  24. ccxt/async_support/coinsph.py +124 -2
  25. ccxt/async_support/cryptocom.py +109 -2
  26. ccxt/async_support/cryptomus.py +42 -80
  27. ccxt/async_support/delta.py +75 -36
  28. ccxt/async_support/derive.py +46 -10
  29. ccxt/async_support/ellipx.py +175 -77
  30. ccxt/async_support/gate.py +1 -1
  31. ccxt/async_support/gemini.py +3 -4
  32. ccxt/async_support/hitbtc.py +56 -65
  33. ccxt/async_support/hyperliquid.py +2 -2
  34. ccxt/async_support/kraken.py +27 -23
  35. ccxt/async_support/kucoinfutures.py +5 -0
  36. ccxt/async_support/lbank.py +1 -1
  37. ccxt/async_support/paradex.py +120 -4
  38. ccxt/base/exchange.py +21 -2
  39. ccxt/base/types.py +3 -0
  40. ccxt/bitget.py +1 -2
  41. ccxt/bitrue.py +14 -32
  42. ccxt/bitso.py +33 -0
  43. ccxt/bitstamp.py +33 -0
  44. ccxt/blofin.py +145 -14
  45. ccxt/btcbox.py +24 -5
  46. ccxt/bybit.py +16 -37
  47. ccxt/cex.py +2 -4
  48. ccxt/coinbase.py +56 -42
  49. ccxt/coinbaseexchange.py +141 -32
  50. ccxt/coincatch.py +14 -67
  51. ccxt/coinex.py +28 -29
  52. ccxt/coinlist.py +17 -16
  53. ccxt/coinmetro.py +20 -11
  54. ccxt/coinone.py +8 -10
  55. ccxt/coinsph.py +124 -2
  56. ccxt/cryptocom.py +109 -2
  57. ccxt/cryptomus.py +42 -80
  58. ccxt/delta.py +75 -36
  59. ccxt/derive.py +46 -10
  60. ccxt/ellipx.py +175 -77
  61. ccxt/gate.py +1 -1
  62. ccxt/gemini.py +3 -4
  63. ccxt/hitbtc.py +56 -65
  64. ccxt/hyperliquid.py +2 -2
  65. ccxt/kraken.py +27 -23
  66. ccxt/kucoinfutures.py +5 -0
  67. ccxt/lbank.py +1 -1
  68. ccxt/paradex.py +120 -4
  69. ccxt/pro/__init__.py +69 -3
  70. ccxt/pro/binance.py +31 -33
  71. ccxt/pro/bithumb.py +5 -3
  72. ccxt/pro/kraken.py +249 -79
  73. ccxt/pro/mexc.py +252 -7
  74. ccxt/pro/poloniex.py +6 -2
  75. {ccxt-4.4.82.dist-info → ccxt-4.4.85.dist-info}/METADATA +7 -9
  76. {ccxt-4.4.82.dist-info → ccxt-4.4.85.dist-info}/RECORD +79 -87
  77. ccxt/abstract/bl3p.py +0 -19
  78. ccxt/abstract/idex.py +0 -26
  79. ccxt/async_support/base/ws/fast_client.py +0 -97
  80. ccxt/async_support/bl3p.py +0 -543
  81. ccxt/async_support/idex.py +0 -1889
  82. ccxt/bl3p.py +0 -543
  83. ccxt/idex.py +0 -1889
  84. ccxt/pro/idex.py +0 -687
  85. {ccxt-4.4.82.dist-info → ccxt-4.4.85.dist-info}/LICENSE.txt +0 -0
  86. {ccxt-4.4.82.dist-info → ccxt-4.4.85.dist-info}/WHEEL +0 -0
  87. {ccxt-4.4.82.dist-info → ccxt-4.4.85.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.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
  async 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
  async 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
@@ -1866,7 +1866,7 @@ class gate(Exchange, ImplicitAPI):
1866
1866
  'code': code,
1867
1867
  'type': type,
1868
1868
  'precision': precision,
1869
- 'limits': self.limits,
1869
+ 'limits': None,
1870
1870
  'networks': {},
1871
1871
  'info': [], # will be filled below
1872
1872
  }
@@ -276,7 +276,7 @@ class gemini(Exchange, ImplicitAPI):
276
276
  'fetchMarketFromWebRetries': 10,
277
277
  'fetchMarketsFromAPI': {
278
278
  'fetchDetailsForAllSymbols': False,
279
- 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH'],
279
+ 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH', 'SOL'],
280
280
  },
281
281
  'fetchMarkets': {
282
282
  'webApiEnable': True, # fetches from WEB
@@ -431,7 +431,6 @@ class gemini(Exchange, ImplicitAPI):
431
431
  networkCode = None
432
432
  if networkId is not None:
433
433
  networkCode = self.network_id_to_code(networkId)
434
- if networkCode is not None:
435
434
  networks[networkCode] = {
436
435
  'info': currency,
437
436
  'id': networkId,
@@ -452,7 +451,7 @@ class gemini(Exchange, ImplicitAPI):
452
451
  },
453
452
  },
454
453
  }
455
- result[code] = {
454
+ result[code] = self.safe_currency_structure({
456
455
  'info': currency,
457
456
  'id': id,
458
457
  'code': code,
@@ -474,7 +473,7 @@ class gemini(Exchange, ImplicitAPI):
474
473
  },
475
474
  },
476
475
  'networks': networks,
477
- }
476
+ })
478
477
  return result
479
478
 
480
479
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -929,29 +929,46 @@ class hitbtc(Exchange, ImplicitAPI):
929
929
  """
930
930
  response = await 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
  async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
@@ -369,7 +369,7 @@ class hyperliquid(Exchange, ImplicitAPI):
369
369
  id = i
370
370
  name = self.safe_string(data, 'name')
371
371
  code = self.safe_currency_code(name)
372
- result[code] = {
372
+ result[code] = self.safe_currency_structure({
373
373
  'id': id,
374
374
  'name': name,
375
375
  'code': code,
@@ -391,7 +391,7 @@ class hyperliquid(Exchange, ImplicitAPI):
391
391
  'max': None,
392
392
  },
393
393
  },
394
- }
394
+ })
395
395
  return result
396
396
 
397
397
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -1616,6 +1616,8 @@ class kraken(Exchange, ImplicitAPI):
1616
1616
  'volume': self.amount_to_precision(symbol, amount),
1617
1617
  }
1618
1618
  orderRequest = self.order_request('createOrder', symbol, type, request, amount, price, params)
1619
+ flags = self.safe_string(orderRequest[0], 'oflags', '')
1620
+ isUsingCost = flags.find('viqc') > -1
1619
1621
  response = await self.privatePostAddOrder(self.extend(orderRequest[0], orderRequest[1]))
1620
1622
  #
1621
1623
  # {
@@ -1627,6 +1629,10 @@ class kraken(Exchange, ImplicitAPI):
1627
1629
  # }
1628
1630
  #
1629
1631
  result = self.safe_dict(response, 'result')
1632
+ result['usingCost'] = isUsingCost
1633
+ # it's impossible to know if the order was created using cost or base currency
1634
+ # becuase kraken only returns something like self: {order: 'buy 10.00000000 LTCUSD @ market'}
1635
+ # self usingCost flag is used to help the parsing but omited from the order
1630
1636
  return self.parse_order(result)
1631
1637
 
1632
1638
  def find_market_by_altname_or_id(self, id):
@@ -1713,22 +1719,15 @@ class kraken(Exchange, ImplicitAPI):
1713
1719
  # }
1714
1720
  #
1715
1721
  # ws - createOrder
1716
- # {
1717
- # "descr": 'sell 0.00010000 XBTUSDT @ market',
1718
- # "event": 'addOrderStatus',
1719
- # "reqid": 1,
1720
- # "status": 'ok',
1721
- # "txid": 'OAVXZH-XIE54-JCYYDG'
1722
- # }
1722
+ # {
1723
+ # "order_id": "OXM2QD-EALR2-YBAVEU"
1724
+ # }
1725
+ #
1723
1726
  # ws - editOrder
1724
- # {
1725
- # "descr": "order edited price = 9000.00000000",
1726
- # "event": "editOrderStatus",
1727
- # "originaltxid": "O65KZW-J4AW3-VFS74A",
1728
- # "reqid": 3,
1729
- # "status": "ok",
1730
- # "txid": "OTI672-HJFAO-XOIPPK"
1731
- # }
1727
+ # {
1728
+ # "amend_id": "TJSMEH-AA67V-YUSQ6O",
1729
+ # "order_id": "OXM2QD-EALR2-YBAVEU"
1730
+ # }
1732
1731
  #
1733
1732
  # {
1734
1733
  # "error": [],
@@ -1796,6 +1795,8 @@ class kraken(Exchange, ImplicitAPI):
1796
1795
  # "oflags": "fciq"
1797
1796
  # }
1798
1797
  #
1798
+ isUsingCost = self.safe_bool(order, 'usingCost', False)
1799
+ order = self.omit(order, 'usingCost')
1799
1800
  description = self.safe_dict(order, 'descr', {})
1800
1801
  orderDescriptionObj = self.safe_dict(order, 'descr') # can be null
1801
1802
  orderDescription = None
@@ -1808,11 +1809,15 @@ class kraken(Exchange, ImplicitAPI):
1808
1809
  marketId = None
1809
1810
  price = None
1810
1811
  amount = None
1812
+ cost = None
1811
1813
  triggerPrice = None
1812
1814
  if orderDescription is not None:
1813
1815
  parts = orderDescription.split(' ')
1814
1816
  side = self.safe_string(parts, 0)
1815
- amount = self.safe_string(parts, 1)
1817
+ if not isUsingCost:
1818
+ amount = self.safe_string(parts, 1)
1819
+ else:
1820
+ cost = self.safe_string(parts, 1)
1816
1821
  marketId = self.safe_string(parts, 2)
1817
1822
  part4 = self.safe_string(parts, 4)
1818
1823
  part5 = self.safe_string(parts, 5)
@@ -1842,13 +1847,12 @@ class kraken(Exchange, ImplicitAPI):
1842
1847
  # kraken truncates the cost in the api response so we will ignore it and calculate it from average & filled
1843
1848
  # cost = self.safe_string(order, 'cost')
1844
1849
  price = self.safe_string(description, 'price', price)
1845
- # when type = trailling stop returns price = '+50.0000%'
1846
- if (price is not None) and price.endswith('%'):
1850
+ # when type = trailing stop returns price = '+50.0000%'
1851
+ if (price is not None) and (price.endswith('%') or Precise.string_equals(price, '0.00000') or Precise.string_equals(price, '0')):
1847
1852
  price = None # self is not the price we want
1848
- if (price is None) or Precise.string_equals(price, '0'):
1853
+ if price is None:
1849
1854
  price = self.safe_string(description, 'price2')
1850
- if (price is None) or Precise.string_equals(price, '0'):
1851
- price = self.safe_string(order, 'price', price)
1855
+ price = self.safe_string_2(order, 'limitprice', 'price', price)
1852
1856
  flags = self.safe_string(order, 'oflags', '')
1853
1857
  isPostOnly = flags.find('post') > -1
1854
1858
  average = self.safe_number(order, 'price')
@@ -1865,7 +1869,7 @@ class kraken(Exchange, ImplicitAPI):
1865
1869
  elif flags.find('fcib') >= 0:
1866
1870
  fee['currency'] = market['base']
1867
1871
  status = self.parse_order_status(self.safe_string(order, 'status'))
1868
- id = self.safe_string_n(order, ['id', 'txid', 'amend_id'])
1872
+ id = self.safe_string_n(order, ['id', 'txid', 'order_id', 'amend_id'])
1869
1873
  if (id is None) or (id.startswith('[')):
1870
1874
  txid = self.safe_list(order, 'txid')
1871
1875
  id = self.safe_string(txid, 0)
@@ -1922,7 +1926,7 @@ class kraken(Exchange, ImplicitAPI):
1922
1926
  'triggerPrice': triggerPrice,
1923
1927
  'takeProfitPrice': takeProfitPrice,
1924
1928
  'stopLossPrice': stopLossPrice,
1925
- 'cost': None,
1929
+ 'cost': cost,
1926
1930
  'amount': amount,
1927
1931
  'filled': filled,
1928
1932
  'average': average,
@@ -1510,6 +1510,7 @@ class kucoinfutures(kucoin, ImplicitAPI):
1510
1510
  :param str [params.timeInForce]: GTC, GTT, IOC, or FOK, default is GTC, limit orders only
1511
1511
  :param str [params.postOnly]: Post only flag, invalid when timeInForce is IOC or FOK
1512
1512
  :param float [params.cost]: the cost of the order in units of USDT
1513
+ :param str [params.marginMode]: 'cross' or 'isolated', default is 'isolated'
1513
1514
  ----------------- Exchange Specific Parameters -----------------
1514
1515
  :param float [params.leverage]: Leverage size of the order(mandatory param in request, default is 1)
1515
1516
  :param str [params.clientOid]: client order id, defaults to uuid if not passed
@@ -1607,6 +1608,10 @@ class kucoinfutures(kucoin, ImplicitAPI):
1607
1608
  'type': type, # limit or market
1608
1609
  'leverage': 1,
1609
1610
  }
1611
+ marginModeUpper = self.safe_string_upper(params, 'marginMode')
1612
+ if marginModeUpper is not None:
1613
+ params = self.omit(params, 'marginMode')
1614
+ request['marginMode'] = marginModeUpper
1610
1615
  cost = self.safe_string(params, 'cost')
1611
1616
  params = self.omit(params, 'cost')
1612
1617
  if cost is not None: