@bitpay-labs/bitcore-wallet-service 11.8.1 → 11.9.0

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 (101) hide show
  1. package/bws.example.config.js +4 -2
  2. package/package.json +4 -4
  3. package/src/bws.ts +2 -0
  4. package/src/config.ts +4 -2
  5. package/src/externalservices/moonpay.ts +85 -1
  6. package/src/lib/blockchainexplorers/v8.ts +1 -1
  7. package/src/lib/common/utils.ts +18 -5
  8. package/src/lib/expressapp.ts +63 -2378
  9. package/src/lib/model/txproposal.ts +14 -10
  10. package/src/lib/routes/advertisements.ts +151 -0
  11. package/src/lib/routes/blockchain.ts +151 -0
  12. package/src/lib/routes/context.ts +149 -0
  13. package/src/lib/routes/maintenance.ts +114 -0
  14. package/src/lib/routes/moralis.ts +89 -0
  15. package/src/lib/routes/notifications.ts +135 -0
  16. package/src/lib/routes/services.ts +540 -0
  17. package/src/lib/routes/setup.ts +86 -0
  18. package/src/lib/routes/transactions.ts +196 -0
  19. package/src/lib/routes/walletdata.ts +166 -0
  20. package/src/lib/routes/wallets.ts +288 -0
  21. package/src/lib/server.ts +24 -1
  22. package/src/lib/storage.ts +3 -0
  23. package/test/integration/externalservices/moonpay.test.ts +149 -0
  24. package/test/utils.test.ts +29 -0
  25. package/ts_build/package.json +4 -4
  26. package/ts_build/src/bws.js +3 -0
  27. package/ts_build/src/bws.js.map +1 -1
  28. package/ts_build/src/config.d.ts.map +1 -1
  29. package/ts_build/src/config.js.map +1 -1
  30. package/ts_build/src/externalservices/moonpay.d.ts +4 -0
  31. package/ts_build/src/externalservices/moonpay.d.ts.map +1 -1
  32. package/ts_build/src/externalservices/moonpay.js +68 -1
  33. package/ts_build/src/externalservices/moonpay.js.map +1 -1
  34. package/ts_build/src/lib/blockchainexplorers/v8.js +1 -1
  35. package/ts_build/src/lib/common/index.d.ts +1 -0
  36. package/ts_build/src/lib/common/index.d.ts.map +1 -1
  37. package/ts_build/src/lib/common/utils.d.ts +1 -0
  38. package/ts_build/src/lib/common/utils.d.ts.map +1 -1
  39. package/ts_build/src/lib/common/utils.js +20 -9
  40. package/ts_build/src/lib/common/utils.js.map +1 -1
  41. package/ts_build/src/lib/expressapp.d.ts.map +1 -1
  42. package/ts_build/src/lib/expressapp.js +64 -2224
  43. package/ts_build/src/lib/expressapp.js.map +1 -1
  44. package/ts_build/src/lib/model/txproposal.d.ts +1 -4
  45. package/ts_build/src/lib/model/txproposal.d.ts.map +1 -1
  46. package/ts_build/src/lib/model/txproposal.js +13 -9
  47. package/ts_build/src/lib/model/txproposal.js.map +1 -1
  48. package/ts_build/src/lib/routes/advertisements.d.ts +11 -0
  49. package/ts_build/src/lib/routes/advertisements.d.ts.map +1 -0
  50. package/ts_build/src/lib/routes/advertisements.js +119 -0
  51. package/ts_build/src/lib/routes/advertisements.js.map +1 -0
  52. package/ts_build/src/lib/routes/blockchain.d.ts +13 -0
  53. package/ts_build/src/lib/routes/blockchain.d.ts.map +1 -0
  54. package/ts_build/src/lib/routes/blockchain.js +125 -0
  55. package/ts_build/src/lib/routes/blockchain.js.map +1 -0
  56. package/ts_build/src/lib/routes/context.d.ts +12 -0
  57. package/ts_build/src/lib/routes/context.d.ts.map +1 -0
  58. package/ts_build/src/lib/routes/context.js +115 -0
  59. package/ts_build/src/lib/routes/context.js.map +1 -0
  60. package/ts_build/src/lib/routes/maintenance.d.ts +10 -0
  61. package/ts_build/src/lib/routes/maintenance.d.ts.map +1 -0
  62. package/ts_build/src/lib/routes/maintenance.js +101 -0
  63. package/ts_build/src/lib/routes/maintenance.js.map +1 -0
  64. package/ts_build/src/lib/routes/moralis.d.ts +9 -0
  65. package/ts_build/src/lib/routes/moralis.d.ts.map +1 -0
  66. package/ts_build/src/lib/routes/moralis.js +78 -0
  67. package/ts_build/src/lib/routes/moralis.js.map +1 -0
  68. package/ts_build/src/lib/routes/notifications.d.ts +10 -0
  69. package/ts_build/src/lib/routes/notifications.d.ts.map +1 -0
  70. package/ts_build/src/lib/routes/notifications.js +120 -0
  71. package/ts_build/src/lib/routes/notifications.js.map +1 -0
  72. package/ts_build/src/lib/routes/services.d.ts +11 -0
  73. package/ts_build/src/lib/routes/services.d.ts.map +1 -0
  74. package/ts_build/src/lib/routes/services.js +440 -0
  75. package/ts_build/src/lib/routes/services.js.map +1 -0
  76. package/ts_build/src/lib/routes/setup.d.ts +4 -0
  77. package/ts_build/src/lib/routes/setup.d.ts.map +1 -0
  78. package/ts_build/src/lib/routes/setup.js +79 -0
  79. package/ts_build/src/lib/routes/setup.js.map +1 -0
  80. package/ts_build/src/lib/routes/transactions.d.ts +9 -0
  81. package/ts_build/src/lib/routes/transactions.d.ts.map +1 -0
  82. package/ts_build/src/lib/routes/transactions.js +188 -0
  83. package/ts_build/src/lib/routes/transactions.js.map +1 -0
  84. package/ts_build/src/lib/routes/walletdata.d.ts +10 -0
  85. package/ts_build/src/lib/routes/walletdata.d.ts.map +1 -0
  86. package/ts_build/src/lib/routes/walletdata.js +152 -0
  87. package/ts_build/src/lib/routes/walletdata.js.map +1 -0
  88. package/ts_build/src/lib/routes/wallets.d.ts +13 -0
  89. package/ts_build/src/lib/routes/wallets.d.ts.map +1 -0
  90. package/ts_build/src/lib/routes/wallets.js +291 -0
  91. package/ts_build/src/lib/routes/wallets.js.map +1 -0
  92. package/ts_build/src/lib/server.d.ts.map +1 -1
  93. package/ts_build/src/lib/server.js +19 -1
  94. package/ts_build/src/lib/server.js.map +1 -1
  95. package/ts_build/src/lib/storage.d.ts.map +1 -1
  96. package/ts_build/src/lib/storage.js +3 -0
  97. package/ts_build/src/lib/storage.js.map +1 -1
  98. package/ts_build/test/integration/externalservices/moonpay.test.js +139 -0
  99. package/ts_build/test/integration/externalservices/moonpay.test.js.map +1 -1
  100. package/ts_build/test/utils.test.js +23 -0
  101. package/ts_build/test/utils.test.js.map +1 -1
@@ -0,0 +1,86 @@
1
+ import compression from 'compression';
2
+ import express from 'express';
3
+ import RateLimit from 'express-rate-limit';
4
+ import config from '../../config';
5
+ import { Common } from '../common';
6
+ import { logger, transports } from '../logger';
7
+ import { WalletService } from '../server';
8
+ import { LogMiddleware } from './middleware/log';
9
+
10
+ const Defaults = Common.Defaults;
11
+
12
+ export function setupAppMiddleware(app: express.Express, opts) {
13
+ app.use(compression());
14
+
15
+ app.use((req, res, next) => {
16
+ res.setHeader('Access-Control-Allow-Origin', '*');
17
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
18
+ res.setHeader(
19
+ 'Access-Control-Allow-Headers',
20
+ 'x-signature,x-identity,x-identities,x-session,x-client-version,x-wallet-id,X-Requested-With,Content-Type,Authorization'
21
+ );
22
+ res.setHeader('x-service-version', WalletService.getServiceVersion());
23
+ next();
24
+ });
25
+
26
+ app.use((req, res, next) => {
27
+ if ('OPTIONS' == req.method) {
28
+ res.sendStatus(200);
29
+ res.end();
30
+ return;
31
+ }
32
+ next();
33
+ });
34
+
35
+ app.enable('trust proxy');
36
+
37
+ app.use((req, res, next) => {
38
+ req.on('abort', () => {
39
+ logger.warn('Request aborted by the client');
40
+ });
41
+ next();
42
+ });
43
+
44
+ const POST_LIMIT = 1024 * 100;
45
+ const POST_LIMIT_LARGE = 2 * 1024 * 1024;
46
+
47
+ app.use((req, res, next) => {
48
+ if (req.path.includes('/txproposals') || req.path.includes('/tss/')) {
49
+ return express.json({ limit: POST_LIMIT_LARGE })(req, res, next);
50
+ } else {
51
+ return express.json({ limit: POST_LIMIT })(req, res, next);
52
+ }
53
+ });
54
+
55
+ app.use((req, res, next) => {
56
+ if (config.maintenanceOpts.maintenanceMode === true) {
57
+ const errorCode = 503;
58
+ const errorMessage = 'BWS down for maintenance';
59
+ res.status(503).send({ code: errorCode, message: errorMessage });
60
+ } else {
61
+ next();
62
+ }
63
+ });
64
+
65
+ if (opts.disableLogs) {
66
+ for (const transport of transports) {
67
+ transport.level = 'error';
68
+ }
69
+ } else {
70
+ app.use(LogMiddleware());
71
+ }
72
+ }
73
+
74
+ export function createEstimateFeeLimiter(opts) {
75
+ if (Defaults.RateLimit.estimateFee && !opts.ignoreRateLimiter) {
76
+ logger.info(
77
+ 'Limiting estimate fee per IP: %o req/h',
78
+ ((Defaults.RateLimit.estimateFee.max / Defaults.RateLimit.estimateFee.windowMs) * 60 * 60 * 1000).toFixed(2)
79
+ );
80
+ return new RateLimit(Defaults.RateLimit.estimateFee);
81
+ }
82
+
83
+ return (req, res, next) => {
84
+ next();
85
+ };
86
+ }
@@ -0,0 +1,196 @@
1
+ import express from 'express';
2
+ import { Errors } from '../errors/errordefinitions';
3
+ import type * as Types from '../../types/expressapp';
4
+
5
+ interface RouteContext {
6
+ getServerWithAuth: Types.GetServerWithAuthFn;
7
+ returnError: Types.ReturnErrorFn;
8
+ }
9
+
10
+ export function registerTransactionRoutes(router: express.Router, context: RouteContext) {
11
+ const { getServerWithAuth, returnError } = context;
12
+
13
+ router.get('/v1/txproposals/', (req, res) => {
14
+ getServerWithAuth(req, res, server => {
15
+ server.getPendingTxs({ noCashAddr: true }, (err, pendings) => {
16
+ if (err) return returnError(err, res, req);
17
+ res.json(pendings);
18
+ });
19
+ });
20
+ });
21
+
22
+ router.get('/v2/txproposals/', (req, res) => {
23
+ getServerWithAuth(req, res, server => {
24
+ server.getPendingTxs({}, (err, pendings) => {
25
+ if (err) return returnError(err, res, req);
26
+ res.json(pendings);
27
+ });
28
+ });
29
+ });
30
+
31
+ router.post('/v1/txproposals/', (req, res) => {
32
+ return returnError(Errors.UPGRADE_NEEDED, res, req);
33
+ });
34
+
35
+ router.post('/v2/txproposals/', (req, res) => {
36
+ getServerWithAuth(req, res, server => {
37
+ req.body.noCashAddr = true;
38
+ req.body.txpVersion = 3;
39
+ server.createTx(req.body, (err, txp) => {
40
+ if (err) return returnError(err, res, req);
41
+ res.json(txp);
42
+ });
43
+ });
44
+ });
45
+
46
+ router.post('/v3/txproposals/', (req, res) => {
47
+ getServerWithAuth(req, res, server => {
48
+ req.body.txpVersion = 3;
49
+ server.createTx(req.body, (err, txp) => {
50
+ if (err) return returnError(err, res, req);
51
+ res.json(txp);
52
+ });
53
+ });
54
+ });
55
+
56
+ router.post('/v1/txproposals/:id/signatures/', (req, res) => {
57
+ getServerWithAuth(req, res, server => {
58
+ req.body.maxTxpVersion = 3;
59
+ req.body.txProposalId = req.params['id'];
60
+ server.signTx(req.body, (err, txp) => {
61
+ if (err) return returnError(err, res, req);
62
+ res.json(txp);
63
+ res.end();
64
+ });
65
+ });
66
+ });
67
+
68
+ router.post('/v2/txproposals/:id/signatures/', (req, res) => {
69
+ getServerWithAuth(req, res, server => {
70
+ req.body.txProposalId = req.params['id'];
71
+ req.body.maxTxpVersion = 3;
72
+ req.body.supportBchSchnorr = true;
73
+ server.signTx(req.body, (err, txp) => {
74
+ if (err) return returnError(err, res, req);
75
+ res.json(txp);
76
+ res.end();
77
+ });
78
+ });
79
+ });
80
+
81
+ router.post('/v1/txproposals/:id/prepare/', (req, res) => {
82
+ getServerWithAuth(req, res, server => {
83
+ req.body.txProposalId = req.params['id'];
84
+ server.prepareTx(req.body, (err, txp) => {
85
+ if (err) return returnError(err, res, req);
86
+ res.json(txp);
87
+ res.end();
88
+ });
89
+ });
90
+ });
91
+
92
+ router.post('/v1/txproposals/:id/publish/', (req, res) => {
93
+ getServerWithAuth(req, res, server => {
94
+ req.body.txProposalId = req.params['id'];
95
+ req.body.noCashAddr = true;
96
+ server.publishTx(req.body, (err, txp) => {
97
+ if (err) return returnError(err, res, req);
98
+ res.json(txp);
99
+ res.end();
100
+ });
101
+ });
102
+ });
103
+
104
+ router.post('/v2/txproposals/:id/publish/', (req, res) => {
105
+ getServerWithAuth(req, res, server => {
106
+ req.body.txProposalId = req.params['id'];
107
+ server.publishTx(req.body, (err, txp) => {
108
+ if (err) return returnError(err, res, req);
109
+ res.json(txp);
110
+ res.end();
111
+ });
112
+ });
113
+ });
114
+
115
+ router.post('/v1/txproposals/:id/broadcast/', (req, res) => {
116
+ getServerWithAuth(req, res, server => {
117
+ req.body.txProposalId = req.params['id'];
118
+ server.broadcastTx(req.body, (err, txp) => {
119
+ if (err) return returnError(err, res, req);
120
+ res.json(txp);
121
+ res.end();
122
+ });
123
+ });
124
+ });
125
+
126
+ router.post('/v1/txproposals/:id/rejections', (req, res) => {
127
+ getServerWithAuth(req, res, server => {
128
+ req.body.txProposalId = req.params['id'];
129
+ server.rejectTx(req.body, (err, txp) => {
130
+ if (err) return returnError(err, res, req);
131
+ res.json(txp);
132
+ res.end();
133
+ });
134
+ });
135
+ });
136
+
137
+ router.delete('/v1/txproposals/:id/', (req, res) => {
138
+ getServerWithAuth(req, res, server => {
139
+ req.body.txProposalId = req.params['id'];
140
+ server.removePendingTx(req.body, err => {
141
+ if (err) return returnError(err, res, req);
142
+ res.json({ success: true });
143
+ res.end();
144
+ });
145
+ });
146
+ });
147
+
148
+ router.get('/v1/txproposals/:id/', (req, res) => {
149
+ getServerWithAuth(req, res, server => {
150
+ req.body.txProposalId = req.params['id'];
151
+ server.getTx(req.body, (err, tx) => {
152
+ if (err) return returnError(err, res, req);
153
+ res.json(tx);
154
+ res.end();
155
+ });
156
+ });
157
+ });
158
+
159
+ router.get('/v1/txproposalsbyhash/:id/', (req, res) => {
160
+ getServerWithAuth(req, res, server => {
161
+ req.body.txid = req.params['id'];
162
+ server.getTxByHash(req.body, (err, tx) => {
163
+ if (err) return returnError(err, res, req);
164
+ res.json(tx);
165
+ res.end();
166
+ });
167
+ });
168
+ });
169
+
170
+ router.get('/v1/txhistory/', (req, res) => {
171
+ getServerWithAuth(req, res, server => {
172
+ const opts: {
173
+ skip?: number;
174
+ limit?: number;
175
+ reverse?: boolean;
176
+ includeExtendedInfo?: boolean;
177
+ tokenAddress?: string;
178
+ multisigContractAddress?: string;
179
+ } = {};
180
+ if (req.query.skip) opts.skip = +req.query.skip;
181
+ if (req.query.limit) opts.limit = +req.query.limit;
182
+ if (req.query.reverse == '1') opts.reverse = true;
183
+ if (req.query.tokenAddress) opts.tokenAddress = req.query.tokenAddress as string;
184
+ if (req.query.multisigContractAddress) {
185
+ opts.multisigContractAddress = req.query.multisigContractAddress as string;
186
+ }
187
+ if (req.query.includeExtendedInfo == '1') opts.includeExtendedInfo = true;
188
+
189
+ server.getTxHistory(opts, (err, txs) => {
190
+ if (err) return returnError(err, res, req);
191
+ res.json(txs);
192
+ res.end();
193
+ });
194
+ });
195
+ });
196
+ }
@@ -0,0 +1,166 @@
1
+ import express from 'express';
2
+ import { Common } from '../common';
3
+ import type * as Types from '../../types/expressapp';
4
+ import type { GetAddressesOpts } from '../../types/server';
5
+
6
+ const Utils = Common.Utils;
7
+
8
+ interface RouteContext {
9
+ getServerWithAuth: Types.GetServerWithAuthFn;
10
+ logDeprecated: Types.LogDeprecatedFn;
11
+ returnError: Types.ReturnErrorFn;
12
+ }
13
+
14
+ export function registerWalletDataRoutes(router: express.Router, context: RouteContext) {
15
+ const { getServerWithAuth, logDeprecated, returnError } = context;
16
+
17
+ router.post('/v1/addresses/', (req, res) => {
18
+ logDeprecated(req);
19
+ getServerWithAuth(req, res, server => {
20
+ server.createAddress(
21
+ {
22
+ ignoreMaxGap: true
23
+ },
24
+ (err, address) => {
25
+ if (err) return returnError(err, res, req);
26
+ res.json(address);
27
+ }
28
+ );
29
+ });
30
+ });
31
+
32
+ router.post('/v2/addresses/', (req, res) => {
33
+ logDeprecated(req);
34
+ getServerWithAuth(req, res, server => {
35
+ server.createAddress(
36
+ {
37
+ ignoreMaxGap: true
38
+ },
39
+ (err, address) => {
40
+ if (err) return returnError(err, res, req);
41
+ res.json(address);
42
+ }
43
+ );
44
+ });
45
+ });
46
+
47
+ router.post('/v3/addresses/', (req, res) => {
48
+ getServerWithAuth(req, res, server => {
49
+ let opts = req.body;
50
+ opts = opts || {};
51
+ opts.noCashAddr = true;
52
+ server.createAddress(opts, (err, address) => {
53
+ if (err) return returnError(err, res, req);
54
+ res.json(address);
55
+ });
56
+ });
57
+ });
58
+
59
+ router.post('/v4/addresses/', (req, res) => {
60
+ getServerWithAuth(req, res, server => {
61
+ server.createAddress(req.body, (err, address) => {
62
+ if (err) return returnError(err, res, req);
63
+ res.json(address);
64
+ });
65
+ });
66
+ });
67
+
68
+ router.get('/v1/addresses/', (req, res) => {
69
+ logDeprecated(req);
70
+ req.query.noChange = req.query.noChange ?? '1';
71
+ req.redirectedUrl = req.url;
72
+ req.url = '/v2/addresses?' + Object.entries(req.query).map(([key, value]) => `${key}=${value}`).join('&');
73
+ router.handle(req, res);
74
+ });
75
+
76
+ router.get('/v2/addresses/', (req, res) => {
77
+ getServerWithAuth(req, res, server => {
78
+ const opts: GetAddressesOpts = {};
79
+ if (req.query.limit) opts.limit = +req.query.limit;
80
+ if (req.query.skip) opts.skip = +req.query.skip;
81
+ opts.reverse = req.query.reverse == '1';
82
+ if (req.query.addresses) {
83
+ opts.addresses = Array.isArray(req.query.addresses) ? req.query.addresses : req.query.addresses.split(',');
84
+ }
85
+ opts.noChange = Utils.castToBool(req.query.noChange);
86
+
87
+ server.getAddresses(opts, (err, addresses) => {
88
+ if (err) return returnError(err, res, req);
89
+ res.json(addresses);
90
+ });
91
+ });
92
+ });
93
+
94
+ router.get('/v1/balance/', (req, res) => {
95
+ getServerWithAuth(req, res, server => {
96
+ const opts: { coin?: string; twoStep?: boolean; tokenAddress?: string; multisigContractAddress?: string } = {};
97
+ if (req.query.coin) opts.coin = req.query.coin as string;
98
+ if (req.query.twoStep == '1') opts.twoStep = true;
99
+ if (req.query.tokenAddress) opts.tokenAddress = req.query.tokenAddress as string;
100
+ if (req.query.multisigContractAddress) {
101
+ opts.multisigContractAddress = req.query.multisigContractAddress as string;
102
+ }
103
+
104
+ server.getBalance(opts, (err, balance) => {
105
+ if (err) return returnError(err, res, req);
106
+ res.json(balance);
107
+ });
108
+ });
109
+ });
110
+
111
+ router.get('/v1/sendmaxinfo/', (req, res) => {
112
+ getServerWithAuth(req, res, server => {
113
+ const query = req.query;
114
+ const opts: {
115
+ feePerKb?: number;
116
+ feeLevel?: number;
117
+ returnInputs?: boolean;
118
+ excludeUnconfirmedUtxos?: boolean;
119
+ } = {};
120
+ if (query.feePerKb) opts.feePerKb = +query.feePerKb;
121
+ if (query.feeLevel) opts.feeLevel = Number(query.feeLevel);
122
+ if (query.excludeUnconfirmedUtxos == '1') opts.excludeUnconfirmedUtxos = true;
123
+ if (query.returnInputs == '1') opts.returnInputs = true;
124
+
125
+ server.getSendMaxInfo(opts, (err, info) => {
126
+ if (err) return returnError(err, res, req);
127
+ res.json(info);
128
+ });
129
+ });
130
+ });
131
+
132
+ router.get('/v1/utxos/', (req, res) => {
133
+ const opts: { addresses?: string[] } = {};
134
+ const addresses = req.query.addresses;
135
+ if (addresses && typeof addresses === 'string') {
136
+ opts.addresses = (req.query.addresses as string).split(',');
137
+ }
138
+
139
+ getServerWithAuth(req, res, server => {
140
+ server.getUtxos(opts, (err, utxos) => {
141
+ if (err) return returnError(err, res, req);
142
+ res.json(utxos);
143
+ });
144
+ });
145
+ });
146
+
147
+ router.get('/v1/txcoins/', (req, res) => {
148
+ const txId = req.query.txId;
149
+ getServerWithAuth(req, res, server => {
150
+ server.getCoinsForTx({ txId }, (err, coins) => {
151
+ if (err) return returnError(err, res, req);
152
+ res.json(coins);
153
+ });
154
+ });
155
+ });
156
+
157
+ router.post('/v1/broadcast_raw/', (req, res) => {
158
+ getServerWithAuth(req, res, server => {
159
+ server.broadcastRawTx(req.body, (err, txid) => {
160
+ if (err) return returnError(err, res, req);
161
+ res.json(txid);
162
+ res.end();
163
+ });
164
+ });
165
+ });
166
+ }