UNPKG

node-experiencepoints

Version:
196 lines (165 loc) 5.07 kB
var http = require('http') , https = require('https') var api = require('./commands') , errors = require('./errors') function Client(options) { this.opts = { host: 'localhost' , port: 28191 , method: 'POST' , user: '' , pass: '' , headers: { 'Host': 'localhost' , 'Authorization': '' } , passphrasecallback: null , https: false , ca: null } if (options) { this.set(options) } } Client.prototype = { invalid:function(command) { var args = Array.prototype.slice.call(arguments, 1) , fn = args.pop() if (typeof fn !== 'function') { fn = console.log } return fn(new Error('No such command "' + command + '"')) }, send:function(command) { var args = Array.prototype.slice.call(arguments, 1) , self = this , fn if (typeof args[args.length-1] === 'function') { fn = args.pop().bind(this) }else { fn = console.log } var rpcData = JSON.stringify({ id: new Date().getTime() , method: command.toLowerCase() , params: args }) var options = this.opts options.headers['Content-Length'] = rpcData.length var request; if (options.https === true){ request = https.request; } else{ request = http.request; } var req = request(options, function(res) { var data = '' res.setEncoding('utf8') res.on('data', function(chunk) { data += chunk }) res.on('end', function() { try { data = JSON.parse(data) }catch(exception) { var errMsg = res.statusCode !== 200 ? 'Invalid params ' + res.statusCode : 'Failed to parse JSON' errMsg += ' : '+JSON.stringify(data) return fn(new Error(errMsg)) } if (data.error) { if (data.error.code === errors.RPC_WALLET_UNLOCK_NEEDED && options.passphrasecallback) { return self.unlock(command, args, fn) } else { var err = new Error(JSON.stringify(data)) err.code = data.error.code return fn(err) } } fn(null, data.result !== null ? data.result : data) }) }) req.on('error', fn) req.end(rpcData) return this }, exec:function(command) { var func = api.isCommand(command) ? 'send' : 'invalid' return this[func].apply(this, arguments) }, auth:function(user, pass) { if (user && pass) { var authString = ('Basic ') + new Buffer(user+':'+pass).toString('base64') this.opts.headers['Authorization'] = authString } return this }, unlock:function(command, args, fn) { var self = this var retry = function(err) { if (err) { fn(err) } else { var sendargs = args.slice(); sendargs.unshift(command); sendargs.push(fn) self.send.apply(self, sendargs) } } this.opts.passphrasecallback(command, args, function(err, passphrase, timeout) { if (err) { fn(err) } else { self.send('walletpassphrase', passphrase, timeout, retry) } }) }, set:function(k, v) { var type = typeof(k); if (typeof(k) === 'object') { for (var key in k) { this.set(key, k[key]); }; return; }; var opts = this.opts; var k = k.toLowerCase(); if (opts.hasOwnProperty(k)) { opts[k] = v if (/^(user|pass)$/.test(k)) { this.auth(opts.user, opts.pass) }else if (k === 'host') { opts.headers['Host'] = v }else if (k === 'passphrasecallback' || k === 'https' || k === 'ca') { opts[k] = v } } return this; }, get:function(k) { //Special case for booleans if(this.opts[k] === false){ return false; }else { if(this.opts[k] !== false){ var opt = this.opts[k.toLowerCase()] } return opt; //new Error('No such option "'+k+'" exists'); } }, errors: errors } api.commands.forEach(function(command) { var cp = Client.prototype; var tlc = [command.toLowerCase()]; cp[command] = cp[tlc] = function() { cp.send.apply(this, tlc.concat(([]).slice.call(arguments))); }; }) module.exports = function(options) { return new Client(options) }