diff --git a/js/controllers/addresses.js b/js/controllers/addresses.js index cef87776f..d53ff8ae1 100644 --- a/js/controllers/addresses.js +++ b/js/controllers/addresses.js @@ -9,8 +9,7 @@ angular.module('copayApp.controllers').controller('AddressesController', $scope.loading = true; w.generateAddress(null, function() { $timeout(function() { - controllerUtils.setSocketHandlers(); - controllerUtils.updateAddressList(); + controllerUtils.updateGlobalAddresses(); $scope.loading = false; }, 1); }); diff --git a/js/controllers/sidebar.js b/js/controllers/sidebar.js index ee356bb94..feebe40da 100644 --- a/js/controllers/sidebar.js +++ b/js/controllers/sidebar.js @@ -57,9 +57,6 @@ angular.module('copayApp.controllers').controller('SidebarController', function( return new Array(num); } - // Init socket handlers (with no wallet yet) - controllerUtils.setSocketHandlers(); - if ($rootScope.wallet) { $scope.$on('$idleWarn', function(a,countdown) { if (!(countdown%5)) diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index 9c7fce321..16242ddbf 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -50,7 +50,7 @@ var Insight = function (opts) { var self = this; this.socket.on('connect', function() { self.status = self.STATUS.CONNECTED; - self.suscribeToBlocks(); + self.subscribeToBlocks(); self.emit('connect', 0); }); @@ -82,7 +82,7 @@ Insight.prototype.STATUS = { } /** @private */ -Insight.prototype.suscribeToBlocks = function() { +Insight.prototype.subscribeToBlocks = function() { if (this.listeningBlocks || !this.socket.connected) return; var self = this; @@ -132,9 +132,12 @@ Insight.prototype.subscribe = function(addresses) { addresses.forEach(function(address) { preconditions.checkArgument(new bitcore.Address(address).isValid()); - self.subscribed.push(address); - self.socket.emit('subscribe', address); - self.socket.on(address, handlerFor(self, address)); + // skip already subscibed + if (self.subscribed.indexOf(address) == -1) { + self.subscribed.push(address); + self.socket.emit('subscribe', address); + self.socket.on(address, handlerFor(self, address)); + } }); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 1c3de8943..43fd21509 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -805,8 +805,6 @@ Wallet.prototype.sendTx = function(ntxid, cb) { var self = this; this.blockchain.broadcast(txHex, function(err, txid) { - if(err) throw err; - self.log('BITCOIND txid:', txid); if (txid) { self.txProposals.get(ntxid).setSent(txid); diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index 6b3b32ca7..f7054383d 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -99,7 +99,7 @@ angular.module('copayApp.services') root.startNetwork = function(w, $scope) { root.setupRootVariables(); root.installStartupHandlers(w, $scope); - root.setSocketHandlers(); + root.updateGlobalAddresses(); var handlePeerVideo = function(err, peerID, url) { if (err) { @@ -120,7 +120,7 @@ angular.module('copayApp.services') }); w.on('ready', function(myPeerID) { $rootScope.wallet = w; - + root.setConnectionListeners(); if ($rootScope.pendingPayment) { $location.path('send'); @@ -132,7 +132,7 @@ angular.module('copayApp.services') }); w.on('publicKeyRingUpdated', function(dontDigest) { - root.setSocketHandlers(); + root.updateGlobalAddresses(); if (!dontDigest) { $rootScope.$digest(); } @@ -304,44 +304,38 @@ angular.module('copayApp.services') wallet.blockchain.on('disconnect', function() { notification.error('Networking problem', 'Connection to Insight lost, trying to reconnect...'); }); + + wallet.blockchain.on('tx', function(tx) { + notification.funds('Funds received!', tx.address); + root.updateBalance(function() { + $rootScope.$digest(); + }); + }); + + if (!$rootScope.wallet.spendUnconfirmed) { + wallet.blockchain.on('block', function(block) { + root.updateBalance(function() { + $rootScope.$digest(); + }); + }); + } } - root.setSocketHandlers = function() { - root.updateAddressList(); - + root.updateGlobalAddresses = function() { if (!$rootScope.wallet) return; - var currentAddrs = Socket.getListeners(); + root.updateAddressList(); + var currentAddrs = $rootScope.wallet.blockchain.getListeners(); var allAddrs = $rootScope.addrInfos; var newAddrs = []; for (var i in allAddrs) { var a = allAddrs[i]; - if (!currentAddrs[a.addressStr]) + if (!currentAddrs[a.addressStr] && !a.isChange) newAddrs.push(a); } for (var i = 0; i < newAddrs.length; i++) { - Socket.emit('subscribe', newAddrs[i].addressStr); - } - newAddrs.forEach(function(a) { - Socket.on(a.addressStr, function(txid) { - - if (!a.isChange) - notification.funds('Funds received!', a.addressStr); - - root.updateBalance(function() { - $rootScope.$digest(); - }); - }); - }); - - if (!$rootScope.wallet.spendUnconfirmed && !Socket.isListeningBlocks()) { - Socket.emit('subscribe', 'inv'); - Socket.on('block', function(block) { - root.updateBalance(function() { - $rootScope.$digest(); - }); - }); + $rootScope.wallet.blockchain.subscribe(newAddrs[i].addressStr); } }; return root; diff --git a/test/mocks/FakeBlockchain.js b/test/mocks/FakeBlockchain.js index 1db31f97b..c6dd8ca4f 100644 --- a/test/mocks/FakeBlockchain.js +++ b/test/mocks/FakeBlockchain.js @@ -6,6 +6,10 @@ function FakeBlockchain(opts) { opts = opts || {}; } +FakeBlockchain.prototype.getTransaction = function(txid, cb) { + return cb(null, {txid: txid}); +}; + FakeBlockchain.prototype.getTransactions = function(addresses, cb) { return cb(null, []); }; diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 2386d3002..09dc4afe5 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -752,7 +752,7 @@ describe('Wallet model', function() { var utxo = createUTXO(w); w.blockchain.fixUnspent(utxo); w.createTx(toAddress, amountSatStr, null, function(ntxid) { - sinon.stub(w.blockchain, 'sendRawTransaction').yields(undefined); + sinon.stub(w.blockchain, 'broadcast').yields({statusCode: 303}); var spyCheckSentTx = sinon.spy(w, '_checkSentTx'); w.sendTx(ntxid, function () {}); chai.expect(spyCheckSentTx.calledOnce).to.be.true; diff --git a/test/test.blockchain.Insight.js b/test/test.blockchain.Insight.js index eacc99808..a84b138bd 100644 --- a/test/test.blockchain.Insight.js +++ b/test/test.blockchain.Insight.js @@ -98,6 +98,14 @@ describe('Insight model', function() { emitSpy.calledWith('subscribe', 'mg7UbtKgMvWAixTNMbC8soyUnwFk1qxEuM'); }); + it('should subscribe to an address once', function() { + var blockchain = new Insight(FAKE_OPTS); + + blockchain.subscribe('mg7UbtKgMvWAixTNMbC8soyUnwFk1qxEuM'); + blockchain.subscribe('mg7UbtKgMvWAixTNMbC8soyUnwFk1qxEuM'); + blockchain.subscribed.length.should.equal(1); + }); + it('should subscribe to a list of addresses', function() { var blockchain = new Insight(FAKE_OPTS); var emitSpy = sinon.spy(blockchain.socket, 'emit'); diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index b7aa7041b..284719d3d 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -62,26 +62,26 @@ describe("Unit: controllerUtils", function() { expect($rootScope.unitName).to.be.equal('bits'); }); })); - describe("Unit: controllerUtils #setSocketHandlers", function() { + describe("Unit: controllerUtils #updateGlobalAddresses", function() { it(' should call updateAddressList ', inject(function(controllerUtils, $rootScope) { var spy = sinon.spy(controllerUtils, 'updateAddressList'); - controllerUtils.setSocketHandlers(); + controllerUtils.updateGlobalAddresses(); sinon.assert.callCount(spy, 1); })); it('should update addresses', inject(function(controllerUtils, $rootScope) { $rootScope.wallet = new FakeWallet(); var Waddr = Object.keys($rootScope.wallet.balanceByAddr)[0]; - controllerUtils.setSocketHandlers(); + controllerUtils.updateGlobalAddresses(); expect($rootScope.addrInfos[0].address).to.be.equal(Waddr);; })); it('should set System Event Handlers', inject(function(controllerUtils, $rootScope, Socket) { var spy = sinon.spy(Socket, 'sysOn'); $rootScope.wallet = new FakeWallet(); - controllerUtils.setSocketHandlers(); + controllerUtils.updateGlobalAddresses(); sinon.assert.callCount(spy, 5); ['error', 'reconnect_error', 'reconnect_failed', 'connect', 'reconnect'].forEach(function(e) { sinon.assert.calledWith(spy, e); @@ -92,7 +92,7 @@ describe("Unit: controllerUtils", function() { var spy = sinon.spy(Socket, 'on'); $rootScope.wallet = new FakeWallet(); var Waddr = Object.keys($rootScope.wallet.balanceByAddr)[0]; - controllerUtils.setSocketHandlers(); + controllerUtils.updateGlobalAddresses(); sinon.assert.calledWith(spy, Waddr); })); });