Extended api updates

-Moved /ext/summary from routes/index.js to app.js with the rest of the extended apis and renamed to /etc/getsummary
-Added a new setting to enable/disable public use of /ext/getsummary + added it to list of public apis on the /info page
-Added a new setting to enable/disable public use of /ext/getaddresstxs + added it to list of public apis on the /info page + updated the return data so that it returns a named object array for public api for better readability and still returns the same array list for internal datatable use
-Updated /ext/getlasttxs so that it returns a named object array for public api for better readability and still returns the same array list for internal datatable use
-/ext/getsummary now only returns the online and offline masternode counts if the getmasternodecount api is available and enabled
This commit is contained in:
joeuhren
2021-01-01 18:24:39 -07:00
parent f70952f66b
commit ca52b10f59
10 changed files with 254 additions and 172 deletions
+175 -77
View File
@@ -56,6 +56,41 @@ app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', nodeapi.app);
app.use('/', routes);
// post method to claim an address using verifymessage functionality
app.post('/claim', function(req, res) {
// initialize the bad-words filter
var bad_word_lib = require('bad-words');
var bad_word_filter = new bad_word_lib();
// clean the message (Display name) of bad words
var message = (req.body.message == null || req.body.message == '' ? '' : bad_word_filter.clean(req.body.message));
// check if the message was filtered
if (message == req.body.message) {
// call the verifymessage api
lib.verify_message(req.body.address, req.body.signature, req.body.message, function(body) {
if (body == false) {
res.json({'status': 'failed', 'error': true, 'message': 'Invalid signature'});
} else if (body == true) {
db.update_label(req.body.address, req.body.message, function(val) {
// check if the update was successful
if (val == '')
res.json({'status': 'success'});
else if (val == 'no_address')
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address ' + req.body.address + ' is not valid or does not have any transactions'});
else
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address or signature is invalid'});
});
} else
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address or signature is invalid'});
});
} else {
// message was filtered which would change the signature
res.json({'status': 'failed', 'error': true, 'message': 'Display name contains bad words and cannot be saved: ' + message});
}
});
// extended apis
app.use('/ext/getmoneysupply', function(req, res) {
// check if the getmoneysupply api is enabled
if (settings.display.api == true && settings.public_api.ext['getmoneysupply']) {
@@ -235,7 +270,7 @@ app.use('/ext/getbasicstats', function(req, res) {
app.use('/ext/getlasttxs/:min', function(req, res) {
// check if the getlasttxs api is enabled or else check the headers to see if it matches an internal ajax request from the explorer itself (TODO: come up with a more secure method of whitelisting ajax calls from the explorer)
if ((settings.display.api == true && settings.public_api.ext['getlasttxs']) || (req.headers['x-requested-with'] != null && req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest' && req.headers.referer != null && req.headers.accept.indexOf('text/javascript') > -1 && req.headers.accept.indexOf('application/json') > -1)) {
var min = req.params.min, start, length;
var min = req.params.min, start, length, internal = false;
// split url suffix by forward slash and remove blank entries
var split = req.url.split('/').filter(function(v) { return v; });
// determine how many parameters were passed
@@ -249,10 +284,13 @@ app.use('/ext/getlasttxs/:min', function(req, res) {
if (split.length == 1) {
// capture start
start = split[0];
} else if (split.length > 2) {
} else if (split.length >= 2) {
// capture start and length
start = split[0];
length = split[1];
// check if this is an internal request
if (split.length > 2 && split[2] == 'internal')
internal = true;
}
break;
}
@@ -267,94 +305,154 @@ app.use('/ext/getlasttxs/:min', function(req, res) {
else
min = (min * 100000000);
db.get_last_txs(start, length, min, function(data, count) {
res.json({"data":data, "recordsTotal": count, "recordsFiltered": count});
db.get_last_txs(start, length, min, internal, function(data, count) {
// check if this is an internal request
if (internal) {
// display data formatted for internal datatable
res.json({"data": data, "recordsTotal": count, "recordsFiltered": count});
} else {
// display data in more readable format for public api
res.json(data);
}
});
} else
res.end('This method is disabled');
});
app.use('/ext/getaddresstxs/:address/:start/:length', function(req,res) {
// fix parameters
if (typeof req.params.length === 'undefined' || isNaN(req.params.length) || req.params.length > settings.txcount)
req.params.length = settings.txcount;
if (typeof req.params.start === 'undefined' || isNaN(req.params.start) || req.params.start < 0)
req.params.start = 0;
if (typeof req.params.min === 'undefined' || isNaN(req.params.min) || req.params.min < 0)
req.params.min = 0;
else
req.params.min = (req.params.min * 100000000);
app.use('/ext/getaddresstxs/:address/:start/:length', function(req, res) {
// check if the getaddresstxs api is enabled or else check the headers to see if it matches an internal ajax request from the explorer itself (TODO: come up with a more secure method of whitelisting ajax calls from the explorer)
if ((settings.display.api == true && settings.public_api.ext['getaddresstxs']) || (req.headers['x-requested-with'] != null && req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest' && req.headers.referer != null && req.headers.accept.indexOf('text/javascript') > -1 && req.headers.accept.indexOf('application/json') > -1)) {
var internal = false;
// split url suffix by forward slash and remove blank entries
var split = req.url.split('/').filter(function(v) { return v; });
// check if this is an internal request
if (split.length > 0 && split[0] == 'internal')
internal = true;
// fix parameters
if (typeof req.params.length === 'undefined' || isNaN(req.params.length) || req.params.length > settings.txcount)
req.params.length = settings.txcount;
if (typeof req.params.start === 'undefined' || isNaN(req.params.start) || req.params.start < 0)
req.params.start = 0;
if (typeof req.params.min === 'undefined' || isNaN(req.params.min) || req.params.min < 0)
req.params.min = 0;
else
req.params.min = (req.params.min * 100000000);
db.get_address_txs_ajax(req.params.address, req.params.start, req.params.length, function(txs, count) {
var data = [];
for (i = 0; i < txs.length; i++) {
if (typeof txs[i].txid !== "undefined") {
var out = 0;
var vin = 0;
db.get_address_txs_ajax(req.params.address, req.params.start, req.params.length, function(txs, count) {
var data = [];
txs[i].vout.forEach(function(r) {
if (r.addresses == req.params.address) {
out += r.amount;
for (i = 0; i < txs.length; i++) {
if (typeof txs[i].txid !== "undefined") {
var out = 0;
var vin = 0;
txs[i].vout.forEach(function(r) {
if (r.addresses == req.params.address)
out += r.amount;
});
txs[i].vin.forEach(function(s) {
if (s.addresses == req.params.address)
vin += s.amount;
});
if (internal) {
var row = [];
row.push(txs[i].timestamp);
row.push(txs[i].txid);
row.push(Number(out / 100000000));
row.push(Number(vin / 100000000));
row.push(Number(txs[i].balance / 100000000));
data.push(row);
} else {
data.push({
timestamp: txs[i].timestamp,
txid: txs[i].txid,
sent: Number(out / 100000000),
received: Number(vin / 100000000),
balance: Number(txs[i].balance / 100000000)
});
}
});
txs[i].vin.forEach(function(s) {
if (s.addresses == req.params.address) {
vin += s.amount;
}
});
var row = [];
row.push(new Date((txs[i].timestamp) * 1000).toUTCString());
row.push(txs[i].txid);
row.push(out);
row.push(vin);
row.push(txs[i].balance);
data.push(row);
}
}
}
res.json({"data":data, "recordsTotal": count, "recordsFiltered": count});
});
});
app.post('/claim', function(req, res) {
// initialize the bad-words filter
var bad_word_lib = require('bad-words');
var bad_word_filter = new bad_word_lib();
// clean the message (Display name) of bad words
var message = (req.body.message == null || req.body.message == '' ? '' : bad_word_filter.clean(req.body.message));
// check if the message was filtered
if (message == req.body.message) {
// call the verifymessage api
lib.verify_message(req.body.address, req.body.signature, req.body.message, function(body) {
if (body == false) {
res.json({'status': 'failed', 'error': true, 'message': 'Invalid signature'});
} else if (body == true) {
db.update_label(req.body.address, req.body.message, function(val) {
// check if the update was successful
if (val == '')
res.json({'status': 'success'});
else if (val == 'no_address')
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address ' + req.body.address + ' is not valid or does not have any transactions'});
else
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address or signature is invalid'});
});
} else
res.json({'status': 'failed', 'error': true, 'message': 'Wallet address or signature is invalid'});
// check if this is an internal request
if (internal) {
// display data formatted for internal datatable
res.json({"data": data, "recordsTotal": count, "recordsFiltered": count});
} else {
// display data in more readable format for public api
res.json(data);
}
});
} else {
// message was filtered which would change the signature
res.json({'status': 'failed', 'error': true, 'message': 'Display name contains bad words and cannot be saved: ' + message});
}
} else
res.end('This method is disabled');
});
app.use('/ext/connections', function(req,res){
db.get_peers(function(peers){
res.send({data: peers});
});
app.use('/ext/getsummary', function(req, res) {
// check if the getsummary api is enabled or else check the headers to see if it matches an internal ajax request from the explorer itself (TODO: come up with a more secure method of whitelisting ajax calls from the explorer)
if ((settings.display.api == true && settings.public_api.ext['getsummary']) || (req.headers['x-requested-with'] != null && req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest' && req.headers.referer != null && req.headers.accept.indexOf('text/javascript') > -1 && req.headers.accept.indexOf('application/json') > -1)) {
lib.get_difficulty(function(difficulty) {
difficultyHybrid = '';
if (difficulty && difficulty['proof-of-work']) {
if (settings.index.difficulty == 'Hybrid') {
difficultyHybrid = 'POS: ' + difficulty['proof-of-stake'];
difficulty = 'POW: ' + difficulty['proof-of-work'];
} else if (settings.index.difficulty == 'POW')
difficulty = difficulty['proof-of-work'];
else
difficulty = difficulty['proof-of-stake'];
}
lib.get_hashrate(function(hashrate) {
lib.get_connectioncount(function(connections) {
lib.get_blockcount(function(blockcount) {
db.get_stats(settings.coin, function (stats) {
lib.get_masternodecount(function(masternodestotal) {
if (hashrate == 'There was an error. Check your console.')
hashrate = 0;
// check if the masternode count api is enabled
if (settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '') {
// masternode count api is available
var mn_total = 0;
var mn_enabled = 0;
if (masternodestotal) {
if (masternodestotal.total)
mn_total = masternodestotal.total;
if (masternodestotal.enabled)
mn_enabled = masternodestotal.enabled;
}
res.send({
difficulty: (difficulty ? difficulty : '-'),
difficultyHybrid: difficultyHybrid,
supply: (stats == null || stats.supply == null ? 0 : stats.supply),
hashrate: hashrate,
lastPrice: (stats == null || stats.last_price == null ? 0 : stats.last_price),
connections: (connections ? connections : '-'),
masternodeCountOnline: (masternodestotal ? mn_enabled : '-'),
masternodeCountOffline: (masternodestotal ? Math.floor(mn_total - mn_enabled) : '-'),
blockcount: (blockcount ? blockcount : '-')
});
} else {
// masternode count api is not available
res.send({
difficulty: (difficulty ? difficulty : '-'),
difficultyHybrid: difficultyHybrid,
supply: (stats == null || stats.supply == null ? 0 : stats.supply),
hashrate: hashrate,
lastPrice: (stats == null || stats.last_price == null ? 0 : stats.last_price),
connections: (connections ? connections : '-'),
blockcount: (blockcount ? blockcount : '-')
});
}
});
});
});
});
});
});
} else
res.end('This method is disabled');
});
// get the list of masternodes from local collection
+22 -10
View File
@@ -491,18 +491,30 @@ module.exports = {
});
},
get_last_txs: function(start, length, min, cb) {
get_last_txs: function(start, length, min, internal, cb) {
this.get_last_txs_ajax(start, length, min, function(txs, count) {
var data = [];
for(i=0; i<txs.length; i++) {
var row = [];
row.push(txs[i].blockindex);
row.push(txs[i].blockhash);
row.push(txs[i].txid);
row.push(txs[i].vout.length);
row.push((txs[i].total));
row.push(new Date((txs[i].timestamp) * 1000).toUTCString());
data.push(row);
for (i = 0; i < txs.length; i++) {
if (internal) {
var row = [];
row.push(txs[i].blockindex);
row.push(txs[i].blockhash);
row.push(txs[i].txid);
row.push(txs[i].vout.length);
row.push((txs[i].total / 100000000));
row.push(txs[i].timestamp);
data.push(row);
} else {
data.push({
blockindex: txs[i].blockindex,
blockhash: txs[i].blockhash,
txid: txs[i].txid,
recipients: txs[i].vout.length,
amount: (txs[i].total / 100000000),
timestamp: txs[i].timestamp
});
}
}
return cb(data, count);
});
+2
View File
@@ -253,11 +253,13 @@ exports.public_api = {
"getmoneysupply": true,
"getdistribution": true,
"getaddress": true,
"getaddresstxs": true,
"gettx": true,
"getbalance": true,
"getlasttxs": true,
"getcurrentprice": true,
"getbasicstats": true,
"getsummary": true,
"getmasternodelist": true,
"getmasternoderewards": true,
"getmasternoderewardstotal": true
-49
View File
@@ -472,53 +472,4 @@ router.get('/qr/:string', function(req, res) {
}
});
router.get('/ext/summary', function(req, res) {
lib.get_difficulty(function(difficulty) {
difficultyHybrid = '';
if (difficulty && difficulty['proof-of-work']) {
if (settings.index.difficulty == 'Hybrid') {
difficultyHybrid = 'POS: ' + difficulty['proof-of-stake'];
difficulty = 'POW: ' + difficulty['proof-of-work'];
} else if (settings.index.difficulty == 'POW') {
difficulty = difficulty['proof-of-work'];
} else {
difficulty = difficulty['proof-of-stake'];
}
}
lib.get_hashrate(function(hashrate) {
lib.get_connectioncount(function(connections){
lib.get_masternodecount(function(masternodestotal){
lib.get_blockcount(function(blockcount) {
db.get_stats(settings.coin, function (stats) {
if (hashrate == 'There was an error. Check your console.') {
hashrate = 0;
}
var mn_total = 0;
var mn_enabled = 0;
if (masternodestotal) {
if (masternodestotal.total)
mn_total = masternodestotal.total;
if (masternodestotal.enabled)
mn_enabled = masternodestotal.enabled;
}
res.send({ data: [{
difficulty: (difficulty ? difficulty : '-'),
difficultyHybrid: difficultyHybrid,
supply: (stats == null || stats.supply == null ? 0 : stats.supply),
hashrate: hashrate,
lastPrice: (stats == null || stats.last_price == null ? 0 : stats.last_price),
connections: (connections ? connections : '-'),
masternodeCountOnline: (masternodestotal ? mn_enabled : '-'),
masternodeCountOffline: (masternodestotal ? Math.floor(mn_total - mn_enabled) : '-'),
blockcount: (blockcount ? blockcount : '-')
}]});
});
});
});
});
});
});
});
module.exports = router;
+2
View File
@@ -338,11 +338,13 @@
"getmoneysupply": true,
"getdistribution": true,
"getaddress": true,
"getaddresstxs": true,
"gettx": true,
"getbalance": true,
"getlasttxs": true,
"getcurrentprice": true,
"getbasicstats": true,
"getsummary": true,
"getmasternodelist": true,
"getmasternoderewards": true,
"getmasternoderewardstotal": true
+6 -6
View File
@@ -30,7 +30,7 @@ script.
ajax: {
url: '/ext/getaddresstxs/' + hashAddress,
beforeSend: function(jqXHR, settings) {
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url);
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url) + '/internal';
return true;
}
},
@@ -41,11 +41,11 @@ script.
}
},
rowCallback: function (row, data, index) {
var timestamp = data[0]; //variables for better readability
var timestamp = new Date(data[0] * 1000).toUTCString(); //variables for better readability
var txhash = data[1]; //variables for better readability
var out = data[2]; //variables for better readability
var vin = data[3]; //variables for better readability
var balance = Number(data[4] / 100000000).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability
var balance = data[4].toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability
var balanceParts = balance.split('.');
$("td:eq(0)", row).html('<a href="/tx/' + txhash + '"><span class="fa fa-eye" data-toggle="tooltip" data-placement="top" title="#{settings.locale.view_tx}"></span></a>').addClass('text-center d-table-cell d-md-none');
$("td:eq(1)", row).html('<a href="/tx/' + txhash + '">' + txhash + '</a>').addClass('breakWord d-none d-md-table-cell');
@@ -54,7 +54,7 @@ script.
var rowclass = 'info';
if (out > 0 && vin > 0) {
amount = Number((out - vin) / 100000000);
amount = Number(out - vin);
if (amount < 0) {
amount = Number(amount * -1).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
updown = '-';
@@ -65,11 +65,11 @@ script.
amount = amount.toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
}
} else if (out > 0) {
amount = Number(out / 100000000).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
amount = Number(out).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
updown = '+';
rowclass = 'bg-success';
} else {
amount = Number(vin / 100000000).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
amount = Number(vin).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
updown = '-';
rowclass = 'bg-danger';
}
+3 -3
View File
@@ -32,7 +32,7 @@ block content
ajax: {
url: '/ext/getlasttxs/0',
beforeSend: function(jqXHR, settings) {
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url);
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url) + '/internal';
return true;
}
},
@@ -47,10 +47,10 @@ block content
var blockhash = data[1]; //variables for better readability
var txhash = data[2]; //variables for better readability
var outputs = data[3]; //variables for better readability
var amount = Number(data[4] / 100000000).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability
var amount = Number(data[4]).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}); //variables for better readability
var amountParts = amount.split('.');
var amount = amountParts[0] + '.<span class="decimal">' + amountParts[1] + '</span>';
var timestamp = data[5];
var timestamp = new Date(data[5] * 1000).toUTCString();
$("td:eq(0)", row).html('<a href="/tx/' + txhash + '"><span class="fa fa-eye" data-toggle="tooltip" data-placement="top" title="#{settings.locale.view_tx}"></span></a>').addClass('text-center d-table-cell d-md-none');
$("td:eq(1)", row).html('<a href="/block/' + blockhash + '">' + blockindex + '</a>');
$("td:eq(2)", row).html('<a href="/tx/' + txhash + '">' + txhash + '</a>').addClass("text-center breakWord d-none d-md-table-cell");
+16 -4
View File
@@ -11,7 +11,7 @@ block content
em #{settings.locale.api_message}
hr
- var hide_rpc_api_section = !(settings.public_api.rpc['getdifficulty'] == true && settings.api_cmds['getdifficulty'] != null && settings.api_cmds['getdifficulty'] != '') && !(settings.public_api.rpc['getconnectioncount'] == true && settings.api_cmds['getconnectioncount'] != null && settings.api_cmds['getconnectioncount'] != '') && !(settings.public_api.rpc['getblockcount'] == true && settings.api_cmds['getblockcount'] != null && settings.api_cmds['getblockcount'] != '') && !(settings.public_api.rpc['getblockhash'] == true && settings.api_cmds['getblockhash'] != null && settings.api_cmds['getblockhash'] != '') && !(settings.public_api.rpc['getblock'] == true && settings.api_cmds['getblock'] != null && settings.api_cmds['getblock'] != '') && !(settings.public_api.rpc['getrawtransaction'] == true && settings.api_cmds['getrawtransaction'] != null && settings.api_cmds['getrawtransaction'] != '') && !(settings.public_api.rpc['getnetworkhashps'] == true && settings.index.show_hashrate == true && settings.api_cmds['getnetworkhashps'] != null && settings.api_cmds['getnetworkhashps'] != '') && !(settings.public_api.rpc['getvotelist'] == true && settings.api_cmds['getvotelist'] != null && settings.api_cmds['getvotelist'] != '') && !(settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '') && (!settings.heavy || (!(settings.public_api.rpc['getmaxmoney'] == true && settings.api_cmds.heavies['getmaxmoney'] != null && settings.api_cmds.heavies['getmaxmoney'] != '') && !(settings.public_api.rpc['getmaxvote'] == true && settings.api_cmds.heavies['getmaxvote'] != null && settings.api_cmds.heavies['getmaxvote'] != '') && !(settings.public_api.rpc['getvote'] == true && settings.api_cmds.heavies['getvote'] != null && settings.api_cmds.heavies['getvote'] != '') && !(settings.public_api.rpc['getphase'] == true && settings.api_cmds.heavies['getphase'] != null && settings.api_cmds.heavies['getphase'] != '') && !(settings.public_api.rpc['getreward'] == true && settings.api_cmds.heavies['getreward'] != null && settings.api_cmds.heavies['getreward'] != '') && !(settings.public_api.rpc['getsupply'] == true && settings.api_cmds.heavies['getsupply'] != null && settings.api_cmds.heavies['getsupply'] != '') && !(settings.public_api.rpc['getnextrewardestimate'] == true && settings.api_cmds.heavies['getnextrewardestimate'] != null && settings.api_cmds.heavies['getnextrewardestimate'] != '') && !(settings.public_api.rpc['getnextrewardwhenstr'] == true && settings.api_cmds.heavies['getnextrewardwhenstr'] != null && settings.api_cmds.heavies['getnextrewardwhenstr'] != '')));
- var hide_ext_api_section = !settings.public_api.ext['getmoneysupply'] && !settings.public_api.ext['getdistribution'] && !settings.public_api.ext['getaddress'] && !settings.public_api.ext['gettx'] && !settings.public_api.ext['getbalance'] && !settings.public_api.ext['getlasttxs'] && !settings.public_api.ext['getcurrentprice'] && !settings.public_api.ext['getbasicstats'] && !(settings.public_api.ext['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != '') && !settings.public_api.ext['getmasternoderewards'] && !settings.public_api.ext['getmasternoderewardstotal'];
- var hide_ext_api_section = !settings.public_api.ext['getmoneysupply'] && !settings.public_api.ext['getdistribution'] && !settings.public_api.ext['getaddress'] && !settings.public_api.ext['getaddresstxs'] && !settings.public_api.ext['gettx'] && !settings.public_api.ext['getbalance'] && !settings.public_api.ext['getlasttxs'] && !settings.public_api.ext['getcurrentprice'] && !settings.public_api.ext['getbasicstats'] && !settings.public_api.ext['getsummary'] && !(settings.public_api.ext['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != '') && !settings.public_api.ext['getmasternoderewards'] && !settings.public_api.ext['getmasternoderewardstotal'];
if !hide_rpc_api_section
h3 #{settings.locale.api_calls}
p
@@ -167,6 +167,13 @@ block content
div
em Returns information for given address
a(href='/ext/getaddress/' + hashes.address) #{address}/ext/getaddress/#{hashes.address}
if settings.public_api.ext['getaddresstxs'] == true
li
p
div.font-weight-bold getaddresstxs (/ext/getaddresstxs/hash/start/length)
div
em Returns last [length] transactions for address [hash], starting from offset [start]
a(href='/ext/getaddresstxs/' + hashes.address + '/0/50') #{address}/ext/getaddresstxs/#{hashes.address}/0/50
if settings.public_api.ext['gettx'] == true
li
p
@@ -186,9 +193,7 @@ block content
p
div.font-weight-bold getlasttxs (/ext/getlasttxs/min/start/length)
div
em Returns last [length] transactions greater than [min], starting from offset [start]
div
em Note: returned values are in satoshis
em Returns last [length] transactions greater than [min] coins, starting from offset [start]
div
a(href='/ext/getlasttxs/100/0/100') #{address}/ext/getlasttxs/100/0/100
if settings.public_api.ext['getcurrentprice'] == true
@@ -205,6 +210,13 @@ block content
div
em="Returns basic statistics about the coin including: block count, circulating supply, USD price, BTC price" + (settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '' ? ', ' + '# of masternodes' : '')
a(href='/ext/getbasicstats') #{address}/ext/getbasicstats
if settings.public_api.ext['getsummary'] == true
li
p
div.font-weight-bold getsummary
div
em="Returns a summary of coin data including: difficulty, hybrid difficulty, circulating supply, hash rate, BTC price, network connection count, block count" + (settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '' ? ', ' + 'count of online masternodes' + ', ' + 'count of offline masternodes' : '')
a(href='/ext/getsummary') #{address}/ext/getsummary
if settings.public_api.ext['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != ''
li
p
+25 -20
View File
@@ -114,32 +114,37 @@ html(lang='en')
}
}
function update_stats() {
$.ajax({url: '/ext/summary', success: function(json) {
var mnOnlineText = json.data[0].masternodeCountOnline+" node"+(json.data[0].masternodeCountOnline == 1 ? "" : "s")+" online";
var mnOfflineText = json.data[0].masternodeCountOffline+" unreachable node"+(json.data[0].masternodeCountOffline == 1 ? "" : "s");
$.ajax({url: '/ext/getsummary', headers: {Accept: 'application/json, text/javascript, */*; q=0.01'}, success: function(json) {
if (json.masternodeCountOnline == null)
json.masternodeCountOnline = '-';
if (json.masternodeCountOffline == null)
json.masternodeCountOffline = '-';
$("#masternodeCountOnline").text(json.data[0].masternodeCountOnline).prop("alt", mnOnlineText).prop("title", mnOnlineText).attr("data-original-title", mnOnlineText);
$("#masternodeCountOffline").text(json.data[0].masternodeCountOffline).prop("alt", mnOfflineText).prop("title", mnOfflineText).attr("data-original-title", mnOfflineText);
var mnOnlineText = json.masternodeCountOnline+" node"+(json.masternodeCountOnline == 1 ? "" : "s")+" online";
var mnOfflineText = json.masternodeCountOffline+" unreachable node"+(json.masternodeCountOffline == 1 ? "" : "s");
$("#masternodeCountOnline").text(json.masternodeCountOnline).prop("alt", mnOnlineText).prop("title", mnOnlineText).attr("data-original-title", mnOnlineText);
$("#masternodeCountOffline").text(json.masternodeCountOffline).prop("alt", mnOfflineText).prop("title", mnOfflineText).attr("data-original-title", mnOfflineText);
$("#spnMasternodeCountOnline").prop("alt", mnOnlineText).prop("title", mnOnlineText).attr("data-original-title", mnOnlineText);
$("#spnMasternodeCountOffline").prop("alt", mnOfflineText).prop("title", mnOfflineText).attr("data-original-title", mnOfflineText);
showTopPanelData('masternodepanel', 'masternodePanelLoading');
var supplyString = json.data[0].supply;
var diffString = json.data[0].difficulty;
var hashrateString = json.data[0].hashrate;
var supplyString = json.supply;
var diffString = json.difficulty;
var hashrateString = json.hashrate;
var splitValue, splitParts;
if (!isNaN(json.data[0].difficulty))
diffString = Number(json.data[0].difficulty).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':2,'useGrouping':true});
if (!isNaN(json.data[0].supply))
supplyString = parseInt(parseFloat(json.data[0].supply).toFixed(0)).toLocaleString('en');
if (!isNaN(json.data[0].hashrate))
hashrateString = Number(json.data[0].hashrate).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
if (!isNaN(json.difficulty))
diffString = Number(json.difficulty).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':2,'useGrouping':true});
if (!isNaN(json.supply))
supplyString = parseInt(parseFloat(json.supply).toFixed(0)).toLocaleString('en');
if (!isNaN(json.hashrate))
hashrateString = Number(json.hashrate).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
$("#lblX1").text(' ');
$("#supply").text(supplyString);
splitValue = Number(parseFloat(json.data[0].lastPrice).toFixed(8) * parseInt(parseFloat(json.data[0].supply).toFixed(0))).toLocaleString('en');
splitValue = Number(parseFloat(json.lastPrice).toFixed(8) * parseInt(parseFloat(json.supply).toFixed(0))).toLocaleString('en');
splitParts = splitValue.split('.');
showTopPanelData('supplypanel', 'supplyPanelLoading');
@@ -149,10 +154,10 @@ html(lang='en')
splitParts = diffString.split('.');
$("#difficulty").html(splitParts[0] + '.<span class="decimal">' + splitParts[1] + '</span>');
if (json.data[0].difficultyHybrid == null || json.data[0].difficultyHybrid == '') {
if (json.difficultyHybrid == null || json.difficultyHybrid == '') {
$("#difficultyHybrid").html('0.<span class="decimal">00</span>');
} else {
splitValue = Number(json.data[0].difficultyHybrid).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
splitValue = Number(json.difficultyHybrid).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
splitParts = splitValue.split('.');
$("#difficultyHybrid").html(splitParts[0] + '.<span class="decimal">' + splitParts[1] + '</span>');
}
@@ -163,13 +168,13 @@ html(lang='en')
$("#hashrate").html(splitParts[0] + '.<span class="decimal">' + splitParts[1] + '</span>');
showTopPanelData('hashratepanel', 'hashratePanelLoading');
splitValue = Number(json.data[0].lastPrice).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
splitValue = Number(json.lastPrice).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true});
splitParts = splitValue.split('.');
$("#lastPrice").html(splitParts[0] + '.<span class="decimal">' + splitParts[1] + '</span>');
showTopPanelData('pricepanel', 'pricePanelLoading');
$("#lblConnections").text(json.data[0].connections + ' connections');
$("#lblBlockcount").text(json.data[0].blockcount + ' blocks');
$("#lblConnections").text(json.connections + ' connections');
$("#lblBlockcount").text(json.blockcount + ' blocks');
}});
}
$('.iquidus').css('color',$('.table').css('color'));
+3 -3
View File
@@ -33,7 +33,7 @@ block content
ajax: {
url: '/ext/getlasttxs/#{min_amount}',
beforeSend: function(jqXHR, settings) {
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url);
settings.url = settings.url.substring(0, settings.url.indexOf('?')) + '/' + getParameterByName('start', settings.url) + '/' + getParameterByName('length', settings.url) + '/internal';
return true;
}
},
@@ -48,10 +48,10 @@ block content
var blockhash = data[1]; //variables for better readability
var txhash = data[2]; //variables for better readability
var outputs = data[3]; //variables for better readability
var amount = (data[4] / 100000000); //variables for better readability
var amount = data[4]; //variables for better readability
var amountParts = Number(amount).toLocaleString('en',{'minimumFractionDigits':2,'maximumFractionDigits':8,'useGrouping':true}).split('.');
var amountStr = amountParts[0] + '.<span class="decimal">' + amountParts[1] + '</span>';
var timestamp = data[5]; //variables for better readability
var timestamp = new Date(data[5] * 1000).toUTCString(); //variables for better readability
if (amount > '#{flagb}') {
var total = "<label class='badge badge-danger'>" + amountStr + "</label>";
} else if (amount > '#{flaga}') {