My code to get my Balance from the Kraken API does work in Python (based on the krakenex library), but not in the JS version (based loosely off the kraken-api library, but with the crypto
library substituted for crypto-js
). The error is always: Invalid Key.
Even when I copy the headers and the nonce sent by the Python client into Postman, I get Invalid Key.
I believe the signature and nonce to be valid, because when they are not, Kraken retorts that either the signature or nonce are invalid.
Is there anything else that Javascript's fetch
does differently than Python3 requests
? Because the body and headers are otherwise identical.
JS code that generates auth data:
const getMessageSignature = (path, request, secret, nonce) => {
// API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
const message = qs.stringify(request);
console.log(message);
const secret_buffer = btoa(secret);
const hash = CryptoJS.algo.SHA256.create();
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret_buffer);
const hash_digest = hash.update(nonce + message).finalize().toString(CryptoJS.enc.Hex);
const hmac_digest = hmac.update(path + hash_digest).finalize().toString(CryptoJS.enc.Base64);
// CANNOT USE ORIGINAL LIB CODE (Buffer, got and crypto not supported)
// const secret_buffer = new Buffer(secret, 'base64');
// const hash = new crypto.createHash('sha256');
// const hmac = new crypto.createHmac('sha512', secret_buffer);
// const hash_digest = hash.update(nonce + message).digest('binary');
// const hmac_digest = hmac.update(path + hash_digest, 'binary').digest('base64');
return hmac_digest;
};
Update: In fact, the following observations are weird:
what gives?
Update2 Seems the requests are identical (other than the signature and nonce of course, which will and should change with every request).
Turns out it was the signature after all and Kraken simply doesn't give very accurate responses (which makes some sense, but is a pain if you're trying to figure something out). Finally I was able to rewrite the code using CryptoJS only:
const getMessageSignature = (path, request, secret, nonce) => {
// API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
const message = JSON.stringify(request);
const hash = CryptoJS.SHA256(nonce + message);
const secret_buffer = CryptoJS.enc.Base64.parse(secret);
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA512, secret_buffer);
hmac.update(path, secret_buffer);
hmac.update(hash, secret_buffer);
return hmac.finalize().toString(CryptoJS.enc.Base64);
};
This yields a correct signature and Kraken no longer complains. Zzah.