Bitcoin Forum
June 17, 2024, 08:14:37 AM *
News: Voting for pizza day contest
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Kraken API help  (Read 1336 times)
enter`name`here (OP)
Jr. Member
*
Offline Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 12:44:03 AM
 #1

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 Offline

Activity: 3486
Merit: 10653



View Profile
June 09, 2017, 04:41:19 AM
 #2

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
Code:
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", "MySuperSecretApiKeyGoesHere");

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, "MySuperSecretApiSecretGoesHere")

convert these to python code, i'm just pointing out what goes where Smiley

.
.BLACKJACK ♠ FUN.
█████████
██████████████
████████████
█████████████████
████████████████▄▄
░█████████████▀░▀▀
██████████████████
░██████████████
████████████████
░██████████████
████████████
███████████████░██
██████████
CRYPTO CASINO &
SPORTS BETTING
▄▄███████▄▄
▄███████████████▄
███████████████████
█████████████████████
███████████████████████
█████████████████████████
█████████████████████████
█████████████████████████
███████████████████████
█████████████████████
███████████████████
▀███████████████▀
█████████
.
enter`name`here (OP)
Jr. Member
*
Offline Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 01:28:59 PM
 #3

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 Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 02:01:45 PM
 #4

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 Offline

Activity: 2926
Merit: 1131



View Profile
June 09, 2017, 02:07:17 PM
 #5

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 Wink                          
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 Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 02:40:10 PM
 #6

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 Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 03:33:09 PM
 #7

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 Offline

Activity: 61
Merit: 1


View Profile
June 09, 2017, 06:25:18 PM
 #8

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 Offline

Activity: 2
Merit: 0


View Profile
January 22, 2018, 06:16:45 PM
 #9

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 Offline

Activity: 1
Merit: 0


View Profile
January 24, 2018, 09:53:30 PM
 #10

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 Offline

Activity: 1
Merit: 0


View Profile
January 29, 2018, 07:28:32 PM
 #11



i have the same problem, using the C# exemple of kraken site:

Quote
           
        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 Offline

Activity: 2
Merit: 0


View Profile
January 31, 2018, 06:31:22 PM
 #12

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
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!