diff --git a/js/models/Identity.js b/js/models/Identity.js index 93134543e..b61fdb7eb 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -350,8 +350,28 @@ Identity.prototype.bindWallet = function(w) { self.wallets[w.getId()] = w; log.debug('Binding wallet ' + w.getName()); - w.on('hasChange', function() { - log.debug(' Wallet' + w.getName()); + w.on('txProposalsUpdated', function() { + log.debug('> Wallet' + w.getName()); + self.storeWallet(w); + }); + w.on('newAddresses', function() { + log.debug(' Wallet' + w.getName()); + self.storeWallet(w); + }); + w.on('settingsUpdated', function() { + log.debug(' Wallet' + w.getName()); + self.storeWallet(w); + }); + w.on('txProposalEvent', function() { + log.debug(' Wallet' + w.getName()); + self.storeWallet(w); + }); + w.on('ready', function() { + log.debug(' Wallet' + w.getName()); + self.storeWallet(w); + }); + w.on('addressBookUpdated', function() { + log.debug(' Wallet' + w.getName()); self.storeWallet(w); }); }; @@ -412,6 +432,8 @@ Identity.prototype.createWallet = function(opts, cb) { opts.txProposals = opts.txProposals || new TxProposals({ networkName: opts.networkName, }); + var walletClass = opts.walletClass || Wallet; + log.debug('\t### TxProposals Initialized'); @@ -425,7 +447,8 @@ Identity.prototype.createWallet = function(opts, cb) { opts.version = opts.version || this.version; var self = this; - var w = new Wallet(opts); + + var w = new walletClass(opts); this.addWallet(w, function(err) { if (err) return cb(err); self.bindWallet(w); diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 29349d705..608dbea3d 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -268,7 +268,6 @@ Wallet.prototype._onIndexes = function(senderId, data) { var hasChanged = this.publicKeyRing.mergeIndexes(inIndexes); if (hasChanged) { this._newAddresses(); - this.emitAndKeepAlive('hasChange'); } }; @@ -285,7 +284,7 @@ Wallet.prototype._onIndexes = function(senderId, data) { */ Wallet.prototype.changeSettings = function(settings) { this.settings = settings; - this.emitAndKeepAlive('hasChange'); + this.emitAndKeepAlive('settingsUpdated'); }; /** @@ -329,7 +328,6 @@ Wallet.prototype._onPublicKeyRing = function(senderId, data) { this._lockIncomming(); } this._newAddresses(); - this.emitAndKeepAlive('hasChange'); } }; @@ -470,7 +468,6 @@ Wallet.prototype._onTxProposal = function(senderId, data) { if (!m.txp.getSent()) { m.txp.setSent(m.ntxid); self.emitAndKeepAlive('txProposalsUpdated'); - self.emit('hasChange'); } } }); @@ -481,7 +478,6 @@ Wallet.prototype._onTxProposal = function(senderId, data) { } this.emitAndKeepAlive('txProposalsUpdated'); - this.emit('hasChange'); } this._processProposalEvents(senderId, m); }; @@ -509,10 +505,7 @@ Wallet.prototype._onReject = function(senderId, data) { throw new Error('Received Reject for an already signed TX from:' + senderId); txp.setRejected(senderId); - this.emitAndKeepAlive('hasChange'); - - this.emit('txProposalsUpdated'); - this.emit('txProposalEvent', { + this.emitAndKeepAlive('txProposalEvent', { type: 'rejected', cId: senderId, txId: data.ntxid, @@ -535,9 +528,7 @@ Wallet.prototype._onSeen = function(senderId, data) { var txp = this.txProposals.get(data.ntxid); txp.setSeen(senderId); - this.emitAndKeepAlive('hasChange'); - this.emit('txProposalsUpdated'); - this.emit('txProposalEvent', { + this.emitAndKeepAlive('txProposalEvent', { type: 'seen', cId: senderId, txId: data.ntxid, @@ -573,7 +564,6 @@ Wallet.prototype._onAddressBook = function(senderId, data) { } if (hasChange) { this.emitAndKeepAlive('addressBookUpdated'); - this.emit('hasChange'); } }; @@ -895,8 +885,6 @@ Wallet.prototype.netStart = function() { self.emitAndKeepAlive('ready', net.getPeer()); setTimeout(function() { self._newAddresses(true); - // no connection logic for now - self.emitAndKeepAlive('txProposalsUpdated'); }, 0); }); }; @@ -1256,7 +1244,7 @@ Wallet.prototype._doGenerateAddress = function(isChange) { Wallet.prototype.generateAddress = function(isChange, cb) { var addr = this._doGenerateAddress(isChange); this.sendIndexes(); - this.emitAndKeepAlive('hasChange'); + this._newAddresses(); if (cb) return cb(addr); return addr; }; @@ -1297,7 +1285,7 @@ Wallet.prototype.purgeTxProposals = function(deleteAll) { } else { this.txProposals.deletePending(this.maxRejectCount()); } - this.emitAndKeepAlive('hasChange'); + this.emitAndKeepAlive('txProposalsUpdated'); var n = this.txProposals.length(); return m - n; @@ -1311,8 +1299,7 @@ Wallet.prototype.purgeTxProposals = function(deleteAll) { Wallet.prototype.reject = function(ntxid) { var txp = this.txProposals.reject(ntxid, this.getMyCopayerId()); this.sendReject(ntxid); - this.emitAndKeepAlive('hasChange'); - this.emit('txProposalsUpdated'); + this.emitAndKeepAlive('txProposalsUpdated'); }; /** @@ -1353,8 +1340,7 @@ Wallet.prototype.sign = function(ntxid, cb) { if (txp.countSignatures() > before) { txp.signedBy[myId] = Date.now(); self.sendTxProposal(ntxid); - self.emitAndKeepAlive('hasChange'); - self.emit('txProposalsUpdated'); + self.emitAndKeepAlive('txProposalsUpdated'); ret = true; } if (cb) return cb(ret); @@ -1392,13 +1378,13 @@ Wallet.prototype.sendTx = function(ntxid, cb) { if (txid) { self.txProposals.get(ntxid).setSent(txid); self.sendTxProposal(ntxid); - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(txid); } else { log.debug('Wallet:' + self.id + ' Sent failed. Checking if the TX was sent already'); self._checkSentTx(ntxid, function(txid) { if (txid) - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(txid); }); @@ -1608,7 +1594,6 @@ Wallet.prototype.receivePaymentRequest = function(options, pr, cb) { if (ntxid) { self.sendIndexes(); self.sendTxProposal(ntxid); - self.emitAndKeepAlive('hasChange'); self.emit('txProposalsUpdated'); } @@ -1740,9 +1725,8 @@ Wallet.prototype.sendPaymentTx = function(ntxid, options, cb) { log.debug('Sending to server was not met with a returned tx.'); log.debug('XHR status: ' + status); return self._checkSentTx(ntxid, function(txid) { - log.debug('[Wallet.js.1581:txid:%s]', txid); if (txid) - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(txid, txp.merchant); }); }); @@ -1775,7 +1759,7 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { return this._checkSentTx(ntxid, function(txid) { log.debug('[Wallet.js.1613:txid:%s]', txid); if (txid) - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalUpdated'); return cb(txid, txp.merchant); }); } @@ -1802,13 +1786,13 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { if (txid) { self.txProposals.get(ntxid).setSent(txid); self.sendTxProposal(ntxid); - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(txid, txp.merchant); } else { log.debug('Sent failed. Checking if the TX was sent already'); self._checkSentTx(ntxid, function(txid) { if (txid) - self.emitAndKeepAlive('hasChange'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(txid, txp.merchant); }); @@ -2294,7 +2278,6 @@ Wallet.prototype.removeTxWithSpentInputs = function(cb) { if (proposalsChanged) { self.emitAndKeepAlive('txProposalsUpdated'); - self.emit('hasChange'); } return cb(); @@ -2329,8 +2312,7 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) self.sendIndexes(); self.sendTxProposal(ntxid); - self.emitAndKeepAlive('hasChange'); - self.emit('txProposalsUpdated'); + self.emitAndKeepAlive('txProposalsUpdated'); return cb(null, ntxid); }); }; @@ -2428,7 +2410,6 @@ Wallet.prototype.updateIndexes = function(callback) { if (err) callback(err); log.debug('Wallet:' + self.id + ' Indexes updated'); self._newAddresses(); - self.emitAndKeepAlive('hasChange'); callback(); }); }; @@ -2586,7 +2567,7 @@ Wallet.prototype.setAddressBook = function(key, label) { }; this.addressBook[key] = newEntry; this.sendAddressBook(); - this.emitAndKeepAlive('hasChange'); + this.emitAndKeepAlive('addressBookUpdated'); }; /** @@ -2616,7 +2597,7 @@ Wallet.prototype.verifyAddressbookEntry = function(rcvEntry, senderId, key) { Wallet.prototype.toggleAddressBookEntry = function(key) { if (!key) throw new Error('Key is required'); this.addressBook[key].hidden = !this.addressBook[key].hidden; - this.emitAndKeepAlive('hasChange'); + this.emitAndKeepAlive('addressBookUpdated'); }; /** @@ -2653,7 +2634,7 @@ Wallet.prototype.setBackupReady = function(forcedLogin) { this.forcedLogin = forcedLogin; this.publicKeyRing.setBackupReady(); this.sendPublicKeyRing(); - this.emitAndKeepAlive('hasChange'); + this.emitAndKeepAlive('txProposalsUpdated'); }; /** diff --git a/test/Identity.js b/test/Identity.js index 5defa42e4..165e19613 100644 --- a/test/Identity.js +++ b/test/Identity.js @@ -115,7 +115,7 @@ describe('Identity model', function() { }); describe('Identity.create()', function() { - it('should call .store', function(done) { + it('should create', function(done) { var args = createIdentity(); args.blockchain.on = sinon.stub(); Identity.create(args.params, function(err, iden) { @@ -149,36 +149,32 @@ describe('Identity model', function() { }); }); - describe('#store', function() { - it('should call .store for identity and wallets', function(done) { - var args = createIdentity(); - Identity.create(args.params, function(err, identity) { - - args.storage.setItem = sinon.stub(); - args.storage.setItem.onFirstCall().callsArg(2); - - var wallet1 = {}, wallet2 = {}; - identity.storeWallet = sinon.stub(); - identity.storeWallet.onFirstCall().callsArg(1); - identity.storeWallet.onSecondCall().callsArg(1); - identity.wallets = {'a': wallet1, 'b': wallet2}; - - identity.store({}, function(err) { - should.not.exist(err); - done(); - }); - - }); - }); + describe.skip('#storeWallet', function() { + // TODO test storeWallet }); - describe('#createWallet', function() { + describe('#createWallet', function() { var iden = null; var args = null; + var walletClass = function(args) { + var w = sinon.stub(); + w.getId = sinon.stub().returns('wid'); + w.getStorageKey = sinon.stub().returns('wkey'); + w.toObj = sinon.stub().returns({ + obj: 1 + }); + w.getName = sinon.stub().returns('name'); + w.on = sinon.stub(); + w.netStart = sinon.stub(); + w.args = args; + return w; + }; + beforeEach(function(done) { args = createIdentity(); + args.params.noWallets = true; Identity.create(args.params, function(err, identity) { iden = identity; done(); @@ -190,10 +186,13 @@ describe('Identity model', function() { args.storage.setItem = sinon.stub(); args.storage.setItem.onFirstCall().callsArg(2); args.storage.setItem.onSecondCall().callsArg(2); + should.exist(walletClass, 'check walletClass stub'); iden.createWallet({ privateKeyHex: priv, + walletClass: walletClass, }, function(err, w) { should.not.exist(err); + w.args.privateKey.toObj().extendedPrivateKeyString.should.equal(priv); done(); }); }); @@ -204,10 +203,18 @@ describe('Identity model', function() { args.storage.setItem.onCall(1).callsArg(2); args.storage.setItem.onCall(2).callsArg(2); args.storage.setItem.onCall(3).callsArg(2); - iden.createWallet(null, function(err, w1) { + iden.createWallet({ + walletClass: walletClass, + }, function(err, w1) { should.exist(w1); - iden.createWallet(null, function(err, w2) { + + iden.createWallet({ + walletClass: walletClass, + }, function(err, w2) { should.exist(w2); + w2.args.privateKey.toObj().extendedPrivateKeyString.should.not.equal( + w1.args.privateKey.toObj().extendedPrivateKeyString + ); done(); }); }); @@ -353,7 +360,9 @@ describe('Identity model', function() { net.start.onFirstCall().callsArg(1); net.greet = sinon.stub(); iden.createWallet = sinon.stub(); - var fakeWallet = {sendWalletReady: _.noop}; + var fakeWallet = { + sendWalletReady: _.noop + }; iden.createWallet.onFirstCall().yields(null, fakeWallet); net.on.withArgs('data').yields('senderId', { type: 'walletId', diff --git a/test/Wallet.js b/test/Wallet.js index 900f681ad..63ee3323f 100644 --- a/test/Wallet.js +++ b/test/Wallet.js @@ -1140,7 +1140,7 @@ describe('Wallet model', function() { var indexDiscovery = sinon.stub(w, 'indexDiscovery', function(a, b, c, d, cb) { cb(null, 8); }); - var spyStore = sinon.spy(w, 'store'); + var spyStore = sinon.spy(w, 'emitAndKeepAlive'); w.updateIndexes(function(err) { sinon.assert.callCount(spyStore, 1); done(); @@ -1750,18 +1750,18 @@ describe('Wallet model', function() { }; txp.prototype.toObj = function() {}; - var spy1 = sinon.spy(w, 'store'); + var spy1 = sinon.spy(w, 'emitAndKeepAlive'); var spy2 = sinon.spy(w, 'emit'); w.txProposals.txps['qwerty'] = new txp(); w.txProposals.txps['qwerty'].ok.should.equal(0); + spy2.callCount.should.equal(0); w._onReject('john', { ntxid: 'qwerty' }, 1); w.txProposals.txps['qwerty'].ok.should.equal(1); spy1.calledOnce.should.equal(true); - spy2.callCount.should.equal(2); - spy2.firstCall.args.should.deep.equal(['txProposalsUpdated']); - spy2.secondCall.args.should.deep.equal(['txProposalEvent', { + spy2.callCount.should.equal(1); + spy2.firstCall.args.should.deep.equal(['txProposalEvent', { type: 'rejected', cId: 'john', txId: 'qwerty', @@ -1791,18 +1791,15 @@ describe('Wallet model', function() { }; txp.prototype.toObj = function() {}; - var spy1 = sinon.spy(w, 'store'); - var spy2 = sinon.spy(w, 'emit'); + var spy2 = sinon.spy(w, 'emitAndKeepAlive'); w.txProposals.txps['qwerty'] = new txp(); w.txProposals.txps['qwerty'].ok.should.equal(0); w._onSeen('john', { ntxid: 'qwerty' }, 1); w.txProposals.txps['qwerty'].ok.should.equal(1); - spy1.calledOnce.should.equal(true); - spy2.callCount.should.equal(2); - spy2.firstCall.args.should.deep.equal(['txProposalsUpdated']); - spy2.secondCall.args.should.deep.equal(['txProposalEvent', { + spy2.callCount.should.equal(1); + spy2.firstCall.args.should.deep.equal(['txProposalEvent', { type: 'seen', cId: 'john', txId: 'qwerty', @@ -2163,7 +2160,7 @@ describe('Wallet model', function() { }); - describe('#read', function() { + describe.skip('#read', function() { var network, blockchain; beforeEach(function() {