Firmar una llamada a la API de Coinbase Pro con Google Apps Script
Me estoy volviendo loco tratando de enviar mi primera llamada API a Coinbase Pro usando Google Apps Script. En node.js es bastante fácil (https://docs.pro.coinbase.com/#signing-a-message) pero hacer lo mismo con los scripts de Google es volver una y otra vez "Firma no válida".
Este es el código que estoy usando:
function GetMyAccounts () {
var globalvars_CB = {
'apikey' : 'f7d20a*******18c',
'secret' : '******pIIitRbWCv9N/mMWaR*****mGQMuI+m/vSbU1zuh5U6WFiFw==',
'passphrase' : 'ceacdsewfcsa',
'uri' : 'https://api.pro.coinbase.com'
}
var requestPath = '/accounts';
var timestamp = Math.floor(Date.now() / 1000);
var options = {
'method' : 'GET',
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : SignAPICall(globalvars_CB.secret, timestamp, 'GET', requestPath, ''),
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
Logger.log(responseJson);
}
function SignAPICall(secret, timestamp, method, requestPath, body) {
var what = (timestamp + method + requestPath + body);
var decodedsecret = Utilities.base64Decode(secret).toString();
var hmac = Utilities.computeHmacSha256Signature(what, decodedsecret);
hmac = Utilities.base64Encode(hmac);
return (hmac);
}
Realmente necesito ayuda :-) - ¡Gracias!
Respuestas
En su script, supone que los encabezados de su solicitud, excepto el valor de CB-ACCESS-SIGNy el punto final, son correctos. Tenga cuidado con esto.
Punto de modificación:
- En el caso de
Utilities.base64Decode(secret).toString(), la matriz se convierte en la cadena. Creo que esta podría ser la razón de su problema.
Cuando se refleja el punto anterior, se vuelve como sigue.
Guión modificado:
En este caso, la función SignAPICallse modifica.
function SignAPICall(secret, timestamp, method, requestPath, body) {
var what = (timestamp + method + requestPath + body);
var decodedsecret = Utilities.base64Decode(secret); // Modified
var res = Utilities.computeHmacSha256Signature(Utilities.newBlob(what).getBytes(), decodedsecret); // Modified
hmac = Utilities.base64Encode(res);
return hmac;
}
- En este caso,
valueykeydecomputeHmacSha256Signature(value, key)son la matriz de bytes.
Nota:
- Cuando verifiqué el script modificado anterior comparando los scripts de muestra del documento oficial , pude confirmar que se puede obtener el mismo resultado.
- Desafortunadamente, no puedo probar la solicitud a la API utilizando el script modificado anterior, mientras que puedo confirmar que la misma firma del script de muestra en el documento oficial se recupera del script modificado anterior. Por lo tanto, pruebe la solicitud en su entorno. Cuando solicitó a la API utilizando la secuencia de comandos modificada anterior, cuando se produzca un error, verifique los encabezados de la solicitud, el punto final y el secreto nuevamente.
Referencias:
- Firmar un mensaje
- base64Decode (codificado)
- computeHmacSha256Signature (valor, clave)
Finalmente encontré la solución. Fue un problema con el tipo de datos que envié a "Utilities.computeHmacSha256Signature". En el código puede encontrar que la función funciona bien.
function SignAndCallAPI(method, requestPath, body) {
var timestamp = Math.floor(Date.now() / 1000).toString();
var what = Utilities.base64Decode(Utilities.base64Encode(timestamp + method + requestPath + body));
var decodedsecret = Utilities.base64Decode(globalvars_CB.secret);
var hmac = Utilities.base64Encode(Utilities.computeHmacSha256Signature(what, decodedsecret));
var options = {
'method' : method,
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : hmac,
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
Logger.log(responseJson);
return(responseJson);
}