From d47bb65fdd250990527ff8ddaec7b2f5492f77f6 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 18 Aug 2015 17:39:29 -0300 Subject: [PATCH 1/8] test --- test/integration/server.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/integration/server.js b/test/integration/server.js index 9fb0d2f..d5e6ed1 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -1117,6 +1117,25 @@ describe('Wallet service', function() { }); }); + describe.only('#getStatus', function() { + var server, wallet; + beforeEach(function(done) { + helpers.createAndJoinWallet(1, 1, function(s, w) { + server = s; + wallet = w; + done(); + }); + }); + + it('should get status', function(done) { + server.getStatus({}, function(err, status) { + should.not.exist(err); + should.exist(status); + done(); + }); + }); + }); + describe('#verifyMessageSignature', function() { var server, wallet; beforeEach(function(done) { From f8d9ca542d99c68086ad7543d4d5fce432228482 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 18 Aug 2015 17:56:46 -0300 Subject: [PATCH 2/8] implement get status & improve tests --- lib/server.js | 45 ++++++++++++++++++++++++++++++++++++++ test/integration/server.js | 29 +++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index d881ad9..a3f0631 100644 --- a/lib/server.js +++ b/lib/server.js @@ -272,6 +272,51 @@ WalletService.prototype.getWallet = function(opts, cb) { }); }; +/** + * Retrieves wallet status. + * @param {Object} opts + * @returns {Object} status + */ +WalletService.prototype.getStatus = function(opts, cb) { + var self = this; + + var status = {}; + async.parallel([ + + function(next) { + self.getWallet({}, function(err, wallet) { + if (err) return next(err); + status.wallet = wallet; + next(); + }); + }, + function(next) { + self.getBalance({}, function(err, balance) { + if (err) return next(err); + status.balance = balance; + next(); + }); + }, + function(next) { + self.getPendingTxs({}, function(err, pendingTxps) { + if (err) return next(err); + status.pendingTxps = pendingTxps; + next(); + }); + }, + function(next) { + self.getPreferences({}, function(err, preferences) { + if (err) return next(err); + status.preferences = preferences; + next(); + }); + }, + ], function(err) { + if (err) return cb(err); + return cb(null, status); + }); +}; + /* * Verifies a signature * @param text diff --git a/test/integration/server.js b/test/integration/server.js index d5e6ed1..3fba9fc 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -1131,9 +1131,36 @@ describe('Wallet service', function() { server.getStatus({}, function(err, status) { should.not.exist(err); should.exist(status); + should.exist(status.wallet); + status.wallet.name.should.equal(wallet.name); + should.exist(status.wallet.copayers); + status.wallet.copayers.length.should.equal(1); + should.exist(status.balance); + status.balance.totalAmount.should.equal(0); + should.exist(status.preferences); + should.exist(status.pendingTxps); + status.pendingTxps.should.be.empty; done(); }); }); + it('should get status after tx creation', function(done) { + helpers.stubUtxos(server, wallet, [100, 200], function() { + var txOpts = helpers.createSimpleProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey_1H_0); + server.createTx(txOpts, function(err, tx) { + should.not.exist(err); + should.exist(tx); + server.getStatus({}, function(err, status) { + should.not.exist(err); + status.pendingTxps.length.should.equal(1); + var balance = status.balance; + balance.totalAmount.should.equal(helpers.toSatoshi(300)); + balance.lockedAmount.should.equal(tx.inputs[0].satoshis); + balance.availableAmount.should.equal(balance.totalAmount - balance.lockedAmount); + done(); + }); + }); + }); + }); }); describe('#verifyMessageSignature', function() { @@ -1853,8 +1880,8 @@ describe('Wallet service', function() { isChange: true }); change.length.should.equal(1); + done(); }); - done(); }); }); }); From 1007ad1b05919f36852a7a9136a05c134ee0375d Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 18 Aug 2015 18:22:43 -0300 Subject: [PATCH 3/8] includeExtendedInfo switch --- lib/server.js | 13 +++++++++++++ test/integration/server.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/server.js b/lib/server.js index a3f0631..b7f99d8 100644 --- a/lib/server.js +++ b/lib/server.js @@ -275,17 +275,30 @@ WalletService.prototype.getWallet = function(opts, cb) { /** * Retrieves wallet status. * @param {Object} opts + * @param {Object} opts.includeExtendedInfo - Include PKR info & address managers for wallet & copayers * @returns {Object} status */ WalletService.prototype.getStatus = function(opts, cb) { var self = this; + opts = opts || {}; + var status = {}; async.parallel([ function(next) { self.getWallet({}, function(err, wallet) { if (err) return next(err); + + var walletExtendedKeys = ['publicKeyRing', 'pubKey', 'addressManager']; + var copayerExtendedKeys = ['xPubKey', 'requestPubKey', 'signature', 'addressManager']; + + if (!opts.includeExtendedInfo) { + wallet = _.omit(wallet, walletExtendedKeys); + wallet.copayers = _.map(wallet.copayers, function(copayer) { + return _.omit(copayer, copayerExtendedKeys); + }); + } status.wallet = wallet; next(); }); diff --git a/test/integration/server.js b/test/integration/server.js index 3fba9fc..2fc2c91 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -1140,6 +1140,34 @@ describe('Wallet service', function() { should.exist(status.preferences); should.exist(status.pendingTxps); status.pendingTxps.should.be.empty; + + should.not.exist(status.wallet.publicKeyRing); + should.not.exist(status.wallet.pubKey); + should.not.exist(status.wallet.addressManager); + should.not.exist(status.wallet.copayers[0].xPubKey); + should.not.exist(status.wallet.copayers[0].requestPubKey); + should.not.exist(status.wallet.copayers[0].signature); + should.not.exist(status.wallet.copayers[0].requestPubKey); + should.not.exist(status.wallet.copayers[0].addressManager); + + done(); + }); + }); + it('should get status including extended info', function(done) { + server.getStatus({ + includeExtendedInfo: true + }, function(err, status) { + should.not.exist(err); + should.exist(status); + should.exist(status.wallet.publicKeyRing); + should.exist(status.wallet.pubKey); + should.exist(status.wallet.addressManager); + should.exist(status.wallet.copayers[0].xPubKey); + should.exist(status.wallet.copayers[0].requestPubKey); + should.exist(status.wallet.copayers[0].signature); + should.exist(status.wallet.copayers[0].requestPubKey); + should.exist(status.wallet.copayers[0].addressManager); + done(); }); }); From 0ee0161e1055b7eedeb06e0acc6842e66b14c92d Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 18 Aug 2015 18:23:35 -0300 Subject: [PATCH 4/8] v2/wallets/ endpoint --- lib/expressapp.js | 48 ++++++++++++++--------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/lib/expressapp.js b/lib/expressapp.js index acdfe8e..5c54efa 100644 --- a/lib/expressapp.js +++ b/lib/expressapp.js @@ -159,43 +159,23 @@ ExpressApp.prototype.start = function(opts, cb) { }); }); - + // DEPRECATED router.get('/v1/wallets/', function(req, res) { getServerWithAuth(req, res, function(server) { - var result = {}; - async.parallel([ - - function(next) { - server.getWallet({}, function(err, wallet) { - if (err) return next(err); - result.wallet = wallet; - next(); - }); - }, - function(next) { - server.getBalance({}, function(err, balance) { - if (err) return next(err); - result.balance = balance; - next(); - }); - }, - function(next) { - server.getPendingTxs({}, function(err, pendingTxps) { - if (err) return next(err); - result.pendingTxps = pendingTxps; - next(); - }); - }, - function(next) { - server.getPreferences({}, function(err, preferences) { - if (err) return next(err); - result.preferences = preferences; - next(); - }); - }, - ], function(err) { + server.getStatus({ + includeExtendedInfo: true + }, function(err, status) { if (err) return returnError(err, res, req); - res.json(result); + res.json(status); + }); + }); + }); + + router.get('/v2/wallets/', function(req, res) { + getServerWithAuth(req, res, function(server) { + server.getStatus({}, function(err, status) { + if (err) return returnError(err, res, req); + res.json(status); }); }); }); From cffde9de82eb2a54ca0b2484dcb9c4d4effd3266 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Wed, 19 Aug 2015 15:24:04 -0300 Subject: [PATCH 5/8] rm leveldb storage --- lib/storage_leveldb.js | 383 ----------------------------------------- 1 file changed, 383 deletions(-) delete mode 100644 lib/storage_leveldb.js diff --git a/lib/storage_leveldb.js b/lib/storage_leveldb.js deleted file mode 100644 index 8553287..0000000 --- a/lib/storage_leveldb.js +++ /dev/null @@ -1,383 +0,0 @@ -'use strict'; - -var _ = require('lodash'); -var levelup = require('levelup'); -var net = require('net'); -var async = require('async'); -var $ = require('preconditions').singleton(); -var log = require('npmlog'); -var util = require('util'); -log.debug = log.verbose; -log.disableColor(); - -var Wallet = require('./model/wallet'); -var Copayer = require('./model/copayer'); -var Address = require('./model/address'); -var TxProposal = require('./model/txproposal'); -var Notification = require('./model/notification'); - -var Storage = function(opts) { - opts = opts || {}; - this.db = opts.db; - - if (!this.db) { - this.db = levelup(opts.dbPath || './db/bws.db', { - valueEncoding: 'json' - }); - } -}; - -var zeroPad = function(x, length) { - return _.padLeft(parseInt(x), length, '0'); -}; - -var walletPrefix = function(id) { - return 'w!' + id; -}; - -var opKey = function(key) { - return key ? '!' + key : ''; -}; - -var MAX_TS = _.repeat('9', 14); - - -var KEY = { - WALLET: function(walletId) { - return walletPrefix(walletId) + '!main'; - }, - COPAYER: function(id) { - return 'copayer!' + id; - }, - TXP: function(walletId, txProposalId) { - return walletPrefix(walletId) + '!txp' + opKey(txProposalId); - }, - NOTIFICATION: function(walletId, notificationId) { - return walletPrefix(walletId) + '!not' + opKey(notificationId); - }, - PENDING_TXP: function(walletId, txProposalId) { - return walletPrefix(walletId) + '!ptxp' + opKey(txProposalId); - }, - ADDRESS: function(walletId, address) { - return walletPrefix(walletId) + '!addr' + opKey(address); - }, -}; - -Storage.prototype.fetchWallet = function(id, cb) { - this.db.get(KEY.WALLET(id), function(err, data) { - if (err) { - if (err.notFound) return cb(); - return cb(err); - } - return cb(null, Wallet.fromObj(data)); - }); -}; - -Storage.prototype.storeWallet = function(wallet, cb) { - this.db.put(KEY.WALLET(wallet.id), wallet, cb); -}; - -Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) { - var ops = []; - ops.push({ - type: 'put', - key: KEY.WALLET(wallet.id), - value: wallet - }); - _.each(wallet.copayers, function(copayer) { - var value = { - walletId: wallet.id, - requestPubKey: copayer.requestPubKey, - }; - ops.push({ - type: 'put', - key: KEY.COPAYER(copayer.id), - value: value - }); - }); - this.db.batch(ops, cb); -}; - -Storage.prototype.fetchCopayerLookup = function(copayerId, cb) { - this.db.get(KEY.COPAYER(copayerId), function(err, data) { - if (err) { - if (err.notFound) return cb(); - return cb(err); - } - return cb(null, data); - }); -}; - -Storage.prototype._completeTxData = function(walletId, txs, cb) { - var txList = [].concat(txs); - this.fetchWallet(walletId, function(err, wallet) { - if (err) return cb(err); - _.each(txList, function(tx) { - tx.creatorName = wallet.getCopayer(tx.creatorId).name; - _.each(tx.actions, function(action) { - action.copayerName = wallet.getCopayer(action.copayerId).name; - }); - }); - return cb(null, txs); - }); -}; - -Storage.prototype.fetchTx = function(walletId, txProposalId, cb) { - var self = this; - this.db.get(KEY.TXP(walletId, txProposalId), function(err, data) { - if (err) { - if (err.notFound) return cb(); - return cb(err); - } - return self._completeTxData(walletId, TxProposal.fromObj(data), cb); - }); -}; - - -Storage.prototype.fetchPendingTxs = function(walletId, cb) { - var self = this; - - var txs = []; - var key = KEY.PENDING_TXP(walletId); - this.db.createReadStream({ - gte: key, - lt: key + '~' - }) - .on('data', function(data) { - txs.push(TxProposal.fromObj(data.value)); - }) - .on('error', function(err) { - if (err.notFound) return cb(); - return cb(err); - }) - .on('end', function() { - return self._completeTxData(walletId, txs, cb); - }); -}; - -/** - * fetchTxs. Times are in UNIX EPOCH (seconds) - * - * @param walletId - * @param opts.minTs - * @param opts.maxTs - * @param opts.limit - */ -Storage.prototype.fetchTxs = function(walletId, opts, cb) { - var self = this; - - var txs = []; - opts = opts || {}; - opts.limit = _.isNumber(opts.limit) ? parseInt(opts.limit) : -1; - opts.minTs = _.isNumber(opts.minTs) ? zeroPad(opts.minTs, 11) : 0; - opts.maxTs = _.isNumber(opts.maxTs) ? zeroPad(opts.maxTs, 11) : MAX_TS; - - var key = KEY.TXP(walletId, opts.minTs); - var endkey = KEY.TXP(walletId, opts.maxTs); - - this.db.createReadStream({ - gt: key, - lt: endkey + '~', - reverse: true, - limit: opts.limit, - }) - .on('data', function(data) { - txs.push(TxProposal.fromObj(data.value)); - }) - .on('error', function(err) { - if (err.notFound) return cb(); - return cb(err); - }) - .on('end', function() { - return self._completeTxData(walletId, txs, cb); - }); -}; - - -/** - * fetchNotifications - * - * @param walletId - * @param opts.minTs - * @param opts.maxTs - * @param opts.limit - */ -Storage.prototype.fetchNotifications = function(walletId, opts, cb) { - var txs = []; - opts = opts || {}; - opts.limit = _.isNumber(opts.limit) ? parseInt(opts.limit) : -1; - opts.minTs = _.isNumber(opts.minTs) ? zeroPad(opts.minTs, 11) : 0; - opts.maxTs = _.isNumber(opts.maxTs) ? zeroPad(opts.maxTs, 11) : MAX_TS; - - var key = KEY.NOTIFICATION(walletId, opts.minTs); - var endkey = KEY.NOTIFICATION(walletId, opts.maxTs); - - this.db.createReadStream({ - gt: key, - lt: endkey + '~', - reverse: opts.reverse, - limit: opts.limit, - }) - .on('data', function(data) { - txs.push(Notification.fromObj(data.value)); - }) - .on('error', function(err) { - if (err.notFound) return cb(); - return cb(err); - }) - .on('end', function() { - return cb(null, txs); - }); -}; - - -Storage.prototype.storeNotification = function(walletId, notification, cb) { - this.db.put(KEY.NOTIFICATION(walletId, notification.id), notification, cb); -}; - - -// TODO should we store only txp.id on keys for indexing -// or the whole txp? For now, the entire record makes sense -// (faster + easier to access) -Storage.prototype.storeTx = function(walletId, txp, cb) { - var ops = [{ - type: 'put', - key: KEY.TXP(walletId, txp.id), - value: txp, - }]; - - if (txp.isPending()) { - ops.push({ - type: 'put', - key: KEY.PENDING_TXP(walletId, txp.id), - value: txp, - }); - } else { - ops.push({ - type: 'del', - key: KEY.PENDING_TXP(walletId, txp.id), - }); - } - this.db.batch(ops, cb); -}; - -Storage.prototype.removeTx = function(walletId, txProposalId, cb) { - var ops = [{ - type: 'del', - key: KEY.TXP(walletId, txProposalId), - }, { - type: 'del', - key: KEY.PENDING_TXP(walletId, txProposalId), - }]; - - this.db.batch(ops, cb); -}; - -Storage.prototype._delByKey = function(key, cb) { - var self = this; - var keys = []; - this.db.createKeyStream({ - gte: key, - lt: key + '~', - }) - .on('data', function(key) { - keys.push(key); - }) - .on('error', function(err) { - if (err.notFound) return cb(); - return cb(err); - }) - .on('end', function(err) { - self.db.batch(_.map(keys, function(k) { - return { - key: k, - type: 'del' - }; - }), function(err) { - return cb(err); - }); - }); -}; - -Storage.prototype._removeCopayers = function(walletId, cb) { - var self = this; - - this.fetchWallet(walletId, function(err, w) { - if (err || !w) return cb(err); - - self.db.batch(_.map(w.copayers, function(c) { - return { - type: 'del', - key: KEY.COPAYER(c.id), - }; - }), cb); - }); -}; - -Storage.prototype.removeWallet = function(walletId, cb) { - var self = this; - - async.series([ - - function(next) { - // This should be the first step. Will check the wallet exists - self._removeCopayers(walletId, next); - }, - function(next) { - self._delByKey(walletPrefix(walletId), cb); - }, - ], cb); -}; - - -Storage.prototype.fetchAddresses = function(walletId, cb) { - var addresses = []; - var key = KEY.ADDRESS(walletId); - this.db.createReadStream({ - gte: key, - lt: key + '~' - }) - .on('data', function(data) { - addresses.push(Address.fromObj(data.value)); - }) - .on('error', function(err) { - if (err.notFound) return cb(); - return cb(err); - }) - .on('end', function() { - return cb(null, addresses); - }); -}; - -Storage.prototype.storeAddressAndWallet = function(wallet, addresses, cb) { - var ops = _.map([].concat(addresses), function(address) { - return { - type: 'put', - key: KEY.ADDRESS(wallet.id, address.address), - value: address, - }; - }); - ops.unshift({ - type: 'put', - key: KEY.WALLET(wallet.id), - value: wallet, - }); - - this.db.batch(ops, cb); -}; - -Storage.prototype._dump = function(cb, fn) { - fn = fn || console.log; - - this.db.readStream() - .on('data', function(data) { - fn(util.inspect(data, { - depth: 10 - })); - }) - .on('end', function() { - if (cb) return cb(); - }); -}; - -module.exports = Storage; From 6cba8abc5ce99e48cb06f2c6f18b706013dba963 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 25 Aug 2015 16:12:47 -0300 Subject: [PATCH 6/8] add custom data to copayers --- lib/model/copayer.js | 4 ++++ lib/server.js | 11 ++++++++--- test/integration/server.js | 28 +++++++++++++++++++--------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/model/copayer.js b/lib/model/copayer.js index 5fa31da..db9eef7 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -48,6 +48,8 @@ Copayer.create = function(opts) { copayerIndex: opts.copayerIndex }); + x.customData = opts.customData; + return x; }; @@ -73,6 +75,8 @@ Copayer.fromObj = function(obj) { } x.addressManager = AddressManager.fromObj(obj.addressManager); + x.customData = obj.customData; + return x; }; diff --git a/lib/server.js b/lib/server.js index b7f99d8..aa1ff39 100644 --- a/lib/server.js +++ b/lib/server.js @@ -291,8 +291,12 @@ WalletService.prototype.getStatus = function(opts, cb) { if (err) return next(err); var walletExtendedKeys = ['publicKeyRing', 'pubKey', 'addressManager']; - var copayerExtendedKeys = ['xPubKey', 'requestPubKey', 'signature', 'addressManager']; + var copayerExtendedKeys = ['xPubKey', 'requestPubKey', 'signature', 'addressManager', 'customData']; + wallet.copayers = _.map(wallet.copayers, function(copayer) { + if (copayer.id == self.copayerId) return copayer; + return _.omit(copayer, 'customData'); + }); if (!opts.includeExtendedInfo) { wallet = _.omit(wallet, walletExtendedKeys); wallet.copayers = _.map(wallet.copayers, function(copayer) { @@ -406,8 +410,8 @@ WalletService.prototype._addCopayerToWallet = function(wallet, opts, cb) { xPubKey: opts.xPubKey, requestPubKey: opts.requestPubKey, signature: opts.copayerSignature, + customData: opts.customData, }); - self.storage.fetchCopayerLookup(copayer.id, function(err, res) { if (err) return cb(err); if (res) return cb(Errors.COPAYER_REGISTERED); @@ -508,7 +512,8 @@ WalletService.prototype.addAccess = function(opts, cb) { * @param {string} opts.name - The copayer name. * @param {string} opts.xPubKey - Extended Public Key for this copayer. * @param {string} opts.requestPubKey - Public Key used to check requests from this copayer. - * @param {string} opts.copayerSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify the that the copayer joining knows the wallet secret. + * @param {string} opts.copayerSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify that the copayer joining knows the wallet secret. + * @param {string} opts.customData - (optional) Custom data for this copayer. */ WalletService.prototype.joinWallet = function(opts, cb) { var self = this; diff --git a/test/integration/server.js b/test/integration/server.js index 2fc2c91..80aab2f 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -104,6 +104,7 @@ helpers.createAndJoinWallet = function(m, n, opts, cb) { name: 'copayer ' + (i + 1), xPubKey: TestData.copayers[i + offset].xPubKey_45H, requestPubKey: TestData.copayers[i + offset].pubKey_1H_0, + customData: 'custom data ' + (i + 1), }); server.joinWallet(copayerOpts, function(err, result) { @@ -912,6 +913,7 @@ describe('Wallet service', function() { name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, requestPubKey: TestData.copayers[0].pubKey_1H_0, + customData: 'dummy custom data', }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); @@ -923,6 +925,7 @@ describe('Wallet service', function() { var copayer = wallet.copayers[0]; copayer.name.should.equal('me'); copayer.id.should.equal(copayerId); + copayer.customData.should.equal('dummy custom data'); server.getNotifications({}, function(err, notifications) { should.not.exist(err); var notif = _.find(notifications, { @@ -1117,7 +1120,7 @@ describe('Wallet service', function() { }); }); - describe.only('#getStatus', function() { + describe('#getStatus', function() { var server, wallet; beforeEach(function(done) { helpers.createAndJoinWallet(1, 1, function(s, w) { @@ -1144,12 +1147,14 @@ describe('Wallet service', function() { should.not.exist(status.wallet.publicKeyRing); should.not.exist(status.wallet.pubKey); should.not.exist(status.wallet.addressManager); - should.not.exist(status.wallet.copayers[0].xPubKey); - should.not.exist(status.wallet.copayers[0].requestPubKey); - should.not.exist(status.wallet.copayers[0].signature); - should.not.exist(status.wallet.copayers[0].requestPubKey); - should.not.exist(status.wallet.copayers[0].addressManager); - + _.each(status.wallet.copayers, function(copayer) { + should.not.exist(copayer.xPubKey); + should.not.exist(copayer.requestPubKey); + should.not.exist(copayer.signature); + should.not.exist(copayer.requestPubKey); + should.not.exist(copayer.addressManager); + should.not.exist(copayer.customData); + }); done(); }); }); @@ -1167,7 +1172,11 @@ describe('Wallet service', function() { should.exist(status.wallet.copayers[0].signature); should.exist(status.wallet.copayers[0].requestPubKey); should.exist(status.wallet.copayers[0].addressManager); - + should.exist(status.wallet.copayers[0].customData); + // Do not return other copayer's custom data + _.each(_.rest(status.wallet.copayers), function(copayer) { + should.not.exist(copayer.customData); + }); done(); }); }); @@ -1593,7 +1602,8 @@ describe('Wallet service', function() { it('should be able to re-gain access from xPrivKey', function(done) { ws.addAccess(opts, function(err, res) { should.not.exist(err); - server.getBalance(res.wallet.walletId, function(err, bal) { should.not.exist(err); + server.getBalance(res.wallet.walletId, function(err, bal) { + should.not.exist(err); bal.totalAmount.should.equal(1e8); getAuthServer(opts.copayerId, reqPrivKey, function(err, server2) { server2.getBalance(res.wallet.walletId, function(err, bal2) { From 286cf936f6c2ec1b7f4470d45deca1ef979d66fd Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 25 Aug 2015 16:15:07 -0300 Subject: [PATCH 7/8] v0.1.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f012580..0d68ff7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "bitcore-wallet-service", "description": "A service for Mutisig HD Bitcoin Wallets", "author": "BitPay Inc", - "version": "0.1.7", + "version": "0.1.8", "keywords": [ "bitcoin", "copay", From 1dfc599ac43ae535a6ec65db26363faa3290de1c Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 25 Aug 2015 16:29:40 -0300 Subject: [PATCH 8/8] fix arg in express --- lib/expressapp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/expressapp.js b/lib/expressapp.js index 5c54efa..1af6364 100644 --- a/lib/expressapp.js +++ b/lib/expressapp.js @@ -173,7 +173,7 @@ ExpressApp.prototype.start = function(opts, cb) { router.get('/v2/wallets/', function(req, res) { getServerWithAuth(req, res, function(server) { - server.getStatus({}, function(err, status) { + server.getStatus(req.body, function(err, status) { if (err) return returnError(err, res, req); res.json(status); });