Firma una chiamata all'API Coinbase Pro con Google Apps Script
Sto impazzendo cercando di inviare la mia prima chiamata API a Coinbase Pro utilizzando Google Apps Script. In node.js è abbastanza semplice (https://docs.pro.coinbase.com/#signing-a-message) ma fare lo stesso con gli script di Google significa semplicemente restituire ancora e ancora "Firma non valida".
Questo è il codice che sto 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);
}
Ho davvero bisogno di aiuto :-) - Grazie!
Risposte
Nello script, si suppone che le intestazioni della richiesta, ad eccezione del valore di CB-ACCESS-SIGNe dell'endpoint, siano corrette. Per favore, stai attento.
Punto di modifica:
- Nel caso di
Utilities.base64Decode(secret).toString(), l'array viene convertito nella stringa. Penso che questo potrebbe essere il motivo del tuo problema.
Quando il punto sopra viene riflesso, diventa il seguente.
Script modificato:
In questo caso, la funzione SignAPICallviene modificata.
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;
}
- In questo caso,
valueekeyofcomputeHmacSha256Signature(value, key)sono l'array di byte.
Nota:
- Quando ho controllato lo script modificato sopra confrontando gli script di esempio del documento ufficiale , ho potuto confermare che è possibile ottenere lo stesso risultato.
- Sfortunatamente, non posso testare la richiesta all'API utilizzando lo script modificato sopra mentre posso confermare che la stessa firma dallo script di esempio nel documento ufficiale viene recuperata dallo script modificato sopra. Quindi prova la richiesta nel tuo ambiente. Quando hai richiesto all'API utilizzando lo script modificato sopra, quando si verifica un errore, controlla di nuovo le intestazioni della richiesta, l'endpoint e il segreto.
Riferimenti:
- Firmare un messaggio
- base64Decode (codificato)
- computeHmacSha256Signature (valore, chiave)
Finalmente ho trovato la soluzione. Era un problema con il tipo di dati che ho inviato a "Utilities.computeHmacSha256Signature". Nel codice puoi trovare la funzione che funziona bene.
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);
}