@bitpay-labs/bitcore-wallet-service 11.10.6 → 11.10.8

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 (103) hide show
  1. package/package.json +3 -3
  2. package/src/externalservices/coingecko.ts +24 -10
  3. package/src/externalservices/moonpay.ts +23 -1
  4. package/src/externalservices/transak.ts +25 -3
  5. package/src/lib/chain/doge/index.ts +1 -1
  6. package/src/lib/chain/eth/abi-invoice.ts +139 -90
  7. package/src/lib/common/constants.ts +5 -2
  8. package/src/lib/common/defaults.ts +11 -2
  9. package/src/lib/errors/errordefinitions.ts +6 -0
  10. package/src/lib/model/copayer.ts +1 -0
  11. package/src/lib/model/tsskeygen.ts +33 -4
  12. package/src/lib/model/tsssign.ts +34 -3
  13. package/src/lib/pushnotificationsservice.ts +3 -1
  14. package/src/lib/routes/middleware/authTssRequest.ts +10 -4
  15. package/src/lib/routes/middleware/verifyTssMessage.ts +13 -8
  16. package/src/lib/routes/tss.ts +11 -4
  17. package/src/lib/server.ts +54 -25
  18. package/src/lib/storage.ts +24 -1
  19. package/src/lib/tss.ts +232 -30
  20. package/src/types/externalservices.d.ts +29 -1
  21. package/test/integration/externalservices/coinGecko.test.ts +71 -7
  22. package/test/integration/externalservices/transak.test.ts +84 -0
  23. package/test/integration/server.test.ts +780 -1
  24. package/test/integration/tss.test.ts +275 -0
  25. package/test/model/copayer.test.ts +128 -0
  26. package/test/storage.test.ts +91 -0
  27. package/ts_build/package.json +1 -1
  28. package/ts_build/src/externalservices/coingecko.d.ts.map +1 -1
  29. package/ts_build/src/externalservices/coingecko.js +14 -8
  30. package/ts_build/src/externalservices/coingecko.js.map +1 -1
  31. package/ts_build/src/externalservices/moonpay.d.ts.map +1 -1
  32. package/ts_build/src/externalservices/moonpay.js +38 -2
  33. package/ts_build/src/externalservices/moonpay.js.map +1 -1
  34. package/ts_build/src/externalservices/transak.d.ts +1 -0
  35. package/ts_build/src/externalservices/transak.d.ts.map +1 -1
  36. package/ts_build/src/externalservices/transak.js +15 -3
  37. package/ts_build/src/externalservices/transak.js.map +1 -1
  38. package/ts_build/src/lib/chain/doge/index.js +1 -1
  39. package/ts_build/src/lib/chain/doge/index.js.map +1 -1
  40. package/ts_build/src/lib/chain/eth/abi-invoice.d.ts +254 -41
  41. package/ts_build/src/lib/chain/eth/abi-invoice.d.ts.map +1 -1
  42. package/ts_build/src/lib/chain/eth/abi-invoice.js +138 -89
  43. package/ts_build/src/lib/chain/eth/abi-invoice.js.map +1 -1
  44. package/ts_build/src/lib/common/constants.d.ts +4 -2
  45. package/ts_build/src/lib/common/constants.d.ts.map +1 -1
  46. package/ts_build/src/lib/common/constants.js +4 -2
  47. package/ts_build/src/lib/common/constants.js.map +1 -1
  48. package/ts_build/src/lib/common/defaults.d.ts +4 -2
  49. package/ts_build/src/lib/common/defaults.d.ts.map +1 -1
  50. package/ts_build/src/lib/common/defaults.js +4 -2
  51. package/ts_build/src/lib/common/defaults.js.map +1 -1
  52. package/ts_build/src/lib/common/index.d.ts +8 -4
  53. package/ts_build/src/lib/common/index.d.ts.map +1 -1
  54. package/ts_build/src/lib/errors/errordefinitions.d.ts +3 -0
  55. package/ts_build/src/lib/errors/errordefinitions.d.ts.map +1 -1
  56. package/ts_build/src/lib/errors/errordefinitions.js +3 -0
  57. package/ts_build/src/lib/errors/errordefinitions.js.map +1 -1
  58. package/ts_build/src/lib/model/copayer.d.ts.map +1 -1
  59. package/ts_build/src/lib/model/copayer.js +1 -0
  60. package/ts_build/src/lib/model/copayer.js.map +1 -1
  61. package/ts_build/src/lib/model/tsskeygen.d.ts +3 -0
  62. package/ts_build/src/lib/model/tsskeygen.d.ts.map +1 -1
  63. package/ts_build/src/lib/model/tsskeygen.js +12 -3
  64. package/ts_build/src/lib/model/tsskeygen.js.map +1 -1
  65. package/ts_build/src/lib/model/tsssign.d.ts +7 -0
  66. package/ts_build/src/lib/model/tsssign.d.ts.map +1 -1
  67. package/ts_build/src/lib/model/tsssign.js +22 -2
  68. package/ts_build/src/lib/model/tsssign.js.map +1 -1
  69. package/ts_build/src/lib/pushnotificationsservice.d.ts.map +1 -1
  70. package/ts_build/src/lib/pushnotificationsservice.js +3 -1
  71. package/ts_build/src/lib/pushnotificationsservice.js.map +1 -1
  72. package/ts_build/src/lib/routes/middleware/authTssRequest.d.ts.map +1 -1
  73. package/ts_build/src/lib/routes/middleware/authTssRequest.js +8 -2
  74. package/ts_build/src/lib/routes/middleware/authTssRequest.js.map +1 -1
  75. package/ts_build/src/lib/routes/middleware/verifyTssMessage.d.ts.map +1 -1
  76. package/ts_build/src/lib/routes/middleware/verifyTssMessage.js +11 -6
  77. package/ts_build/src/lib/routes/middleware/verifyTssMessage.js.map +1 -1
  78. package/ts_build/src/lib/routes/tss.d.ts.map +1 -1
  79. package/ts_build/src/lib/routes/tss.js +4 -4
  80. package/ts_build/src/lib/routes/tss.js.map +1 -1
  81. package/ts_build/src/lib/server.d.ts.map +1 -1
  82. package/ts_build/src/lib/server.js +34 -25
  83. package/ts_build/src/lib/server.js.map +1 -1
  84. package/ts_build/src/lib/storage.d.ts +4 -0
  85. package/ts_build/src/lib/storage.d.ts.map +1 -1
  86. package/ts_build/src/lib/storage.js +18 -1
  87. package/ts_build/src/lib/storage.js.map +1 -1
  88. package/ts_build/src/lib/tss.d.ts +4 -0
  89. package/ts_build/src/lib/tss.d.ts.map +1 -1
  90. package/ts_build/src/lib/tss.js +74 -17
  91. package/ts_build/src/lib/tss.js.map +1 -1
  92. package/ts_build/test/integration/externalservices/coinGecko.test.js +62 -8
  93. package/ts_build/test/integration/externalservices/coinGecko.test.js.map +1 -1
  94. package/ts_build/test/integration/externalservices/transak.test.js +78 -0
  95. package/ts_build/test/integration/externalservices/transak.test.js.map +1 -1
  96. package/ts_build/test/integration/server.test.js +640 -0
  97. package/ts_build/test/integration/server.test.js.map +1 -1
  98. package/ts_build/test/integration/tss.test.js +245 -0
  99. package/ts_build/test/integration/tss.test.js.map +1 -1
  100. package/ts_build/test/model/copayer.test.js +91 -0
  101. package/ts_build/test/model/copayer.test.js.map +1 -1
  102. package/ts_build/test/storage.test.js +73 -0
  103. package/ts_build/test/storage.test.js.map +1 -1
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@bitpay-labs/bitcore-wallet-service",
3
3
  "description": "A service for Mutisig HD Bitcoin Wallets",
4
4
  "author": "BitPay Inc",
5
- "version": "11.10.6",
5
+ "version": "11.10.8",
6
6
  "license": "MIT",
7
7
  "main": "ts_build/src/index.js",
8
8
  "types": "./ts_build/src/index.d.ts",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@bitpay-labs/bitcore-logging": "^11.10.4",
45
- "@bitpay-labs/bitcore-tss": "^11.10.4",
45
+ "@bitpay-labs/bitcore-tss": "^11.10.8",
46
46
  "@bitpay-labs/crypto-wallet-core": "^11.10.4",
47
47
  "@sendgrid/mail": "6.5.4",
48
48
  "abi-decoder": "2.4.0",
@@ -107,5 +107,5 @@
107
107
  "email": "kjoseph@bitpay.com"
108
108
  }
109
109
  ],
110
- "gitHead": "68cba09ab40e3e91528cae682333303c08b3f565"
110
+ "gitHead": "c22ec6ab93ac3d455bfd76421509ecfa7b0aab1c"
111
111
  }
@@ -36,8 +36,13 @@ type CoinGeckoRequest = Pick<Request, 'params' | 'query'>;
36
36
 
37
37
  const SUPPORTED_FIAT_CODES = new Set<string>(Defaults.FIAT_CURRENCIES.map(f => f.code));
38
38
 
39
- const ALLOWED_DAYS = new Set([1, 7, 30, 90, 365, 1825]);
40
- const DEFAULT_ALL_TIME_DAYS = 100000;
39
+ const ALLOWED_NUMERIC_DAYS = new Set([1, 7, 30, 90, 365, 1825]);
40
+
41
+ // CoinGecko's documented all-time value for `market_chart` is the literal string `max`
42
+ const ALL_TIME_DAYS = 'max';
43
+
44
+ type FiatRateNumericDays = 1 | 7 | 30 | 90 | 365 | 1825;
45
+ type FiatRateDays = FiatRateNumericDays | typeof ALL_TIME_DAYS;
41
46
 
42
47
  const MAX_QUERY_PARAM_LENGTH = 64;
43
48
  const CHAIN_PARAM_PATTERN = /^[a-z0-9-_]+$/i;
@@ -122,6 +127,16 @@ function validateQueryParam(query: Record<string, unknown> | undefined, key: str
122
127
  }
123
128
  }
124
129
 
130
+ function isAllowedNumericDays(value: number): value is FiatRateNumericDays {
131
+ return ALLOWED_NUMERIC_DAYS.has(value);
132
+ }
133
+
134
+ function parseFiatRateNumericDays(raw: string): FiatRateNumericDays {
135
+ const parsed = +raw;
136
+ if (!isAllowedNumericDays(parsed)) throw badRequest('Invalid days');
137
+ return parsed;
138
+ }
139
+
125
140
  function parseCoinChainTokenAddress(
126
141
  query: Record<string, unknown> | undefined
127
142
  ): { coin?: string; chain?: string; tokenAddress?: string } {
@@ -320,12 +335,12 @@ export class CoinGeckoService {
320
335
  throw badRequest('Unsupported coin. For token symbols, pass `chain` and `tokenAddress`.');
321
336
  }
322
337
 
323
- private async fetchFiatRatesForId(id: string, vsCurrency: string, days: number): Promise<FiatRatePoint[]> {
338
+ private async fetchFiatRatesForId(id: string, vsCurrency: string, days: FiatRateDays): Promise<FiatRatePoint[]> {
324
339
  const { API_KEY } = this.coinGeckoGetCredentials();
325
340
  const headers = this.coinGeckoGetHeaders(API_KEY);
326
341
 
327
- const params: any = { vs_currency: vsCurrency, days };
328
- if (days >= 90) params.interval = 'daily';
342
+ const params: Record<string, string | number | boolean | undefined> = { vs_currency: vsCurrency, days };
343
+ if (days === ALL_TIME_DAYS || days >= 90) params.interval = 'daily';
329
344
 
330
345
  const url = this.cgUrl(`/v3/coins/${encodeURIComponent(id)}/market_chart`, params);
331
346
  const body = await this.coinGeckoGetJson(url, headers);
@@ -341,7 +356,7 @@ export class CoinGeckoService {
341
356
  private async getFiatRatesForId(
342
357
  id: string,
343
358
  vsCurrency: string,
344
- days: number,
359
+ days: FiatRateDays,
345
360
  useDbCache: boolean
346
361
  ): Promise<FiatRatePoint[]> {
347
362
  if (!useDbCache) return this.fetchFiatRatesForId(id, vsCurrency, days);
@@ -465,13 +480,12 @@ export class CoinGeckoService {
465
480
 
466
481
  const { coin: coinParam, chain: chainParam, tokenAddress: tokenAddressParam } = parseCoinChainTokenAddress(req.query);
467
482
 
468
- let days = DEFAULT_ALL_TIME_DAYS;
483
+ // An omitted `days` means ALL-time history.
484
+ let days: FiatRateDays = ALL_TIME_DAYS;
469
485
  try {
470
486
  const daysParam = getQueryString(req.query, 'days');
471
487
  if (daysParam !== undefined) {
472
- const parsed = +daysParam;
473
- if (!ALLOWED_DAYS.has(parsed)) throw badRequest('Invalid days');
474
- days = parsed;
488
+ days = parseFiatRateNumericDays(daysParam);
475
489
  }
476
490
  } catch {
477
491
  throw badRequest('Invalid days');
@@ -218,14 +218,32 @@ export class MoonpayService {
218
218
  qs.push('baseCurrencyAmount=' + encodeURIComponent(req.body.baseCurrencyAmount));
219
219
  qs.push('externalTransactionId=' + encodeURIComponent(req.body.externalTransactionId));
220
220
  qs.push('redirectURL=' + encodeURIComponent(req.body.redirectURL));
221
+ if (req.body.defaultCurrencyCode) qs.push('defaultCurrencyCode=' + encodeURIComponent(req.body.defaultCurrencyCode));
222
+ if (req.body.walletAddressTag) qs.push('walletAddressTag=' + encodeURIComponent(req.body.walletAddressTag));
223
+ if (req.body.walletAddresses) qs.push('walletAddresses=' + encodeURIComponent(req.body.walletAddresses));
224
+ if (req.body.walletAddressTags) qs.push('walletAddressTags=' + encodeURIComponent(req.body.walletAddressTags));
221
225
  if (req.body.lockAmount) qs.push('lockAmount=' + encodeURIComponent(req.body.lockAmount));
222
226
  if (req.body.colorCode) qs.push('colorCode=' + encodeURIComponent(req.body.colorCode));
223
227
  if (req.body.theme) qs.push('theme=' + encodeURIComponent(req.body.theme));
228
+ if (req.body.themeId) qs.push('themeId=' + encodeURIComponent(req.body.themeId));
224
229
  if (req.body.language) qs.push('language=' + encodeURIComponent(req.body.language));
230
+ if (req.body.quoteCurrencyAmount) qs.push('quoteCurrencyAmount=' + encodeURIComponent(req.body.quoteCurrencyAmount));
231
+ if (req.body.email) qs.push('email=' + encodeURIComponent(req.body.email));
232
+ if (req.body.externalCustomerId) qs.push('externalCustomerId=' + encodeURIComponent(req.body.externalCustomerId));
225
233
  if (req.body.showWalletAddressForm)
226
234
  qs.push('showWalletAddressForm=' + encodeURIComponent(req.body.showWalletAddressForm));
227
235
  if (req.body.paymentMethod) qs.push('paymentMethod=' + encodeURIComponent(req.body.paymentMethod));
228
236
  if (req.body.areFeesIncluded) qs.push('areFeesIncluded=' + encodeURIComponent(req.body.areFeesIncluded));
237
+ if (req.body.showAllCurrencies) qs.push('showAllCurrencies=' + encodeURIComponent(req.body.showAllCurrencies));
238
+ if (req.body.showOnlyCurrencies) qs.push('showOnlyCurrencies=' + encodeURIComponent(req.body.showOnlyCurrencies));
239
+ if (req.body.unsupportedRegionRedirectUrl)
240
+ qs.push('unsupportedRegionRedirectUrl=' + encodeURIComponent(req.body.unsupportedRegionRedirectUrl));
241
+ if (req.body.skipUnsupportedRegionScreen)
242
+ qs.push('skipUnsupportedRegionScreen=' + encodeURIComponent(req.body.skipUnsupportedRegionScreen));
243
+
244
+ // Only supported for DeFi Buy integrations
245
+ if (req.body.contractAddress) qs.push('contractAddress=' + encodeURIComponent(req.body.contractAddress));
246
+ if (req.body.networkCode) qs.push('networkCode=' + encodeURIComponent(req.body.networkCode));
229
247
 
230
248
  // Web requests are proxied through the bitpay backend, so the IP on this
231
249
  // request belongs to that server, not the customer. The proxy captures the
@@ -286,16 +304,20 @@ export class MoonpayService {
286
304
  qs.push('externalTransactionId=' + encodeURIComponent(req.body.externalTransactionId));
287
305
  qs.push('redirectURL=' + encodeURIComponent(req.body.redirectURL));
288
306
 
307
+ if (req.body.defaultBaseCurrencyCode) qs.push('defaultBaseCurrencyCode=' + encodeURIComponent(req.body.defaultBaseCurrencyCode));
289
308
  if (req.body.quoteCurrencyCode) qs.push('quoteCurrencyCode=' + encodeURIComponent(req.body.quoteCurrencyCode));
309
+ if (req.body.quoteCurrencyAmount) qs.push('quoteCurrencyAmount=' + encodeURIComponent(req.body.quoteCurrencyAmount));
290
310
  if (req.body.paymentMethod) qs.push('paymentMethod=' + encodeURIComponent(req.body.paymentMethod));
291
311
  if (req.body.externalCustomerId) qs.push('externalCustomerId=' + encodeURIComponent(req.body.externalCustomerId));
292
312
  if (req.body.refundWalletAddress) qs.push('refundWalletAddress=' + encodeURIComponent(req.body.refundWalletAddress));
313
+ if (req.body.refundWalletAddresses) qs.push('refundWalletAddresses=' + encodeURIComponent(req.body.refundWalletAddresses));
293
314
  if (req.body.lockAmount) qs.push('lockAmount=' + encodeURIComponent(req.body.lockAmount));
294
315
  if (req.body.colorCode) qs.push('colorCode=' + encodeURIComponent(req.body.colorCode));
295
316
  if (req.body.theme) qs.push('theme=' + encodeURIComponent(req.body.theme));
317
+ if (req.body.themeId) qs.push('themeId=' + encodeURIComponent(req.body.themeId));
296
318
  if (req.body.language) qs.push('language=' + encodeURIComponent(req.body.language));
297
319
  if (req.body.email) qs.push('email=' + encodeURIComponent(req.body.email));
298
- if (req.body.externalCustomerId) qs.push('externalCustomerId=' + encodeURIComponent(req.body.externalCustomerId));
320
+ if (req.body.showAllCurrencies) qs.push('showAllCurrencies=' + encodeURIComponent(req.body.showAllCurrencies));
299
321
  if (req.body.showWalletAddressForm)
300
322
  qs.push('showWalletAddressForm=' + encodeURIComponent(req.body.showWalletAddressForm));
301
323
  if (req.body.unsupportedRegionRedirectUrl) qs.push('unsupportedRegionRedirectUrl=' + encodeURIComponent(req.body.unsupportedRegionRedirectUrl));
@@ -36,8 +36,27 @@ export class TransakService {
36
36
  return keys;
37
37
  }
38
38
 
39
+ // Web requests are proxied through the bitpay backend, so the IP on the
40
+ // request belongs to that server, not the customer. The proxy captures the
41
+ // customer's public IP and forwards it as deviceIp. Web credentials are only
42
+ // held by the proxy, so the forwarded value is trusted for that context only.
43
+ // Falls back to the request IP so web calls keep working until the proxy
44
+ // change that forwards deviceIp is deployed.
45
+ // Must be called before transakGetKeys, which strips context from the body.
46
+ private transakGetUserIp(req): string {
47
+ const isWebContext = req.body?.context === 'web';
48
+ let userIp = (isWebContext && req.body.deviceIp) || Utils.getIpFromReq(req);
49
+ if (userIp) {
50
+ // Canonicalize IPv4-mapped IPv6 (dual-stack sockets report IPv4 clients as
51
+ // ::ffff:1.2.3.4) so Transak sees a plain IPv4 address.
52
+ userIp = String(userIp).trim().replace(/^::ffff:/i, '');
53
+ }
54
+ return userIp || '';
55
+ }
56
+
39
57
  transakGetAccessToken(req): Promise<any> {
40
58
  return new Promise((resolve, reject) => {
59
+ const userIp = this.transakGetUserIp(req);
41
60
  let keys;
42
61
  try {
43
62
  keys = this.transakGetKeys(req);
@@ -52,7 +71,7 @@ export class TransakService {
52
71
  'Content-Type': 'application/json',
53
72
  'api-secret': SECRET_KEY,
54
73
  'x-api-key': API_KEY,
55
- 'x-user-ip': Utils.getIpFromReq(req),
74
+ 'x-user-ip': userIp,
56
75
  };
57
76
 
58
77
  const body = {
@@ -220,6 +239,7 @@ export class TransakService {
220
239
 
221
240
  const requiredParams = req.body.context === 'web' ? ['accessToken'] : appRequiredParams;
222
241
  const referrerDomain = req.body.referrerDomain ?? req.body.context === 'web' ? 'bitpay.com' : 'bitpay';
242
+ const userIp = this.transakGetUserIp(req);
223
243
  let keys;
224
244
  try {
225
245
  keys = this.transakGetKeys(req, false);
@@ -238,12 +258,14 @@ export class TransakService {
238
258
  'Content-Type': 'application/json',
239
259
  'access-token': req.body.accessToken,
240
260
  'x-api-key': API_KEY,
241
- 'x-user-ip': Utils.getIpFromReq(req),
261
+ 'x-user-ip': userIp,
242
262
  };
243
263
 
264
+ const widgetBody = { ...req.body };
265
+ delete widgetBody.deviceIp;
244
266
  const body = {
245
267
  widgetParams: {
246
- ...req.body,
268
+ ...widgetBody,
247
269
  apiKey: API_KEY,
248
270
  referrerDomain,
249
271
  },
@@ -377,7 +377,7 @@ export class DogeChain extends BtcChain implements IChain {
377
377
  if (amount < Defaults.MIN_OUTPUT_AMOUNT) return cb(null, info);
378
378
 
379
379
  if (opts.returnInputs) {
380
- info.inputs = _.shuffle(inputs);
380
+ info.inputs = _.shuffle(txp.inputs);
381
381
  }
382
382
 
383
383
  return cb(null, info);
@@ -1,59 +1,12 @@
1
1
  export const InvoiceAbi = [
2
- {
3
- constant: true,
4
- inputs: [],
5
- name: 'owner',
6
- outputs: [
7
- {
8
- name: '',
9
- type: 'address'
10
- }
11
- ],
12
- payable: false,
13
- stateMutability: 'view',
14
- type: 'function'
15
- },
16
- {
17
- constant: true,
18
- inputs: [],
19
- name: 'quoteSigner',
20
- outputs: [
21
- {
22
- name: '',
23
- type: 'address'
24
- }
25
- ],
26
- payable: false,
27
- stateMutability: 'view',
28
- type: 'function'
29
- },
30
- {
31
- constant: true,
32
- inputs: [
33
- {
34
- name: '',
35
- type: 'bytes32'
36
- }
37
- ],
38
- name: 'isPaid',
39
- outputs: [
40
- {
41
- name: '',
42
- type: 'bool'
43
- }
44
- ],
45
- payable: false,
46
- stateMutability: 'view',
47
- type: 'function'
48
- },
49
2
  {
50
3
  inputs: [
51
4
  {
5
+ internalType: 'address',
52
6
  name: 'valueSigner',
53
7
  type: 'address'
54
8
  }
55
9
  ],
56
- payable: false,
57
10
  stateMutability: 'nonpayable',
58
11
  type: 'constructor'
59
12
  },
@@ -62,21 +15,25 @@ export const InvoiceAbi = [
62
15
  inputs: [
63
16
  {
64
17
  indexed: true,
18
+ internalType: 'bytes32',
65
19
  name: 'hash',
66
20
  type: 'bytes32'
67
21
  },
68
22
  {
69
23
  indexed: true,
24
+ internalType: 'address',
70
25
  name: 'tokenContract',
71
26
  type: 'address'
72
27
  },
73
28
  {
74
29
  indexed: false,
30
+ internalType: 'uint256',
75
31
  name: 'time',
76
32
  type: 'uint256'
77
33
  },
78
34
  {
79
35
  indexed: false,
36
+ internalType: 'uint256',
80
37
  name: 'value',
81
38
  type: 'uint256'
82
39
  }
@@ -85,41 +42,95 @@ export const InvoiceAbi = [
85
42
  type: 'event'
86
43
  },
87
44
  {
88
- constant: true,
45
+ inputs: [],
46
+ name: 'activate',
47
+ outputs: [],
48
+ stateMutability: 'nonpayable',
49
+ type: 'function'
50
+ },
51
+ {
52
+ inputs: [],
53
+ name: 'deactivate',
54
+ outputs: [],
55
+ stateMutability: 'nonpayable',
56
+ type: 'function'
57
+ },
58
+ {
59
+ inputs: [],
60
+ name: 'deactivated',
61
+ outputs: [
62
+ {
63
+ internalType: 'bool',
64
+ name: '',
65
+ type: 'bool'
66
+ }
67
+ ],
68
+ stateMutability: 'view',
69
+ type: 'function'
70
+ },
71
+ {
72
+ inputs: [
73
+ {
74
+ internalType: 'bytes32',
75
+ name: '',
76
+ type: 'bytes32'
77
+ }
78
+ ],
79
+ name: 'isPaid',
80
+ outputs: [
81
+ {
82
+ internalType: 'bool',
83
+ name: '',
84
+ type: 'bool'
85
+ }
86
+ ],
87
+ stateMutability: 'view',
88
+ type: 'function'
89
+ },
90
+ {
89
91
  inputs: [
90
92
  {
93
+ internalType: 'uint256',
91
94
  name: 'value',
92
95
  type: 'uint256'
93
96
  },
94
97
  {
98
+ internalType: 'uint256',
95
99
  name: 'gasPrice',
96
100
  type: 'uint256'
97
101
  },
98
102
  {
103
+ internalType: 'uint256',
99
104
  name: 'expiration',
100
105
  type: 'uint256'
101
106
  },
102
107
  {
108
+ internalType: 'bytes32',
103
109
  name: 'payload',
104
110
  type: 'bytes32'
105
111
  },
106
112
  {
113
+ internalType: 'bytes32',
107
114
  name: 'hash',
108
115
  type: 'bytes32'
109
116
  },
110
117
  {
118
+ internalType: 'uint8',
111
119
  name: 'v',
112
120
  type: 'uint8'
113
121
  },
114
122
  {
123
+ internalType: 'bytes32',
115
124
  name: 'r',
116
125
  type: 'bytes32'
117
126
  },
118
127
  {
128
+ internalType: 'bytes32',
119
129
  name: 's',
120
130
  type: 'bytes32'
121
131
  },
122
132
  {
133
+ internalType: 'address',
123
134
  name: 'tokenContract',
124
135
  type: 'address'
125
136
  }
@@ -127,151 +138,189 @@ export const InvoiceAbi = [
127
138
  name: 'isValidPayment',
128
139
  outputs: [
129
140
  {
141
+ internalType: 'bool',
130
142
  name: 'valid',
131
143
  type: 'bool'
132
144
  }
133
145
  ],
134
- payable: false,
135
146
  stateMutability: 'view',
136
147
  type: 'function'
137
148
  },
138
149
  {
139
- constant: true,
150
+ inputs: [],
151
+ name: 'owner',
152
+ outputs: [
153
+ {
154
+ internalType: 'address',
155
+ name: '',
156
+ type: 'address'
157
+ }
158
+ ],
159
+ stateMutability: 'view',
160
+ type: 'function'
161
+ },
162
+ {
140
163
  inputs: [
141
164
  {
165
+ internalType: 'uint256',
142
166
  name: 'value',
143
167
  type: 'uint256'
144
168
  },
145
169
  {
170
+ internalType: 'uint256',
146
171
  name: 'gasPrice',
147
172
  type: 'uint256'
148
173
  },
149
174
  {
175
+ internalType: 'uint256',
150
176
  name: 'expiration',
151
177
  type: 'uint256'
152
178
  },
153
179
  {
180
+ internalType: 'bytes32',
154
181
  name: 'payload',
155
182
  type: 'bytes32'
156
183
  },
157
184
  {
185
+ internalType: 'bytes32',
158
186
  name: 'hash',
159
187
  type: 'bytes32'
160
188
  },
161
189
  {
190
+ internalType: 'uint8',
162
191
  name: 'v',
163
192
  type: 'uint8'
164
193
  },
165
194
  {
195
+ internalType: 'bytes32',
166
196
  name: 'r',
167
197
  type: 'bytes32'
168
198
  },
169
199
  {
200
+ internalType: 'bytes32',
170
201
  name: 's',
171
202
  type: 'bytes32'
172
203
  },
173
204
  {
205
+ internalType: 'address',
174
206
  name: 'tokenContract',
175
207
  type: 'address'
176
208
  }
177
209
  ],
178
- name: 'validatePayment',
210
+ name: 'pay',
211
+ outputs: [],
212
+ stateMutability: 'payable',
213
+ type: 'function'
214
+ },
215
+ {
216
+ inputs: [],
217
+ name: 'quoteSigner',
179
218
  outputs: [
180
219
  {
181
- name: 'valid',
182
- type: 'bool'
220
+ internalType: 'address',
221
+ name: '',
222
+ type: 'address'
183
223
  }
184
224
  ],
185
- payable: false,
186
225
  stateMutability: 'view',
187
226
  type: 'function'
188
227
  },
189
228
  {
190
- constant: false,
191
229
  inputs: [
192
230
  {
231
+ internalType: 'address',
232
+ name: 'newAdmin',
233
+ type: 'address'
234
+ }
235
+ ],
236
+ name: 'setAdmin',
237
+ outputs: [],
238
+ stateMutability: 'nonpayable',
239
+ type: 'function'
240
+ },
241
+ {
242
+ inputs: [
243
+ {
244
+ internalType: 'address',
245
+ name: 'newQuoteSigner',
246
+ type: 'address'
247
+ }
248
+ ],
249
+ name: 'setSigner',
250
+ outputs: [],
251
+ stateMutability: 'nonpayable',
252
+ type: 'function'
253
+ },
254
+ {
255
+ inputs: [
256
+ {
257
+ internalType: 'uint256',
193
258
  name: 'value',
194
259
  type: 'uint256'
195
260
  },
196
261
  {
262
+ internalType: 'uint256',
197
263
  name: 'gasPrice',
198
264
  type: 'uint256'
199
265
  },
200
266
  {
267
+ internalType: 'uint256',
201
268
  name: 'expiration',
202
269
  type: 'uint256'
203
270
  },
204
271
  {
272
+ internalType: 'bytes32',
205
273
  name: 'payload',
206
274
  type: 'bytes32'
207
275
  },
208
276
  {
277
+ internalType: 'bytes32',
209
278
  name: 'hash',
210
279
  type: 'bytes32'
211
280
  },
212
281
  {
282
+ internalType: 'uint8',
213
283
  name: 'v',
214
284
  type: 'uint8'
215
285
  },
216
286
  {
287
+ internalType: 'bytes32',
217
288
  name: 'r',
218
289
  type: 'bytes32'
219
290
  },
220
291
  {
292
+ internalType: 'bytes32',
221
293
  name: 's',
222
294
  type: 'bytes32'
223
295
  },
224
296
  {
297
+ internalType: 'address',
225
298
  name: 'tokenContract',
226
299
  type: 'address'
227
300
  }
228
301
  ],
229
- name: 'pay',
230
- outputs: [],
231
- payable: true,
232
- stateMutability: 'payable',
233
- type: 'function'
234
- },
235
- {
236
- constant: false,
237
- inputs: [
238
- {
239
- name: 'tokenContract',
240
- type: 'address'
241
- }
242
- ],
243
- name: 'withdraw',
244
- outputs: [],
245
- payable: false,
246
- stateMutability: 'nonpayable',
247
- type: 'function'
248
- },
249
- {
250
- constant: false,
251
- inputs: [
302
+ name: 'validatePayment',
303
+ outputs: [
252
304
  {
253
- name: 'newQuoteSigner',
254
- type: 'address'
305
+ internalType: 'bool',
306
+ name: 'valid',
307
+ type: 'bool'
255
308
  }
256
309
  ],
257
- name: 'setSigner',
258
- outputs: [],
259
- payable: false,
260
- stateMutability: 'nonpayable',
310
+ stateMutability: 'view',
261
311
  type: 'function'
262
312
  },
263
313
  {
264
- constant: false,
265
314
  inputs: [
266
315
  {
267
- name: 'newAdmin',
316
+ internalType: 'address',
317
+ name: 'tokenContract',
268
318
  type: 'address'
269
319
  }
270
320
  ],
271
- name: 'setAdmin',
321
+ name: 'withdraw',
272
322
  outputs: [],
273
- payable: false,
274
323
  stateMutability: 'nonpayable',
275
324
  type: 'function'
276
325
  }
277
- ];
326
+ ] as const;
@@ -226,6 +226,9 @@ export const Constants = {
226
226
 
227
227
  // May be different from the defaults if we rollback
228
228
  // or want to beta test new versions.
229
- TSS_KEYGEN_SCHEME_VERSION_MAX: 1,
230
- TSS_SIGGEN_SCHEME_VERSION_MAX: 1,
229
+ TSS_KEYGEN_SCHEME_VERSION_MAX: 1.1,
230
+ TSS_SIGGEN_SCHEME_VERSION_MAX: 1.1,
231
+
232
+ TSS_KEYGEN_SCHEME_VERSION_MIN: 1,
233
+ TSS_SIGGEN_SCHEME_VERSION_MIN: 1,
231
234
  } as const;
@@ -434,6 +434,15 @@ export const Defaults = {
434
434
  { code: 'NZD', name: 'New Zealand Dollar' }
435
435
  ],
436
436
 
437
- TSS_KEYGEN_SCHEME_VERSION: 1,
438
- TSS_SIGGEN_SCHEME_VERSION: 1,
437
+ // In general, the major version represents server upgrades or major security upgrades, and the minor version represents client upgrades.
438
+ // Example1: If the server has an API response overhaul, that's a breaking change for older clients - it should increment the major version.
439
+ // This will result in an UPGRADE_NEEDED error for older clients.
440
+ // Example2: If the client upgrades the encryption scheme, older clients will still be compatible with the server and
441
+ // other older clients - it should increment the minor version. Mismatching client versions will still break the process, but
442
+ // the difference from a major version bump is that matching older clients will still work.
443
+ TSS_KEYGEN_SCHEME_VERSION: 1.1,
444
+ TSS_SIGGEN_SCHEME_VERSION: 1.1,
445
+
446
+ TSS_KEYGEN_TIME_LIMIT: 20, // minutes
447
+ TSS_SIGGEN_TIME_LIMIT: 60 * 24, // minutes - 1 day (TODO tighten this up after testing)
439
448
  } as const;
@@ -76,6 +76,9 @@ interface Errors<T> {
76
76
  TSS_BWS_JOIN_SECRET_NOT_FOUND: T;
77
77
  TSS_NO_FINAL_SIGNATURE: T;
78
78
  TSS_INVALID_FINAL_SIGNATURE: T;
79
+ TSS_SESSION_EXPIRED: T;
80
+ TSS_MISMATCH_VERSION: T;
81
+ TSS_FINAL_SIGNATURE_MISMATCH: T;
79
82
  };
80
83
 
81
84
  const errors: Errors<string> = {
@@ -148,6 +151,9 @@ const errors: Errors<string> = {
148
151
  TSS_BWS_JOIN_SECRET_NOT_FOUND: 'BWS join secret not found',
149
152
  TSS_NO_FINAL_SIGNATURE: 'No signature provided',
150
153
  TSS_INVALID_FINAL_SIGNATURE: 'Invalid signature provided',
154
+ TSS_SESSION_EXPIRED: 'TSS session has expired',
155
+ TSS_MISMATCH_VERSION: 'TSS version does not match session version',
156
+ TSS_FINAL_SIGNATURE_MISMATCH: 'Final signature does not match the one generated by the session',
151
157
  };
152
158
 
153
159
  const errorsObject = { codes: {} };