@bitpay-labs/bitcore-wallet-service 11.11.1 → 11.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/Dockerfile +1 -1
  2. package/package.json +5 -5
  3. package/src/lib/chain/btc/index.ts +3 -2
  4. package/src/lib/chain/eth/index.ts +134 -117
  5. package/src/lib/chain/sol/index.ts +1 -1
  6. package/src/lib/chain/xrp/index.ts +1 -1
  7. package/src/lib/common/constants.ts +1 -1
  8. package/src/lib/common/utils.ts +18 -1
  9. package/src/lib/model/tsskeygen.ts +16 -0
  10. package/src/lib/routes/maintenance.ts +11 -2
  11. package/src/lib/routes/middleware/authTssRequest.ts +28 -16
  12. package/src/lib/routes/middleware/verifyTssMessage.ts +4 -1
  13. package/src/lib/routes/services.ts +7 -1
  14. package/src/lib/routes/tss.ts +33 -30
  15. package/src/lib/routes/wallets.ts +3 -1
  16. package/src/lib/server.ts +198 -105
  17. package/src/lib/storage.ts +129 -20
  18. package/src/lib/tss.ts +111 -7
  19. package/test/chain/eth.test.ts +70 -0
  20. package/test/chain/sol.test.ts +1 -1
  21. package/test/chain/xrp.test.ts +1 -1
  22. package/test/expressapp.test.ts +243 -0
  23. package/test/integration/addressReads.test.ts +503 -0
  24. package/test/integration/bcmonitor.test.ts +44 -0
  25. package/test/integration/server.test.ts +251 -49
  26. package/test/integration/tss.test.ts +428 -0
  27. package/test/integration/walletReads.test.ts +488 -0
  28. package/ts_build/package.json +4 -4
  29. package/ts_build/src/lib/chain/btc/index.d.ts.map +1 -1
  30. package/ts_build/src/lib/chain/btc/index.js +3 -2
  31. package/ts_build/src/lib/chain/btc/index.js.map +1 -1
  32. package/ts_build/src/lib/chain/eth/index.d.ts +8 -1
  33. package/ts_build/src/lib/chain/eth/index.d.ts.map +1 -1
  34. package/ts_build/src/lib/chain/eth/index.js +114 -102
  35. package/ts_build/src/lib/chain/eth/index.js.map +1 -1
  36. package/ts_build/src/lib/chain/sol/index.js +1 -1
  37. package/ts_build/src/lib/chain/sol/index.js.map +1 -1
  38. package/ts_build/src/lib/chain/xrp/index.js +1 -1
  39. package/ts_build/src/lib/chain/xrp/index.js.map +1 -1
  40. package/ts_build/src/lib/common/constants.d.ts +1 -1
  41. package/ts_build/src/lib/common/constants.js +1 -1
  42. package/ts_build/src/lib/common/index.d.ts +2 -1
  43. package/ts_build/src/lib/common/index.d.ts.map +1 -1
  44. package/ts_build/src/lib/common/utils.d.ts +1 -0
  45. package/ts_build/src/lib/common/utils.d.ts.map +1 -1
  46. package/ts_build/src/lib/common/utils.js +16 -1
  47. package/ts_build/src/lib/common/utils.js.map +1 -1
  48. package/ts_build/src/lib/model/tsskeygen.d.ts +10 -0
  49. package/ts_build/src/lib/model/tsskeygen.d.ts.map +1 -1
  50. package/ts_build/src/lib/model/tsskeygen.js +3 -0
  51. package/ts_build/src/lib/model/tsskeygen.js.map +1 -1
  52. package/ts_build/src/lib/routes/maintenance.d.ts.map +1 -1
  53. package/ts_build/src/lib/routes/maintenance.js +12 -4
  54. package/ts_build/src/lib/routes/maintenance.js.map +1 -1
  55. package/ts_build/src/lib/routes/middleware/authTssRequest.d.ts +6 -2
  56. package/ts_build/src/lib/routes/middleware/authTssRequest.d.ts.map +1 -1
  57. package/ts_build/src/lib/routes/middleware/authTssRequest.js +21 -14
  58. package/ts_build/src/lib/routes/middleware/authTssRequest.js.map +1 -1
  59. package/ts_build/src/lib/routes/middleware/verifyTssMessage.d.ts.map +1 -1
  60. package/ts_build/src/lib/routes/middleware/verifyTssMessage.js +2 -1
  61. package/ts_build/src/lib/routes/middleware/verifyTssMessage.js.map +1 -1
  62. package/ts_build/src/lib/routes/services.d.ts.map +1 -1
  63. package/ts_build/src/lib/routes/services.js +6 -1
  64. package/ts_build/src/lib/routes/services.js.map +1 -1
  65. package/ts_build/src/lib/routes/tss.d.ts.map +1 -1
  66. package/ts_build/src/lib/routes/tss.js +32 -30
  67. package/ts_build/src/lib/routes/tss.js.map +1 -1
  68. package/ts_build/src/lib/routes/wallets.d.ts.map +1 -1
  69. package/ts_build/src/lib/routes/wallets.js +2 -1
  70. package/ts_build/src/lib/routes/wallets.js.map +1 -1
  71. package/ts_build/src/lib/server.d.ts +24 -3
  72. package/ts_build/src/lib/server.d.ts.map +1 -1
  73. package/ts_build/src/lib/server.js +148 -97
  74. package/ts_build/src/lib/server.js.map +1 -1
  75. package/ts_build/src/lib/storage.d.ts +26 -10
  76. package/ts_build/src/lib/storage.d.ts.map +1 -1
  77. package/ts_build/src/lib/storage.js +99 -20
  78. package/ts_build/src/lib/storage.js.map +1 -1
  79. package/ts_build/src/lib/tss.d.ts +12 -0
  80. package/ts_build/src/lib/tss.d.ts.map +1 -1
  81. package/ts_build/src/lib/tss.js +64 -5
  82. package/ts_build/src/lib/tss.js.map +1 -1
  83. package/ts_build/test/chain/eth.test.js +59 -0
  84. package/ts_build/test/chain/eth.test.js.map +1 -1
  85. package/ts_build/test/chain/sol.test.js +1 -1
  86. package/ts_build/test/chain/sol.test.js.map +1 -1
  87. package/ts_build/test/chain/xrp.test.js +1 -1
  88. package/ts_build/test/chain/xrp.test.js.map +1 -1
  89. package/ts_build/test/expressapp.test.js +222 -0
  90. package/ts_build/test/expressapp.test.js.map +1 -1
  91. package/ts_build/test/integration/addressReads.test.d.ts +2 -0
  92. package/ts_build/test/integration/addressReads.test.d.ts.map +1 -0
  93. package/ts_build/test/integration/addressReads.test.js +465 -0
  94. package/ts_build/test/integration/addressReads.test.js.map +1 -0
  95. package/ts_build/test/integration/bcmonitor.test.js +40 -0
  96. package/ts_build/test/integration/bcmonitor.test.js.map +1 -1
  97. package/ts_build/test/integration/server.test.js +228 -48
  98. package/ts_build/test/integration/server.test.js.map +1 -1
  99. package/ts_build/test/integration/tss.test.d.ts.map +1 -1
  100. package/ts_build/test/integration/tss.test.js +344 -0
  101. package/ts_build/test/integration/tss.test.js.map +1 -1
  102. package/ts_build/test/integration/walletReads.test.d.ts +2 -0
  103. package/ts_build/test/integration/walletReads.test.d.ts.map +1 -0
  104. package/ts_build/test/integration/walletReads.test.js +436 -0
  105. package/ts_build/test/integration/walletReads.test.js.map +1 -0
@@ -0,0 +1,436 @@
1
+ 'use strict';
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const chai = __importStar(require("chai"));
40
+ require("chai/register-should");
41
+ const util_1 = __importDefault(require("util"));
42
+ const sinon_1 = __importDefault(require("sinon"));
43
+ const storage_1 = require("../../src/lib/storage");
44
+ const TestData = __importStar(require("../testdata"));
45
+ const helpers_1 = __importDefault(require("./helpers"));
46
+ const should = chai.should();
47
+ const TOKEN_ADDRESS = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
48
+ const TO_ADDRESS = '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7';
49
+ const WALLET_EXTENDED_KEYS = ['publicKeyRing', 'pubKey', 'addressManager'];
50
+ const COPAYER_EXTENDED_KEYS = ['xPubKey', 'requestPubKey', 'signature', 'addressManager', 'customData'];
51
+ const omit = (obj, keys) => Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)));
52
+ describe('Wallet reads', function () {
53
+ let blockchainExplorer;
54
+ let storage;
55
+ before(async function () {
56
+ ({ blockchainExplorer, storage } = await helpers_1.default.before());
57
+ });
58
+ beforeEach(async function () {
59
+ await helpers_1.default.beforeEach();
60
+ });
61
+ afterEach(function () {
62
+ sinon_1.default.restore();
63
+ });
64
+ after(async function () {
65
+ await helpers_1.default.after();
66
+ });
67
+ const call = (server, method, opts = {}) => util_1.default.promisify(server[method]).call(server, opts);
68
+ const storedWallet = async (walletId) => JSON.parse(JSON.stringify(await util_1.default.promisify(storage.fetchWallet).call(storage, walletId)));
69
+ const createTx = (server, amount, message = 'some message') => helpers_1.default.createAndPublishTx(server, { outputs: [{ toAddress: TO_ADDRESS, amount }], feePerKb: 100e2, message }, TestData.copayers[0].privKey_1H_0);
70
+ const sign = (server, txp, copayer = 0) => call(server, 'signTx', {
71
+ txProposalId: txp.id,
72
+ signatures: helpers_1.default.clientSign(txp, TestData.copayers[copayer].xPrivKey_44H_0H_0H)
73
+ });
74
+ const countWalletReads = (walletId) => {
75
+ const fetchWallet = sinon_1.default.spy(storage, 'fetchWallet');
76
+ return () => fetchWallet.getCalls().filter(c => c.args[0] === walletId).length;
77
+ };
78
+ describe('getStatus', function () {
79
+ it('returns the stored wallet without the extended fields', async function () {
80
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2);
81
+ await call(server, 'getStatus');
82
+ const status = await call(server, 'getStatus');
83
+ const expected = omit(await storedWallet(wallet.id), WALLET_EXTENDED_KEYS);
84
+ expected.copayers = expected.copayers.map(copayer => omit(copayer, COPAYER_EXTENDED_KEYS));
85
+ JSON.parse(JSON.stringify(status.wallet)).should.deep.equal(expected);
86
+ });
87
+ it('returns the stored wallet with the extended fields, and only the caller\'s customData', async function () {
88
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2);
89
+ await call(server, 'getStatus');
90
+ const status = await call(server, 'getStatus', { includeExtendedInfo: true });
91
+ const expected = await storedWallet(wallet.id);
92
+ expected.copayers = expected.copayers.map(copayer => copayer.id == server.copayerId ? copayer : omit(copayer, ['customData']));
93
+ JSON.parse(JSON.stringify(status.wallet)).should.deep.equal(expected);
94
+ status.wallet.copayers.find(c => c.id == server.copayerId).customData.should.equal('custom data 1');
95
+ });
96
+ for (const includeExtendedInfo of [false, true]) {
97
+ it(`keeps every copayer's customData in storage when a status registers the wallet (includeExtendedInfo: ${includeExtendedInfo})`, async function () {
98
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2);
99
+ (await storedWallet(wallet.id)).beRegistered.should.equal(false);
100
+ await call(server, 'getStatus', { includeExtendedInfo });
101
+ blockchainExplorer.register.calledOnce.should.equal(true);
102
+ const stored = await storedWallet(wallet.id);
103
+ stored.beRegistered.should.equal(true);
104
+ stored.copayers.map(c => c.customData).should.deep.equal(['custom data 1', 'custom data 2']);
105
+ stored.should.not.have.property('tokenAddress');
106
+ stored.should.not.have.property('multisigContractAddress');
107
+ });
108
+ }
109
+ it('keeps a token status and a native status of one wallet apart when they run together', async function () {
110
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'eth' });
111
+ await call(server, 'createAddress');
112
+ await helpers_1.default.stubUtxos(server, wallet, [1], { tokenAddress: TOKEN_ADDRESS });
113
+ const seen = [];
114
+ const getBalance = blockchainExplorer.getBalance;
115
+ sinon_1.default.stub(blockchainExplorer, 'getBalance').callsFake((w, cb) => {
116
+ seen.push(w.tokenAddress || null);
117
+ return getBalance(w, cb);
118
+ });
119
+ const [native, token] = await Promise.all([
120
+ call(server, 'getStatus'),
121
+ call(server, 'getStatus', { tokenAddress: TOKEN_ADDRESS })
122
+ ]);
123
+ native.balance.totalAmount.should.equal(1e18);
124
+ token.balance.totalAmount.should.equal(2e6);
125
+ seen.sort().should.deep.equal([null, TOKEN_ADDRESS].sort());
126
+ });
127
+ it('keeps the token address the balance step sets out of the returned and the stored wallet', async function () {
128
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'eth' });
129
+ await call(server, 'createAddress');
130
+ await helpers_1.default.stubUtxos(server, wallet, [1], { tokenAddress: TOKEN_ADDRESS });
131
+ await storage.db.collection(storage_1.Storage.collections.WALLETS).updateOne({ id: wallet.id }, { $set: { beRegistered: false } });
132
+ const status = await call(server, 'getStatus', { tokenAddress: TOKEN_ADDRESS, includeExtendedInfo: true });
133
+ status.balance.totalAmount.should.equal(2e6);
134
+ status.wallet.should.not.have.property('tokenAddress');
135
+ status.wallet.should.not.have.property('multisigContractAddress');
136
+ const stored = await storedWallet(wallet.id);
137
+ stored.beRegistered.should.equal(true);
138
+ stored.should.not.have.property('tokenAddress');
139
+ JSON.parse(JSON.stringify(status.wallet)).should.deep.equal({ ...stored, beRegistered: status.wallet.beRegistered });
140
+ });
141
+ it('counts pending txps as locked and the inputs of broadcast txps as spent', async function () {
142
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
143
+ await helpers_1.default.stubUtxos(server, wallet, [1, 2]);
144
+ const broadcast = await sign(server, await createTx(server, 1.5e8));
145
+ helpers_1.default.stubBroadcast(broadcast.txid);
146
+ await call(server, 'broadcastTx', { txProposalId: broadcast.id });
147
+ const pending = await createTx(server, 0.5e8);
148
+ const status = await call(server, 'getStatus');
149
+ const sum = inputs => inputs.reduce((total, input) => total + input.satoshis, 0);
150
+ status.balance.totalAmount.should.equal(3e8 - sum(broadcast.inputs));
151
+ status.balance.lockedAmount.should.equal(sum(pending.inputs));
152
+ status.pendingTxps.map(t => t.id).should.deep.equal([pending.id]);
153
+ });
154
+ it('adds the creator\'s and the copayers\' names to pending txps', async function () {
155
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(2, 3);
156
+ await helpers_1.default.stubUtxos(server, wallet, [1]);
157
+ const txp = await createTx(server, 0.5e8);
158
+ const server2 = await helpers_1.default.getAuthServer(wallet.copayers[1].id);
159
+ await sign(server2, txp, 1);
160
+ const status = await call(server, 'getStatus');
161
+ status.pendingTxps.length.should.equal(1);
162
+ const [pending] = status.pendingTxps;
163
+ pending.creatorName.should.equal('copayer 1');
164
+ pending.actions.map(a => [a.type, a.copayerName]).should.deep.equal([['accept', 'copayer 2']]);
165
+ pending.derivationStrategy.should.equal('BIP44');
166
+ should.not.exist(pending.raw);
167
+ });
168
+ it('adds the raw tx to accepted pending txps', async function () {
169
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2);
170
+ await helpers_1.default.stubUtxos(server, wallet, [1]);
171
+ const signed = await sign(server, await createTx(server, 0.5e8));
172
+ const status = await call(server, 'getStatus');
173
+ status.pendingTxps.length.should.equal(1);
174
+ status.pendingTxps[0].status.should.equal('accepted');
175
+ status.pendingTxps[0].raw.should.equal(signed.getRawTx());
176
+ });
177
+ it('falls back to BIP45 for txps of a wallet stored without a derivation strategy', async function () {
178
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
179
+ await helpers_1.default.stubUtxos(server, wallet, [1]);
180
+ await createTx(server, 0.5e8);
181
+ await storage.db.collection(storage_1.Storage.collections.WALLETS).updateOne({ id: wallet.id }, { $unset: { derivationStrategy: '' } });
182
+ const status = await call(server, 'getStatus');
183
+ status.pendingTxps[0].derivationStrategy.should.equal('BIP45');
184
+ });
185
+ it('migrates an old BCH wallet to cash addresses', async function () {
186
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'bch', earlyRet: true, nativeCashAddr: false });
187
+ (await storedWallet(server.walletId)).nativeCashAddr.should.equal(false);
188
+ const status = await call(server, 'getStatus');
189
+ status.wallet.nativeCashAddr.should.equal(true);
190
+ (await storedWallet(server.walletId)).nativeCashAddr.should.equal(true);
191
+ });
192
+ describe('wallet reads', function () {
193
+ it('reads the wallet once for a UTXO wallet with pending and broadcast txps', async function () {
194
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
195
+ await helpers_1.default.stubUtxos(server, wallet, [1, 1, 1]);
196
+ const broadcast = await sign(server, await createTx(server, 0.5e8));
197
+ helpers_1.default.stubBroadcast(broadcast.txid);
198
+ await call(server, 'broadcastTx', { txProposalId: broadcast.id });
199
+ await createTx(server, 0.5e8);
200
+ await sign(server, await createTx(server, 0.5e8));
201
+ const reads = countWalletReads(wallet.id);
202
+ await call(server, 'getStatus');
203
+ reads().should.equal(1);
204
+ });
205
+ it('reads the wallet once for an account-based wallet', async function () {
206
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'eth' });
207
+ await call(server, 'createAddress');
208
+ await helpers_1.default.stubUtxos(server, wallet, [1]);
209
+ const reads = countWalletReads(wallet.id);
210
+ await call(server, 'getStatus');
211
+ reads().should.equal(1);
212
+ });
213
+ it('reads the wallet once when the status registers the wallet', async function () {
214
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2);
215
+ (await storedWallet(wallet.id)).beRegistered.should.equal(false);
216
+ const reads = countWalletReads(wallet.id);
217
+ await call(server, 'getStatus');
218
+ reads().should.equal(1);
219
+ blockchainExplorer.register.calledOnce.should.equal(true);
220
+ });
221
+ it('migrates an old BCH wallet once', async function () {
222
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'bch', earlyRet: true, nativeCashAddr: false });
223
+ const migrate = sinon_1.default.spy(storage, 'migrateToCashAddr');
224
+ await call(server, 'getStatus');
225
+ migrate.callCount.should.equal(1);
226
+ });
227
+ });
228
+ describe('errors', function () {
229
+ it('fails with UPGRADE_NEEDED for a SOL wallet and an old client', async function () {
230
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'sol' });
231
+ server.clientVersion = 'bwc-10.10.0';
232
+ const err = await call(server, 'getStatus').catch(e => e);
233
+ err.code.should.equal('UPGRADE_NEEDED');
234
+ });
235
+ it('fails with WALLET_NOT_FOUND when the wallet is gone', async function () {
236
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
237
+ await storage.db.collection(storage_1.Storage.collections.WALLETS).deleteOne({ id: wallet.id });
238
+ const err = await call(server, 'getStatus').catch(e => e);
239
+ err.code.should.equal('WALLET_NOT_FOUND');
240
+ });
241
+ it('passes on a storage error reading the wallet', async function () {
242
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1);
243
+ sinon_1.default.stub(server.storage, 'fetchWallet').callsArgWith(1, new Error('wallet read failed'));
244
+ const err = await call(server, 'getStatus').catch(e => e);
245
+ err.message.should.equal('wallet read failed');
246
+ });
247
+ it('passes on a storage error reading the pending txps', async function () {
248
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1);
249
+ sinon_1.default.stub(server.storage, 'fetchPendingTxs').callsArgWith(1, new Error('pending read failed'));
250
+ const err = await call(server, 'getStatus').catch(e => e);
251
+ err.message.should.equal('pending read failed');
252
+ });
253
+ it('passes on a storage error reading the preferences', async function () {
254
+ const { server } = await helpers_1.default.createAndJoinWallet(1, 1);
255
+ sinon_1.default.stub(server.storage, 'fetchPreferences').callsArgWith(2, new Error('preferences read failed'));
256
+ const err = await call(server, 'getStatus').catch(e => e);
257
+ err.message.should.equal('preferences read failed');
258
+ });
259
+ it('passes on a balance error, with or without includeExtendedInfo', async function () {
260
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
261
+ await helpers_1.default.stubUtxos(server, wallet, [1]);
262
+ sinon_1.default.stub(blockchainExplorer, 'getUtxos').callsArgWith(2, new Error('utxos failed'));
263
+ for (const includeExtendedInfo of [false, true]) {
264
+ const err = await call(server, 'getStatus', { includeExtendedInfo }).catch(e => e);
265
+ err.message.should.equal('utxos failed');
266
+ }
267
+ });
268
+ it('returns no balance for a wallet that needs a scan only with includeExtendedInfo', async function () {
269
+ const { server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1);
270
+ await storage.db.collection(storage_1.Storage.collections.WALLETS).updateOne({ id: wallet.id }, { $set: { scanStatus: 'error' } });
271
+ const err = await call(server, 'getStatus').catch(e => e);
272
+ err.code.should.equal('WALLET_NEED_SCAN');
273
+ const status = await call(server, 'getStatus', { includeExtendedInfo: true });
274
+ should.exist(status.wallet);
275
+ should.not.exist(status.balance);
276
+ });
277
+ });
278
+ });
279
+ describe('tx and note decoration', function () {
280
+ let server;
281
+ let server2;
282
+ let txp;
283
+ beforeEach(async function () {
284
+ let wallet;
285
+ ({ server, wallet } = await helpers_1.default.createAndJoinWallet(1, 2));
286
+ await helpers_1.default.stubUtxos(server, wallet, [1, 1]);
287
+ txp = await sign(server, await createTx(server, 0.5e8));
288
+ helpers_1.default.stubBroadcast(txp.txid);
289
+ await call(server, 'broadcastTx', { txProposalId: txp.id });
290
+ server2 = await helpers_1.default.getAuthServer(wallet.copayers[1].id);
291
+ await call(server2, 'editTxNote', { txid: txp.txid, body: 'a note' });
292
+ });
293
+ const expectDecorated = tx => {
294
+ tx.creatorName.should.equal('copayer 1');
295
+ tx.actions.map(a => [a.type, a.copayerName]).should.deep.equal([['accept', 'copayer 1']]);
296
+ tx.note.body.should.equal('a note');
297
+ tx.note.editedByName.should.equal('copayer 2');
298
+ };
299
+ it('getTx adds the names and the note', async function () {
300
+ const tx = await call(server, 'getTx', { txProposalId: txp.id });
301
+ expectDecorated(tx);
302
+ tx.derivationStrategy.should.equal('BIP44');
303
+ });
304
+ it('getTxByHash adds the names and the note', async function () {
305
+ const tx = await call(server, 'getTxByHash', { txid: txp.txid });
306
+ expectDecorated(tx);
307
+ });
308
+ it('getTxHistory adds the proposal and the note to the matching tx', async function () {
309
+ helpers_1.default.stubHistory(0, 1000, [{
310
+ txid: txp.txid,
311
+ category: 'send',
312
+ satoshis: 0.5e8,
313
+ fee: 1000,
314
+ height: 900,
315
+ address: TO_ADDRESS,
316
+ outputs: [{ address: TO_ADDRESS, amount: 0.5e8 }],
317
+ blockTime: new Date().toISOString()
318
+ }]);
319
+ const history = await call(server, 'getTxHistory');
320
+ history.length.should.equal(1);
321
+ const [tx] = history;
322
+ tx.proposalId.should.equal(txp.id);
323
+ tx.creatorName.should.equal('copayer 1');
324
+ tx.message.should.equal('some message');
325
+ tx.actions.map(a => [a.type, a.copayerName]).should.deep.equal([['accept', 'copayer 1']]);
326
+ tx.note.body.should.equal('a note');
327
+ tx.note.editedByName.should.equal('copayer 2');
328
+ });
329
+ it('getTx reads the wallet once', async function () {
330
+ const reads = countWalletReads(server.walletId);
331
+ await call(server, 'getTx', { txProposalId: txp.id });
332
+ reads().should.equal(1);
333
+ });
334
+ it('getTxByHash reads the wallet once', async function () {
335
+ const reads = countWalletReads(server.walletId);
336
+ await call(server, 'getTxByHash', { txid: txp.txid });
337
+ reads().should.equal(1);
338
+ });
339
+ it('getTxHistory reads the wallet once', async function () {
340
+ helpers_1.default.stubHistory(0, 1000, [{
341
+ txid: txp.txid, category: 'send', satoshis: 0.5e8, fee: 1000, height: 900, address: TO_ADDRESS,
342
+ outputs: [{ address: TO_ADDRESS, amount: 0.5e8 }], blockTime: new Date().toISOString()
343
+ }]);
344
+ const reads = countWalletReads(server.walletId);
345
+ const history = await call(server, 'getTxHistory');
346
+ should.exist(history[0].proposalId);
347
+ reads().should.equal(1);
348
+ });
349
+ it('getTx and getTxByHash fail with TX_NOT_FOUND for an unknown tx', async function () {
350
+ for (const [method, opts] of [['getTx', { txProposalId: 'unknown' }], ['getTxByHash', { txid: 'unknown' }]]) {
351
+ const err = await call(server, method, opts).catch(e => e);
352
+ err.code.should.equal('TX_NOT_FOUND');
353
+ }
354
+ });
355
+ it('getTx returns a txp that has not been broadcast, without a note', async function () {
356
+ const pending = await createTx(server, 0.1e8);
357
+ const tx = await call(server, 'getTx', { txProposalId: pending.id });
358
+ tx.id.should.equal(pending.id);
359
+ tx.creatorName.should.equal('copayer 1');
360
+ should.not.exist(tx.txid);
361
+ should.not.exist(tx.note);
362
+ });
363
+ const byIdAndHash = () => [['getTx', { txProposalId: txp.id }], ['getTxByHash', { txid: txp.txid }]];
364
+ it('getTx and getTxByHash pass on a storage error reading the wallet, after one read', async function () {
365
+ const fetchWallet = sinon_1.default.stub(storage, 'fetchWallet').callsArgWith(1, new Error('wallet read failed'));
366
+ for (const [method, opts] of byIdAndHash()) {
367
+ fetchWallet.resetHistory();
368
+ const err = await call(server, method, opts).catch(e => e);
369
+ err.message.should.equal('wallet read failed');
370
+ fetchWallet.callCount.should.equal(1, method);
371
+ }
372
+ });
373
+ it('getTx and getTxByHash pass on a storage error looking up the tx', async function () {
374
+ sinon_1.default.stub(storage, 'fetchTx').callsArgWith(2, new Error('tx read failed'));
375
+ sinon_1.default.stub(storage, 'fetchTxByHashForWallet').callsArgWith(2, new Error('tx read failed'));
376
+ for (const [method, opts] of byIdAndHash()) {
377
+ const err = await call(server, method, opts).catch(e => e);
378
+ err.message.should.equal('tx read failed', method);
379
+ }
380
+ });
381
+ it('getTx and getTxByHash return the tx without its note when the note read fails', async function () {
382
+ sinon_1.default.stub(storage, 'fetchTxNote').callsArgWith(2, new Error('note read failed'));
383
+ for (const [method, opts] of byIdAndHash()) {
384
+ const tx = await call(server, method, opts);
385
+ tx.id.should.equal(txp.id);
386
+ should.not.exist(tx.note);
387
+ }
388
+ });
389
+ it('getTxByHash returns a tx that has no txid as it is', async function () {
390
+ const tx = await util_1.default.promisify(storage.fetchTx).call(storage, server.walletId, txp.id);
391
+ tx.txid = undefined;
392
+ sinon_1.default.stub(storage, 'fetchTxByHashForWallet').callsFake((walletId, hash, cb) => cb(null, tx));
393
+ const fetchTxNote = sinon_1.default.spy(storage, 'fetchTxNote');
394
+ const result = await call(server, 'getTxByHash', { txid: txp.txid });
395
+ result.id.should.equal(txp.id);
396
+ fetchTxNote.called.should.equal(false);
397
+ });
398
+ it('each storage fetch completes from the wallet it is given, without reading it', async function () {
399
+ const given = await util_1.default.promisify(storage.fetchWallet).call(storage, server.walletId);
400
+ for (const copayer of given.copayers)
401
+ copayer.name = 'given ' + copayer.name;
402
+ const fetchWallet = sinon_1.default.spy(storage, 'fetchWallet');
403
+ const walletId = server.walletId;
404
+ const pending = await createTx(server, 0.1e8);
405
+ fetchWallet.resetHistory();
406
+ const fetches = [
407
+ ['fetchTx', cb => storage.fetchTx(walletId, txp.id, cb, given), tx => [tx.creatorName]],
408
+ ['fetchTxByHashForWallet', cb => storage.fetchTxByHashForWallet(walletId, txp.txid, cb, given), tx => [tx.creatorName]],
409
+ ['fetchPendingTxs', cb => storage.fetchPendingTxs(walletId, cb, given), txs => txs.map(t => t.creatorName)],
410
+ ['fetchTxs', cb => storage.fetchTxs(walletId, {}, cb, given), txs => txs.map(t => t.creatorName)],
411
+ ['fetchBroadcastedTxs', cb => storage.fetchBroadcastedTxs(walletId, {}, cb, given), txs => txs.map(t => t.creatorName)],
412
+ ['fetchTxNote', cb => storage.fetchTxNote(walletId, txp.txid, cb, given), note => [note.editedByName]],
413
+ ['fetchTxNotes', cb => storage.fetchTxNotes(walletId, {}, cb, given), notes => notes.map(n => n.editedByName)]
414
+ ];
415
+ for (const [name, fetch, names] of fetches) {
416
+ const result = await util_1.default.promisify(fetch)();
417
+ const got = names(result);
418
+ got.length.should.be.above(0, name);
419
+ got.every(n => n.startsWith('given ')).should.equal(true, name);
420
+ }
421
+ fetchWallet.callCount.should.equal(0);
422
+ should.exist(pending);
423
+ });
424
+ it('a storage error reading the wallet fails each completion', async function () {
425
+ sinon_1.default.stub(storage, 'fetchWallet').callsArgWith(1, new Error('wallet read failed'));
426
+ for (const run of [
427
+ cb => storage.fetchTx(server.walletId, txp.id, cb),
428
+ cb => storage.fetchTxNote(server.walletId, txp.txid, cb)
429
+ ]) {
430
+ const err = await util_1.default.promisify(run)().catch(e => e);
431
+ err.message.should.equal('wallet read failed');
432
+ }
433
+ });
434
+ });
435
+ });
436
+ //# sourceMappingURL=walletReads.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletReads.test.js","sourceRoot":"","sources":["../../../test/integration/walletReads.test.ts"],"names":[],"mappings":"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"}