diff --git a/README.md b/README.md index 5452f52..cb155b7 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,31 @@ The Exor block explorer. This project is a fork of [Ciquidus Explorer](https://github.com/suprnurd/ciquidus) which is a fork of [Iquidus Explorer](https://github.com/iquidus/explorer). Shoutouts to both Luke Williams for the original code and Alan Rudolf for all the additional bonus featues which saved me tons of time! I'm only standing on the shoulders of giants. Thank you both!!! +### Features + +- Custom rpc/api command support which increases blockchain compatibility. Supported cmds: + - **getnetworkhashps:** Returns the estimated network hashes per second + - **getmininginfo:** Returns a json object containing mining-related information + - **getdifficulty:** Returns the proof-of-work difficulty as a multiple of the minimum difficulty + - **getconnectioncount:** Returns the number of connections to other nodes + - **getblockcount:** Returns the number of blocks in the longest blockchain + - **getblockhash:** Returns hash of block in best-block-chain at height provided + - **getblock:** Returns an object with information about the block + - **getrawtransaction:** Returns raw transaction data + - **getinfo:** Returns an object containing various state info + - **gettxoutsetinfo:** Returns an object with statistics about the unspent transaction output set + - **getsupply:** Returns the current money supply + - **getmaxmoney:** Returns the number of coins that will be produced in total + - **getmaxvote:** Returns the maximum allowed vote for the current phase of voting + - **getvote:** Returns the current block reward vote setting + - **getphase:** Returns the current voting phase name + - **getreward:** Returns the current block reward + - **getnextrewardestimate:** Returns an estimate for the next block reward based on the current state of decentralized voting + - **getnextrewardwhenstr:** Returns a string describing how long until the votes are tallied and the next block reward is computed + - **getvotelist:** Returns an object with details regarding the current vote list + - **getmasternodecount:** Returns a json object containing the total number of masternodes on the network + - **getmasternodelist:** Returns a json array containing status information for all masternodes on the network + ### See it in action - https://explorer.exor.io/ diff --git a/app.js b/app.js index 12f8182..fc51ec7 100644 --- a/app.js +++ b/app.js @@ -63,10 +63,10 @@ app.use(express.static(path.join(__dirname, 'public'))); // routes app.use('/api', nodeapi.app); app.use('/', routes); -app.use('/ext/getmoneysupply', function(req,res){ - lib.get_supply(function(supply){ +app.use('/ext/getmoneysupply', function(req,res) { + lib.get_supply(function(supply) { res.setHeader('content-type', 'text/plain'); - res.end(supply.toString()); + res.end((supply ? supply.toString() : '0')); }); }); @@ -119,12 +119,12 @@ app.use('/ext/gettx/:txid', function(req, res) { db.get_tx(txid, function(tx) { if (tx) { lib.get_blockcount(function(blockcount) { - res.send({ active: 'tx', tx: tx, confirmations: settings.confirmations, blockcount: blockcount}); + res.send({ active: 'tx', tx: tx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0)}); }); } else { lib.get_rawtransaction(txid, function(rtx) { - if (rtx.txid) { + if (rtx && rtx.txid) { lib.prepare_vin(rtx, function(vin) { lib.prepare_vout(rtx.vout, rtx.txid, vin, function(rvout, rvin) { lib.calculate_total(rvout, function(total){ @@ -150,7 +150,7 @@ app.use('/ext/gettx/:txid', function(req, res) { blockindex: rtx.blockheight, }; lib.get_blockcount(function(blockcount) { - res.send({ active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: blockcount}); + res.send({ active: 'tx', tx: utx, confirmations: settings.confirmations, blockcount: (blockcount ? blockcount : 0)}); }); } }); @@ -192,15 +192,15 @@ app.use('/ext/getcurrentprice', function(req,res){ }); }); -app.use('/ext/getbasicstats', function(req,res){ - lib.get_blockcount(function(blockcount){ - lib.get_supply(function(supply){ - db.get_stats(settings.coin, function (stats){ - lib.get_masternodecount(function(masternodestotal){ - eval('var p_ext = { "block_count": blockcount, "money_supply": supply, "last_price_'+settings.markets.exchange.toLowerCase()+'": stats.last_price, "last_price_usd": stats.last_usd_price, "masternode_count": masternodestotal.total }'); +app.use('/ext/getbasicstats', function(req,res) { + lib.get_blockcount(function(blockcount) { + lib.get_supply(function(supply) { + db.get_stats(settings.coin, function (stats) { + lib.get_masternodecount(function(masternodestotal) { + eval('var p_ext = { "block_count": (blockcount ? blockcount : 0), "money_supply": (supply ? supply : 0), "last_price_'+settings.markets.exchange.toLowerCase()+'": stats.last_price, "last_price_usd": stats.last_usd_price, "masternode_count": masternodestotal.total }'); res.send(p_ext); }); - }); + }); }); }); }); @@ -318,6 +318,7 @@ app.set('labels', settings.labels); app.set('homelink', settings.homelink); app.set('logoheight', settings.logoheight); app.set('burned_coins', settings.burned_coins); +app.set('api_cmds', settings.api_cmds); app.set('footer_height_desktop', settings.footer_height_desktop); app.set('footer_height_tablet', settings.footer_height_tablet); diff --git a/lib/database.js b/lib/database.js index c13c7da..8395ee1 100644 --- a/lib/database.js +++ b/lib/database.js @@ -116,7 +116,7 @@ function find_tx(txid, cb) { function save_tx(txid, blockheight, cb) { lib.get_rawtransaction(txid, function(tx){ - if (tx != 'There was an error. Check your console.') { + if (tx && tx != 'There was an error. Check your console.') { lib.prepare_vin(tx, function(vin) { lib.prepare_vout(tx.vout, txid, vin, ((typeof tx.vjoinsplit === 'undefined' || tx.vjoinsplit == null) ? [] : tx.vjoinsplit), function(vout, nvin) { lib.syncLoop(vin.length, function (loop) { @@ -680,14 +680,14 @@ module.exports = { }, function(){ console.log(newVotes); Heavy.updateOne({coin: coin}, { - lvote: vote, - reward: reward, - supply: supply, - cap: maxmoney, - estnext: estnext, - phase: phase, - maxvote: maxvote, - nextin: nextin, + lvote: (vote ? vote : 0), + reward: (reward ? reward : 0), + supply: (supply ? supply : 0), + cap: (maxmoney ? maxmoney : 0), + estnext: (estnext ? estnext : 0), + phase: (phase ? phase : 'N/A'), + maxvote: (maxvote ? maxvote : 0), + nextin: (nextin ? nextin : 'N/A'), votes: newVotes, }, function() { //console.log('address updated: %s', hash); @@ -765,8 +765,8 @@ module.exports = { Stats.updateOne({coin: coin}, { coin: coin, count : count, - supply: supply, - connections: connections + supply: (supply ? supply : 0), + connections: (connections ? connections : 0) }, function(err) { if (err) { console.log("Error during Stats Update: ", err); @@ -774,8 +774,8 @@ module.exports = { return cb({ coin: coin, count : count, - supply: supply, - connections: connections, + supply: (supply ? supply : 0), + connections: (connections ? connections : 0), last: (stats.last ? stats.last : 0), txes: (stats.txes ? stats.txes : 0) }); diff --git a/lib/explorer.js b/lib/explorer.js index 3cb9e34..9059511 100644 --- a/lib/explorer.js +++ b/lib/explorer.js @@ -29,6 +29,48 @@ function rpcCommand(params, cb) { }); } +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