diff --git a/js/controllers/signin.js b/js/controllers/signin.js index fee00a14a..7ecd0680c 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -43,8 +43,6 @@ angular.module('copay.signin').controller('SigninController', $location.path('peer'); $rootScope.$digest(); }, function() { - -console.log('[signin.js.46] SETTING MESSAGE'); //TODO $rootScope.flashMessage = { message: 'Connection refussed', type: 'error'}; $location.path('home'); $rootScope.$digest(); diff --git a/js/models/PrivateKey.js b/js/models/PrivateKey.js index 1b27fe7d3..1f827277f 100644 --- a/js/models/PrivateKey.js +++ b/js/models/PrivateKey.js @@ -6,15 +6,19 @@ var bitcore = require('bitcore'); var BIP32 = bitcore.BIP32; var WalletKey = bitcore.WalletKey; var networks = bitcore.networks; +var util = bitcore.util; var PublicKeyRing = require('./PublicKeyRing'); function PrivateKey(opts) { - this.id = opts.id; this.network = opts.networkName === 'testnet' ? networks.testnet : networks.livenet; - this.BIP32 = opts.BIP32 || new BIP32(this.network.name); + this.BIP32 = opts.BIP32 || new BIP32(opts.extendedPrivateKeyString || this.network.name); + this._calcId(); }; +PrivateKey.prototype._calcId = function() { + this.id = util.ripe160(this.BIP32.extendedPublicKey).toString('hex'); +}; PrivateKey.prototype.getBIP32 = function(index,isChange) { if (typeof index === 'undefined') { @@ -24,6 +28,21 @@ PrivateKey.prototype.getBIP32 = function(index,isChange) { PublicKeyRing.ChangeBranch(index):PublicKeyRing.PublicBranch(index) ); }; + +PrivateKey.fromObj = function(o) { + return new PrivateKey({ + extendedPrivateKeyString: o.extendedPrivateKeyString, + networkName: o.networkName, + }); +}; + +PrivateKey.prototype.toObj = function() { + return { + extendedPrivateKeyString: this.BIP32.extendedPrivateKeyString(), + networkName: this.network.name, + }; +}; + PrivateKey.prototype.get = function(index,isChange) { var derivedBIP32 = this.getBIP32(index,isChange); var wk = new WalletKey({network: this.network}); @@ -34,6 +53,7 @@ PrivateKey.prototype.get = function(index,isChange) { PrivateKey.prototype.getAll = function(addressIndex, changeAddressIndex) { var ret = []; + for(var i=0;i probably not in network.js var createWallet = function(walletId) { + console.log('### CREATING WALLET. ID:' + walletId); + var priv = new copay.PrivateKey({networkName: config.networkName}); + console.log('\t### PrivateKey Initialized'); + //TODO create a wallet and WalletId, not only pkr var pkr = new copay.PublicKeyRing({ - network: config.networkName, + networkName: config.networkName, id: walletId, }); - pkr.addCopayer(); - console.log('\t### PublicKeyRing Initialized:'); + + // Add self to the ring. + pkr.addCopayer(priv.getBIP32().extendedPublicKeyString()); + console.log('\t### PublicKeyRing Initialized'); + + var txp = new copay.TxProposals({ + networkName: config.networkName, + publicKeyRing: pkr, + }); + console.log('\t### TxProposals Initialized'); + Storage.addWalletId(pkr.id); Storage.set(pkr.id, 'publicKeyRing', pkr.toObj()); + Storage.set(pkr.id, 'privateKey', priv.toObj()); + Storage.set(pkr.id, 'txProposals', txp.toObj()); + console.log('\t### Wallet Stored'); + // Store it on rootScope + $rootScope.priv = priv; // TODO secure this. $rootScope.walletId = pkr.id; $rootScope.publicKeyRing = pkr; + $rootScope.txProposals = txp; }; var openWallet = function (walletId) { var ret = false; var pkr = Storage.get(walletId, 'publicKeyRing'); + var priv = Storage.get(walletId, 'privateKey'); + var txp = Storage.get(walletId, 'txProposals'); if (pkr) { console.log('### WALLET OPENED:', walletId, pkr); $rootScope.walletId = walletId; $rootScope.publicKeyRing = new copay.PublicKeyRing.fromObj(pkr); + $rootScope.txProposals = new copay.TxProposals.fromObj(txp); + $rootScope.priv = new copay.PrivateKey.fromObj(priv); //TODO secure ret = true; } return ret; @@ -133,7 +156,6 @@ angular.module('copay.network') // public methods var init = function(cb) { - var cp = $rootScope.cp = new copay.CopayPeer({ apiKey: config.p2pApiKey, debug: config.p2pDebug, @@ -141,7 +163,6 @@ angular.module('copay.network') }); _setupHandlers(); - // inicia session cp.start(function(peerId) { return cb(); }); @@ -156,15 +177,15 @@ angular.module('copay.network') _refreshUx(); }; - var connect = function(peerId, openCallback, failCallBack) { + var connect = function(peerId, openCallback, failCallback) { if ($rootScope.cp) { $rootScope.cp.connectTo(peerId, openCallback, function () { disconnect(); - failCallBack(); + failCallback(); }); } else - return failCallBack(); + return failCallback(); }; return { diff --git a/test/test.PrivateKey.js b/test/test.PrivateKey.js index d1325e971..1c678aa0e 100644 --- a/test/test.PrivateKey.js +++ b/test/test.PrivateKey.js @@ -67,4 +67,25 @@ describe('PrivateKey model', function() { } }); + it('should calculate .id', function () { + var w1 = new PrivateKey(config); + should.exist(w1.id); + w1.id.length.should.equal(40); + }); + it('fromObj toObj roundtrip', function () { + var w1 = new PrivateKey(config); + var w2 = PrivateKey.fromObj(w1.toObj()); + + w2.getBIP32().extendedPrivateKeyString().should.equal(w1.getBIP32().extendedPrivateKeyString()); + w2.getBIP32().extendedPublicKeyString().should.equal(w1.getBIP32().extendedPublicKeyString()); + w2.id.should.equal(w1.id); + + + w2.getBIP32(1,1).extendedPrivateKeyString().should + .equal(w1.getBIP32(1,1).extendedPrivateKeyString()); + w2.getBIP32(1,0).extendedPrivateKeyString().should + .equal(w1.getBIP32(1,0).extendedPrivateKeyString()); + }); + + }); diff --git a/test/test.txproposal.js b/test/test.txproposal.js index 89194d0e1..8377a0206 100644 --- a/test/test.txproposal.js +++ b/test/test.txproposal.js @@ -44,11 +44,13 @@ var createW = function (bip32s) { else w.addCopayer(); } - w.generateAddress(true); - w.generateAddress(true); - w.generateAddress(true); - w.generateAddress(false); - w.generateAddress(false); + w.generateAddress(true); + w.generateAddress(true); + w.generateAddress(true); + w.generateAddress(false); + w.generateAddress(false); + w.generateAddress(false); + //3x3 indexes return w; }; @@ -91,57 +93,64 @@ describe('TxProposals model', function() { networkName: config.networkName, publicKeyRing: createW([priv.getBIP32()]), }); - should.exist(w); - w.network.name.should.equal('livenet'); - + 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); unspentTest[0].scriptPubKey = w.publicKeyRing.getRedeemScript(index, isChange).getBuffer(); - var tx = w.create( '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', bignum('123456789'), unspentTest, - [priv.get(index,isChange)] + priv ); should.exist(tx); tx.isComplete().should.equal(false); tx.countInputMissingSignatures(0).should.equal(2); + (w.txs[0].signedBy[priv.id] - ts > 0).should.equal(true); + (w.txs[0].seenBy[priv.id] - ts > 0).should.equal(true); } } - }); - it('#create. Signing with derivate keys block', function () { + it('#toObj #fromObj roundtrip', function () { var priv = new PrivateKey(config); - - var privs = priv.getAll(3,3); - var w = new TxProposals({ networkName: config.networkName, publicKeyRing: createW([priv.getBIP32()]), }); - should.exist(w); - w.network.name.should.equal('livenet'); + var ts = Date.now(); + var isChange=0; + var index=0; - for (var isChange=0; isChange<2; isChange++) { - for (var index=0; index<3; index++) { - unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange); - unspentTest[0].scriptPubKey = w.publicKeyRing.getRedeemScript(index, isChange).getBuffer(); - var tx = w.create( - '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', - bignum('123456789'), - unspentTest, - privs - ); - should.exist(tx); - tx.isComplete().should.equal(false); - tx.countInputMissingSignatures(0).should.equal(2); - } - } + unspentTest[0].address = w.publicKeyRing.getAddress(index, isChange); + unspentTest[0].scriptPubKey = w.publicKeyRing.getRedeemScript(index, isChange).getBuffer(); + var tx = w.create( + '15q6HKjWHAksHcH91JW23BJEuzZgFwydBt', + bignum('123456789'), + unspentTest, + priv + ); + tx.isComplete().should.equal(false); + tx.countInputMissingSignatures(0).should.equal(2); + (w.txs[0].signedBy[priv.id] - ts > 0).should.equal(true); + (w.txs[0].seenBy[priv.id] - ts > 0).should.equal(true); + var o = w.toObj(); + should.exist(o); + o.txs.length.should.equal(1); + should.exist(o.txs[0].txHex); + should.exist(o.txs[0].signedBy); + should.exist(o.txs[0].seenBy); + should.exist(o.txs[0].signedBy[priv.id]); + + var w2 = TxProposals.fromObj(o); + var tx2 = w2.txs[0].tx; + tx2.isComplete().should.equal(false); + tx2.countInputMissingSignatures(0).should.equal(2); + (w2.txs[0].signedBy[priv.id] - ts > 0).should.equal(true); + (w2.txs[0].seenBy[priv.id] - ts > 0).should.equal(true); }); });