diff --git a/index.html b/index.html index e554b4fde..1de223647 100644 --- a/index.html +++ b/index.html @@ -133,7 +133,7 @@
- {{addr.addrStr}} > + {{addr}} >
diff --git a/js/config.js b/js/config.js index 9d2bf0553..8e0d35ee8 100644 --- a/js/config.js +++ b/js/config.js @@ -11,9 +11,11 @@ var config = { requiredCopayers: 2, totalCopayers: 3, }, - insight: { - host: 'localhost', - port: 3001 + blockchain: { + host: 'test.insight.is', + port: 80 + // host: 'localhost', + // port: 3001 }, verbose: 1, }; diff --git a/js/controllers/home.js b/js/controllers/home.js index 9f6d0bc41..204f10504 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -10,13 +10,13 @@ angular.module('copay.home').controller('HomeController', $location.path('signin'); } else { - $scope.addrs = $rootScope.wallet.publicKeyRing.getAddresses(); + $scope.addrs = $rootScope.wallet.getAddressesStr(); $scope.selectedAddr = $scope.addrs[0]; } $scope.newAddr = function() { var a = $rootScope.wallet.generateAddress(); - $scope.addrs.push({ addrStr: a.toString('hex') }); + $scope.addrs.push({ addrStr: a.toString() }); }; $scope.selectAddr = function(addr) { diff --git a/js/controllers/send.js b/js/controllers/send.js index 0c05b0af2..8b2bf9e0a 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -16,29 +16,22 @@ angular.module('copay.send').controller('SendController', var opts = {remainderOut: { address: pkr.generateAddress(true).toString() }}; // From @cmgustavo's wallet - var unspentTest = [{ - "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", - "vout": 1, - "amount": 10, - "confirmations":7 - }]; + w.listUnspent(function (unspentTest) { +console.log('[send.js.19:unspentTest:]',unspentTest); //TODO - unspentTest[0].address = pkr.generateAddress(false).toString(); - unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(false); - -console.log('[send.js.29:txp:] BEFORE',txp); //TODO - - txp.create( - '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', - '123456789', - unspentTest, - w.privateKey, - opts - ); + txp.create( + '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', + '123456789', + unspentTest, + w.privateKey, + opts + ); console.log('[send.js.29:txp:] READY:',txp); //TODO - Network.storeOpenWallet(); - Network.sendTxProposals(); - $rootScope.$digest; + Network.storeOpenWallet(); + Network.sendTxProposals(); + $rootScope.$digest; + + }); }; }); diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index 6ced3ebdb..d45be6266 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -5,8 +5,9 @@ var bitcore = require('bitcore'); function Insight(opts) { opts = opts || {}; - this.host = 'test.insight.is'; - this.port = '80'; + this.host = opts.host || 'localhost'; + this.port = opts.port || '3001'; + this.scheme = opts.scheme || 'http'; } function _asyncForEach(array, fn, callback) { @@ -40,7 +41,7 @@ Insight.prototype.getBalance = function(unspent) { Insight.prototype.listUnspent = function(addresses, cb) { var self = this; - if (!addresses || !addresses.length) return cb(); + if (!addresses || !addresses.length) return cb([]); var all = []; @@ -48,8 +49,11 @@ Insight.prototype.listUnspent = function(addresses, cb) { var options = { host: self.host, port: self.port, + scheme: self.scheme, method: 'GET', - path: '/api/addr/' + addr + '/utxo' + path: '/api/addr/' + addr + '/utxo', + + headers: { 'Access-Control-Request-Headers' : '' } }; self._request(options, function(err, res) { @@ -74,7 +78,6 @@ Insight.prototype.sendRawTransaction = function(rawtx, cb) { data: 'rawtx='+rawtx, headers: { 'content-type' : 'application/x-www-form-urlencoded' } }; - this._request(options, function(err,res) { if (err) return cb(); return cb(res.txid); diff --git a/js/models/core/PublicKeyRing.js b/js/models/core/PublicKeyRing.js index a5e4a8bcb..b7851ad24 100644 --- a/js/models/core/PublicKeyRing.js +++ b/js/models/core/PublicKeyRing.js @@ -275,7 +275,7 @@ PublicKeyRing.prototype._mergePubkeys = function(inPKR) { } if (!haveIt) { if (self.isComplete()) { - console.log('[PublicKeyRing.js.318] REPEATED KEY', epk); //TODO + //console.log('[PublicKeyRing.js.318] REPEATED KEY', epk); //TODO throw new Error('trying to add more pubkeys, when PKR isComplete at merge'); } self.copayersBIP32.push(new BIP32(epk)); diff --git a/js/models/core/TxProposals.js b/js/models/core/TxProposals.js index 28de54ae7..b3e0cced0 100644 --- a/js/models/core/TxProposals.js +++ b/js/models/core/TxProposals.js @@ -26,7 +26,6 @@ function TxProposals(opts) { this.walletId = opts.walletId; this.network = opts.networkName === 'livenet' ? bitcore.networks.livenet : bitcore.networks.testnet; - this.publicKeyRing = opts.publicKeyRing; this.txps = []; } @@ -136,6 +135,10 @@ TxProposals.prototype._mergeBuilder = function(myTxps, theirTxps, mergeInfo) { }); }; +TxProposals.prototype.add = function(data) { + this.txps.push( new TxProposal(data) ); +}; + TxProposals.prototype.merge = function(t) { if (this.network.name !== t.network.name) throw new Error('network mismatch in:', t); @@ -157,44 +160,6 @@ TxProposals.prototype.merge = function(t) { return mergeInfo.stats; }; -TxProposals.prototype.create = function(toAddress, amountSatStr, utxos, priv, opts) { - var pkr = this.publicKeyRing; - opts = opts || {}; - var amountSat = bitcore.bignum(amountSatStr); - - if (! pkr.isComplete() ) { - throw new Error('publicKeyRing is not complete'); - } - - var opts = { - remainderOut: opts.remainderOut || { address: pkr.generateAddress(true).toString() } - }; - - var b = new Builder(opts) - .setUnspent(utxos) - .setHashToScriptMap(pkr.getRedeemScriptMap()) - .setOutputs([{address: toAddress, amountSat: amountSat}]) - ; - - var signRet; - if (priv) { - b.sign( priv.getAll(pkr.addressIndex, pkr.changeAddressIndex) ); - } - var me = {}; - if (priv) me[priv.id] = Date.now(); - - this.txps.push( - new TxProposal({ - signedBy: priv && b.signaturesAdded ? me : {}, - seenBy: priv ? me : {}, - builder: b, - }) - ); - return 1; -}; - -TxProposals.prototype.sign = function(index) { -}; module.exports = require('soop')(TxProposals); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 75674a567..39ba995ff 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1,17 +1,18 @@ 'use strict'; -var imports = require('soop').imports(); +var imports = require('soop').imports(); -var bitcore = require('bitcore'); -var coinUtil = bitcore.util; +var bitcore = require('bitcore'); +var coinUtil = bitcore.util; var buffertools = bitcore.buffertools; -var http = require('http'); +var Builder = bitcore.TransactionBuilder; +var http = require('http'); -var Storage = imports.Storage; -var Network = imports.Network; -var Blockchain = imports.Blockchain; +var Storage = imports.Storage; +var Network = imports.Network; +var Blockchain = imports.Blockchain; -var copay = copay || require('../../../copay'); +var copay = copay || require('../../../copay'); function Wallet(config) { this._startInterface(config); @@ -56,7 +57,6 @@ Wallet.prototype.create = function(opts) { this.txProposals = new copay.TxProposals({ walletId: this.id, - publicKeyRing: this.publicKeyRing, networkName: this.networkName, }); this.log('\t### TxProposals Initialized'); @@ -167,8 +167,56 @@ Wallet.prototype.getAddresses = function() { return this.publicKeyRing.getAddresses(); }; +Wallet.prototype.getAddressesStr = function() { + var ret = []; + this.publicKeyRing.getAddresses().forEach(function(a) { + ret.push(a.toString()); + }); + return ret; +}; + + + Wallet.prototype.listUnspent = function(cb) { - this.blockchain.listUnspent(this.getAddresses(), cb); + this.blockchain.listUnspent(this.getAddressesStr(), cb); +}; + +Wallet.prototype.createTx = function(toAddress, amountSatStr, utxos, opts) { + var pkr = this.publicKeyRing; + var priv = this.privateKey; + opts = opts || {}; + + var amountSat = bitcore.bignum(amountSatStr); + + if (! pkr.isComplete() ) { + throw new Error('publicKeyRing is not complete'); + } + + if (!opts.remainderOut) { + opts.remainderOut ={ address: pkr.generateAddress(true).toString() }; + }; + + var b = new Builder(opts) + .setUnspent(utxos) + .setHashToScriptMap(pkr.getRedeemScriptMap()) + .setOutputs([{address: toAddress, amountSat: amountSat}]) + ; + + var signRet; + if (priv) { + b.sign( priv.getAll(pkr.addressIndex, pkr.changeAddressIndex) ); + } + var me = {}; + if (priv) me[priv.id] = Date.now(); + + this.txProposals.add({ + signedBy: priv && b.signaturesAdded ? me : {}, + seenBy: priv ? me : {}, + builder: b, + }); +}; + +Wallet.prototype.sign = function(txp) { }; // // HERE? not sure diff --git a/test/test.txproposal.js b/test/test.txproposal.js index 66d72d5ba..26ed2974d 100644 --- a/test/test.txproposal.js +++ b/test/test.txproposal.js @@ -10,6 +10,7 @@ var Key = bitcore.Key; var BIP32 = bitcore.BIP32; var bignum = bitcore.bignum; var Script = bitcore.Script; +var Builder = bitcore.TransactionBuilder; var util = bitcore.util; var networks = bitcore.networks; var copay = copay || require('../copay'); @@ -69,106 +70,60 @@ describe('TxProposals model', function() { w.network.name.should.equal('livenet'); }); - it('#create, no signing', function () { - var w = new TxProposals({ - networkName: config.networkName, - publicKeyRing: createPKR(), - }); - should.exist(w); - w.network.name.should.equal('livenet'); + function createTx(toAddress, amountSatStr, utxos, opts, priv, pkr) { + opts = opts || {}; - unspentTest[0].address = w.publicKeyRing.getAddress(1, true).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true); + var amountSat = bitcore.bignum(amountSatStr); - w.create( - '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', - '123456789', - unspentTest - ); - var tx = w.txps[0].builder.build(); - should.exist(tx); - tx.isComplete().should.equal(false); - Object.keys(w.txps[0].signedBy).length.should.equal(0); - Object.keys(w.txps[0].seenBy).length.should.equal(0); - }); - - - it('#create, signing with wrong key', function () { - var w = new TxProposals({ - networkName: config.networkName, - publicKeyRing: createPKR(), - }); - should.exist(w); - w.network.name.should.equal('livenet'); - - unspentTest[0].address = w.publicKeyRing.getAddress(1, true).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true); - - var priv = new PrivateKey(config); - w.create( - '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', - '123456789', - unspentTest, - priv - ); - var tx = w.txps[0].builder.build(); - should.exist(tx); - tx.isComplete().should.equal(false); - Object.keys(w.txps[0].signedBy).length.should.equal(0); - Object.keys(w.txps[0].seenBy).length.should.equal(1); - }); - - - it('#create. Signing with derivate keys', function () { - - var priv = new PrivateKey(config); - var w = new TxProposals({ - networkName: config.networkName, - publicKeyRing: createPKR([priv.getBIP32()]), - }); - - var ts = Date.now(); - for (var isChange=0; isChange<2; isChange++) { - for (var index=0; index<3; index++) { - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( - '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', - '123456789', - unspentTest, - priv - ); - var tx = w.txps[0].builder.build(); - should.exist(tx); - tx.isComplete().should.equal(false); - - tx.countInputMissingSignatures(0).should.equal(2); - - (w.txps[0].signedBy[priv.id] - ts > 0).should.equal(true); - (w.txps[0].seenBy[priv.id] - ts > 0).should.equal(true); - } + if(! pkr.isComplete() ) { + throw new Error('publicKeyRing is not complete'); } - }); + + if (!opts.remainderOut) { + opts.remainderOut ={ address: pkr.generateAddress(true).toString() }; + }; + + var b = new Builder(opts) + .setUnspent(utxos) + .setHashToScriptMap(pkr.getRedeemScriptMap()) + .setOutputs([{address: toAddress, amountSat: amountSat}]) + ; + + var signRet; + if (priv) { + b.sign( priv.getAll(pkr.addressIndex, pkr.changeAddressIndex) ); + } + var me = {}; + if (priv) me[priv.id] = Date.now(); + + return { + signedBy: priv && b.signaturesAdded ? me : {}, + seenBy: priv ? me : {}, + builder: b, + }; + }; + it('#merge with self', function () { - var priv = new PrivateKey(config); var w = new TxProposals({ networkName: config.networkName, - publicKeyRing: createPKR([priv.getBIP32()]), }); + var pkr=createPKR([priv.getBIP32()]); var ts = Date.now(); var isChange=0; var index=0; - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, - priv - ); + {}, + priv, + pkr + )); var tx = w.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -184,13 +139,11 @@ describe('TxProposals model', function() { (w.txps[0].signedBy[priv.id] - ts > 0).should.equal(true); (w.txps[0].seenBy[priv.id] - ts > 0).should.equal(true); - }); it('#merge, merge signatures case 1', function () { - var priv2 = new PrivateKey(config); var priv = new PrivateKey(config); var ts = Date.now(); @@ -202,17 +155,17 @@ describe('TxProposals model', function() { var w = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv2, - opts - ); + pkr + )); var tx = w.txps[0].builder.build(); tx.isComplete().should.equal(false); @@ -226,15 +179,16 @@ describe('TxProposals model', function() { networkName: config.networkName, publicKeyRing: w.publicKeyRing, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w2.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w2.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv, - opts - ); + pkr + )); var tx = w2.txps[0].builder.build(); tx.isComplete().should.equal(false); @@ -275,17 +229,18 @@ var _dumpChunks = function (scriptSig, label) { var w = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + + w.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv3, - opts - ); + pkr + )); var tx = w.txps[0].builder.build(); tx.isComplete().should.equal(false); @@ -297,17 +252,18 @@ var _dumpChunks = function (scriptSig, label) { var w2 = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w2.create( + + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w2.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv, - opts - ); + pkr + )); tx = w2.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -329,15 +285,16 @@ var _dumpChunks = function (scriptSig, label) { networkName: config.networkName, publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w3.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w3.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv2, - opts - ); + pkr + )); tx = w3.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -372,17 +329,17 @@ var _dumpChunks = function (scriptSig, label) { var w = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv, - opts - ); + pkr + )); var tx = w.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -392,17 +349,17 @@ var _dumpChunks = function (scriptSig, label) { var w2 = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w2.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w2.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv2, - opts - ); + pkr + )); var tx = w2.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -412,17 +369,17 @@ var _dumpChunks = function (scriptSig, label) { var w3 = new TxProposals({ networkName: config.networkName, - publicKeyRing: pkr, }); - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w3.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w3.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, + opts, priv3, - opts - ); + pkr + )); var tx = w3.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); @@ -458,23 +415,25 @@ var _dumpChunks = function (scriptSig, label) { it('#toObj #fromObj roundtrip', function () { var priv = new PrivateKey(config); + var pkr = createPKR([priv.getBIP32()]); var w = new TxProposals({ walletId: 'qwerty', networkName: config.networkName, - publicKeyRing: createPKR([priv.getBIP32()]), }); var ts = Date.now(); var isChange=0; var index=0; - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); - unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); - w.create( + unspentTest[0].address = pkr.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = pkr.getScriptPubKeyHex(index, isChange); + w.add(createTx( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', '123456789', unspentTest, - priv - ); + {}, + priv, + pkr + )); var tx = w.txps[0].builder.build(); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); diff --git a/test/test.wallet.js b/test/test.wallet.js index c43bfbbe0..98f069e32 100644 --- a/test/test.wallet.js +++ b/test/test.wallet.js @@ -21,7 +21,11 @@ describe('Wallet model', function() { wallet: { requiredCopayers: 3, totalCopayers: 5, - } + }, + blockchain: { + host: 'test.insight.is', + port: 80 + }, }; var opts = {}; @@ -51,7 +55,7 @@ describe('Wallet model', function() { should.exist(w.txProposals); }); - it('should create', function () { + it('should list unspent', function (done) { var opts = {}; var w = new Wallet(config); w.create(); @@ -60,10 +64,13 @@ describe('Wallet model', function() { should.exist(w.id); w.publicKeyRing.isComplete().should.equal(true); + + w.listUnspent(function(utxos) { + utxos.length.should.equal(0); + done(); + }); }); - - describe('factory', function() { it('should create the factory', function() { should.exist(Wallet.factory); @@ -79,4 +86,111 @@ describe('Wallet model', function() { }); }); + var unspentTest = [ + { + "address": "dummy", + "scriptPubKey": "dummy", + "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1", + "vout": 1, + "amount": 10, + "confirmations":7 + } + ]; + + var createWallet = function (bip32s) { + var w = new Wallet(config); + w.create(); + should.exist(w); + + var pkr = w.publicKeyRing; + + for(var i=0; i<4; i++) { + if (bip32s) { + var b=bip32s[i]; + pkr.addCopayer(b?b.extendedPublicKeyString():null); + } + else + pkr.addCopayer(); + } + pkr.generateAddress(true); + pkr.generateAddress(true); + pkr.generateAddress(true); + pkr.generateAddress(false); + pkr.generateAddress(false); + pkr.generateAddress(false); + //3x3 indexes + + return w; + }; + + it('#create, 1 sign', function () { + + var w = createWallet(); + + unspentTest[0].address = w.publicKeyRing.getAddress(1, true).toString(); + unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true); + + w.createTx( + '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', + '123456789', + unspentTest + ); + + var t = w.txProposals; + var tx = t.txps[0].builder.build(); + should.exist(tx); + tx.isComplete().should.equal(false); + Object.keys(t.txps[0].signedBy).length.should.equal(1); + Object.keys(t.txps[0].seenBy).length.should.equal(1); + }); + + + + it('#create. Signing with derivate keys', function () { + + var w = createWallet(); + + var ts = Date.now(); + for (var isChange=0; isChange<2; isChange++) { + for (var index=0; index<3; index++) { + unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange).toString(); + unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(index, isChange); + w.createTx( + '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', + '123456789', + unspentTest + ); + var t = w.txProposals; + var tx = t.txps[0].builder.build(); + should.exist(tx); + tx.isComplete().should.equal(false); + tx.countInputMissingSignatures(0).should.equal(2); + + ( t.txps[0].signedBy[w.privateKey.id] - ts > 0).should.equal(true); + ( t.txps[0].seenBy[w.privateKey.id] - ts > 0).should.equal(true); + } + } + }); + + // TODO: when sign is implemented + it.skip('#create, signing with wrong key', function () { + var w1 = createWallet(); + + unspentTest[0].address = w.publicKeyRing.getAddress(1, true).toString(); + unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true); + + var priv = new PrivateKey(config); + w.create( + '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', + '123456789', + unspentTest + ); + var tx = w.txps[0].builder.build(); + should.exist(tx); + tx.isComplete().should.equal(false); + Object.keys(w.txps[0].signedBy).length.should.equal(0); + Object.keys(w.txps[0].seenBy).length.should.equal(1); + }); + + });