Websocket api works for spot but not for futures (Ed25519 signatures)

I have tested signature generation to both endpoints with identical data to sign. I’ve hided my API Key from server replys but be sure it is the same. This is log data from two parallel threads. I’ve stored timestamp from first and use it in second thread. As you can see, signatues it is the same. After "W: " the data that goes to web socket. "R: " - received from socket.

12:06:58.8927 Connecting to wss://ws-api.binance.com/ws-api/v3
12:07:00.0261 W: {"id":"128","method":"session.logon","params":{"apiKey":"my_key","signature":"1zpzJs3sRvGOwx7JX1hfy0FUjyMiNYte0KEy/bQabjKkR+QciDN4qtESes5/zrugzEE3T/lHJ4Ws6KBva3BvCA=","timestamp":1716466020026}}
12:07:00.3000 R: {"id":"128","status":200,"result":{"apiKey":"my_key","authorizedSince":1716466020026,"connectedSince":1716466019886,"returnRateLimits":true,"serverTime":1716466020162}}

12:06:58.8937 Connecting to wss://ws-fapi.binance.com/ws-fapi/v1
12:07:00.0317 W: {"id":"128","method":"session.logon","params":{"apiKey":"my_key","signature":"1zpzJs3sRvGOwx7JX1hfy0FUjyMiNYte0KEy/bQabjKkR+QciDN4qtESes5/zrugzEE3T/lHJ4Ws6KBva3BvCA=","timestamp":1716466020026}}
12:07:00.3085 R: {"id":"128","status":400,"error":{"code":-1022,"msg":"Signature for this request is not valid."}}

Non-signed requests are working:

11:55:23.5421 Connecting to wss://ws-fapi.binance.com/ws-fapi/v1
11:55:24.6768 W: {"id":"32768","method":"userDataStream.start","params":{"apiKey":""}}
11:55:24.9538 R: {"id":"32768","status":200,"result":{"listenKey":"my_listen_key"} ... }

But signed equests are not:

11:55:24.9543 W: {"id":"128","method":"session.logon","params":{"apiKey":"","signature":"tUUDtBv1ZP7W3RgQrZZQ7wrCAHuqLw9XyrEw8iKe0SbxhgXXVLyzO9tOhyzzLMycVX4WN/AxGunKxBCe4sc6Bg=","timestamp":1716465324954}}
11:55:25.2295 R: {"id":"128","status":400,"error":{"code":-1022,"msg":"Signature for this request is not valid."} ... }

Tryed other key pair and double checked that Futures is enabled in it, IP is correct, etc.

Not sure how you’re signing the params; but they should be sent in the order as they were signed. You can safely append the signature at the end.

{"apiKey": "", "timestamp": 0, "signature": ""}

To sign you need to create a “request string”, basically “apiKey=YOURAPIKEY&timestamp=YOURTIMESTAMP”. A javascript map doesn’t have any specific ordering, although one can usually depend on insertion order. But regardless, the map itself isn’t used for signing, just for sending the parameters, and I doubt the order inside the object matters at all.

But for the original question, note that he shows the same signature for both requests. Since it seems to be working for the ws-api version, it does indicate that he does create the proper “request string” for signing (he isn’t showing it though).

Assuming your code and signing is correct, the only other two options I can imagine is not allowing futures or something related to the warning you get when hovering over the futures enabling flag:

“The Futures API cannot be used if the API key was created before the Futures account was opened, or if you have enabled portfolio margin.”

But I would be surprised if either of these two generates a signature error. Which again points back the signature being wrongly calculated. Maybe you could share some code snippet or something?

I discovered I’ve made a mistake in calculating that signature. Thank you for discussion!

I tried to create signature with the following code:

params.timestamp = Date.now()
        params.signature = crypto.createHmac('sha256', process.env.BINANCE_API_SECRET).update(Object.keys(params).sort().map(key => `${key}=${params[key]}`).join('&')).digest('hex')

but it the result from the websocket tells me that:

{"id":"1720472182862","status":400,"error":{"code":-4056,"msg":"HMAC_SHA256 API key is not supported."},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":179}]}

and this is written in nowhere that tells HMAC_SHA256 API Key is not supported on new Binance Websocket futures order.

How did you resolve it @sackett ?

thanks to this post: Websocket API signatures broken? I just noticed that session.logon message is not accepting SHA256 HMAC. what a shame…