as the title says…
I got the example posted by @larry.kubin for the GET request, which looks like this:
var crypto = require('crypto');
const https = require('https');
// current unix timestamp in seconds (note Date.now() returns milliseconds)
var cb_access_timestamp = Date.now() / 1000;
// obtained API key, secret, and passphrase from https://pro.coinbase.com/profile/api
var cb_access_passphrase = '';
var cb_api_key = '';
var secret = '';
var path = '/orders?status=done'; // fetching my completed orders
var body = ''; // body is empty in this case
var method = 'GET';
// create the prehash string by concatenating required parts
var message = cb_access_timestamp + method + path + body;
// decode the base64 secret
// NOTE: added .from() to address DeprecationWarning: Buffer() is deprecated
var key = Buffer.from(secret, 'base64');
// create a sha256 hmac with the secret
var hmac = crypto.createHmac('sha256', key);
// sign the require message with the hmac, and finally base64 encode the result
var cb_access_sign = hmac.update(message).digest('base64');
const options = {
hostname: 'api.exchange.coinbase.com',
port: 443,
path: path,
method: method,
headers: {
'Content-Type': 'application/json',
'Content-Length': 0,
'User-Agent': 'my-app',
'CB-ACCESS-KEY': cb_api_key,
'CB-ACCESS-PASSPHRASE': cb_access_passphrase,
'CB-ACCESS-SIGN': cb_access_sign,
'CB-ACCESS-TIMESTAMP': cb_access_timestamp
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
I got my api key, passphrase and secret stored in a .env file
Everything works great. If I do a manual transaction I can use this script and query the filled orders.
Returns status 200
And all the details about the transaction.
Furthermore, I wanted to create a similar request for posting a transaction.
Changed the method to POST, built a body{} this time and used the same methods as in the GET request.
However, I am getting:
statusCode: 401
{"message":"invalid signature"}
If I leave the body empty like in the GET request, I am getting:
statusCode: 400
{"message":"product_id is not a valid product"}
which tells me that the request is going through, but it is expecting parameters for the body.
Below is my entire code that I have tried to put together for this task. I have used both the crypto package recommended in the api docs, as well as the CryptoJS package suggested by @shurr .
Both scenarios return the same status code:
statusCode: 401
{"message":"invalid signature"}
Here’s my full code:
const config = require('dotenv').config();
var crypto = require('crypto');
//var CryptoJS = require('crypto-js');
const https = require('https');
// current unix timestamp in seconds (note Date.now() returns milliseconds)
var cb_access_timestamp = Date.now() / 1000;
// obtained API key, secret, and passphrase from https://pro.coinbase.com/profile/api
var cb_access_passphrase = process.env.cb_access_passphrase;
var cb_api_key = process.env.cb_api_key;
var cb_secret = process.env.cb_secret;
var path = '/orders';
//var path = '/trade';
//var body = '';
var body = JSON.stringify({
"product_id":"BTC-USD",
"side":"buy",
"type":"limit",
"size":"0.0001",
"price":"44415.51"
});
var method = 'POST';
// create the prehash string by concatenating required parts
var message = cb_access_timestamp + method + path + body;
var key = Buffer.from(cb_secret, 'base64');
var hmac = crypto.createHmac('sha256', key);
var sign = hmac.update(message).digest('base64');
//var key = CryptoJS.enc.Base64.parse(cb_secret);
//var hash = CryptoJS.HmacSHA256(message, key);
//var sign = hash.toString(CryptoJS.enc.Base64);
const options = {
hostname: 'api.exchange.coinbase.com',
//hostname: 'api.pro.coinbase.com',
port: 443,
path: path,
method: method,
headers: {
'Content-Type': 'application/json',
'Content-Length': 0,
'User-Agent': 'MyTradingBot',
'CB-ACCESS-KEY': cb_api_key,
'CB-ACCESS-PASSPHRASE': cb_access_passphrase,
'CB-ACCESS-SIGN': sign,
'CB-ACCESS-TIMESTAMP': cb_access_timestamp
}
}
const req = https.request(options, res => {
console.log(message);
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
Apologies for the lengthy post, but I was trying to describe my issue as detailed as possible.
Any help is greatly appreciated.