diff --git a/lib/blockchainexplorers/insight.js b/lib/blockchainexplorers/insight.js index cec4e70..ce98d13 100644 --- a/lib/blockchainexplorers/insight.js +++ b/lib/blockchainexplorers/insight.js @@ -113,21 +113,39 @@ Insight.prototype.getTransactions = function(addresses, from, to, cb) { }); }; -Insight.prototype.getAddressActivity = function(address, cb) { - var url = this.url + this.apiPrefix + '/addr/' + address; - var args = { - method: 'GET', - url: url, - json: true, +Insight.prototype.getAddressActivity = function(addresses, cb) { + function getOneAddressActivity(address, cb) { + var url = this.url + this.apiPrefix + '/addr/' + address; + var args = { + method: 'GET', + url: url, + json: true, + }; + + request(args, function(err, res, result) { + if (res && res.statusCode == 404) return cb(); + if (err || res.statusCode !== 200) + return cb(_parseErr(err, res)); + + var nbTxs = result.unconfirmedTxApperances + result.txApperances; + return cb(null, nbTxs > 0); + }); }; - request(args, function(err, res, result) { - if (res && res.statusCode == 404) return cb(); - if (err || res.statusCode !== 200) - return cb(_parseErr(err, res)); + addresses = [].concat(addresses); + var activityFound = false; + var i = 0; - var nbTxs = result.unconfirmedTxApperances + result.txApperances; - return cb(null, nbTxs > 0); + async.until(function() { + return activityFound; + }, function(next) { + getOneAddressActivity(addresses[i++], function(err, res) { + if (err) return next(err); + activityFound = !!res; + return next(); + }); + }, function(err) { + return cb(err, activityFound); }); }; diff --git a/lib/server.js b/lib/server.js index 622afdd..8c80fd2 100644 --- a/lib/server.js +++ b/lib/server.js @@ -692,29 +692,52 @@ WalletService.prototype.getPreferences = function(opts, cb) { }); }; +WalletService.prototype._canCreateAddress = function(ignoreMaxGap, cb) { + var self = this; + + if (ignoreMaxGap) return cb(null, true); + self.storage.fetchAddresses(self.walletId, function(err, addresses) { + if (err) return cb(err); + var latestAddresses = _.takeRight(_.reject(addresses, { + isChange: true + }), WalletService.MAX_MAIN_ADDRESS_GAP); + if (latestAddresses.length < WalletService.MAX_MAIN_ADDRESS_GAP) return cb(null, true); + + var bc = self._getBlockchainExplorer(latestAddresses[0].network); + bc.getAddressActivity(latestAddresses, cb); + }); +}; /** * Creates a new address. * @param {Object} opts + * @param {Boolean} [opts.ignoreMaxGap=false] - Ignore constraint of maximum number of consecutive addresses without activity * @returns {Address} address */ WalletService.prototype.createAddress = function(opts, cb) { var self = this; + opts = opts || {}; + self._runLocked(cb, function(cb) { self.getWallet({}, function(err, wallet) { if (err) return cb(err); if (!wallet.isComplete()) return cb(Errors.WALLET_NOT_COMPLETE); - var address = wallet.createAddress(false); - - self.storage.storeAddressAndWallet(wallet, address, function(err) { + self._canCreateAddress(opts.ignoreMaxGap, function(err, canCreate) { if (err) return cb(err); + if (!canCreate) return cb(Errors.MAIN_ADDRESS_GAP_REACHED); - self._notify('NewAddress', { - address: address.address, - }, function() { - return cb(null, address); + var address = wallet.createAddress(false); + + self.storage.storeAddressAndWallet(wallet, address, function(err) { + if (err) return cb(err); + + self._notify('NewAddress', { + address: address.address, + }, function() { + return cb(null, address); + }); }); }); }); diff --git a/test/integration/server.js b/test/integration/server.js index 93b2331..11b9e9b 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -1668,7 +1668,7 @@ describe('Wallet service', function() { }); }); - it.only('should fail to create more consecutive addresses with no activity than allowed', function(done) { + it('should fail to create more consecutive addresses with no activity than allowed', function(done) { var MAX_MAIN_ADDRESS_GAP_old = WalletService.MAX_MAIN_ADDRESS_GAP; var n = WalletService.MAX_MAIN_ADDRESS_GAP = 2; helpers.stubAddressActivity([]);