diff --git a/lib/server.js b/lib/server.js index a611bfb..fe77b00 100644 --- a/lib/server.js +++ b/lib/server.js @@ -181,19 +181,39 @@ CopayServer.prototype.createAddress = function(opts, cb) { var address = wallet.createAddress(opts.isChange); - self.storage.storeWallet(wallet, function(err) { + self.storage.storeAddress(wallet.id, address, function(err) { if (err) return cb(err); - - self.storage.storeAddress(opts.walletId, address, function(err) { - if (err) return cb(err); - - return cb(null, address); + + self.storage.storeWallet(wallet, function(err) { + if (err) { + self.storage.removeAddress(wallet.id, address, function () { + return cb(err); + }); + } else { + return cb(null, address); + } }); }); }); }); }; +/** + * Get all addresses. + * @param {Object} opts + * @param {string} opts.walletId - The wallet id. + * @returns {Address[]} + */ +CopayServer.prototype.getAddresses = function (opts, cb) { + var self = this; + + self.storage.fetchAddresses(opts.walletId, function(err, addresses) { + if (err) return cb(err); + + return cb(null, addresses); + }); +}; + /** * Verifies that a given message was actually sent by an authorized copayer. * @param {Object} opts diff --git a/lib/storage.js b/lib/storage.js index c43a53f..d2b0fe0 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -82,6 +82,9 @@ Storage.prototype.storeAddress = function (walletId, address, cb) { this.db.put('wallet-' + walletId + '-address-' + address.address, address, cb); }; +Storage.prototype.removeAddress = function (walletId, address, cb) { + this.db.del('wallet-' + walletId + '-address-' + address.address, cb); +}; Storage.prototype._dump = function (cb) { diff --git a/test/integration.js b/test/integration.js index 4a1affb..d3754d4 100644 --- a/test/integration.js +++ b/test/integration.js @@ -638,6 +638,70 @@ describe('Copay server', function() { }); }); }); + + it('should not create address if unable to store wallet', function(done) { + helpers.createAndJoinWallet('123', 2, 2, function(err, wallet) { + + var storeWalletStub = sinon.stub(server.storage, 'storeWallet'); + storeWalletStub.yields('dummy error'); + + server.createAddress({ + walletId: '123', + isChange: true, + }, function(err, address) { + err.should.exist; + should.not.exist(address); + + server.getAddresses({ walletId: '123' }, function (err, addresses) { + addresses.length.should.equal(0); + + server.storage.storeWallet.restore(); + server.createAddress({ + walletId: '123', + isChange: true, + }, function(err, address) { + should.not.exist(err); + address.should.exist; + address.address.should.equal('3CauZ5JUFfmSAx2yANvCRoNXccZ3YSUjXH'); + address.path.should.equal('m/2147483647/1/0'); + done(); + }); + }); + }); + }); + }); + + it('should not create address if unable to store addresses', function(done) { + helpers.createAndJoinWallet('123', 2, 2, function(err, wallet) { + + var storeAddressStub = sinon.stub(server.storage, 'storeAddress'); + storeAddressStub.yields('dummy error'); + + server.createAddress({ + walletId: '123', + isChange: true, + }, function(err, address) { + err.should.exist; + should.not.exist(address); + + server.getAddresses({ walletId: '123' }, function (err, addresses) { + addresses.length.should.equal(0); + + server.storage.storeAddress.restore(); + server.createAddress({ + walletId: '123', + isChange: true, + }, function(err, address) { + should.not.exist(err); + address.should.exist; + address.address.should.equal('3CauZ5JUFfmSAx2yANvCRoNXccZ3YSUjXH'); + address.path.should.equal('m/2147483647/1/0'); + done(); + }); + }); + }); + }); + }); }); describe('#createTx', function() {