@bitpay-labs/bitcore-wallet-service 11.8.2 → 11.10.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 (127) hide show
  1. package/bws.example.config.js +4 -2
  2. package/package.json +4 -4
  3. package/src/config.ts +4 -2
  4. package/src/externalservices/moonpay.ts +85 -1
  5. package/src/lib/blockchainexplorers/v8.ts +1 -1
  6. package/src/lib/chain/eth/index.ts +8 -7
  7. package/src/lib/chain/index.ts +1 -1
  8. package/src/lib/chain/sol/index.ts +4 -4
  9. package/src/lib/chain/xrp/index.ts +3 -3
  10. package/src/lib/common/utils.ts +12 -5
  11. package/src/lib/errors/errordefinitions.ts +2 -0
  12. package/src/lib/expressapp.ts +6 -3
  13. package/src/lib/model/txnote.ts +3 -0
  14. package/src/lib/model/txproposal.ts +153 -68
  15. package/src/lib/model/txproposal_legacy.ts +5 -4
  16. package/src/lib/model/txproposalaction.ts +9 -0
  17. package/src/lib/routes/blockchain.ts +2 -3
  18. package/src/lib/routes/context.ts +10 -1
  19. package/src/lib/routes/maintenance.ts +6 -3
  20. package/src/lib/routes/services.ts +12 -0
  21. package/src/lib/routes/transactions.ts +17 -2
  22. package/src/lib/routes/walletdata.ts +1 -2
  23. package/src/lib/routes/wallets.ts +9 -4
  24. package/src/lib/server.ts +62 -9
  25. package/src/lib/storage.ts +13 -12
  26. package/src/types/expressapp.d.ts +2 -1
  27. package/test/chain/bch.test.ts +8 -1
  28. package/test/chain/btc.test.ts +2 -2
  29. package/test/chain/doge.test.ts +4 -6
  30. package/test/chain/ltc.test.ts +4 -5
  31. package/test/chain/xrp.test.ts +4 -39
  32. package/test/integration/externalservices/moonpay.test.ts +149 -0
  33. package/test/model/txproposal.test.ts +64 -1
  34. package/test/utils.test.ts +29 -0
  35. package/ts_build/package.json +3 -3
  36. package/ts_build/src/config.d.ts.map +1 -1
  37. package/ts_build/src/config.js.map +1 -1
  38. package/ts_build/src/externalservices/moonpay.d.ts +4 -0
  39. package/ts_build/src/externalservices/moonpay.d.ts.map +1 -1
  40. package/ts_build/src/externalservices/moonpay.js +68 -1
  41. package/ts_build/src/externalservices/moonpay.js.map +1 -1
  42. package/ts_build/src/lib/blockchainexplorers/v8.js +1 -1
  43. package/ts_build/src/lib/chain/eth/index.d.ts +6 -5
  44. package/ts_build/src/lib/chain/eth/index.d.ts.map +1 -1
  45. package/ts_build/src/lib/chain/eth/index.js +5 -5
  46. package/ts_build/src/lib/chain/eth/index.js.map +1 -1
  47. package/ts_build/src/lib/chain/index.d.ts +1 -1
  48. package/ts_build/src/lib/chain/index.d.ts.map +1 -1
  49. package/ts_build/src/lib/chain/index.js.map +1 -1
  50. package/ts_build/src/lib/chain/sol/index.js +4 -4
  51. package/ts_build/src/lib/chain/sol/index.js.map +1 -1
  52. package/ts_build/src/lib/chain/xrp/index.js +3 -3
  53. package/ts_build/src/lib/chain/xrp/index.js.map +1 -1
  54. package/ts_build/src/lib/common/utils.d.ts.map +1 -1
  55. package/ts_build/src/lib/common/utils.js +14 -9
  56. package/ts_build/src/lib/common/utils.js.map +1 -1
  57. package/ts_build/src/lib/errors/errordefinitions.d.ts +1 -0
  58. package/ts_build/src/lib/errors/errordefinitions.d.ts.map +1 -1
  59. package/ts_build/src/lib/errors/errordefinitions.js +1 -0
  60. package/ts_build/src/lib/errors/errordefinitions.js.map +1 -1
  61. package/ts_build/src/lib/expressapp.d.ts.map +1 -1
  62. package/ts_build/src/lib/expressapp.js +5 -3
  63. package/ts_build/src/lib/expressapp.js.map +1 -1
  64. package/ts_build/src/lib/model/txnote.d.ts +1 -0
  65. package/ts_build/src/lib/model/txnote.d.ts.map +1 -1
  66. package/ts_build/src/lib/model/txnote.js +1 -0
  67. package/ts_build/src/lib/model/txnote.js.map +1 -1
  68. package/ts_build/src/lib/model/txproposal.d.ts +72 -52
  69. package/ts_build/src/lib/model/txproposal.d.ts.map +1 -1
  70. package/ts_build/src/lib/model/txproposal.js +69 -17
  71. package/ts_build/src/lib/model/txproposal.js.map +1 -1
  72. package/ts_build/src/lib/model/txproposal_legacy.d.ts +3 -3
  73. package/ts_build/src/lib/model/txproposal_legacy.d.ts.map +1 -1
  74. package/ts_build/src/lib/model/txproposal_legacy.js +1 -0
  75. package/ts_build/src/lib/model/txproposal_legacy.js.map +1 -1
  76. package/ts_build/src/lib/model/txproposalaction.d.ts +2 -0
  77. package/ts_build/src/lib/model/txproposalaction.d.ts.map +1 -1
  78. package/ts_build/src/lib/model/txproposalaction.js +2 -0
  79. package/ts_build/src/lib/model/txproposalaction.js.map +1 -1
  80. package/ts_build/src/lib/routes/blockchain.d.ts.map +1 -1
  81. package/ts_build/src/lib/routes/blockchain.js +2 -36
  82. package/ts_build/src/lib/routes/blockchain.js.map +1 -1
  83. package/ts_build/src/lib/routes/context.d.ts +1 -0
  84. package/ts_build/src/lib/routes/context.d.ts.map +1 -1
  85. package/ts_build/src/lib/routes/context.js +8 -1
  86. package/ts_build/src/lib/routes/context.js.map +1 -1
  87. package/ts_build/src/lib/routes/maintenance.d.ts.map +1 -1
  88. package/ts_build/src/lib/routes/maintenance.js +6 -36
  89. package/ts_build/src/lib/routes/maintenance.js.map +1 -1
  90. package/ts_build/src/lib/routes/services.d.ts.map +1 -1
  91. package/ts_build/src/lib/routes/services.js +10 -0
  92. package/ts_build/src/lib/routes/services.js.map +1 -1
  93. package/ts_build/src/lib/routes/transactions.d.ts +1 -0
  94. package/ts_build/src/lib/routes/transactions.d.ts.map +1 -1
  95. package/ts_build/src/lib/routes/transactions.js +14 -2
  96. package/ts_build/src/lib/routes/transactions.js.map +1 -1
  97. package/ts_build/src/lib/routes/walletdata.d.ts.map +1 -1
  98. package/ts_build/src/lib/routes/walletdata.js +1 -35
  99. package/ts_build/src/lib/routes/walletdata.js.map +1 -1
  100. package/ts_build/src/lib/routes/wallets.d.ts +1 -0
  101. package/ts_build/src/lib/routes/wallets.d.ts.map +1 -1
  102. package/ts_build/src/lib/routes/wallets.js +8 -4
  103. package/ts_build/src/lib/routes/wallets.js.map +1 -1
  104. package/ts_build/src/lib/server.d.ts +6 -2
  105. package/ts_build/src/lib/server.d.ts.map +1 -1
  106. package/ts_build/src/lib/server.js +45 -3
  107. package/ts_build/src/lib/server.js.map +1 -1
  108. package/ts_build/src/lib/storage.d.ts +6 -6
  109. package/ts_build/src/lib/storage.d.ts.map +1 -1
  110. package/ts_build/src/lib/storage.js +6 -6
  111. package/ts_build/src/lib/storage.js.map +1 -1
  112. package/ts_build/test/chain/bch.test.js +7 -0
  113. package/ts_build/test/chain/bch.test.js.map +1 -1
  114. package/ts_build/test/chain/btc.test.js +2 -2
  115. package/ts_build/test/chain/btc.test.js.map +1 -1
  116. package/ts_build/test/chain/doge.test.js +3 -5
  117. package/ts_build/test/chain/doge.test.js.map +1 -1
  118. package/ts_build/test/chain/ltc.test.js +3 -4
  119. package/ts_build/test/chain/ltc.test.js.map +1 -1
  120. package/ts_build/test/chain/xrp.test.js +3 -38
  121. package/ts_build/test/chain/xrp.test.js.map +1 -1
  122. package/ts_build/test/integration/externalservices/moonpay.test.js +139 -0
  123. package/ts_build/test/integration/externalservices/moonpay.test.js.map +1 -1
  124. package/ts_build/test/model/txproposal.test.js +57 -0
  125. package/ts_build/test/model/txproposal.test.js.map +1 -1
  126. package/ts_build/test/utils.test.js +23 -0
  127. package/ts_build/test/utils.test.js.map +1 -1
@@ -1,6 +1,5 @@
1
1
  import * as async from 'async';
2
2
  import express from 'express';
3
- import * as _ from 'lodash';
4
3
  import { Common } from '../common';
5
4
  import { ClientError } from '../errors/clienterror';
6
5
  import logger from '../logger';
@@ -16,6 +15,7 @@ interface RouteContext {
16
15
  getServerWithMultiAuth: Types.GetServerWithMultiAuthFn;
17
16
  logDeprecated: Types.LogDeprecatedFn;
18
17
  returnError: Types.ReturnErrorFn;
18
+ checkNumberFormat: Types.CheckNumberFormatFn;
19
19
  }
20
20
 
21
21
  function getServerOrReturnError(req, res, context: RouteContext): WalletService | null {
@@ -28,7 +28,7 @@ function getServerOrReturnError(req, res, context: RouteContext): WalletService
28
28
  }
29
29
 
30
30
  export function registerWalletRoutes(router: express.Router, context: RouteContext) {
31
- const { createWalletLimiter, getServerWithAuth, getServerWithMultiAuth, logDeprecated, returnError } = context;
31
+ const { createWalletLimiter, getServerWithAuth, getServerWithMultiAuth, logDeprecated, returnError, checkNumberFormat } = context;
32
32
 
33
33
  router.post('/v1/wallets/', createWalletLimiter, (req, res) => {
34
34
  logDeprecated(req);
@@ -97,13 +97,15 @@ export function registerWalletRoutes(router: express.Router, context: RouteConte
97
97
 
98
98
  router.get('/v3/wallets/', (req, res) => {
99
99
  getServerWithAuth(req, res, server => {
100
+ checkNumberFormat(req.query.numberFormat, res);
100
101
  const opts = {
101
102
  includeExtendedInfo: false,
102
103
  twoStep: false,
103
104
  includeServerMessages: false,
104
105
  tokenAddress: req.query.tokenAddress,
105
106
  multisigContractAddress: req.query.multisigContractAddress,
106
- network: req.query.network
107
+ network: req.query.network,
108
+ numberFormat: req.query.numberFormat
107
109
  };
108
110
  if (req.query.includeExtendedInfo == '1') opts.includeExtendedInfo = true;
109
111
  if (req.query.twoStep == '1') opts.twoStep = true;
@@ -122,6 +124,8 @@ export function registerWalletRoutes(router: express.Router, context: RouteConte
122
124
  const twoStep = req.query.twoStep == '1';
123
125
  const silentFailure = req.query.silentFailure == '1';
124
126
  const includeServerMessages = req.query.serverMessageArray == '1';
127
+ const numberFormat = req.query.numberFormat;
128
+ checkNumberFormat(numberFormat, res);
125
129
 
126
130
  const buildOpts = (request, copayerId) => {
127
131
  const getParam = (param, returnArray = false) => {
@@ -137,6 +141,7 @@ export function registerWalletRoutes(router: express.Router, context: RouteConte
137
141
  twoStep,
138
142
  silentFailure,
139
143
  includeServerMessages,
144
+ numberFormat,
140
145
  tokenAddresses: getParam('tokenAddress', true) as string[] | null,
141
146
  multisigContractAddress: getParam('multisigContractAddress') as string | null,
142
147
  network: getParam('network') as string | null
@@ -212,7 +217,7 @@ export function registerWalletRoutes(router: express.Router, context: RouteConte
212
217
  if (res.headersSent) {
213
218
  return;
214
219
  }
215
- return res.json(_.flatten(responses));
220
+ return res.json(responses.flat());
216
221
  });
217
222
 
218
223
  router.post('/v1/wallets/exist', async (req, res) => {
package/src/lib/server.ts CHANGED
@@ -844,6 +844,7 @@ export class WalletService implements IWalletService {
844
844
  * @param {Object} opts.tokenAddress - (Optional) Token contract address to pass in getBalance
845
845
  * @param {Object} opts.multisigContractAddress - (Optional) Multisig ETH contract address to pass in getBalance
846
846
  * @param {Object} opts.network - (Optional ETH MULTISIG) Multisig ETH contract address network
847
+ * @param {string} opts.numberFormat Returns txp tx-build values as 'string', 'hex', or 'number' (default)
847
848
  * @returns {Object} status
848
849
  */
849
850
  getStatus(opts, cb) {
@@ -1879,7 +1880,7 @@ export class WalletService implements IWalletService {
1879
1880
  next => {
1880
1881
  utxoIndex = _.keyBy(allUtxos, utxoKey);
1881
1882
 
1882
- this.getPendingTxs({}, (err, txps) => {
1883
+ this.getPendingTxs({ numberFormat: opts.numberFormat }, (err, txps) => {
1883
1884
  if (err) return next(err);
1884
1885
 
1885
1886
  const lockedInputs = txps.flatMap(t => t.inputs).map(utxoKey);
@@ -1888,7 +1889,7 @@ export class WalletService implements IWalletService {
1888
1889
  utxoIndex[input].locked = true;
1889
1890
  }
1890
1891
  }
1891
- logger.debug(`Got ${lockedInputs.length} locked utxos`);
1892
+ logger.debug(`Got ${lockedInputs.length} locked utxos`);
1892
1893
  return next();
1893
1894
  });
1894
1895
  },
@@ -2689,6 +2690,17 @@ export class WalletService implements IWalletService {
2689
2690
  });
2690
2691
  }
2691
2692
 
2693
+ createTx(opts, cb) {
2694
+ this._createTx(opts, (err, txp) => {
2695
+ if (err) return cb(err);
2696
+ if (opts.numberFormat) {
2697
+ txp = TxProposal.formatNumbers(txp, opts.numberFormat);
2698
+ }
2699
+ return cb(null, txp);
2700
+ });
2701
+ }
2702
+
2703
+
2692
2704
  /**
2693
2705
  * Creates a new transaction proposal.
2694
2706
  * @param {Object} opts
@@ -2736,7 +2748,7 @@ export class WalletService implements IWalletService {
2736
2748
  * @param {Boolean} opts.refreshOnPublish - Optional. Allows publish function to refresh txp data
2737
2749
  * @returns {TxProposal} Transaction proposal. outputs address format will use the same format as inpunt.
2738
2750
  */
2739
- createTx(opts, cb) {
2751
+ private _createTx(opts, cb) {
2740
2752
  opts = opts ? _.clone(opts) : {};
2741
2753
 
2742
2754
  const checkTxpAlreadyExists = (txProposalId, cb) => {
@@ -2869,6 +2881,7 @@ export class WalletService implements IWalletService {
2869
2881
  outputs: opts.outputs,
2870
2882
  message: opts.message,
2871
2883
  from: opts.from,
2884
+ sendMax: opts.sendMax,
2872
2885
  changeAddress,
2873
2886
  feeLevel: opts.feeLevel,
2874
2887
  feePerKb,
@@ -3000,6 +3013,17 @@ export class WalletService implements IWalletService {
3000
3013
  );
3001
3014
  }
3002
3015
 
3016
+
3017
+ publishTx(opts, cb) {
3018
+ this._publishTx(opts, (err, txp) => {
3019
+ if (err) return cb(err);
3020
+ if (opts.numberFormat) {
3021
+ txp = TxProposal.formatNumbers(txp, opts.numberFormat);
3022
+ }
3023
+ return cb(null, txp);
3024
+ });
3025
+ }
3026
+
3003
3027
  /**
3004
3028
  * Publish an already created tx proposal so inputs are locked and other copayers in the wallet can see it.
3005
3029
  * @param {Object} opts
@@ -3007,7 +3031,7 @@ export class WalletService implements IWalletService {
3007
3031
  * @param {string} opts.proposalSignature - S(raw tx). Used by other copayers to verify the proposal.
3008
3032
  * @param {Boolean} [opts.noCashAddr] - do not use cashaddress for bch
3009
3033
  */
3010
- publishTx(opts, cb) {
3034
+ private _publishTx(opts, cb) {
3011
3035
  if (!checkRequired(opts, ['txProposalId', 'proposalSignature'], cb)) return;
3012
3036
 
3013
3037
  this._runLocked(cb, cb => {
@@ -3088,7 +3112,7 @@ export class WalletService implements IWalletService {
3088
3112
  * @param {string} opts.txProposalId - The tx proposal id.
3089
3113
  * @returns {Object} txProposal
3090
3114
  */
3091
- getTx(opts, cb) {
3115
+ getTx(opts, cb: (err: any, txp?: TxProposal) => void) {
3092
3116
  this.storage.fetchTx(this.walletId, opts.txProposalId, (err, txp) => {
3093
3117
  if (err) return cb(err);
3094
3118
  if (!txp) return cb(Errors.TX_NOT_FOUND);
@@ -3287,6 +3311,7 @@ export class WalletService implements IWalletService {
3287
3311
  * @param {string} opts.signatures - The signatures of the inputs of this tx for this copayer (in appearance order)
3288
3312
  * @param {string} opts.maxTxpVersion - Client's maximum supported txp version
3289
3313
  * @param {boolean} opts.supportBchSchnorr - indication whether to use schnorr for signing tx
3314
+ * @param {string} opts.numberFormat - Optional. If specified, the tx proposal will ensure the numbers are in the format specified (e.g. 'string'). This is to ensure precision handling matches the client's
3290
3315
  */
3291
3316
  signTx(opts, cb) {
3292
3317
  if (!checkRequired(opts, ['txProposalId', 'signatures'], cb)) return;
@@ -3343,7 +3368,7 @@ export class WalletService implements IWalletService {
3343
3368
  const xPubKey = wallet.tssKeyId ? wallet.clientDerivedPublicKey : copayer.xPubKey;
3344
3369
 
3345
3370
  try {
3346
- if (!txp.sign(this.copayerId, opts.signatures, xPubKey)) {
3371
+ if (!txp.sign(this.copayerId, opts.signatures, xPubKey, opts.numberFormat)) {
3347
3372
  this.logw('Error signing transaction (BAD_SIGNATURES)');
3348
3373
  this.logw('Client version:', this.clientVersion);
3349
3374
  this.logw('Arguments:', JSON.stringify(opts));
@@ -3413,6 +3438,16 @@ export class WalletService implements IWalletService {
3413
3438
  });
3414
3439
  }
3415
3440
 
3441
+ prepareTx(opts, cb) {
3442
+ this._prepareTx(opts, (err, txp) => {
3443
+ if (err) return cb(err);
3444
+ if (opts.numberFormat) {
3445
+ txp = TxProposal.formatNumbers(txp, opts.numberFormat);
3446
+ }
3447
+ return cb(null, txp);
3448
+ });
3449
+ }
3450
+
3416
3451
  /**
3417
3452
  * Prepare a transaction proposal for signing.
3418
3453
  * Assigns JIT values (nonce, and in the future: fee, gas) to a deferred txp.
@@ -3420,7 +3455,7 @@ export class WalletService implements IWalletService {
3420
3455
  * @param {Object} opts
3421
3456
  * @param {string} opts.txProposalId - The identifier of the transaction.
3422
3457
  */
3423
- prepareTx(opts, cb) {
3458
+ private _prepareTx(opts, cb) {
3424
3459
  if (!checkRequired(opts, ['txProposalId'], cb)) return;
3425
3460
 
3426
3461
  this._runLocked(cb, cb => {
@@ -3635,16 +3670,34 @@ export class WalletService implements IWalletService {
3635
3670
  );
3636
3671
  }
3637
3672
 
3673
+
3674
+ /**
3675
+ * Retrieves pending transaction proposals.
3676
+ * @param {'number'|'string'|'hex'|'bigint'} opts.numberFormat The format to return numbers in. Not ALL numbers - just certain ones that are needed for tx building/verifying by the client.
3677
+ * @param cb
3678
+ */
3679
+ async getPendingTxs(opts, cb) {
3680
+ this._getPendingTxs(opts, (err, txps) => {
3681
+ if (err) return cb(err);
3682
+ if (opts.numberFormat) {
3683
+ const formattedTxps = txps.map(t => TxProposal.formatNumbers(t, opts.numberFormat));
3684
+ return cb(null, formattedTxps);
3685
+ }
3686
+ return cb(null, txps);
3687
+ });
3688
+ }
3689
+
3638
3690
  /**
3639
3691
  * Retrieves pending transaction proposals.
3640
3692
  * @param {Object} opts
3641
3693
  * @param {Boolean} opts.noCashAddr (do not use cashaddr, only for backwards compat)
3642
3694
  * @param {String} opts.tokenAddress ERC20 Token Contract Address
3643
3695
  * @param {String} opts.multisigContractAddress MULTISIG ETH Contract Address
3644
- * @param {String} opts.network The network of the MULTISIG ETH transactions
3696
+ * @param {String} opts.network The network of the MULTISIG ETH transactions
3697
+ * @param {String} opts.numberFormat Return numbers as format. 'number' (default), 'hex', or 'string'
3645
3698
  * @returns {TxProposal[]} Transaction proposal.
3646
3699
  */
3647
- async getPendingTxs(opts, cb) {
3700
+ private async _getPendingTxs(opts, cb: (err: any, txps?: ITxProposal[]) => void) {
3648
3701
  if (opts.multisigContractAddress) {
3649
3702
  try {
3650
3703
  const multisigTxpsInfo = await this.getMultisigTxpsInfo(opts);
@@ -310,24 +310,25 @@ export class Storage {
310
310
  }
311
311
 
312
312
  // TODO: should be done client-side
313
- _completeTxData(walletId, txs, cb) {
313
+ _completeTxData(walletId: string, txs: TxProposal | TxProposal[], cb: (err?: any, txs?: TxProposal | TxProposal[]) => void) {
314
314
  this.fetchWallet(walletId, (err, wallet) => {
315
315
  if (err) return cb(err);
316
- _.each([].concat(txs), tx => {
316
+ for (const tx of [].concat(txs) as TxProposal[]) {
317
317
  tx.derivationStrategy = wallet.derivationStrategy || 'BIP45';
318
318
  tx.creatorName = wallet.getCopayer(tx.creatorId).name;
319
- _.each(tx.actions, action => {
319
+ for (const action of tx.actions) {
320
320
  action.copayerName = wallet.getCopayer(action.copayerId).name;
321
- });
321
+ }
322
322
 
323
- if (tx.status == 'accepted') tx.raw = tx.getRawTx();
324
- });
323
+ if (tx.status == 'accepted')
324
+ tx.raw = tx.getRawTx();
325
+ }
325
326
  return cb(null, txs);
326
327
  });
327
328
  }
328
329
 
329
330
  // TODO: remove walletId from signature
330
- fetchTx(walletId, txProposalId, cb) {
331
+ fetchTx(walletId: string, txProposalId: string, cb: (err?: any, tx?: TxProposal) => void) {
331
332
  if (!this.db) return cb();
332
333
 
333
334
  this.db.collection(collections.TXS).findOne(
@@ -385,7 +386,7 @@ export class Storage {
385
386
  }
386
387
 
387
388
  fetchEthPendingTxs(multisigTxpsInfo) {
388
- return new Promise((resolve, reject) => {
389
+ return new Promise<TxProposal[]>((resolve, reject) => {
389
390
  this.db
390
391
  .collection(collections.TXS)
391
392
  .find({
@@ -1286,7 +1287,7 @@ export class Storage {
1286
1287
  });
1287
1288
  }
1288
1289
 
1289
- fetchTxNote(walletId, txid, cb) {
1290
+ fetchTxNote(walletId, txid, cb: (err?: any, note?: TxNote) => void) {
1290
1291
  this.db.collection(collections.TX_NOTES).findOne(
1291
1292
  {
1292
1293
  walletId,
@@ -1301,12 +1302,12 @@ export class Storage {
1301
1302
  }
1302
1303
 
1303
1304
  // TODO: should be done client-side
1304
- _completeTxNotesData(walletId, notes, cb) {
1305
+ _completeTxNotesData(walletId, notes: TxNote | TxNote[], cb: (err?: any, notes?: TxNote | TxNote[]) => void) {
1305
1306
  this.fetchWallet(walletId, (err, wallet) => {
1306
1307
  if (err) return cb(err);
1307
- _.each([].concat(notes), note => {
1308
+ for (const note of [].concat(notes) as TxNote[]) {
1308
1309
  note.editedByName = wallet.getCopayer(note.editedBy).name;
1309
- });
1310
+ }
1310
1311
  return cb(null, notes);
1311
1312
  });
1312
1313
  }
@@ -12,4 +12,5 @@ export type GetServerFn = (req: express.Request, res: express.Response) => Walle
12
12
  export type ServerCallback = (server: WalletService, err?: Error) => void;
13
13
  export type GetServerWithAuthFn = (req: express.Request, res: express.Response, opts?: ServerOpts | ServerCallback, cb?: ServerCallback) => Promise<WalletService | void>;
14
14
  export type GetServerWithMultiAuthFn = (req: express.Request, res: express.Response, opts?: ServerOpts) => Array<Promise<WalletService | void>>;
15
- export type CreateWalletLimiterFn = (req: express.Request, res: express.Response, next: express.NextFunction) => void;
15
+ export type CreateWalletLimiterFn = (req: express.Request, res: express.Response, next: express.NextFunction) => void;
16
+ export type CheckNumberFormatFn = (numberFormat: string | undefined, res: express.Response) => void;
@@ -73,6 +73,11 @@ const aTXP = function() {
73
73
  version: '1.0.0',
74
74
  createdOn: 1424372337,
75
75
  address: '3CauZ5JUFfmSAx2yANvCRoNXccZ3YSUjXH',
76
+ walletId: 'thisdoesntmatter',
77
+ coin: 'bch',
78
+ chain: 'bch',
79
+ network: 'livenet',
80
+ type: 'P2SH',
76
81
  path: 'm/2147483647/1/0',
77
82
  publicKeys: ['030562cb099e6043dc499eb359dd97c9d500a3586498e4bcf0228a178cc20e6f16',
78
83
  '0367027d17dbdfc27b5e31f8ed70e14d47949f0fa392261e977db0851c8b0d6fac',
@@ -96,15 +101,17 @@ const aTXP = function() {
96
101
  requiredRejections: 1,
97
102
  walletN: 2,
98
103
  addressType: 'P2SH',
99
- status: 'pending',
104
+ status: 'pending' as const,
100
105
  actions: [],
101
106
  fee: 10000,
102
107
  outputs: [{
103
108
  toAddress: 'qq0zkyfjkjfec47hgcu0acdzw36td4s2evqyyllszk',
109
+ address: 'qq0zkyfjkjfec47hgcu0acdzw36td4s2evqyyllszk',
104
110
  amount: 10000000,
105
111
  message: 'first message'
106
112
  }, {
107
113
  toAddress: 'qq0zkyfjkjfec47hgcu0acdzw36td4s2evqyyllszk',
114
+ address: 'qq0zkyfjkjfec47hgcu0acdzw36td4s2evqyyllszk',
108
115
  amount: 20000000,
109
116
  message: 'second message'
110
117
  }],
@@ -262,7 +262,7 @@ const aTXP = function() {
262
262
  chain: 'btc',
263
263
  coin: 'btc',
264
264
  network: 'livenet',
265
- amount: '30000000',
265
+ amount: 30000000,
266
266
  message: 'some message',
267
267
  proposalSignature: '7035022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9',
268
268
  changeAddress: {
@@ -328,4 +328,4 @@ const aTXP = function() {
328
328
  return txp;
329
329
  };
330
330
 
331
- const signedTxp = { 'actions': [{ 'version': '1.0.0', 'createdOn': 1588099987, 'copayerId': '671fee02a6c1c4de2e2609f9f9a6180dc03acfff6b759fe0b13a616ed4880065', 'type': 'accept', 'signatures': ['3045022100ace0efb22eaf21b77d5e4a31a491ad06fbcfe700ace5abe8453ec0328c714cba02205090a44975d4b65b5e2f4473da038e83875826b369fc79558a741268ed574bb0'], 'xpub': 'xpub6DVmxcjRgZdHNSEcXSiFtweVwMSTc3TMwRJ45nJYvyqvLbK1poPerupqh87rSoz27wvckb1CKnGZoLmLXSZyNGZtVd7neqSvdwJL6fceQpe', 'comment': null }], 'version': 3, 'createdOn': 1588099987, 'id': '7cea0d95-3308-48e7-a4be-3f16d66e1f5a', 'walletId': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'creatorId': '671fee02a6c1c4de2e2609f9f9a6180dc03acfff6b759fe0b13a616ed4880065', 'coin': 'bch', 'network': 'livenet', 'outputs': [{ 'amount': 80000000, 'toAddress': 'CPrtPWbp8cCftTQu5fzuLG5zPJNDHMMf8X' }], 'amount': 80000000, 'message': 'some message', 'payProUrl': null, 'changeAddress': { 'version': '1.0.0', 'createdOn': 1588099987, 'address': 'CWwtFMy3GMr5qMEtvEdUDjePfShzkJXCnh', 'walletId': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'isChange': true, 'path': 'm/1/0', 'publicKeys': ['02129acdcc600694b3ce55a2d05244186e806174eb0bafde20e5a6395ded647857'], 'coin': 'bch', 'network': 'livenet', 'type': 'P2PKH', 'hasActivity': null, 'beRegistered': null }, 'inputs': [{ 'txid': '4e7feb01fb039f3a719e9390c8f7cb501fb8a0a083f72a43b4cbb420d8505cc0', 'vout': 5, 'satoshis': 100000000, 'scriptPubKey': '76a914d391e62337ed194a1e428f32d14838e5d848180a88ac', 'address': 'qrfere3rxlk3jjs7g28n952g8rjasjqcpgx3axq70t', 'confirmations': 44, 'publicKeys': ['024d27ca79a3ed27a143cb9d1dff01e4e6445294679a700ca404ca449211d08aa7'], 'wallet': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'path': 'm/0/1' }], 'walletM': 1, 'walletN': 1, 'requiredSignatures': 1, 'requiredRejections': 1, 'status': 'accepted', 'txid': '8541ed35ac43e07e362a00ebab9448eefa63840c75ca38edff6785c223503a29', 'broadcastedOn': null, 'inputPaths': ['m/0/1'], 'outputOrder': [1, 0], 'fee': 2430, 'feeLevel': null, 'feePerKb': 10000, 'excludeUnconfirmedUtxos': false, 'addressType': 'P2PKH', 'customData': null, 'proposalSignature': '3045022100e8a1ac6eef882fb3e7311c725093317df99e5ed46f52fdee9064560bb757d1c902200b09f806a17d4c7950097b8714293725ce741c6de25914f81a8ca0ca1107fc4c', 'signingMethod': 'ecdsa', 'proposalSignaturePubKey': null, 'proposalSignaturePubKeySig': null, 'lockUntilBlockHeight': null, 'gasPrice': null, 'from': null, 'nonce': null, 'gasLimit': null, 'data': null, 'tokenAddress': null, 'destinationTag': null, 'invoiceID': null, 'derivationStrategy': 'BIP44', 'creatorName': 'copayer 1', 'raw': '0100000001c05c50d820b4cbb4432af783a0a0b81f50cbf7c890939e713a9f03fb01eb7f4e050000006b483045022100ace0efb22eaf21b77d5e4a31a491ad06fbcfe700ace5abe8453ec0328c714cba02205090a44975d4b65b5e2f4473da038e83875826b369fc79558a741268ed574bb04121024d27ca79a3ed27a143cb9d1dff01e4e6445294679a700ca404ca449211d08aa7ffffffff0282233101000000001976a9149edd2399faccf4e57df08bef78962fa0228741cf88ac00b4c404000000001976a91451224bca38efcaa31d5340917c3f3f713b8b20e488ac00000000', 'isPending': true } ;
331
+ const signedTxp: ITxProposal = { 'actions': [{ 'version': '1.0.0', 'createdOn': 1588099987, 'copayerId': '671fee02a6c1c4de2e2609f9f9a6180dc03acfff6b759fe0b13a616ed4880065', 'type': 'accept', 'signatures': ['3045022100ace0efb22eaf21b77d5e4a31a491ad06fbcfe700ace5abe8453ec0328c714cba02205090a44975d4b65b5e2f4473da038e83875826b369fc79558a741268ed574bb0'], 'xpub': 'xpub6DVmxcjRgZdHNSEcXSiFtweVwMSTc3TMwRJ45nJYvyqvLbK1poPerupqh87rSoz27wvckb1CKnGZoLmLXSZyNGZtVd7neqSvdwJL6fceQpe', 'comment': null }], 'version': 3, 'createdOn': 1588099987, 'id': '7cea0d95-3308-48e7-a4be-3f16d66e1f5a', 'walletId': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'creatorId': '671fee02a6c1c4de2e2609f9f9a6180dc03acfff6b759fe0b13a616ed4880065', 'coin': 'bch', 'chain': 'bch', 'network': 'livenet', 'outputs': [{ 'amount': 80000000, 'toAddress': 'CPrtPWbp8cCftTQu5fzuLG5zPJNDHMMf8X' }], 'amount': 80000000, 'message': 'some message', 'payProUrl': null, 'changeAddress': { 'version': '1.0.0', 'createdOn': 1588099987, 'address': 'CWwtFMy3GMr5qMEtvEdUDjePfShzkJXCnh', 'walletId': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'isChange': true, 'path': 'm/1/0', 'publicKeys': ['02129acdcc600694b3ce55a2d05244186e806174eb0bafde20e5a6395ded647857'], 'coin': 'bch', 'network': 'livenet', 'type': 'P2PKH', 'hasActivity': null, 'beRegistered': null }, 'inputs': [{ 'txid': '4e7feb01fb039f3a719e9390c8f7cb501fb8a0a083f72a43b4cbb420d8505cc0', 'vout': 5, 'satoshis': 100000000, 'scriptPubKey': '76a914d391e62337ed194a1e428f32d14838e5d848180a88ac', 'address': 'qrfere3rxlk3jjs7g28n952g8rjasjqcpgx3axq70t', 'confirmations': 44, 'publicKeys': ['024d27ca79a3ed27a143cb9d1dff01e4e6445294679a700ca404ca449211d08aa7'], 'wallet': '7eaf4d32-c2fd-4262-864a-4c42fc9236f8', 'path': 'm/0/1' }], 'walletM': 1, 'walletN': 1, 'requiredSignatures': 1, 'requiredRejections': 1, 'status': 'accepted', 'txid': '8541ed35ac43e07e362a00ebab9448eefa63840c75ca38edff6785c223503a29', 'broadcastedOn': null, 'inputPaths': ['m/0/1'], 'outputOrder': [1, 0], 'fee': 2430, 'feeLevel': null, 'feePerKb': 10000, 'excludeUnconfirmedUtxos': false, 'addressType': 'P2PKH', 'customData': null, 'proposalSignature': '3045022100e8a1ac6eef882fb3e7311c725093317df99e5ed46f52fdee9064560bb757d1c902200b09f806a17d4c7950097b8714293725ce741c6de25914f81a8ca0ca1107fc4c', 'signingMethod': 'ecdsa', 'proposalSignaturePubKey': null, 'proposalSignaturePubKeySig': null, 'lockUntilBlockHeight': null, 'gasPrice': null, 'from': null, 'nonce': null, 'gasLimit': null, 'data': null, 'tokenAddress': null, 'destinationTag': null, 'invoiceID': null, 'creatorName': 'copayer 1', 'raw': '0100000001c05c50d820b4cbb4432af783a0a0b81f50cbf7c890939e713a9f03fb01eb7f4e050000006b483045022100ace0efb22eaf21b77d5e4a31a491ad06fbcfe700ace5abe8453ec0328c714cba02205090a44975d4b65b5e2f4473da038e83875826b369fc79558a741268ed574bb04121024d27ca79a3ed27a143cb9d1dff01e4e6445294679a700ca404ca449211d08aa7ffffffff0282233101000000001976a9149edd2399faccf4e57df08bef78962fa0228741cf88ac00b4c404000000001976a91451224bca38efcaa31d5340917c3f3f713b8b20e488ac00000000' };
@@ -168,7 +168,7 @@ const aTXP = () => {
168
168
  coin: 'doge',
169
169
  chain: 'doge',
170
170
  network: 'livenet',
171
- amount: (1.2550574e14).toString(),
171
+ amount: 1.2550574e14,
172
172
  message: 'some message',
173
173
  proposalSignature: '304402207e8ba2f9e88c1e7a76979f7e9df4d1cf43784d196b4b92f7f605386d0562216c022025356aae37397771a5fcb7520e97096fed197598a0e68883f6b30f3ccddd636c',
174
174
  changeAddress: {
@@ -240,7 +240,7 @@ const aTXP = () => {
240
240
  return txp;
241
241
  };
242
242
 
243
- const signedTxp = {
243
+ const signedTxp: ITxProposal = {
244
244
  actions: [
245
245
  {
246
246
  version: '1.0.0',
@@ -261,6 +261,7 @@ const signedTxp = {
261
261
  walletId: 'd98853c7-5a4b-48de-9f6c-8fb36aa271f1',
262
262
  creatorId: '5a49148ea402f06943b511912f31bc9114153e6055c38642fe789f7b2c7bf9f8',
263
263
  coin: 'doge',
264
+ chain: 'doge',
264
265
  network: 'testnet',
265
266
  outputs: [
266
267
  {
@@ -339,9 +340,6 @@ const signedTxp = {
339
340
  multisigTxId: null,
340
341
  destinationTag: null,
341
342
  invoiceID: null,
342
- derivationStrategy: 'BIP44',
343
343
  creatorName: 'copayer 1',
344
- raw: '0100000001b8a1d4773add3d5ca38652537310e9bd64d812d771e16f62b4a6e33e79f85453000000006b483045022100a9bee101f13eeb8f6bdf1b6421974a17b2aeb0bcf080526df20e93483a67bbca022071ba69e707430136fb65488b1e5413eb54279770b74b7e15fe15aeac16770ceb012102f4526941f57f37b8f1cd4970091ebcd1701980a82d26a781b2e44b384609eb22ffffffff026c81c9f6160900001976a914aeb332ea003a7efb5dab0dcc56d19fed84e26afb88acf4cb5156010000001976a914afbf96bfb28815cad8205c8f2f5a86819136664c88ac00000000',
345
- note: null,
346
- isPending: false
344
+ raw: '0100000001b8a1d4773add3d5ca38652537310e9bd64d812d771e16f62b4a6e33e79f85453000000006b483045022100a9bee101f13eeb8f6bdf1b6421974a17b2aeb0bcf080526df20e93483a67bbca022071ba69e707430136fb65488b1e5413eb54279770b74b7e15fe15aeac16770ceb012102f4526941f57f37b8f1cd4970091ebcd1701980a82d26a781b2e44b384609eb22ffffffff026c81c9f6160900001976a914aeb332ea003a7efb5dab0dcc56d19fed84e26afb88acf4cb5156010000001976a914afbf96bfb28815cad8205c8f2f5a86819136664c88ac00000000'
347
345
  };
@@ -168,7 +168,7 @@ const aTXP = () => {
168
168
  coin: 'ltc',
169
169
  chain: 'ltc',
170
170
  network: 'livenet',
171
- amount: '30000000',
171
+ amount: 30000000,
172
172
  message: 'some message',
173
173
  proposalSignature: '7035022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9',
174
174
  changeAddress: {
@@ -233,7 +233,7 @@ const aTXP = () => {
233
233
  return txp;
234
234
  };
235
235
 
236
- const signedTxp = {
236
+ const signedTxp: ITxProposal = {
237
237
  actions: [
238
238
  {
239
239
  version: '1.0.0',
@@ -250,6 +250,7 @@ const signedTxp = {
250
250
  ],
251
251
  version: 3,
252
252
  createdOn: 1626385821,
253
+ creatorName: 'Ben',
253
254
  id: 'b89d4f4b-0c36-4054-8e09-0d3867f1fc89',
254
255
  walletId: '10f76944-ac95-494a-ba32-1eba9a581332',
255
256
  creatorId: '16f48373387600f00741e74488da2f82409e82105f515e6c7a856368cc95fc78',
@@ -261,7 +262,6 @@ const signedTxp = {
261
262
  amount: 10000,
262
263
  toAddress: 'mu2QPdDVzsuAJAcMKbhqWqZYfeWcAonGEf',
263
264
  message: null,
264
- encryptedMessage: null
265
265
  }
266
266
  ],
267
267
  amount: 10000,
@@ -323,6 +323,5 @@ const signedTxp = {
323
323
  multisigContractAddress: undefined,
324
324
  multisigTxId: undefined,
325
325
  destinationTag: undefined,
326
- invoiceID: undefined,
327
- isPending: false
326
+ invoiceID: undefined
328
327
  };
@@ -91,7 +91,7 @@ const aTXP = function() {
91
91
  excludeUnconfirmedUtxos: true,
92
92
  addressType: 'P2PKH',
93
93
  customData: null,
94
- amount: '1000000',
94
+ amount: 1000000,
95
95
  fee: 10,
96
96
  version: 3,
97
97
  broadcastedOn: 1763669150,
@@ -108,12 +108,11 @@ const aTXP = function() {
108
108
  return txp;
109
109
  };
110
110
 
111
- const signedTxp = {
111
+ const signedTxp: ITxProposal = {
112
112
  creatorName: '{"iv":"aN+YwTvJRK73M7FfCFzIzA==","v":1,"iter":1,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","ct":"TqFvhWq2/F6ykA=="}',
113
113
  createdOn: 1763669147,
114
114
  id: 'a911faec-975e-4c53-a852-8ebf579ff1f6',
115
115
  txid: 'B6BB3DE3F87395619D108DC35E2CC88440C998D854A12E2E312BC5A8DC11F121',
116
- txids: '',
117
116
  walletId: '093352fc-a597-4837-94ee-8b9e3f1a5039',
118
117
  creatorId: 'c10c8e84ac963c539d86451aea8ce6f92dfaeeebbef1f5dd212d324301ea278f',
119
118
  coin: 'xrp',
@@ -122,8 +121,6 @@ const signedTxp = {
122
121
  message: '',
123
122
  payProUrl: '',
124
123
  from: 'rPsaG3gUYCPdoN2X1EgynYfYbwKeSbdTCN',
125
- changeAddress: '',
126
- escrowAddress: '',
127
124
  inputs: [],
128
125
  outputs: [{
129
126
  amount: 1000000,
@@ -165,42 +162,10 @@ const signedTxp = {
165
162
  proposalSignaturePubKey: '',
166
163
  proposalSignaturePubKeySig: '',
167
164
  signingMethod: 'ecdsa',
168
- lowFees: '',
169
165
  raw: [
170
166
  '12000022800000002400BF209C6140000000000F424068400000000000000A7321024DDE2306BEACF6D450495F40E69400824C99235FECEB742952FBA550C91F9C597446304402206188D1A90328D034F7D01E0ECEB6629AAEF47AF09EF33C4BF91871076AE60C81022056EE1DB7B90B7A701087FA8135E434616C5824F1CCC3FC87F741771E22BE9A138114F1B7FDA196A474A7A5CE0588E03B1BE41F8605978314D51E9EDD6905A6D2FDB4ADD86744C56323439285'
171
167
  ],
172
168
  nonce: 12525724,
173
- gasPrice: '',
174
- maxGasFee: '',
175
- priorityGasFee: '',
176
- txType: '',
177
- gasLimit: '',
178
- data: '',
179
- tokenAddress: '',
180
- multisigContractAddress: '',
181
- multisigTxId: '',
182
- destinationTag: '',
183
- invoiceID: '',
184
- lockUntilBlockHeight: '',
185
- instantAcceptanceEscrow: '',
186
- isTokenSwap: '',
187
- multiSendContractAddress: '',
188
- enableRBF: '',
189
- replaceTxByFee: '',
190
- multiTx: '',
191
- space: '',
192
- nonceAddress: '',
193
- blockHash: '',
194
- blockHeight: '',
195
- category: '',
196
- priorityFee: '',
197
- computeUnits: '',
198
- memo: '',
199
- fromAta: '',
200
- decimals: '',
201
- refreshOnPublish: '',
202
- prePublishRaw: '',
203
- note: '',
204
- derivationStrategy: 'BIP44',
205
- isPending: false
169
+ destinationTag: null,
170
+ invoiceID: ''
206
171
  };