Browse Source

spv jumblr; select spv server

v0.25
pbca26 7 years ago
parent
commit
e84d0186db
  1. 11
      routes/electrumjs/electrumjs.networks.js
  2. 239
      routes/shepherd.js

11
routes/electrumjs/electrumjs.networks.js

@ -95,17 +95,6 @@ networks.komodo = {
wif: 0xbc,
dustThreshold: 1000,
};
networks.revs = {
messagePrefix: '\x19Komodo Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4,
},
pubKeyHash: 0x3c,
scriptHash: 0x55,
wif: 0xbc,
dustThreshold: 1000,
};
networks.viacoin = {
messagePrefix: '\x19Viacoin Signed Message:\n',

239
routes/shepherd.js

@ -58,12 +58,23 @@ const electrumServers = {
txfee: 10000,
abbr: 'REVS',
},
jumblr: {
address: '173.212.225.176',
port: 50051,
proto: 'tcp',
txfee: 10000,
abbr: 'JUMBLR',
},
komodo: { // !estimatefee
address: '173.212.225.176',
port: 50011,
proto: 'tcp',
txfee: 10000,
abbr: 'KMD',
serverList: [
'173.212.225.176:50011',
'136.243.45.140:50011'
],
},
dogecoin: { // !estimatefee
address: '173.212.225.176',
@ -154,6 +165,10 @@ const electrumServers = {
proto: 'tcp',
txfee: 10000,
abbr: 'CHIPS',
serverList: [
'173.212.225.176:50076',
'136.243.45.140:50076'
],
},
};
@ -224,6 +239,54 @@ shepherd.kmdMainPassiveMode = false;
shepherd.coindInstanceRegistry = coindInstanceRegistry;
shepherd.getNetworkData = function(network) {
const coin = shepherd.findNetworkObj(network) || shepherd.findNetworkObj(network.toUpperCase()) || shepherd.findNetworkObj(network.toLowerCase());
const coinUC = coin ? coin.toUpperCase() : null;
if (coin === 'SUPERNET' ||
coin === 'REVS' ||
coin === 'SUPERNET' ||
coin === 'PANGEA' ||
coin === 'DEX' ||
coin === 'JUMBLR' ||
coin === 'BET' ||
coin === 'CRYPTO' ||
coin === 'COQUI' ||
coin === 'HODL' ||
coin === 'SHARK' ||
coin === 'BOTS' ||
coin === 'MGW' ||
coin === 'MVP' ||
coin === 'KV' ||
coin === 'CEAL' ||
coin === 'MESH' ||
coin === 'WLC' ||
coin === 'MNZ' ||
coinUC === 'SUPERNET' ||
coinUC === 'REVS' ||
coinUC === 'SUPERNET' ||
coinUC === 'PANGEA' ||
coinUC === 'DEX' ||
coinUC === 'JUMBLR' ||
coinUC === 'BET' ||
coinUC === 'CRYPTO' ||
coinUC === 'COQUI' ||
coinUC === 'HODL' ||
coinUC === 'SHARK' ||
coinUC === 'BOTS' ||
coinUC === 'MGW' ||
coinUC === 'MVP' ||
coinUC === 'KV' ||
coinUC === 'CEAL' ||
coinUC === 'MESH' ||
coinUC === 'WLC' ||
coinUC === 'MNZ') {
return electrumJSNetworks.komodo;
} else {
return electrumJSNetworks[network];
}
}
shepherd.seedToWif = function(seed, network, iguana) {
const bytes = sha256(seed, { asBytes: true });
@ -242,8 +305,8 @@ shepherd.seedToWif = function(seed, network, iguana) {
const hex = toHexString(bytes);
const key = new CoinKey(new Buffer(hex, 'hex'), {
private: electrumJSNetworks[network].wif,
public: electrumJSNetworks[network].pubKeyHash,
private: shepherd.getNetworkData(network).wif,
public: shepherd.getNetworkData(network).pubKeyHash,
});
key.compressed = true;
@ -278,6 +341,72 @@ shepherd.findNetworkObj = function(coin) {
}
}
shepherd.get('/electrum/servers/test', function(req, res, next) {
const ecl = new electrumJSCore(req.query.port, req.query.address, 'tcp'); // tcp or tls
ecl.connect();
ecl.serverVersion()
.then((serverData) => {
ecl.close();
console.log('serverData');
console.log(serverData);
if (serverData &&
typeof serverData === 'string' &&
serverData.indexOf('Electrum') > -1) {
const successObj = {
msg: 'success',
result: true,
};
res.end(JSON.stringify(successObj));
} else {
const successObj = {
msg: 'error',
result: false,
};
res.end(JSON.stringify(successObj));
}
});
});
shepherd.get('/electrum/keys', function(req, res, next) {
let _matchingKeyPairs = 0;
let _electrumKeys = {};
for (let key in electrumServers) {
const _abbr = electrumServers[key].abbr;
const { priv, pub } = shepherd.seedToWif(req.query.seed, shepherd.findNetworkObj(_abbr), req.query.iguana);
if (electrumKeys[_abbr].pub === pub &&
electrumKeys[_abbr].priv === priv) {
_matchingKeyPairs++;
}
}
if (req.query.active) {
_electrumKeys = JSON.parse(JSON.stringify(electrumKeys));
for (let key in _electrumKeys) {
if (!electrumCoins[key]) {
delete _electrumKeys[key];
}
}
} else {
_electrumKeys = electrumKeys;
}
shepherd.log(JSON.stringify(_electrumKeys, null, '\t'));
const successObj = {
msg: 'success',
result: _matchingKeyPairs === Object.keys(electrumKeys).length ? _electrumKeys : false,
};
res.end(JSON.stringify(successObj));
});
shepherd.get('/electrum/login', function(req, res, next) {
for (let key in electrumServers) {
const _abbr = electrumServers[key].abbr;
@ -356,17 +485,50 @@ shepherd.get('/electrum/bip39/seed', function(req, res, next) {
});
shepherd.get('/electrum/servers', function(req, res, next) {
if (req.query.abbr) {
let _electrumServers = {};
for (let key in electrumServers) {
_electrumServers[electrumServers[key].abbr] = electrumServers[key];
}
const successObj = {
msg: 'success',
result: {
servers: _electrumServers,
},
};
res.end(JSON.stringify(successObj));
} else {
const successObj = {
msg: 'success',
result: {
servers: electrumServers,
},
};
res.end(JSON.stringify(successObj));
}
});
shepherd.get('/electrum/coins/server/set', function(req, res, next) {
electrumCoins[req.query.coin].server = {
ip: req.query.address,
port: req.query.port,
};
console.log(JSON.stringify(electrumCoins[req.query.coin]), null, '\t');
const successObj = {
msg: 'success',
result: {
servers: electrumServers,
},
result: true,
};
res.end(JSON.stringify(successObj));
});
shepherd.addElectrumCoin = function(coin, serverID) {
shepherd.addElectrumCoin = function(coin) {
for (let key in electrumServers) {
if (electrumServers[key].abbr === coin) {
electrumCoins[coin] = {
@ -376,6 +538,7 @@ shepherd.addElectrumCoin = function(coin, serverID) {
ip: electrumServers[key].address,
port: electrumServers[key].port,
},
serverList: electrumServers[key].serverList ? electrumServers[key].serverList : 'none',
txfee: 'calculated' /*electrumServers[key].txfee*/,
};
@ -504,7 +667,7 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
console.log(_rawtxJSON);
// decode tx
const _network = electrumJSNetworks[network];
const _network = shepherd.getNetworkData(network);
const decodedTx = electrumJSTxDecoder(_rawtxJSON, _network);
if (decodedTx.format.locktime > 0) {
@ -518,9 +681,10 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
const successObj = {
msg: 'success',
result: {
balance: 0.00000001 * json.confirmed,
unconfirmed: json.unconfirmed,
sats: json.confirmed,
balance: Number((0.00000001 * json.confirmed).toFixed(8)),
unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)),
unconfirmedSats: json.unconfirmed,
balanceSats: json.confirmed,
interest: Number(interestTotal.toFixed(8)),
interestSats: Math.floor(interestTotal * 100000000),
total: interestTotal > 0 ? Number((0.00000001 * json.confirmed + interestTotal).toFixed(8)) : 0,
@ -536,9 +700,10 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
const successObj = {
msg: 'success',
result: {
balance: 0.00000001 * json.confirmed,
unconfirmed: json.unconfirmed,
sats: json.confirmed,
balance: Number((0.00000001 * json.confirmed).toFixed(8)),
unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)),
unconfirmedSats: json.unconfirmed,
balanceSats: json.confirmed,
interest: 0,
interestSats: 0,
total: 0,
@ -552,9 +717,10 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
const successObj = {
msg: 'success',
result: {
balance: 0.00000001 * json.confirmed,
unconfirmed: json.unconfirmed,
sats: json.confirmed,
balance: Number((0.00000001 * json.confirmed).toFixed(8)),
unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)),
unconfirmedSats: json.unconfirmed,
balanceSats: json.confirmed,
interest: 0,
},
};
@ -621,7 +787,7 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
} else {
// !expensive call!
// TODO: limit e.g. 1-10, 10-20 etc
const MAX_TX = 10;
const MAX_TX = req.query.maxlength || 10;
ecl.connect();
ecl.blockchainNumblocksSubscribe()
@ -646,7 +812,7 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console.log(_rawtxJSON);
// decode tx
const _network = electrumJSNetworks[network];
const _network = shepherd.getNetworkData(network);
const decodedTx = electrumJSTxDecoder(_rawtxJSON, _network);
let txInputs = [];
@ -814,7 +980,7 @@ shepherd.get('/electrum/gettransactiontest', function(req, res, next) {
.then((json) => {
console.log('electrum gettransaction ==>');
console.log(json);
const _network = electrumJSNetworks[req.query.network];
const _network = shepherd.getNetworkData(req.query.network);
const decodedTx = electrumJSTxDecoder(json, _network);
let txInputs = [];
@ -1062,7 +1228,7 @@ shepherd.get('/electrum/formatlisttransactions', function(req, res, next) {
});
shepherd.get('/electrum/decoderawtx', function(req, res, next) {
const _network = electrumJSNetworks[req.query.network];
const _network = shepherd.getNetworkData(req.query.network);
const _rawtx = req.query.rawtx;
// const _rawtx = '0100000001dd6d064f5665f8454293ecaa9dbb55accf4f7e443d35f3b5ab7760f54b6c15fe000000006a473044022056355585a4a501ec9afc96aa5df124cf29ad3ac6454b47cd07cd7d89ec95ec2b022074c4604ee349d30e5336f210598e4dc576bf16ebeb67eeac3f4e82f56e930fee012103b90ba01af308757054e0484bb578765d5df59c4a57adbb94e2419df5e7232a63feffffff0289fc923b000000001976a91424af38fcb13bbc171b0b42bb017244a53b6bb2fa88ac20a10700000000001976a9142f4c0f91fc06ac228c120aee41741d0d3909683288ac49258b58';
const decodedTx = electrumJSTxDecoder(_rawtx, _network);
@ -1168,11 +1334,13 @@ shepherd.get('/electrum/subset', function(req, res, next) {
// single sig
shepherd.buildSignedTx = function(sendTo, changeAddress, wif, network, utxo, changeValue, spendValue) {
let key = bitcoinJS.ECPair.fromWIF(wif, electrumJSNetworks[network]);
let tx = new bitcoinJS.TransactionBuilder(electrumJSNetworks[network]);
console.log(`net ${network}`);
console.log(shepherd.getNetworkData(network));
let key = bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network));
let tx = new bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network));
console.log('buildSignedTx priv key ' + wif);
console.log('buildSignedTx pub key ' + key.getAddress().toString());
console.log(`buildSignedTx priv key ${wif}`);
console.log(`buildSignedTx pub key ${key.getAddress().toString()}`);
// console.log('buildSignedTx std tx fee ' + electrumServers[network].txfee);
for (let i = 0; i < utxo.length; i++) {
@ -1185,7 +1353,12 @@ shepherd.buildSignedTx = function(sendTo, changeAddress, wif, network, utxo, cha
tx.addOutput(changeAddress, Number(changeValue));
}
tx.setLockTime(Math.floor(Date.now() / 1000) - 777);
if (network === 'komodo' ||
network === 'KMD') {
const _locktime = Math.floor(Date.now() / 1000) - 777;
tx.setLockTime(_locktime);
console.log(`kmd tx locktime set to ${_locktime}`);
}
console.log('buildSignedTx unsigned tx data vin');
console.log(tx.tx.ins);
@ -1234,7 +1407,6 @@ shepherd.get('/electrum/createrawtx', function(req, res, next) {
}
ecl.connect();
//ecl.blockchainAddressListunspent(changeAddress)
shepherd.listunspent(ecl, changeAddress, network, network === 'komodo' ? true : false)
.then((utxoList) => {
ecl.close();
@ -1327,7 +1499,8 @@ shepherd.get('/electrum/createrawtx', function(req, res, next) {
// account for KMD interest
if (network === 'komodo' &&
totalInterest > 0) {
const _feeOverhead = shepherd.estimateTxSize(0, 1) * 2;
// account for extra vout
const _feeOverhead = outputs.length === 1 ? shepherd.estimateTxSize(0, 1) * feeRate : 0;
console.log(`max interest to claim ${totalInterest} (${totalInterest * 0.00000001})`);
console.log('estimated fee overhead ' + _feeOverhead);
@ -1440,7 +1613,7 @@ shepherd.listunspent = function(ecl, address, network, full) {
console.log(_rawtxJSON);
// decode tx
const _network = electrumJSNetworks[network];
const _network = shepherd.getNetworkData(network);
const decodedTx = electrumJSTxDecoder(_rawtxJSON, _network);
if (network === 'komodo') {
@ -1623,6 +1796,16 @@ shepherd.log = function(msg) {
});
};
shepherd.startSPV = function(coin) {
if (coin === 'KMD+REVS+JUMBLR') {
shepherd.addElectrumCoin('KMD');
shepherd.addElectrumCoin('REVS');
shepherd.addElectrumCoin('JUMBLR');
} else {
shepherd.addElectrumCoin(coin);
}
}
shepherd.startKMDNative = function(selection, isManual) {
if (isManual) {
shepherd.kmdMainPassiveMode = true;

Loading…
Cancel
Save