2025-02-02 19:10:17 -07:00
const request = require ( 'postman-request' ) ;
const async = require ( 'async' ) ;
const settings = require ( './settings' ) ;
const Address = require ( '../models/address' ) ;
const base _server = 'http://127.0.0.1:' + settings . webserver . port + '/' ;
const base _url = base _server + 'api/' ;
2020-11-21 20:30:20 -07:00
const onode = require ( './node' ) ;
const client = new onode . Client ( settings . wallet ) ;
2020-11-20 18:43:30 -07:00
2023-05-16 20:29:57 -06:00
const rpc _queue = async . queue ( ( task _params , cb ) => {
client . cmd ( [ task _params ] , function ( err , response ) {
if ( err )
2024-06-16 18:58:12 -06:00
return cb ( ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` ) ;
2023-05-16 20:29:57 -06:00
else
return cb ( response ) ;
} ) ;
} , settings . api _cmds . rpc _concurrent _tasks ) ;
2019-05-27 10:33:22 -07:00
// returns coinbase total sent as current coin supply
function coinbase _supply ( cb ) {
2023-05-07 20:55:29 -06:00
Address . findOne ( { a _id : 'coinbase' } ) . then ( ( address ) => {
2021-03-17 17:54:09 -06:00
if ( address )
2019-05-27 10:33:22 -07:00
return cb ( address . sent ) ;
2021-03-17 17:54:09 -06:00
else
2020-11-23 20:22:40 -07:00
return cb ( 0 ) ;
2023-05-07 20:55:29 -06:00
} ) . catch ( ( err ) => {
console . log ( err ) ;
return cb ( 0 ) ;
2019-05-27 10:33:22 -07:00
} ) ;
}
2020-11-22 16:36:22 -07:00
function rpcCommand ( params , cb ) {
2023-05-16 20:29:57 -06:00
rpc _queue . push ( { method : params [ 0 ] . method , params : params [ 0 ] . parameters } , cb ) ;
2020-11-22 16:36:22 -07:00
}
2019-05-27 10:33:22 -07:00
2020-12-07 21:32:43 -07:00
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 ( ' ' ) ;
2021-03-17 17:54:09 -06:00
for ( i = 0 ; i < split . length ; i ++ ) {
if ( i == 0 )
2020-12-07 21:32:43 -07:00
method _name = split [ i ] ;
else
params . push ( split [ i ] ) ;
}
}
return { method : method _name , parameters : params } ;
}
function convertHashUnits ( hashes ) {
2021-01-22 15:04:32 -07:00
if ( settings . shared _pages . page _header . panels . network _panel . nethash _units == 'K' ) {
2020-12-07 21:32:43 -07:00
// return units in KH/s
return ( hashes / 1000 ) . toFixed ( 4 ) ;
2021-01-22 15:04:32 -07:00
} else if ( settings . shared _pages . page _header . panels . network _panel . nethash _units == 'M' ) {
2020-12-07 21:32:43 -07:00
// return units in MH/s
return ( hashes / 1000000 ) . toFixed ( 4 ) ;
2021-01-22 15:04:32 -07:00
} else if ( settings . shared _pages . page _header . panels . network _panel . nethash _units == 'G' ) {
2020-12-07 21:32:43 -07:00
// return units in GH/s
return ( hashes / 1000000000 ) . toFixed ( 4 ) ;
2021-01-22 15:04:32 -07:00
} else if ( settings . shared _pages . page _header . panels . network _panel . nethash _units == 'T' ) {
2020-12-07 21:32:43 -07:00
// return units in TH/s
return ( hashes / 1000000000000 ) . toFixed ( 4 ) ;
2021-01-22 15:04:32 -07:00
} else if ( settings . shared _pages . page _header . panels . network _panel . nethash _units == 'P' ) {
2020-12-07 21:32:43 -07:00
// return units in PH/s
return ( hashes / 1000000000000000 ) . toFixed ( 4 ) ;
} else {
// return units in H/s
return hashes . toFixed ( 4 ) ;
}
}
2025-02-02 19:10:17 -07:00
function processVoutAddresses ( address _list , vout _value , arr _vout ) {
2021-03-20 01:34:13 -06:00
// check if there are any addresses to process
if ( address _list != null && address _list . length > 0 ) {
2022-07-17 14:28:58 -06:00
// check if vout address is inside an array
if ( Array . isArray ( address _list [ 0 ] ) ) {
// extract the address
address _list [ 0 ] = address _list [ 0 ] [ 0 ] ;
}
2025-02-02 19:10:17 -07:00
const amount _sat = module . exports . convert _to _satoshi ( parseFloat ( vout _value ) ) ;
const index = module . exports . is _unique ( arr _vout , address _list [ 0 ] , 'addresses' ) ;
2021-03-20 01:34:13 -06:00
2025-02-02 19:10:17 -07:00
// check if vout address is unique, if so add to array, if not add its amount to existing index
if ( index == - 1 ) {
// unique vout
arr _vout . push ( { addresses : address _list [ 0 ] , amount : amount _sat } ) ;
} else {
// already exists
arr _vout [ index ] . amount += amount _sat ;
}
2021-03-20 01:34:13 -06:00
}
2025-02-02 19:10:17 -07:00
// return the list of addresses
return arr _vout ;
2021-03-20 01:34:13 -06:00
}
function encodeP2PKaddress ( p2pk _descriptor , cb ) {
// find the descriptor value
module . exports . get _descriptorinfo ( p2pk _descriptor , function ( descriptor _info ) {
// check for errors
if ( descriptor _info != null ) {
// encode the address using the output descriptor
module . exports . get _deriveaddresses ( descriptor _info . descriptor , function ( p2pkh _address ) {
// check for errors
if ( p2pkh _address != null ) {
// return P2PKH address
return cb ( p2pkh _address ) ;
} else {
// address could not be encoded
return cb ( null ) ;
}
} ) ;
} else {
// address could not be encoded
return cb ( null ) ;
}
} ) ;
}
2024-02-02 15:21:45 -07:00
function normalizeMasternodeCount ( raw _count ) {
// check if any data was returned
if ( raw _count != null ) {
// check if the data is in the expected object format
if ( raw _count . total != null && raw _count . enabled != null ) {
// data is already in the correct format
return raw _count ;
} else {
const regex = /^\d+ \/ \d+$/ ;
// check if the data is in the format of "{enabled_count} / {total_count}"
if ( regex . test ( raw _count ) ) {
const splitCount = raw _count . split ( '/' ) ;
// enabled / total format detected
// return the data formatted as an object
return {
enabled : splitCount [ 0 ] . trim ( ) ,
total : splitCount [ 1 ] . trim ( )
} ;
// check if the data is in the format of "Total: {total_count} Enabled: {enabled_count}"
2024-02-03 08:56:40 -07:00
} else if ( raw _count . toString ( ) . indexOf ( 'Total: ' ) > - 1 && raw _count . toString ( ) . indexOf ( 'Enabled: ' ) ) {
2024-02-02 15:21:45 -07:00
// Total: {total_count} Enabled: {enabled_count}" format detected
const totalRegex = /Total: (\d+)/ ;
const enabledRegex = /Enabled: (\d+)/ ;
const totalMatch = raw _count . match ( totalRegex ) ;
const enabledMatch = raw _count . match ( enabledRegex ) ;
// check if both the total and enabled values were found
if ( totalMatch && enabledMatch ) {
// return the data formatted as an object
return {
total : totalMatch [ 1 ] ,
enabled : enabledMatch [ 1 ]
} ;
} else {
// the data is in an unrecognized format
return raw _count ;
}
} else {
// the data is in an unrecognized format
return raw _count ;
}
}
} else {
// no data returned, so nothing to fix
return raw _count ;
}
}
2025-02-02 19:10:17 -07:00
function get _input _addresses ( input , vout , cb ) {
let addresses = [ ] ;
if ( input . coinbase ) {
let amount = 0 ;
for ( let i = 0 ; i < vout . length ; i ++ )
amount += parseFloat ( vout [ i ] . value ) ;
addresses . push ( { hash : 'coinbase' , amount : amount } ) ;
return cb ( addresses , null ) ;
} else {
module . exports . get _rawtransaction ( input . txid , function ( tx ) {
if ( tx ) {
let tx _type = null ;
async . eachSeries ( tx . vout , function ( current _vout , loop ) {
if ( current _vout . n == input . vout ) {
if ( current _vout . scriptPubKey . addresses || current _vout . scriptPubKey . address ) {
let new _address = current _vout . scriptPubKey . address || current _vout . scriptPubKey . addresses [ 0 ] ;
// check if address is inside an array
if ( Array . isArray ( new _address ) ) {
// extract the address
new _address = new _address [ 0 ] ;
}
const index = module . exports . is _unique ( addresses , new _address , 'hash' ) ;
if ( index == - 1 )
addresses . push ( { hash : new _address , amount : current _vout . value } ) ;
else
addresses [ index ] . amount += current _vout . value ;
loop ( ) ;
} else {
// no addresses defined
// check if bitcoin features are enabled
if ( settings . blockchain _specific . bitcoin . enabled == true ) {
// assume the asm value is a P2PK (Pay To Pubkey) public key that should be encoded as a P2PKH (Pay To Pubkey Hash) address
encodeP2PKaddress ( current _vout . scriptPubKey . asm , function ( p2pkh _address ) {
// check if the address was encoded properly
if ( p2pkh _address != null ) {
// mark this tx as p2pk
tx _type = 'p2pk' ;
// check if address is inside an array
if ( Array . isArray ( p2pkh _address ) ) {
// extract the address
p2pkh _address = p2pkh _address [ 0 ] ;
}
// save the P2PKH address
const index = module . exports . is _unique ( addresses , p2pkh _address , 'hash' ) ;
if ( index == - 1 )
addresses . push ( { hash : p2pkh _address , amount : current _vout . value } ) ;
else
addresses [ index ] . amount += current _vout . value ;
loop ( ) ;
} else {
// could not decipher the address, save as unknown and move to next vin
console . log ( 'Failed to find vin address from tx ' + input . txid ) ;
const index = module . exports . is _unique ( addresses , 'unknown_address' , 'hash' ) ;
if ( index == - 1 )
addresses . push ( { hash : 'unknown_address' , amount : current _vout . value } ) ;
else
addresses [ index ] . amount += current _vout . value ;
loop ( ) ;
}
} ) ;
} else {
// could not decipher the address, save as unknown and move to next vin
console . log ( 'Failed to find vin address from tx ' + input . txid ) ;
const index = module . exports . is _unique ( addresses , 'unknown_address' , 'hash' ) ;
if ( index == - 1 )
addresses . push ( { hash : 'unknown_address' , amount : current _vout . value } ) ;
else
addresses [ index ] . amount += current _vout . value ;
loop ( ) ;
}
}
} else
loop ( ) ;
} , function ( ) {
return cb ( addresses , tx _type ) ;
} ) ;
} else
return cb ( ) ;
} ) ;
}
}
function finalize _vout ( first _vout , arr _vout , arr _vin , tx _type , txid , cb ) {
if ( typeof first _vout !== 'undefined' && first _vout . scriptPubKey . type == 'nonstandard' ) {
if ( arr _vin . length > 0 && arr _vout . length > 0 ) {
if ( arr _vin [ 0 ] . addresses == arr _vout [ 0 ] . addresses ) {
// pos
arr _vout [ 0 ] . amount -= arr _vin [ 0 ] . amount ;
arr _vin . shift ( ) ;
// check if any vin remains
if ( arr _vin == null || arr _vin . length == 0 ) {
// empty vin should be linked to coinbase
arr _vin = [ { coinbase : 'coinbase' } ] ;
let new _vout = [ ] ;
// loop through the arr_vout to create a copy of the data with coin amounts only for use with prepare_vin()
for ( i = 0 ; i < arr _vout . length ; i ++ )
new _vout . push ( { value : arr _vout [ i ] . amount / 100000000 } ) ;
// call the prepare_vin again to populate the vin data correctly
module . exports . prepare _vin ( { txid : txid , vin : arr _vin , vout : new _vout } , function ( return _vin , return _tx _type _vin ) {
return cb ( arr _vout , return _vin , return _tx _type _vin ) ;
} ) ;
} else
return cb ( arr _vout , arr _vin , tx _type ) ;
} else
return cb ( arr _vout , arr _vin , tx _type ) ;
} else
return cb ( arr _vout , arr _vin , tx _type ) ;
} else
return cb ( arr _vout , arr _vin , tx _type ) ;
}
2020-11-22 16:36:22 -07:00
module . exports = {
2025-02-02 19:10:17 -07:00
convert _to _satoshi : function ( amount ) {
// fix to 8 decimals and convert to string
const fixed = amount . toFixed ( 8 ) . toString ( ) ;
2019-05-27 10:33:22 -07:00
// remove decimal (.) and return integer
2025-02-02 19:10:17 -07:00
return parseInt ( fixed . replace ( '.' , '' ) ) ;
2019-05-27 10:33:22 -07:00
} ,
get _hashrate : function ( cb ) {
2020-12-07 21:32:43 -07:00
// check if hash rate should be hidden
2021-03-17 17:54:09 -06:00
if ( settings . shared _pages . show _hashrate == false )
return cb ( '-' ) ;
2020-12-07 21:32:43 -07:00
// check how to acquire network hashrate
2021-01-22 15:04:32 -07:00
if ( settings . shared _pages . page _header . panels . network _panel . nethash == 'netmhashps' ) {
2020-12-07 21:32:43 -07:00
// load getmininginfo rpc call from settings
var cmd = prepareRpcCommand ( settings . api _cmds . getmininginfo ) ;
// check if the rpc cmd is valid
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
// check if getting data from wallet rpc or web api request
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
// get data from wallet via rpc cmd
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-17 17:54:09 -06:00
return cb ( '-' ) ;
2020-12-07 21:32:43 -07:00
var net _hash = null ;
// check for different implementations of the net has value
if ( response . netmhashps ) {
// value returned in MH/s so convert to H/s
net _hash = ( response . netmhashps * 1000000 ) ;
} else if ( response . networkhashps )
net _hash = response . networkhashps ;
else if ( response . hashespersec )
net _hash = response . hashespersec ;
// check if netmhashps has a value
if ( net _hash ) {
// return hash value with proper units
return cb ( convertHashUnits ( net _hash ) ) ;
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// netmhashps is blank/null
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
}
2020-12-07 21:32:43 -07:00
} ) ;
} else {
// get data via internal web api request
var uri = base _url + 'getmininginfo' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` ) {
2020-12-07 21:32:43 -07:00
// return a blank value
return cb ( '-' ) ;
} else {
var net _hash = null ;
// check for different implementations of the net has value
if ( body . netmhashps ) {
// value returned in MH/s so convert to H/s
net _hash = ( body . netmhashps * 1000000 ) ;
} else if ( body . networkhashps )
net _hash = body . networkhashps ;
else if ( body . hashespersec )
net _hash = body . hashespersec ;
// check if there is a net hash value
if ( net _hash ) {
// return hash value with proper units
return cb ( convertHashUnits ( net _hash ) ) ;
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// netmhashps is blank/null
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
}
}
2020-12-07 21:32:43 -07:00
} ) ;
}
} else {
// getmininginfo cmd not set
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
}
2021-01-22 15:04:32 -07:00
} else if ( settings . shared _pages . page _header . panels . network _panel . nethash == 'getnetworkhashps' ) {
2020-12-07 21:32:43 -07:00
// load getnetworkhashps rpc call from settings
var cmd = prepareRpcCommand ( settings . api _cmds . getnetworkhashps ) ;
// check if the rpc cmd is valid
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
// check if getting data from wallet rpc or web api request
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
// get data from wallet via rpc cmd
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-17 17:54:09 -06:00
return cb ( '-' ) ;
2020-12-07 21:32:43 -07:00
// check if the response has a value
if ( response ) {
// return hash value with proper units
return cb ( convertHashUnits ( response ) ) ;
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// response is blank/null
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
}
2020-12-07 21:32:43 -07:00
} ) ;
} else {
// get data via internal web api request
var uri = base _url + 'getnetworkhashps' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` ) {
2020-12-07 21:32:43 -07:00
// return a blank value
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// return hash value with proper units
return cb ( convertHashUnits ( body ) ) ;
2020-11-22 16:06:53 -07:00
}
2020-12-07 21:32:43 -07:00
} ) ;
}
} else {
// getnetworkhashps cmd not set
return cb ( '-' ) ;
2020-11-22 16:06:53 -07:00
}
2020-12-07 21:32:43 -07:00
} else {
// Invalid network hashrate setting value
return cb ( '-' ) ;
2019-05-27 10:33:22 -07:00
}
} ,
get _difficulty : function ( cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getdifficulty ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getdifficulty' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _connectioncount : function ( cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getconnectioncount ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getconnectioncount' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
2020-12-30 18:22:02 -07:00
get _masternodelist : function ( cb ) {
var cmd = prepareRpcCommand ( settings . api _cmds . getmasternodelist ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-30 18:22:02 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-30 18:22:02 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getmasternodelist' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-30 18:22:02 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-30 18:22:02 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
} ,
2019-05-27 10:33:22 -07:00
get _masternodecount : function ( cb ) {
2023-11-03 18:42:34 -06:00
// 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' ] != '' ) {
var cmd = prepareRpcCommand ( settings . api _cmds . getmasternodecount ) ;
2020-12-07 21:32:43 -07:00
2023-11-03 18:42:34 -06:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
if ( settings . api _cmds . use _rpc ) {
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2023-11-03 18:42:34 -06:00
return cb ( null ) ;
else
2024-02-02 15:21:45 -07:00
return cb ( normalizeMasternodeCount ( response ) ) ;
2023-11-03 18:42:34 -06:00
} ) ;
} else {
var uri = base _url + 'getmasternodecount' ;
2021-03-17 17:54:09 -06:00
2023-11-03 18:42:34 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2023-11-03 18:42:34 -06:00
return cb ( null ) ;
else
2024-02-02 15:21:45 -07:00
return cb ( normalizeMasternodeCount ( body ) ) ;
2023-11-03 18:42:34 -06:00
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2020-12-07 21:32:43 -07:00
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
2019-05-27 10:33:22 -07:00
} ,
get _blockcount : function ( cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getblockcount ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getblockcount' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _blockhash : function ( height , cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getblockhash , ( height ? [ parseInt ( height ) ] : [ ] ) ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getblockhash?height=' + ( height ? height : '' ) ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:36:22 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-20 18:43:30 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _block : function ( hash , cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getblock , ( hash ? [ hash ] : [ ] ) ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getblock?hash=' + hash ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-20 18:43:30 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _rawtransaction : function ( hash , cb ) {
2020-12-07 21:32:43 -07:00
var cmd = prepareRpcCommand ( settings . api _cmds . getrawtransaction , ( hash ? [ hash , 1 ] : [ ] ) ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getrawtransaction?txid=' + hash + '&decrypt=1' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-20 18:56:25 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _maxmoney : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getmaxmoney ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getmaxmoney' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _maxvote : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getmaxvote ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getmaxvote' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _vote : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getvote ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getvote' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _phase : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getphase ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getphase' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _reward : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getreward ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getreward' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _estnext : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getnextrewardestimate ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getnextrewardestimate' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
get _nextin : function ( cb ) {
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getnextrewardwhenstr ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getnextrewardwhenstr' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2019-05-27 10:33:22 -07:00
} ,
2021-03-20 01:34:13 -06:00
get _descriptorinfo : function ( descriptor , cb ) {
// format the descriptor correctly for use in the getdescriptorinfo cmd
descriptor = 'pkh(' + descriptor . replace ( ' OP_CHECKSIG' , '' ) + ')' ;
var cmd = prepareRpcCommand ( settings . blockchain _specific . bitcoin . api _cmds . getdescriptorinfo , ( descriptor ? [ descriptor ] : [ ] ) ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
if ( settings . api _cmds . use _rpc ) {
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-20 01:34:13 -06:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getdescriptorinfo?descriptor=' + encodeURIComponent ( descriptor ) ;
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2021-03-20 01:34:13 -06:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-20 01:34:13 -06:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
} ,
get _deriveaddresses : function ( descriptor , cb ) {
var cmd = prepareRpcCommand ( settings . blockchain _specific . bitcoin . api _cmds . deriveaddresses , ( descriptor ? [ descriptor ] : [ ] ) ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
if ( settings . api _cmds . use _rpc ) {
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-20 01:34:13 -06:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'deriveaddresses?descriptor=' + encodeURIComponent ( descriptor ) ;
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2021-03-20 01:34:13 -06:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2021-03-20 01:34:13 -06:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
} ,
2019-05-27 10:33:22 -07:00
balance _supply : function ( cb ) {
2023-05-07 20:55:29 -06:00
Address . find ( { } , 'balance' ) . where ( 'balance' ) . gt ( 0 ) . exec ( ) . then ( ( docs ) => {
2025-02-02 19:10:17 -07:00
let count = 0 ;
2021-03-17 17:54:09 -06:00
2025-02-02 19:10:17 -07:00
async . eachSeries ( docs , function ( current _doc , loop ) {
count += current _doc . balance ;
loop ( ) ;
2021-01-22 15:04:32 -07:00
} , function ( ) {
2019-05-27 10:33:22 -07:00
return cb ( count ) ;
} ) ;
2023-05-07 20:55:29 -06:00
} ) . catch ( ( err ) => {
console . log ( err ) ;
return cb ( 0 ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ,
get _supply : function ( cb ) {
2021-01-22 15:04:32 -07:00
if ( settings . sync . supply == 'HEAVY' ) {
2020-12-07 21:32:43 -07:00
// attempt to get the supply from the getsupply or similar api cmd that returns the current money supply as a single positive decimal value
2021-01-22 15:04:32 -07:00
var cmd = prepareRpcCommand ( settings . blockchain _specific . heavycoin . api _cmds . getsupply ) ;
2020-12-07 21:32:43 -07:00
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getsupply' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2021-01-22 15:04:32 -07:00
} else if ( settings . sync . supply == 'GETINFO' ) {
2020-12-07 21:32:43 -07:00
// attempt to get the supply from the getinfo or similar api cmd that returns and object containing various state info. Must include a value called "moneysupply" which represents the current running total of coins
var cmd = prepareRpcCommand ( settings . api _cmds . getinfo ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( ! response || ! response . moneysupply || response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response . moneysupply ) ;
} ) ;
} else {
var uri = base _url + 'getinfo' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( ! body || ! body . moneysupply || body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body . moneysupply ) ;
} ) ;
}
2020-11-22 16:06:53 -07:00
} else {
2020-12-07 21:32:43 -07:00
// cmd not in use. return null.
return cb ( null ) ;
2020-11-22 16:06:53 -07:00
}
2021-01-22 15:04:32 -07:00
} else if ( settings . sync . supply == 'BALANCES' ) {
2020-12-07 21:32:43 -07:00
// get the supply by running a query on the addresses collection and summing up all positive balances (potentially a long running query for blockchains with tons of addresses)
module . exports . balance _supply ( function ( supply ) {
return cb ( supply / 100000000 ) ;
} ) ;
2021-01-22 15:04:32 -07:00
} else if ( settings . sync . supply == 'TXOUTSET' ) {
2020-12-07 21:32:43 -07:00
// attempt to get the supply from the gettxoutsetinfo or similar api cmd that returns an object with statistics about the unspent transaction output set. Must include a value called "total_amount" which represents the current running total of coins
var cmd = prepareRpcCommand ( settings . api _cmds . gettxoutsetinfo ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-07 21:32:43 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( ! response || ! response . total _amount || response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( response . total _amount ) ;
} ) ;
} else {
var uri = base _url + 'gettxoutsetinfo' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-07 21:32:43 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( ! body || ! body . total _amount || body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-07 21:32:43 -07:00
return cb ( null ) ;
else
return cb ( body . total _amount ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
2022-06-24 21:12:35 -06:00
} else if ( settings . sync . supply == 'GETBLOCKCHAININFO' ) {
// attempt to get the supply from the getblockchaininfo or similar api cmd that returns and object containing various state info. Must include a value called "moneysupply" which represents the current running total of coins
var cmd = prepareRpcCommand ( settings . api _cmds . getblockchaininfo ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
if ( settings . api _cmds . use _rpc ) {
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( ! response || ! response . moneysupply || response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2022-06-24 21:12:35 -06:00
return cb ( null ) ;
else
return cb ( response . moneysupply ) ;
} ) ;
} else {
var uri = base _url + 'getblockchaininfo' ;
request ( { uri : uri , json : true } , function ( error , response , body ) {
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( ! body || ! body . moneysupply || body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2022-06-24 21:12:35 -06:00
return cb ( null ) ;
else
return cb ( body . moneysupply ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
2020-12-07 21:32:43 -07:00
} else {
// returns coinbase total sent as current coin supply
coinbase _supply ( function ( supply ) {
return cb ( supply / 100000000 ) ;
} ) ;
2019-05-27 10:33:22 -07:00
}
} ,
2020-12-21 16:19:14 -07:00
get _peerinfo : function ( cb ) {
var cmd = prepareRpcCommand ( settings . api _cmds . getpeerinfo ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-21 16:19:14 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-21 16:19:14 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'getpeerinfo' ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-21 16:19:14 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-21 16:19:14 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
2020-12-21 18:12:40 -07:00
} ,
verify _message : function ( address , signature , message , cb ) {
var cmd = prepareRpcCommand ( settings . api _cmds . verifymessage , [ address , signature , message ] ) ;
if ( ! ( cmd . method == '' && cmd . parameters . length == 0 ) ) {
2021-01-22 15:04:32 -07:00
if ( settings . api _cmds . use _rpc ) {
2020-12-21 18:12:40 -07:00
rpcCommand ( [ { method : cmd . method , parameters : cmd . parameters } ] , function ( response ) {
// check if an error msg was received from the rpc server
2024-06-16 18:58:12 -06:00
if ( response == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-21 18:12:40 -07:00
return cb ( null ) ;
else
return cb ( response ) ;
} ) ;
} else {
var uri = base _url + 'verifymessage?address=' + address + '&signature=' + signature + '&message=' + message ;
2021-03-17 17:54:09 -06:00
2022-06-04 16:27:18 -06:00
request ( { uri : uri , json : true } , function ( error , response , body ) {
2020-12-21 18:12:40 -07:00
// check if an error msg was received from the web api server
2024-06-16 18:58:12 -06:00
if ( body == ` ${ settings . localization . ex _error } : ${ settings . localization . check _console } ` )
2020-12-21 18:12:40 -07:00
return cb ( null ) ;
else
return cb ( body ) ;
} ) ;
}
} else {
// cmd not in use. return null.
return cb ( null ) ;
}
} ,
2021-03-17 17:54:09 -06:00
2020-12-21 16:19:14 -07:00
get _geo _location : function ( address , cb ) {
2022-06-04 16:27:18 -06:00
request ( { uri : 'https://reallyfreegeoip.org/json/' + address , json : true } , function ( error , response , geo ) {
2020-12-21 16:19:14 -07:00
return cb ( error , geo ) ;
} ) ;
} ,
2019-05-27 10:33:22 -07:00
2025-02-02 19:10:17 -07:00
is _unique : function ( array , object , key _name ) {
for ( let i = 0 ; i < array . length ; i ++ ) {
if ( array [ i ] [ key _name ] === object )
return i ;
}
2021-03-17 17:54:09 -06:00
2025-02-02 19:10:17 -07:00
return - 1 ;
2019-05-27 10:33:22 -07:00
} ,
2025-02-02 19:10:17 -07:00
calculate _total : function ( vout ) {
let total = 0 ;
2021-03-17 17:54:09 -06:00
2025-02-02 19:10:17 -07:00
for ( let i = 0 ; i < vout . length ; i ++ )
total += vout [ i ] . amount ;
2021-03-17 17:54:09 -06:00
2025-02-02 19:10:17 -07:00
return total ;
2019-05-27 10:33:22 -07:00
} ,
2019-10-17 22:06:30 -06:00
prepare _vout : function ( vout , txid , vin , vhidden , cb ) {
2025-02-02 19:10:17 -07:00
let arr _vout = [ ] ;
let arr _vin = vin ;
let tx _type = null ;
2021-03-17 17:54:09 -06:00
2025-01-09 20:00:37 -07:00
try {
2025-02-02 19:10:17 -07:00
async . eachSeries ( vout , function ( current _vout , loop ) {
2025-01-09 20:00:37 -07:00
// make sure vout has an address
2025-02-02 19:10:17 -07:00
if ( current _vout . scriptPubKey . type != 'nonstandard' && current _vout . scriptPubKey . type != 'nulldata' ) {
2025-01-09 20:00:37 -07:00
// check if this is a zerocoin tx
2025-02-02 19:10:17 -07:00
if ( current _vout . scriptPubKey . type != 'zerocoinmint' ) {
const address _list = current _vout . scriptPubKey . addresses ;
2025-01-09 20:00:37 -07:00
// check if there are one or more addresses in the vout
if ( address _list == null || address _list . length == 0 ) {
// no addresses defined
// check if there is a single address defined
2025-02-02 19:10:17 -07:00
if ( current _vout . scriptPubKey . address == null ) {
2025-01-09 20:00:37 -07:00
// no single address defined
// check if bitcoin features are enabled
if ( settings . blockchain _specific . bitcoin . enabled == true ) {
// assume the asm value is a P2PK (Pay To Pubkey) public key that should be encoded as a P2PKH (Pay To Pubkey Hash) address
2025-02-02 19:10:17 -07:00
encodeP2PKaddress ( current _vout . scriptPubKey . asm , function ( p2pkh _address ) {
2025-01-09 20:00:37 -07:00
// check if the address was encoded properly
if ( p2pkh _address != null ) {
// mark this tx as p2pk
tx _type = 'p2pk' ;
2025-02-02 19:10:17 -07:00
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( p2pkh _address , current _vout . value , arr _vout ) ;
2025-01-09 20:00:37 -07:00
} else {
2025-02-02 19:10:17 -07:00
// could not decipher the address, save as unknown
2025-01-09 20:00:37 -07:00
console . log ( 'Failed to find vout address from tx ' + txid ) ;
2025-02-02 19:10:17 -07:00
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( [ 'unknown_address' ] , current _vout . value , arr _vout ) ;
2025-01-09 20:00:37 -07:00
}
2025-02-02 19:10:17 -07:00
// move to next vout
loop ( ) ;
2025-01-09 20:00:37 -07:00
} ) ;
} else {
// could not decipher the address, save as unknown and move to next vout
console . log ( 'Failed to find vout address from tx ' + txid ) ;
2025-02-02 19:10:17 -07:00
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( [ 'unknown_address' ] , current _vout . value , arr _vout ) ;
// move to next vout
loop ( ) ;
2025-01-09 20:00:37 -07:00
}
2021-11-20 11:02:29 -07:00
} else {
2025-02-02 19:10:17 -07:00
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( [ current _vout . scriptPubKey . address ] , current _vout . value , arr _vout ) ;
// move to next vout
loop ( ) ;
2021-11-20 11:02:29 -07:00
}
2021-01-22 15:04:32 -07:00
} else {
2025-02-02 19:10:17 -07:00
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( address _list , current _vout . value , arr _vout ) ;
// move to next vout
loop ( ) ;
2021-01-22 15:04:32 -07:00
}
2021-03-20 01:34:13 -06:00
} else {
2025-01-09 20:00:37 -07:00
// TODO: add support for zerocoin transactions
console . log ( 'Zerocoin tx found. skipping for now as it is unsupported' ) ;
tx _type = "zerocoin" ;
2025-02-02 19:10:17 -07:00
loop ( ) ;
2021-03-20 01:34:13 -06:00
}
2021-01-22 15:04:32 -07:00
} else {
2025-01-09 20:00:37 -07:00
// no address, move to next vout
2025-02-02 19:10:17 -07:00
loop ( ) ;
2021-01-22 15:04:32 -07:00
}
2025-01-09 20:00:37 -07:00
} , function ( ) {
2025-02-02 19:10:17 -07:00
// check if zksnarks is enabled and there are any hidden/anonymous outputs
if ( settings . blockchain _specific . zksnarks . enabled == true && vhidden != null && vhidden . length > 0 ) {
const hidden _address = 'hidden_address' ;
tx _type = 'zksnarks' ;
// loop through all hidden/anonymous outputs
async . eachSeries ( vhidden , function ( current _vhidden , loop ) {
if ( current _vhidden . vpub _old > 0 ) {
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( [ hidden _address ] , parseFloat ( current _vhidden . vpub _old ) , arr _vout ) ;
// move to next vout
loop ( ) ;
} else {
const amount _sat = module . exports . convert _to _satoshi ( parseFloat ( current _vhidden . vpub _new ) ) ;
const index = module . exports . is _unique ( arr _vin , hidden _address , 'addresses' ) ;
if ( ( ! vout || vout . length == 0 ) && ( ! vin || vin . length == 0 ) ) {
// hidden sender is sending to hidden recipient
// the sent and received values are not known in this case. only the fee paid is known and subtracted from the sender.
// process vout addresses and save the updated array
arr _vout = processVoutAddresses ( [ hidden _address ] , 0 , arr _vout ) ;
// add a private send address with the known amount sent
if ( index == - 1 ) {
// add hidden address to array
arr _vin . push ( { addresses : hidden _address , amount : amount _sat } ) ;
2025-01-09 20:00:37 -07:00
} else {
2025-02-02 19:10:17 -07:00
// update hidden address amount in array
arr _vin [ index ] . amount = arr _vin [ index ] . amount + amount _sat ;
2025-01-09 20:00:37 -07:00
}
2023-05-06 12:36:35 -06:00
2025-02-02 19:10:17 -07:00
// move to next vout
loop ( ) ;
} else {
// add a private send address with the known amount sent
if ( index == - 1 ) {
// add hidden address to array
arr _vin . push ( { addresses : hidden _address , amount : amount _sat } ) ;
} else {
// update hidden address amount in array
arr _vin [ index ] . amount += amount _sat ;
2025-01-09 20:00:37 -07:00
}
2023-05-06 12:36:35 -06:00
2025-02-02 19:10:17 -07:00
// move to next vout
loop ( ) ;
2023-05-06 12:36:35 -06:00
}
2025-02-02 19:10:17 -07:00
}
} , function ( ) {
// finished updating hidden vout data
finalize _vout ( vout [ 0 ] , arr _vout , arr _vin , tx _type , txid , function ( final _arr _vout , final _arr _vin , final _tx _type ) {
return cb ( final _arr _vout , final _arr _vin , final _tx _type ) ;
} ) ;
} ) ;
} else {
// finalize vout data
finalize _vout ( vout [ 0 ] , arr _vout , arr _vin , tx _type , txid , function ( final _arr _vout , final _arr _vin , final _tx _type ) {
return cb ( final _arr _vout , final _arr _vin , final _tx _type ) ;
} ) ;
}
2025-01-09 20:00:37 -07:00
} ) ;
} catch ( err ) {
// check if a "Maximum call stack size exceeded" error occurred
if ( err instanceof RangeError && /Maximum call stack size exceeded/i . test ( err . message ) ) {
// return invalid results with error msg
return cb ( null , null , 'StackSizeError' ) ;
} else {
// any other error should be output normally
throw err ;
}
}
2019-05-27 10:33:22 -07:00
} ,
prepare _vin : function ( tx , cb ) {
2025-02-02 19:10:17 -07:00
let arr _vin = [ ] ;
let tx _type = null ;
2021-03-17 17:54:09 -06:00
2025-02-02 19:10:17 -07:00
async . eachSeries ( tx . vin , function ( vin , loop ) {
get _input _addresses ( vin , tx . vout , function ( addresses , tx _type _vin ) {
2021-03-20 01:34:13 -06:00
// check if the tx type is set
if ( tx _type _vin != null ) {
// set the tx type return value
tx _type = tx _type _vin ;
}
2019-05-27 10:33:22 -07:00
if ( addresses && addresses . length ) {
2025-02-02 19:10:17 -07:00
const amount _sat = module . exports . convert _to _satoshi ( parseFloat ( addresses [ 0 ] . amount ) ) ;
const index = module . exports . is _unique ( arr _vin , addresses [ 0 ] . hash , 'addresses' ) ;
if ( index == - 1 )
arr _vin . push ( { addresses : addresses [ 0 ] . hash , amount : amount _sat } ) ;
else
arr _vin [ index ] . amount += amount _sat ;
loop ( ) ;
2021-03-20 01:34:13 -06:00
} else {
// could not decipher the address, save as unknown and move to next vin
console . log ( 'Failed to find vin address from tx ' + tx . txid ) ;
2021-03-21 19:10:30 -06:00
2025-02-02 19:10:17 -07:00
const index = module . exports . is _unique ( arr _vin , 'unknown_address' , 'addresses' ) ;
if ( index == - 1 )
arr _vin . push ( { addresses : 'unknown_address' , amount : 0 } ) ;
loop ( ) ;
2021-03-20 01:34:13 -06:00
}
2019-05-27 10:33:22 -07:00
} ) ;
2021-03-17 17:54:09 -06:00
} , function ( ) {
2021-03-20 01:34:13 -06:00
return cb ( arr _vin , tx _type ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2022-04-30 20:53:10 -06:00
} ,
create _lock : function ( lock ) {
const fs = require ( 'fs' ) ;
var fname = './tmp/' + lock + '.pid' ;
try {
fs . appendFileSync ( fname , process . pid . toString ( ) ) ;
return true ;
} catch ( err ) {
console . log ( "Error: Unable to remove lock: %s" , fname ) ;
return false ;
}
} ,
remove _lock : function ( lock ) {
const fs = require ( 'fs' ) ;
var fname = './tmp/' + lock + '.pid' ;
try {
fs . unlinkSync ( fname ) ;
return true ;
} catch ( err ) {
console . log ( "Error: Unable to remove lock: %s" , fname ) ;
return false ;
}
} ,
2022-07-03 19:13:50 -06:00
is _locked : function ( lock _array , silent = false ) {
2022-04-30 20:53:10 -06:00
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
var retVal = false ;
// loop through all lock files that need to be checked
for ( var i = 0 ; i < lock _array . length ; i ++ ) {
var pidFile = path . join ( path . dirname ( _ _dirname ) , 'tmp' , ` ${ lock _array [ i ] } .pid ` ) ;
// check if the script is already running (tmp/file.pid file already exists)
if ( fs . existsSync ( pidFile ) ) {
const { execSync } = require ( 'child_process' ) ;
var deactivateLock = false ;
// the pid file exists
// determine the operating system
switch ( process . platform ) {
case 'win32' :
// windows
// run a cmd that will determine if the lock should still be active
var cmdResult = execSync ( ` tasklist /FI "PID eq ${ fs . readFileSync ( pidFile ) . toString ( ) } " ` ) ;
// check if the process that created the lock is actually still running (crude check by testing for # of carriage returns or node.exe process running, but should work universally across different systems and languages)
if ( cmdResult . toString ( ) . split ( '\n' ) . length < 4 || cmdResult . toString ( ) . toLowerCase ( ) . indexOf ( '\nnode.exe' ) == - 1 ) {
// lock should be deactivated
deactivateLock = true ;
}
break ;
default :
// linux or other
// run a cmd that will determine if the lock should still be active
try {
2022-07-03 20:00:07 -06:00
var cmdResult = execSync ( 'ps -p `cat "' + pidFile + '"` > /dev/null' ) ;
2022-04-30 20:53:10 -06:00
} catch ( err ) {
// if an error occurs, the process is NOT running and therefore the lock should be deactivated
deactivateLock = true ;
}
}
// check if the lock should be deactivated
if ( deactivateLock ) {
// script is not actually running so the lock file can be deleted
try {
fs . rmSync ( pidFile ) ;
} catch ( err ) {
2022-07-03 19:13:50 -06:00
if ( ! silent )
console . log ( ` Failed to delete lock file ${ pidFile } : ${ err } ` ) ;
2022-04-30 20:53:10 -06:00
}
} else {
// script is running
2022-07-03 19:13:50 -06:00
if ( ! silent )
console . log ( ` ${ lock _array [ i ] } script is running.. ` ) ;
2022-04-30 20:53:10 -06:00
retVal = true ;
break ;
}
}
}
return retVal ;
2024-01-05 00:47:22 -07:00
} ,
get _market _currency _code : function ( ) {
let currency = '' ;
// check if the market price is being updated by coingecko api
if ( settings . markets _page . market _price == 'COINGECKO' ) {
currency = ( settings . markets _page . coingecko _currency == null || settings . markets _page . coingecko _currency == '' ? '' : settings . markets _page . coingecko _currency ) ;
} else if ( settings . markets _page . default _exchange . trading _pair != null && settings . markets _page . default _exchange . trading _pair . indexOf ( '/' ) > - 1 ) {
currency = settings . markets _page . default _exchange . trading _pair . split ( '/' ) [ 1 ] ;
}
return currency ;
2019-05-27 10:33:22 -07:00
}
} ;