Binance API- Passing Security (Header or body)

Get help with using AutoHotkey and its commands and hotkeys
usdarkejo
Posts: 5
Joined: 15 Jul 2016, 17:13

Binance API- Passing Security (Header or body)

18 May 2018, 12:12

Hi All,

I've been working on this for passed 2 days. Here is the code I have so far. From what I'm reading, this should work, but I'm sure there is something I need to modify. What I'm trying to do is pull in all my account information. The official API documentation is located here: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md

Before anyone asks if I've read the documentation or researched on my own, know that the majority of the code I have was pulled from someone elses custom AHK code that works flawlessly on another exchange. I have searched, searched, and searched some more. I have also checked all my variables and they seem to be assigned correctly.


Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
jeeswg
Posts: 4797
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Binance API- Passing Security (Header or body)

18 May 2018, 12:48

Perhaps you need colons here:

Code: [Select all] [Download] GeSHi © Codebox Plus

apikey := "Changed For Forum Post"
secret := "Changed For Forum Post"

Otherwise posting the error message/response text might give a clue.
usdarkejo
Posts: 5
Joined: 15 Jul 2016, 17:13

Re: Binance API- Passing Security (Header or body)

18 May 2018, 12:57

Hi Jeeswg,

Surprisingly, that did seem to move me in the right direction. Initially, I was receiving "The request could not be satisfied". Adding the colons as you suggested did not change the outcome, but when I removed 'PostData' from line oHttp.Send(PostData)' -- as some people have suggested to identify error messages -- I received the message, "Mandatory Parameter 'timestamp' was not sent.". Now I'm wondering if maybe the format for the time sent (A_now) to the timestamp query string is not formatted correctly. I will keep playing around, but if you see I'm heading down the wrong path, please let me know.

Code: [Select all] [Download] GeSHi © Codebox Plus

postdata := "TimeStamp=" a_now
sign := HMAC(secret, postdata, "sha512")
url := "https://api.binance.com/api/v3/account"

oHTTP.Open("GET", URL , False) ;Post request
oHTTP.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
oHTTP.SetRequestHeader("Key", apikey)
oHTTP.SetRequestHeader("Sign", sign)
oHTTP.Send(PostData) ;Send POST request
User avatar
jeeswg
Posts: 4797
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Binance API- Passing Security (Header or body)

18 May 2018, 13:12

I don't know Binance, I looked up Binance and timestamp, and I believe that this might work:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

usdarkejo
Posts: 5
Joined: 15 Jul 2016, 17:13

Re: Binance API- Passing Security (Header or body)

18 May 2018, 13:19

I thought we were on to something. I have verified the new variable is in milliseconds using your code above, modified the timestamp parameter and still receive the same error message.
User avatar
gregster
Posts: 1351
Joined: 30 Sep 2013, 06:48

Re: Binance API- Passing Security (Header or body)

18 May 2018, 23:59

Fear not, young api-rentice :) ! You have searched and I have found!

While pulling some working code from somewhere else can surely help, there are almost every time some differences and you will have to read very closely (and there is often room for interpretation). With that said, the Binance API docs are not good, but I have seen much worse :roll: . In the working code (see below) I used the following code (first two you already know):

* jeeswg's Unix-Time-function (much smaller than my version, thanks for that!),
* the same HMAC function you used, I think - I haven't really compared, but just copied the version I always used successfully (I think, it was made by forum member 'just me' back in the day)
* and finally - and optionally - Coco's JSON Class (https://autohotkey.com/boards/viewtopic.php?t=627) to parse the response string (not necessary, but a huge help with JSON data - otherwise, you will have to do a lot of parsing) - this library, I included through the #include directive in the first line. Just download JSON.ahk and put it in the same folder and it should work.

Some remarks what went wrong with your code: You were creating a sha512 HMAC hash, while the binance API docs advise you to use a sha256 HMAC hash - that breaks the whole request early on beyond repair... The timestamp needs to be UNIX UTC in milliseconds (not very clear in the docs, but quite common for APIs), but that was fixed by jeeswg. Then, you have some comments which mention a POST request, although you are using a GET request - which is correct in this case:

Code: [Select all] [Download] GeSHi © Codebox Plus

Account information (USER_DATA)
GET /api/v3/account (HMAC SHA256) Get current account information.
Weight: 5

Parameters:
Name Type Mandatory Description
------------------------------------------------------------
recvWindow LONG NO
timestamp LONG YES

But unfortunately, you didn't follow these crucial hints from the docs:
For GET endpoints, parameters must be sent as a query string.
[...]
API-keys are passed into the Rest API via the X-MBX-APIKEY header.

You are trying to send the parameters in the request body instead. Also, the header name for the API key is wrong, and the signature needs to be part of the query string here, not a header (other APIs will handle this different). Judging by the thread title, you already had a suspicion...
That is all excusable, if you are not used to work with APIs. But these are other breaking points in your script.
I admit, without the examples from the binance docs (and a little experience), I would have needed much more time myself... :shh:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


Don't forget to include your API keys. It seems, POST requests can be done with the query string method, too, but I haven't looked closely so far.

Let us know, if this worked (it should, if I didn't make any bad copy-paste-errors) and if you need further help. Good luck!
usdarkejo
Posts: 5
Joined: 15 Jul 2016, 17:13

Re: Binance API- Passing Security (Header or body)

19 May 2018, 05:23

Thank you, Gregster! Great explanation as well - That worked like a charm. If only they would post more examples in their documentation because as you said, their documentation is not good. :-(
User avatar
jeeswg
Posts: 4797
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Binance API- Passing Security (Header or body)

20 May 2018, 13:34

- Nicely done gregster!
- What's the significance of the timestamp, is it a problem if it's too early or too late, does it need to be precise?
- Here's a function to get the Unix time now in milliseconds:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

User avatar
gregster
Posts: 1351
Joined: 30 Sep 2013, 06:48

Re: Binance API- Passing Security (Header or body)

20 May 2018, 14:56

jeeswg wrote:- What's the significance of the timestamp, is it a problem if it's too early or too late, does it need to be precise?
It depends, there are APIs which only use the timestamp as a (increasing) nonce - then you don't need a precise timestamp (or you could use your local time instead of UTC), but the binance API - according to the docs - seems to also compare the sent timestamp to its own server time:
Binance API docs (https://github.com/binance-exchange/bin ... est-api.md) wrote:
A SIGNED endpoint also requires a parameter, timestamp, to be sent which should be the millisecond timestamp of when the request was created and sent.
An additional parameter, recvWindow, may be sent to specific the number of milliseconds after timestamp the request is valid for. If recvWindow is not sent, it defaults to 5000.
The logic is as follows:

Code: [Select all] [Download] GeSHi © Codebox Plus

 if (timestamp < (serverTime + 1000) && (serverTime - timestamp) <= recvWindow) {
// process request
} else {
// reject request
}

Serious trading is about timing. Networks can be unstable and unreliable, which can lead to requests taking varying amounts of time to reach the servers. With recvWindow, you can specify that the request must be processed within a certain number of milliseconds or be rejected by the server.

So, it seems, they are using the timestamp to validate the API call; and the optional parameter recvWindow, which is mentioned in the docs I quoted in the last post, can be used to adjust the acceptable delay for a valid call.

I will have a look at the other function you provided, but since the default for recvWindow is 5000 ms and sending the data via the internet also takes at least some milliseconds, I don't think that millisecond precision is really needed here - the other function which just multiplies by 1000 is probably good enough for this application - with a (significantly) smaller window you might end up with too many discarded calls, I assume. It could still be useful for other things...

Return to “Ask For Help”

Who is online

Users browsing this forum: Google [Bot], imustbeamoron, swagfag, ZeroX4 and 46 guests