python-binance icon indicating copy to clipboard operation
python-binance copied to clipboard

Authentication using Ed25519 API keys

Open iden83 opened this issue 1 year ago • 3 comments

Describe the improvement Hi there,

Is there a chance to use the Ed25519 keys to authenticate? Binance has implemented them July 2023. There's a description here but I didn't manage to implement it in python: https://binance-docs.github.io/apidocs/spot/en/#signed-trade-user_data-and-margin-endpoint-security

Thanks a lot for your work everyone ( @sammchardy )

To implement Adding Ed25519 keys for binance-python project

Challenging part Ed25519 is supported by newer Python version in Crypto module, but importKey function doesn't deal with that well...

This is the announcement post: https://www.binance.com/en/support/announcement/binance-now-supports-ed25519-api-keys-2023-07-19-30372026b6af4fbbb9b38ab5c3f91755

Users are advised to switch to Ed25519 API keys as they offer optimized API performance and enhanced security

iden83 avatar Jan 31 '24 19:01 iden83

Hello @iden83, will be added shortly, thanks for reporting it!

carlosmiei avatar Oct 18 '24 14:10 carlosmiei

when can use in pip install -U python-binance ?

QGB avatar Oct 20 '24 08:10 QGB

@QGB I think there will be a new release in a few days.

carlosmiei avatar Oct 20 '24 09:10 carlosmiei

@QGB @iden83 We just released a new version with support for EDDSA keys. Please upgrade and let us know if anything!

carlosmiei avatar Oct 23 '24 11:10 carlosmiei

@QGB @iden83 We just released a new version with support for EDDSA keys. Please upgrade and let us know if anything!

Does EDDSA keys support futures API? I got problem

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(self, method, path, signed, version, **kwargs)
    397     def _request_futures_api(self, method, path, signed=False, version: int = 1, **kwargs) -> Dict:
    398         uri = self._create_futures_api_uri(path, version)
    399 
--> 400         return self._request(method, uri, signed, True, **kwargs)

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(self, method, uri, signed, force_params, **kwargs)
    372 
    373         kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs)
    374 
    375         self.response = getattr(self.session, method)(uri, **kwargs)
--> 376         return self._handle_response(self.response)

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(response)
    381         Raises the appropriate exceptions when necessary; otherwise, returns the
    382         response.
    383         """
    384         if not (200 <= response.status_code < 300):
--> 385             raise BinanceAPIException(response, response.status_code, response.text)
    386         try:
    387             return response.json()
    388         except ValueError:

BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

QGB avatar Nov 23 '24 15:11 QGB

Hello @QGB, yes it does.

Can you please double-check your keys are valid and correctly set? (no whitespaces/line breaks/etc)

@QGB you can check here https://github.com/sammchardy/python-binance/blob/master/tests/test_cryptography.py#L5 what is the expected format.

carlosmiei avatar Nov 23 '24 18:11 carlosmiei

Hello @QGB, yes it does.

Can you please double-check your keys are valid and correctly set? (no whitespaces/line breaks/etc)

@QGB you can check here https://github.com/sammchardy/python-binance/blob/master/tests/test_cryptography.py#L5 what is the expected format.

This keys for Spot API is OK。only error in futures

QGB avatar Nov 24 '24 07:11 QGB

@QGB I will double-check it and get back to you.

carlosmiei avatar Nov 24 '24 09:11 carlosmiei

@QGB You're right I managed to reproduce the issue, working on a fix right now!

carlosmiei avatar Nov 25 '24 15:11 carlosmiei

@QGB Not sure exactly what's causing the issue yet but can you try this on your end?

client.futures_account_balance(recvwindow="2000") for some reason this seems to fix it.

carlosmiei avatar Nov 25 '24 16:11 carlosmiei

(actually, after some more testing, it seems random... sometimes it works sometimes does not)

carlosmiei avatar Nov 25 '24 16:11 carlosmiei

@QGB I think I found the issue, working on a fix right now!

carlosmiei avatar Nov 26 '24 11:11 carlosmiei

@QGB We just released a new version that fixes this issue.

Can you please upgrade your python-binance version and try again?

carlosmiei avatar Nov 27 '24 17:11 carlosmiei

@carlosmiei 1.0.25 create spot order has error. 1.0.22 is OK

binance.__version__
Out[2]: '1.0.22'

client.create_order(symbol='VTHOUSDT',side='BUY',type='LIMIT',timeInForce='GTC',quantity=366,price=0.00287,)
Out[4]: 
{'symbol': 'VTHOUSDT',
 'orderListId': -1,
 'price': '0.00287000',
 'origQty': '366.00000000',
 'executedQty': '0.00000000',
 'cummulativeQuoteQty': '0.00000000',
 'status': 'NEW',
 'timeInForce': 'GTC',
 'type': 'LIMIT',
 'side': 'BUY',
 'fills': [],
 'selfTradePreventionMode': 'EXPIRE_MAKER'}

In [5]: 

In [5]: 

In [5]: pip uninstall -y python-binance
Found existing installation: python-binance 1.0.22
Uninstalling python-binance-1.0.22:
  Successfully uninstalled python-binance-1.0.22
Note: you may need to restart the kernel to use updated packages.

In [6]:                                                                                                                                                                               
Do you really want to exit ([y]/n)? y
(pyb124) qgb@10-40-47-90:~$ python3.12 -m IPython
Python 3.12.7 | packaged by Anaconda, Inc. | (main, Oct  4 2024, 13:27:36) [GCC 11.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.27.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: pip install dill pydes numpy python-binance==1.0.25
Requirement already satisfied: dill in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (0.3.9)
Requirement already satisfied: pydes in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (2.0.1)
Requirement already satisfied: numpy in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (2.1.3)
Collecting python-binance==1.0.25
  Downloading python_binance-1.0.25-py2.py3-none-any.whl.metadata (13 kB)
Requirement already satisfied: requests in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (2.32.3)
Requirement already satisfied: six in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (1.16.0)
Requirement already satisfied: dateparser in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (1.2.0)
Requirement already satisfied: aiohttp in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (3.11.10)
Requirement already satisfied: websockets in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (14.1)
Requirement already satisfied: pycryptodome in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from python-binance==1.0.25) (3.21.0)
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (2.4.4)
Requirement already satisfied: aiosignal>=1.1.2 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (1.3.1)
Requirement already satisfied: attrs>=17.3.0 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (24.2.0)
Requirement already satisfied: frozenlist>=1.1.1 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (1.5.0)
Requirement already satisfied: multidict<7.0,>=4.5 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (6.1.0)
Requirement already satisfied: propcache>=0.2.0 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (0.2.1)
Requirement already satisfied: yarl<2.0,>=1.17.0 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from aiohttp->python-binance==1.0.25) (1.18.3)
Requirement already satisfied: python-dateutil in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from dateparser->python-binance==1.0.25) (2.9.0.post0)
Requirement already satisfied: pytz in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from dateparser->python-binance==1.0.25) (2024.2)
Requirement already satisfied: regex!=2019.02.19,!=2021.8.27 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from dateparser->python-binance==1.0.25) (2024.11.6)
Requirement already satisfied: tzlocal in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from dateparser->python-binance==1.0.25) (5.2)
Requirement already satisfied: charset-normalizer<4,>=2 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from requests->python-binance==1.0.25) (3.4.0)
Requirement already satisfied: idna<4,>=2.5 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from requests->python-binance==1.0.25) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from requests->python-binance==1.0.25) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in ./anaconda3/envs/pyb124/lib/python3.12/site-packages (from requests->python-binance==1.0.25) (2024.8.30)
Downloading python_binance-1.0.25-py2.py3-none-any.whl (100 kB)
Installing collected packages: python-binance
Successfully installed python-binance-1.0.25
Note: you may need to restart the kernel to use updated packages.

In [2]: 
   ...: import binance.client
   ...: client=binance.client.Client(**ka)
   ...: binance.__version__
Out[2]: '1.0.25'

In [3]: 

client.create_order(symbol='VTHOUSDT',side='BUY',type='LIMIT',timeInForce='GTC',quantity=366,price=0.00287,)
---------------------------------------------------------------------------
BinanceAPIException                       Traceback (most recent call last)
<ipython-input-3-df908548949e> in ?()
----> 1 B.gclient.create_order(symbol='VTHOUSDT',side='BUY',type='LIMIT',timeInForce='GTC',quantity=366,price=0.00287,)

~/anaconda3/envs/pyb124/lib/python3.12/site-packages/binance/client.py in ?(self, **params)
   1315 
   1316         """
   1317         if "newClientOrderId" not in params:
   1318             params["newClientOrderId"] = self.SPOT_ORDER_PREFIX + self.uuid22()
-> 1319         return self._post("order", True, data=params)

~/anaconda3/envs/pyb124/lib/python3.12/site-packages/binance/client.py in ?(self, path, signed, version, **kwargs)
    164     def _post(
    165         self, path, signed=False, version=BaseClient.PUBLIC_API_VERSION, **kwargs
    166     ) -> Dict:
--> 167         return self._request_api("post", path, signed, version, **kwargs)

~/anaconda3/envs/pyb124/lib/python3.12/site-packages/binance/client.py in ?(self, method, path, signed, version, **kwargs)
     95         version=BaseClient.PUBLIC_API_VERSION,
     96         **kwargs,
     97     ):
     98         uri = self._create_api_uri(path, signed, version)
---> 99         return self._request(method, uri, signed, **kwargs)

~/anaconda3/envs/pyb124/lib/python3.12/site-packages/binance/client.py in ?(self, method, uri, signed, force_params, **kwargs)
     71 
     72         kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs)
     73 
     74         self.response = getattr(self.session, method)(uri, headers=headers, **kwargs)
---> 75         return self._handle_response(self.response)

~/anaconda3/envs/pyb124/lib/python3.12/site-packages/binance/client.py in ?(response)
     80         Raises the appropriate exceptions when necessary; otherwise, returns the
     81         response.
     82         """
     83         if not (200 <= response.status_code < 300):
---> 84             raise BinanceAPIException(response, response.status_code, response.text)
     85         try:
     86             return response.json()
     87         except ValueError:

BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

QGB avatar Dec 08 '24 07:12 QGB

@carlosmiei In spot create order. _generate_signature uri_encode must be False. Futures create order _generate_signature uri_encode True or False doesn't matter.

https://github.com/sammchardy/python-binance/blob/10f398688b58fed8fc0e28e9e0c36d0cb01fdd24/binance/base_client.py#L332

QGB avatar Dec 09 '24 11:12 QGB

@QGB Will check this ASAP, thanks for reporting it

carlosmiei avatar Dec 09 '24 11:12 carlosmiei

@QGB I can reproduce the error, but i don't think it is related to the URI_ENCODE. At CCXT the payload is always uri_encoded and it works as expected (I tested it): https://github.com/ccxt/ccxt/blob/master/python/ccxt/binance.py#L11114

carlosmiei avatar Dec 09 '24 14:12 carlosmiei

@QGB Found the issue, will be fixed here: https://github.com/sammchardy/python-binance/pull/1506

carlosmiei avatar Dec 09 '24 16:12 carlosmiei

@carlosmiei The latest version seems to error randomly.

In [14]: client.futures_position_information()
---------------------------------------------------------------------------
BinanceAPIException                       Traceback (most recent call last)
<ipython-input-14-06c54064b085> in ?()
----> 1 client.futures_position_information()

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(self, **params)
   7670 
   7671         https://binance-docs.github.io/apidocs/futures/en/#position-information-user_data
   7672 
   7673         """
-> 7674         return self._request_futures_api("get", "positionRisk", True, 3, data=params)

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(self, method, path, signed, version, **kwargs)
    104         version = self._get_version(version, **kwargs)
    105         uri = self._create_futures_api_uri(path, version)
    106         force_params = kwargs.pop("force_params", False)
    107 
--> 108         return self._request(method, uri, signed, force_params, **kwargs)

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(self, method, uri, signed, force_params, **kwargs)
     71 
     72         kwargs = self._get_request_kwargs(method, signed, force_params, **kwargs)
     73 
     74         self.response = getattr(self.session, method)(uri, headers=headers, **kwargs)
---> 75         return self._handle_response(self.response)

~/anaconda3/lib/python3.11/site-packages/binance/client.py in ?(response)
     80         Raises the appropriate exceptions when necessary; otherwise, returns the
     81         response.
     82         """
     83         if not (200 <= response.status_code < 300):
---> 84             raise BinanceAPIException(response, response.status_code, response.text)
     85         try:
     86             return response.json()
     87         except ValueError:

BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

In [15]: client.futures_position_information()
Out[15]: 
[{'symbol': 'JASMYUSDT',
  'positionSide': 'SHORT',

QGB avatar Dec 15 '24 17:12 QGB