Coinbase.com API + Secret HMAC authentication in node.js - javascript

I have read some node.js docs (crypto, https) and try to use coinbase.com API in my coin.js file to get bitcoin balance of my account. But there are still some errors. When I run this code with correct key and secret values I get: [SyntaxError: Unexpected end of input]
error parsing json.
Thank you in advance for your responses.
var async = require('async');
var http = require('http');
var https = require('https');
var crypto = require('crypto');
var key = 'some_key_from_coinbasecom';
var secret = 'some_secret_from_coinbasecom';
var nonce = String(Date.now() * 1e6);
var url = 'https://coinbase.com/api/v1/account/balance';
var message = nonce + url + ''; // if body is not empty then put here body
var signature = crypto.createHmac('sha256', secret).update(message).digest('hex');
var options = {
method: 'GET',
path: '/api/v1/account/balance',
ACCESS_KEY: key,
ACCESS_SIGNATURE: signature,
ACCESS_NONCE: nonce,
hostname: 'coinbase.com'
};
https.get(options, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
try {
var balance_json = JSON.parse(body);
if (balance_json.error) {
console.log(balance_json.error);
return;
} else {
// Here I have expected to get my balance json data
console.log(balance_json);
}
} catch (error) {
console.log(error);
console.log("error parsing json");
}
});
res.on('error', function(e) {
console.log(e);
console.log("error syncing balance");
});
});
I have tried another implementation:
https.get(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
}).on('error', function(e) {
console.error(e);
});
There are results of this code (I have hidden some strings by XXXXXXXXXX):
statusCode: 401
headers: { server: 'cloudflare-nginx',
date: 'Wed, 14 May 2014 17:21:09 GMT',
'content-type': 'text/html; charset=utf-8',
'transfer-encoding': 'chunked',
connection: 'keep-alive',
'set-cookie':
[ '__cfduid=deacXXXXXXXXXXXXXXXXXXXXXXXXXXXX1400088069337; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.coinbase.com; HttpOnly',
'request_method=GET; path=/; secure' ],
'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
expires: '-1',
pragma: 'no-cache',
status: '401 Unauthorized',
'strict-transport-security': 'max-age=31536000',
vary: 'Accept-Encoding',
'www-authenticate': 'Bearer realm="Doorkeeper", error="invalid_token", error_description="The access token is invalid"',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-rack-cache': 'miss',
'x-request-id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'x-runtime': '0.031708',
'x-ua-compatible': 'IE=Edge,chrome=1',
'cf-ray': 'XXXXXXXXXXXXXXXXXXXXXXXXXX-LHR' }

From https://coinbase.com/docs/api/authentication:
The ACCESS_KEY header is simply your API key.
The ACCESS_SIGNATURE header ...
... ACCESS_NONCE header in your requests ...
In http://nodejs.org/api/https.html document you can find that headers are put into specific options.headers objects
Try to set options this way:
var options = {
method: 'GET',
path: '/api/v1/account/balance',
hostname: 'coinbase.com',
headers: {
ACCESS_KEY: key,
ACCESS_SIGNATURE: signature,
ACCESS_NONCE: nonce,
}
};

Related

how to invoke a windows process using nodejs

I have a process running on my machine at port 8123, how can I invoke or call a windows process using nodejs..?
I tried using request
let bytes = new Buffer(xml, 'ascii')
var options = {
url: "https://" + host + ":" + port,
headers: {
'Content-Type': 'text/xml',
'Content-Length': Buffer.byteLength(bytes),
'Connection': 'keep-alive'
},
method: 'POST',
requestCert: true,
agent: false,
rejectUnauthorized: false
};
function callback(error, response, body) {
if (error) cb(error)
else cb(response)
}
request(options, callback);
but its returning with error code ECONNRESET and message assocket hang up
also tried HTTP like this
var options = {
host: '127.0.0.1',
port: port,
method: 'POST',
agent: false,
headers: {
'Content-Length': Buffer.byteLength(bytes),
'Content-Type': 'text/xml',
'Connection': 'keep-alive'
},
};
var req = http.request(options, function (res) {
res.on('data', function (chunk) {
cb('BODY: ' + chunk);
});
});
req.on('error', function (e) {
cb('problem with request: ' + e.message);
});
req.end();
this also returns the same error

Node HTTP POST Request to Netatmo

I'm trying to do a http POST request to my Netatmo weatherstation's cloud using NodeJS. It really needs to be http post and not use the node's 'request' module, because I indend to use it in AWS Lambda and that module is currently not supported there.
Whatever I try, I get the dreaded {"error":"invalid_request"} with result 400.. I am at a loss as to what the problem is.
Here's my snippet:
var querystring = require('querystring');
var https = require('https');
function getNetatmoData(callback, cardTitle){
var sessionAttributes = {};
var shouldEndSession = false;
cardTitle = "Welcome";
var speechOutput ="";
var repromptText ="";
console.log("sending request to netatmo...")
var payload = querystring.stringify({
'grant_type' : 'password',
'client_id' : clientId,
'client_secret' : clientSecret,
'username' : userId,
'password' : pass,
'scope' : 'read_station'
});
var options = {
host: 'api.netatmo.net',
path: '/oauth2/token',
method: 'POST',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(payload)
};
//console.log('making request with data: ',options);
var req = https.request(options, function(res) {
res.setEncoding('utf8');
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
res.on('error', function (chunk) {
console.log('Error: '+chunk);
});
res.on('end', function() {
speechOutput = "Request successfuly processed."
console.log(speechOutput);
repromptText = ""
//callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
});
});
req.on('error', function(e){console.log('error: '+e)});
req.write(payload);
req.end();
}
Here's Cloud9's console log:
Debugger listening on port 15454
sending request to netatmo...
statusCode: 400
headers: { server: 'nginx',
date: 'Tue, 24 Nov 2015 19:30:25 GMT',
'content-type': 'application/json',
'content-length': '27',
connection: 'close',
'cache-control': 'no-store',
'access-control-allow-origin': '*' }
body: {"error":"invalid_request"}
Request successfuly processed.
Aarrgh.. I oversaw something. Apparently, the headers need to be set in the options when making the request. It is in the headers variable that the Content-Type and Content-Length are set.
Without further adue, here is the correct working of the options variable :
var options = {
host: 'api.netatmo.net',
path: '/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(payload)
}
};

How to send form data in node.js

I am able to get to the server but unable to post my form data.
How should I post the form data with the https request?
I am using form-data library for form-data, and https request for post call.
When I run the following code, I am able to reach the service, but the service gives a response saying that the form data is not submitted.
var https = require('https');
var FormData = require('form-data');
//var querystring = require('querystring');
var fs = require('fs');
var form = new FormData();
connect();
function connect() {
username = "wr";
password = "45!"
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var options = {
hostname: 'trans/sun.com',
port: 443,
path: '/transfer/upload-v1/file',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Authorization': auth,
'Content-Type': 'application/json',
//'Content-Length': postData.length
}
};
form.append('deviceId', '2612');
form.append('compressionType', 'Z');
form.append('file', fs.createReadStream('/Mybugs.txt'));
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
//console.log("headers: ", res.headers);
res.setEncoding('utf8');
res.on('data', function(d) {
console.log(d)
});
});
req.write(form + '');
req.end();
req.on('error', function(e) {
console.error(e);
});
}
You never link your form to your request. Check this example provided with the form-data documentation
var http = require('http');
var request = http.request({
method: 'post',
host: 'example.org',
path: '/upload',
headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
console.log(res.statusCode);
});

Unable to POST data in node.js script

I am requesting a https post method with a data but my data is not going with the request and thats why service is giving error, so how can i change my code so that it will get to the server , here is my code
var https = require('https');
var querystring = require('querystring');
connect();
function connect(){
var postData = querystring.stringify({
'application': 'QF2',
'client': 'COMMAND',
'userId': 'devicexxx',
'operation': 'at-cmd',
'payload': 'dfdfdfdf',
'messageId': '123e454567-e89b-12d3-a456-42665544'
});
var options = {
hostname: 'cus.inco.com',
port: 443,
path: '/portal/action/dev',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
//console.log("headers: ", res.headers);
res.setEncoding('utf8');
res.on('data', function(d) {
console.log(d)
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
}
You need to write() your POST data before you end the request.
req.write(postData);
req.end();

Steps to send a https request to a rest service in Node js

What are the steps to send a https request in node js to a rest service?
I have an api exposed like (Original link not working...)
How to pass the request and what are the options I need to give for this API like
host, port, path and method?
just use the core https module with the https.request function. Example for a POST request (GET would be similar):
var https = require('https');
var options = {
host: 'www.google.com',
port: 443,
path: '/upload',
method: 'POST'
};
var req = https.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
The easiest way is to use the request module.
request('https://example.com/url?a=b', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
Note if you are using https.request do not directly use the body from res.on('data',... This will fail if you have a large data coming in chunks. So you need to concatenate all the data and then process the response in res.on('end'. Example -
var options = {
hostname: "www.google.com",
port: 443,
path: "/upload",
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(post_data)
}
};
//change to http for local testing
var req = https.request(options, function (res) {
res.setEncoding('utf8');
var body = '';
res.on('data', function (chunk) {
body = body + chunk;
});
res.on('end',function(){
console.log("Body :" + body);
if (res.statusCode !== 200) {
callback("Api call failed with response code " + res.statusCode);
} else {
callback(null);
}
});
});
req.on('error', function (e) {
console.log("Error : " + e.message);
callback(e);
});
// write data to request body
req.write(post_data);
req.end();
Using the request module solved the issue.
// Include the request library for Node.js
var request = require('request');
// Basic Authentication credentials
var username = "vinod";
var password = "12345";
var authenticationHeader = "Basic " + new Buffer(username + ":" + password).toString("base64");
request(
{
url : "https://133-70-97-54-43.sample.com/feedSample/Query_Status_View/Query_Status/Output1?STATUS=Joined%20school",
headers : { "Authorization" : authenticationHeader }
},
function (error, response, body) {
console.log(body); } );
Since there isn't any example with a ´GET´ method here is one.
The catch is that the path in the options Object should be set to '/' in order to send the request correctly
const https = require('https')
const options = {
hostname: 'www.google.com',
port: 443,
path: '/',
method: 'GET',
headers: {
'Accept': 'plain/html',
'Accept-Encoding': '*',
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`);
console.log('headers:', res.headers);
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(`Error on Get Request --> ${error}`)
})
req.end()
The example using 'GET' method is good but it can also be used with constant variables in TypeScript/Node.js setup. If that's the case, the functions on('error') and end() have to be defined outside of the https.request function.
const https = require('https')
const options = {
hostname: 'www.google.com',
port: 443,
path: '/',
method: 'GET',
headers: {
'Accept': 'plain/html',
'Accept-Encoding': '*',
}
}
const request = https.request(options, res => {
const callback = (data: string) => {
process.stdout.write(`response data: ${data}`);
}
res.on('data', callback)
})
request.on('error', error => {
console.error(`Error on Get Request --> ${error}`)
})
request.end()

Categories