2021-03-17 17:54:09 -06:00
var express = require ( 'express' ) ,
path = require ( 'path' ) ,
nodeapi = require ( './lib/nodeapi' ) ,
favicon = require ( 'serve-favicon' ) ,
logger = require ( 'morgan' ) ,
cookieParser = require ( 'cookie-parser' ) ,
bodyParser = require ( 'body-parser' ) ,
settings = require ( './lib/settings' ) ,
routes = require ( './routes/index' ) ,
lib = require ( './lib/explorer' ) ,
db = require ( './lib/database' ) ,
package _metadata = require ( './package.json' ) ,
2022-07-03 19:13:50 -06:00
locale = require ( './lib/locale' ) ;
2019-05-27 10:33:22 -07:00
var app = express ( ) ;
2020-12-21 19:28:55 -07:00
var apiAccessList = [ ] ;
2022-04-11 14:43:02 -06:00
const { exec } = require ( 'child_process' ) ;
2019-05-27 10:33:22 -07:00
2020-12-21 19:28:55 -07:00
// pass wallet rpc connection info to nodeapi
2019-05-27 10:33:22 -07:00
nodeapi . setWalletDetails ( settings . wallet ) ;
2021-01-22 15:04:32 -07:00
// dynamically build the nodeapi cmd access list by adding all non-blockchain-specific api cmds that have a value
Object . keys ( settings . api _cmds ) . forEach ( function ( key , index , map ) {
2023-05-16 20:29:57 -06:00
if ( key != 'use_rpc' && key != 'rpc_concurrent_tasks' && settings . api _cmds [ key ] != null && settings . api _cmds [ key ] != '' )
2020-12-21 19:28:55 -07:00
apiAccessList . push ( key ) ;
} ) ;
2021-01-22 15:04:32 -07:00
// dynamically find and add additional blockchain_specific api cmds
Object . keys ( settings . blockchain _specific ) . forEach ( function ( key , index , map ) {
// check if this feature is enabled and has api cmds
if ( settings . blockchain _specific [ key ] . enabled == true && Object . keys ( settings . blockchain _specific [ key ] ) . indexOf ( 'api_cmds' ) > - 1 ) {
// add all blockchain specific api cmds that have a value
Object . keys ( settings . blockchain _specific [ key ] [ 'api_cmds' ] ) . forEach ( function ( key2 , index , map ) {
if ( settings . blockchain _specific [ key ] [ 'api_cmds' ] [ key2 ] != null && settings . blockchain _specific [ key ] [ 'api_cmds' ] [ key2 ] != '' )
apiAccessList . push ( key2 ) ;
} ) ;
}
} ) ;
2023-05-22 20:54:32 -06:00
2020-12-21 19:28:55 -07:00
// whitelist the cmds in the nodeapi access list
nodeapi . setAccess ( 'only' , apiAccessList ) ;
2023-05-22 20:54:32 -06:00
// determine if http traffic should be forwarded to https
if ( settings . webserver . tls . enabled == true && settings . webserver . tls . always _redirect == true ) {
app . use ( function ( req , res , next ) {
if ( req . secure ) {
// continue without redirecting
next ( ) ;
} else {
// add webserver port to the host value if it does not already exist
const host = req . headers . host + ( req . headers . host . indexOf ( ':' ) > - 1 ? '' : ':' + settings . webserver . port . toString ( ) ) ;
// redirect to the correct https page
res . redirect ( 301 , 'https://' + host . replace ( ':' + settings . webserver . port . toString ( ) , ( settings . webserver . tls . port != 443 ? ':' + settings . webserver . tls . port . toString ( ) : '' ) ) + req . url ) ;
}
} ) ;
}
2019-05-27 10:33:22 -07:00
// determine if cors should be enabled
2021-01-22 15:04:32 -07:00
if ( settings . webserver . cors . enabled == true ) {
2021-03-17 17:54:09 -06:00
app . use ( function ( req , res , next ) {
res . header ( "Access-Control-Allow-Origin" , settings . webserver . cors . corsorigin ) ;
res . header ( 'Access-Control-Allow-Methods' , 'DELETE, PUT, GET, POST' ) ;
res . header ( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" ) ;
next ( ) ;
} ) ;
2019-05-27 10:33:22 -07:00
}
2023-05-22 20:54:32 -06:00
2019-05-27 10:33:22 -07:00
// view engine setup
app . set ( 'views' , path . join ( _ _dirname , 'views' ) ) ;
app . set ( 'view engine' , 'pug' ) ;
2022-06-18 14:19:52 -06:00
var default _favicon = '' ;
// loop through the favicons
Object . keys ( settings . shared _pages . favicons ) . forEach ( function ( key , index , map ) {
// remove the public directory from the path if exists
if ( settings . shared _pages . favicons [ key ] != null && settings . shared _pages . favicons [ key ] . indexOf ( 'public/' ) > - 1 )
settings . shared _pages . favicons [ key ] = settings . shared _pages . favicons [ key ] . replace ( /public\//g , '' ) ;
// check if the favicon file exists
if ( ! db . fs . existsSync ( path . join ( './public' , settings . shared _pages . favicons [ key ] ) ) )
settings . shared _pages . favicons [ key ] = '' ;
else if ( default _favicon == '' )
default _favicon = settings . shared _pages . favicons [ key ] ;
} ) ;
if ( default _favicon != '' )
app . use ( favicon ( path . join ( './public' , default _favicon ) ) ) ;
2019-05-27 10:33:22 -07:00
app . use ( logger ( 'dev' ) ) ;
app . use ( bodyParser . json ( ) ) ;
app . use ( bodyParser . urlencoded ( { extended : true } ) ) ;
app . use ( cookieParser ( ) ) ;
app . use ( express . static ( path . join ( _ _dirname , 'public' ) ) ) ;
// routes
app . use ( '/api' , nodeapi . app ) ;
app . use ( '/' , routes ) ;
2020-12-28 15:12:56 -07:00
2021-01-01 18:24:39 -07:00
// post method to claim an address using verifymessage functionality
app . post ( '/claim' , function ( req , res ) {
2021-01-22 15:04:32 -07:00
// check if the bad-words filter is enabled
if ( settings . claim _address _page . enable _bad _word _filter == true ) {
// 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 ) ) ;
} else {
// Do not use the bad word filter
var message = ( req . body . message == null || req . body . message == '' ? '' : req . body . message ) ;
}
2021-01-01 18:24:39 -07:00
// 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 ) {
2021-03-17 17:54:09 -06:00
if ( body == false )
2021-01-01 18:24:39 -07:00
res . json ( { 'status' : 'failed' , 'error' : true , 'message' : 'Invalid signature' } ) ;
2021-03-17 17:54:09 -06:00
else if ( body == true ) {
2021-01-01 18:24:39 -07:00
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
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getmoneysupply' , function ( req , res ) {
// check if the getmoneysupply api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getmoneysupply . enabled == true ) {
// lookup stats
db . get _stats ( settings . coin . name , function ( stats ) {
2020-12-28 15:12:56 -07:00
res . setHeader ( 'content-type' , 'text/plain' ) ;
2021-01-22 15:04:32 -07:00
res . end ( ( stats && stats . supply ? stats . supply . toString ( ) : '0' ) ) ;
2020-12-28 15:12:56 -07:00
} ) ;
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getaddress/:hash' , function ( req , res ) {
// check if the getaddress api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getaddress . enabled == true ) {
2020-12-28 15:12:56 -07:00
db . get _address ( req . params . hash , false , function ( address ) {
2021-01-22 15:04:32 -07:00
db . get _address _txs _ajax ( req . params . hash , 0 , settings . api _page . public _apis . ext . getaddresstxs . max _items _per _query , function ( txs , count ) {
2020-12-28 15:12:56 -07:00
if ( address ) {
var last _txs = [ ] ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
for ( i = 0 ; i < txs . length ; i ++ ) {
if ( typeof txs [ i ] . txid !== "undefined" ) {
var out = 0 ,
2021-03-17 17:54:09 -06:00
vin = 0 ,
tx _type = 'vout' ,
row = { } ;
2020-12-28 15:12:56 -07:00
txs [ i ] . vout . forEach ( function ( r ) {
if ( r . addresses == req . params . hash )
out += r . amount ;
} ) ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
txs [ i ] . vin . forEach ( function ( s ) {
if ( s . addresses == req . params . hash )
vin += s . amount ;
} ) ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
if ( vin > out )
tx _type = 'vin' ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
row [ 'addresses' ] = txs [ i ] . txid ;
row [ 'type' ] = tx _type ;
last _txs . push ( row ) ;
2020-11-23 20:58:34 -07:00
}
}
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
var a _ext = {
address : address . a _id ,
sent : ( address . sent / 100000000 ) ,
received : ( address . received / 100000000 ) ,
balance : ( address . balance / 100000000 ) . toString ( ) . replace ( /(^-+)/mg , '' ) ,
last _txs : last _txs
} ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
res . send ( a _ext ) ;
} else
res . send ( { error : 'address not found.' , hash : req . params . hash } ) ;
} ) ;
2020-11-23 20:58:34 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2020-11-20 14:32:27 -07:00
app . use ( '/ext/gettx/:txid' , function ( req , res ) {
2020-12-28 15:12:56 -07:00
// check if the gettx api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . gettx . enabled == true ) {
2020-12-28 15:12:56 -07:00
var txid = req . params . txid ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
db . get _tx ( txid , function ( tx ) {
if ( tx ) {
lib . get _blockcount ( function ( blockcount ) {
2023-03-03 15:20:33 -07:00
res . send ( { active : 'tx' , tx : tx , confirmations : ( blockcount - tx . blockindex + 1 ) , blockcount : ( blockcount ? blockcount : 0 ) } ) ;
2020-12-28 15:12:56 -07:00
} ) ;
2021-03-17 17:54:09 -06:00
} else {
2020-12-28 15:12:56 -07:00
lib . get _rawtransaction ( txid , function ( rtx ) {
if ( rtx && rtx . txid ) {
2021-03-20 01:34:13 -06:00
lib . prepare _vin ( rtx , function ( vin , tx _type _vin ) {
lib . prepare _vout ( rtx . vout , rtx . txid , vin , ( ( typeof rtx . vjoinsplit === 'undefined' || rtx . vjoinsplit == null ) ? [ ] : rtx . vjoinsplit ) , function ( rvout , rvin , tx _type _vout ) {
2020-12-28 15:12:56 -07:00
lib . calculate _total ( rvout , function ( total ) {
if ( ! rtx . confirmations > 0 ) {
var utx = {
txid : rtx . txid ,
vin : rvin ,
vout : rvout ,
total : total . toFixed ( 8 ) ,
timestamp : rtx . time ,
blockhash : '-' ,
2021-03-17 17:54:09 -06:00
blockindex : - 1
2020-12-28 15:12:56 -07:00
} ;
2021-03-17 17:54:09 -06:00
2023-03-03 15:20:33 -07:00
res . send ( { active : 'tx' , tx : utx , confirmations : rtx . confirmations , blockcount : - 1 } ) ;
2020-12-28 15:12:56 -07:00
} else {
var utx = {
txid : rtx . txid ,
vin : rvin ,
vout : rvout ,
total : total . toFixed ( 8 ) ,
timestamp : rtx . time ,
blockhash : rtx . blockhash ,
2021-03-17 17:54:09 -06:00
blockindex : rtx . blockheight
2020-12-28 15:12:56 -07:00
} ;
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
lib . get _blockcount ( function ( blockcount ) {
2023-03-03 15:20:33 -07:00
res . send ( { active : 'tx' , tx : utx , confirmations : rtx . confirmations , blockcount : ( blockcount ? blockcount : 0 ) } ) ;
2020-12-28 15:12:56 -07:00
} ) ;
}
} ) ;
2020-11-20 14:32:27 -07:00
} ) ;
} ) ;
2021-03-17 17:54:09 -06:00
} else
2020-12-28 15:12:56 -07:00
res . send ( { error : 'tx not found.' , hash : txid } ) ;
} ) ;
}
} ) ;
} else
res . end ( 'This method is disabled' ) ;
2020-11-20 14:32:27 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getbalance/:hash' , function ( req , res ) {
// check if the getbalance api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getbalance . enabled == true ) {
2020-12-28 15:12:56 -07:00
db . get _address ( req . params . hash , false , function ( address ) {
if ( address ) {
res . setHeader ( 'content-type' , 'text/plain' ) ;
res . end ( ( address . balance / 100000000 ) . toString ( ) . replace ( /(^-+)/mg , '' ) ) ;
} else
res . send ( { error : 'address not found.' , hash : req . params . hash } ) ;
} ) ;
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getdistribution' , function ( req , res ) {
// check if the getdistribution api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getdistribution . enabled == true ) {
db . get _richlist ( settings . coin . name , function ( richlist ) {
db . get _stats ( settings . coin . name , function ( stats ) {
2020-12-28 15:12:56 -07:00
db . get _distribution ( richlist , stats , function ( dist ) {
res . send ( dist ) ;
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
2020-12-28 15:12:56 -07:00
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getcurrentprice' , function ( req , res ) {
// check if the getcurrentprice api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getcurrentprice . enabled == true ) {
db . get _stats ( settings . coin . name , function ( stats ) {
eval ( 'var p_ext = { "last_price_' + settings . markets _page . default _exchange . trading _pair . split ( '/' ) [ 1 ] . toLowerCase ( ) + '": stats.last_price, "last_price_usd": stats.last_usd_price, }' ) ;
2021-03-17 17:54:09 -06:00
res . send ( p _ext ) ;
2020-12-28 15:12:56 -07:00
} ) ;
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2020-12-28 15:12:56 -07:00
app . use ( '/ext/getbasicstats' , function ( req , res ) {
// check if the getbasicstats api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getbasicstats . enabled == true ) {
2020-12-30 18:51:39 -07:00
// lookup stats
2021-01-22 15:04:32 -07:00
db . get _stats ( settings . coin . name , function ( stats ) {
// check if the masternode count api is enabled
if ( settings . api _page . public _apis . rpc . getmasternodecount . enabled == true && settings . api _cmds [ 'getmasternodecount' ] != null && settings . api _cmds [ 'getmasternodecount' ] != '' ) {
// masternode count api is available
lib . get _masternodecount ( function ( masternodestotal ) {
eval ( 'var p_ext = { "block_count": (stats.count ? stats.count : 0), "money_supply": (stats.supply ? stats.supply : 0), "last_price_' + settings . markets _page . default _exchange . trading _pair . split ( '/' ) [ 1 ] . toLowerCase ( ) + '": stats.last_price, "last_price_usd": stats.last_usd_price, "masternode_count": masternodestotal.total }' ) ;
res . send ( p _ext ) ;
2019-06-07 20:05:28 -06:00
} ) ;
2021-01-22 15:04:32 -07:00
} else {
// masternode count api is not available
eval ( 'var p_ext = { "block_count": (stats.count ? stats.count : 0), "money_supply": (stats.supply ? stats.supply : 0), "last_price_' + settings . markets _page . default _exchange . trading _pair . split ( '/' ) [ 1 ] . toLowerCase ( ) + '": stats.last_price, "last_price_usd": stats.last_usd_price }' ) ;
res . send ( p _ext ) ;
}
2019-06-07 20:05:28 -06:00
} ) ;
2020-12-28 15:12:56 -07:00
} else
res . end ( 'This method is disabled' ) ;
2019-06-07 20:05:28 -06:00
} ) ;
2020-11-28 20:40:37 -07:00
app . use ( '/ext/getlasttxs/:min' , function ( req , res ) {
2020-12-28 15:12:56 -07:00
// 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)
2021-01-22 15:04:32 -07:00
if ( ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getlasttxs . enabled == true ) || ( 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 ) ) {
2021-01-01 18:24:39 -07:00
var min = req . params . min , start , length , internal = false ;
2020-12-28 15:12:56 -07:00
// 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
switch ( split . length ) {
case 2 :
2020-12-18 14:55:30 -07:00
// capture start and length
start = split [ 0 ] ;
length = split [ 1 ] ;
2020-12-28 15:12:56 -07:00
break ;
default :
if ( split . length == 1 ) {
// capture start
start = split [ 0 ] ;
2021-01-01 18:24:39 -07:00
} else if ( split . length >= 2 ) {
2020-12-28 15:12:56 -07:00
// capture start and length
start = split [ 0 ] ;
length = split [ 1 ] ;
2021-01-01 18:24:39 -07:00
// check if this is an internal request
if ( split . length > 2 && split [ 2 ] == 'internal' )
internal = true ;
2020-12-28 15:12:56 -07:00
}
2021-03-17 17:54:09 -06:00
2020-12-28 15:12:56 -07:00
break ;
}
2020-12-18 14:55:30 -07:00
2020-12-28 15:12:56 -07:00
// fix parameters
2021-01-22 15:04:32 -07:00
if ( typeof length === 'undefined' || isNaN ( length ) || length > settings . api _page . public _apis . ext . getlasttxs . max _items _per _query )
length = settings . api _page . public _apis . ext . getlasttxs . max _items _per _query ;
2020-12-28 15:12:56 -07:00
if ( typeof start === 'undefined' || isNaN ( start ) || start < 0 )
start = 0 ;
if ( typeof min === 'undefined' || isNaN ( min ) || min < 0 )
min = 0 ;
else
min = ( min * 100000000 ) ;
2020-12-18 14:55:30 -07:00
2021-01-01 18:24:39 -07:00
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 ) ;
}
2020-12-28 15:12:56 -07:00
} ) ;
} else
res . end ( 'This method is disabled' ) ;
2020-11-28 20:40:37 -07:00
} ) ;
2021-01-01 18:24:39 -07:00
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)
2021-01-22 15:04:32 -07:00
if ( ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getaddresstxs . enabled == true ) || ( 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 ) ) {
2021-01-01 18:24:39 -07:00
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
2021-01-22 15:04:32 -07:00
if ( typeof req . params . length === 'undefined' || isNaN ( req . params . length ) || req . params . length > settings . api _page . public _apis . ext . getaddresstxs . max _items _per _query )
req . params . length = settings . api _page . public _apis . ext . getaddresstxs . max _items _per _query ;
2021-01-01 18:24:39 -07:00
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 ) ;
2020-11-19 21:37:42 -07:00
2021-01-01 18:24:39 -07:00
db . get _address _txs _ajax ( req . params . address , req . params . start , req . params . length , function ( txs , count ) {
var data = [ ] ;
2020-11-19 21:37:42 -07:00
2021-01-01 18:24:39 -07:00
for ( i = 0 ; i < txs . length ; i ++ ) {
if ( typeof txs [ i ] . txid !== "undefined" ) {
var out = 0 ;
var vin = 0 ;
2020-11-19 21:37:42 -07:00
2021-01-01 18:24:39 -07:00
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 ;
} ) ;
2020-11-19 21:37:42 -07:00
2021-01-01 18:24:39 -07:00
if ( internal ) {
var row = [ ] ;
2021-03-17 17:54:09 -06:00
2021-01-01 18:24:39 -07:00
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 ) ) ;
2021-03-17 17:54:09 -06:00
2021-01-01 18:24:39 -07:00
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 )
} ) ;
}
}
2020-12-18 15:17:52 -07:00
}
2021-01-01 18:24:39 -07:00
// 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' ) ;
2020-11-19 21:37:42 -07:00
} ) ;
2021-01-01 18:24:39 -07:00
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)
2021-01-22 15:04:32 -07:00
if ( ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getsummary . enabled == true ) || ( 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 ) ) {
2021-04-11 20:39:52 -06:00
lib . get _connectioncount ( function ( connections ) {
lib . get _blockcount ( function ( blockcount ) {
// check if this is a footer-only method that should only return the connection count and block count
if ( req . headers [ 'footer-only' ] != null && req . headers [ 'footer-only' ] == 'true' ) {
// only return the connection count and block count
res . send ( {
connections : ( connections ? connections : '-' ) ,
blockcount : ( blockcount ? blockcount : '-' )
} ) ;
} else {
lib . get _hashrate ( function ( hashrate ) {
2021-01-22 15:04:32 -07:00
db . get _stats ( settings . coin . name , function ( stats ) {
2021-01-01 18:24:39 -07:00
lib . get _masternodecount ( function ( masternodestotal ) {
2021-04-11 20:39:52 -06:00
lib . get _difficulty ( function ( difficulty ) {
difficultyHybrid = '' ;
if ( difficulty && difficulty [ 'proof-of-work' ] ) {
if ( settings . shared _pages . difficulty == 'Hybrid' ) {
difficultyHybrid = 'POS: ' + difficulty [ 'proof-of-stake' ] ;
difficulty = 'POW: ' + difficulty [ 'proof-of-work' ] ;
} else if ( settings . shared _pages . difficulty == 'POW' )
difficulty = difficulty [ 'proof-of-work' ] ;
else
difficulty = difficulty [ 'proof-of-stake' ] ;
2021-01-01 18:24:39 -07:00
}
2021-03-17 17:54:09 -06:00
2021-04-11 20:39:52 -06:00
if ( hashrate == 'There was an error. Check your console.' )
hashrate = 0 ;
// check if the masternode count api is enabled
if ( settings . api _page . public _apis . rpc . getmasternodecount . enabled == 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 : '-' )
} ) ;
}
} ) ;
2021-01-01 18:24:39 -07:00
} ) ;
} ) ;
} ) ;
2021-04-11 20:39:52 -06:00
}
2021-01-01 18:24:39 -07:00
} ) ;
2020-12-22 18:06:40 -07:00
} ) ;
2021-01-01 18:24:39 -07:00
} else
res . end ( 'This method is disabled' ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-02 01:30:47 -07:00
app . use ( '/ext/getnetworkpeers' , function ( req , res ) {
// check if the getnetworkpeers 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)
2021-01-22 15:04:32 -07:00
if ( ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getnetworkpeers . enabled == true ) || ( 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 ) ) {
2021-01-02 01:30:47 -07:00
// get list of peers
db . get _peers ( function ( peers ) {
// loop through peers list and remove the mongo _id and __v keys
for ( i = 0 ; i < peers . length ; i ++ ) {
delete peers [ i ] [ '_doc' ] [ '_id' ] ;
delete peers [ i ] [ '_doc' ] [ '__v' ] ;
}
2021-03-17 17:54:09 -06:00
2022-07-01 21:11:57 -06:00
// sort ip6 addresses to the bottom
peers . sort ( function ( a , b ) {
var address1 = a . address . indexOf ( ':' ) > - 1 ;
var address2 = b . address . indexOf ( ':' ) > - 1 ;
if ( address1 < address2 )
return - 1 ;
else if ( address1 > address2 )
return 1 ;
else
return 0 ;
} ) ;
// return peer data
res . json ( peers ) ;
2021-01-02 01:30:47 -07:00
} ) ;
} else
res . end ( 'This method is disabled' ) ;
} ) ;
2020-12-30 18:22:02 -07:00
// get the list of masternodes from local collection
app . use ( '/ext/getmasternodelist' , function ( req , res ) {
// check if the getmasternodelist 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)
2021-01-22 15:04:32 -07:00
if ( ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getmasternodelist . enabled == true ) || ( 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 ) ) {
2020-12-30 18:22:02 -07:00
// get the masternode list from local collection
db . get _masternodes ( function ( masternodes ) {
// loop through masternode list and remove the mongo _id and __v keys
for ( i = 0 ; i < masternodes . length ; i ++ ) {
delete masternodes [ i ] [ '_doc' ] [ '_id' ] ;
delete masternodes [ i ] [ '_doc' ] [ '__v' ] ;
}
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// return masternode list
res . send ( masternodes ) ;
} ) ;
} else
res . end ( 'This method is disabled' ) ;
} ) ;
2020-12-30 20:27:42 -07:00
// returns a list of masternode reward txs for a single masternode address from a specific block height
app . use ( '/ext/getmasternoderewards/:hash/:since' , function ( req , res ) {
// check if the getmasternoderewards api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getmasternoderewards . enabled == true ) {
2020-12-30 20:27:42 -07:00
db . get _masternode _rewards ( req . params . hash , req . params . since , function ( rewards ) {
if ( rewards != null ) {
// loop through the tx list to fix vout values and remove unnecessary data such as the always empty vin array and the mongo _id and __v keys
for ( i = 0 ; i < rewards . length ; i ++ ) {
// remove unnecessary data keys
delete rewards [ i ] [ 'vin' ] ;
delete rewards [ i ] [ '_id' ] ;
delete rewards [ i ] [ '__v' ] ;
// convert amounts from satoshis
rewards [ i ] [ 'total' ] = rewards [ i ] [ 'total' ] / 100000000 ;
rewards [ i ] [ 'vout' ] [ 'amount' ] = rewards [ i ] [ 'vout' ] [ 'amount' ] / 100000000 ;
}
2021-03-17 17:54:09 -06:00
2020-12-30 20:27:42 -07:00
// return list of masternode rewards
res . json ( rewards ) ;
} else
res . send ( { error : "failed to retrieve masternode rewards" , hash : req . params . hash , since : req . params . since } ) ;
} ) ;
} else
res . end ( 'This method is disabled' ) ;
} ) ;
// returns the total masternode rewards received for a single masternode address from a specific block height
app . use ( '/ext/getmasternoderewardstotal/:hash/:since' , function ( req , res ) {
// check if the getmasternoderewardstotal api is enabled
2021-01-22 15:04:32 -07:00
if ( settings . api _page . enabled == true && settings . api _page . public _apis . ext . getmasternoderewardstotal . enabled == true ) {
2020-12-30 20:27:42 -07:00
db . get _masternode _rewards _totals ( req . params . hash , req . params . since , function ( total _rewards ) {
if ( total _rewards != null ) {
// return the total of masternode rewards
res . json ( total _rewards ) ;
} else
res . send ( { error : "failed to retrieve masternode rewards" , hash : req . params . hash , since : req . params . since } ) ;
} ) ;
} else
res . end ( 'This method is disabled' ) ;
} ) ;
2023-05-06 12:36:35 -06:00
// get the list of orphans from local collection
app . use ( '/ext/getorphanlist/:start/:length' , function ( req , res ) {
// 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 ( 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 ) {
// fix parameters
if ( typeof req . params . start === 'undefined' || isNaN ( req . params . start ) || req . params . start < 0 )
req . params . start = 0 ;
if ( typeof req . params . length === 'undefined' || isNaN ( req . params . length ) )
req . params . length = 10 ;
// get the orphan list from local collection
db . get _orphans ( req . params . start , req . params . length , function ( orphans , count ) {
var data = [ ] ;
for ( i = 0 ; i < orphans . length ; i ++ ) {
var row = [ ] ;
row . push ( orphans [ i ] . blockindex ) ;
row . push ( orphans [ i ] . orphan _blockhash ) ;
row . push ( orphans [ i ] . good _blockhash ) ;
row . push ( orphans [ i ] . prev _blockhash ) ;
row . push ( orphans [ i ] . next _blockhash ) ;
data . push ( row ) ;
}
// display data formatted for internal datatable
res . json ( { "data" : data , "recordsTotal" : count , "recordsFiltered" : count } ) ;
} ) ;
} else
res . end ( 'This method is disabled' ) ;
} ) ;
2022-04-11 01:37:27 -06:00
app . use ( '/ext/getnetworkchartdata' , function ( req , res ) {
db . get _network _chart _data ( function ( data ) {
if ( data )
res . send ( data ) ;
else
res . send ( ) ;
} ) ;
} ) ;
2022-07-03 19:13:50 -06:00
app . use ( '/system/restartexplorer' , function ( req , res , next ) {
// check to ensure this special cmd is only executed by the local server
if ( req . _remoteAddress != null && req . _remoteAddress . indexOf ( '127.0.0.1' ) > - 1 ) {
// send a msg to the cluster process telling it to restart
process . send ( 'restart' ) ;
res . end ( ) ;
} else {
// show the error page
var err = new Error ( 'Not Found' ) ;
err . status = 404 ;
next ( err ) ;
}
} ) ;
2021-01-22 15:04:32 -07:00
var market _data = [ ] ;
var market _count = 0 ;
// check if markets are enabled
if ( settings . markets _page . enabled == true ) {
// dynamically populate market data
Object . keys ( settings . markets _page . exchanges ) . forEach ( function ( key , index , map ) {
// check if market is enabled via settings
if ( settings . markets _page . exchanges [ key ] . enabled == true ) {
// check if market is installed/supported
if ( db . fs . existsSync ( './lib/markets/' + key + '.js' ) ) {
// load market file
var exMarket = require ( './lib/markets/' + key ) ;
// save market_name and market_logo from market file to settings
2022-06-26 20:48:13 -06:00
eval ( 'market_data.push({id: "' + key + '", name: "' + ( exMarket . market _name == null ? '' : exMarket . market _name ) + '", alt_name: "' + ( exMarket . market _name _alt == null ? '' : exMarket . market _name _alt ) + '", logo: "' + ( exMarket . market _logo == null ? '' : exMarket . market _logo ) + '", alt_logo: "' + ( exMarket . market _logo _alt == null ? '' : exMarket . market _logo _alt ) + '", trading_pairs: []});' ) ;
2021-01-22 15:04:32 -07:00
// loop through all trading pairs for this market
for ( var i = 0 ; i < settings . markets _page . exchanges [ key ] . trading _pairs . length ; i ++ ) {
2022-06-26 20:48:13 -06:00
var isAlt = false ;
var pair = settings . markets _page . exchanges [ key ] . trading _pairs [ i ] . toUpperCase ( ) ; // ensure trading pair setting is always uppercase
var coin _symbol = pair . split ( '/' ) [ 0 ] ;
var pair _symbol = pair . split ( '/' ) [ 1 ] ;
// determine if using the alt name + logo
if ( exMarket . market _url _template != null && exMarket . market _url _template != '' ) {
switch ( ( exMarket . market _url _case == null || exMarket . market _url _case == '' ? 'l' : exMarket . market _url _case . toLowerCase ( ) ) ) {
case 'l' :
case 'lower' :
isAlt = ( exMarket . isAlt != null ? exMarket . isAlt ( { coin : coin _symbol . toLowerCase ( ) , exchange : pair _symbol . toLowerCase ( ) } ) : false ) ;
break ;
case 'u' :
case 'upper' :
isAlt = ( exMarket . isAlt != null ? exMarket . isAlt ( { coin : coin _symbol . toUpperCase ( ) , exchange : pair _symbol . toUpperCase ( ) } ) : false ) ;
break ;
default :
}
}
2021-01-22 15:04:32 -07:00
// add trading pair to market_data
2022-06-26 20:48:13 -06:00
market _data [ market _data . length - 1 ] . trading _pairs . push ( {
pair : pair ,
isAlt : isAlt
} ) ;
2021-01-22 15:04:32 -07:00
// increment the market count
market _count ++ ;
}
2022-06-26 20:48:13 -06:00
// sort trading pairs by alt status
market _data [ market _data . length - 1 ] . trading _pairs . sort ( function ( a , b ) {
if ( a . isAlt < b . isAlt )
return - 1 ;
else if ( a . isAlt > b . isAlt )
return 1 ;
else
return 0 ;
} ) ;
2021-01-22 15:04:32 -07:00
}
}
} ) ;
// sort market data by market name
market _data . sort ( function ( a , b ) {
var name1 = a . name . toLowerCase ( ) ;
var name2 = b . name . toLowerCase ( ) ;
if ( name1 < name2 )
return - 1 ;
else if ( name1 > name2 )
return 1 ;
else
return 0 ;
} ) ;
// Fix default exchange case
settings . markets _page . default _exchange . exchange _name = settings . markets _page . default _exchange . exchange _name . toLowerCase ( ) ;
settings . markets _page . default _exchange . trading _pair = settings . markets _page . default _exchange . trading _pair . toUpperCase ( ) ;
var ex = settings . markets _page . exchanges ;
var ex _name = settings . markets _page . default _exchange . exchange _name ;
var ex _pair = settings . markets _page . default _exchange . trading _pair ;
var ex _keys = Object . keys ( ex ) ;
var ex _error = '' ;
// check to ensure default market and trading pair exist and are enabled
if ( ex [ ex _name ] == null ) {
// exchange name does not exist in exchanges list
ex _error = 'Default exchange name is not valid' + ': ' + ex _name ;
} else if ( ! ex [ ex _name ] . enabled ) {
// exchange is not enabled
ex _error = 'Default exchange is disabled in settings' + ': ' + ex _name ;
} else if ( ex [ ex _name ] . trading _pairs . findIndex ( p => p . toLowerCase ( ) == ex _pair . toLowerCase ( ) ) == - 1 ) {
// invalid default exchange trading pair
ex _error = 'Default exchange trading pair is not valid' + ': ' + ex _pair ;
}
// check if there was an error msg
if ( ex _error != '' ) {
// there was an error, so find the next available market from settings.json
var new _default _index = - 1 ;
// find the first enabled exchange with at least one trading pair
for ( var i = 0 ; i < ex _keys . length ; i ++ ) {
if ( ex [ ex _keys [ i ] ] [ 'enabled' ] === true && ex [ ex _keys [ i ] ] [ 'trading_pairs' ] . length > 0 ) {
// found a match so save the index
new _default _index = i ;
// stop looking for more matches
break ;
}
}
// check if a valid and enabled market was found
if ( new _default _index == - 1 ) {
// no valid markets found
console . log ( 'WARNING: ' + ex _error + '. ' + 'No valid or enabled markets found in settings.json. The markets feature will be temporarily disabled. To restore markets functionality, please enable at least 1 market and ensure at least 1 valid trading pair is added. Finally, restart the explorer to resolve the problem' ) ;
// disable the markets feature for this session
settings . markets _page . enabled = false ;
} else {
// a valid and enabled market was found to replace the default
console . log ( 'WARNING: ' + ex _error + '. ' + 'Default exchange will be set to' + ': ' + ex _keys [ new _default _index ] + ' (' + ex [ ex _keys [ new _default _index ] ] . trading _pairs [ 0 ] + ')' ) ;
// set new default exchange data
settings . markets _page . default _exchange . exchange _name = ex _keys [ new _default _index ] ;
settings . markets _page . default _exchange . trading _pair = ex [ ex _keys [ new _default _index ] ] . trading _pairs [ 0 ] ;
}
}
}
// check if home_link_logo file exists
if ( ! db . fs . existsSync ( path . join ( './public' , settings . shared _pages . page _header . home _link _logo ) ) )
settings . shared _pages . page _header . home _link _logo = '' ;
// always disable the rpc masternode list cmd from public apis
settings . api _page . public _apis . rpc . getmasternodelist = { "enabled" : false } ;
2019-05-27 10:33:22 -07:00
// locals
2020-11-22 20:29:56 -07:00
app . set ( 'explorer_version' , package _metadata . version ) ;
2019-05-27 10:33:22 -07:00
app . set ( 'locale' , locale ) ;
2021-01-22 15:04:32 -07:00
app . set ( 'coin' , settings . coin ) ;
2022-04-11 01:37:27 -06:00
app . set ( 'network_history' , settings . network _history ) ;
2021-01-22 15:04:32 -07:00
app . set ( 'shared_pages' , settings . shared _pages ) ;
app . set ( 'index_page' , settings . index _page ) ;
app . set ( 'block_page' , settings . block _page ) ;
app . set ( 'transaction_page' , settings . transaction _page ) ;
app . set ( 'address_page' , settings . address _page ) ;
2021-04-07 12:26:47 -06:00
app . set ( 'error_page' , settings . error _page ) ;
2020-12-31 15:19:48 -07:00
app . set ( 'masternodes_page' , settings . masternodes _page ) ;
app . set ( 'movement_page' , settings . movement _page ) ;
app . set ( 'network_page' , settings . network _page ) ;
app . set ( 'richlist_page' , settings . richlist _page ) ;
app . set ( 'markets_page' , settings . markets _page ) ;
2021-01-22 15:04:32 -07:00
app . set ( 'api_page' , settings . api _page ) ;
app . set ( 'claim_address_page' , settings . claim _address _page ) ;
2023-05-06 12:36:35 -06:00
app . set ( 'orphans_page' , settings . orphans _page ) ;
2019-05-27 10:33:22 -07:00
app . set ( 'labels' , settings . labels ) ;
2020-12-07 21:32:43 -07:00
app . set ( 'api_cmds' , settings . api _cmds ) ;
2021-01-22 15:04:32 -07:00
app . set ( 'blockchain_specific' , settings . blockchain _specific ) ;
2020-12-05 20:10:17 -07:00
2019-05-27 10:33:22 -07:00
// determine panel offset based on which panels are enabled
2020-12-27 17:26:01 -07:00
var paneltotal = 5 ;
2021-01-22 15:04:32 -07:00
var panelcount = ( settings . shared _pages . page _header . panels . network _panel . enabled == true && settings . shared _pages . page _header . panels . network _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . difficulty _panel . enabled == true && settings . shared _pages . page _header . panels . difficulty _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . masternodes _panel . enabled == true && settings . shared _pages . page _header . panels . masternodes _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . coin _supply _panel . enabled == true && settings . shared _pages . page _header . panels . coin _supply _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . price _panel . enabled == true && settings . shared _pages . page _header . panels . price _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . market _cap _panel . enabled == true && settings . shared _pages . page _header . panels . market _cap _panel . display _order > 0 ? 1 : 0 ) +
2023-08-19 16:24:03 -06:00
( settings . shared _pages . page _header . panels . logo _panel . enabled == true && settings . shared _pages . page _header . panels . logo _panel . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . spacer _panel _1 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _1 . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . spacer _panel _2 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _2 . display _order > 0 ? 1 : 0 ) +
( settings . shared _pages . page _header . panels . spacer _panel _3 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _3 . display _order > 0 ? 1 : 0 ) ;
2020-12-27 17:26:01 -07:00
app . set ( 'paneloffset' , paneltotal + 1 - panelcount ) ;
2019-05-27 10:33:22 -07:00
// determine panel order
2021-01-22 15:04:32 -07:00
var panel _order = new Array ( ) ;
2020-12-27 17:26:01 -07:00
2021-01-22 15:04:32 -07:00
if ( settings . shared _pages . page _header . panels . network _panel . enabled == true && settings . shared _pages . page _header . panels . network _panel . display _order > 0 ) panel _order . push ( { name : 'network_panel' , val : settings . shared _pages . page _header . panels . network _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . difficulty _panel . enabled == true && settings . shared _pages . page _header . panels . difficulty _panel . display _order > 0 ) panel _order . push ( { name : 'difficulty_panel' , val : settings . shared _pages . page _header . panels . difficulty _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . masternodes _panel . enabled == true && settings . shared _pages . page _header . panels . masternodes _panel . display _order > 0 ) panel _order . push ( { name : 'masternodes_panel' , val : settings . shared _pages . page _header . panels . masternodes _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . coin _supply _panel . enabled == true && settings . shared _pages . page _header . panels . coin _supply _panel . display _order > 0 ) panel _order . push ( { name : 'coin_supply_panel' , val : settings . shared _pages . page _header . panels . coin _supply _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . price _panel . enabled == true && settings . shared _pages . page _header . panels . price _panel . display _order > 0 ) panel _order . push ( { name : 'price_panel' , val : settings . shared _pages . page _header . panels . price _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . market _cap _panel . enabled == true && settings . shared _pages . page _header . panels . market _cap _panel . display _order > 0 ) panel _order . push ( { name : 'market_cap_panel' , val : settings . shared _pages . page _header . panels . market _cap _panel . display _order } ) ;
if ( settings . shared _pages . page _header . panels . logo _panel . enabled == true && settings . shared _pages . page _header . panels . logo _panel . display _order > 0 ) panel _order . push ( { name : 'logo_panel' , val : settings . shared _pages . page _header . panels . logo _panel . display _order } ) ;
2023-08-19 16:24:03 -06:00
if ( settings . shared _pages . page _header . panels . spacer _panel _1 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _1 . display _order > 0 ) panel _order . push ( { name : 'spacer_panel_1' , val : settings . shared _pages . page _header . panels . spacer _panel _1 . display _order } ) ;
if ( settings . shared _pages . page _header . panels . spacer _panel _2 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _2 . display _order > 0 ) panel _order . push ( { name : 'spacer_panel_2' , val : settings . shared _pages . page _header . panels . spacer _panel _2 . display _order } ) ;
if ( settings . shared _pages . page _header . panels . spacer _panel _3 . enabled == true && settings . shared _pages . page _header . panels . spacer _panel _3 . display _order > 0 ) panel _order . push ( { name : 'spacer_panel_3' , val : settings . shared _pages . page _header . panels . spacer _panel _3 . display _order } ) ;
2020-12-27 17:26:01 -07:00
2021-01-22 15:04:32 -07:00
panel _order . sort ( function ( a , b ) { return a . val - b . val ; } ) ;
2020-12-27 17:26:01 -07:00
2021-03-17 17:54:09 -06:00
for ( var i = 1 ; i < 6 ; i ++ )
2021-01-22 15:04:32 -07:00
app . set ( 'panel' + i . toString ( ) , ( ( panel _order . length >= i ) ? panel _order [ i - 1 ] . name : '' ) ) ;
2020-12-25 21:08:25 -07:00
app . set ( 'market_data' , market _data ) ;
2021-01-22 15:04:32 -07:00
app . set ( 'market_count' , market _count ) ;
2020-12-05 17:39:14 -07:00
2019-05-27 10:33:22 -07:00
// catch 404 and forward to error handler
app . use ( function ( req , res , next ) {
var err = new Error ( 'Not Found' ) ;
err . status = 404 ;
next ( err ) ;
} ) ;
2023-05-27 21:45:03 -06:00
// error handler - will print stacktrace when in development mode, otherwise no stacktraces will be leaked to the user
2019-05-27 10:33:22 -07:00
app . use ( function ( err , req , res , next ) {
2021-03-17 17:54:09 -06:00
res . status ( err . status || 500 ) ;
res . render ( 'error' , {
message : err . message ,
2023-05-27 21:45:03 -06:00
error : ( app . get ( 'env' ) === 'development' ? err : { } )
2021-03-17 17:54:09 -06:00
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-03-26 13:53:00 -06:00
// determine if tls features should be enabled
if ( settings . webserver . tls . enabled == true ) {
try {
var tls _options = {
key : db . fs . readFileSync ( settings . webserver . tls . key _file ) ,
cert : db . fs . readFileSync ( settings . webserver . tls . cert _file ) ,
ca : db . fs . readFileSync ( settings . webserver . tls . chain _file )
} ;
} catch ( e ) {
console . warn ( 'There was a problem reading tls certificates. Check that the certificate, chain and key paths are correct.' ) ;
}
var https = require ( 'https' ) ;
https . createServer ( tls _options , app ) . listen ( settings . webserver . tls . port ) ;
}
2022-04-11 14:43:02 -06:00
// get the latest git commit id (if exists)
exec ( 'git rev-parse HEAD' , ( err , stdout , stderr ) => {
// check if the commit id was returned
if ( stdout != null && stdout != '' ) {
// set the explorer revision code based on the git commit id
app . set ( 'revision' , stdout . substring ( 0 , 7 ) ) ;
}
} ) ;
2020-11-20 16:28:28 -07:00
module . exports = app ;