ccxt 4.4.92__py2.py3-none-any.whl → 4.4.94__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.
- ccxt/__init__.py +1 -1
- ccxt/abstract/lbank.py +1 -1
- ccxt/ascendex.py +9 -8
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +9 -8
- ccxt/async_support/base/exchange.py +4 -1
- ccxt/async_support/base/ws/client.py +3 -0
- ccxt/async_support/binance.py +42 -1
- ccxt/async_support/bitmex.py +3 -3
- ccxt/async_support/bybit.py +83 -10
- ccxt/async_support/coinbase.py +4 -1
- ccxt/async_support/coinbaseexchange.py +53 -0
- ccxt/async_support/coincheck.py +45 -4
- ccxt/async_support/coinex.py +16 -12
- ccxt/async_support/coinmetro.py +15 -3
- ccxt/async_support/cryptomus.py +30 -52
- ccxt/async_support/deribit.py +6 -6
- ccxt/async_support/exmo.py +64 -52
- ccxt/async_support/htx.py +5 -1
- ccxt/async_support/hyperliquid.py +126 -33
- ccxt/async_support/kucoin.py +12 -14
- ccxt/async_support/latoken.py +19 -71
- ccxt/async_support/lbank.py +2 -2
- ccxt/async_support/okx.py +159 -3
- ccxt/async_support/paradex.py +54 -0
- ccxt/async_support/phemex.py +3 -3
- ccxt/async_support/wavesexchange.py +12 -2
- ccxt/base/exchange.py +96 -31
- ccxt/binance.py +42 -1
- ccxt/bitmex.py +3 -3
- ccxt/bybit.py +83 -10
- ccxt/coinbase.py +4 -1
- ccxt/coinbaseexchange.py +53 -0
- ccxt/coincheck.py +45 -4
- ccxt/coinex.py +16 -12
- ccxt/coinmetro.py +14 -3
- ccxt/cryptomus.py +30 -52
- ccxt/deribit.py +6 -6
- ccxt/exmo.py +64 -52
- ccxt/htx.py +5 -1
- ccxt/hyperliquid.py +126 -33
- ccxt/kucoin.py +12 -14
- ccxt/latoken.py +19 -71
- ccxt/lbank.py +2 -2
- ccxt/okx.py +159 -3
- ccxt/paradex.py +54 -0
- ccxt/phemex.py +3 -3
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitstamp.py +48 -16
- ccxt/pro/bybit.py +2 -1
- ccxt/test/tests_async.py +17 -15
- ccxt/test/tests_sync.py +17 -15
- ccxt/wavesexchange.py +12 -2
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/METADATA +4 -4
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/RECORD +58 -58
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/WHEEL +0 -0
- {ccxt-4.4.92.dist-info → ccxt-4.4.94.dist-info}/top_level.txt +0 -0
@@ -354,6 +354,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
354
354
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
355
355
|
:returns dict: an associative dictionary of currencies
|
356
356
|
"""
|
357
|
+
if self.check_required_credentials(False):
|
358
|
+
await self.handle_builder_fee_approval()
|
357
359
|
request: dict = {
|
358
360
|
'type': 'meta',
|
359
361
|
}
|
@@ -627,6 +629,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
627
629
|
'quote': quote,
|
628
630
|
'settle': None,
|
629
631
|
'baseId': baseId,
|
632
|
+
'baseName': baseName,
|
630
633
|
'quoteId': quoteId,
|
631
634
|
'settleId': None,
|
632
635
|
'type': 'spot',
|
@@ -696,7 +699,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
696
699
|
# }
|
697
700
|
#
|
698
701
|
quoteId = 'USDC'
|
699
|
-
|
702
|
+
baseName = self.safe_string(market, 'name')
|
703
|
+
base = self.safe_currency_code(baseName)
|
700
704
|
quote = self.safe_currency_code(quoteId)
|
701
705
|
baseId = self.safe_string(market, 'baseId')
|
702
706
|
settleId = 'USDC'
|
@@ -728,6 +732,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
728
732
|
'quote': quote,
|
729
733
|
'settle': settle,
|
730
734
|
'baseId': baseId,
|
735
|
+
'baseName': baseName,
|
731
736
|
'quoteId': quoteId,
|
732
737
|
'settleId': settleId,
|
733
738
|
'type': 'swap',
|
@@ -784,6 +789,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
784
789
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
785
790
|
:param str [params.type]: wallet type, ['spot', 'swap'], defaults to swap
|
786
791
|
:param str [params.marginMode]: 'cross' or 'isolated', for margin trading, uses self.options.defaultMarginMode if not passed, defaults to None/None/None
|
792
|
+
:param str [params.subAccountAddress]: sub account user address
|
787
793
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
788
794
|
"""
|
789
795
|
userAddress = None
|
@@ -793,9 +799,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
793
799
|
marginMode = None
|
794
800
|
marginMode, params = self.handle_margin_mode_and_params('fetchBalance', params)
|
795
801
|
isSpot = (type == 'spot')
|
796
|
-
reqType = 'spotClearinghouseState' if (isSpot) else 'clearinghouseState'
|
797
802
|
request: dict = {
|
798
|
-
'type':
|
803
|
+
'type': 'spotClearinghouseState' if (isSpot) else 'clearinghouseState',
|
799
804
|
'user': userAddress,
|
800
805
|
}
|
801
806
|
response = await self.publicPostInfo(self.extend(request, params))
|
@@ -879,7 +884,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
879
884
|
market = self.market(symbol)
|
880
885
|
request: dict = {
|
881
886
|
'type': 'l2Book',
|
882
|
-
'coin': market['
|
887
|
+
'coin': market['baseName'] if market['swap'] else market['id'],
|
883
888
|
}
|
884
889
|
response = await self.publicPostInfo(self.extend(request, params))
|
885
890
|
#
|
@@ -1112,7 +1117,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1112
1117
|
request: dict = {
|
1113
1118
|
'type': 'candleSnapshot',
|
1114
1119
|
'req': {
|
1115
|
-
'coin': market['
|
1120
|
+
'coin': market['baseName'] if market['swap'] else market['id'],
|
1116
1121
|
'interval': self.safe_string(self.timeframes, timeframe, timeframe),
|
1117
1122
|
'startTime': since,
|
1118
1123
|
'endTime': until,
|
@@ -1175,6 +1180,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1175
1180
|
:param int [params.until]: timestamp in ms of the latest trade
|
1176
1181
|
:param str [params.address]: wallet address that made trades
|
1177
1182
|
:param str [params.user]: wallet address that made trades
|
1183
|
+
:param str [params.subAccountAddress]: sub account user address
|
1178
1184
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1179
1185
|
"""
|
1180
1186
|
userAddress = None
|
@@ -1353,6 +1359,67 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1353
1359
|
}
|
1354
1360
|
return self.sign_user_signed_action(messageTypes, message)
|
1355
1361
|
|
1362
|
+
def build_approve_builder_fee_sig(self, message):
|
1363
|
+
messageTypes: dict = {
|
1364
|
+
'HyperliquidTransaction:ApproveBuilderFee': [
|
1365
|
+
{'name': 'hyperliquidChain', 'type': 'string'},
|
1366
|
+
{'name': 'maxFeeRate', 'type': 'string'},
|
1367
|
+
{'name': 'builder', 'type': 'address'},
|
1368
|
+
{'name': 'nonce', 'type': 'uint64'},
|
1369
|
+
],
|
1370
|
+
}
|
1371
|
+
return self.sign_user_signed_action(messageTypes, message)
|
1372
|
+
|
1373
|
+
async def approve_builder_fee(self, builder: str, maxFeeRate: str):
|
1374
|
+
nonce = self.milliseconds()
|
1375
|
+
isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
1376
|
+
payload: dict = {
|
1377
|
+
'hyperliquidChain': 'Testnet' if isSandboxMode else 'Mainnet',
|
1378
|
+
'maxFeeRate': maxFeeRate,
|
1379
|
+
'builder': builder,
|
1380
|
+
'nonce': nonce,
|
1381
|
+
}
|
1382
|
+
sig = self.build_approve_builder_fee_sig(payload)
|
1383
|
+
action = {
|
1384
|
+
'hyperliquidChain': payload['hyperliquidChain'],
|
1385
|
+
'signatureChainId': '0x66eee',
|
1386
|
+
'maxFeeRate': payload['maxFeeRate'],
|
1387
|
+
'builder': payload['builder'],
|
1388
|
+
'nonce': nonce,
|
1389
|
+
'type': 'approveBuilderFee',
|
1390
|
+
}
|
1391
|
+
request: dict = {
|
1392
|
+
'action': action,
|
1393
|
+
'nonce': nonce,
|
1394
|
+
'signature': sig,
|
1395
|
+
'vaultAddress': None,
|
1396
|
+
}
|
1397
|
+
#
|
1398
|
+
# {
|
1399
|
+
# "status": "ok",
|
1400
|
+
# "response": {
|
1401
|
+
# "type": "default"
|
1402
|
+
# }
|
1403
|
+
# }
|
1404
|
+
#
|
1405
|
+
return await self.privatePostExchange(request)
|
1406
|
+
|
1407
|
+
async def handle_builder_fee_approval(self):
|
1408
|
+
buildFee = self.safe_bool(self.options, 'builderFee', True)
|
1409
|
+
if not buildFee:
|
1410
|
+
return False # skip if builder fee is not enabled
|
1411
|
+
approvedBuilderFee = self.safe_bool(self.options, 'approvedBuilderFee', False)
|
1412
|
+
if approvedBuilderFee:
|
1413
|
+
return True # skip if builder fee is already approved
|
1414
|
+
try:
|
1415
|
+
builder = self.safe_string(self.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6')
|
1416
|
+
maxFeeRate = self.safe_string(self.options, 'feeRate', '0.01%')
|
1417
|
+
await self.approve_builder_fee(builder, maxFeeRate)
|
1418
|
+
self.options['approvedBuilderFee'] = True
|
1419
|
+
except Exception as e:
|
1420
|
+
self.options['builderFee'] = False # disable builder fee if an error occurs
|
1421
|
+
return True
|
1422
|
+
|
1356
1423
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
1357
1424
|
"""
|
1358
1425
|
create a trade order
|
@@ -1372,6 +1439,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1372
1439
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1373
1440
|
:param str [params.slippage]: the slippage for market order
|
1374
1441
|
:param str [params.vaultAddress]: the vault address for order
|
1442
|
+
:param str [params.subAccountAddress]: sub account user address
|
1375
1443
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1376
1444
|
"""
|
1377
1445
|
await self.load_markets()
|
@@ -1390,6 +1458,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1390
1458
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1391
1459
|
"""
|
1392
1460
|
await self.load_markets()
|
1461
|
+
await self.handle_builder_fee_approval()
|
1393
1462
|
request = self.create_orders_request(orders, params)
|
1394
1463
|
response = await self.privatePostExchange(request)
|
1395
1464
|
#
|
@@ -1553,10 +1622,10 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1553
1622
|
'type': 'order',
|
1554
1623
|
'orders': orderReq,
|
1555
1624
|
'grouping': grouping,
|
1556
|
-
# 'brokerCode': 1, # cant
|
1557
1625
|
}
|
1558
|
-
if
|
1559
|
-
|
1626
|
+
if self.safe_bool(self.options, 'approvedBuilderFee', False):
|
1627
|
+
wallet = self.safe_string_lower(self.options, 'builder', '0x6530512A6c89C7cfCEbC3BA7fcD9aDa5f30827a6')
|
1628
|
+
orderAction['builder'] = {'b': wallet, 'f': self.safe_integer(self.options, 'feeInt', 10)}
|
1560
1629
|
signature = self.sign_l1_action(orderAction, nonce, vaultAddress)
|
1561
1630
|
request: dict = {
|
1562
1631
|
'action': orderAction,
|
@@ -1581,6 +1650,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1581
1650
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1582
1651
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1583
1652
|
:param str [params.vaultAddress]: the vault address for order
|
1653
|
+
:param str [params.subAccountAddress]: sub account user address
|
1584
1654
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1585
1655
|
"""
|
1586
1656
|
orders = await self.cancel_orders([id], symbol, params)
|
@@ -1598,6 +1668,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1598
1668
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1599
1669
|
:param string|str[] [params.clientOrderId]: client order ids,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1600
1670
|
:param str [params.vaultAddress]: the vault address
|
1671
|
+
:param str [params.subAccountAddress]: sub account user address
|
1601
1672
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1602
1673
|
"""
|
1603
1674
|
self.check_required_credentials()
|
@@ -1636,7 +1707,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1636
1707
|
})
|
1637
1708
|
cancelAction['cancels'] = cancelReq
|
1638
1709
|
vaultAddress = None
|
1639
|
-
vaultAddress, params = self.
|
1710
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelOrders', 'vaultAddress', 'subAccountAddress')
|
1640
1711
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1641
1712
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1642
1713
|
request['action'] = cancelAction
|
@@ -1680,6 +1751,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1680
1751
|
:param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
|
1681
1752
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1682
1753
|
:param str [params.vaultAddress]: the vault address
|
1754
|
+
:param str [params.subAccountAddress]: sub account user address
|
1683
1755
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1684
1756
|
"""
|
1685
1757
|
self.check_required_credentials()
|
@@ -1716,7 +1788,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1716
1788
|
cancelAction['type'] = 'cancelByCloid' if cancelByCloid else 'cancel'
|
1717
1789
|
cancelAction['cancels'] = cancelReq
|
1718
1790
|
vaultAddress = None
|
1719
|
-
vaultAddress, params = self.
|
1791
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelOrdersForSymbols', 'vaultAddress', 'subAccountAddress')
|
1720
1792
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1721
1793
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1722
1794
|
request['action'] = cancelAction
|
@@ -1746,6 +1818,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1746
1818
|
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
1747
1819
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1748
1820
|
:param str [params.vaultAddress]: the vault address
|
1821
|
+
:param str [params.subAccountAddress]: sub account user address
|
1749
1822
|
:returns dict: the api result
|
1750
1823
|
"""
|
1751
1824
|
self.check_required_credentials()
|
@@ -1761,7 +1834,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1761
1834
|
'time': nonce + timeout,
|
1762
1835
|
}
|
1763
1836
|
vaultAddress = None
|
1764
|
-
vaultAddress, params = self.
|
1837
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'cancelAllOrdersAfter', 'vaultAddress', 'subAccountAddress')
|
1765
1838
|
vaultAddress = self.format_vault_address(vaultAddress)
|
1766
1839
|
signature = self.sign_l1_action(cancelAction, nonce, vaultAddress)
|
1767
1840
|
request['action'] = cancelAction
|
@@ -1904,6 +1977,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
1904
1977
|
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
1905
1978
|
:param str [params.clientOrderId]: client order id,(optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef)
|
1906
1979
|
:param str [params.vaultAddress]: the vault address for order
|
1980
|
+
:param str [params.subAccountAddress]: sub account user address
|
1907
1981
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
1908
1982
|
"""
|
1909
1983
|
await self.load_markets()
|
@@ -2023,7 +2097,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2023
2097
|
market = self.market(symbol)
|
2024
2098
|
request: dict = {
|
2025
2099
|
'type': 'fundingHistory',
|
2026
|
-
'coin': market['
|
2100
|
+
'coin': market['baseName'],
|
2027
2101
|
}
|
2028
2102
|
if since is not None:
|
2029
2103
|
request['startTime'] = since
|
@@ -2071,6 +2145,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2071
2145
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2072
2146
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2073
2147
|
:param str [params.method]: 'openOrders' or 'frontendOpenOrders' default is 'frontendOpenOrders'
|
2148
|
+
:param str [params.subAccountAddress]: sub account user address
|
2074
2149
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2075
2150
|
"""
|
2076
2151
|
userAddress = None
|
@@ -2159,6 +2234,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2159
2234
|
:param int [limit]: the maximum number of open orders structures to retrieve
|
2160
2235
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2161
2236
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2237
|
+
:param str [params.subAccountAddress]: sub account user address
|
2162
2238
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2163
2239
|
"""
|
2164
2240
|
userAddress = None
|
@@ -2195,6 +2271,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2195
2271
|
:param str symbol: unified symbol of the market the order was made in
|
2196
2272
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2197
2273
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2274
|
+
:param str [params.subAccountAddress]: sub account user address
|
2198
2275
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2199
2276
|
"""
|
2200
2277
|
userAddress = None
|
@@ -2420,6 +2497,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2420
2497
|
:param int [limit]: the maximum number of trades structures to retrieve
|
2421
2498
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2422
2499
|
:param int [params.until]: timestamp in ms of the latest trade
|
2500
|
+
:param str [params.subAccountAddress]: sub account user address
|
2423
2501
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
2424
2502
|
"""
|
2425
2503
|
userAddress = None
|
@@ -2540,6 +2618,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2540
2618
|
:param str[] [symbols]: list of unified market symbols
|
2541
2619
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2542
2620
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
2621
|
+
:param str [params.subAccountAddress]: sub account user address
|
2543
2622
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
2544
2623
|
"""
|
2545
2624
|
await self.load_markets()
|
@@ -2680,6 +2759,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2680
2759
|
:param str symbol: unified market symbol of the market the position is held in, default is None
|
2681
2760
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2682
2761
|
:param str [params.leverage]: the rate of leverage, is required if setting trade mode(symbol)
|
2762
|
+
:param str [params.vaultAddress]: the vault address
|
2763
|
+
:param str [params.subAccountAddress]: sub account user address
|
2683
2764
|
:returns dict: response from the exchange
|
2684
2765
|
"""
|
2685
2766
|
if symbol is None:
|
@@ -2700,7 +2781,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2700
2781
|
'leverage': leverage,
|
2701
2782
|
}
|
2702
2783
|
vaultAddress = None
|
2703
|
-
vaultAddress, params = self.
|
2784
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'setMarginMode', 'vaultAddress', 'subAccountAddress')
|
2704
2785
|
if vaultAddress is not None:
|
2705
2786
|
if vaultAddress.startswith('0x'):
|
2706
2787
|
vaultAddress = vaultAddress.replace('0x', '')
|
@@ -2749,7 +2830,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2749
2830
|
'leverage': leverage,
|
2750
2831
|
}
|
2751
2832
|
vaultAddress = None
|
2752
|
-
vaultAddress, params = self.
|
2833
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'setLeverage', 'vaultAddress', 'subAccountAddress')
|
2753
2834
|
vaultAddress = self.format_vault_address(vaultAddress)
|
2754
2835
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
2755
2836
|
request: dict = {
|
@@ -2781,6 +2862,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2781
2862
|
:param str symbol: unified market symbol
|
2782
2863
|
:param float amount: amount of margin to add
|
2783
2864
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2865
|
+
:param str [params.vaultAddress]: the vault address
|
2866
|
+
:param str [params.subAccountAddress]: sub account user address
|
2784
2867
|
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
|
2785
2868
|
"""
|
2786
2869
|
return await self.modify_margin_helper(symbol, amount, 'add', params)
|
@@ -2794,6 +2877,8 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2794
2877
|
:param str symbol: unified market symbol
|
2795
2878
|
:param float amount: the amount of margin to remove
|
2796
2879
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2880
|
+
:param str [params.vaultAddress]: the vault address
|
2881
|
+
:param str [params.subAccountAddress]: sub account user address
|
2797
2882
|
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=reduce-margin-structure>`
|
2798
2883
|
"""
|
2799
2884
|
return await self.modify_margin_helper(symbol, amount, 'reduce', params)
|
@@ -2813,7 +2898,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2813
2898
|
'ntli': sz,
|
2814
2899
|
}
|
2815
2900
|
vaultAddress = None
|
2816
|
-
vaultAddress, params = self.
|
2901
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'modifyMargin', 'vaultAddress', 'subAccountAddress')
|
2817
2902
|
vaultAddress = self.format_vault_address(vaultAddress)
|
2818
2903
|
signature = self.sign_l1_action(updateAction, nonce, vaultAddress)
|
2819
2904
|
request: dict = {
|
@@ -2908,28 +2993,31 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
2908
2993
|
transferRequest['vaultAddress'] = vaultAddress
|
2909
2994
|
transferResponse = await self.privatePostExchange(transferRequest)
|
2910
2995
|
return transferResponse
|
2911
|
-
#
|
2912
|
-
self.check_address(toAccount)
|
2996
|
+
# transfer between main account and subaccount
|
2913
2997
|
if code is not None:
|
2914
2998
|
code = code.upper()
|
2915
2999
|
if code != 'USDC':
|
2916
3000
|
raise NotSupported(self.id + ' transfer() only support USDC')
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
2920
|
-
|
2921
|
-
|
3001
|
+
isDeposit = False
|
3002
|
+
subAccountAddress = None
|
3003
|
+
if fromAccount == 'main':
|
3004
|
+
subAccountAddress = toAccount
|
3005
|
+
isDeposit = True
|
3006
|
+
elif toAccount == 'main':
|
3007
|
+
subAccountAddress = fromAccount
|
3008
|
+
else:
|
3009
|
+
raise NotSupported(self.id + ' transfer() only support main <> subaccount transfer')
|
3010
|
+
self.check_address(subAccountAddress)
|
3011
|
+
usd = self.parse_to_int(Precise.string_mul(self.number_to_string(amount), '1000000'))
|
3012
|
+
action = {
|
3013
|
+
'type': 'subAccountTransfer',
|
3014
|
+
'subAccountUser': subAccountAddress,
|
3015
|
+
'isDeposit': isDeposit,
|
3016
|
+
'usd': usd,
|
2922
3017
|
}
|
2923
|
-
sig = self.
|
3018
|
+
sig = self.sign_l1_action(action, nonce)
|
2924
3019
|
request: dict = {
|
2925
|
-
'action':
|
2926
|
-
'hyperliquidChain': payload['hyperliquidChain'],
|
2927
|
-
'signatureChainId': '0x66eee', # check self out
|
2928
|
-
'destination': toAccount,
|
2929
|
-
'amount': str(amount),
|
2930
|
-
'time': nonce,
|
2931
|
-
'type': 'usdSend',
|
2932
|
-
},
|
3020
|
+
'action': action,
|
2933
3021
|
'nonce': nonce,
|
2934
3022
|
'signature': sig,
|
2935
3023
|
}
|
@@ -3074,6 +3162,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3074
3162
|
:param str symbol: unified market symbol
|
3075
3163
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3076
3164
|
:param str [params.user]: user address, will default to self.walletAddress if not provided
|
3165
|
+
:param str [params.subAccountAddress]: sub account user address
|
3077
3166
|
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
3078
3167
|
"""
|
3079
3168
|
await self.load_markets()
|
@@ -3180,6 +3269,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3180
3269
|
:param int [limit]: max number of ledger entries to return
|
3181
3270
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3182
3271
|
:param int [params.until]: timestamp in ms of the latest ledger entry
|
3272
|
+
:param str [params.subAccountAddress]: sub account user address
|
3183
3273
|
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
3184
3274
|
"""
|
3185
3275
|
await self.load_markets()
|
@@ -3267,6 +3357,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3267
3357
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
3268
3358
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3269
3359
|
:param int [params.until]: the latest time in ms to fetch withdrawals for
|
3360
|
+
:param str [params.subAccountAddress]: sub account user address
|
3270
3361
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3271
3362
|
"""
|
3272
3363
|
await self.load_markets()
|
@@ -3308,6 +3399,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3308
3399
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
3309
3400
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3310
3401
|
:param int [params.until]: the latest time in ms to fetch withdrawals for
|
3402
|
+
:param str [params.subAccountAddress]: sub account user address
|
3311
3403
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3312
3404
|
"""
|
3313
3405
|
await self.load_markets()
|
@@ -3405,6 +3497,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3405
3497
|
:param int [since]: the earliest time in ms to fetch funding history for
|
3406
3498
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
3407
3499
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3500
|
+
:param str [params.subAccountAddress]: sub account user address
|
3408
3501
|
:returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
3409
3502
|
"""
|
3410
3503
|
await self.load_markets()
|
@@ -3495,7 +3588,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3495
3588
|
|
3496
3589
|
def handle_public_address(self, methodName: str, params: dict):
|
3497
3590
|
userAux = None
|
3498
|
-
userAux, params = self.
|
3591
|
+
userAux, params = self.handle_option_and_params_2(params, methodName, 'user', 'subAccountAddress')
|
3499
3592
|
user = userAux
|
3500
3593
|
user, params = self.handle_option_and_params(params, methodName, 'address', userAux)
|
3501
3594
|
if (user is not None) and (user != ''):
|
@@ -3562,7 +3655,7 @@ class hyperliquid(Exchange, ImplicitAPI):
|
|
3562
3655
|
def parse_create_edit_order_args(self, id: Str, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
3563
3656
|
market = self.market(symbol)
|
3564
3657
|
vaultAddress = None
|
3565
|
-
vaultAddress, params = self.
|
3658
|
+
vaultAddress, params = self.handle_option_and_params_2(params, 'createOrder', 'vaultAddress', 'subAccountAddress')
|
3566
3659
|
vaultAddress = self.format_vault_address(vaultAddress)
|
3567
3660
|
symbol = market['symbol']
|
3568
3661
|
order = {
|
ccxt/async_support/kucoin.py
CHANGED
@@ -1397,35 +1397,31 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1397
1397
|
# }
|
1398
1398
|
#
|
1399
1399
|
currenciesData = self.safe_list(response, 'data', [])
|
1400
|
+
brokenCurrencies = self.safe_list(self.options, 'brokenCurrencies', ['00', 'OPEN_ERROR', 'HUF', 'BDT'])
|
1401
|
+
otherFiats = self.safe_list(self.options, 'fiats', ['KWD', 'IRR', 'PKR'])
|
1400
1402
|
result: dict = {}
|
1401
1403
|
for i in range(0, len(currenciesData)):
|
1402
1404
|
entry = currenciesData[i]
|
1403
1405
|
id = self.safe_string(entry, 'currency')
|
1404
|
-
|
1406
|
+
if self.in_array(id, brokenCurrencies):
|
1407
|
+
continue # skip buggy entries: https://t.me/KuCoin_API/217798
|
1405
1408
|
code = self.safe_currency_code(id)
|
1406
1409
|
networks: dict = {}
|
1407
1410
|
chains = self.safe_list(entry, 'chains', [])
|
1408
|
-
rawPrecision = self.safe_string(entry, 'precision')
|
1409
|
-
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1410
1411
|
chainsLength = len(chains)
|
1411
|
-
if not chainsLength:
|
1412
|
-
# one buggy coin, which doesn't contain info https://t.me/KuCoin_API/173118
|
1413
|
-
continue
|
1414
1412
|
for j in range(0, chainsLength):
|
1415
1413
|
chain = chains[j]
|
1416
1414
|
chainId = self.safe_string(chain, 'chainId')
|
1417
1415
|
networkCode = self.network_id_to_code(chainId, code)
|
1418
|
-
chainWithdrawEnabled = self.safe_bool(chain, 'isWithdrawEnabled', False)
|
1419
|
-
chainDepositEnabled = self.safe_bool(chain, 'isDepositEnabled', False)
|
1420
1416
|
networks[networkCode] = {
|
1421
1417
|
'info': chain,
|
1422
1418
|
'id': chainId,
|
1423
1419
|
'name': self.safe_string(chain, 'chainName'),
|
1424
1420
|
'code': networkCode,
|
1425
|
-
'active':
|
1421
|
+
'active': None,
|
1426
1422
|
'fee': self.safe_number(chain, 'withdrawalMinFee'),
|
1427
|
-
'deposit':
|
1428
|
-
'withdraw':
|
1423
|
+
'deposit': self.safe_bool(chain, 'isDepositEnabled'),
|
1424
|
+
'withdraw': self.safe_bool(chain, 'isWithdrawEnabled'),
|
1429
1425
|
'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'withdrawPrecision'))),
|
1430
1426
|
'limits': {
|
1431
1427
|
'withdraw': {
|
@@ -1439,10 +1435,12 @@ class kucoin(Exchange, ImplicitAPI):
|
|
1439
1435
|
},
|
1440
1436
|
}
|
1441
1437
|
# kucoin has determined 'fiat' currencies with below logic
|
1442
|
-
|
1438
|
+
rawPrecision = self.safe_string(entry, 'precision')
|
1439
|
+
precision = self.parse_number(self.parse_precision(rawPrecision))
|
1440
|
+
isFiat = self.in_array(id, otherFiats) or ((rawPrecision == '2') and (chainsLength == 0))
|
1443
1441
|
result[code] = self.safe_currency_structure({
|
1444
1442
|
'id': id,
|
1445
|
-
'name':
|
1443
|
+
'name': self.safe_string(entry, 'fullName'),
|
1446
1444
|
'code': code,
|
1447
1445
|
'type': 'fiat' if isFiat else 'crypto',
|
1448
1446
|
'precision': precision,
|
@@ -2628,7 +2626,7 @@ class kucoin(Exchange, ImplicitAPI):
|
|
2628
2626
|
"""
|
2629
2627
|
await self.load_markets()
|
2630
2628
|
request: dict = {}
|
2631
|
-
trigger = self.
|
2629
|
+
trigger = self.safe_bool_2(params, 'trigger', 'stop', False)
|
2632
2630
|
hf = None
|
2633
2631
|
hf, params = self.handle_hf_and_params(params)
|
2634
2632
|
params = self.omit(params, 'stop')
|
ccxt/async_support/latoken.py
CHANGED
@@ -247,6 +247,8 @@ class latoken(Exchange, ImplicitAPI):
|
|
247
247
|
'fetchTradingFee': {
|
248
248
|
'method': 'fetchPrivateTradingFee', # or 'fetchPublicTradingFee'
|
249
249
|
},
|
250
|
+
'timeDifference': 0, # the difference between system clock and exchange clock
|
251
|
+
'adjustForTimeDifference': True, # controls the adjustment logic upon instantiation
|
250
252
|
},
|
251
253
|
'features': {
|
252
254
|
'spot': {
|
@@ -347,39 +349,6 @@ class latoken(Exchange, ImplicitAPI):
|
|
347
349
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
348
350
|
:returns dict[]: an array of objects representing market data
|
349
351
|
"""
|
350
|
-
currencies = await self.fetch_currencies_from_cache(params)
|
351
|
-
#
|
352
|
-
# [
|
353
|
-
# {
|
354
|
-
# "id":"1a075819-9e0b-48fc-8784-4dab1d186d6d",
|
355
|
-
# "status":"CURRENCY_STATUS_ACTIVE",
|
356
|
-
# "type":"CURRENCY_TYPE_ALTERNATIVE", # CURRENCY_TYPE_CRYPTO, CURRENCY_TYPE_IEO
|
357
|
-
# "name":"MyCryptoBank",
|
358
|
-
# "tag":"MCB",
|
359
|
-
# "description":"",
|
360
|
-
# "logo":"",
|
361
|
-
# "decimals":18,
|
362
|
-
# "created":1572912000000,
|
363
|
-
# "tier":1,
|
364
|
-
# "assetClass":"ASSET_CLASS_UNKNOWN",
|
365
|
-
# "minTransferAmount":0
|
366
|
-
# },
|
367
|
-
# {
|
368
|
-
# "id":"db02758e-2507-46a5-a805-7bc60355b3eb",
|
369
|
-
# "status":"CURRENCY_STATUS_ACTIVE",
|
370
|
-
# "type":"CURRENCY_TYPE_FUTURES_CONTRACT",
|
371
|
-
# "name":"BTC USDT Futures Contract",
|
372
|
-
# "tag":"BTCUSDT",
|
373
|
-
# "description":"",
|
374
|
-
# "logo":"",
|
375
|
-
# "decimals":8,
|
376
|
-
# "created":1589459984395,
|
377
|
-
# "tier":1,
|
378
|
-
# "assetClass":"ASSET_CLASS_UNKNOWN",
|
379
|
-
# "minTransferAmount":0
|
380
|
-
# },
|
381
|
-
# ]
|
382
|
-
#
|
383
352
|
response = await self.publicGetPair(params)
|
384
353
|
#
|
385
354
|
# [
|
@@ -401,8 +370,9 @@ class latoken(Exchange, ImplicitAPI):
|
|
401
370
|
# }
|
402
371
|
# ]
|
403
372
|
#
|
404
|
-
if self.
|
373
|
+
if self.safe_bool(self.options, 'adjustForTimeDifference', False):
|
405
374
|
await self.load_time_difference()
|
375
|
+
currencies = self.safe_dict(self.options, 'cachedCurrencies', {})
|
406
376
|
currenciesById = self.index_by(currencies, 'id')
|
407
377
|
result = []
|
408
378
|
for i in range(0, len(response)):
|
@@ -411,11 +381,13 @@ class latoken(Exchange, ImplicitAPI):
|
|
411
381
|
# the exchange shows them inverted
|
412
382
|
baseId = self.safe_string(market, 'baseCurrency')
|
413
383
|
quoteId = self.safe_string(market, 'quoteCurrency')
|
414
|
-
baseCurrency = self.
|
415
|
-
quoteCurrency = self.
|
416
|
-
|
417
|
-
|
418
|
-
|
384
|
+
baseCurrency = self.safe_dict(currenciesById, baseId)
|
385
|
+
quoteCurrency = self.safe_dict(currenciesById, quoteId)
|
386
|
+
baseCurrencyInfo = self.safe_dict(baseCurrency, 'info')
|
387
|
+
quoteCurrencyInfo = self.safe_dict(quoteCurrency, 'info')
|
388
|
+
if baseCurrencyInfo is not None and quoteCurrencyInfo is not None:
|
389
|
+
base = self.safe_currency_code(self.safe_string(baseCurrencyInfo, 'tag'))
|
390
|
+
quote = self.safe_currency_code(self.safe_string(quoteCurrencyInfo, 'tag'))
|
419
391
|
lowercaseQuote = quote.lower()
|
420
392
|
capitalizedQuote = self.capitalize(lowercaseQuote)
|
421
393
|
status = self.safe_string(market, 'status')
|
@@ -470,28 +442,13 @@ class latoken(Exchange, ImplicitAPI):
|
|
470
442
|
})
|
471
443
|
return result
|
472
444
|
|
473
|
-
async def fetch_currencies_from_cache(self, params={}):
|
474
|
-
# self method is now redundant
|
475
|
-
# currencies are now fetched before markets
|
476
|
-
options = self.safe_value(self.options, 'fetchCurrencies', {})
|
477
|
-
timestamp = self.safe_integer(options, 'timestamp')
|
478
|
-
expires = self.safe_integer(options, 'expires', 1000)
|
479
|
-
now = self.milliseconds()
|
480
|
-
if (timestamp is None) or ((now - timestamp) > expires):
|
481
|
-
response = await self.publicGetCurrency(params)
|
482
|
-
self.options['fetchCurrencies'] = self.extend(options, {
|
483
|
-
'response': response,
|
484
|
-
'timestamp': now,
|
485
|
-
})
|
486
|
-
return self.safe_value(self.options['fetchCurrencies'], 'response')
|
487
|
-
|
488
445
|
async def fetch_currencies(self, params={}) -> Currencies:
|
489
446
|
"""
|
490
447
|
fetches all available currencies on an exchange
|
491
448
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
492
449
|
:returns dict: an associative dictionary of currencies
|
493
450
|
"""
|
494
|
-
response = await self.
|
451
|
+
response = await self.publicGetCurrency(params)
|
495
452
|
#
|
496
453
|
# [
|
497
454
|
# {
|
@@ -530,27 +487,18 @@ class latoken(Exchange, ImplicitAPI):
|
|
530
487
|
id = self.safe_string(currency, 'id')
|
531
488
|
tag = self.safe_string(currency, 'tag')
|
532
489
|
code = self.safe_currency_code(tag)
|
533
|
-
fee = self.safe_number(currency, 'fee')
|
534
490
|
currencyType = self.safe_string(currency, 'type')
|
535
|
-
|
536
|
-
|
537
|
-
type = 'other'
|
538
|
-
else:
|
539
|
-
# CURRENCY_TYPE_CRYPTO and CURRENCY_TYPE_IEO are all cryptos
|
540
|
-
type = 'crypto'
|
541
|
-
status = self.safe_string(currency, 'status')
|
542
|
-
active = (status == 'CURRENCY_STATUS_ACTIVE')
|
543
|
-
name = self.safe_string(currency, 'name')
|
544
|
-
result[code] = {
|
491
|
+
isCrypto = (currencyType == 'CURRENCY_TYPE_CRYPTO' or currencyType == 'CURRENCY_TYPE_IEO')
|
492
|
+
result[code] = self.safe_currency_structure({
|
545
493
|
'id': id,
|
546
494
|
'code': code,
|
547
495
|
'info': currency,
|
548
|
-
'name': name,
|
549
|
-
'type':
|
550
|
-
'active':
|
496
|
+
'name': self.safe_string(currency, 'name'),
|
497
|
+
'type': 'crypto' if isCrypto else 'other',
|
498
|
+
'active': self.safe_string(currency, 'status') == 'CURRENCY_STATUS_ACTIVE',
|
551
499
|
'deposit': None,
|
552
500
|
'withdraw': None,
|
553
|
-
'fee': fee,
|
501
|
+
'fee': self.safe_number(currency, 'fee'),
|
554
502
|
'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'decimals'))),
|
555
503
|
'limits': {
|
556
504
|
'amount': {
|
@@ -563,7 +511,7 @@ class latoken(Exchange, ImplicitAPI):
|
|
563
511
|
},
|
564
512
|
},
|
565
513
|
'networks': {},
|
566
|
-
}
|
514
|
+
})
|
567
515
|
return result
|
568
516
|
|
569
517
|
async def fetch_balance(self, params={}) -> Balances:
|