@bitpay-labs/bitcore-wallet-service 11.11.0 → 11.11.2

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 (157) hide show
  1. package/Dockerfile +1 -1
  2. package/package.json +5 -5
  3. package/src/config.ts +0 -20
  4. package/src/externalservices/banxa.ts +51 -10
  5. package/src/externalservices/changelly.ts +54 -6
  6. package/src/externalservices/moonpay.ts +85 -19
  7. package/src/externalservices/oneInch.ts +13 -5
  8. package/src/externalservices/ramp.ts +42 -8
  9. package/src/externalservices/sardine.ts +51 -10
  10. package/src/externalservices/simplex.ts +58 -11
  11. package/src/externalservices/thorswap.ts +46 -11
  12. package/src/externalservices/transak.ts +53 -11
  13. package/src/lib/chain/btc/index.ts +3 -2
  14. package/src/lib/chain/eth/index.ts +134 -117
  15. package/src/lib/chain/sol/index.ts +1 -1
  16. package/src/lib/chain/xrp/index.ts +1 -1
  17. package/src/lib/routes/services.ts +0 -12
  18. package/src/lib/routes/wallets.ts +3 -1
  19. package/src/lib/server.ts +136 -91
  20. package/src/lib/storage.ts +90 -20
  21. package/src/types/externalservices.d.ts +0 -1
  22. package/test/chain/eth.test.ts +70 -0
  23. package/test/chain/sol.test.ts +1 -1
  24. package/test/chain/xrp.test.ts +1 -1
  25. package/test/expressapp.test.ts +144 -0
  26. package/test/integration/addressReads.test.ts +503 -0
  27. package/test/integration/bcmonitor.test.ts +44 -0
  28. package/test/integration/externalservices/banxa.test.ts +95 -5
  29. package/test/integration/externalservices/changelly.test.ts +118 -6
  30. package/test/integration/externalservices/coinGecko.test.ts +4 -0
  31. package/test/integration/externalservices/moonpay.test.ts +178 -9
  32. package/test/integration/externalservices/oneInch.test.ts +28 -1
  33. package/test/integration/externalservices/ramp.test.ts +126 -4
  34. package/test/integration/externalservices/sardine.test.ts +95 -5
  35. package/test/integration/externalservices/simplex.test.ts +95 -5
  36. package/test/integration/externalservices/thorswap.test.ts +81 -5
  37. package/test/integration/externalservices/transak.test.ts +98 -6
  38. package/test/integration/helpers.ts +1 -1
  39. package/test/integration/server.test.ts +254 -136
  40. package/test/integration/walletReads.test.ts +488 -0
  41. package/ts_build/package.json +3 -3
  42. package/ts_build/src/config.d.ts.map +1 -1
  43. package/ts_build/src/config.js +0 -4
  44. package/ts_build/src/config.js.map +1 -1
  45. package/ts_build/src/externalservices/banxa.d.ts.map +1 -1
  46. package/ts_build/src/externalservices/banxa.js +51 -10
  47. package/ts_build/src/externalservices/banxa.js.map +1 -1
  48. package/ts_build/src/externalservices/changelly.d.ts.map +1 -1
  49. package/ts_build/src/externalservices/changelly.js +54 -6
  50. package/ts_build/src/externalservices/changelly.js.map +1 -1
  51. package/ts_build/src/externalservices/moonpay.d.ts.map +1 -1
  52. package/ts_build/src/externalservices/moonpay.js +85 -19
  53. package/ts_build/src/externalservices/moonpay.js.map +1 -1
  54. package/ts_build/src/externalservices/oneInch.d.ts.map +1 -1
  55. package/ts_build/src/externalservices/oneInch.js +13 -5
  56. package/ts_build/src/externalservices/oneInch.js.map +1 -1
  57. package/ts_build/src/externalservices/ramp.d.ts.map +1 -1
  58. package/ts_build/src/externalservices/ramp.js +42 -8
  59. package/ts_build/src/externalservices/ramp.js.map +1 -1
  60. package/ts_build/src/externalservices/sardine.d.ts.map +1 -1
  61. package/ts_build/src/externalservices/sardine.js +51 -10
  62. package/ts_build/src/externalservices/sardine.js.map +1 -1
  63. package/ts_build/src/externalservices/simplex.d.ts.map +1 -1
  64. package/ts_build/src/externalservices/simplex.js +55 -11
  65. package/ts_build/src/externalservices/simplex.js.map +1 -1
  66. package/ts_build/src/externalservices/thorswap.d.ts.map +1 -1
  67. package/ts_build/src/externalservices/thorswap.js +45 -11
  68. package/ts_build/src/externalservices/thorswap.js.map +1 -1
  69. package/ts_build/src/externalservices/transak.d.ts.map +1 -1
  70. package/ts_build/src/externalservices/transak.js +53 -11
  71. package/ts_build/src/externalservices/transak.js.map +1 -1
  72. package/ts_build/src/lib/chain/btc/index.d.ts.map +1 -1
  73. package/ts_build/src/lib/chain/btc/index.js +3 -2
  74. package/ts_build/src/lib/chain/btc/index.js.map +1 -1
  75. package/ts_build/src/lib/chain/eth/index.d.ts +8 -1
  76. package/ts_build/src/lib/chain/eth/index.d.ts.map +1 -1
  77. package/ts_build/src/lib/chain/eth/index.js +114 -102
  78. package/ts_build/src/lib/chain/eth/index.js.map +1 -1
  79. package/ts_build/src/lib/chain/sol/index.js +1 -1
  80. package/ts_build/src/lib/chain/sol/index.js.map +1 -1
  81. package/ts_build/src/lib/chain/xrp/index.js +1 -1
  82. package/ts_build/src/lib/chain/xrp/index.js.map +1 -1
  83. package/ts_build/src/lib/routes/services.d.ts.map +1 -1
  84. package/ts_build/src/lib/routes/services.js +0 -10
  85. package/ts_build/src/lib/routes/services.js.map +1 -1
  86. package/ts_build/src/lib/routes/wallets.d.ts.map +1 -1
  87. package/ts_build/src/lib/routes/wallets.js +2 -1
  88. package/ts_build/src/lib/routes/wallets.js.map +1 -1
  89. package/ts_build/src/lib/server.d.ts +1 -3
  90. package/ts_build/src/lib/server.d.ts.map +1 -1
  91. package/ts_build/src/lib/server.js +128 -96
  92. package/ts_build/src/lib/server.js.map +1 -1
  93. package/ts_build/src/lib/storage.d.ts +17 -10
  94. package/ts_build/src/lib/storage.d.ts.map +1 -1
  95. package/ts_build/src/lib/storage.js +73 -20
  96. package/ts_build/src/lib/storage.js.map +1 -1
  97. package/ts_build/test/chain/eth.test.js +59 -0
  98. package/ts_build/test/chain/eth.test.js.map +1 -1
  99. package/ts_build/test/chain/sol.test.js +1 -1
  100. package/ts_build/test/chain/sol.test.js.map +1 -1
  101. package/ts_build/test/chain/xrp.test.js +1 -1
  102. package/ts_build/test/chain/xrp.test.js.map +1 -1
  103. package/ts_build/test/expressapp.test.js +132 -0
  104. package/ts_build/test/expressapp.test.js.map +1 -1
  105. package/ts_build/test/integration/addressReads.test.d.ts +2 -0
  106. package/ts_build/test/integration/addressReads.test.d.ts.map +1 -0
  107. package/ts_build/test/integration/addressReads.test.js +465 -0
  108. package/ts_build/test/integration/addressReads.test.js.map +1 -0
  109. package/ts_build/test/integration/bcmonitor.test.js +40 -0
  110. package/ts_build/test/integration/bcmonitor.test.js.map +1 -1
  111. package/ts_build/test/integration/externalservices/banxa.test.d.ts.map +1 -1
  112. package/ts_build/test/integration/externalservices/banxa.test.js +93 -5
  113. package/ts_build/test/integration/externalservices/banxa.test.js.map +1 -1
  114. package/ts_build/test/integration/externalservices/changelly.test.d.ts.map +1 -1
  115. package/ts_build/test/integration/externalservices/changelly.test.js +111 -6
  116. package/ts_build/test/integration/externalservices/changelly.test.js.map +1 -1
  117. package/ts_build/test/integration/externalservices/coinGecko.test.js +4 -0
  118. package/ts_build/test/integration/externalservices/coinGecko.test.js.map +1 -1
  119. package/ts_build/test/integration/externalservices/moonpay.test.d.ts.map +1 -1
  120. package/ts_build/test/integration/externalservices/moonpay.test.js +169 -9
  121. package/ts_build/test/integration/externalservices/moonpay.test.js.map +1 -1
  122. package/ts_build/test/integration/externalservices/oneInch.test.d.ts.map +1 -1
  123. package/ts_build/test/integration/externalservices/oneInch.test.js +26 -1
  124. package/ts_build/test/integration/externalservices/oneInch.test.js.map +1 -1
  125. package/ts_build/test/integration/externalservices/ramp.test.d.ts.map +1 -1
  126. package/ts_build/test/integration/externalservices/ramp.test.js +115 -4
  127. package/ts_build/test/integration/externalservices/ramp.test.js.map +1 -1
  128. package/ts_build/test/integration/externalservices/sardine.test.d.ts.map +1 -1
  129. package/ts_build/test/integration/externalservices/sardine.test.js +94 -5
  130. package/ts_build/test/integration/externalservices/sardine.test.js.map +1 -1
  131. package/ts_build/test/integration/externalservices/simplex.test.d.ts.map +1 -1
  132. package/ts_build/test/integration/externalservices/simplex.test.js +89 -5
  133. package/ts_build/test/integration/externalservices/simplex.test.js.map +1 -1
  134. package/ts_build/test/integration/externalservices/thorswap.test.d.ts.map +1 -1
  135. package/ts_build/test/integration/externalservices/thorswap.test.js +76 -5
  136. package/ts_build/test/integration/externalservices/thorswap.test.js.map +1 -1
  137. package/ts_build/test/integration/externalservices/transak.test.d.ts.map +1 -1
  138. package/ts_build/test/integration/externalservices/transak.test.js +93 -6
  139. package/ts_build/test/integration/externalservices/transak.test.js.map +1 -1
  140. package/ts_build/test/integration/helpers.js +1 -1
  141. package/ts_build/test/integration/helpers.js.map +1 -1
  142. package/ts_build/test/integration/server.test.js +225 -124
  143. package/ts_build/test/integration/server.test.js.map +1 -1
  144. package/ts_build/test/integration/walletReads.test.d.ts +2 -0
  145. package/ts_build/test/integration/walletReads.test.d.ts.map +1 -0
  146. package/ts_build/test/integration/walletReads.test.js +436 -0
  147. package/ts_build/test/integration/walletReads.test.js.map +1 -0
  148. package/src/externalservices/wyre.ts +0 -131
  149. package/test/integration/externalservices/wyre.test.ts +0 -270
  150. package/ts_build/src/externalservices/wyre.d.ts +0 -7
  151. package/ts_build/src/externalservices/wyre.d.ts.map +0 -1
  152. package/ts_build/src/externalservices/wyre.js +0 -144
  153. package/ts_build/src/externalservices/wyre.js.map +0 -1
  154. package/ts_build/test/integration/externalservices/wyre.test.d.ts +0 -2
  155. package/ts_build/test/integration/externalservices/wyre.test.d.ts.map +0 -1
  156. package/ts_build/test/integration/externalservices/wyre.test.js +0 -281
  157. package/ts_build/test/integration/externalservices/wyre.test.js.map +0 -1
@@ -19,6 +19,76 @@ describe('Chain ETH', function() {
19
19
  x.address.should.equal('0x01');
20
20
  });
21
21
 
22
+ describe('#onTx', function() {
23
+ const token = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
24
+ const sender = '0xC877cBCF020A8AA259A1Efab1559B2A3A7259086';
25
+ const recipient = '0x37D3bCDA9d7d5Dc41e32DAd77a5BA89a77aA8BD0';
26
+ const multisig = '0x9527a556f0D9AA753dE0D1f9Ad024a17dd281B1D';
27
+ // a tx event as bitcore-node emits it to the wallets room
28
+ const tx = (fields = {}) => ({ chain: 'ETH', network: 'mainnet', txid: '0x01', to: token, from: sender, value: 0, ...fields });
29
+ // effects as bitcore-node builds them
30
+ const erc20 = { type: 'ERC20:transfer', to: recipient, from: sender, amount: '1000000', contractAddress: token, callStack: '' };
31
+ const internal = { to: recipient, from: sender, amount: '2000', callStack: '0' };
32
+ const multisigEffect = type => ({ type, to: recipient, from: sender, amount: '3000', contractAddress: multisig, callStack: '' });
33
+
34
+ it('notifies the tx recipient and value for a tx without effects', function() {
35
+ ChainService.onTx('eth', tx({ to: recipient, value: 5000 })).should.deep.equal({
36
+ txid: '0x01',
37
+ out: { address: recipient, amount: 5000, tokenAddress: undefined, multisigContractAddress: undefined }
38
+ });
39
+ ChainService.onTx('eth', tx({ to: recipient, value: 5000, effects: [] })).out.should.deep.equal({
40
+ address: recipient, amount: 5000, tokenAddress: undefined, multisigContractAddress: undefined
41
+ });
42
+ });
43
+
44
+ it('notifies the recipient of an internal value transfer', function() {
45
+ ChainService.onTx('eth', tx({ effects: [internal] })).out.should.deep.equal({
46
+ address: recipient, amount: '2000', tokenAddress: undefined, multisigContractAddress: undefined
47
+ });
48
+ });
49
+
50
+ for (const type of ['MULTISIG:confirmTransaction', 'MULTISIG:submitTransaction']) {
51
+ it(`notifies the recipient of a ${type} with its multisig contract`, function() {
52
+ ChainService.onTx('eth', tx({ effects: [internal, multisigEffect(type)] })).out.should.deep.equal({
53
+ address: recipient, amount: '3000', tokenAddress: undefined, multisigContractAddress: multisig
54
+ });
55
+ });
56
+ }
57
+
58
+ it('prefers a multisig effect to an ERC20 transfer', function() {
59
+ ChainService.onTx('eth', tx({ effects: [erc20, multisigEffect('MULTISIG:submitTransaction')] })).out.should.deep.equal({
60
+ address: recipient, amount: '3000', tokenAddress: undefined, multisigContractAddress: multisig
61
+ });
62
+ });
63
+
64
+ it('falls back to the tx recipient for effects it does not know', function() {
65
+ const other = { type: 'OTHER:call', to: recipient, from: sender, amount: '1', contractAddress: token, callStack: '' };
66
+ ChainService.onTx('eth', tx({ effects: [other] })).out.should.deep.equal({
67
+ address: token, amount: 0, tokenAddress: undefined, multisigContractAddress: undefined
68
+ });
69
+ });
70
+
71
+ it('handles MATIC txs the same way', function() {
72
+ ChainService.onTx('matic', tx({ chain: 'MATIC', to: recipient, value: 5000 })).out.should.deep.equal({
73
+ address: recipient, amount: 5000, tokenAddress: undefined, multisigContractAddress: undefined
74
+ });
75
+ });
76
+
77
+ it('notifies the token recipient, amount and token of an ERC20 transfer', function() {
78
+ ChainService.onTx('eth', tx({ effects: [erc20] })).should.deep.equal({
79
+ txid: '0x01',
80
+ out: { address: recipient, amount: '1000000', tokenAddress: token, multisigContractAddress: undefined }
81
+ });
82
+ ChainService.onTx('matic', tx({ chain: 'MATIC', effects: [erc20] })).out.tokenAddress.should.equal(token);
83
+ });
84
+
85
+ it('prefers an ERC20 transfer to an internal value transfer', function() {
86
+ ChainService.onTx('eth', tx({ effects: [internal, erc20] })).out.should.deep.equal({
87
+ address: recipient, amount: '1000000', tokenAddress: token, multisigContractAddress: undefined
88
+ });
89
+ });
90
+ });
91
+
22
92
  describe('#selectTxInputs', function() {
23
93
  it('should reject a total that a number rounds down to the balance', function(done) {
24
94
  const server = {
@@ -27,7 +27,7 @@ describe('Chain SOL', function() {
27
27
  getRentMinimum: (_space, cb) => cb(null, Defaults.MIN_SOL_BALANCE)
28
28
  }),
29
29
  getPendingTxs: (_opts, cb) => cb(null, c.txps),
30
- storage: { fetchAddresses: (_walletId, cb) => cb(null, []) }
30
+ storage: { fetchAddressesPage: (_walletId, _opts, cb) => cb(null, []) }
31
31
  };
32
32
  const wallet = { chain: 'sol', network: 'livenet' };
33
33
 
@@ -20,7 +20,7 @@ describe('Chain XRP', function() {
20
20
  getReserve: cb => cb(null, 1000000)
21
21
  }),
22
22
  getPendingTxs: (_opts, cb) => cb(null, [{ amount: '3000000', fee: '12' }]),
23
- storage: { fetchAddresses: (_walletId, cb) => cb(null, []) }
23
+ storage: { fetchAddressesPage: (_walletId, _opts, cb) => cb(null, []) }
24
24
  };
25
25
  const wallet = { chain: 'xrp', network: 'livenet' };
26
26
 
@@ -11,6 +11,8 @@ import { Common } from '../src/lib/common';
11
11
  import { WalletService } from '../src/lib/server';
12
12
  import { ExpressApp } from '../src/lib/expressapp';
13
13
  import { ClientError } from '../src/lib/errors/clienterror';
14
+ import { BitcoreLib } from '@bitpay-labs/crypto-wallet-core';
15
+ import * as TestData from './testdata';
14
16
 
15
17
  const Defaults = Common.Defaults;
16
18
  const should = chai.should();
@@ -762,6 +764,148 @@ describe('ExpressApp', function() {
762
764
  });
763
765
  });
764
766
 
767
+ describe('/v1/wallets/exist', function() {
768
+ const idA = 'a'.repeat(64);
769
+ const idB = 'b'.repeat(64);
770
+ const idC = 'c'.repeat(64);
771
+ let storage;
772
+
773
+ function sign(message) {
774
+ const hash = Common.Utils.hashMessage(message, false);
775
+ return BitcoreLib.crypto.ECDSA.sign(hash, new BitcoreLib.PrivateKey(TestData.keyPair.priv), { endian: 'little' }).toString();
776
+ }
777
+
778
+ // posts each body in turn, and calls back with each response's status and body
779
+ function postEach(bodies, cb) {
780
+ sandbox.stub(WalletService, 'initialize').callsArg(1);
781
+ sandbox.stub(WalletService, 'getStorage').returns(storage);
782
+ start(ExpressApp, function() {
783
+ const results = [];
784
+ (function next() {
785
+ if (results.length === bodies.length) {
786
+ return cb(null, results);
787
+ }
788
+ request({
789
+ url: testHost + ':' + testPort + config.basePath + '/v1/wallets/exist',
790
+ method: 'post',
791
+ json: true,
792
+ body: bodies[results.length]
793
+ }, function(err, res, body) {
794
+ if (err) {
795
+ return cb(err);
796
+ }
797
+ results.push({ status: res.statusCode, body });
798
+ next();
799
+ });
800
+ })();
801
+ });
802
+ }
803
+
804
+ function post(body, cb) {
805
+ postEach([body], (err, results) => (err ? cb(err) : cb(null, { statusCode: results[0].status }, results[0].body)));
806
+ }
807
+
808
+ beforeEach(function() {
809
+ const copayer = { requestPubKeys: [{ key: TestData.keyPair.pub }] };
810
+ storage = {
811
+ fetchCopayerLookup: sinon.stub().callsFake(async id => (id === idA || id === idB ? copayer : undefined))
812
+ };
813
+ });
814
+
815
+ it('returns the copayers whose signature verifies against their request key', function(done) {
816
+ post({
817
+ copayers: [
818
+ { copayerId: idA, signature: sign(idA) },
819
+ { copayerId: idB, signature: sign(idA) },
820
+ { copayerId: idC, signature: sign(idC) }
821
+ ]
822
+ }, function(err, res, body) {
823
+ should.not.exist(err);
824
+ res.statusCode.should.equal(200);
825
+ body.should.deep.equal([idA]);
826
+ storage.fetchCopayerLookup.args.should.deep.equal([[idA], [idB], [idC]]);
827
+ done();
828
+ });
829
+ });
830
+
831
+ it('returns no copayers when given none to check', function(done) {
832
+ postEach([
833
+ {},
834
+ { copayers: null },
835
+ { copayers: idA },
836
+ { copayers: { copayerId: idA, signature: sign(idA) } },
837
+ { copayers: [] }
838
+ ], function(err, results) {
839
+ should.not.exist(err);
840
+ results.should.deep.equal(Array(5).fill({ status: 200, body: [] }));
841
+ storage.fetchCopayerLookup.callCount.should.equal(0);
842
+ done();
843
+ });
844
+ });
845
+
846
+ it('does not verify a copayer whose signature is not a string', function(done) {
847
+ post({
848
+ copayers: [
849
+ { copayerId: idA, signature: 1 },
850
+ { copayerId: idA, signature: [sign(idA)] },
851
+ { copayerId: idB, signature: {} },
852
+ { copayerId: idB }
853
+ ]
854
+ }, function(err, res, body) {
855
+ should.not.exist(err);
856
+ res.statusCode.should.equal(200);
857
+ body.should.deep.equal([]);
858
+ storage.fetchCopayerLookup.callCount.should.equal(4);
859
+ done();
860
+ });
861
+ });
862
+
863
+ it('treats a copayer that fails to load as not found', function(done) {
864
+ storage.fetchCopayerLookup.withArgs(idB).rejects(new Error('lookup failed'));
865
+ post({
866
+ copayers: [
867
+ { copayerId: idA, signature: sign(idA) },
868
+ { copayerId: idB, signature: sign(idB) }
869
+ ]
870
+ }, function(err, res, body) {
871
+ should.not.exist(err);
872
+ res.statusCode.should.equal(200);
873
+ body.should.deep.equal([idA]);
874
+ done();
875
+ });
876
+ });
877
+
878
+ it('looks up only copayer ids that are strings', function(done) {
879
+ post({
880
+ copayers: [
881
+ { copayerId: { id: idB }, signature: sign(idB) },
882
+ { copayerId: [idB], signature: sign(idB) },
883
+ { copayerId: 1, signature: sign(idB) },
884
+ { signature: sign(idB) },
885
+ { copayerId: idA, signature: sign(idA) }
886
+ ]
887
+ }, function(err, res, body) {
888
+ should.not.exist(err);
889
+ res.statusCode.should.equal(200);
890
+ body.should.deep.equal([idA]);
891
+ storage.fetchCopayerLookup.args.should.deep.equal([[idA]]);
892
+ done();
893
+ });
894
+ });
895
+
896
+ it('skips copayers that are not objects', function(done) {
897
+ post({
898
+ copayers: [null, idB, { copayerId: idA, signature: sign(idA) }]
899
+ }, function(err, res, body) {
900
+ should.not.exist(err);
901
+ res.statusCode.should.equal(200);
902
+ body.should.deep.equal([idA]);
903
+ storage.fetchCopayerLookup.args.should.deep.equal([[idA]]);
904
+ done();
905
+ });
906
+ });
907
+ });
908
+
765
909
  describe('Clear cache', function() {
766
910
  it('/v1/clearcache/', function(done) {
767
911
  const resolveStub = sinon.stub().callsFake( () => { return Promise.resolve(true);});