In continuation of building Google SpreadSheet using Google Apps Script I've done with getting my Bittrex and Poloniex balances, but can't get to work with Cryptopia.
Here is a link to my struggles with Bittrex Map JSON objects array to strings
Here is an official API links: https://www.cryptopia.co.nz/Forum/Thread/256
Here are some examples:
- https://www.cryptopia.co.nz/Forum/Thread/262
- https://github.com/Coac/cryptopia.js/blob/master/index.js
- https://github.com/sigwo/node-cryptopia/blob/master/cryptopia.js
Here is my code, which getting "Invalid authorization header" error:
// Get Cryptopia balances
var key = keys.getRange("B4").getValue();
var secret = keys.getRange("C4").getValue();
var baseUrl = 'https://www.cryptopia.co.nz/api/';
var command = "GetBalance";
var url = baseUrl + command;
var signature = key + "POST" + encodeURIComponent(url).toLowerCase() + nonce;
var hmacsignature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256,signature,secret);
var header_value = "amx " + key + ":" + hmacsignature + ":" + nonce;
var headers = { 'Authorization': header_value, 'Content-Type':'application/json; charset=utf-8' };
var options = {
method: 'POST',
headers: headers
};
var response = UrlFetchApp.fetch("https://www.cryptopia.co.nz/api/GetBalance", options);
var json = JSON.parse(response.getContentText());
}
From your sample links, it seems that hmacsignature
is encoded by base64. So how about the following modofication?
From :
var hmacsignature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256,signature,secret);
To :
var hmacsignature = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256,signature,secret));
Note :
- Is
nonce
declared? If you have not declared it, you can use a following script.
var nonce = Math.floor(new Date().getTime() / 1000);
I cannot test this. So I don't know whether this works fine. If this didn't work, I'm sorry.
Edit :
How about this? var params = {};
might be required, even if there is no request parameters. So I added this and Content-Length
. And then, is secret
encoded by base64? I thought that it may be encoded from other scripts.
var key = keys.getRange("B4").getValue();
var secret = keys.getRange("C4").getValue();
var nonce = Math.floor(new Date().getTime() / 1000); // Added
var params = {}; // Added
var baseUrl = 'https://www.cryptopia.co.nz/api/';
var command = "GetBalance";
var url = baseUrl + command;
var requestContentBase64String = Utilities.base64Encode(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, JSON.stringify(params), Utilities.Charset.UTF_8)); // Added
var signature = key + "POST" + encodeURIComponent(url).toLowerCase() + nonce + requestContentBase64String; // Modified
var hmacsignature = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, signature, Utilities.base64Decode(secret), Utilities.Charset.UTF_8)); // Modified
var header_value = "amx " + key + ":" + hmacsignature + ":" + nonce;
var headers = {
"Authorization": header_value,
"Content-Type": 'application/json; charset=utf-8',
"Content-Length" : Utilities.newBlob(JSON.stringify(params)).getBytes().length // Added
};
var options = {
method: 'POST',
headers: headers
};
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response.getContentText());
Utilities.computeHmacSignature(algorithm, value, key)
method does not compute the binary input correctly. The type of value
and key
parameter is String
, but Utilities.base64Decode
's result is Byte[]
. The raw binary value is changed while being converted from Byte[]
to String
.
Use jsSHA, and cf. https://stackoverflow.com/a/14007167.
The following can be used to calculate the correct value, and fetch the result by proper UrlFetchApp.fetch
's options
.
.... paste src/sha256.js contents ...
...
var params = {"Currency" : "BTC"};
...
var sha = new jsSHA("SHA-256", "TEXT");
sha.setHMACKey(secret, "B64");
sha.update(signature);
var hmacsignature = sha.getHMAC("B64");
var header_value = "amx " + key + ":" + hmacsignature + ":" + nonce;
var headers = {
"Authorization" : header_value,
};
var options = {
"contentType": 'application/json; charset=utf-8',
"method": 'post',
"headers": headers,
"payload": JSON.stringify(params),
"contentLength": JSON.stringify(params).length
};
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response.getContentText());
Logger.log(json);