@ -36,7 +36,9 @@ var guiLog = {};
var rpcConf = { } ;
var appRuntimeLog = [ ] ;
var lockDownAddCoin = false ;
var electrumCoins = { } ;
var electrumCoins = {
auth : false ,
} ;
const electrumJSCore = require ( './electrumjs/electrumjs.core.js' ) ;
const electrumJSNetworks = require ( './electrumjs/electrumjs.networks.js' ) ;
@ -47,6 +49,13 @@ const electrumServers = {
port : 50032 ,
proto : 'tcp' ,
} , * /
revs : { // !estimatefee
address : '173.212.225.176' ,
port : 50050 ,
proto : 'tcp' ,
txfee : 10000 ,
abbr : 'REVS' ,
} ,
komodo : { // !estimatefee
address : '173.212.225.176' ,
port : 50011 ,
@ -237,8 +246,8 @@ shepherd.seedToWif = function(seed, network, iguana) {
key . compressed = true ;
console . log ( 'seedtowif priv key' + key . privateWif ) ;
console . log ( 'seedtowif pub key' + key . publicAddress ) ;
console . log ( 'seedtowif priv key ' + key . privateWif ) ;
console . log ( 'seedtowif pub key ' + key . publicAddress ) ;
return {
priv : key . privateWif ,
@ -259,11 +268,38 @@ shepherd.get('/electrum/seedtowif', function(req, res, next) {
res . end ( JSON . stringify ( successObj ) ) ;
} ) ;
shepherd . findNetworkObj = function ( coin ) {
for ( let key in electrumServers ) {
if ( electrumServers [ key ] . abbr === coin ) {
return key ;
}
}
}
shepherd . get ( '/electrum/login' , function ( req , res , next ) {
const keys = shepherd . seedToWif ( req . query . seed , req . query . network , req . query . iguana ) ;
for ( let key in electrumCoins ) {
if ( key !== 'auth' ) {
const keys = shepherd . seedToWif ( req . query . seed , shepherd . findNetworkObj ( key ) , req . query . iguana ) ;
electrumCoins [ key ] . priv = keys . priv ;
electrumCoins [ key ] . pub = keys . pub ;
}
}
electrumCoins [ coin ] . priv = keys . priv ;
electrumCoins [ coin ] . pub = keys . pub ;
electrumCoins . auth = true ;
console . log ( JSON . stringify ( electrumCoins , null , '\t' ) ) ;
const successObj = {
msg : 'success' ,
result : 'true'
} ;
res . end ( JSON . stringify ( successObj ) ) ;
} ) ;
shepherd . get ( '/electrum/dev/logout' , function ( req , res , next ) {
electrumCoins . auth = false ;
const successObj = {
msg : 'success' ,
@ -279,7 +315,7 @@ shepherd.get('/electrum/bip39/seed', function(req, res, next) {
var crypto = require ( 'crypto' ) ;
// what you describe as 'seed'
var randomBytes = crypto . randomBytes ( 16 ) ; // 128 bits is enough
var randomBytes = crypto . randomBytes ( 16 ) ; // 128 bits is enough
// your 12 word phrase
var mnemonic = bip39 . entropyToMnemonic ( randomBytes . toString ( 'hex' ) ) ;
@ -336,6 +372,7 @@ shepherd.addElectrumCoin = function(coin, serverID) {
ip : electrumServers [ key ] . address ,
port : electrumServers [ key ] . port ,
} ,
txfee : electrumServers [ key ] . txfee ,
} ;
return true ;
@ -359,12 +396,11 @@ shepherd.get('/electrum/coins/add', function(req, res, next) {
} ) ;
shepherd . get ( '/electrum/coins' , function ( req , res , next ) {
let _ electrumCoins = Object . assign ( { } , electrumCoins ) ;
let _ electrumCoins = JSON . parse ( JSON . stringify ( electrumCoins ) ) ; // deep cloning
for ( let key in electrumServers ) {
if ( _ electrumCoins [ key ] . wif ) {
_ electrumCoins [ key ] . wif = null ;
_ electrumCoins [ key ] . priv = null ;
for ( let key in _ electrumCoins ) {
if ( _ electrumCoins [ key ] . priv ) {
delete _ electrumCoins [ key ] . priv ;
}
}
@ -377,19 +413,22 @@ shepherd.get('/electrum/coins', function(req, res, next) {
} ) ;
shepherd . get ( '/electrum/getbalance' , function ( req , res , next ) {
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
const network = req . query . network || shepherd . findNetworkObj ( req . query . coin ) ;
const ecl = new electrumJSCore ( electrumServers [ network ] . port , electrumServers [ network ] . address , electrumServers [ network ] . proto ) ; // tcp or tls
ecl . connect ( ) ;
ecl . blockchainAddressGetBalance ( req . query . address )
. then ( ( json ) => {
ecl . close ( ) ;
console . log ( 'electrum getbalance ==>' ) ;
console . log ( 0.00000001 * json . confirmed ) ;
console . log ( json ) ;
const successObj = {
msg : 'success' ,
result : {
balance : 0.00000001 * json . confirmed ,
unconfirmed : json . unconfirmed ,
sats : json . confirmed ,
} ,
} ;
@ -397,8 +436,23 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
} ) ;
} ) ;
shepherd . get ( '/electrum/listtransactions' , function ( req , res , next ) {
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
shepherd . sortTransactions = function ( transactions ) {
return transactions . sort ( function ( b , a ) {
if ( a . height < b . height ) {
return - 1 ;
}
if ( a . height > b . height ) {
return 1 ;
}
return 0 ;
} ) ;
}
/ * s h e p h e r d . g e t ( ' / e l e c t r u m / l i s t t r a n s a c t i o n s ' , f u n c t i o n ( r e q , r e s , n e x t ) {
const network = req . query . network || shepherd . findNetworkObj ( req . query . coin ) ;
const ecl = new electrumJSCore ( electrumServers [ network ] . port , electrumServers [ network ] . address , electrumServers [ network ] . proto ) ; // tcp or tls
if ( ! req . query . full ) {
ecl . connect ( ) ;
@ -408,6 +462,8 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console . log ( 'electrum listtransactions ==>' ) ;
console . log ( json ) ;
json = shepherd . sortTransactions ( json ) ;
const successObj = {
msg : 'success' ,
result : {
@ -430,6 +486,7 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
. then ( ( json ) => {
if ( json &&
json . length ) {
json = shepherd . sortTransactions ( json ) ;
json = json . slice ( 0 , MAX_TX ) ;
console . log ( json . length ) ;
let _ rawtx = [ ] ;
@ -443,7 +500,7 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console . log ( _ json ) ;
// decode tx
const _ network = electrumJSNetworks [ req . query . network ] ;
const _ network = electrumJSNetworks [ network ] ;
const decodedTx = electrumJSTxDecoder ( _ json , _ network ) ;
// TODO: multi vin
@ -502,10 +559,17 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
let result = [ ] ;
for ( let i = 0 ; i < _ rawtx . length ; i ++ ) {
result = result . concat ( shepherd . parseTransactionAddresses ( _ rawtx [ i ] , req . query . address ) ) ;
}
const successObj = {
msg : 'success' ,
result : {
listtransactions : _ rawtx ,
//listtransactions: _rawtx,
listtransactions : result ,
} ,
} ;
@ -520,8 +584,275 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
} ) ;
} ) ;
}
} ) ; * /
shepherd . get ( '/electrum/listtransactions' , function ( req , res , next ) {
const network = req . query . network || shepherd . findNetworkObj ( req . query . coin ) ;
const ecl = new electrumJSCore ( electrumServers [ network ] . port , electrumServers [ network ] . address , electrumServers [ network ] . proto ) ; // tcp or tls
if ( ! req . query . full ) {
ecl . connect ( ) ;
ecl . blockchainAddressGetHistory ( req . query . address )
. then ( ( json ) => {
ecl . close ( ) ;
console . log ( 'electrum listtransactions ==>' ) ;
console . log ( json ) ;
json = shepherd . sortTransactions ( json ) ;
const successObj = {
msg : 'success' ,
result : {
listtransactions : json ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
} ) ;
} else {
// !expensive call!
// TODO: limit e.g. 1-10, 10-20 etc
const MAX_TX = 10 ;
ecl . connect ( ) ;
ecl . blockchainNumblocksSubscribe ( )
. then ( function ( currentHeight ) {
ecl . blockchainAddressGetHistory ( req . query . address )
. then ( ( json ) => {
if ( json &&
json . length ) {
json = shepherd . sortTransactions ( json ) ;
json = json . slice ( 0 , MAX_TX ) ;
console . log ( json . length ) ;
let _ rawtx = [ ] ;
// get raw tx
for ( let i = 0 ; i < json . length ; i ++ ) {
ecl . blockchainBlockGetHeader ( json [ i ] . height )
. then ( ( blockInfo ) => {
ecl . blockchainTransactionGet ( json [ i ] [ 'tx_hash' ] )
. then ( ( _ rawtxJSON ) => {
console . log ( 'electrum gettransaction ==>' ) ;
console . log ( i + ' | ' + ( _ rawtxJSON . length - 1 ) ) ;
console . log ( _ rawtxJSON ) ;
// decode tx
const _ network = electrumJSNetworks [ network ] ;
const decodedTx = electrumJSTxDecoder ( _ rawtxJSON , _ network ) ;
let txInputs = [ ] ;
console . log ( 'decodedtx =>' ) ;
console . log ( decodedTx . outputs ) ;
if ( decodedTx . inputs ) {
for ( let j = 0 ; j < decodedTx . inputs . length ; j ++ ) {
if ( decodedTx . inputs [ j ] . txid !== '0000000000000000000000000000000000000000000000000000000000000000' ) {
ecl . blockchainTransactionGet ( decodedTx . inputs [ j ] . txid )
. then ( ( rawInput ) => {
console . log ( 'electrum raw input tx ==>' ) ;
//console.log
const decodedVinVout = electrumJSTxDecoder ( rawInput , _ network ) ;
console . log ( decodedVinVout . outputs [ decodedTx . inputs [ j ] . n ] ) ;
txInputs . push ( decodedVinVout . outputs [ decodedTx . inputs [ j ] . n ] ) ;
if ( j === decodedTx . inputs . length - 1 ) {
const _ parsedTx = {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : txInputs ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : blockInfo . timestamp ,
confirmations : currentHeight - json [ i ] . height ,
} ;
const formattedTx = shepherd . parseTransactionAddresses ( _ parsedTx , req . query . address ) ;
if ( formattedTx . type ) {
_ rawtx . push ( formattedTx ) ;
} else {
_ rawtx . push ( formattedTx [ 0 ] ) ;
_ rawtx . push ( formattedTx [ 1 ] ) ;
}
if ( i === json . length - 1 ) {
ecl . close ( ) ;
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
const successObj = {
msg : 'success' ,
result : {
listtransactions : _ rawtx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
}
} ) ;
} else {
if ( j === decodedTx . inputs . length - 1 ) {
const _ parsedTx = {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : txInputs ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : blockInfo . timestamp ,
confirmations : currentHeight - json [ i ] . height ,
} ;
const formattedTx = shepherd . parseTransactionAddresses ( _ parsedTx , req . query . address ) ;
if ( formattedTx . type ) {
_ rawtx . push ( formattedTx ) ;
} else {
_ rawtx . push ( formattedTx [ 0 ] ) ;
_ rawtx . push ( formattedTx [ 1 ] ) ;
}
if ( i === json . length - 1 ) {
ecl . close ( ) ;
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
const successObj = {
msg : 'success' ,
result : {
listtransactions : _ rawtx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
}
}
}
} else {
const _ parsedTx = {
network : decodedTx . network ,
format : 'cant parse' ,
inputs : 'cant parse' ,
outputs : 'cant parse' ,
height : json [ i ] . height ,
timestamp : blockInfo . timestamp ,
confirmations : currentHeight - json [ i ] . height ,
} ;
const formattedTx = shepherd . parseTransactionAddresses ( _ parsedTx , req . query . address ) ;
_ rawtx . push ( formattedTx ) ;
if ( i === json . length - 1 ) {
ecl . close ( ) ;
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
const successObj = {
msg : 'success' ,
result : {
listtransactions : _ rawtx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
}
} ) ;
} ) ;
}
} else {
const successObj = {
msg : 'success' ,
result : {
listtransactions : [ ] ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
} ) ;
} ) ;
}
} ) ;
// TODO: multi vin
/ * i f ( d e c o d e d T x . i n p u t s [ 0 ] . t x i d = = = ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ' ) {
ecl . blockchainBlockGetHeader ( json [ i ] . height )
. then ( ( blockInfo ) => {
_ rawtx . push ( {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : decodedTx . inputs ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : blockInfo . timestamp ,
confirmations : currentHeight - json [ i ] . height ,
miner : true ,
} ) ;
if ( i === json . length - 1 ) {
ecl . close ( ) ;
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
const successObj = {
msg : 'success' ,
result : {
listtransactions : _ rawtx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
} ) ;
} else {
// get vin tx, decode
ecl . blockchainBlockGetHeader ( json [ i ] . height )
. then ( ( blockInfo ) => {
ecl . blockchainTransactionGet ( decodedTx . inputs [ 0 ] . txid )
. then ( ( __ json ) => {
console . log ( 'electrum decoderawtx input tx ==>' ) ;
console . log ( __ json ) ;
const decodedVin = electrumJSTxDecoder ( __ json , _ network ) ;
_ rawtx . push ( {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : decodedVin . outputs [ decodedTx . inputs [ 0 ] . n ] ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : blockInfo . timestamp ,
confirmations : currentHeight - json [ i ] . height ,
} ) ;
if ( i === json . length - 1 ) {
ecl . close ( ) ;
console . log ( 'electrum gettransaction array ==>' ) ;
console . log ( _ rawtx ) ;
let result = [ ] ;
for ( let i = 0 ; i < _ rawtx . length ; i ++ ) {
result = result . concat ( shepherd . parseTransactionAddresses ( _ rawtx [ i ] , req . query . address ) ) ;
}
const successObj = {
msg : 'success' ,
result : {
//listtransactions: _rawtx,
listtransactions : result ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
} ) ;
} ) ;
} * /
shepherd . get ( '/electrum/gettransaction' , function ( req , res , next ) {
// TODO: block time, confs, current height
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
@ -544,8 +875,83 @@ shepherd.get('/electrum/gettransaction', function(req, res, next) {
} ) ;
} ) ;
shepherd . get ( '/electrum/gettransactiontest' , function ( req , res , next ) {
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
ecl . connect ( ) ;
ecl . blockchainTransactionGet ( req . query . txid )
. then ( ( json ) => {
console . log ( 'electrum gettransaction ==>' ) ;
console . log ( json ) ;
const _ network = electrumJSNetworks [ req . query . network ] ;
const decodedTx = electrumJSTxDecoder ( json , _ network ) ;
let txInputs = [ ] ;
console . log ( 'decodedtx =>' ) ;
console . log ( decodedTx . outputs ) ;
for ( let i = 0 ; i < decodedTx . inputs . length ; i ++ ) {
if ( decodedTx . inputs [ i ] . txid !== '0000000000000000000000000000000000000000000000000000000000000000' ) {
ecl . blockchainTransactionGet ( decodedTx . inputs [ i ] . txid )
. then ( ( rawInput ) => {
console . log ( 'electrum raw input tx ==>' ) ;
//console.log
const decodedVinVout = electrumJSTxDecoder ( rawInput , _ network ) ;
console . log ( decodedVinVout . outputs [ decodedTx . inputs [ i ] . n ] ) ;
txInputs . push ( decodedVinVout . outputs [ decodedTx . inputs [ i ] . n ] ) ;
if ( i === decodedTx . inputs . length - 1 ) {
const _ parsedTx = {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : txInputs ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : 0 /*blockInfo.timestamp*/ ,
confirmations : 0 /*currentHeight - json[i].height*/ ,
} ;
shepherd . parseTransactionAddresses ( _ parsedTx , req . query . address ) ;
ecl . close ( ) ;
const successObj = {
msg : 'success' ,
result : {
gettransaction : _ parsedTx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
} ) ;
} else {
if ( i === decodedTx . inputs . length - 1 ) {
const _ parsedTx = {
network : decodedTx . network ,
format : decodedTx . format ,
inputs : txInputs ,
outputs : decodedTx . outputs ,
height : json [ i ] . height ,
timestamp : 0 /*blockInfo.timestamp*/ ,
confirmations : 0 /*currentHeight - json[i].height*/ ,
} ;
shepherd . parseTransactionAddresses ( _ parsedTx , req . query . address ) ;
const successObj = {
msg : 'success' ,
result : {
gettransaction : _ parsedTx ,
} ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
}
}
}
} ) ;
} ) ;
shepherd . parseTransactionAddresses = function ( tx , targetAddress ) {
// TODO: - mined flag
// TODO: - sum vins / sum vouts to the same address
// - multi vin multi vout
// - detect change address
let result = [ ] ;
@ -554,6 +960,21 @@ shepherd.parseTransactionAddresses = function(tx, targetAddress) {
outputs : { } ,
} ;
let addressFound = false ;
let _ sum = {
inputs : 0 ,
outputs : 0 ,
} ;
if ( tx . format === 'cant parse' ) {
return {
type : 'unknown' ,
amount : 'unknown' ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
}
}
for ( let key in _ parse ) {
if ( ! tx [ key ] . length ) {
@ -566,19 +987,28 @@ shepherd.parseTransactionAddresses = function(tx, targetAddress) {
for ( let i = 0 ; i < _ parse [ key ] . length ; i ++ ) {
console . log ( key + ' ==>' ) ;
console . log ( _ parse [ key ] [ i ] ) ;
if ( key === 'outputs' ||
( key === 'inputs' && _ parse [ key ] [ i ] . scriptPubKey . addresses && _ parse [ key ] [ i ] . value ) ) {
console . log ( Number ( _ parse [ key ] [ i ] . value ) ) ;
if ( _ parse [ key ] [ i ] . scriptPubKey &&
_ parse [ key ] [ i ] . scriptPubKey . addresses &&
_ parse [ key ] [ i ] . scriptPubKey . addresses [ 0 ] === targetAddress &&
_ parse [ key ] [ i ] . value ) {
_ sum [ key ] += Number ( _ parse [ key ] [ i ] . value ) ;
}
/ * i f ( k e y = = = ' o u t p u t s ' | |
( key === 'inputs' && _ parse [ key ] [ i ] . scriptPubKey && _ parse [ key ] [ i ] . scriptPubKey . addresses && _ parse [ key ] [ i ] . value ) ) {
if ( ! targetAddress || ( targetAddress === _ parse [ key ] [ i ] . scriptPubKey . addresses [ 0 ] && ! addressFound ) ) {
let _ type ;
if ( tx . miner ) {
_ type = 'miner' ;
} else {
_ type = key === 'inputs' ? 'out' : 'in' ;
_ type = key === 'inputs' ? 'sent' : 'received ' ;
}
result . push ( {
type : _ type , // flip
value : _ parse [ key ] [ i ] . value ,
amount : Number ( _ parse [ key ] [ i ] . value ) ,
address : _ parse [ key ] [ i ] . scriptPubKey . addresses [ 0 ] ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
@ -587,11 +1017,62 @@ shepherd.parseTransactionAddresses = function(tx, targetAddress) {
addressFound = true ;
}
}
} * /
}
}
if ( _ sum . inputs > 0 &&
_ sum . outputs > 0 ) {
// vin + change, break into two tx
result = [ { // reorder since tx sort by default is from newest to oldest
type : 'sent' ,
amount : Number ( _ sum . inputs ) ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
} , {
type : 'received' ,
amount : Number ( _ sum . outputs ) ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
} ] ;
} else if ( _ sum . inputs === 0 && _ sum . outputs > 0 ) {
result = {
type : 'received' ,
amount : Number ( _ sum . outputs ) ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
} ;
} else if ( _ sum . inputs > 0 && _ sum . outputs === 0 ) {
result = {
type : 'sent' ,
amount : Number ( _ sum . inputs ) ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
} ;
} else {
// (?)
result = {
type : 'other' ,
amount : 'unknown' ,
address : targetAddress ,
timestamp : tx . timestamp ,
txid : tx . format . txid ,
confirmations : tx . confirmations ,
} ;
}
console . log ( 'parseTransactionAddresses result ==>' ) ;
console . log ( _ sum ) ;
console . log ( result ) ;
return result ;
}
@ -783,14 +1264,15 @@ shepherd.findUtxoSet = function(utxoList, target) {
let sum = 0 ;
function findUtxoSubset ( ) {
if ( utxoList [ 0 ] . value >= target ) {
if ( Number ( utxoList [ 0 ] . value ) >= Number ( target ) ) {
sum = utxoList [ 0 ] . value ;
result . push ( utxoList [ 0 ] ) ;
} else {
for ( let i = 0 ; i < utxoList . length ; i ++ ) {
if ( sum < target ) {
sum += Number ( utxoList [ i ] . value ) ;
result . push ( utxoList [ i ] ) ;
} else {
sum += Number ( utxoList [ i ] . value ) ;
result . push ( utxoList [ i ] ) ;
if ( sum >= Number ( target ) ) {
break ;
}
}
@ -845,8 +1327,14 @@ shepherd.buildSignedTx = function(sendTo, changeAddress, wif, network, utxo, cha
}
tx . addOutput ( sendTo , Number ( spendValue ) ) ;
tx . addOutput ( changeAddress , Number ( changeValue ) ) ;
if ( changeValue > 0 ) {
tx . addOutput ( changeAddress , Number ( changeValue ) ) ;
}
console . log ( 'buildSignedTx unsigned tx data vin' ) ;
console . log ( tx . tx . ins ) ;
console . log ( 'buildSignedTx unsigned tx data vout' ) ;
console . log ( tx . tx . outs ) ;
console . log ( 'buildSignedTx unsigned tx data' ) ;
console . log ( tx ) ;
@ -861,14 +1349,35 @@ shepherd.buildSignedTx = function(sendTo, changeAddress, wif, network, utxo, cha
return rawtx ;
}
shepherd . maxSpendBalance = function ( utxoList , fee ) {
let maxSpendBalance = 0 ;
for ( let i = 0 ; i < utxoList . length ; i ++ ) {
maxSpendBalance += Number ( utxoList [ i ] . value ) ;
}
if ( fee ) {
return Number ( maxSpendBalance ) - Number ( fee ) ;
} else {
return maxSpendBalance ;
}
}
shepherd . get ( '/electrum/createrawtx' , function ( req , res , next ) {
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
const network = req . query . network || shepherd . findNetworkObj ( req . query . coin ) ;
const ecl = new electrumJSCore ( electrumServers [ network ] . port , electrumServers [ network ] . address , electrumServers [ network ] . proto ) ; // tcp or tls
const outputAddress = req . query . address ;
const changeAddress = req . query . change ;
const wif = req . query . wif ;
le t wif = req . query . wif ;
const value = req . query . value ;
const network = req . query . network ;
const push = req . query . push ;
const fee = electrumServers [ network ] . txfee ;
console . log ( electrumCoins [ req . query . coin ] ) ;
if ( req . query . gui ) {
wif = electrumCoins [ req . query . coin ] . priv ;
}
ecl . connect ( ) ;
ecl . blockchainAddressListunspent ( changeAddress )
@ -877,9 +1386,21 @@ shepherd.get('/electrum/createrawtx', function(req, res, next) {
console . log ( 'electrum listunspent ==>' ) ;
const _ utxoSet = shepherd . findUtxoSet ( utxoList , Number ( req . query . value ) + Number ( electrumServers [ req . query . network ] . txfee ) ) ; // target + txfee
let _ value = Number ( value ) + Number ( fee ) ;
let _ utxoSet = shepherd . findUtxoSet ( utxoList , _ value ) ; // target + txfee
const _ rawtx = shepherd . buildSignedTx ( outputAddress , changeAddress , wif , network , _ utxoSet . set , _ utxoSet . change , value ) ;
if ( Number ( value ) >= shepherd . maxSpendBalance ( utxoList , fee ) ) {
_ value = shepherd . maxSpendBalance ( utxoList , fee ) ;
_ utxoSet = {
set : utxoList ,
change : 0 ,
} ;
}
console . log ( 'maxspend ' + shepherd . maxSpendBalance ( utxoList , fee ) ) ;
console . log ( 'value ' + value ) ;
const _ rawtx = shepherd . buildSignedTx ( outputAddress , changeAddress , wif , network , _ utxoSet . set , _ utxoSet . change , _ utxoSet . change <= 0 ? _ value : value ) ;
if ( ! push ) {
const successObj = {
@ -887,7 +1408,8 @@ shepherd.get('/electrum/createrawtx', function(req, res, next) {
result : {
utxoSet : _ utxoSet . set ,
change : _ utxoSet . change ,
wif ,
// wif,
fee ,
value ,
outputAddress ,
changeAddress ,
@ -898,7 +1420,7 @@ shepherd.get('/electrum/createrawtx', function(req, res, next) {
res . end ( JSON . stringify ( successObj ) ) ;
} else {
const ecl = new electrumJSCore ( electrumServers [ req . query . network ] . port , electrumServers [ req . query . network ] . address , electrumServers [ req . query . network ] . proto ) ; // tcp or tls
const ecl = new electrumJSCore ( electrumServers [ network ] . port , electrumServers [ network ] . address , electrumServers [ network ] . proto ) ; // tcp or tls
ecl . connect ( ) ;
ecl . blockchainTransactionBroadcast ( _ rawtx )
@ -3007,7 +3529,9 @@ shepherd.get('/InstantDEX/allcoins', function(req, res, next) {
let electrumCoinsList = [ ] ;
for ( let key in electrumCoins ) {
electrumCoinsList . push ( electrumCoins [ key ] . abbr ) ;
if ( key !== 'auth' ) {
electrumCoinsList . push ( electrumCoins [ key ] . abbr ) ;
}
}
for ( let key in coindInstanceRegistry ) {
@ -3017,6 +3541,7 @@ shepherd.get('/InstantDEX/allcoins', function(req, res, next) {
successObj = {
native : nativeCoindList ,
spv : electrumCoinsList ,
total : Object . keys ( electrumCoins ) . length - 1 + Object . keys ( nativeCoindList ) . length ,
} ;
res . end ( JSON . stringify ( successObj ) ) ;
@ -3026,14 +3551,27 @@ shepherd.get('/InstantDEX/allcoins', function(req, res, next) {
* type : GET
*
* /
shepherd . get ( '/SuperNET/activehandle ' , function ( req , res , next ) { // not finished
shepherd . get ( '/auth/status ' , function ( req , res , next ) { // not finished
let successObj ;
let _ status = false ;
if ( Object . keys ( coindInstanceRegistry ) . length ) {
if ( Object . keys ( electrumCoins ) . length > 1 && electrumCoins . auth ) {
_ status = true ;
} else if ( Object . keys ( electrumCoins ) . length === 1 && ! electrumCoins . auth ) {
_ status = true ;
}
} else if ( Object . keys ( electrumCoins ) . length > 1 && electrumCoins . auth ) {
_ status = true ;
} else if ( Object . keys ( electrumCoins ) . length === 1 && ! Object . keys ( coindInstanceRegistry ) . length ) {
_ status = true ;
}
successObj = {
pubkey : 'nativeonly' ,
result : 'success' ,
handle : '' ,
status : Object . keys ( coindInstanceRegistry ) . length ? 'unlocked' : 'locked' ,
status : _ status ? 'unlocked' : 'locked' ,
duration : 2507830 ,
} ;