diff --git a/package.json b/package.json index 1841ae5..94e1645 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,8 @@ "arch": "^2.1.0", "bip39": "^2.4.0", "bitcoinjs-lib": "^3.2.0", + "bitcoinjs-lib-bch": "git://github.com/bitcoinjs/bitcoinjs-lib#opt-in-bitcoincash-sighash", + "bitcoinjs-lib-zcash": "git://github.com/karel-3d/bitcoinjs-lib#zcash", "bluebird": "^3.4.7", "body-parser": "^1.15.2", "buffer-reverse": "^1.0.1", diff --git a/routes/electrumjs/electrumServers.js b/routes/electrumjs/electrumServers.js index 9239a24..2329a1d 100644 --- a/routes/electrumjs/electrumServers.js +++ b/routes/electrumjs/electrumServers.js @@ -286,7 +286,7 @@ let electrumServers = { 'electrum1.cipig.net:10000', 'electrum2.cipig.net:10000' ], - }, + },*/ btg: { address: '173.212.225.176', port: 10052, @@ -320,7 +320,7 @@ let electrumServers = { 'electrum2.cipig.net:10050' ], }, - /*bch: { + bch: { address: 'electrum1.cipig.net', port: 10051, proto: 'tcp', @@ -330,7 +330,7 @@ let electrumServers = { 'electrum1.cipig.net:10051', 'electrum2.cipig.net:10051' ], - },*/ + }, argentum: { // !estimatefee address: '173.212.225.176', port: 50081, diff --git a/routes/shepherd/electrum/createtx.js b/routes/shepherd/electrum/createtx.js index 3478ab1..a87da8a 100644 --- a/routes/shepherd/electrum/createtx.js +++ b/routes/shepherd/electrum/createtx.js @@ -1,7 +1,17 @@ +const bitcoinJSForks = require('bitcoinforksjs-lib'); + module.exports = (shepherd) => { // unsigned tx shepherd.buildUnsignedTx = (sendTo, changeAddress, network, utxo, changeValue, spendValue) => { - let tx = new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); + let tx; + + if (network === 'btg') { + shepherd.log('enable btg'); + tx = new bitcoinJSForks.TransactionBuilder(shepherd.getNetworkData(network)); + tx.enableBitcoinGold(true); + } else { + tx = new shepherd.bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); + } shepherd.log('buildSignedTx'); // console.log(`buildSignedTx priv key ${wif}`); @@ -86,6 +96,60 @@ module.exports = (shepherd) => { return rawtx; } + // btg + shepherd.buildSignedTxForks = (sendTo, changeAddress, wif, network, utxo, changeValue, spendValue) => { + let tx; + + if (network === 'btg' || + network === 'bch') { + tx = new bitcoinJSForks.TransactionBuilder(shepherd.getNetworkData(network)); + } + + const keyPair = bitcoinJSForks.ECPair.fromWIF(wif, shepherd.getNetworkData(network)); + const pk = bitcoinJSForks.crypto.hash160(keyPair.getPublicKeyBuffer()); + const spk = bitcoinJSForks.script.pubKeyHash.output.encode(pk); + + shepherd.log(`buildSignedTx${network.toUpperCase()}`); + + for (let i = 0; i < utxo.length; i++) { + tx.addInput(utxo[i].txid, utxo[i].vout, bitcoinJSForks.Transaction.DEFAULT_SEQUENCE, spk); + } + + tx.addOutput(sendTo, Number(spendValue)); + + if (changeValue > 0) { + tx.addOutput(changeAddress, Number(changeValue)); + } + + if (network === 'btg') { + tx.enableBitcoinGold(true); + } else if (network === 'bch') { + tx.enableBitcoinCash(true); + } + + tx.setVersion(2); + + shepherd.log('buildSignedTx unsigned tx data vin', true); + shepherd.log(tx.tx.ins, true); + shepherd.log('buildSignedTx unsigned tx data vout', true); + shepherd.log(tx.tx.outs, true); + shepherd.log('buildSignedTx unsigned tx data', true); + shepherd.log(tx, true); + + const hashType = bitcoinJSForks.Transaction.SIGHASH_ALL | bitcoinJSForks.Transaction.SIGHASH_BITCOINCASHBIP143; + + for (let i = 0; i < utxo.length; i++) { + tx.sign(i, keyPair, null, hashType, utxo[i].value); + } + + const rawtx = tx.build().toHex(); + + shepherd.log('buildSignedTx signed tx hex', true); + shepherd.log(rawtx, true); + + return rawtx; + } + shepherd.maxSpendBalance = (utxoList, fee) => { let maxSpendBalance = 0; @@ -101,7 +165,7 @@ module.exports = (shepherd) => { } shepherd.get('/electrum/createrawtx', (req, res, next) => { - // txid 64 char + // TODO: unconf output(s) error message const network = req.query.network || shepherd.findNetworkObj(req.query.coin); const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[network].port, shepherd.electrumServers[network].address, shepherd.electrumServers[network].proto); // tcp or tls const outputAddress = req.query.address; @@ -123,7 +187,9 @@ module.exports = (shepherd) => { ecl.close(); if (utxoList && - utxoList.length) { + utxoList.length && + utxoList[0] && + utxoList[0].txid) { let utxoListFormatted = []; let totalInterest = 0; let totalInterestUTXOCount = 0; @@ -316,15 +382,28 @@ module.exports = (shepherd) => { value ); } else { - _rawtx = shepherd.buildSignedTx( - outputAddress, - changeAddress, - wif, - network, - inputs, - _change, - value - ); + if (network === 'btg' || + network === 'bch') { + _rawtx = shepherd.buildSignedTxForks( + outputAddress, + changeAddress, + wif, + network, + inputs, + _change, + value + ); + } else { + _rawtx = shepherd.buildSignedTx( + outputAddress, + changeAddress, + wif, + network, + inputs, + _change, + value + ); + } } if (!push ||