Assine uma chamada para Coinbase Pro API com Google Apps Script
Estou ficando louco tentando enviar minha primeira chamada de API para Coinbase Pro usando o Google Apps Script. Em node.js é muito fácil (https://docs.pro.coinbase.com/#signing-a-message), mas fazer o mesmo com os scripts do Google é apenas retornar "Assinatura inválida" repetidamente.
Este é o código que estou 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);
}
Eu realmente preciso de ajuda :-) - Obrigado!
Respostas
Em seu script, ele supõe que os cabeçalhos de sua solicitação, exceto para o valor de CB-ACCESS-SIGNe endpoint, estão corretos. Por favor, tome cuidado com isso.
Ponto de modificação:
- No caso de
Utilities.base64Decode(secret).toString(), a matriz é convertida em string. Acho que esse pode ser o motivo do seu problema.
Quando o ponto acima é refletido, ele se torna o seguinte.
Script modificado:
Nesse caso, a função SignAPICallé modificada.
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;
}
- Nesse caso,
valueekeydecomputeHmacSha256Signature(value, key)são a matriz de bytes.
Nota:
- Quando verifiquei o script modificado acima, comparando os scripts de amostra do documento oficial , pude confirmar que o mesmo resultado pode ser obtido.
- Infelizmente, não posso testar a solicitação à API usando o script modificado acima, enquanto posso confirmar que a mesma assinatura do script de amostra no documento oficial foi recuperada do script modificado acima. Portanto, teste a solicitação em seu ambiente. Quando você solicitou à API usando o script modificado acima, quando ocorrer um erro, verifique os cabeçalhos da solicitação, o endpoint e o segredo novamente.
Referências:
- Assinando uma Mensagem
- base64Decode (codificado)
- computeHmacSha256Signature (valor, chave)
Finalmente encontrei a solução para isso. Era um problema com o tipo de dados que enviei para "Utilities.computeHmacSha256Signature". No código, você pode encontrar a função funcionando bem.
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);
}