ccxt 4.4.75__py2.py3-none-any.whl → 4.4.78__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 +3 -3
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/myokx.py +4 -0
- ccxt/abstract/okx.py +4 -0
- ccxt/abstract/upbit.py +51 -37
- ccxt/abstract/xt.py +3 -0
- ccxt/apex.py +1884 -0
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +3 -3
- ccxt/async_support/apex.py +1884 -0
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +2 -2
- ccxt/async_support/binance.py +39 -217
- ccxt/async_support/bingx.py +1 -1
- ccxt/async_support/bitfinex.py +2 -2
- ccxt/async_support/bitflyer.py +2 -2
- ccxt/async_support/bitget.py +135 -65
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitmex.py +6 -6
- ccxt/async_support/bitrue.py +48 -0
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +29 -4
- ccxt/async_support/coincatch.py +66 -0
- ccxt/async_support/coinex.py +3 -1
- ccxt/async_support/coinlist.py +85 -2
- ccxt/async_support/cryptocom.py +2 -2
- ccxt/async_support/defx.py +1 -1
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/derive.py +2 -2
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/gate.py +1 -1
- ccxt/async_support/hitbtc.py +5 -2
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/hyperliquid.py +13 -6
- ccxt/async_support/kraken.py +2 -2
- ccxt/async_support/krakenfutures.py +2 -2
- ccxt/async_support/kucoinfutures.py +2 -2
- ccxt/async_support/mexc.py +50 -52
- ccxt/async_support/okx.py +21 -9
- ccxt/async_support/oxfun.py +2 -2
- ccxt/async_support/paradex.py +5 -10
- ccxt/async_support/phemex.py +4 -3
- ccxt/async_support/poloniex.py +3 -3
- ccxt/async_support/probit.py +1 -0
- ccxt/async_support/tradeogre.py +2 -1
- ccxt/async_support/upbit.py +265 -89
- ccxt/async_support/vertex.py +2 -2
- ccxt/async_support/whitebit.py +1 -0
- ccxt/async_support/woo.py +5 -3
- ccxt/async_support/woofipro.py +2 -2
- ccxt/async_support/xt.py +115 -5
- ccxt/base/exchange.py +76 -3
- ccxt/binance.py +39 -217
- ccxt/bingx.py +1 -1
- ccxt/bitfinex.py +2 -2
- ccxt/bitflyer.py +2 -2
- ccxt/bitget.py +135 -65
- ccxt/bitmart.py +2 -2
- ccxt/bitmex.py +6 -6
- ccxt/bitrue.py +48 -0
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +29 -4
- ccxt/coincatch.py +66 -0
- ccxt/coinex.py +3 -1
- ccxt/coinlist.py +85 -2
- ccxt/cryptocom.py +2 -2
- ccxt/defx.py +1 -1
- ccxt/delta.py +1 -1
- ccxt/deribit.py +2 -2
- ccxt/derive.py +2 -2
- ccxt/digifinex.py +2 -2
- ccxt/gate.py +1 -1
- ccxt/hitbtc.py +5 -2
- ccxt/htx.py +2 -2
- ccxt/hyperliquid.py +13 -6
- ccxt/kraken.py +2 -2
- ccxt/krakenfutures.py +2 -2
- ccxt/kucoinfutures.py +2 -2
- ccxt/mexc.py +50 -52
- ccxt/okx.py +21 -9
- ccxt/oxfun.py +2 -2
- ccxt/paradex.py +5 -10
- ccxt/phemex.py +4 -3
- ccxt/poloniex.py +3 -3
- ccxt/pro/__init__.py +5 -1
- ccxt/pro/apex.py +984 -0
- ccxt/pro/coinbase.py +4 -6
- ccxt/pro/gate.py +22 -2
- ccxt/pro/hollaex.py +2 -2
- ccxt/pro/hyperliquid.py +1 -1
- ccxt/pro/p2b.py +2 -2
- ccxt/pro/tradeogre.py +272 -0
- ccxt/probit.py +1 -0
- ccxt/test/tests_async.py +27 -0
- ccxt/test/tests_sync.py +27 -0
- ccxt/tradeogre.py +2 -1
- ccxt/upbit.py +265 -89
- ccxt/vertex.py +2 -2
- ccxt/whitebit.py +1 -0
- ccxt/woo.py +5 -3
- ccxt/woofipro.py +2 -2
- ccxt/xt.py +115 -5
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/METADATA +4 -4
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/RECORD +108 -106
- ccxt/abstract/ace.py +0 -15
- ccxt/ace.py +0 -1152
- ccxt/async_support/ace.py +0 -1152
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/LICENSE.txt +0 -0
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/WHEEL +0 -0
- {ccxt-4.4.75.dist-info → ccxt-4.4.78.dist-info}/top_level.txt +0 -0
ccxt/async_support/xt.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.xt import ImplicitAPI
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Any, Currencies, Currency, DepositAddress, Int, LedgerEntry, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderSide, OrderType, Str, Tickers, FundingRate, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Any, Currencies, Currency, DepositAddress, Int, LedgerEntry, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderSide, OrderType, Position, Str, Tickers, FundingRate, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -59,7 +59,7 @@ class xt(Exchange, ImplicitAPI):
|
|
59
59
|
'createOrder': True,
|
60
60
|
'createPostOnlyOrder': False,
|
61
61
|
'createReduceOnlyOrder': True,
|
62
|
-
'editOrder':
|
62
|
+
'editOrder': True,
|
63
63
|
'fetchAccounts': False,
|
64
64
|
'fetchBalance': True,
|
65
65
|
'fetchBidsAsks': True,
|
@@ -246,6 +246,9 @@ class xt(Exchange, ImplicitAPI):
|
|
246
246
|
'open-order': 1,
|
247
247
|
'order/{orderId}': 1,
|
248
248
|
},
|
249
|
+
'put': {
|
250
|
+
'order/{orderId}': 1,
|
251
|
+
},
|
249
252
|
},
|
250
253
|
'linear': {
|
251
254
|
'get': {
|
@@ -280,6 +283,7 @@ class xt(Exchange, ImplicitAPI):
|
|
280
283
|
'future/trade/v1/order/cancel-all': 1,
|
281
284
|
'future/trade/v1/order/create': 1,
|
282
285
|
'future/trade/v1/order/create-batch': 1,
|
286
|
+
'future/trade/v1/order/update': 1,
|
283
287
|
'future/user/v1/account/open': 1,
|
284
288
|
'future/user/v1/position/adjust-leverage': 1,
|
285
289
|
'future/user/v1/position/auto-margin': 1,
|
@@ -323,6 +327,7 @@ class xt(Exchange, ImplicitAPI):
|
|
323
327
|
'future/trade/v1/order/cancel-all': 1,
|
324
328
|
'future/trade/v1/order/create': 1,
|
325
329
|
'future/trade/v1/order/create-batch': 1,
|
330
|
+
'future/trade/v1/order/update': 1,
|
326
331
|
'future/user/v1/account/open': 1,
|
327
332
|
'future/user/v1/position/adjust-leverage': 1,
|
328
333
|
'future/user/v1/position/auto-margin': 1,
|
@@ -957,6 +962,12 @@ class xt(Exchange, ImplicitAPI):
|
|
957
962
|
},
|
958
963
|
},
|
959
964
|
}
|
965
|
+
typeRaw = self.safe_string(entry, 'type')
|
966
|
+
type: Str = None
|
967
|
+
if typeRaw == 'FT':
|
968
|
+
type = 'crypto'
|
969
|
+
else:
|
970
|
+
type = 'other'
|
960
971
|
result[code] = {
|
961
972
|
'info': entry,
|
962
973
|
'id': currencyId,
|
@@ -968,6 +979,7 @@ class xt(Exchange, ImplicitAPI):
|
|
968
979
|
'deposit': deposit,
|
969
980
|
'withdraw': withdraw,
|
970
981
|
'networks': networks,
|
982
|
+
'type': type,
|
971
983
|
'limits': {
|
972
984
|
'amount': {
|
973
985
|
'min': None,
|
@@ -3338,7 +3350,7 @@ class xt(Exchange, ImplicitAPI):
|
|
3338
3350
|
# "cancelId": "208322474307982720"
|
3339
3351
|
# }
|
3340
3352
|
#
|
3341
|
-
# swap and future: createOrder, cancelOrder
|
3353
|
+
# swap and future: createOrder, cancelOrder, editOrder
|
3342
3354
|
#
|
3343
3355
|
# {
|
3344
3356
|
# "returnCode": 0,
|
@@ -3443,6 +3455,14 @@ class xt(Exchange, ImplicitAPI):
|
|
3443
3455
|
# "createdTime": 1681273420039
|
3444
3456
|
# }
|
3445
3457
|
#
|
3458
|
+
# spot editOrder
|
3459
|
+
#
|
3460
|
+
# {
|
3461
|
+
# "orderId": "484203027161892224",
|
3462
|
+
# "modifyId": "484203544105344000",
|
3463
|
+
# "clientModifyId": null
|
3464
|
+
# }
|
3465
|
+
#
|
3446
3466
|
marketId = self.safe_string(order, 'symbol')
|
3447
3467
|
marketType = ('result' in order) or 'contract' if ('positionSide' in order) else 'spot'
|
3448
3468
|
market = self.safe_market(marketId, market, None, marketType)
|
@@ -3456,7 +3476,7 @@ class xt(Exchange, ImplicitAPI):
|
|
3456
3476
|
return self.safe_order({
|
3457
3477
|
'info': order,
|
3458
3478
|
'id': self.safe_string_n(order, ['orderId', 'result', 'cancelId', 'entrustId', 'profitId']),
|
3459
|
-
'clientOrderId': self.
|
3479
|
+
'clientOrderId': self.safe_string_2(order, 'clientOrderId', 'clientModifyId'),
|
3460
3480
|
'timestamp': timestamp,
|
3461
3481
|
'datetime': self.iso8601(timestamp),
|
3462
3482
|
'lastTradeTimestamp': lastUpdatedTimestamp,
|
@@ -4474,7 +4494,7 @@ class xt(Exchange, ImplicitAPI):
|
|
4474
4494
|
return self.parse_position(entry, marketInner)
|
4475
4495
|
return None
|
4476
4496
|
|
4477
|
-
async def fetch_positions(self, symbols: List[str] = None, params={}):
|
4497
|
+
async def fetch_positions(self, symbols: List[str] = None, params={}) -> List[Position]:
|
4478
4498
|
"""
|
4479
4499
|
fetch all open positions
|
4480
4500
|
|
@@ -4679,6 +4699,94 @@ class xt(Exchange, ImplicitAPI):
|
|
4679
4699
|
#
|
4680
4700
|
return response # unify return type
|
4681
4701
|
|
4702
|
+
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
|
4703
|
+
"""
|
4704
|
+
cancels an order and places a new order
|
4705
|
+
|
4706
|
+
https://doc.xt.com/#orderorderUpdate
|
4707
|
+
https://doc.xt.com/#futures_orderupdate
|
4708
|
+
https://doc.xt.com/#futures_entrustupdateProfit
|
4709
|
+
|
4710
|
+
:param str id: order id
|
4711
|
+
:param str symbol: unified symbol of the market to create an order in
|
4712
|
+
:param str type: 'market' or 'limit'
|
4713
|
+
:param str side: 'buy' or 'sell'
|
4714
|
+
:param float amount: how much of the currency you want to trade in units of the base currency
|
4715
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
4716
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4717
|
+
:param float [params.stopLoss]: price to set a stop-loss on an open position
|
4718
|
+
:param float [params.takeProfit]: price to set a take-profit on an open position
|
4719
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
4720
|
+
"""
|
4721
|
+
if amount is None:
|
4722
|
+
raise ArgumentsRequired(self.id + ' editOrder() requires an amount argument')
|
4723
|
+
await self.load_markets()
|
4724
|
+
market = self.market(symbol)
|
4725
|
+
request = {}
|
4726
|
+
stopLoss = self.safe_number_2(params, 'stopLoss', 'triggerStopPrice')
|
4727
|
+
takeProfit = self.safe_number_2(params, 'takeProfit', 'triggerProfitPrice')
|
4728
|
+
params = self.omit(params, ['stopLoss', 'takeProfit'])
|
4729
|
+
isStopLoss = (stopLoss is not None)
|
4730
|
+
isTakeProfit = (takeProfit is not None)
|
4731
|
+
if isStopLoss or isTakeProfit:
|
4732
|
+
request['profitId'] = id
|
4733
|
+
else:
|
4734
|
+
request['orderId'] = id
|
4735
|
+
request['price'] = self.price_to_precision(symbol, price)
|
4736
|
+
response = None
|
4737
|
+
if market['swap']:
|
4738
|
+
if isStopLoss:
|
4739
|
+
request['triggerStopPrice'] = self.price_to_precision(symbol, stopLoss)
|
4740
|
+
elif takeProfit is not None:
|
4741
|
+
request['triggerProfitPrice'] = self.price_to_precision(symbol, takeProfit)
|
4742
|
+
else:
|
4743
|
+
request['origQty'] = self.amount_to_precision(symbol, amount)
|
4744
|
+
subType = None
|
4745
|
+
subType, params = self.handle_sub_type_and_params('editOrder', market, params)
|
4746
|
+
if subType == 'inverse':
|
4747
|
+
if isStopLoss or isTakeProfit:
|
4748
|
+
response = await self.privateInversePostFutureTradeV1EntrustUpdateProfitStop(self.extend(request, params))
|
4749
|
+
else:
|
4750
|
+
response = await self.privateInversePostFutureTradeV1OrderUpdate(self.extend(request, params))
|
4751
|
+
#
|
4752
|
+
# {
|
4753
|
+
# "returnCode": 0,
|
4754
|
+
# "msgInfo": "success",
|
4755
|
+
# "error": null,
|
4756
|
+
# "result": "483869474947826752"
|
4757
|
+
# }
|
4758
|
+
#
|
4759
|
+
else:
|
4760
|
+
if isStopLoss or isTakeProfit:
|
4761
|
+
response = await self.privateLinearPostFutureTradeV1EntrustUpdateProfitStop(self.extend(request, params))
|
4762
|
+
else:
|
4763
|
+
response = await self.privateLinearPostFutureTradeV1OrderUpdate(self.extend(request, params))
|
4764
|
+
#
|
4765
|
+
# {
|
4766
|
+
# "returnCode": 0,
|
4767
|
+
# "msgInfo": "success",
|
4768
|
+
# "error": null,
|
4769
|
+
# "result": "483869474947826752"
|
4770
|
+
# }
|
4771
|
+
#
|
4772
|
+
else:
|
4773
|
+
request['quantity'] = self.amount_to_precision(symbol, amount)
|
4774
|
+
response = await self.privateSpotPutOrderOrderId(self.extend(request, params))
|
4775
|
+
#
|
4776
|
+
# {
|
4777
|
+
# "rc": 0,
|
4778
|
+
# "mc": "SUCCESS",
|
4779
|
+
# "ma": [],
|
4780
|
+
# "result": {
|
4781
|
+
# "orderId": "484203027161892224",
|
4782
|
+
# "modifyId": "484203544105344000",
|
4783
|
+
# "clientModifyId": null
|
4784
|
+
# }
|
4785
|
+
# }
|
4786
|
+
#
|
4787
|
+
result = response if (market['swap']) else self.safe_dict(response, 'result', {})
|
4788
|
+
return self.parse_order(result, market)
|
4789
|
+
|
4682
4790
|
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
4683
4791
|
#
|
4684
4792
|
# spot: error
|
@@ -4776,6 +4884,8 @@ class xt(Exchange, ImplicitAPI):
|
|
4776
4884
|
else:
|
4777
4885
|
body['media'] = id
|
4778
4886
|
isUndefinedBody = ((method == 'GET') or (path == 'order/{orderId}') or (path == 'ws-token'))
|
4887
|
+
if (method == 'PUT') and (endpoint == 'spot'):
|
4888
|
+
isUndefinedBody = False
|
4779
4889
|
body = None if isUndefinedBody else self.json(body)
|
4780
4890
|
payloadString = None
|
4781
4891
|
if (endpoint == 'spot') or (endpoint == 'user'):
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.4.
|
7
|
+
__version__ = '4.4.78'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -67,6 +67,10 @@ from ccxt.static_dependencies.starknet.hash.address import compute_address
|
|
67
67
|
from ccxt.static_dependencies.starknet.hash.selector import get_selector_from_name
|
68
68
|
from ccxt.static_dependencies.starknet.hash.utils import message_signature, private_to_stark_key
|
69
69
|
from ccxt.static_dependencies.starknet.utils.typed_data import TypedData as TypedDataDataclass
|
70
|
+
try:
|
71
|
+
import apexpro.zklink_sdk as zklink_sdk
|
72
|
+
except ImportError:
|
73
|
+
zklink_sdk = None
|
70
74
|
|
71
75
|
# -----------------------------------------------------------------------------
|
72
76
|
|
@@ -509,7 +513,7 @@ class Exchange(object):
|
|
509
513
|
proxyUrl = self.check_proxy_url_settings(url, method, headers, body)
|
510
514
|
if proxyUrl is not None:
|
511
515
|
request_headers.update({'Origin': self.origin})
|
512
|
-
url = proxyUrl + url
|
516
|
+
url = proxyUrl + self.url_encoder_for_proxy_url(url)
|
513
517
|
# proxy agents
|
514
518
|
proxies = None # set default
|
515
519
|
httpProxy, httpsProxy, socksProxy = self.check_proxy_settings(url, method, headers, body)
|
@@ -1755,6 +1759,69 @@ class Exchange(object):
|
|
1755
1759
|
def binary_length(self, binary):
|
1756
1760
|
return len(binary)
|
1757
1761
|
|
1762
|
+
def get_zk_contract_signature_obj(self, seeds: str, params={}):
|
1763
|
+
if zklink_sdk is None:
|
1764
|
+
raise Exception('zklink_sdk is not installed, please do pip3 install apexomni-arm or apexomni-x86-mac or apexomni-x86-windows-linux')
|
1765
|
+
|
1766
|
+
slotId = self.safe_string(params, 'slotId')
|
1767
|
+
nonceInt = int(self.remove0x_prefix(self.hash(self.encode(slotId), 'sha256', 'hex')), 16)
|
1768
|
+
|
1769
|
+
maxUint64 = 18446744073709551615
|
1770
|
+
maxUint32 = 4294967295
|
1771
|
+
|
1772
|
+
slotId = (nonceInt % maxUint64) / maxUint32
|
1773
|
+
nonce = nonceInt % maxUint32
|
1774
|
+
accountId = int(self.safe_string(params, 'accountId'), 10) % maxUint32
|
1775
|
+
|
1776
|
+
priceStr = (Decimal(self.safe_string(params, 'price')) * Decimal(10) ** Decimal('18')).quantize(Decimal(0), rounding='ROUND_DOWN')
|
1777
|
+
sizeStr = (Decimal(self.safe_string(params, 'size')) * Decimal(10) ** Decimal('18')).quantize(Decimal(0), rounding='ROUND_DOWN')
|
1778
|
+
|
1779
|
+
takerFeeRateStr = (Decimal(self.safe_string(params, 'takerFeeRate')) * Decimal(10000)).quantize(Decimal(0), rounding='ROUND_UP')
|
1780
|
+
makerFeeRateStr = (Decimal(self.safe_string(params, 'makerFeeRate')) * Decimal(10000)).quantize(Decimal(0), rounding='ROUND_UP')
|
1781
|
+
|
1782
|
+
builder = zklink_sdk.ContractBuilder(
|
1783
|
+
int(accountId), int(0), int(slotId), int(nonce), int(self.safe_number(params, 'pairId')),
|
1784
|
+
sizeStr.__str__(), priceStr.__str__(), self.safe_string(params, 'direction') == "BUY",
|
1785
|
+
int(takerFeeRateStr), int(makerFeeRateStr), False)
|
1786
|
+
|
1787
|
+
|
1788
|
+
tx = zklink_sdk.Contract(builder)
|
1789
|
+
seedsByte = bytes.fromhex(seeds.removeprefix('0x'))
|
1790
|
+
signerSeed = zklink_sdk.ZkLinkSigner().new_from_seed(seedsByte)
|
1791
|
+
auth_data = signerSeed.sign_musig(tx.get_bytes())
|
1792
|
+
signature = auth_data.signature
|
1793
|
+
return signature
|
1794
|
+
|
1795
|
+
def get_zk_transfer_signature_obj(self, seeds: str, params={}):
|
1796
|
+
if zklink_sdk is None:
|
1797
|
+
raise Exception('zklink_sdk is not installed, please do pip3 install apexomni-arm or apexomni-x86-mac or apexomni-x86-windows-linux')
|
1798
|
+
|
1799
|
+
nonce = self.safe_string(params, 'nonce', '0')
|
1800
|
+
if self.safe_bool(params, 'isContract'):
|
1801
|
+
formattedUint32 = '4294967295'
|
1802
|
+
formattedNonce = int(self.remove0x_prefix(self.hash(self.encode(nonce), 'sha256', 'hex')), 16)
|
1803
|
+
nonce = Precise.string_mod(str(formattedNonce), formattedUint32)
|
1804
|
+
|
1805
|
+
tx_builder = zklink_sdk.TransferBuilder(
|
1806
|
+
int(self.safe_number(params, 'zkAccountId', 0)),
|
1807
|
+
self.safe_string(params, 'receiverAddress'),
|
1808
|
+
int(self.safe_number(params, 'subAccountId', 0)),
|
1809
|
+
int(self.safe_number(params, 'receiverSubAccountId', 0)),
|
1810
|
+
int(self.safe_number(params, 'tokenId', 0)),
|
1811
|
+
self.safe_string(params, 'amount', '0'),
|
1812
|
+
self.safe_string(params, 'fee', '0'),
|
1813
|
+
self.parse_to_int(nonce),
|
1814
|
+
int(self.safe_number(params, 'timestampSeconds', 0))
|
1815
|
+
)
|
1816
|
+
|
1817
|
+
tx = zklink_sdk.Transfer(tx_builder)
|
1818
|
+
seedsByte = bytes.fromhex(seeds.removeprefix('0x'))
|
1819
|
+
signerSeed = zklink_sdk.ZkLinkSigner().new_from_seed(seedsByte)
|
1820
|
+
auth_data = signerSeed.sign_musig(tx.get_bytes())
|
1821
|
+
signature = auth_data.signature
|
1822
|
+
return signature
|
1823
|
+
|
1824
|
+
|
1758
1825
|
# ########################################################################
|
1759
1826
|
# ########################################################################
|
1760
1827
|
# ########################################################################
|
@@ -2254,6 +2321,12 @@ class Exchange(object):
|
|
2254
2321
|
raise InvalidProxySettings(self.id + ' you have multiple conflicting proxy settings(' + joinedProxyNames + '), please use only one from : proxyUrl, proxy_url, proxyUrlCallback, proxy_url_callback')
|
2255
2322
|
return proxyUrl
|
2256
2323
|
|
2324
|
+
def url_encoder_for_proxy_url(self, targetUrl: str):
|
2325
|
+
# to be overriden
|
2326
|
+
includesQuery = targetUrl.find('?') >= 0
|
2327
|
+
finalUrl = self.encode_uri_component(targetUrl) if includesQuery else targetUrl
|
2328
|
+
return finalUrl
|
2329
|
+
|
2257
2330
|
def check_proxy_settings(self, url: Str = None, method: Str = None, headers=None, body=None):
|
2258
2331
|
usedProxies = []
|
2259
2332
|
httpProxy = None
|
@@ -2947,7 +3020,7 @@ class Exchange(object):
|
|
2947
3020
|
# find lowest precision(which is more desired)
|
2948
3021
|
precision = self.safe_string(network, 'precision')
|
2949
3022
|
precisionMain = self.safe_string(currency, 'precision')
|
2950
|
-
if precisionMain is None or Precise.
|
3023
|
+
if precisionMain is None or Precise.string_gt(precision, precisionMain):
|
2951
3024
|
currency['precision'] = self.parse_number(precision)
|
2952
3025
|
# limits
|
2953
3026
|
limits = self.safe_dict(network, 'limits')
|
ccxt/binance.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.binance import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import json
|
10
|
-
from ccxt.base.types import Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, Greeks, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, LongShortRatio, MarginMode, MarginModes, MarginModification, Market, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, MarketInterface, TransferEntry
|
10
|
+
from ccxt.base.types import Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, Greeks, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Leverage, Leverages, LeverageTier, LeverageTiers, LongShortRatio, MarginMode, MarginModes, MarginModification, Market, Num, Option, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, MarketInterface, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
@@ -43,7 +43,7 @@ class binance(Exchange, ImplicitAPI):
|
|
43
43
|
return self.deep_extend(super(binance, self).describe(), {
|
44
44
|
'id': 'binance',
|
45
45
|
'name': 'Binance',
|
46
|
-
'countries': [
|
46
|
+
'countries': [], # Japan
|
47
47
|
'rateLimit': 50,
|
48
48
|
'certified': True,
|
49
49
|
'pro': True,
|
@@ -1356,195 +1356,8 @@ class binance(Exchange, ImplicitAPI):
|
|
1356
1356
|
'SPL': 'SOL', # temporarily keep support for SPL(old name)
|
1357
1357
|
'SOL': 'SOL', # we shouldn't rename SOL
|
1358
1358
|
},
|
1359
|
-
# keeping self object for backward-compatibility
|
1360
|
-
'reverseNetworks': {
|
1361
|
-
'tronscan.org': 'TRC20',
|
1362
|
-
'etherscan.io': 'ERC20',
|
1363
|
-
'bscscan.com': 'BSC',
|
1364
|
-
'explorer.binance.org': 'BEP2',
|
1365
|
-
'bithomp.com': 'XRP',
|
1366
|
-
'bloks.io': 'EOS',
|
1367
|
-
'stellar.expert': 'XLM',
|
1368
|
-
'blockchair.com/bitcoin': 'BTC',
|
1369
|
-
'blockchair.com/bitcoin-cash': 'BCH',
|
1370
|
-
'blockchair.com/ecash': 'XEC',
|
1371
|
-
'explorer.litecoin.net': 'LTC',
|
1372
|
-
'explorer.avax.network': 'AVAX',
|
1373
|
-
'solscan.io': 'SOL',
|
1374
|
-
'polkadot.subscan.io': 'DOT',
|
1375
|
-
'dashboard.internetcomputer.org': 'ICP',
|
1376
|
-
'explorer.chiliz.com': 'CHZ',
|
1377
|
-
'cardanoscan.io': 'ADA',
|
1378
|
-
'mainnet.theoan.com': 'AION',
|
1379
|
-
'algoexplorer.io': 'ALGO',
|
1380
|
-
'explorer.ambrosus.com': 'AMB',
|
1381
|
-
'viewblock.io/zilliqa': 'ZIL',
|
1382
|
-
'viewblock.io/arweave': 'AR',
|
1383
|
-
'explorer.ark.io': 'ARK',
|
1384
|
-
'atomscan.com': 'ATOM',
|
1385
|
-
'www.mintscan.io': 'CTK',
|
1386
|
-
'explorer.bitcoindiamond.org': 'BCD',
|
1387
|
-
'btgexplorer.com': 'BTG',
|
1388
|
-
'bts.ai': 'BTS',
|
1389
|
-
'explorer.celo.org': 'CELO',
|
1390
|
-
'explorer.nervos.org': 'CKB',
|
1391
|
-
'cerebro.cortexlabs.ai': 'CTXC',
|
1392
|
-
'chainz.cryptoid.info': 'VIA',
|
1393
|
-
'explorer.dcrdata.org': 'DCR',
|
1394
|
-
'digiexplorer.info': 'DGB',
|
1395
|
-
'dock.subscan.io': 'DOCK',
|
1396
|
-
'dogechain.info': 'DOGE',
|
1397
|
-
'explorer.elrond.com': 'EGLD',
|
1398
|
-
'blockscout.com': 'ETC',
|
1399
|
-
'explore-fetchhub.fetch.ai': 'FET',
|
1400
|
-
'filfox.info': 'FIL',
|
1401
|
-
'fio.bloks.io': 'FIO',
|
1402
|
-
'explorer.firo.org': 'FIRO',
|
1403
|
-
'neoscan.io': 'NEO',
|
1404
|
-
'ftmscan.com': 'FTM',
|
1405
|
-
'explorer.gochain.io': 'GO',
|
1406
|
-
'block.gxb.io': 'GXS',
|
1407
|
-
'hash-hash.info': 'HBAR',
|
1408
|
-
'www.hiveblockexplorer.com': 'HIVE',
|
1409
|
-
'explorer.helium.com': 'HNT',
|
1410
|
-
'tracker.icon.foundation': 'ICX',
|
1411
|
-
'www.iostabc.com': 'IOST',
|
1412
|
-
'explorer.iota.org': 'IOTA',
|
1413
|
-
'iotexscan.io': 'IOTX',
|
1414
|
-
'irishub.iobscan.io': 'IRIS',
|
1415
|
-
'kava.mintscan.io': 'KAVA',
|
1416
|
-
'scope.klaytn.com': 'KLAY',
|
1417
|
-
'kmdexplorer.io': 'KMD',
|
1418
|
-
'kusama.subscan.io': 'KSM',
|
1419
|
-
'explorer.lto.network': 'LTO',
|
1420
|
-
'polygonscan.com': 'POLYGON',
|
1421
|
-
'explorer.ont.io': 'ONT',
|
1422
|
-
'minaexplorer.com': 'MINA',
|
1423
|
-
'nanolooker.com': 'NANO',
|
1424
|
-
'explorer.nebulas.io': 'NAS',
|
1425
|
-
'explorer.nbs.plus': 'NBS',
|
1426
|
-
'explorer.nebl.io': 'NEBL',
|
1427
|
-
'nulscan.io': 'NULS',
|
1428
|
-
'nxscan.com': 'NXS',
|
1429
|
-
'explorer.harmony.one': 'ONE',
|
1430
|
-
'explorer.poa.network': 'POA',
|
1431
|
-
'qtum.info': 'QTUM',
|
1432
|
-
'explorer.rsk.co': 'RSK',
|
1433
|
-
'www.oasisscan.com': 'ROSE',
|
1434
|
-
'ravencoin.network': 'RVN',
|
1435
|
-
'sc.tokenview.com': 'SC',
|
1436
|
-
'secretnodes.com': 'SCRT',
|
1437
|
-
'explorer.skycoin.com': 'SKY',
|
1438
|
-
'steemscan.com': 'STEEM',
|
1439
|
-
'explorer.stacks.co': 'STX',
|
1440
|
-
'www.thetascan.io': 'THETA',
|
1441
|
-
'scan.tomochain.com': 'TOMO',
|
1442
|
-
'explore.vechain.org': 'VET',
|
1443
|
-
'explorer.vite.net': 'VITE',
|
1444
|
-
'www.wanscan.org': 'WAN',
|
1445
|
-
'wavesexplorer.com': 'WAVES',
|
1446
|
-
'wax.eosx.io': 'WAXP',
|
1447
|
-
'waltonchain.pro': 'WTC',
|
1448
|
-
'chain.nem.ninja': 'XEM',
|
1449
|
-
'verge-blockchain.info': 'XVG',
|
1450
|
-
'explorer.yoyow.org': 'YOYOW',
|
1451
|
-
'explorer.zcha.in': 'ZEC',
|
1452
|
-
'explorer.zensystem.io': 'ZEN',
|
1453
|
-
},
|
1454
1359
|
'networksById': {
|
1455
1360
|
'SOL': 'SOL', # temporary fix for SPL definition
|
1456
|
-
'tronscan.org': 'TRC20',
|
1457
|
-
'etherscan.io': 'ERC20',
|
1458
|
-
'bscscan.com': 'BSC',
|
1459
|
-
'explorer.binance.org': 'BEP2',
|
1460
|
-
'bithomp.com': 'XRP',
|
1461
|
-
'bloks.io': 'EOS',
|
1462
|
-
'stellar.expert': 'XLM',
|
1463
|
-
'blockchair.com/bitcoin': 'BTC',
|
1464
|
-
'blockchair.com/bitcoin-cash': 'BCH',
|
1465
|
-
'blockchair.com/ecash': 'XEC',
|
1466
|
-
'explorer.litecoin.net': 'LTC',
|
1467
|
-
'explorer.avax.network': 'AVAX',
|
1468
|
-
'solscan.io': 'SOL',
|
1469
|
-
'polkadot.subscan.io': 'DOT',
|
1470
|
-
'dashboard.internetcomputer.org': 'ICP',
|
1471
|
-
'explorer.chiliz.com': 'CHZ',
|
1472
|
-
'cardanoscan.io': 'ADA',
|
1473
|
-
'mainnet.theoan.com': 'AION',
|
1474
|
-
'algoexplorer.io': 'ALGO',
|
1475
|
-
'explorer.ambrosus.com': 'AMB',
|
1476
|
-
'viewblock.io/zilliqa': 'ZIL',
|
1477
|
-
'viewblock.io/arweave': 'AR',
|
1478
|
-
'explorer.ark.io': 'ARK',
|
1479
|
-
'atomscan.com': 'ATOM',
|
1480
|
-
'www.mintscan.io': 'CTK',
|
1481
|
-
'explorer.bitcoindiamond.org': 'BCD',
|
1482
|
-
'btgexplorer.com': 'BTG',
|
1483
|
-
'bts.ai': 'BTS',
|
1484
|
-
'explorer.celo.org': 'CELO',
|
1485
|
-
'explorer.nervos.org': 'CKB',
|
1486
|
-
'cerebro.cortexlabs.ai': 'CTXC',
|
1487
|
-
'chainz.cryptoid.info': 'VIA',
|
1488
|
-
'explorer.dcrdata.org': 'DCR',
|
1489
|
-
'digiexplorer.info': 'DGB',
|
1490
|
-
'dock.subscan.io': 'DOCK',
|
1491
|
-
'dogechain.info': 'DOGE',
|
1492
|
-
'explorer.elrond.com': 'EGLD',
|
1493
|
-
'blockscout.com': 'ETC',
|
1494
|
-
'explore-fetchhub.fetch.ai': 'FET',
|
1495
|
-
'filfox.info': 'FIL',
|
1496
|
-
'fio.bloks.io': 'FIO',
|
1497
|
-
'explorer.firo.org': 'FIRO',
|
1498
|
-
'neoscan.io': 'NEO',
|
1499
|
-
'ftmscan.com': 'FTM',
|
1500
|
-
'explorer.gochain.io': 'GO',
|
1501
|
-
'block.gxb.io': 'GXS',
|
1502
|
-
'hash-hash.info': 'HBAR',
|
1503
|
-
'www.hiveblockexplorer.com': 'HIVE',
|
1504
|
-
'explorer.helium.com': 'HNT',
|
1505
|
-
'tracker.icon.foundation': 'ICX',
|
1506
|
-
'www.iostabc.com': 'IOST',
|
1507
|
-
'explorer.iota.org': 'IOTA',
|
1508
|
-
'iotexscan.io': 'IOTX',
|
1509
|
-
'irishub.iobscan.io': 'IRIS',
|
1510
|
-
'kava.mintscan.io': 'KAVA',
|
1511
|
-
'scope.klaytn.com': 'KLAY',
|
1512
|
-
'kmdexplorer.io': 'KMD',
|
1513
|
-
'kusama.subscan.io': 'KSM',
|
1514
|
-
'explorer.lto.network': 'LTO',
|
1515
|
-
'polygonscan.com': 'POLYGON',
|
1516
|
-
'explorer.ont.io': 'ONT',
|
1517
|
-
'minaexplorer.com': 'MINA',
|
1518
|
-
'nanolooker.com': 'NANO',
|
1519
|
-
'explorer.nebulas.io': 'NAS',
|
1520
|
-
'explorer.nbs.plus': 'NBS',
|
1521
|
-
'explorer.nebl.io': 'NEBL',
|
1522
|
-
'nulscan.io': 'NULS',
|
1523
|
-
'nxscan.com': 'NXS',
|
1524
|
-
'explorer.harmony.one': 'ONE',
|
1525
|
-
'explorer.poa.network': 'POA',
|
1526
|
-
'qtum.info': 'QTUM',
|
1527
|
-
'explorer.rsk.co': 'RSK',
|
1528
|
-
'www.oasisscan.com': 'ROSE',
|
1529
|
-
'ravencoin.network': 'RVN',
|
1530
|
-
'sc.tokenview.com': 'SC',
|
1531
|
-
'secretnodes.com': 'SCRT',
|
1532
|
-
'explorer.skycoin.com': 'SKY',
|
1533
|
-
'steemscan.com': 'STEEM',
|
1534
|
-
'explorer.stacks.co': 'STX',
|
1535
|
-
'www.thetascan.io': 'THETA',
|
1536
|
-
'scan.tomochain.com': 'TOMO',
|
1537
|
-
'explore.vechain.org': 'VET',
|
1538
|
-
'explorer.vite.net': 'VITE',
|
1539
|
-
'www.wanscan.org': 'WAN',
|
1540
|
-
'wavesexplorer.com': 'WAVES',
|
1541
|
-
'wax.eosx.io': 'WAXP',
|
1542
|
-
'waltonchain.pro': 'WTC',
|
1543
|
-
'chain.nem.ninja': 'XEM',
|
1544
|
-
'verge-blockchain.info': 'XVG',
|
1545
|
-
'explorer.yoyow.org': 'YOYOW',
|
1546
|
-
'explorer.zcha.in': 'ZEC',
|
1547
|
-
'explorer.zensystem.io': 'ZEN',
|
1548
1361
|
},
|
1549
1362
|
'impliedNetworks': {
|
1550
1363
|
'ETH': {'ERC20': 'ETH'},
|
@@ -8706,39 +8519,19 @@ class binance(Exchange, ImplicitAPI):
|
|
8706
8519
|
def parse_deposit_address(self, response, currency: Currency = None) -> DepositAddress:
|
8707
8520
|
#
|
8708
8521
|
# {
|
8709
|
-
# "
|
8522
|
+
# "coin": "XRP",
|
8710
8523
|
# "address": "rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh",
|
8711
8524
|
# "tag": "108618262",
|
8712
|
-
# "
|
8713
|
-
# "coin": "XRP",
|
8714
|
-
# "address": "rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh",
|
8715
|
-
# "tag": "108618262",
|
8716
|
-
# "url": "https://bithomp.com/explorer/rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh"
|
8717
|
-
# }
|
8525
|
+
# "url": "https://bithomp.com/explorer/rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh"
|
8718
8526
|
# }
|
8719
8527
|
#
|
8720
|
-
|
8721
|
-
url = self.safe_string(info, 'url')
|
8528
|
+
url = self.safe_string(response, 'url')
|
8722
8529
|
address = self.safe_string(response, 'address')
|
8723
8530
|
currencyId = self.safe_string(response, 'currency')
|
8724
8531
|
code = self.safe_currency_code(currencyId, currency)
|
8725
|
-
|
8726
|
-
|
8727
|
-
|
8728
|
-
parts = url.split('/')
|
8729
|
-
topLevel = self.safe_string(parts, 2)
|
8730
|
-
if (topLevel == 'blockchair.com') or (topLevel == 'viewblock.io'):
|
8731
|
-
subLevel = self.safe_string(parts, 3)
|
8732
|
-
if subLevel is not None:
|
8733
|
-
topLevel = topLevel + '/' + subLevel
|
8734
|
-
impliedNetwork = self.safe_string(reverseNetworks, topLevel)
|
8735
|
-
impliedNetworks = self.safe_dict(self.options, 'impliedNetworks', {
|
8736
|
-
'ETH': {'ERC20': 'ETH'},
|
8737
|
-
'TRX': {'TRC20': 'TRX'},
|
8738
|
-
})
|
8739
|
-
if code in impliedNetworks:
|
8740
|
-
conversion = self.safe_dict(impliedNetworks, code, {})
|
8741
|
-
impliedNetwork = self.safe_string(conversion, impliedNetwork, impliedNetwork)
|
8532
|
+
# deposit-address endpoint provides only network url(not network ID/CODE)
|
8533
|
+
# so we should map the url to network(their data is inside currencies)
|
8534
|
+
networkCode = self.get_network_code_by_network_url(code, url)
|
8742
8535
|
tag = self.safe_string(response, 'tag', '')
|
8743
8536
|
if len(tag) == 0:
|
8744
8537
|
tag = None
|
@@ -8746,7 +8539,7 @@ class binance(Exchange, ImplicitAPI):
|
|
8746
8539
|
return {
|
8747
8540
|
'info': response,
|
8748
8541
|
'currency': code,
|
8749
|
-
'network':
|
8542
|
+
'network': networkCode,
|
8750
8543
|
'address': address,
|
8751
8544
|
'tag': tag,
|
8752
8545
|
}
|
@@ -10317,7 +10110,7 @@ class binance(Exchange, ImplicitAPI):
|
|
10317
10110
|
'percentage': None,
|
10318
10111
|
})
|
10319
10112
|
|
10320
|
-
def fetch_positions(self, symbols: Strings = None, params={}):
|
10113
|
+
def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
10321
10114
|
"""
|
10322
10115
|
fetch all open positions
|
10323
10116
|
|
@@ -11294,6 +11087,35 @@ class binance(Exchange, ImplicitAPI):
|
|
11294
11087
|
}
|
11295
11088
|
return self.safe_string(ledgerType, type, type)
|
11296
11089
|
|
11090
|
+
def get_network_code_by_network_url(self, currencyCode: str, depositUrl: Str = None) -> Str:
|
11091
|
+
# depositUrl is like : https://bscscan.com/address/0xEF238AB229342849..
|
11092
|
+
if depositUrl is None:
|
11093
|
+
return None
|
11094
|
+
networkCode = None
|
11095
|
+
currency = self.currency(currencyCode)
|
11096
|
+
networks = self.safe_dict(currency, 'networks', {})
|
11097
|
+
networkCodes = list(networks.keys())
|
11098
|
+
for i in range(0, len(networkCodes)):
|
11099
|
+
currentNetworkCode = networkCodes[i]
|
11100
|
+
info = self.safe_dict(networks[currentNetworkCode], 'info', {})
|
11101
|
+
siteUrl = self.safe_string(info, 'contractAddressUrl')
|
11102
|
+
# check if url matches the field's value
|
11103
|
+
if siteUrl is not None and depositUrl.startswith(self.get_base_domain_from_url(siteUrl)):
|
11104
|
+
networkCode = currentNetworkCode
|
11105
|
+
return networkCode
|
11106
|
+
|
11107
|
+
def get_base_domain_from_url(self, url: Str) -> Str:
|
11108
|
+
if url is None:
|
11109
|
+
return None
|
11110
|
+
urlParts = url.split('/')
|
11111
|
+
scheme = self.safe_string(urlParts, 0)
|
11112
|
+
if scheme is None:
|
11113
|
+
return None
|
11114
|
+
domain = self.safe_string(urlParts, 2)
|
11115
|
+
if domain is None:
|
11116
|
+
return None
|
11117
|
+
return scheme + '//' + domain + '/'
|
11118
|
+
|
11297
11119
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
11298
11120
|
urls = self.urls
|
11299
11121
|
if not (api in urls['api']):
|
ccxt/bingx.py
CHANGED
@@ -2371,7 +2371,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
2371
2371
|
positions = self.parse_positions(records)
|
2372
2372
|
return self.filter_by_symbol_since_limit(positions, symbol, since, limit)
|
2373
2373
|
|
2374
|
-
def fetch_positions(self, symbols: Strings = None, params={}):
|
2374
|
+
def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
2375
2375
|
"""
|
2376
2376
|
fetch all open positions
|
2377
2377
|
|