Browse Source

zec, hush spv

pkg_automation_electrum
pbca26 7 years ago
parent
commit
b4e7effa57
  1. 4
      package.json
  2. 35
      routes/electrumjs/electrumServers.js
  3. 37
      routes/electrumjs/electrumjs.networks.js
  4. 120
      routes/electrumjs/electrumjs.txdecoder-2bytes.js
  5. 2
      routes/shepherd.js
  6. 91
      routes/shepherd/daemonControl.js
  7. 2
      routes/shepherd/electrum/balance.js
  8. 5
      routes/shepherd/electrum/createtx.js
  9. 34
      routes/shepherd/electrum/keys.js
  10. 5
      routes/shepherd/electrum/listunspent.js
  11. 4
      routes/shepherd/electrum/merkle.js
  12. 13
      routes/shepherd/electrum/network.js
  13. 6
      routes/shepherd/electrum/transactions.js

4
package.json

@ -28,14 +28,14 @@
"dependencies": { "dependencies": {
"adm-zip": "^0.4.7", "adm-zip": "^0.4.7",
"arch": "^2.1.0", "arch": "^2.1.0",
"bigi": "^1.4.2",
"bip39": "^2.4.0", "bip39": "^2.4.0",
"bitcoinjs-lib": "^3.2.0",
"bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash", "bitcoinforksjs-lib": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash",
"bitcoinjs-lib": "^3.2.0",
"bitcoinjs-lib-zcash": "git://github.com/karel-3d/bitcoinjs-lib#zcash", "bitcoinjs-lib-zcash": "git://github.com/karel-3d/bitcoinjs-lib#zcash",
"bluebird": "^3.4.7", "bluebird": "^3.4.7",
"body-parser": "^1.15.2", "body-parser": "^1.15.2",
"buffer-reverse": "^1.0.1", "buffer-reverse": "^1.0.1",
"coinkey": "^2.0.0",
"coinselect": "github:bitcoinjs/coinselect", "coinselect": "github:bitcoinjs/coinselect",
"electron": "1.6.5", "electron": "1.6.5",
"express": "^4.14.0", "express": "^4.14.0",

35
routes/electrumjs/electrumServers.js

@ -1,13 +1,4 @@
let electrumServers = { let electrumServers = {
/*zcash: { 2 bytes address fix is required
address: '173.212.225.176',
port: 50032,
proto: 'tcp',
serverList: [
'173.212.225.176:50032',
'136.243.45.140:50032'
],
},*/
coqui: { // !estimatefee coqui: { // !estimatefee
address: 'electrum1.cipig.net', address: 'electrum1.cipig.net',
port: 10011, port: 10011,
@ -298,7 +289,7 @@ let electrumServers = {
'94.130.224.11:10052' '94.130.224.11:10052'
], ],
}, },
/*blk: { can't decode tx! blk: { // can't decode tx!
address: 'electrum1.cipig.net', address: 'electrum1.cipig.net',
port: 10054, port: 10054,
proto: 'tcp', proto: 'tcp',
@ -308,7 +299,7 @@ let electrumServers = {
'electrum1.cipig.net:10054', 'electrum1.cipig.net:10054',
'electrum2.cipig.net:10054' 'electrum2.cipig.net:10054'
], ],
},*/ },
sib: { sib: {
address: 'electrum1.cipig.net', address: 'electrum1.cipig.net',
port: 10050, port: 10050,
@ -353,6 +344,28 @@ let electrumServers = {
'electrum2.cipig.net:10053' 'electrum2.cipig.net:10053'
], ],
}, },
zec: {
address: '173.212.225.176',
port: 50032,
proto: 'tcp',
txfee: 10000,
abbr: 'ZEC',
serverList: [
'173.212.225.176:50032',
'136.243.45.140:50032'
],
},
hush: {
address: '173.212.225.176',
port: 50013,
proto: 'tcp',
txfee: 10000,
abbr: 'HUSH',
serverList: [
'173.212.225.176:50013',
'136.243.45.140:50013'
],
},
}; };
electrumServers.crw = electrumServers.crown; electrumServers.crw = electrumServers.crown;

37
routes/electrumjs/electrumjs.networks.js

@ -240,19 +240,32 @@ networks.sib = {
dustThreshold: 1000, dustThreshold: 1000,
}; };
networks.zcash = {
messagePrefix: '\x19Zcash Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x05358394,
},
pubKeyHash: 0x1cb8,
scriptHash: 0x1cbd,
wif: 0x80,
dustThreshold: 1000,
};
networks.hush = {
messagePrefix: '\Hush Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4,
},
pubKeyHash: 0x1cb8,
scriptHash: 0x1cbd,
wif: 0x80,
dustThreshold: 1000,
};
networks.btc = networks.bitcoin; networks.btc = networks.bitcoin;
networks.crw = networks.crown; networks.crw = networks.crown;
networks.dgb = networks.digibyte; networks.dgb = networks.digibyte;
networks.arg = networks.argentum; networks.arg = networks.argentum;
networks.zec = networks.zcash;
/*networks.zcash = {
messagePrefix: '\x19Zcash Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4,
},
pubKeyHash: 0x1cb8,
scriptHash: 0x1cbd,
wif: 0x80,
dustThreshold: 1000,
};*/

120
routes/electrumjs/electrumjs.txdecoder-2bytes.js

@ -0,0 +1,120 @@
/*
MIT License
Copyright (c) 2017 Yuki Akiyama, SuperNET
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
var bitcoin = require('bitcoinjs-lib-zcash');
var decodeFormat = function(tx) {
var result = {
txid: tx.getId(),
version: tx.version,
locktime: tx.locktime,
};
return result;
}
var decodeInput = function(tx) {
var result = [];
tx.ins.forEach(function(input, n) {
var vin = {
txid: input.hash.reverse().toString('hex'),
n: input.index,
script: bitcoin.script.toASM(input.script),
sequence: input.sequence,
};
result.push(vin);
});
return result;
}
var decodeOutput = function(tx, network) {
var format = function(out, n, network) {
var vout = {
satoshi: out.value,
value: (1e-8 * out.value).toFixed(8),
n: n,
scriptPubKey: {
asm: bitcoin.script.toASM(out.script),
hex: out.script.toString('hex'),
type: bitcoin.script.classifyOutput(out.script),
addresses: [],
},
};
switch(vout.scriptPubKey.type) {
case 'pubkeyhash':
vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network));
break;
case 'pubkey':
const pubKeyBuffer = new Buffer(vout.scriptPubKey.asm.split(' ')[0], 'hex');
vout.scriptPubKey.addresses.push(bitcoin.ECPair.fromPublicKeyBuffer(pubKeyBuffer, network).getAddress());
break;
case 'scripthash':
vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network));
break;
}
return vout;
}
var result = [];
tx.outs.forEach(function(out, n) {
result.push(format(out, n, network));
});
return result;
}
var TxDecoder = module.exports = function(rawtx, network) {
try {
const _tx = bitcoin.Transaction.fromHex(rawtx);
return {
tx: _tx,
network: network,
format: decodeFormat(_tx),
inputs: decodeInput(_tx),
outputs: decodeOutput(_tx, network),
};
} catch (e) {
return false;
}
}
TxDecoder.prototype.decode = function() {
var result = {};
var self = this;
Object.keys(self.format).forEach(function(key) {
result[key] = self.format[key];
});
result.outputs = self.outputs;
return result;
}

2
routes/shepherd.js

@ -18,7 +18,6 @@ shepherd.Promise = require('bluebird');
shepherd.exec = require('child_process').exec; shepherd.exec = require('child_process').exec;
shepherd.execFile = require('child_process').execFile; shepherd.execFile = require('child_process').execFile;
shepherd.sha256 = require('sha256'); shepherd.sha256 = require('sha256');
shepherd.CoinKey = require('coinkey');
shepherd.bitcoinJS = require('bitcoinjs-lib'); shepherd.bitcoinJS = require('bitcoinjs-lib');
shepherd.coinSelect = require('coinselect'); shepherd.coinSelect = require('coinselect');
shepherd.fixPath = require('fix-path'); shepherd.fixPath = require('fix-path');
@ -63,6 +62,7 @@ shepherd.electrumKeys = {};
shepherd.electrumJSCore = require('./electrumjs/electrumjs.core.js'); shepherd.electrumJSCore = require('./electrumjs/electrumjs.core.js');
shepherd.electrumJSNetworks = require('./electrumjs/electrumjs.networks.js'); shepherd.electrumJSNetworks = require('./electrumjs/electrumjs.networks.js');
shepherd.electrumJSTxDecoder = require('./electrumjs/electrumjs.txdecoder.js'); shepherd.electrumJSTxDecoder = require('./electrumjs/electrumjs.txdecoder.js');
shepherd.electrumJSTxDecoderZ = require('./electrumjs/electrumjs.txdecoder-2bytes.js');
shepherd.electrumServers = require('./electrumjs/electrumServers.js'); shepherd.electrumServers = require('./electrumjs/electrumServers.js');
shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA = 'connection error or incomplete data'; shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA = 'connection error or incomplete data';

91
routes/shepherd/daemonControl.js

@ -11,6 +11,7 @@ const md5 = require('../md5.js');
module.exports = (shepherd) => { module.exports = (shepherd) => {
const getConf = (flock, coind) => { const getConf = (flock, coind) => {
const _platform = os.platform();
let DaemonConfPath = ''; let DaemonConfPath = '';
let nativeCoindDir; let nativeCoindDir;
@ -23,7 +24,7 @@ module.exports = (shepherd) => {
shepherd.writeLog(`getconf flock: ${flock}`); shepherd.writeLog(`getconf flock: ${flock}`);
if (coind) { if (coind) {
switch (os.platform()) { switch (_platform) {
case 'darwin': case 'darwin':
nativeCoindDir = `${process.env.HOME}/Library/Application Support/${shepherd.nativeCoindList[coind.toLowerCase()].bin}`; nativeCoindDir = `${process.env.HOME}/Library/Application Support/${shepherd.nativeCoindList[coind.toLowerCase()].bin}`;
break; break;
@ -39,29 +40,29 @@ module.exports = (shepherd) => {
switch (flock) { switch (flock) {
case 'komodod': case 'komodod':
DaemonConfPath = shepherd.komodoDir; DaemonConfPath = shepherd.komodoDir;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
shepherd.log('===>>> SHEPHERD API OUTPUT ===>>>'); shepherd.log('===>>> SHEPHERD API OUTPUT ===>>>');
} }
break; break;
case 'zcashd': case 'zcashd':
DaemonConfPath = shepherd.ZcashDir; DaemonConfPath = shepherd.ZcashDir;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
case 'chipsd': case 'chipsd':
DaemonConfPath = shepherd.chipsDir; DaemonConfPath = shepherd.chipsDir;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
case 'coind': case 'coind':
DaemonConfPath = os.platform() === 'win32' ? shepherd.path.normalize(`${shepherd.coindRootDir}/${coind.toLowerCase()}`) : `${shepherd.coindRootDir}/${coind.toLowerCase()}`; DaemonConfPath = _platform === 'win32' ? shepherd.path.normalize(`${shepherd.coindRootDir}/${coind.toLowerCase()}`) : `${shepherd.coindRootDir}/${coind.toLowerCase()}`;
break; break;
default: default:
DaemonConfPath = `${shepherd.komodoDir}/${flock}`; DaemonConfPath = `${shepherd.komodoDir}/${flock}`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = shepherd.path.normalize(DaemonConfPath); DaemonConfPath = shepherd.path.normalize(DaemonConfPath);
} }
} }
@ -482,57 +483,58 @@ module.exports = (shepherd) => {
} }
const setConf = (flock, coind) => { const setConf = (flock, coind) => {
const _platform = os.platform();
let nativeCoindDir; let nativeCoindDir;
let DaemonConfPath; let DaemonConfPath;
shepherd.log(flock); shepherd.log(flock);
shepherd.writeLog(`setconf ${flock}`); shepherd.writeLog(`setconf ${flock}`);
if (os.platform() === 'darwin') { switch (_platform) {
nativeCoindDir = coind ? `${process.env.HOME}/Library/Application Support/${shepherd.nativeCoindList[coind.toLowerCase()].bin}` : null; case 'darwin':
} nativeCoindDir = coind ? `${process.env.HOME}/Library/Application Support/${shepherd.nativeCoindList[coind.toLowerCase()].bin}` : null;
break;
if (os.platform() === 'linux') { case 'linux':
nativeCoindDir = coind ? `${process.env.HOME}/.${shepherd.nativeCoindList[coind.toLowerCase()].bin.toLowerCase()}` : null; nativeCoindDir = coind ? `${process.env.HOME}/.${shepherd.nativeCoindList[coind.toLowerCase()].bin.toLowerCase()}` : null;
} break;
case 'win32':
if (os.platform() === 'win32') { nativeCoindDir = coind ? `${process.env.APPDATA}/${shepherd.nativeCoindList[coind.toLowerCase()].bin}` : null;
nativeCoindDir = coind ? `${process.env.APPDATA}/${shepherd.nativeCoindList[coind.toLowerCase()].bin}` : null; break;
} }
switch (flock) { switch (flock) {
case 'komodod': case 'komodod':
DaemonConfPath = `${shepherd.komodoDir}/komodo.conf`; DaemonConfPath = `${shepherd.komodoDir}/komodo.conf`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
case 'zcashd': case 'zcashd':
DaemonConfPath = `${shepherd.ZcashDir}/zcash.conf`; DaemonConfPath = `${shepherd.ZcashDir}/zcash.conf`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
case 'chipsd': case 'chipsd':
DaemonConfPath = `${shepherd.chipsDir}/chips.conf`; DaemonConfPath = `${shepherd.chipsDir}/chips.conf`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
case 'coind': case 'coind':
DaemonConfPath = `${nativeCoindDir}/${shepherd.nativeCoindList[coind.toLowerCase()].bin.toLowerCase()}.conf`; DaemonConfPath = `${nativeCoindDir}/${shepherd.nativeCoindList[coind.toLowerCase()].bin.toLowerCase()}.conf`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
break; break;
default: default:
DaemonConfPath = `${shepherd.komodoDir}/${flock}/${flock}.conf`; DaemonConfPath = `${shepherd.komodoDir}/${flock}/${flock}.conf`;
if (os.platform() === 'win32') { if (_platform === 'win32') {
DaemonConfPath = path.normalize(DaemonConfPath); DaemonConfPath = path.normalize(DaemonConfPath);
} }
} }
@ -790,14 +792,17 @@ module.exports = (shepherd) => {
* params: herd * params: herd
*/ */
shepherd.post('/herd', (req, res) => { shepherd.post('/herd', (req, res) => {
shepherd.log('======= req.body ======='); const _body = req.body;
shepherd.log(req.body); shepherd.log('herd req.body =>');
shepherd.log(_body);
if (req.body.options && if (_body.options &&
!shepherd.kmdMainPassiveMode) { !shepherd.kmdMainPassiveMode) {
const testCoindPort = (skipError) => { const testCoindPort = (skipError) => {
const _acName = req.body.options.ac_name;
if (!shepherd.lockDownAddCoin) { if (!shepherd.lockDownAddCoin) {
const _port = shepherd.assetChainPorts[req.body.options.ac_name]; const _port = shepherd.assetChainPorts[_acName];
portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => { portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => {
// Status is 'open' if currently in use or 'closed' if available // Status is 'open' if currently in use or 'closed' if available
@ -808,13 +813,13 @@ module.exports = (shepherd) => {
shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`); shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`);
shepherd.io.emit('service', { shepherd.io.emit('service', {
komodod: { komodod: {
error: `error starting ${req.body.herd} ${req.body.options.ac_name} daemon. Port ${_port} is already taken!`, error: `error starting ${_body.herd} ${_acName} daemon. Port ${_port} is already taken!`,
}, },
}); });
const obj = { const obj = {
msg: 'error', msg: 'error',
result: `error starting ${req.body.herd} ${req.body.options.ac_name} daemon. Port ${_port} is already taken!`, result: `error starting ${_body.herd} ${_acName} daemon. Port ${_port} is already taken!`,
}; };
res.status(500); res.status(500);
@ -825,7 +830,7 @@ module.exports = (shepherd) => {
} }
} else { } else {
if (!skipError) { if (!skipError) {
herder(req.body.herd, req.body.options); herder(_body.herd, _body.options);
const obj = { const obj = {
msg: 'success', msg: 'success',
@ -842,14 +847,14 @@ module.exports = (shepherd) => {
} }
} }
if (req.body.herd === 'komodod') { if (_body.herd === 'komodod') {
// check if komodod instance is already running // check if komodod instance is already running
testCoindPort(); testCoindPort();
setTimeout(() => { setTimeout(() => {
testCoindPort(true); testCoindPort(true);
}, 10000); }, 10000);
} else { } else {
herder(req.body.herd, req.body.options, req.body.coind); herder(_body.herd, _body.options, _body.coind);
const obj = { const obj = {
msg: 'success', msg: 'success',
@ -860,7 +865,7 @@ module.exports = (shepherd) => {
} }
} else { } else {
// (?) // (?)
herder(req.body.herd, req.body.options); herder(_body.herd, _body.options);
const obj = { const obj = {
msg: 'success', msg: 'success',
@ -875,14 +880,16 @@ module.exports = (shepherd) => {
* type: POST * type: POST
*/ */
shepherd.post('/setconf', (req, res) => { shepherd.post('/setconf', (req, res) => {
shepherd.log('======= req.body ======='); const _body = req.body;
shepherd.log(req.body);
shepherd.log('setconf req.body =>');
shepherd.log(_body);
if (os.platform() === 'win32' && if (os.platform() === 'win32' &&
req.body.chain == 'komodod') { _body.chain == 'komodod') {
setkomodoconf = spawn(path.join(__dirname, '../assets/bin/win64/genkmdconf.bat')); setkomodoconf = spawn(path.join(__dirname, '../assets/bin/win64/genkmdconf.bat'));
} else { } else {
shepherd.setConf(req.body.chain); shepherd.setConf(_body.chain);
} }
const obj = { const obj = {
@ -897,15 +904,15 @@ module.exports = (shepherd) => {
* type: POST * type: POST
*/ */
shepherd.post('/getconf', (req, res) => { shepherd.post('/getconf', (req, res) => {
shepherd.log('======= req.body ======='); const _body = req.body;
shepherd.log(req.body);
shepherd.log('getconf req.body =>');
shepherd.log(_body);
const confpath = getConf(req.body.chain, req.body.coind); const confpath = getConf(_body.chain, _body.coind);
shepherd.log('got conf path is:'); shepherd.log(`getconf path is: ${confpath}`);
shepherd.log(confpath); shepherd.writeLog(`getconf path is: ${confpath}`);
shepherd.writeLog('got conf path is:');
shepherd.writeLog(confpath);
const obj = { const obj = {
msg: 'success', msg: 'success',

2
routes/shepherd/electrum/balance.js

@ -45,7 +45,7 @@ module.exports = (shepherd) => {
// decode tx // decode tx
const _network = shepherd.getNetworkData(network); const _network = shepherd.getNetworkData(network);
const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, _network); const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network);
if (decodedTx && if (decodedTx &&
decodedTx.format && decodedTx.format &&

5
routes/shepherd/electrum/createtx.js

@ -1,4 +1,5 @@
const bitcoinJSForks = require('bitcoinforksjs-lib'); const bitcoinJSForks = require('bitcoinforksjs-lib');
const bitcoinZcash = require('bitcoinjs-lib-zcash');
module.exports = (shepherd) => { module.exports = (shepherd) => {
// unsigned tx // unsigned tx
@ -52,8 +53,8 @@ module.exports = (shepherd) => {
// single sig // single sig
shepherd.buildSignedTx = (sendTo, changeAddress, wif, network, utxo, changeValue, spendValue) => { shepherd.buildSignedTx = (sendTo, changeAddress, wif, network, utxo, changeValue, spendValue) => {
let key = shepherd.bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network)); let key = shepherd.isZcash(network) ? bitcoinZcash.ECPair.fromWIF(wif, shepherd.getNetworkData(network)) : shepherd.bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network));
let tx = new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); let tx = shepherd.isZcash(network) ? new bitcoinZcash.TransactionBuilder(shepherd.getNetworkData(network)) : new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network));
shepherd.log('buildSignedTx'); shepherd.log('buildSignedTx');
// console.log(`buildSignedTx priv key ${wif}`); // console.log(`buildSignedTx priv key ${wif}`);

34
routes/shepherd/electrum/keys.js

@ -1,6 +1,9 @@
const sha256 = require('js-sha256'); const sha256 = require('js-sha256');
const bip39 = require('bip39'); const bip39 = require('bip39');
const crypto = require('crypto'); const crypto = require('crypto');
const bigi = require('bigi');
const bitcoinZcash = require('bitcoinjs-lib-zcash');
const bitcoin = require('bitcoinjs-lib');
module.exports = (shepherd) => { module.exports = (shepherd) => {
shepherd.seedToWif = (seed, network, iguana) => { shepherd.seedToWif = (seed, network, iguana) => {
@ -19,30 +22,19 @@ module.exports = (shepherd) => {
bytes[31] |= 64; bytes[31] |= 64;
} }
const toHexString = (byteArray) => { const d = bigi.fromBuffer(bytes);
return Array.from(byteArray, (byte) => { const keyPair = shepherd.isZcash(network) ? new bitcoinZcash.ECPair(d, null, { network: shepherd.getNetworkData(network) }) : new bitcoinZcash.ECPair(d, null, { network: shepherd.getNetworkData(network) });
return ('0' + (byte & 0xFF).toString(16)).slice(-2); const keys = {
}).join(''); pub: keyPair.getAddress(),
} priv: keyPair.toWIF(),
};
const hex = toHexString(bytes);
const key = new shepherd.CoinKey(new Buffer(hex, 'hex'), {
private: shepherd.getNetworkData(network).wif,
public: shepherd.getNetworkData(network).pubKeyHash,
});
key.compressed = true;
/*shepherd.log(`seed: ${seed}`, true); /*shepherd.log(`seed: ${seed}`, true);
shepherd.log(`network ${network}`, true); shepherd.log(`network ${network}`, true);
shepherd.log(`seedtowif priv key ${key.privateWif}`, true); shepherd.log(`seedtowif priv key ${keys.priv}`, true);
shepherd.log(`seedtowif pub key ${key.publicAddress}`, true);*/ shepherd.log(`seedtowif pub key ${keys.pub}`, true);*/
return { return keys;
priv: key.privateWif,
pub: key.publicAddress,
};
} }
shepherd.get('/electrum/wiftopub', (req, res, next) => { shepherd.get('/electrum/wiftopub', (req, res, next) => {
@ -63,7 +55,7 @@ module.exports = (shepherd) => {
}); });
shepherd.get('/electrum/seedtowif', (req, res, next) => { shepherd.get('/electrum/seedtowif', (req, res, next) => {
const keys = shepherd.seedToWif(req.query.seed, req.query.network, req.query.iguana); let keys = shepherd.seedToWif(req.query.seed, req.query.network, req.query.iguana);
const successObj = { const successObj = {
msg: 'success', msg: 'success',

5
routes/shepherd/electrum/listunspent.js

@ -36,7 +36,7 @@ module.exports = (shepherd) => {
// decode tx // decode tx
const _network = shepherd.getNetworkData(network); const _network = shepherd.getNetworkData(network);
const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, _network); const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network);
shepherd.log('decoded tx =>', true); shepherd.log('decoded tx =>', true);
shepherd.log(decodedTx, true); shepherd.log(decodedTx, true);
@ -71,7 +71,8 @@ module.exports = (shepherd) => {
if (verify) { if (verify) {
shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height) shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height)
.then((verifyMerkleRes) => { .then((verifyMerkleRes) => {
if (verifyMerkleRes && verifyMerkleRes === shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA) { if (verifyMerkleRes &&
verifyMerkleRes === shepherd.CONNECTION_ERROR_OR_INCOMPLETE_DATA) {
verifyMerkleRes = false; verifyMerkleRes = false;
} }

4
routes/shepherd/electrum/merkle.js

@ -2,11 +2,11 @@ module.exports = (shepherd) => {
// get merkle root // get merkle root
shepherd.getMerkleRoot = (txid, proof, pos) => { shepherd.getMerkleRoot = (txid, proof, pos) => {
const reverse = require('buffer-reverse'); const reverse = require('buffer-reverse');
let hash = txid;
let serialized;
const _sha256 = (data) => { const _sha256 = (data) => {
return shepherd.crypto.createHash('sha256').update(data).digest(); return shepherd.crypto.createHash('sha256').update(data).digest();
} }
let hash = txid;
let serialized;
shepherd.log(`getMerkleRoot txid ${txid}`, true); shepherd.log(`getMerkleRoot txid ${txid}`, true);
shepherd.log(`getMerkleRoot pos ${pos}`, true); shepherd.log(`getMerkleRoot pos ${pos}`, true);

13
routes/shepherd/electrum/network.js

@ -1,4 +1,17 @@
module.exports = (shepherd) => { module.exports = (shepherd) => {
shepherd.isZcash = (network) => {
if (network === 'ZEC' ||
network === 'zec' ||
network === 'zcash' ||
network === 'ZCASH' ||
network === 'HUSH' ||
network === 'hush' ||
network === 'blk' ||
network === 'BLK') {
return true;
}
};
shepherd.getNetworkData = (network) => { shepherd.getNetworkData = (network) => {
const coin = shepherd.findNetworkObj(network) || shepherd.findNetworkObj(network.toUpperCase()) || shepherd.findNetworkObj(network.toLowerCase()); const coin = shepherd.findNetworkObj(network) || shepherd.findNetworkObj(network.toUpperCase()) || shepherd.findNetworkObj(network.toLowerCase());
const coinUC = coin ? coin.toUpperCase() : null; const coinUC = coin ? coin.toUpperCase() : null;

6
routes/shepherd/electrum/transactions.js

@ -69,9 +69,10 @@ module.exports = (shepherd) => {
// decode tx // decode tx
const _network = shepherd.getNetworkData(network); const _network = shepherd.getNetworkData(network);
const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, _network); const decodedTx = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(_rawtxJSON, _network) : shepherd.electrumJSTxDecoder(_rawtxJSON, _network);
let txInputs = []; let txInputs = [];
shepherd.log(`decodedtx network ${network}`, true);
shepherd.log('decodedtx =>', true); shepherd.log('decodedtx =>', true);
shepherd.log(decodedTx.outputs, true); shepherd.log(decodedTx.outputs, true);
@ -83,7 +84,7 @@ module.exports = (shepherd) => {
if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') { if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') {
ecl.blockchainTransactionGet(_decodedInput.txid) ecl.blockchainTransactionGet(_decodedInput.txid)
.then((rawInput) => { .then((rawInput) => {
const decodedVinVout = shepherd.electrumJSTxDecoder(rawInput, _network); const decodedVinVout = shepherd.isZcash(network) ? shepherd.electrumJSTxDecoderZ(rawInput, _network) : shepherd.electrumJSTxDecoder(rawInput, _network);
shepherd.log('electrum raw input tx ==>', true); shepherd.log('electrum raw input tx ==>', true);
@ -352,6 +353,7 @@ module.exports = (shepherd) => {
shepherd.log('electrum decoderawtx input tx ==>', true); shepherd.log('electrum decoderawtx input tx ==>', true);
if (req.query.parseonly || if (req.query.parseonly ||
decodedTx.inputs[0].txid === '0000000000000000000000000000000000000000000000000000000000000000') { decodedTx.inputs[0].txid === '0000000000000000000000000000000000000000000000000000000000000000') {
const successObj = { const successObj = {

Loading…
Cancel
Save