var onode = require('./node'), express = require('express'), settings = require('./settings'); module.exports = function() { function express_app() { var app = express(); app.get('/{*splat}', hasAccess, function(req, res) { var method = req.path.substring(1, req.path.length); if ('undefined' != typeof requires_passphrase[method]) { if (wallet_passphrase) client.walletPassphrase(wallet_passphrase, 10); else res.send('A wallet passphrase is needed and has not been set.'); } const query_parameters = req.query; let params = []; Object.keys(query_parameters).forEach(function(parameter) { let param = query_parameters[parameter]; if (!isNaN(param)) param = parseFloat(param); params.push(param); }); var command = []; switch (method) { case 'getnetworkhashps': case 'getmininginfo': case 'getdifficulty': case 'getconnectioncount': case 'getblockcount': case 'getblockhash': case 'getblock': case 'getrawtransaction': case 'getsupply': case 'getinfo': case 'getblockchaininfo': case 'getpeerinfo': case 'gettxoutsetinfo': case 'getmaxmoney': case 'getmaxvote': case 'getvote': case 'getphase': case 'getreward': case 'getnextrewardestimate': case 'getnextrewardwhenstr': case 'getvotelist': case 'getmasternodecount': case 'getmasternodelist': case 'verifymessage': case 'sendmany': command = specialApiCase(method, query_parameters); break; default: command = [{ method: method, params: params }]; break; } client.cmd(command, function(err, response) { if (err) { console.log(err); res.send(`${settings.localization.ex_error}: ${settings.localization.check_console}`); } else { if (typeof response === 'object') res.json(response); else { res.setHeader('content-type', 'text/plain'); res.end(response.toString()); } } }); }); function hasAccess(req, res, next) { var method = req.path.substring(1, req.path.length); var method_enabled = false; // check if this is a "normal" api method if (settings.api_page.public_apis.rpc[method] != null) { // check the enabled property of this normal method method_enabled = settings.api_page.public_apis.rpc[method].enabled; } else { // look for this method in the list of blockchain specific features Object.keys(settings.blockchain_specific).forEach(function(key, index, map) { // check if this feature is enabled and has a definition for this api cmd if (settings.blockchain_specific[key].enabled == true && settings.blockchain_specific[key]['public_apis'] != null && settings.blockchain_specific[key]['public_apis'][method] != null) { // check the enabled properly of this blockchain specific method method_enabled = settings.blockchain_specific[key]['public_apis'][method].enabled; } }); } // only show disabled msg for outside calls. internal calls should always go through if ((!settings.api_page.enabled || method_enabled == null || !method_enabled) && req.headers.host.indexOf('127.0.0.1') == -1) res.end(settings.localization.method_disabled); else if (method == 'getnetworkhashps' && !settings.shared_pages.show_hashrate) { // getnetworkhashps requires show_hashrate to be enabled or else hashrate cannot be returned res.end('-'); } else { if (accesslist.type == 'all') return next(); if ('undefined' == typeof accesslist[method]) { if (accesslist.type == 'only') res.end('This method is restricted'); else return next(); } else { if (accesslist[method] == true) return next(); else res.end('This method is restricted'); } } } function prepareRpcCommand(cmd, addParams) { var method_name = ''; var params = addParams || []; // Check for null/blank string if (cmd != null && cmd.trim() != '') { // Split cmd by spaces var split = cmd.split(' '); for (i=0; i -1) param = param.replace(' ', '+'); params.push(param); } }); var cmd = prepareRpcCommand(settings.api_cmds.verifymessage, params); method_name = cmd.method; params = cmd.parameters; break; case 'sendmany': var after_account = false; var before_min_conf = true; var address_info = {}; Object.keys(query_parameters).forEach(function(parameter) { if (parameter == 'minconf') { before_min_conf = false; params.push(address_info); } let param = query_parameters[parameter]; if (!isNaN(param)) param = parseFloat(param); if (after_account && before_min_conf) address_info[parameter] = param; else params.push(param); if (parameter == 'account') after_account = true; }); if (before_min_conf) params.push(address_info); break; } return [{ method: method_name, params: params }]; } return app; }; var accesslist = {}; var client = {}; var wallet_passphrase = null; var requires_passphrase = { 'dumpprivkey': true, 'importprivkey': true, 'keypoolrefill': true, 'sendfrom': true, 'sendmany': true, 'sendtoaddress': true, 'signmessage': true, 'signrawtransaction': true }; accesslist.type = 'all'; function setAccess(type, access_list) { // reset accesslist = {}; accesslist.type = type; if (type == "only") { for (i = 0; i < access_list.length; i++) accesslist[access_list[i]] = true; } if (type == "restrict") { for (i = 0; i < access_list.length; i++) accesslist[access_list[i]] = false; } // default is for security reasons. Prevents accidental theft of coins/attack if (type == 'default-safe') { var restrict_list = ['dumpprivkey', 'walletpassphrasechange', 'stop']; accesslist.type = 'restrict'; for (i = 0; i < restrict_list.length; i++) accesslist[restrict_list[i]] = false; } if (type == 'read-only') { var restrict_list = ['addmultisigaddress', 'addnode', 'backupwallet', 'createmultisig', 'createrawtransaction', 'encryptwallet', 'importprivkey', 'keypoolrefill', 'lockunspent', 'move', 'sendfrom', 'sendmany', 'sendrawtransaction', 'sendtoaddress', 'setaccount', 'setgenerate', 'settxfee', 'signmessage', 'signrawtransaction', 'stop', 'submitblock', 'walletlock', 'walletpassphrasechange']; accesslist.type = 'restrict'; for (i = 0; i < restrict_list.length; i++) accesslist[restrict_list[i]] = false; } }; function setWalletDetails(details) { if ('undefined' == typeof details.rpc) client = new onode.Client(details); else client = details; }; function setWalletPassphrase(passphrase) { wallet_passphrase = passphrase; }; return { app: express_app(), setAccess: setAccess, setWalletDetails: setWalletDetails, setWalletPassphrase: setWalletPassphrase } }();