Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Node.JS code snippet to Javascript (Google Apps Script)

I would like to convert the following Node.JS code snippet to JavaScript in order to run it in Google Apps Script:

From: Node.JS

function getMessageSignature(path, request, nonce) {
  var message   = querystring.stringify(request);
  var secret    = new Buffer(config.secret, 'base64');
  var hash  = new crypto.createHash('sha256');
  var hmac  = new crypto.createHmac('sha512', secret);
  var hash_digest   = hash.update(nonce + message).digest('binary');
  var hmac_digest   = hmac.update(path + hash_digest, 'binary').digest('base64');
  return hmac_digest;
}

This is the code I have tried so far (and many variations of it):

To: JavaScript / Google Apps Script

function getMessageSignature(url, request, nonce) {

  // Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) 
  //and base64 decoded secret API key

  const secretApiKey = 'wdwdKswdKKewe23edeYIvL/GsltsGWbuBXnarcxZfu/9PjFbXl5npg==';
  var secretApiKeyBytes = Utilities.base64Decode(secretApiKey);
  var blob = Utilities.newBlob(secretApiKeyBytes); 
  var secretApiKeyString = blob.getDataAsString(); // POTENTIAL ERROR HERE?

  var json = Utilities.jsonStringify(request); 

  var hash_digest = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, 
      nonce + json);

  var hmac_digest = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, 
      url + hash_digest, secretApiKeyString); // POTENTIAL ERROR HERE?

  var base64 = Utilities.base64Encode(hmac_digest);

  return base64;
}

When sending the signature as part of my request to the server, I always get the error message from the server: Invalid Key.

BTW: This is the API which I would like to use in JavaScript: Kraken API

I would appreciate any hint or suggestions very much!!

like image 879
AlexR Avatar asked Apr 12 '14 16:04

AlexR


People also ask

Can I use node JS in Google Apps Script?

We're excited to announce Apps Script is now supported by the V8 runtime that powers Chrome and Node. js.

Can I use node js code in JavaScript?

Node.js allows you to run JavaScript on the server.

Is Appscript same as JavaScript?

TypeScript is an object-oriented programming language developed by Microsoft Corporation, whereas JavaScript is the programming language for the web. TypeScript is an open-source language to build large-scale web apps, whereas JavaScript is a server-side programming language that helps to develop interactive web pages.

What version of JavaScript is Apps Script?

It is based on JavaScript 1.6, but also includes some portions of 1.7 and 1.8 and a subset of the ECMAScript 5 API. Apps Script projects run server-side on Google's infrastructure.


2 Answers

Solution:

Use jsSHA (https://github.com/Caligatio/jsSHA/) rather than Google App Script's functions. Create a new "jsSHA.gs" code file in Google App Script and copy/past in all the jsSHA optimised .js files from github.

function getKrakenSignature (path, postdata, nonce) {
  var sha256obj = new jsSHA ("SHA-256", "BYTES");
  sha256obj.update (nonce + postdata);
  var hash_digest = sha256obj.getHash ("BYTES");

  var sha512obj = new jsSHA ("SHA-512", "BYTES");
  sha512obj.setHMACKey (api_key_private, "B64");
  sha512obj.update (path);
  sha512obj.update (hash_digest);
  return sha512obj.getHMAC ("B64");
}

function getKrakenBalance () {
  var path = "/0/private/Balance";
  var nonce = new Date () * 1000;
  var postdata = "nonce=" + nonce;

  var signature = getKrakenSignature (path, postdata, nonce);

  var url = api_url + path;
  var options = {
    method: 'post',
    headers: {
      'API-Key': api_key_public,
      'API-Sign': signature
    },
    payload: postdata
  };

  var response = UrlFetchApp.fetch (url, options);

  // ERROR handling

  return response.getContentText ();
}
like image 154
user8070406 Avatar answered Sep 28 '22 14:09

user8070406


One problem is that querystring.stringify is not the same as Utilities.jsonStringify (which, FYI, is deprecated in favor of JSON.stringify).

I believe that this will be equivalent:

function queryStringify(obj) {
    var params = [];
    for(var key in obj) {
        if(Object.hasOwnProperty(key)) {
           if(typeof key === 'string') {
               params.push([key, obj[key]]);
           } else {
               obj[key].forEach(function(val) {
                   params.push([key, val]);
               });
           }
        }
    }
    return params.map(function(param) {
        return encodeURIComponent(param[0]) + '=' + encodeURIComponent(param[1]);
    }).join('&');
}

Though I am not sure if that is the reason you are seeing your error.

like image 24
Paul Draper Avatar answered Sep 28 '22 16:09

Paul Draper