3

I'm trying to connect my Google Sheet to Coinbase API using apps script. When I try to use the authentication with my keys, I keep getting the same error:

{"errors":[{"id":"authentication_error","message":"invalid timestamp"}]}

(Code 401).

I try to check the time difference between my request and Coinbase server (to see if it is more than 30 seconds) and it doesn't. (1589465439 (mine) / 1589465464 (server)).

My code:

var timestamp = Math.floor(Date.now() / 1000) + 15;

Logger.log(timestamp);

var req = {
  method: 'GET',
  path: '/v2/accounts',
  body: ''
};

var message = timestamp + req.method + req.path + req.body;
var secret = Utilities.base64Decode(apiKey);
secret = Utilities.newBlob(secret).getDataAsString();

//create a hexedecimal encoded SHA256 signature of the message
var hmac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, message, secret);
var signature = Utilities.base64Encode(hmac);

Logger.log(signature);

var signatureStr = '';
for (i = 0; i < signature.length; i++) {
  var byte = signature[i];
  if (byte < 0)
    byte += 256;
  var byteStr = byte.toString(16);
  // Ensure we have 2 chars in our byte, pad with 0
  if (byteStr.length == 1) byteStr = '0' + byteStr;
  signatureStr += byteStr;
}

Logger.log(signatureStr);

var options = {
  baseUrl: 'https://api.coinbase.com/',
  url: req.path,
  method: req.method,
  headers: {
    'CB-ACCESS-SIGN': signatureStr,
    'CB-ACCESS-TIMESTAMP': timestamp,
    'CB-ACCESS-KEY': apiKey
  }
};


var response = UrlFetchApp.fetch("https://api.coinbase.com/v2/accounts", options);
double-beep
  • 5,031
  • 17
  • 33
  • 41
rmachado
  • 31
  • 2

1 Answers1

0

This is an old question, but in case it's still unsolved, I see a few changes that will fix this. I ran into a similar issue and had to solve it.

  1. You should have 2 keys total (1 API key, 1 secret Key). Secret key is a separate key that comes from Coinbase, and is not a decoded variant of the API access key. It does not need explicit decoding.
  2. Where you're passing timestamp as a header -> convert that value to a string to fix the timestamp error.
 headers: {
       'CB-ACCESS-SIGN': signatureStr,
       'CB-ACCESS-TIMESTAMP': timestamp.toString(),
       'CB-ACCESS-KEY': apiKey
    }
  1. You can collapse the hmac and signature variables into this one liner before converting to hex.
 let signature = Utilities.computeHmacSha256Signature(message, secret);

These 3 changes make your code start to work with my keys.

randalv
  • 900
  • 9
  • 19