@bitgo/abstract-utxo 11.6.0 → 11.6.1

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 (82) hide show
  1. package/dist/cjs/src/abstractUtxoCoin.d.ts +6 -22
  2. package/dist/cjs/src/abstractUtxoCoin.d.ts.map +1 -1
  3. package/dist/cjs/src/abstractUtxoCoin.js +14 -55
  4. package/dist/cjs/src/index.d.ts +0 -1
  5. package/dist/cjs/src/index.d.ts.map +1 -1
  6. package/dist/cjs/src/index.js +1 -2
  7. package/dist/cjs/src/transaction/decode.d.ts +2 -6
  8. package/dist/cjs/src/transaction/decode.d.ts.map +1 -1
  9. package/dist/cjs/src/transaction/decode.js +4 -22
  10. package/dist/cjs/src/transaction/explainTransaction.d.ts +3 -6
  11. package/dist/cjs/src/transaction/explainTransaction.d.ts.map +1 -1
  12. package/dist/cjs/src/transaction/explainTransaction.js +4 -12
  13. package/dist/cjs/src/transaction/fixedScript/explainTransaction.d.ts +1 -37
  14. package/dist/cjs/src/transaction/fixedScript/explainTransaction.d.ts.map +1 -1
  15. package/dist/cjs/src/transaction/fixedScript/explainTransaction.js +1 -344
  16. package/dist/cjs/src/transaction/fixedScript/index.d.ts +0 -2
  17. package/dist/cjs/src/transaction/fixedScript/index.d.ts.map +1 -1
  18. package/dist/cjs/src/transaction/fixedScript/index.js +2 -6
  19. package/dist/cjs/src/transaction/fixedScript/parseTransaction.d.ts.map +1 -1
  20. package/dist/cjs/src/transaction/fixedScript/parseTransaction.js +1 -2
  21. package/dist/cjs/src/transaction/fixedScript/signTransaction.d.ts +2 -12
  22. package/dist/cjs/src/transaction/fixedScript/signTransaction.d.ts.map +1 -1
  23. package/dist/cjs/src/transaction/fixedScript/signTransaction.js +17 -49
  24. package/dist/cjs/src/transaction/fixedScript/verifyTransaction.d.ts.map +1 -1
  25. package/dist/cjs/src/transaction/fixedScript/verifyTransaction.js +6 -37
  26. package/dist/cjs/src/transaction/index.d.ts +1 -1
  27. package/dist/cjs/src/transaction/index.d.ts.map +1 -1
  28. package/dist/cjs/src/transaction/index.js +2 -3
  29. package/dist/cjs/src/transaction/signTransaction.d.ts.map +1 -1
  30. package/dist/cjs/src/transaction/signTransaction.js +2 -8
  31. package/dist/cjs/src/transaction/types.d.ts +1 -4
  32. package/dist/cjs/src/transaction/types.d.ts.map +1 -1
  33. package/dist/cjs/src/transaction/types.js +1 -5
  34. package/dist/cjs/test/unit/transaction/fixedScript/explainPsbt.js +11 -47
  35. package/dist/cjs/test/unit/transaction/fixedScript/parsePsbt.js +18 -82
  36. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  37. package/dist/esm/abstractUtxoCoin.d.ts +6 -22
  38. package/dist/esm/abstractUtxoCoin.d.ts.map +1 -1
  39. package/dist/esm/abstractUtxoCoin.js +16 -57
  40. package/dist/esm/index.d.ts +0 -1
  41. package/dist/esm/index.d.ts.map +1 -1
  42. package/dist/esm/index.js +1 -2
  43. package/dist/esm/transaction/decode.d.ts +2 -6
  44. package/dist/esm/transaction/decode.d.ts.map +1 -1
  45. package/dist/esm/transaction/decode.js +4 -21
  46. package/dist/esm/transaction/explainTransaction.d.ts +3 -6
  47. package/dist/esm/transaction/explainTransaction.d.ts.map +1 -1
  48. package/dist/esm/transaction/explainTransaction.js +4 -12
  49. package/dist/esm/transaction/fixedScript/explainTransaction.d.ts +1 -37
  50. package/dist/esm/transaction/fixedScript/explainTransaction.d.ts.map +1 -1
  51. package/dist/esm/transaction/fixedScript/explainTransaction.js +2 -309
  52. package/dist/esm/transaction/fixedScript/index.d.ts +0 -2
  53. package/dist/esm/transaction/fixedScript/index.d.ts.map +1 -1
  54. package/dist/esm/transaction/fixedScript/index.js +1 -3
  55. package/dist/esm/transaction/fixedScript/parseTransaction.d.ts.map +1 -1
  56. package/dist/esm/transaction/fixedScript/parseTransaction.js +1 -2
  57. package/dist/esm/transaction/fixedScript/signTransaction.d.ts +2 -12
  58. package/dist/esm/transaction/fixedScript/signTransaction.d.ts.map +1 -1
  59. package/dist/esm/transaction/fixedScript/signTransaction.js +17 -49
  60. package/dist/esm/transaction/fixedScript/verifyTransaction.d.ts.map +1 -1
  61. package/dist/esm/transaction/fixedScript/verifyTransaction.js +6 -4
  62. package/dist/esm/transaction/index.d.ts +1 -1
  63. package/dist/esm/transaction/index.d.ts.map +1 -1
  64. package/dist/esm/transaction/index.js +2 -2
  65. package/dist/esm/transaction/signTransaction.d.ts.map +1 -1
  66. package/dist/esm/transaction/signTransaction.js +3 -9
  67. package/dist/esm/transaction/types.d.ts +1 -4
  68. package/dist/esm/transaction/types.d.ts.map +1 -1
  69. package/dist/esm/transaction/types.js +2 -4
  70. package/package.json +5 -5
  71. package/dist/cjs/src/transaction/fixedScript/signLegacyTransaction.d.ts +0 -32
  72. package/dist/cjs/src/transaction/fixedScript/signLegacyTransaction.d.ts.map +0 -1
  73. package/dist/cjs/src/transaction/fixedScript/signLegacyTransaction.js +0 -163
  74. package/dist/cjs/src/transaction/fixedScript/signPsbtUtxolib.d.ts +0 -20
  75. package/dist/cjs/src/transaction/fixedScript/signPsbtUtxolib.d.ts.map +0 -1
  76. package/dist/cjs/src/transaction/fixedScript/signPsbtUtxolib.js +0 -157
  77. package/dist/esm/transaction/fixedScript/signLegacyTransaction.d.ts +0 -32
  78. package/dist/esm/transaction/fixedScript/signLegacyTransaction.d.ts.map +0 -1
  79. package/dist/esm/transaction/fixedScript/signLegacyTransaction.js +0 -123
  80. package/dist/esm/transaction/fixedScript/signPsbtUtxolib.d.ts +0 -20
  81. package/dist/esm/transaction/fixedScript/signPsbtUtxolib.d.ts.map +0 -1
  82. package/dist/esm/transaction/fixedScript/signPsbtUtxolib.js +0 -117
@@ -1,123 +0,0 @@
1
- import assert from 'assert';
2
- import * as utxolib from '@bitgo/utxo-lib';
3
- import { bitgo } from '@bitgo/utxo-lib';
4
- import { isTriple } from '@bitgo/sdk-core';
5
- import { BIP32 } from '@bitgo/wasm-utxo';
6
- import debugLib from 'debug';
7
- import { isWalletUnspent } from '../../unspent';
8
- import { toUtxolibBIP32 } from '../../wasmUtil';
9
- import { getReplayProtectionAddresses } from './replayProtection';
10
- import { InputSigningError, TransactionSigningError } from './SigningError';
11
- const debug = debugLib('bitgo:v2:utxo');
12
- const { signInputWithUnspent, toOutput } = utxolib.bitgo;
13
- const UTXOLIB_VALID_CHAIN_CODES = new Set([0, 1, 10, 11, 20, 21, 30, 31, 40, 41]);
14
- /**
15
- * Sign all inputs of a wallet transaction and verify signatures after signing.
16
- * Collects and logs signing errors and verification errors, throws error in the end if any of them
17
- * failed.
18
- *
19
- * @param transaction - wallet transaction (builder) to be signed
20
- * @param unspents - transaction unspents
21
- * @param walletSigner - signing parameters
22
- * @param coinName - coin name for network-specific logic
23
- * @param isLastSignature - Returns full-signed transaction when true. Builds half-signed when false.
24
- * @param replayProtectionAddresses - List of replay protection addresses to skip signing
25
- */
26
- export function signAndVerifyWalletTransaction(transaction, unspents, walletSigner, coinName, { isLastSignature, replayProtectionAddresses, }) {
27
- const network = transaction.network;
28
- if (replayProtectionAddresses === undefined) {
29
- replayProtectionAddresses = getReplayProtectionAddresses(coinName);
30
- }
31
- const prevOutputs = unspents.map((u) => toOutput(u, network));
32
- let txBuilder;
33
- if (transaction instanceof utxolib.bitgo.UtxoTransaction) {
34
- txBuilder = utxolib.bitgo.createTransactionBuilderFromTransaction(transaction, prevOutputs);
35
- if (transaction.ins.length !== unspents.length) {
36
- throw new Error(`transaction inputs must match unspents`);
37
- }
38
- }
39
- else if (transaction instanceof utxolib.bitgo.UtxoTransactionBuilder) {
40
- txBuilder = transaction;
41
- }
42
- else {
43
- throw new Error(`must pass UtxoTransaction or UtxoTransactionBuilder`);
44
- }
45
- const signErrors = unspents
46
- .map((unspent, inputIndex) => {
47
- if (replayProtectionAddresses.includes(unspent.address)) {
48
- debug('Skipping signature for input %d of %d (RP input?)', inputIndex + 1, unspents.length);
49
- return;
50
- }
51
- if (!isWalletUnspent(unspent)) {
52
- return InputSigningError.expectedWalletUnspent(inputIndex, null, unspent);
53
- }
54
- if (!UTXOLIB_VALID_CHAIN_CODES.has(unspent.chain)) {
55
- return new InputSigningError(inputIndex, null, unspent, new Error(`Chain code ${unspent.chain} is not supported for legacy signing`));
56
- }
57
- try {
58
- signInputWithUnspent(txBuilder, inputIndex, unspent, walletSigner);
59
- debug('Successfully signed input %d of %d', inputIndex + 1, unspents.length);
60
- }
61
- catch (e) {
62
- return new InputSigningError(inputIndex, null, unspent, e);
63
- }
64
- })
65
- .filter((e) => e !== undefined);
66
- const signedTransaction = isLastSignature ? txBuilder.build() : txBuilder.buildIncomplete();
67
- const verifyErrors = signedTransaction.ins
68
- .map((input, inputIndex) => {
69
- const unspent = unspents[inputIndex];
70
- if (replayProtectionAddresses.includes(unspent.address)) {
71
- debug('Skipping input signature %d of %d (unspent from replay protection address which is platform signed only)', inputIndex + 1, unspents.length);
72
- return;
73
- }
74
- if (!isWalletUnspent(unspent)) {
75
- return InputSigningError.expectedWalletUnspent(inputIndex, null, unspent);
76
- }
77
- if (!UTXOLIB_VALID_CHAIN_CODES.has(unspent.chain)) {
78
- return new InputSigningError(inputIndex, null, unspent, new Error(`Chain code ${unspent.chain} is not supported for legacy verification`));
79
- }
80
- const walletUnspent = unspent;
81
- try {
82
- const publicKey = walletSigner.deriveForChainAndIndex(walletUnspent.chain, walletUnspent.index).signer.publicKey;
83
- if (!utxolib.bitgo.verifySignatureWithPublicKey(signedTransaction, inputIndex, prevOutputs, publicKey)) {
84
- return new InputSigningError(inputIndex, null, unspent, new Error(`invalid signature`));
85
- }
86
- }
87
- catch (e) {
88
- debug('Invalid signature');
89
- return new InputSigningError(inputIndex, null, unspent, e);
90
- }
91
- })
92
- .filter((e) => e !== undefined);
93
- if (signErrors.length || verifyErrors.length) {
94
- throw new TransactionSigningError(signErrors, verifyErrors);
95
- }
96
- return signedTransaction;
97
- }
98
- export function signLegacyTransaction(tx, signerKeychain, coinName, params) {
99
- switch (params.signingStep) {
100
- case 'signerNonce':
101
- case 'cosignerNonce':
102
- /**
103
- * In certain cases, the caller of this method may not know whether the txHex contains a psbt with taproot key path spend input(s).
104
- * Instead of throwing error, no-op and return the txHex. So that the caller can call this method in the same sequence.
105
- */
106
- return tx;
107
- }
108
- if (tx.ins.length !== params.txInfo?.unspents?.length) {
109
- throw new Error('length of unspents array should equal to the number of transaction inputs');
110
- }
111
- if (!params.pubs || !isTriple(params.pubs)) {
112
- throw new Error(`must provide xpub array`);
113
- }
114
- const keychains = params.pubs.map((pub) => toUtxolibBIP32(BIP32.fromBase58(pub)));
115
- const cosignerPub = params.cosignerPub ?? params.pubs[2];
116
- const cosignerKeychain = toUtxolibBIP32(BIP32.fromBase58(cosignerPub));
117
- assert(signerKeychain);
118
- const walletSigner = new bitgo.WalletUnspentSigner(keychains, toUtxolibBIP32(signerKeychain), cosignerKeychain);
119
- return signAndVerifyWalletTransaction(tx, params.txInfo.unspents, walletSigner, coinName, {
120
- isLastSignature: params.isLastSignature,
121
- });
122
- }
123
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbkxlZ2FjeVRyYW5zYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3RyYW5zYWN0aW9uL2ZpeGVkU2NyaXB0L3NpZ25MZWdhY3lUcmFuc2FjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxLQUFLLE9BQU8sTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBVSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxLQUFLLEVBQVMsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLFFBQVEsTUFBTSxPQUFPLENBQUM7QUFHN0IsT0FBTyxFQUFFLGVBQWUsRUFBZ0IsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUV4QyxNQUFNLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUl6RCxNQUFNLHlCQUF5QixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFVLENBQUMsQ0FBQztBQUUzRjs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSw4QkFBOEIsQ0FDNUMsV0FBbUcsRUFD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QUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFtQyxDQUFDO0lBQ3BILE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6RCxNQUFNLGdCQUFnQixHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7SUFFdkUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3ZCLE1BQU0sWUFBWSxHQUFHLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUNoRCxTQUFTLEVBQ1QsY0FBYyxDQUFDLGNBQWMsQ0FBQyxFQUM5QixnQkFBZ0IsQ0FDakIsQ0FBQztJQUNGLE9BQU8sOEJBQThCLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUU7UUFDeEYsZUFBZSxFQUFFLE1BQU0sQ0FBQyxlQUFlO0tBQ3hDLENBQTJDLENBQUM7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHsgYml0Z28gfSBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHsgaXNUcmlwbGUsIFRyaXBsZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBCSVAzMiwgYmlwMzIgfSBmcm9tICdAYml0Z28vd2FzbS11dHhvJztcbmltcG9ydCBkZWJ1Z0xpYiBmcm9tICdkZWJ1Zyc7XG5cbmltcG9ydCB7IFV0eG9Db2luTmFtZSB9IGZyb20gJy4uLy4uL25hbWVzJztcbmltcG9ydCB7IGlzV2FsbGV0VW5zcGVudCwgdHlwZSBVbnNwZW50IH0gZnJvbSAnLi4vLi4vdW5zcGVudCc7XG5pbXBvcnQgeyB0b1V0eG9saWJCSVAzMiB9IGZyb20gJy4uLy4uL3dhc21VdGlsJztcblxuaW1wb3J0IHsgZ2V0UmVwbGF5UHJvdGVjdGlvbkFkZHJlc3NlcyB9IGZyb20gJy4vcmVwbGF5UHJvdGVjdGlvbic7XG5pbXBvcnQgeyBJbnB1dFNpZ25pbmdFcnJvciwgVHJhbnNhY3Rpb25TaWduaW5nRXJyb3IgfSBmcm9tICcuL1NpZ25pbmdFcnJvcic7XG5cbmNvbnN0IGRlYnVnID0gZGVidWdMaWIoJ2JpdGdvOnYyOnV0eG8nKTtcblxuY29uc3QgeyBzaWduSW5wdXRXaXRoVW5zcGVudCwgdG9PdXRwdXQgfSA9IHV0eG9saWIuYml0Z287XG5cbnR5cGUgUm9vdFdhbGxldEtleXMgPSB1dHhvbGliLmJpdGdvLlJvb3RXYWxsZXRLZXlzO1xuXG5jb25zdCBVVFhPTElCX1ZBTElEX0NIQUlOX0NPREVTID0gbmV3IFNldChbMCwgMSwgMTAsIDExLCAyMCwgMjEsIDMwLCAzMSwgNDAsIDQxXSBhcyBjb25zdCk7XG5cbi8qKlxuICogU2lnbiBhbGwgaW5wdXRzIG9mIGEgd2FsbGV0IHRyYW5zYWN0aW9uIGFuZCB2ZXJpZnkgc2lnbmF0dXJlcyBhZnRlciBzaWduaW5nLlxuICogQ29sbGVjdHMgYW5kIGxvZ3Mgc2lnbmluZyBlcnJvcnMgYW5kIHZlcmlmaWNhdGlvbiBlcnJvcnMsIHRocm93cyBlcnJvciBpbiB0aGUgZW5kIGlmIGFueSBvZiB0aGVtXG4gKiBmYWlsZWQuXG4gKlxuICogQHBhcmFtIHRyYW5zYWN0aW9uIC0gd2FsbGV0IHRyYW5zYWN0aW9uIChidWlsZGVyKSB0byBiZSBzaWduZWRcbiAqIEBwYXJhbSB1bnNwZW50cyAtIHRyYW5zYWN0aW9uIHVuc3BlbnRzXG4gKiBAcGFyYW0gd2FsbGV0U2lnbmVyIC0gc2lnbmluZyBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0gY29pbk5hbWUgLSBjb2luIG5hbWUgZm9yIG5ldHdvcmstc3BlY2lmaWMgbG9naWNcbiAqIEBwYXJhbSBpc0xhc3RTaWduYXR1cmUgLSBSZXR1cm5zIGZ1bGwtc2lnbmVkIHRyYW5zYWN0aW9uIHdoZW4gdHJ1ZS4gQnVpbGRzIGhhbGYtc2lnbmVkIHdoZW4gZmFsc2UuXG4gKiBAcGFyYW0gcmVwbGF5UHJvdGVjdGlvbkFkZHJlc3NlcyAtIExpc3Qgb2YgcmVwbGF5IHByb3RlY3Rpb24gYWRkcmVzc2VzIHRvIHNraXAgc2lnbmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICB0cmFuc2FjdGlvbjogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj4gfCB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4sXG4gIHVuc3BlbnRzOiBVbnNwZW50PFROdW1iZXI+W10sXG4gIHdhbGxldFNpZ25lcjogdXR4b2xpYi5iaXRnby5XYWxsZXRVbnNwZW50U2lnbmVyPFJvb3RXYWxsZXRLZXlzPixcbiAgY29pbk5hbWU6IFV0eG9Db2luTmFtZSxcbiAge1xuICAgIGlzTGFzdFNpZ25hdHVyZSxcbiAgICByZXBsYXlQcm90ZWN0aW9uQWRkcmVzc2VzLFxuICB9OiB7XG4gICAgaXNMYXN0U2lnbmF0dXJlOiBib29sZWFuO1xuICAgIHJlcGxheVByb3RlY3Rpb25BZGRyZXNzZXM/OiBzdHJpbmdbXTtcbiAgfVxuKTogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj4ge1xuICBjb25zdCBuZXR3b3JrID0gdHJhbnNhY3Rpb24ubmV0d29yayBhcyB1dHhvbGliLk5ldHdvcms7XG4gIGlmIChyZXBsYXlQcm90ZWN0aW9uQWRkcmVzc2VzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXBsYXlQcm90ZWN0aW9uQWRkcmVzc2VzID0gZ2V0UmVwbGF5UHJvdGVjdGlvbkFkZHJlc3Nlcyhjb2luTmFtZSk7XG4gIH1cbiAgY29uc3QgcHJldk91dHB1dHMgPSB1bnNwZW50cy5tYXAoKHUpID0+IHRvT3V0cHV0KHUsIG5ldHdvcmspKTtcblxuICBsZXQgdHhCdWlsZGVyOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj47XG4gIGlmICh0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uKSB7XG4gICAgdHhCdWlsZGVyID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkJ1aWxkZXJGcm9tVHJhbnNhY3Rpb248VE51bWJlcj4odHJhbnNhY3Rpb24sIHByZXZPdXRwdXRzKTtcbiAgICBpZiAodHJhbnNhY3Rpb24uaW5zLmxlbmd0aCAhPT0gdW5zcGVudHMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRyYW5zYWN0aW9uIGlucHV0cyBtdXN0IG1hdGNoIHVuc3BlbnRzYCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb25CdWlsZGVyKSB7XG4gICAgdHhCdWlsZGVyID0gdHJhbnNhY3Rpb247XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBtdXN0IHBhc3MgVXR4b1RyYW5zYWN0aW9uIG9yIFV0eG9UcmFuc2FjdGlvbkJ1aWxkZXJgKTtcbiAgfVxuXG4gIGNvbnN0IHNpZ25FcnJvcnM6IElucHV0U2lnbmluZ0Vycm9yPFROdW1iZXI+W10gPSB1bnNwZW50c1xuICAgIC5tYXAoKHVuc3BlbnQ6IFVuc3BlbnQ8VE51bWJlcj4sIGlucHV0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgaWYgKHJlcGxheVByb3RlY3Rpb25BZGRyZXNzZXMuaW5jbHVkZXModW5zcGVudC5hZGRyZXNzKSkge1xuICAgICAgICBkZWJ1ZygnU2tpcHBpbmcgc2lnbmF0dXJlIGZvciBpbnB1dCAlZCBvZiAlZCAoUlAgaW5wdXQ/KScsIGlucHV0SW5kZXggKyAxLCB1bnNwZW50cy5sZW5ndGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWlzV2FsbGV0VW5zcGVudDxUTnVtYmVyPih1bnNwZW50KSkge1xuICAgICAgICByZXR1cm4gSW5wdXRTaWduaW5nRXJyb3IuZXhwZWN0ZWRXYWxsZXRVbnNwZW50PFROdW1iZXI+KGlucHV0SW5kZXgsIG51bGwsIHVuc3BlbnQpO1xuICAgICAgfVxuICAgICAgaWYgKCFVVFhPTElCX1ZBTElEX0NIQUlOX0NPREVTLmhhcyh1bnNwZW50LmNoYWluIGFzIHV0eG9saWIuYml0Z28uQ2hhaW5Db2RlKSkge1xuICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yPFROdW1iZXI+KFxuICAgICAgICAgIGlucHV0SW5kZXgsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICB1bnNwZW50LFxuICAgICAgICAgIG5ldyBFcnJvcihgQ2hhaW4gY29kZSAke3Vuc3BlbnQuY2hhaW59IGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBzaWduaW5nYClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHNpZ25JbnB1dFdpdGhVbnNwZW50PFROdW1iZXI+KFxuICAgICAgICAgIHR4QnVpbGRlcixcbiAgICAgICAgICBpbnB1dEluZGV4LFxuICAgICAgICAgIHVuc3BlbnQgYXMgdW5rbm93biBhcyB1dHhvbGliLmJpdGdvLldhbGxldFVuc3BlbnQ8VE51bWJlcj4sXG4gICAgICAgICAgd2FsbGV0U2lnbmVyXG4gICAgICAgICk7XG4gICAgICAgIGRlYnVnKCdTdWNjZXNzZnVsbHkgc2lnbmVkIGlucHV0ICVkIG9mICVkJywgaW5wdXRJbmRleCArIDEsIHVuc3BlbnRzLmxlbmd0aCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3I8VE51bWJlcj4oaW5wdXRJbmRleCwgbnVsbCwgdW5zcGVudCwgZSk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuZmlsdGVyKChlKTogZSBpcyBJbnB1dFNpZ25pbmdFcnJvcjxUTnVtYmVyPiA9PiBlICE9PSB1bmRlZmluZWQpO1xuXG4gIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gaXNMYXN0U2lnbmF0dXJlID8gdHhCdWlsZGVyLmJ1aWxkKCkgOiB0eEJ1aWxkZXIuYnVpbGRJbmNvbXBsZXRlKCk7XG5cbiAgY29uc3QgdmVyaWZ5RXJyb3JzOiBJbnB1dFNpZ25pbmdFcnJvcjxUTnVtYmVyPltdID0gc2lnbmVkVHJhbnNhY3Rpb24uaW5zXG4gICAgLm1hcCgoaW5wdXQsIGlucHV0SW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHVuc3BlbnQgPSB1bnNwZW50c1tpbnB1dEluZGV4XSBhcyBVbnNwZW50PFROdW1iZXI+O1xuICAgICAgaWYgKHJlcGxheVByb3RlY3Rpb25BZGRyZXNzZXMuaW5jbHVkZXModW5zcGVudC5hZGRyZXNzKSkge1xuICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAnU2tpcHBpbmcgaW5wdXQgc2lnbmF0dXJlICVkIG9mICVkICh1bnNwZW50IGZyb20gcmVwbGF5IHByb3RlY3Rpb24gYWRkcmVzcyB3aGljaCBpcyBwbGF0Zm9ybSBzaWduZWQgb25seSknLFxuICAgICAgICAgIGlucHV0SW5kZXggKyAxLFxuICAgICAgICAgIHVuc3BlbnRzLmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWlzV2FsbGV0VW5zcGVudDxUTnVtYmVyPih1bnNwZW50KSkge1xuICAgICAgICByZXR1cm4gSW5wdXRTaWduaW5nRXJyb3IuZXhwZWN0ZWRXYWxsZXRVbnNwZW50PFROdW1iZXI+KGlucHV0SW5kZXgsIG51bGwsIHVuc3BlbnQpO1xuICAgICAgfVxuICAgICAgaWYgKCFVVFhPTElCX1ZBTElEX0NIQUlOX0NPREVTLmhhcyh1bnNwZW50LmNoYWluIGFzIHV0eG9saWIuYml0Z28uQ2hhaW5Db2RlKSkge1xuICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yPFROdW1iZXI+KFxuICAgICAgICAgIGlucHV0SW5kZXgsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICB1bnNwZW50LFxuICAgICAgICAgIG5ldyBFcnJvcihgQ2hhaW4gY29kZSAke3Vuc3BlbnQuY2hhaW59IGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSB2ZXJpZmljYXRpb25gKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3Qgd2FsbGV0VW5zcGVudCA9IHVuc3BlbnQ7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwdWJsaWNLZXkgPSB3YWxsZXRTaWduZXIuZGVyaXZlRm9yQ2hhaW5BbmRJbmRleChcbiAgICAgICAgICB3YWxsZXRVbnNwZW50LmNoYWluIGFzIHV0eG9saWIuYml0Z28uQ2hhaW5Db2RlLFxuICAgICAgICAgIHdhbGxldFVuc3BlbnQuaW5kZXhcbiAgICAgICAgKS5zaWduZXIucHVibGljS2V5O1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIXV0eG9saWIuYml0Z28udmVyaWZ5U2lnbmF0dXJlV2l0aFB1YmxpY0tleTxUTnVtYmVyPihzaWduZWRUcmFuc2FjdGlvbiwgaW5wdXRJbmRleCwgcHJldk91dHB1dHMsIHB1YmxpY0tleSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFNpZ25pbmdFcnJvcihpbnB1dEluZGV4LCBudWxsLCB1bnNwZW50LCBuZXcgRXJyb3IoYGludmFsaWQgc2lnbmF0dXJlYCkpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGRlYnVnKCdJbnZhbGlkIHNpZ25hdHVyZScpO1xuICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yPFROdW1iZXI+KGlucHV0SW5kZXgsIG51bGwsIHVuc3BlbnQsIGUpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLmZpbHRlcigoZSk6IGUgaXMgSW5wdXRTaWduaW5nRXJyb3I8VE51bWJlcj4gPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBpZiAoc2lnbkVycm9ycy5sZW5ndGggfHwgdmVyaWZ5RXJyb3JzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUcmFuc2FjdGlvblNpZ25pbmdFcnJvcihzaWduRXJyb3JzLCB2ZXJpZnlFcnJvcnMpO1xuICB9XG5cbiAgcmV0dXJuIHNpZ25lZFRyYW5zYWN0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2lnbkxlZ2FjeVRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICB0eDogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj4sXG4gIHNpZ25lcktleWNoYWluOiBiaXAzMi5CSVAzMkludGVyZmFjZSB8IHVuZGVmaW5lZCxcbiAgY29pbk5hbWU6IFV0eG9Db2luTmFtZSxcbiAgcGFyYW1zOiB7XG4gICAgaXNMYXN0U2lnbmF0dXJlOiBib29sZWFuO1xuICAgIHNpZ25pbmdTdGVwOiAnc2lnbmVyTm9uY2UnIHwgJ2Nvc2lnbmVyTm9uY2UnIHwgJ3NpZ25lclNpZ25hdHVyZScgfCB1bmRlZmluZWQ7XG4gICAgdHhJbmZvOiB7IHVuc3BlbnRzPzogVW5zcGVudDxUTnVtYmVyPltdIH0gfCB1bmRlZmluZWQ7XG4gICAgcHViczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gICAgY29zaWduZXJQdWI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgfVxuKTogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj4ge1xuICBzd2l0Y2ggKHBhcmFtcy5zaWduaW5nU3RlcCkge1xuICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICBjYXNlICdjb3NpZ25lck5vbmNlJzpcbiAgICAgIC8qKlxuICAgICAgICogSW4gY2VydGFpbiBjYXNlcywgdGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZCBtYXkgbm90IGtub3cgd2hldGhlciB0aGUgdHhIZXggY29udGFpbnMgYSBwc2J0IHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dChzKS5cbiAgICAgICAqIEluc3RlYWQgb2YgdGhyb3dpbmcgZXJyb3IsIG5vLW9wIGFuZCByZXR1cm4gdGhlIHR4SGV4LiBTbyB0aGF0IHRoZSBjYWxsZXIgY2FuIGNhbGwgdGhpcyBtZXRob2QgaW4gdGhlIHNhbWUgc2VxdWVuY2UuXG4gICAgICAgKi9cbiAgICAgIHJldHVybiB0eDtcbiAgfVxuXG4gIGlmICh0eC5pbnMubGVuZ3RoICE9PSBwYXJhbXMudHhJbmZvPy51bnNwZW50cz8ubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2YgdW5zcGVudHMgYXJyYXkgc2hvdWxkIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgdHJhbnNhY3Rpb24gaW5wdXRzJyk7XG4gIH1cblxuICBpZiAoIXBhcmFtcy5wdWJzIHx8ICFpc1RyaXBsZShwYXJhbXMucHVicykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG11c3QgcHJvdmlkZSB4cHViIGFycmF5YCk7XG4gIH1cblxuICBjb25zdCBrZXljaGFpbnMgPSBwYXJhbXMucHVicy5tYXAoKHB1YikgPT4gdG9VdHhvbGliQklQMzIoQklQMzIuZnJvbUJhc2U1OChwdWIpKSkgYXMgVHJpcGxlPHV0eG9saWIuQklQMzJJbnRlcmZhY2U+O1xuICBjb25zdCBjb3NpZ25lclB1YiA9IHBhcmFtcy5jb3NpZ25lclB1YiA/PyBwYXJhbXMucHVic1syXTtcbiAgY29uc3QgY29zaWduZXJLZXljaGFpbiA9IHRvVXR4b2xpYkJJUDMyKEJJUDMyLmZyb21CYXNlNTgoY29zaWduZXJQdWIpKTtcblxuICBhc3NlcnQoc2lnbmVyS2V5Y2hhaW4pO1xuICBjb25zdCB3YWxsZXRTaWduZXIgPSBuZXcgYml0Z28uV2FsbGV0VW5zcGVudFNpZ25lcjxSb290V2FsbGV0S2V5cz4oXG4gICAga2V5Y2hhaW5zLFxuICAgIHRvVXR4b2xpYkJJUDMyKHNpZ25lcktleWNoYWluKSxcbiAgICBjb3NpZ25lcktleWNoYWluXG4gICk7XG4gIHJldHVybiBzaWduQW5kVmVyaWZ5V2FsbGV0VHJhbnNhY3Rpb24odHgsIHBhcmFtcy50eEluZm8udW5zcGVudHMsIHdhbGxldFNpZ25lciwgY29pbk5hbWUsIHtcbiAgICBpc0xhc3RTaWduYXR1cmU6IHBhcmFtcy5pc0xhc3RTaWduYXR1cmUsXG4gIH0pIGFzIHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+O1xufVxuIl19
@@ -1,20 +0,0 @@
1
- import * as utxolib from '@bitgo/utxo-lib';
2
- import { Musig2Participant } from './musig2';
3
- export type PsbtParsedScriptType = 'p2sh' | 'p2wsh' | 'p2shP2wsh' | 'p2shP2pk' | 'taprootKeyPathSpend' | 'taprootScriptPathSpend' | 'p2trLegacy' | 'p2trMusig2ScriptPath' | 'p2trMusig2KeyPath';
4
- /**
5
- * Sign all inputs of a psbt and verify signatures after signing.
6
- * Collects and logs signing errors and verification errors, throws error in the end if any of them
7
- * failed.
8
- *
9
- * This function mirrors signAndVerifyWalletTransaction, but is used for signing PSBTs instead of
10
- * using TransactionBuilder
11
- *
12
- * @param psbt
13
- * @param signerKeychain
14
- */
15
- export declare function signAndVerifyPsbt(psbt: utxolib.bitgo.UtxoPsbt, signerKeychain: utxolib.BIP32Interface): utxolib.bitgo.UtxoPsbt;
16
- export declare function signPsbtWithMusig2ParticipantUtxolib(coin: Musig2Participant<utxolib.bitgo.UtxoPsbt>, tx: utxolib.bitgo.UtxoPsbt, signerKeychain: utxolib.BIP32Interface | undefined, params: {
17
- signingStep: 'signerNonce' | 'cosignerNonce' | 'signerSignature' | undefined;
18
- walletId: string | undefined;
19
- }): Promise<utxolib.bitgo.UtxoPsbt>;
20
- //# sourceMappingURL=signPsbtUtxolib.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signPsbtUtxolib.d.ts","sourceRoot":"","sources":["../../../../src/transaction/fixedScript/signPsbtUtxolib.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAK3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI7C,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,OAAO,GACP,WAAW,GACX,UAAU,GACV,qBAAqB,GACrB,wBAAwB,GAExB,YAAY,GACZ,sBAAsB,GACtB,mBAAmB,CAAC;AAExB;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAC5B,cAAc,EAAE,OAAO,CAAC,cAAc,GACrC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAwDxB;AAYD,wBAAsB,oCAAoC,CACxD,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC/C,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAC1B,cAAc,EAAE,OAAO,CAAC,cAAc,GAAG,SAAS,EAClD,MAAM,EAAE;IACN,WAAW,EAAE,aAAa,GAAG,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAC7E,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,GACA,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CA6CjC"}
@@ -1,117 +0,0 @@
1
- import assert from 'assert';
2
- import * as utxolib from '@bitgo/utxo-lib';
3
- import { bitgo } from '@bitgo/utxo-lib';
4
- import debugLib from 'debug';
5
- import { InputSigningError, TransactionSigningError } from './SigningError';
6
- const debug = debugLib('bitgo:v2:utxo');
7
- /**
8
- * Sign all inputs of a psbt and verify signatures after signing.
9
- * Collects and logs signing errors and verification errors, throws error in the end if any of them
10
- * failed.
11
- *
12
- * This function mirrors signAndVerifyWalletTransaction, but is used for signing PSBTs instead of
13
- * using TransactionBuilder
14
- *
15
- * @param psbt
16
- * @param signerKeychain
17
- */
18
- export function signAndVerifyPsbt(psbt, signerKeychain) {
19
- const txInputs = psbt.txInputs;
20
- const outputIds = [];
21
- const scriptTypes = [];
22
- const signErrors = psbt.data.inputs
23
- .map((input, inputIndex) => {
24
- const outputId = utxolib.bitgo.formatOutputId(utxolib.bitgo.getOutputIdForInput(txInputs[inputIndex]));
25
- outputIds.push(outputId);
26
- const { scriptType } = utxolib.bitgo.parsePsbtInput(input);
27
- scriptTypes.push(scriptType);
28
- if (scriptType === 'p2shP2pk') {
29
- debug('Skipping signature for input %d of %d (RP input?)', inputIndex + 1, psbt.data.inputs.length);
30
- return;
31
- }
32
- try {
33
- psbt.signInputHD(inputIndex, signerKeychain);
34
- debug('Successfully signed input %d of %d', inputIndex + 1, psbt.data.inputs.length);
35
- }
36
- catch (e) {
37
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, e);
38
- }
39
- })
40
- .filter((e) => e !== undefined);
41
- const verifyErrors = psbt.data.inputs
42
- .map((input, inputIndex) => {
43
- const scriptType = scriptTypes[inputIndex];
44
- if (scriptType === 'p2shP2pk') {
45
- debug('Skipping input signature %d of %d (unspent from replay protection address which is platform signed only)', inputIndex + 1, psbt.data.inputs.length);
46
- return;
47
- }
48
- const outputId = outputIds[inputIndex];
49
- try {
50
- if (!psbt.validateSignaturesOfInputHD(inputIndex, signerKeychain)) {
51
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, new Error(`invalid signature`));
52
- }
53
- }
54
- catch (e) {
55
- debug('Invalid signature');
56
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, e);
57
- }
58
- })
59
- .filter((e) => e !== undefined);
60
- if (signErrors.length || verifyErrors.length) {
61
- throw new TransactionSigningError(signErrors, verifyErrors);
62
- }
63
- return psbt;
64
- }
65
- /**
66
- * Key Value: Unsigned tx id => PSBT
67
- * It is used to cache PSBTs with taproot key path (MuSig2) inputs during external express signer is activated.
68
- * Reason: MuSig2 signer secure nonce is cached in the UtxoPsbt object. It will be required during the signing step.
69
- * For more info, check SignTransactionOptions.signingStep
70
- *
71
- * TODO BTC-276: This cache may need to be done with LRU like memory safe caching if memory issues comes up.
72
- */
73
- const PSBT_CACHE = new Map();
74
- export async function signPsbtWithMusig2ParticipantUtxolib(coin, tx, signerKeychain, params) {
75
- if (bitgo.isTransactionWithKeyPathSpendInput(tx)) {
76
- switch (params.signingStep) {
77
- case 'signerNonce':
78
- assert(signerKeychain);
79
- tx.setAllInputsMusig2NonceHD(signerKeychain);
80
- PSBT_CACHE.set(tx.getUnsignedTx().getId(), tx);
81
- return tx;
82
- case 'cosignerNonce':
83
- assert(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
84
- return await coin.getMusig2Nonces(tx, params.walletId);
85
- case 'signerSignature':
86
- const txId = tx.getUnsignedTx().getId();
87
- const psbt = PSBT_CACHE.get(txId);
88
- assert(psbt, `Psbt is missing from txCache (cache size ${PSBT_CACHE.size}).
89
- This may be due to the request being routed to a different BitGo-Express instance that for signing step 'signerNonce'.`);
90
- PSBT_CACHE.delete(txId);
91
- tx = psbt.combine(tx);
92
- break;
93
- default:
94
- // this instance is not an external signer
95
- assert(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
96
- assert(signerKeychain);
97
- tx.setAllInputsMusig2NonceHD(signerKeychain);
98
- const response = await coin.getMusig2Nonces(tx, params.walletId);
99
- tx = tx.combine(response);
100
- break;
101
- }
102
- }
103
- else {
104
- switch (params.signingStep) {
105
- case 'signerNonce':
106
- case 'cosignerNonce':
107
- /**
108
- * In certain cases, the caller of this method may not know whether the txHex contains a psbt with taproot key path spend input(s).
109
- * Instead of throwing error, no-op and return the txHex. So that the caller can call this method in the same sequence.
110
- */
111
- return tx;
112
- }
113
- }
114
- assert(signerKeychain);
115
- return signAndVerifyPsbt(tx, signerKeychain);
116
- }
117
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnblBzYnRVdHhvbGliLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3RyYW5zYWN0aW9uL2ZpeGVkU2NyaXB0L3NpZ25Qc2J0VXR4b2xpYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxLQUFLLE9BQU8sTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEMsT0FBTyxRQUFRLE1BQU0sT0FBTyxDQUFDO0FBRTdCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzVFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQWN4Qzs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixJQUE0QixFQUM1QixjQUFzQztJQUV0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQy9CLE1BQU0sU0FBUyxHQUFhLEVBQUUsQ0FBQztJQUMvQixNQUFNLFdBQVcsR0FBMkIsRUFBRSxDQUFDO0lBRS9DLE1BQU0sVUFBVSxHQUFnQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07U0FDN0QsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLFVBQWtCLEVBQUUsRUFBRTtRQUNqQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkcsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV6QixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFD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QU0sQ0FBQztRQUNOLFFBQVEsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzNCLEtBQUssYUFBYSxDQUFDO1lBQ25CLEtBQUssZUFBZTtnQkFDbEI7OzttQkFHRztnQkFDSCxPQUFPLEVBQUUsQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8saUJBQWlCLENBQUMsRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0FBQy9DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IGJpdGdvIH0gZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCBkZWJ1Z0xpYiBmcm9tICdkZWJ1Zyc7XG5cbmltcG9ydCB7IElucHV0U2lnbmluZ0Vycm9yLCBUcmFuc2FjdGlvblNpZ25pbmdFcnJvciB9IGZyb20gJy4vU2lnbmluZ0Vycm9yJztcbmltcG9ydCB7IE11c2lnMlBhcnRpY2lwYW50IH0gZnJvbSAnLi9tdXNpZzInO1xuXG5jb25zdCBkZWJ1ZyA9IGRlYnVnTGliKCdiaXRnbzp2Mjp1dHhvJyk7XG5cbmV4cG9ydCB0eXBlIFBzYnRQYXJzZWRTY3JpcHRUeXBlID1cbiAgfCAncDJzaCdcbiAgfCAncDJ3c2gnXG4gIHwgJ3Ayc2hQMndzaCdcbiAgfCAncDJzaFAycGsnXG4gIHwgJ3RhcHJvb3RLZXlQYXRoU3BlbmQnXG4gIHwgJ3RhcHJvb3RTY3JpcHRQYXRoU3BlbmQnXG4gIC8vIHdhc20tdXR4byB0eXBlc1xuICB8ICdwMnRyTGVnYWN5J1xuICB8ICdwMnRyTXVzaWcyU2NyaXB0UGF0aCdcbiAgfCAncDJ0ck11c2lnMktleVBhdGgnO1xuXG4vKipcbiAqIFNpZ24gYWxsIGlucHV0cyBvZiBhIHBzYnQgYW5kIHZlcmlmeSBzaWduYXR1cmVzIGFmdGVyIHNpZ25pbmcuXG4gKiBDb2xsZWN0cyBhbmQgbG9ncyBzaWduaW5nIGVycm9ycyBhbmQgdmVyaWZpY2F0aW9uIGVycm9ycywgdGhyb3dzIGVycm9yIGluIHRoZSBlbmQgaWYgYW55IG9mIHRoZW1cbiAqIGZhaWxlZC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIG1pcnJvcnMgc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uLCBidXQgaXMgdXNlZCBmb3Igc2lnbmluZyBQU0JUcyBpbnN0ZWFkIG9mXG4gKiB1c2luZyBUcmFuc2FjdGlvbkJ1aWxkZXJcbiAqXG4gKiBAcGFyYW0gcHNidFxuICogQHBhcmFtIHNpZ25lcktleWNoYWluXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduQW5kVmVyaWZ5UHNidChcbiAgcHNidDogdXR4b2xpYi5iaXRnby5VdHhvUHNidCxcbiAgc2lnbmVyS2V5Y2hhaW46IHV0eG9saWIuQklQMzJJbnRlcmZhY2Vcbik6IHV0eG9saWIuYml0Z28uVXR4b1BzYnQge1xuICBjb25zdCB0eElucHV0cyA9IHBzYnQudHhJbnB1dHM7XG4gIGNvbnN0IG91dHB1dElkczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc2NyaXB0VHlwZXM6IFBzYnRQYXJzZWRTY3JpcHRUeXBlW10gPSBbXTtcblxuICBjb25zdCBzaWduRXJyb3JzOiBJbnB1dFNpZ25pbmdFcnJvcjxiaWdpbnQ+W10gPSBwc2J0LmRhdGEuaW5wdXRzXG4gICAgLm1hcCgoaW5wdXQsIGlucHV0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0SWQgPSB1dHhvbGliLmJpdGdvLmZvcm1hdE91dHB1dElkKHV0eG9saWIuYml0Z28uZ2V0T3V0cHV0SWRGb3JJbnB1dCh0eElucHV0c1tpbnB1dEluZGV4XSkpO1xuICAgICAgb3V0cHV0SWRzLnB1c2gob3V0cHV0SWQpO1xuXG4gICAgICBjb25zdCB7IHNjcmlwdFR5cGUgfSA9IHV0eG9saWIuYml0Z28ucGFyc2VQc2J0SW5wdXQoaW5wdXQpO1xuICAgICAgc2NyaXB0VHlwZXMucHVzaChzY3JpcHRUeXBlKTtcblxuICAgICAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnNoUDJwaycpIHtcbiAgICAgICAgZGVidWcoJ1NraXBwaW5nIHNpZ25hdHVyZSBmb3IgaW5wdXQgJWQgb2YgJWQgKFJQIGlucHV0PyknLCBpbnB1dEluZGV4ICsgMSwgcHNidC5kYXRhLmlucHV0cy5sZW5ndGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHBzYnQuc2lnbklucHV0SEQoaW5wdXRJbmRleCwgc2lnbmVyS2V5Y2hhaW4pO1xuICAgICAgICBkZWJ1ZygnU3VjY2Vzc2Z1bGx5IHNpZ25lZCBpbnB1dCAlZCBvZiAlZCcsIGlucHV0SW5kZXggKyAxLCBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3I8YmlnaW50PihpbnB1dEluZGV4LCBzY3JpcHRUeXBlLCB7IGlkOiBvdXRwdXRJZCB9LCBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoKGUpOiBlIGlzIElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD4gPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBjb25zdCB2ZXJpZnlFcnJvcnM6IElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD5bXSA9IHBzYnQuZGF0YS5pbnB1dHNcbiAgICAubWFwKChpbnB1dCwgaW5wdXRJbmRleCkgPT4ge1xuICAgICAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVzW2lucHV0SW5kZXhdO1xuICAgICAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnNoUDJwaycpIHtcbiAgICAgICAgZGVidWcoXG4gICAgICAgICAgJ1NraXBwaW5nIGlucHV0IHNpZ25hdHVyZSAlZCBvZiAlZCAodW5zcGVudCBmcm9tIHJlcGxheSBwcm90ZWN0aW9uIGFkZHJlc3Mgd2hpY2ggaXMgcGxhdGZvcm0gc2lnbmVkIG9ubHkpJyxcbiAgICAgICAgICBpbnB1dEluZGV4ICsgMSxcbiAgICAgICAgICBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dElkID0gb3V0cHV0SWRzW2lucHV0SW5kZXhdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mSW5wdXRIRChpbnB1dEluZGV4LCBzaWduZXJLZXljaGFpbikpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yKGlucHV0SW5kZXgsIHNjcmlwdFR5cGUsIHsgaWQ6IG91dHB1dElkIH0sIG5ldyBFcnJvcihgaW52YWxpZCBzaWduYXR1cmVgKSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZGVidWcoJ0ludmFsaWQgc2lnbmF0dXJlJyk7XG4gICAgICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3I8YmlnaW50PihpbnB1dEluZGV4LCBzY3JpcHRUeXBlLCB7IGlkOiBvdXRwdXRJZCB9LCBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoKGUpOiBlIGlzIElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD4gPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBpZiAoc2lnbkVycm9ycy5sZW5ndGggfHwgdmVyaWZ5RXJyb3JzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUcmFuc2FjdGlvblNpZ25pbmdFcnJvcihzaWduRXJyb3JzLCB2ZXJpZnlFcnJvcnMpO1xuICB9XG5cbiAgcmV0dXJuIHBzYnQ7XG59XG5cbi8qKlxuICogS2V5IFZhbHVlOiBVbnNpZ25lZCB0eCBpZCA9PiBQU0JUXG4gKiBJdCBpcyB1c2VkIHRvIGNhY2hlIFBTQlRzIHdpdGggdGFwcm9vdCBrZXkgcGF0aCAoTXVTaWcyKSBpbnB1dHMgZHVyaW5nIGV4dGVybmFsIGV4cHJlc3Mgc2lnbmVyIGlzIGFjdGl2YXRlZC5cbiAqIFJlYXNvbjogTXVTaWcyIHNpZ25lciBzZWN1cmUgbm9uY2UgaXMgY2FjaGVkIGluIHRoZSBVdHhvUHNidCBvYmplY3QuIEl0IHdpbGwgYmUgcmVxdWlyZWQgZHVyaW5nIHRoZSBzaWduaW5nIHN0ZXAuXG4gKiBGb3IgbW9yZSBpbmZvLCBjaGVjayBTaWduVHJhbnNhY3Rpb25PcHRpb25zLnNpZ25pbmdTdGVwXG4gKlxuICogVE9ETyBCVEMtMjc2OiBUaGlzIGNhY2hlIG1heSBuZWVkIHRvIGJlIGRvbmUgd2l0aCBMUlUgbGlrZSBtZW1vcnkgc2FmZSBjYWNoaW5nIGlmIG1lbW9yeSBpc3N1ZXMgY29tZXMgdXAuXG4gKi9cbmNvbnN0IFBTQlRfQ0FDSEUgPSBuZXcgTWFwPHN0cmluZywgdXR4b2xpYi5iaXRnby5VdHhvUHNidD4oKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNpZ25Qc2J0V2l0aE11c2lnMlBhcnRpY2lwYW50VXR4b2xpYihcbiAgY29pbjogTXVzaWcyUGFydGljaXBhbnQ8dXR4b2xpYi5iaXRnby5VdHhvUHNidD4sXG4gIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9Qc2J0LFxuICBzaWduZXJLZXljaGFpbjogdXR4b2xpYi5CSVAzMkludGVyZmFjZSB8IHVuZGVmaW5lZCxcbiAgcGFyYW1zOiB7XG4gICAgc2lnbmluZ1N0ZXA6ICdzaWduZXJOb25jZScgfCAnY29zaWduZXJOb25jZScgfCAnc2lnbmVyU2lnbmF0dXJlJyB8IHVuZGVmaW5lZDtcbiAgICB3YWxsZXRJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9XG4pOiBQcm9taXNlPHV0eG9saWIuYml0Z28uVXR4b1BzYnQ+IHtcbiAgaWYgKGJpdGdvLmlzVHJhbnNhY3Rpb25XaXRoS2V5UGF0aFNwZW5kSW5wdXQodHgpKSB7XG4gICAgc3dpdGNoIChwYXJhbXMuc2lnbmluZ1N0ZXApIHtcbiAgICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICAgICAgYXNzZXJ0KHNpZ25lcktleWNoYWluKTtcbiAgICAgICAgdHguc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChzaWduZXJLZXljaGFpbik7XG4gICAgICAgIFBTQlRfQ0FDSEUuc2V0KHR4LmdldFVuc2lnbmVkVHgoKS5nZXRJZCgpLCB0eCk7XG4gICAgICAgIHJldHVybiB0eDtcbiAgICAgIGNhc2UgJ2Nvc2lnbmVyTm9uY2UnOlxuICAgICAgICBhc3NlcnQocGFyYW1zLndhbGxldElkLCAnd2FsbGV0SWQgaXMgcmVxdWlyZWQgZm9yIE11U2lnMiBiaXRnbyBub25jZScpO1xuICAgICAgICByZXR1cm4gYXdhaXQgY29pbi5nZXRNdXNpZzJOb25jZXModHgsIHBhcmFtcy53YWxsZXRJZCk7XG4gICAgICBjYXNlICdzaWduZXJTaWduYXR1cmUnOlxuICAgICAgICBjb25zdCB0eElkID0gdHguZ2V0VW5zaWduZWRUeCgpLmdldElkKCk7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBQU0JUX0NBQ0hFLmdldCh0eElkKTtcbiAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgIHBzYnQsXG4gICAgICAgICAgYFBzYnQgaXMgbWlzc2luZyBmcm9tIHR4Q2FjaGUgKGNhY2hlIHNpemUgJHtQU0JUX0NBQ0hFLnNpemV9KS5cbiAgICAgICAgICAgIFRoaXMgbWF5IGJlIGR1ZSB0byB0aGUgcmVxdWVzdCBiZWluZyByb3V0ZWQgdG8gYSBkaWZmZXJlbnQgQml0R28tRXhwcmVzcyBpbnN0YW5jZSB0aGF0IGZvciBzaWduaW5nIHN0ZXAgJ3NpZ25lck5vbmNlJy5gXG4gICAgICAgICk7XG4gICAgICAgIFBTQlRfQ0FDSEUuZGVsZXRlKHR4SWQpO1xuICAgICAgICB0eCA9IHBzYnQuY29tYmluZSh0eCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gdGhpcyBpbnN0YW5jZSBpcyBub3QgYW4gZXh0ZXJuYWwgc2lnbmVyXG4gICAgICAgIGFzc2VydChwYXJhbXMud2FsbGV0SWQsICd3YWxsZXRJZCBpcyByZXF1aXJlZCBmb3IgTXVTaWcyIGJpdGdvIG5vbmNlJyk7XG4gICAgICAgIGFzc2VydChzaWduZXJLZXljaGFpbik7XG4gICAgICAgIHR4LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQoc2lnbmVyS2V5Y2hhaW4pO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNvaW4uZ2V0TXVzaWcyTm9uY2VzKHR4LCBwYXJhbXMud2FsbGV0SWQpO1xuICAgICAgICB0eCA9IHR4LmNvbWJpbmUocmVzcG9uc2UpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dpdGNoIChwYXJhbXMuc2lnbmluZ1N0ZXApIHtcbiAgICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICAgIGNhc2UgJ2Nvc2lnbmVyTm9uY2UnOlxuICAgICAgICAvKipcbiAgICAgICAgICogSW4gY2VydGFpbiBjYXNlcywgdGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZCBtYXkgbm90IGtub3cgd2hldGhlciB0aGUgdHhIZXggY29udGFpbnMgYSBwc2J0IHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dChzKS5cbiAgICAgICAgICogSW5zdGVhZCBvZiB0aHJvd2luZyBlcnJvciwgbm8tb3AgYW5kIHJldHVybiB0aGUgdHhIZXguIFNvIHRoYXQgdGhlIGNhbGxlciBjYW4gY2FsbCB0aGlzIG1ldGhvZCBpbiB0aGUgc2FtZSBzZXF1ZW5jZS5cbiAgICAgICAgICovXG4gICAgICAgIHJldHVybiB0eDtcbiAgICB9XG4gIH1cblxuICBhc3NlcnQoc2lnbmVyS2V5Y2hhaW4pO1xuICByZXR1cm4gc2lnbkFuZFZlcmlmeVBzYnQodHgsIHNpZ25lcktleWNoYWluKTtcbn1cbiJdfQ==