enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 12:44:03 AM |
|
I have never made a program that interacts with a website's API before but I am trying my hand at a trading bot! I am writing in python and so far have it so that I can query the public data just fine. example: import requests import json from pprint import pprint pairData = requests.post(" https://api.kraken.com/0/public/AssetPairs", data = {}) pairDataJson = json.loads(pairData.content) pprint(pairDataJson) But I can't seem to wrap my head around the private methods (the whole api-key / api-sign / nonce stuff). I understand I get my api-key by logging in through the website, but from there I am stuck. Can anyone give an example of what a post request would look like for the private methods?
|
|
|
|
pooya87
Legendary
Offline
Activity: 3640
Merit: 11038
Crypto Swap Exchange
|
|
June 09, 2017, 04:41:19 AM |
|
you can just google "kraken api python" and find a lot of libraries that you can either clone and use or copy code from and learn. as for your question i am not at all familiar with python but what i can tell you is that you are making one mistake here, you are making a POST request to a public API endpoint where you should have made a GET request. the endpoints such as AssetPairs, ... which give public data such as prices, orderbooks, etc are all GET. so it will probably be something like pairData = requests.get("https://api.kraken.com/0/public/AssetPairs" /* nothing here*/)
as for private endpoints such as GetBalance, Make an Order, .... nonce is simply a number. since the docs says "unsigned 64 bit integer" then what i usually do is that i get my DateTime.Now and convert it to Epoch and use that as the nonce. also in the headers you add two things: API-Key: which is simply your ApiKey which you get from website something like Header.Add("API-Key", "MySuperSecretApi KeyGoesHere"); API-Sign: HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key something like: string s = " https://api.kraken.com/0/private/TradeBalance" + SHA256("1496983172" + null) HMACSHA512(s.ToBase64.ToByteArray, "MySuperSecretApi SecretGoesHere") convert these to python code, i'm just pointing out what goes where
|
|
|
|
enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 01:28:59 PM |
|
Thank you for your response. I have wrote a function to send private posts but I get a response back telling me I have an invalid signature :S
def privateMethod(method, args = {}): nonce = str(int(time.time())) argJson = json.dumps(args) sha256 = hashlib.sha256(nonce.encode('utf-8') + argJson.encode('utf-8')).hexdigest() urlPath = KrakenAPI.URL + KrakenAPI.PRIVATE + method sha512 = hashlib.sha512(urlPath.encode('utf-8') + sha256.encode('utf-8') + base64.b64decode(KrakenAPI.SECRET_API_KEY)).hexdigest() header = {'API-Key': KrakenAPI.API_KEY, 'API-Sign': sha512} return requests.post(KrakenAPI.URL + KrakenAPI.PRIVATE + method, headers = header, data = urlencode(args))
balanceData = privateMethod("Balance") balanceDataJson = json.loads(balanceData.content) pprint(balanceDataJson)
Also, is there a particular reason I should be using get vs post for the public methods? Genuinely curious.
|
|
|
|
enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 02:01:45 PM |
|
Second attempt, realized I wasn't using HMAC SHA512. Same result.
def privateMethod(method, args = {}): nonce = str(int(time.time())) argJson = json.dumps(args) sha256 = hashlib.sha256(nonce.encode('utf-8') + argJson.encode('utf-8')).hexdigest() urlPath = KrakenAPI.URL + KrakenAPI.PRIVATE + method sha512 = hmac.new(base64.b64decode(KrakenAPI.SECRET_API_KEY), urlPath.encode('utf-8') + sha256.encode('utf-8'), hashlib.sha512).hexdigest() header = {'API-Key': KrakenAPI.API_KEY, 'API-Sign': sha512} return requests.post(KrakenAPI.URL + KrakenAPI.PRIVATE + method, headers = header, data = urlencode(args))
balanceDataJson = privateMethod("Balance") balanceData = json.loads(balanceDataJson.content) pprint(balanceData)
|
|
|
|
Serpens66
Legendary
Offline
Activity: 2954
Merit: 1131
|
|
June 09, 2017, 02:07:17 PM |
|
you use GET/POST depending on what the API documentation is telling you.
And yes, simply google for "kraken API python". I also got a script from there and learned from it.
|
Mit Cointracking (10% Rabatt) behältst du die Übersicht über all deine Trades und Gewinne. Sogar ein Tool für die Steuer ist dabei Great Freeware Game: Clonk Rage binance.com hat nun auch SEPA und EUR Paare! Mit dem RefLink bekommst du 5% Rabatt auf die Tradinggebühren!
|
|
|
enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 02:40:10 PM |
|
OK so I downloaded the python code from github and gleaned a few insights from it. I now get a different error.... {'error': ['EGeneral:Internal error']}
No idea what this could be. It would be nice if the different errors had some documentation..
new code just FYI:
def privateMethod(method, args = {}): nonce = str(int(time.time())) argJson = json.dumps(args) req = urlencode(args) sha256 = hashlib.sha256(nonce.encode() + req.encode()).digest() urlPath = KrakenAPI.URL + KrakenAPI.PRIVATE + method sha512 = base64.b64encode(hmac.new(base64.b64decode(KrakenAPI.SECRET_API_KEY), urlPath.encode() + sha256, hashlib.sha512).digest()).decode() header = {'API-Key': KrakenAPI.API_KEY, 'API-Sign': sha512} return requests.post(KrakenAPI.URL + KrakenAPI.PRIVATE + method, headers = header)
balanceDataJson = privateMethod("Balance") balanceData = json.loads(balanceDataJson.content) pprint(balanceData)
|
|
|
|
enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 03:33:09 PM |
|
Alright so now I get an error message saying invalid key! Is the key not simply what they provide you via the website? Do you not just copy / paste it? I can understand my signature not being valid, but the key?
def privateMethod(method, args = {}): urlPath = KrakenAPI.URL + KrakenAPI.PRIVATE + method args['nonce'] = int(1000*time.time()) postData = urlencode(args) encoded = (str(args['nonce']) + postData).encode() message = urlPath.encode() + hashlib.sha256(encoded).digest() signature = hmac.new(base64.b64decode(KrakenAPI.SECRET_API_KEY), message, hashlib.sha512) sigdigest = base64.b64encode(signature.digest()) header = {'API-Key': KrakenAPI.API_KEY, 'API-Sign': sigdigest.decode()} return requests.post(urlPath, headers = header, data = postData)
balanceDataJson = privateMethod("Balance") balanceData = json.loads(balanceDataJson.content) pprint(balanceData)
|
|
|
|
enter`name`here (OP)
Jr. Member
Offline
Activity: 61
Merit: 1
|
|
June 09, 2017, 06:25:18 PM |
|
So I solved the issue! Today i learned there is a difference between a URL and a URI. The signature uses the URI not the URL (/0/public/Balance as opposed to https://api.kraken.com/0/public/Balance). Thank you guys for responding, your replies did set me on the right track! In case anyone with the same problem googles this 1 year from now here is some code that works for me: def privateMethod(method, args = {}): uriPath = KrakenAPI.PRIVATE + method urlPath = KrakenAPI.URL + KrakenAPI.PRIVATE + method args['nonce'] = int(1000*time.time()) postData = urlencode(args) encoded = (str(args['nonce']) + postData).encode() message = uriPath.encode() + hashlib.sha256(encoded).digest() signature = hmac.new(base64.b64decode(KrakenAPI.SECRET_API_KEY), message, hashlib.sha512) sigdigest = base64.b64encode(signature.digest()) header = {'API-Key': KrakenAPI.API_KEY, 'API-Sign': sigdigest.decode()} return requests.post(urlPath, headers = header, data = postData)
|
|
|
|
MacLovin
Newbie
Offline
Activity: 2
Merit: 0
|
|
January 22, 2018, 06:16:45 PM |
|
Hello "enter`name`here", I'm struggling to get authenticated using Kraken API, I saw your messages on the forum. Do you mind if I ask you some questions?
I use to succeed to connect to bitfinex api and do a simple trading bot, but with kraken they doesn't give much infos on how to get authenticated.
HTTP header: API-Key = API key API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
POST data: nonce = always increasing unsigned 64 bit integer otp = two-factor password (if two-factor enabled, otherwise not required)
Regarding base64 decoded secret api: Do you decode it using ASCII or UTF-8 ?
From what I understood, usualy the post message is broken down in 3 part : the header, the payload and the signature.
In the kraken doc, it seems that you put everthing in the header : the api key, the signature, the endpoint(getBalance, order...). So if you pass an order, where do you put the details :in the header too? Or do you create a payload?
I'm writing my program in nodejs, I don't know if it's an important info... If you could help even just a bit that would be so appreciated
Take care, Mac Lovin
|
|
|
|
Sappher
Newbie
Offline
Activity: 1
Merit: 0
|
|
January 24, 2018, 09:53:30 PM |
|
I'm having issues with this myself as well, been driving me mad... I FINALLY got rid of the "Invalid signature" error, just to battle for hours with "Invalid key". I still haven't gotten it to work. I assume the signature is now okay, as I get the Invalid key error now? But how do I get the key right?? I've tried many things, simply inserting it as it is from my Kraken account API page, to decoding/encoding it from base64, tried UTF-8, Latin, everything...
I'm using C++ and Qt library. Basically been trying it like this (setRawHeader is a method of QNetworkRequest and APIKEYHERE is a string of the API key straight from the Kraken account page):
setRawHeader("API-Key", "APIKEYHERE");
setRawHeader("API-Key", QByteArray("APIKEYHERE"));
setRawHeader("API-Key", QByteArray("APIKEYHERE").toHex());
setRawHeader("API-Key", QByteArray("APIKEYHERE").toBase64());
setRawHeader("API-Key", QByteArray("APIKEYHERE").toHex());
setRawHeader("API-Key", QByteArray::fromBase64("APIKEYHERE").toHex());
setRawHeader("API-Key", QString("APIKEYHERE").toUtf8());
setRawHeader("API-Key", QString("APIKEYHERE").toLatin1());
etc., nothing seems to work. I also downloaded another C++ API from Kraken's API website, and tried that: SAME ERROR! What the hell!
|
|
|
|
wouayo
Newbie
Offline
Activity: 1
Merit: 0
|
|
January 29, 2018, 07:28:32 PM |
|
i have the same problem, using the C# exemple of kraken site: Private Function QueryPrivate(ByVal a_sMethod As String, Optional ByVal props As String = Nothing) As JsonObject Dim nonce As Int64 = DateTime.Now.Ticks props = "nonce=" & nonce & props 'Dim path As String = String.Format("/{0}/private/{1}", _version, a_sMethod) Dim path As String = String.Format(CultureInfo.InvariantCulture, "/{0}/private/{1}", _version, a_sMethod)
Dim address As String = _url & path Dim webRequest As HttpWebRequest = CType(Net.WebRequest.Create(address), HttpWebRequest) webRequest.ContentType = "application/x-www-form-urlencoded" webRequest.Method = "POST" webRequest.Headers.Add("API-Key", _key) Dim base64DecodedSecred As Byte() = Convert.FromBase64String(_secret) Dim np = nonce & Convert.ToChar(0) & props Dim pathBytes = Encoding.UTF8.GetBytes(path) Dim hash256Bytes = sha256_hash(np) Dim z = New Byte(pathBytes.Count() + hash256Bytes.Count() - 1) {} pathBytes.CopyTo(z, 0) hash256Bytes.CopyTo(z, pathBytes.Count())
Dim signature = getHash(base64DecodedSecred, z) webRequest.Headers.Add("API-Sign", Convert.ToBase64String(signature)) If props IsNot Nothing Then Using writer = New StreamWriter(webRequest.GetRequestStream()) writer.Write(props) End Using End If
... i have the EAPI Invalid Key message ... and i don't understand, the keys are ok. If someone have an idea, thanks ....
|
|
|
|
MacLovin
Newbie
Offline
Activity: 2
Merit: 0
|
|
January 31, 2018, 06:31:22 PM |
|
Hey Guys, So i did some steps forward, now I get an error message saying : "Unknow Method".
If anyone have an idea about where this error could come from...
Cheers
|
|
|
|
|