-
-
Save marianzange/354edb2f74e88491f6fa520ea8beb2d8 to your computer and use it in GitHub Desktop.
// Computes the HMAC for requests sent to the Coinbase Pro API. | |
// | |
// - Add the following code as Postman pre-request script | |
// - Adapt the getPatch function an the variable names according to your needs | |
const timestamp = Date.now() / 1000; | |
function getPath(url) { | |
// URL path regex works only if your URLs look like this: {{api_url}}/resource | |
// If you use hardcoded URLs or any other scheme, adapt the regex pattern! | |
const matches = url.match(/.+?(\/.+?)(?:#|\?|$)/); | |
return (matches && matches.length > 1) ? matches[1] : ''; | |
} | |
function computeSignature(request) { | |
const data = request.data; | |
const method = request.method; | |
const path = getPath(request.url); | |
const body = (method === 'GET' || !data) ? '' : JSON.stringify(data); | |
const message = timestamp + method + path + body; | |
const key = CryptoJS.enc.Base64.parse(pm.variables.get('CB-SECRET')); | |
const hash = CryptoJS.HmacSHA256(message, key).toString(CryptoJS.enc.Base64); | |
return hash; | |
} | |
postman.setEnvironmentVariable('hmacSignature', computeSignature(request)); | |
postman.setEnvironmentVariable('hmacTimestamp', timestamp) |
Interesting. I was reading the non-Pro documentation of Coinbase API. Thanks for informing me!
@amgreen2 Try setting the API endpoint as a Postman variable such as {{api_url}}
or adapt the regex to your needs. The regex in the code snippet is a bit crappy.
I am also getting same issue that what amgreen2 is facing.
"Invalid signature"
I was having the same "Invalid API Key" error, but I had overlooked a couple things while struggling to fix the problem. Everything is now working, and here were the troubleshooting steps that I did:
- Add a collection variable: click on the "..." next to your collection in the left sidebar --> variables. Add api_url as variable and "https://api.pro.coinbase.com" as initial value.
- Change your request URL to be: {{api_url}}/accounts (or whatever API endpoint you're targeting).
- Make sure your CB-ACCESS-KEY is copied into both the "pm.environment" and "pm.request.headers.upsert" lines. I had overlooked updating pm.request.headers.upsert.
- Make sure your CB-ACCESS-PASSPHRASE is copied into both the "pm.environment" and "pm.request.headers.upsert" lines.
Everything should work fine after this. Thanks to everyone in this thread for your help!
Here's how I got it working for the non-pro API.
CB-SECRET
is set as an environment variable, the rest I've just put directly in my request.
- Uses
Math.floor
instead ofceil
simply because that's the example given by Coinbase - Passes the HMAC the secret as a string rather than base64 parsing it
- Wants a hex digest rather than base64
- No need for regex for the path, postman provides an array:
pm.request.url.path
(needs joining with/
)
const timestamp = Math.floor(Date.now() / 1000);
console.log(timestamp);
function computeSignature(request) {
const data = request.data;
const method = request.method;
const path = "/" + pm.request.url.path.join("/");
const body = (method === 'GET' || !data) ? '' : JSON.stringify(data);
const message = timestamp + method + path + body;
const key = pm.variables.get('CB-SECRET');
const hash = CryptoJS.HmacSHA256(message, key).toString(CryptoJS.enc.Hex);
console.log("Message: " + message + " HMAC: " + hash);
return hash;
}
pm.environment.set('CB-ACCESS-SIGN', computeSignature(request));
pm.environment.set('CB-ACCESS-TIMESTAMP', timestamp);
This works for me. I had to change this line:
const body = (method === 'GET' || !data) ? '' : JSON.stringify(data);
to
const body = (method === 'GET' || !data) ? '' : data;
Script:
const timestamp = Date.now() / 1000;
pm.environment.set("CB-SECRET", "your-secret");
function computeSignature(request) {
const data = request.data;
const method = request.method;
const path = "/" + pm.request.url.path.join("/");
const body = (method === 'GET' || !data) ? '' : data;
const message = timestamp + method + path + body;
const key = CryptoJS.enc.Base64.parse(pm.variables.get('CB-SECRET'));
const hash = CryptoJS.HmacSHA256(message, key).toString(CryptoJS.enc.Base64);
return hash;
}
pm.environment.set('CB-ACCESS-SIGN', computeSignature(request));
pm.environment.set('CB-ACCESS-TIMESTAMP', timestamp);
Why are you setting CB-ACCESS-PASSPHRASE? I can't see that this is mentioned in their API documentation?