@btc-vision/bitcoin 6.3.0 → 6.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.babelrc +4 -0
  2. package/.gitattributes +2 -0
  3. package/.nyc_output/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +1 -0
  4. package/.nyc_output/processinfo/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +1 -0
  5. package/.nyc_output/processinfo/index.json +1 -0
  6. package/.prettierrc.json +12 -0
  7. package/CHANGELOG.md +403 -0
  8. package/CONTRIBUTING.md +83 -0
  9. package/browser/address.d.ts +16 -0
  10. package/{src → browser}/bip66.d.ts +6 -7
  11. package/{src → browser}/block.d.ts +29 -30
  12. package/{src → browser}/bufferutils.d.ts +34 -54
  13. package/browser/crypto/crypto.d.ts +1 -0
  14. package/{src → browser}/crypto.d.ts +13 -18
  15. package/browser/ecc_lib.d.ts +3 -0
  16. package/browser/hooks/AdvancedSignatureManager.d.ts +16 -0
  17. package/{src → browser}/hooks/HookedSigner.d.ts +4 -4
  18. package/browser/hooks/SignatureManager.d.ts +13 -0
  19. package/browser/index.d.ts +58 -0
  20. package/browser/index.js +2 -0
  21. package/browser/index.js.LICENSE.txt +14 -0
  22. package/browser/merkle.d.ts +1 -0
  23. package/browser/networks.d.ts +23 -0
  24. package/{src → browser}/ops.d.ts +126 -126
  25. package/browser/payments/bip341.d.ts +23 -0
  26. package/browser/payments/embed.d.ts +2 -0
  27. package/browser/payments/index.d.ts +41 -0
  28. package/{src → browser}/payments/lazy.d.ts +2 -2
  29. package/browser/payments/p2ms.d.ts +2 -0
  30. package/browser/payments/p2pk.d.ts +2 -0
  31. package/browser/payments/p2pkh.d.ts +2 -0
  32. package/browser/payments/p2sh.d.ts +2 -0
  33. package/browser/payments/p2tr.d.ts +2 -0
  34. package/browser/payments/p2wpkh.d.ts +2 -0
  35. package/browser/payments/p2wsh.d.ts +2 -0
  36. package/browser/psbt/bip371.d.ts +16 -0
  37. package/browser/psbt/psbtutils.d.ts +26 -0
  38. package/{src → browser}/psbt.d.ts +167 -235
  39. package/browser/push_data.d.ts +7 -0
  40. package/browser/script.d.ts +17 -0
  41. package/browser/script_number.d.ts +2 -0
  42. package/browser/script_signature.d.ts +7 -0
  43. package/{src → browser}/transaction.d.ts +48 -60
  44. package/{src → browser}/types.d.ts +37 -54
  45. package/build/address.d.ts +16 -0
  46. package/build/address.js +148 -0
  47. package/build/bip66.d.ts +6 -0
  48. package/build/bip66.js +99 -0
  49. package/build/block.d.ts +29 -0
  50. package/build/block.js +181 -0
  51. package/build/bufferutils.d.ts +34 -0
  52. package/build/bufferutils.js +141 -0
  53. package/build/crypto/crypto.d.ts +1 -0
  54. package/build/crypto/crypto.js +1 -0
  55. package/build/crypto.d.ts +13 -0
  56. package/build/crypto.js +87 -0
  57. package/build/ecc_lib.d.ts +3 -0
  58. package/build/ecc_lib.js +61 -0
  59. package/build/hooks/AdvancedSignatureManager.d.ts +16 -0
  60. package/build/hooks/AdvancedSignatureManager.js +52 -0
  61. package/build/hooks/HookedSigner.d.ts +4 -0
  62. package/build/hooks/HookedSigner.js +64 -0
  63. package/build/hooks/SignatureManager.d.ts +13 -0
  64. package/build/hooks/SignatureManager.js +45 -0
  65. package/build/index.d.ts +58 -0
  66. package/build/index.js +32 -0
  67. package/build/merkle.d.ts +1 -0
  68. package/build/merkle.js +19 -0
  69. package/build/networks.d.ts +23 -0
  70. package/build/networks.js +121 -0
  71. package/build/ops.d.ts +126 -0
  72. package/{src → build}/ops.js +127 -131
  73. package/build/payments/bip341.d.ts +23 -0
  74. package/build/payments/bip341.js +82 -0
  75. package/build/payments/embed.d.ts +2 -0
  76. package/build/payments/embed.js +39 -0
  77. package/build/payments/index.d.ts +41 -0
  78. package/build/payments/index.js +10 -0
  79. package/build/payments/lazy.d.ts +2 -0
  80. package/{src → build}/payments/lazy.js +28 -32
  81. package/build/payments/p2ms.d.ts +2 -0
  82. package/{src → build}/payments/p2ms.js +128 -158
  83. package/build/payments/p2pk.d.ts +2 -0
  84. package/build/payments/p2pk.js +68 -0
  85. package/build/payments/p2pkh.d.ts +2 -0
  86. package/build/payments/p2pkh.js +135 -0
  87. package/build/payments/p2sh.d.ts +2 -0
  88. package/build/payments/p2sh.js +175 -0
  89. package/build/payments/p2tr.d.ts +2 -0
  90. package/build/payments/p2tr.js +254 -0
  91. package/build/payments/p2wpkh.d.ts +2 -0
  92. package/build/payments/p2wpkh.js +130 -0
  93. package/build/payments/p2wsh.d.ts +2 -0
  94. package/build/payments/p2wsh.js +180 -0
  95. package/build/psbt/bip371.d.ts +16 -0
  96. package/build/psbt/bip371.js +246 -0
  97. package/build/psbt/psbtutils.d.ts +26 -0
  98. package/build/psbt/psbtutils.js +170 -0
  99. package/build/psbt.d.ts +167 -0
  100. package/build/psbt.js +1305 -0
  101. package/build/push_data.d.ts +7 -0
  102. package/build/push_data.js +57 -0
  103. package/build/script.d.ts +17 -0
  104. package/build/script.js +167 -0
  105. package/build/script_number.d.ts +2 -0
  106. package/build/script_number.js +49 -0
  107. package/build/script_signature.d.ts +7 -0
  108. package/build/script_signature.js +49 -0
  109. package/build/transaction.d.ts +48 -0
  110. package/build/transaction.js +445 -0
  111. package/build/types.d.ts +37 -0
  112. package/build/types.js +73 -0
  113. package/cjs/package.json +3 -0
  114. package/eslint.config.js +56 -0
  115. package/gulpfile.js +42 -0
  116. package/package.json +105 -50
  117. package/src/{address.js → address.ts} +93 -73
  118. package/src/{bip66.js → bip66.ts} +23 -19
  119. package/src/{block.js → block.ts} +114 -105
  120. package/src/{bufferutils.js → bufferutils.ts} +65 -67
  121. package/src/crypto/crypto-browser.js +75 -0
  122. package/src/crypto/crypto.ts +1 -0
  123. package/src/crypto.ts +108 -0
  124. package/src/{ecc_lib.js → ecc_lib.ts} +25 -53
  125. package/src/hooks/{AdvancedSignatureManager.js → AdvancedSignatureManager.ts} +34 -18
  126. package/src/hooks/HookedSigner.ts +108 -0
  127. package/src/hooks/{SignatureManager.js → SignatureManager.ts} +26 -14
  128. package/src/index.ts +86 -0
  129. package/src/{merkle.js → merkle.ts} +8 -7
  130. package/src/networks.ts +235 -0
  131. package/src/ops.ts +282 -0
  132. package/src/payments/bip341.ts +140 -0
  133. package/src/payments/embed.ts +55 -0
  134. package/src/payments/{index.d.ts → index.ts} +20 -10
  135. package/src/payments/lazy.ts +28 -0
  136. package/src/payments/p2ms.ts +150 -0
  137. package/src/payments/{p2pk.js → p2pk.ts} +32 -29
  138. package/src/payments/{p2pkh.js → p2pkh.ts} +53 -47
  139. package/src/payments/{p2sh.js → p2sh.ts} +72 -71
  140. package/src/payments/{p2tr.js → p2tr.ts} +114 -125
  141. package/src/payments/{p2wpkh.js → p2wpkh.ts} +51 -56
  142. package/src/payments/{p2wsh.js → p2wsh.ts} +69 -81
  143. package/src/psbt/{bip371.js → bip371.ts} +195 -178
  144. package/src/psbt/psbtutils.ts +299 -0
  145. package/src/{psbt.js → psbt.ts} +1048 -699
  146. package/src/{push_data.js → push_data.ts} +35 -21
  147. package/src/{script.js → script.ts} +93 -77
  148. package/src/{script_number.js → script_number.ts} +15 -21
  149. package/src/{script_signature.js → script_signature.ts} +26 -14
  150. package/src/{transaction.js → transaction.ts} +247 -167
  151. package/src/types.ts +122 -0
  152. package/test/address.spec.js +124 -0
  153. package/test/address.spec.ts +177 -0
  154. package/test/bitcoin.core.spec.js +170 -0
  155. package/test/bitcoin.core.spec.ts +234 -0
  156. package/test/block.spec.js +141 -0
  157. package/test/block.spec.ts +194 -0
  158. package/test/bufferutils.spec.js +427 -0
  159. package/test/bufferutils.spec.ts +513 -0
  160. package/test/crypto.spec.js +41 -0
  161. package/test/crypto.spec.ts +55 -0
  162. package/test/fixtures/address.json +329 -0
  163. package/test/fixtures/block.json +148 -0
  164. package/test/fixtures/bufferutils.json +102 -0
  165. package/test/fixtures/core/README.md +26 -0
  166. package/test/fixtures/core/base58_encode_decode.json +50 -0
  167. package/test/fixtures/core/base58_keys_invalid.json +152 -0
  168. package/test/fixtures/core/base58_keys_valid.json +452 -0
  169. package/test/fixtures/core/blocks.json +27 -0
  170. package/test/fixtures/core/sig_canonical.json +7 -0
  171. package/test/fixtures/core/sig_noncanonical.json +33 -0
  172. package/test/fixtures/core/sighash.json +3505 -0
  173. package/test/fixtures/core/tx_valid.json +2023 -0
  174. package/test/fixtures/crypto.json +43 -0
  175. package/test/fixtures/ecdsa.json +217 -0
  176. package/test/fixtures/ecpair.json +141 -0
  177. package/test/fixtures/embed.json +108 -0
  178. package/test/fixtures/p2ms.json +434 -0
  179. package/test/fixtures/p2pk.json +179 -0
  180. package/test/fixtures/p2pkh.json +276 -0
  181. package/test/fixtures/p2sh.json +508 -0
  182. package/test/fixtures/p2tr.json +1198 -0
  183. package/test/fixtures/p2wpkh.json +290 -0
  184. package/test/fixtures/p2wsh.json +489 -0
  185. package/test/fixtures/psbt.json +924 -0
  186. package/test/fixtures/script.json +465 -0
  187. package/test/fixtures/script_number.json +225 -0
  188. package/test/fixtures/signature.json +140 -0
  189. package/test/fixtures/transaction.json +916 -0
  190. package/test/integration/_regtest.js +7 -0
  191. package/test/integration/_regtest.ts +6 -0
  192. package/test/integration/addresses.spec.js +116 -0
  193. package/test/integration/addresses.spec.ts +154 -0
  194. package/test/integration/bip32.spec.js +85 -0
  195. package/test/integration/bip32.spec.ts +151 -0
  196. package/test/integration/blocks.spec.js +26 -0
  197. package/test/integration/blocks.spec.ts +28 -0
  198. package/test/integration/cltv.spec.js +199 -0
  199. package/test/integration/cltv.spec.ts +283 -0
  200. package/test/integration/csv.spec.js +362 -0
  201. package/test/integration/csv.spec.ts +527 -0
  202. package/test/integration/payments.spec.js +98 -0
  203. package/test/integration/payments.spec.ts +135 -0
  204. package/test/integration/taproot.spec.js +532 -0
  205. package/test/integration/taproot.spec.ts +707 -0
  206. package/test/integration/transactions.spec.js +561 -0
  207. package/test/integration/transactions.spec.ts +769 -0
  208. package/test/payments.spec.js +97 -0
  209. package/test/payments.spec.ts +125 -0
  210. package/test/payments.utils.js +190 -0
  211. package/test/payments.utils.ts +208 -0
  212. package/test/psbt.spec.js +1044 -0
  213. package/test/psbt.spec.ts +1414 -0
  214. package/test/script.spec.js +151 -0
  215. package/test/script.spec.ts +210 -0
  216. package/test/script_number.spec.js +24 -0
  217. package/test/script_number.spec.ts +29 -0
  218. package/test/script_signature.spec.js +52 -0
  219. package/test/script_signature.spec.ts +66 -0
  220. package/test/transaction.spec.js +269 -0
  221. package/test/transaction.spec.ts +387 -0
  222. package/test/ts-node-register.js +5 -0
  223. package/test/tsconfig.json +45 -0
  224. package/test/types.spec.js +46 -0
  225. package/test/types.spec.ts +58 -0
  226. package/tsconfig.base.json +27 -0
  227. package/tsconfig.json +19 -0
  228. package/tsconfig.webpack.json +18 -0
  229. package/webpack.config.js +79 -0
  230. package/src/address.d.ts +0 -42
  231. package/src/crypto.js +0 -128
  232. package/src/ecc_lib.d.ts +0 -17
  233. package/src/hooks/AdvancedSignatureManager.d.ts +0 -44
  234. package/src/hooks/HookedSigner.js +0 -90
  235. package/src/hooks/SignatureManager.d.ts +0 -35
  236. package/src/index.d.ts +0 -42
  237. package/src/index.js +0 -87
  238. package/src/merkle.d.ts +0 -10
  239. package/src/networks.d.ts +0 -29
  240. package/src/networks.js +0 -71
  241. package/src/payments/bip341.d.ts +0 -49
  242. package/src/payments/bip341.js +0 -124
  243. package/src/payments/embed.d.ts +0 -9
  244. package/src/payments/embed.js +0 -54
  245. package/src/payments/index.js +0 -69
  246. package/src/payments/p2ms.d.ts +0 -9
  247. package/src/payments/p2pk.d.ts +0 -10
  248. package/src/payments/p2pkh.d.ts +0 -10
  249. package/src/payments/p2sh.d.ts +0 -10
  250. package/src/payments/p2tr.d.ts +0 -10
  251. package/src/payments/p2wpkh.d.ts +0 -10
  252. package/src/payments/p2wsh.d.ts +0 -10
  253. package/src/psbt/bip371.d.ts +0 -42
  254. package/src/psbt/psbtutils.d.ts +0 -64
  255. package/src/psbt/psbtutils.js +0 -191
  256. package/src/push_data.d.ts +0 -29
  257. package/src/script.d.ts +0 -42
  258. package/src/script_number.d.ts +0 -19
  259. package/src/script_signature.d.ts +0 -21
  260. package/src/types.js +0 -106
@@ -1,28 +1,85 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
3
- exports.prepareFinalScripts = exports.getFinalScripts = exports.Psbt = void 0;
4
- const bip174_1 = require('bip174');
5
- const varuint = require('bip174/src/lib/converter/varint');
6
- const utils_1 = require('bip174/src/lib/utils');
7
- const address_1 = require('./address');
8
- const bufferutils_1 = require('./bufferutils');
9
- const networks_1 = require('./networks');
10
- const payments = require('./payments');
11
- const bip341_1 = require('./payments/bip341');
12
- const bscript = require('./script');
13
- const transaction_1 = require('./transaction');
14
- const bip371_1 = require('./psbt/bip371');
15
- const psbtutils_1 = require('./psbt/psbtutils');
16
- const HookedSigner_js_1 = require('./hooks/HookedSigner.js');
1
+ import { Psbt as PsbtBase } from 'bip174';
2
+ import * as varuint from 'bip174/src/lib/converter/varint.js';
3
+ import {
4
+ Bip32Derivation,
5
+ KeyValue,
6
+ PartialSig,
7
+ PsbtGlobal,
8
+ PsbtGlobalUpdate,
9
+ PsbtInput,
10
+ PsbtInputUpdate,
11
+ PsbtOutput,
12
+ PsbtOutputUpdate,
13
+ TapKeySig,
14
+ TapScriptSig,
15
+ Transaction as ITransaction,
16
+ TransactionFromBuffer,
17
+ } from 'bip174/src/lib/interfaces.js';
18
+ import { checkForInput, checkForOutput } from 'bip174/src/lib/utils.js';
19
+ import { BIP32Interface } from 'bip32';
20
+ import { ECPairInterface } from 'ecpair';
21
+ import { fromOutputScript, toOutputScript } from './address.js';
22
+ import { cloneBuffer, reverseBuffer } from './bufferutils.js';
23
+ import { hookSigner } from './hooks/HookedSigner.js';
24
+ import { payments } from './index.js';
25
+ import { bitcoin as btcNetwork, Network } from './networks.js';
26
+ import { tapleafHash } from './payments/bip341.js';
27
+ import { Payment, PaymentOpts } from './payments/index.js';
28
+ import {
29
+ checkTaprootInputFields,
30
+ checkTaprootInputForSigs,
31
+ checkTaprootOutputFields,
32
+ isTaprootInput,
33
+ serializeTaprootSignature,
34
+ tapScriptFinalizer,
35
+ toXOnly,
36
+ } from './psbt/bip371.js';
37
+ import {
38
+ checkInputForSig,
39
+ isP2MS,
40
+ isP2PK,
41
+ isP2PKH,
42
+ isP2SHScript,
43
+ isP2TR,
44
+ isP2WPKH,
45
+ isP2WSHScript,
46
+ pubkeyInScript,
47
+ witnessStackToScriptWitness,
48
+ } from './psbt/psbtutils.js';
49
+ import * as bscript from './script.js';
50
+ import { Output, Transaction } from './transaction.js';
51
+
52
+ export interface TransactionInput {
53
+ hash: string | Buffer;
54
+ index: number;
55
+ sequence?: number;
56
+ }
57
+
58
+ export interface PsbtTxInput extends TransactionInput {
59
+ hash: Buffer;
60
+ }
61
+
62
+ export interface TransactionOutput {
63
+ script: Buffer;
64
+ value: number;
65
+ }
66
+
67
+ export interface PsbtTxOutput extends TransactionOutput {
68
+ address: string | undefined;
69
+ }
70
+
71
+ // msghash is 32 byte hash of preimage, signature is 64 byte compact signature (r,s 32 bytes each)
72
+ export type ValidateSigFunction = (pubkey: Buffer, msghash: Buffer, signature: Buffer) => boolean;
73
+
17
74
  /**
18
75
  * These are the default arguments for a Psbt instance.
19
76
  */
20
- const DEFAULT_OPTS = {
77
+ const DEFAULT_OPTS: PsbtOpts = {
21
78
  /**
22
79
  * A bitcoinjs Network object. This is only used if you pass an `address`
23
80
  * parameter to addOutput. Otherwise it is not needed and can be left default.
24
81
  */
25
- network: networks_1.bitcoin,
82
+ network: btcNetwork,
26
83
  /**
27
84
  * When extractTransaction is called, the fee rate is checked.
28
85
  * THIS IS NOT TO BE RELIED ON.
@@ -30,6 +87,13 @@ const DEFAULT_OPTS = {
30
87
  */
31
88
  maximumFeeRate: 5000, // satoshi per byte
32
89
  };
90
+
91
+ // Not a breaking change.
92
+ export interface PsbtBaseExtended extends Omit<PsbtBase, 'inputs'> {
93
+ inputs: PsbtInput[];
94
+ globalMap: PsbtGlobal;
95
+ }
96
+
33
97
  /**
34
98
  * Psbt class can parse and generate a PSBT binary based off of the BIP174.
35
99
  * There are 6 roles that this class fulfills. (Explained in BIP174)
@@ -70,103 +134,112 @@ const DEFAULT_OPTS = {
70
134
  /**
71
135
  * Psbt class can parse and generate a PSBT binary based off of the BIP174.
72
136
  */
73
- class Psbt {
74
- data;
75
- __CACHE;
76
- opts;
77
- constructor(opts = {}, data = new bip174_1.Psbt(new PsbtTransaction())) {
78
- this.data = data;
137
+ export class Psbt {
138
+ private readonly __CACHE: PsbtCache;
139
+ private readonly opts: PsbtOpts;
140
+
141
+ constructor(
142
+ opts: PsbtOptsOptional = {},
143
+ public data: PsbtBaseExtended = new PsbtBase(new PsbtTransaction()),
144
+ ) {
79
145
  this.opts = Object.assign({}, DEFAULT_OPTS, opts);
80
146
  this.__CACHE = {
81
147
  __NON_WITNESS_UTXO_TX_CACHE: [],
82
148
  __NON_WITNESS_UTXO_BUF_CACHE: [],
83
149
  __TX_IN_CACHE: {},
84
150
  // @ts-expect-error no.
85
- __TX: this.data.globalMap.unsignedTx.tx,
151
+ __TX: this.data.globalMap.unsignedTx.tx, // Now TypeScript knows unsignedTx is a PsbtTransaction
86
152
  __UNSAFE_SIGN_NONSEGWIT: false,
87
153
  };
88
154
  if (this.data.inputs.length === 0) this.setVersion(2);
89
- const dpew = (obj, attr, enumerable, writable) => {
155
+
156
+ const dpew = <T>(obj: T, attr: string, enumerable: boolean, writable: boolean): void => {
90
157
  Object.defineProperty(obj, attr, {
91
158
  enumerable,
92
159
  writable,
93
160
  });
94
161
  };
162
+
95
163
  dpew(this, '__CACHE', false, true);
96
164
  dpew(this, 'opts', false, true);
97
165
  }
98
- get inputCount() {
166
+
167
+ get inputCount(): number {
99
168
  return this.data.inputs.length;
100
169
  }
101
- get version() {
170
+
171
+ get version(): number {
102
172
  return this.__CACHE.__TX.version;
103
173
  }
104
- set version(version) {
174
+
175
+ set version(version: number) {
105
176
  this.setVersion(version);
106
177
  }
107
- get locktime() {
178
+
179
+ get locktime(): number {
108
180
  return this.__CACHE.__TX.locktime;
109
181
  }
110
- set locktime(locktime) {
182
+
183
+ set locktime(locktime: number) {
111
184
  this.setLocktime(locktime);
112
185
  }
113
- get txInputs() {
114
- return this.__CACHE.__TX.ins.map(input => ({
115
- hash: (0, bufferutils_1.cloneBuffer)(input.hash),
186
+
187
+ get txInputs(): PsbtTxInput[] {
188
+ return this.__CACHE.__TX.ins.map((input) => ({
189
+ hash: cloneBuffer(input.hash),
116
190
  index: input.index,
117
191
  sequence: input.sequence,
118
192
  }));
119
193
  }
120
- get txOutputs() {
121
- return this.__CACHE.__TX.outs.map(output => {
194
+
195
+ get txOutputs(): PsbtTxOutput[] {
196
+ return this.__CACHE.__TX.outs.map((output) => {
122
197
  let address;
123
198
  try {
124
- address = (0, address_1.fromOutputScript)(
125
- output.script,
126
- this.opts.network,
127
- );
199
+ address = fromOutputScript(output.script, this.opts.network);
128
200
  } catch (_) {}
129
201
  return {
130
- script: (0, bufferutils_1.cloneBuffer)(output.script),
202
+ script: cloneBuffer(output.script),
131
203
  value: output.value,
132
204
  address,
133
205
  };
134
206
  });
135
207
  }
136
- static fromBase64(data, opts = {}) {
208
+
209
+ static fromBase64(data: string, opts: PsbtOptsOptional = {}): Psbt {
137
210
  const buffer = Buffer.from(data, 'base64');
138
211
  return this.fromBuffer(buffer, opts);
139
212
  }
140
- static fromHex(data, opts = {}) {
213
+
214
+ static fromHex(data: string, opts: PsbtOptsOptional = {}): Psbt {
141
215
  const buffer = Buffer.from(data, 'hex');
142
216
  return this.fromBuffer(buffer, opts);
143
217
  }
144
- static fromBuffer(buffer, opts = {}) {
145
- const psbtBase = bip174_1.Psbt.fromBuffer(
146
- buffer,
147
- transactionFromBuffer,
148
- );
218
+
219
+ static fromBuffer(buffer: Buffer, opts: PsbtOptsOptional = {}): Psbt {
220
+ const psbtBase = PsbtBase.fromBuffer(buffer, transactionFromBuffer);
149
221
  const psbt = new Psbt(opts, psbtBase);
150
222
  checkTxForDupeIns(psbt.__CACHE.__TX, psbt.__CACHE);
151
223
  return psbt;
152
224
  }
153
- combine(...those) {
154
- this.data.combine(...those.map(o => o.data));
225
+
226
+ combine(...those: Psbt[]): this {
227
+ this.data.combine(...those.map((o) => o.data));
155
228
  return this;
156
229
  }
157
- clone() {
230
+
231
+ clone(): Psbt {
158
232
  // TODO: more efficient cloning
159
- const res = Psbt.fromBuffer(
160
- this.data.toBuffer(),
161
- JSON.parse(JSON.stringify(this.opts)),
162
- );
233
+ const res = Psbt.fromBuffer(this.data.toBuffer(), JSON.parse(JSON.stringify(this.opts)));
163
234
  return res;
164
235
  }
165
- setMaximumFeeRate(satoshiPerByte) {
236
+
237
+ setMaximumFeeRate(satoshiPerByte: number): void {
166
238
  check32Bit(satoshiPerByte); // 42.9 BTC per byte IS excessive... so throw
167
239
  this.opts.maximumFeeRate = satoshiPerByte;
168
240
  }
169
- setVersion(version) {
241
+
242
+ setVersion(version: number): this {
170
243
  check32Bit(version);
171
244
  checkInputsForPartialSig(this.data.inputs, 'setVersion');
172
245
  const c = this.__CACHE;
@@ -174,7 +247,8 @@ class Psbt {
174
247
  c.__EXTRACTED_TX = undefined;
175
248
  return this;
176
249
  }
177
- setLocktime(locktime) {
250
+
251
+ setLocktime(locktime: number): this {
178
252
  check32Bit(locktime);
179
253
  checkInputsForPartialSig(this.data.inputs, 'setLocktime');
180
254
  const c = this.__CACHE;
@@ -182,7 +256,8 @@ class Psbt {
182
256
  c.__EXTRACTED_TX = undefined;
183
257
  return this;
184
258
  }
185
- setInputSequence(inputIndex, sequence) {
259
+
260
+ setInputSequence(inputIndex: number, sequence: number): this {
186
261
  check32Bit(sequence);
187
262
  checkInputsForPartialSig(this.data.inputs, 'setInputSequence');
188
263
  const c = this.__CACHE;
@@ -193,32 +268,32 @@ class Psbt {
193
268
  c.__EXTRACTED_TX = undefined;
194
269
  return this;
195
270
  }
196
- addInputs(inputDatas, checkPartialSigs = true) {
197
- inputDatas.forEach(inputData =>
198
- this.addInput(inputData, checkPartialSigs),
199
- );
271
+
272
+ addInputs(inputDatas: PsbtInputExtended[], checkPartialSigs: boolean = true): this {
273
+ inputDatas.forEach((inputData) => this.addInput(inputData, checkPartialSigs));
200
274
  return this;
201
275
  }
202
- addInput(inputData, checkPartialSigs = true) {
203
- if (
204
- !inputData ||
205
- inputData.hash === undefined ||
206
- inputData.index === undefined
207
- ) {
276
+
277
+ addInput(inputData: PsbtInputExtended, checkPartialSigs: boolean = true): this {
278
+ if (!inputData || inputData.hash === undefined || inputData.index === undefined) {
208
279
  throw new Error(
209
280
  `Invalid arguments for Psbt.addInput. ` +
210
281
  `Requires single object with at least [hash] and [index]`,
211
282
  );
212
283
  }
213
- (0, bip371_1.checkTaprootInputFields)(inputData, inputData, 'addInput');
284
+
285
+ checkTaprootInputFields(inputData, inputData, 'addInput');
286
+
214
287
  if (checkPartialSigs) {
215
288
  checkInputsForPartialSig(this.data.inputs, 'addInput');
216
289
  }
290
+
217
291
  if (inputData.witnessScript) checkInvalidP2WSH(inputData.witnessScript);
218
292
  const c = this.__CACHE;
219
293
  this.data.addInput(inputData);
220
294
  const txIn = c.__TX.ins[c.__TX.ins.length - 1];
221
295
  checkTxInputCache(c, txIn);
296
+
222
297
  const inputIndex = this.data.inputs.length - 1;
223
298
  const input = this.data.inputs[inputIndex];
224
299
  if (input.nonWitnessUtxo) {
@@ -229,17 +304,18 @@ class Psbt {
229
304
  c.__EXTRACTED_TX = undefined;
230
305
  return this;
231
306
  }
232
- addOutputs(outputDatas) {
233
- outputDatas.forEach(outputData => this.addOutput(outputData));
307
+
308
+ addOutputs(outputDatas: PsbtOutputExtended[]): this {
309
+ outputDatas.forEach((outputData) => this.addOutput(outputData));
234
310
  return this;
235
311
  }
236
- addOutput(outputData) {
312
+
313
+ addOutput(outputData: PsbtOutputExtended): this {
237
314
  if (
238
315
  arguments.length > 1 ||
239
316
  !outputData ||
240
317
  outputData.value === undefined ||
241
- (outputData.address === undefined &&
242
- outputData.script === undefined)
318
+ ((outputData as any).address === undefined && (outputData as any).script === undefined)
243
319
  ) {
244
320
  throw new Error(
245
321
  `Invalid arguments for Psbt.addOutput. ` +
@@ -247,17 +323,14 @@ class Psbt {
247
323
  );
248
324
  }
249
325
  checkInputsForPartialSig(this.data.inputs, 'addOutput');
250
- const { address } = outputData;
326
+ const { address } = outputData as any;
251
327
  if (typeof address === 'string') {
252
328
  const { network } = this.opts;
253
- const script = (0, address_1.toOutputScript)(address, network);
329
+ const script = toOutputScript(address, network);
254
330
  outputData = Object.assign({}, outputData, { script });
255
331
  }
256
- (0, bip371_1.checkTaprootOutputFields)(
257
- outputData,
258
- outputData,
259
- 'addOutput',
260
- );
332
+ checkTaprootOutputFields(outputData, outputData, 'addOutput');
333
+
261
334
  const c = this.__CACHE;
262
335
  this.data.addOutput(outputData);
263
336
  c.__FEE = undefined;
@@ -265,68 +338,71 @@ class Psbt {
265
338
  c.__EXTRACTED_TX = undefined;
266
339
  return this;
267
340
  }
268
- extractTransaction(disableFeeCheck, disableOutputChecks) {
341
+
342
+ extractTransaction(disableFeeCheck?: boolean, disableOutputChecks?: boolean): Transaction {
269
343
  if (disableOutputChecks) {
270
- this.data.inputs = this.data.inputs.filter(i => !i.partialSig);
344
+ this.data.inputs = this.data.inputs.filter((i) => !i.partialSig);
271
345
  }
272
- if (!this.data.inputs.every(isFinalized))
273
- throw new Error('Not finalized');
346
+
347
+ if (!this.data.inputs.every(isFinalized)) throw new Error('Not finalized');
274
348
  const c = this.__CACHE;
275
349
  if (!disableFeeCheck) {
276
350
  checkFees(this, c, this.opts);
277
351
  }
278
352
  if (c.__EXTRACTED_TX) return c.__EXTRACTED_TX;
279
353
  const tx = c.__TX.clone();
280
- inputFinalizeGetAmts(
281
- this.data.inputs,
282
- tx,
283
- c,
284
- true,
285
- disableOutputChecks,
286
- );
354
+ inputFinalizeGetAmts(this.data.inputs, tx, c, true, disableOutputChecks);
287
355
  return tx;
288
356
  }
289
- getFeeRate(disableOutputChecks = false) {
357
+
358
+ getFeeRate(disableOutputChecks: boolean = false): number {
290
359
  return getTxCacheValue(
291
360
  '__FEE_RATE',
292
361
  'fee rate',
293
362
  this.data.inputs,
294
363
  this.__CACHE,
295
364
  disableOutputChecks,
296
- );
365
+ )!;
297
366
  }
298
- getFee(disableOutputChecks = false) {
367
+
368
+ getFee(disableOutputChecks: boolean = false): number {
299
369
  return getTxCacheValue(
300
370
  '__FEE',
301
371
  'fee',
302
372
  this.data.inputs,
303
373
  this.__CACHE,
304
374
  disableOutputChecks,
305
- );
375
+ )!;
306
376
  }
307
- finalizeAllInputs() {
308
- (0, utils_1.checkForInput)(this.data.inputs, 0); // making sure we have at least one
309
- range(this.data.inputs.length).forEach(idx => this.finalizeInput(idx));
377
+
378
+ finalizeAllInputs(): this {
379
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
380
+ range(this.data.inputs.length).forEach((idx) => this.finalizeInput(idx));
310
381
  return this;
311
382
  }
312
- finalizeInput(inputIndex, finalScriptsFunc) {
313
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
314
- if ((0, bip371_1.isTaprootInput)(input))
383
+
384
+ finalizeInput(
385
+ inputIndex: number,
386
+ finalScriptsFunc?: FinalScriptsFunc | FinalTaprootScriptsFunc,
387
+ ): this {
388
+ const input = checkForInput(this.data.inputs, inputIndex);
389
+ if (isTaprootInput(input))
315
390
  return this._finalizeTaprootInput(
316
391
  inputIndex,
317
392
  input,
318
393
  undefined,
319
- finalScriptsFunc,
394
+ finalScriptsFunc as FinalTaprootScriptsFunc,
320
395
  );
321
- return this._finalizeInput(inputIndex, input, finalScriptsFunc);
396
+ return this._finalizeInput(inputIndex, input, finalScriptsFunc as FinalScriptsFunc);
322
397
  }
398
+
323
399
  finalizeTaprootInput(
324
- inputIndex,
325
- tapLeafHashToFinalize,
326
- finalScriptsFunc = bip371_1.tapScriptFinalizer,
327
- ) {
328
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
329
- if ((0, bip371_1.isTaprootInput)(input))
400
+ inputIndex: number,
401
+ tapLeafHashToFinalize?: Buffer,
402
+ finalScriptsFunc: FinalTaprootScriptsFunc = tapScriptFinalizer,
403
+ ): this {
404
+ const input = checkForInput(this.data.inputs, inputIndex);
405
+ if (isTaprootInput(input))
330
406
  return this._finalizeTaprootInput(
331
407
  inputIndex,
332
408
  input,
@@ -335,77 +411,70 @@ class Psbt {
335
411
  );
336
412
  throw new Error(`Cannot finalize input #${inputIndex}. Not Taproot.`);
337
413
  }
338
- getInputType(inputIndex) {
339
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
414
+
415
+ getInputType(inputIndex: number): AllScriptType {
416
+ const input = checkForInput(this.data.inputs, inputIndex);
340
417
  const script = getScriptFromUtxo(inputIndex, input, this.__CACHE);
341
418
  const result = getMeaningfulScript(
342
419
  script,
343
420
  inputIndex,
344
421
  'input',
345
- input.redeemScript ||
346
- redeemFromFinalScriptSig(input.finalScriptSig),
347
- input.witnessScript ||
348
- redeemFromFinalWitnessScript(input.finalScriptWitness),
422
+ input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig),
423
+ input.witnessScript || redeemFromFinalWitnessScript(input.finalScriptWitness),
349
424
  );
350
425
  const type = result.type === 'raw' ? '' : result.type + '-';
351
426
  const mainType = classifyScript(result.meaningfulScript);
352
- return type + mainType;
427
+ return (type + mainType) as AllScriptType;
353
428
  }
354
- inputHasPubkey(inputIndex, pubkey) {
355
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
429
+
430
+ inputHasPubkey(inputIndex: number, pubkey: Buffer): boolean {
431
+ const input = checkForInput(this.data.inputs, inputIndex);
356
432
  return pubkeyInInput(pubkey, input, inputIndex, this.__CACHE);
357
433
  }
358
- inputHasHDKey(inputIndex, root) {
359
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
434
+
435
+ inputHasHDKey(inputIndex: number, root: HDSigner): boolean {
436
+ const input = checkForInput(this.data.inputs, inputIndex);
360
437
  const derivationIsMine = bip32DerivationIsMine(root);
361
- return (
362
- !!input.bip32Derivation &&
363
- input.bip32Derivation.some(derivationIsMine)
364
- );
438
+ return !!input.bip32Derivation && input.bip32Derivation.some(derivationIsMine);
365
439
  }
366
- outputHasPubkey(outputIndex, pubkey) {
367
- const output = (0, utils_1.checkForOutput)(
368
- this.data.outputs,
369
- outputIndex,
370
- );
440
+
441
+ outputHasPubkey(outputIndex: number, pubkey: Buffer): boolean {
442
+ const output = checkForOutput(this.data.outputs, outputIndex);
371
443
  return pubkeyInOutput(pubkey, output, outputIndex, this.__CACHE);
372
444
  }
373
- outputHasHDKey(outputIndex, root) {
374
- const output = (0, utils_1.checkForOutput)(
375
- this.data.outputs,
376
- outputIndex,
377
- );
445
+
446
+ outputHasHDKey(outputIndex: number, root: HDSigner): boolean {
447
+ const output = checkForOutput(this.data.outputs, outputIndex);
378
448
  const derivationIsMine = bip32DerivationIsMine(root);
379
- return (
380
- !!output.bip32Derivation &&
381
- output.bip32Derivation.some(derivationIsMine)
382
- );
449
+ return !!output.bip32Derivation && output.bip32Derivation.some(derivationIsMine);
383
450
  }
384
- validateSignaturesOfAllInputs(validator) {
385
- (0, utils_1.checkForInput)(this.data.inputs, 0); // making sure we have at least one
386
- const results = range(this.data.inputs.length).map(idx =>
451
+
452
+ validateSignaturesOfAllInputs(validator: ValidateSigFunction): boolean {
453
+ checkForInput(this.data.inputs, 0); // making sure we have at least one
454
+ const results = range(this.data.inputs.length).map((idx) =>
387
455
  this.validateSignaturesOfInput(idx, validator),
388
456
  );
389
457
  return results.reduce((final, res) => res === true && final, true);
390
458
  }
391
- validateSignaturesOfInput(inputIndex, validator, pubkey) {
459
+
460
+ validateSignaturesOfInput(
461
+ inputIndex: number,
462
+ validator: ValidateSigFunction,
463
+ pubkey?: Buffer,
464
+ ): boolean {
392
465
  const input = this.data.inputs[inputIndex];
393
- if ((0, bip371_1.isTaprootInput)(input))
394
- return this.validateSignaturesOfTaprootInput(
395
- inputIndex,
396
- validator,
397
- pubkey,
398
- );
466
+ if (isTaprootInput(input))
467
+ return this.validateSignaturesOfTaprootInput(inputIndex, validator, pubkey);
468
+
399
469
  return this._validateSignaturesOfInput(inputIndex, validator, pubkey);
400
470
  }
401
- signAllInputsHD(
402
- hdKeyPair,
403
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
404
- ) {
471
+
472
+ signAllInputsHD(hdKeyPair: HDSigner, sighashTypes: number[] = [Transaction.SIGHASH_ALL]): this {
405
473
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
406
474
  throw new Error('Need HDSigner to sign input');
407
475
  }
408
- const results = [];
476
+
477
+ const results: boolean[] = [];
409
478
  for (const i of range(this.data.inputs.length)) {
410
479
  try {
411
480
  this.signInputHD(i, hdKeyPair, sighashTypes);
@@ -414,21 +483,23 @@ class Psbt {
414
483
  results.push(false);
415
484
  }
416
485
  }
417
- if (results.every(v => v === false)) {
486
+ if (results.every((v) => v === false)) {
418
487
  throw new Error('No inputs were signed');
419
488
  }
420
489
  return this;
421
490
  }
491
+
422
492
  signAllInputsHDAsync(
423
- hdKeyPair,
424
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
425
- ) {
426
- return new Promise((resolve, reject) => {
493
+ hdKeyPair: HDSigner | HDSignerAsync,
494
+ sighashTypes: number[] = [Transaction.SIGHASH_ALL],
495
+ ): Promise<void> {
496
+ return new Promise((resolve, reject): any => {
427
497
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
428
498
  return reject(new Error('Need HDSigner to sign input'));
429
499
  }
430
- const results = [];
431
- const promises = [];
500
+
501
+ const results: boolean[] = [];
502
+ const promises: Array<Promise<void>> = [];
432
503
  for (const i of range(this.data.inputs.length)) {
433
504
  promises.push(
434
505
  this.signInputHDAsync(i, hdKeyPair, sighashTypes).then(
@@ -442,47 +513,39 @@ class Psbt {
442
513
  );
443
514
  }
444
515
  return Promise.all(promises).then(() => {
445
- if (results.every(v => v === false)) {
516
+ if (results.every((v) => v === false)) {
446
517
  return reject(new Error('No inputs were signed'));
447
518
  }
448
519
  resolve();
449
520
  });
450
521
  });
451
522
  }
523
+
452
524
  signInputHD(
453
- inputIndex,
454
- hdKeyPair,
455
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
456
- ) {
525
+ inputIndex: number,
526
+ hdKeyPair: HDSigner,
527
+ sighashTypes: number[] = [Transaction.SIGHASH_ALL],
528
+ ): this {
457
529
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
458
530
  throw new Error('Need HDSigner to sign input');
459
531
  }
460
- const signers = getSignersFromHD(
461
- inputIndex,
462
- this.data.inputs,
463
- hdKeyPair,
464
- );
465
- signers.forEach(signer =>
466
- this.signInput(inputIndex, signer, sighashTypes),
467
- );
532
+ const signers = getSignersFromHD(inputIndex, this.data.inputs, hdKeyPair) as Signer[];
533
+ signers.forEach((signer) => this.signInput(inputIndex, signer, sighashTypes));
468
534
  return this;
469
535
  }
536
+
470
537
  signInputHDAsync(
471
- inputIndex,
472
- hdKeyPair,
473
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
474
- ) {
475
- return new Promise((resolve, reject) => {
538
+ inputIndex: number,
539
+ hdKeyPair: HDSigner | HDSignerAsync,
540
+ sighashTypes: number[] = [Transaction.SIGHASH_ALL],
541
+ ): Promise<void> {
542
+ return new Promise((resolve, reject): any => {
476
543
  if (!hdKeyPair || !hdKeyPair.publicKey || !hdKeyPair.fingerprint) {
477
544
  return reject(new Error('Need HDSigner to sign input'));
478
545
  }
479
- const signers = getSignersFromHD(
480
- inputIndex,
481
- this.data.inputs,
482
- hdKeyPair,
483
- );
484
- const promises = signers.map(signer =>
485
- this.signInputAsync(inputIndex, signer, sighashTypes),
546
+ const signers = getSignersFromHD(inputIndex, this.data.inputs, hdKeyPair);
547
+ const promises = signers.map((signer) =>
548
+ this.signInputAsync(inputIndex, signer as unknown as Signer, sighashTypes),
486
549
  );
487
550
  return Promise.all(promises)
488
551
  .then(() => {
@@ -491,13 +554,17 @@ class Psbt {
491
554
  .catch(reject);
492
555
  });
493
556
  }
494
- signAllInputs(keyPair, sighashTypes) {
495
- if (!keyPair || !keyPair.publicKey)
496
- throw new Error('Need Signer to sign input');
557
+
558
+ signAllInputs(
559
+ keyPair: Signer | SignerAlternative | BIP32Interface | ECPairInterface,
560
+ sighashTypes?: number[],
561
+ ): this {
562
+ if (!keyPair || !keyPair.publicKey) throw new Error('Need Signer to sign input');
563
+
497
564
  // TODO: Add a pubkey/pubkeyhash cache to each input
498
565
  // as input information is added, then eventually
499
566
  // optimize this method.
500
- const results = [];
567
+ const results: boolean[] = [];
501
568
  for (const i of range(this.data.inputs.length)) {
502
569
  try {
503
570
  this.signInput(i, keyPair, sighashTypes);
@@ -506,20 +573,25 @@ class Psbt {
506
573
  results.push(false);
507
574
  }
508
575
  }
509
- if (results.every(v => v === false)) {
576
+ if (results.every((v) => v === false)) {
510
577
  throw new Error('No inputs were signed');
511
578
  }
512
579
  return this;
513
580
  }
514
- signAllInputsAsync(keyPair, sighashTypes) {
515
- return new Promise((resolve, reject) => {
581
+
582
+ signAllInputsAsync(
583
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
584
+ sighashTypes?: number[],
585
+ ): Promise<void> {
586
+ return new Promise((resolve, reject): any => {
516
587
  if (!keyPair || !keyPair.publicKey)
517
588
  return reject(new Error('Need Signer to sign input'));
589
+
518
590
  // TODO: Add a pubkey/pubkeyhash cache to each input
519
591
  // as input information is added, then eventually
520
592
  // optimize this method.
521
- const results = [];
522
- const promises = [];
593
+ const results: boolean[] = [];
594
+ const promises: Array<Promise<void>> = [];
523
595
  for (const [i] of this.data.inputs.entries()) {
524
596
  promises.push(
525
597
  this.signInputAsync(i, keyPair, sighashTypes).then(
@@ -533,33 +605,43 @@ class Psbt {
533
605
  );
534
606
  }
535
607
  return Promise.all(promises).then(() => {
536
- if (results.every(v => v === false)) {
608
+ if (results.every((v) => v === false)) {
537
609
  return reject(new Error('No inputs were signed'));
538
610
  }
539
611
  resolve();
540
612
  });
541
613
  });
542
614
  }
543
- signInput(inputIndex, keyPair, sighashTypes) {
544
- if (!keyPair || !keyPair.publicKey)
615
+
616
+ signInput(
617
+ inputIndex: number,
618
+ keyPair: Signer | SignerAlternative | BIP32Interface | ECPairInterface,
619
+ sighashTypes?: number[],
620
+ ): this {
621
+ if (!keyPair || !keyPair.publicKey) {
545
622
  throw new Error('Need Signer to sign input');
546
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
547
- if ((0, bip371_1.isTaprootInput)(input)) {
548
- return this._signTaprootInput(
549
- inputIndex,
550
- input,
551
- keyPair,
552
- undefined,
553
- sighashTypes,
554
- );
555
623
  }
624
+
625
+ const input = checkForInput(this.data.inputs, inputIndex);
626
+ if (isTaprootInput(input)) {
627
+ return this._signTaprootInput(inputIndex, input, keyPair, undefined, sighashTypes);
628
+ }
629
+
556
630
  return this._signInput(inputIndex, keyPair, sighashTypes);
557
631
  }
558
- signTaprootInput(inputIndex, keyPair, tapLeafHashToSign, sighashTypes) {
559
- if (!keyPair || !keyPair.publicKey)
632
+
633
+ signTaprootInput(
634
+ inputIndex: number,
635
+ keyPair: Signer | SignerAlternative | BIP32Interface | ECPairInterface,
636
+ tapLeafHashToSign?: Buffer,
637
+ sighashTypes?: number[],
638
+ ): this {
639
+ if (!keyPair || !keyPair.publicKey) {
560
640
  throw new Error('Need Signer to sign input');
561
- const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
562
- if ((0, bip371_1.isTaprootInput)(input))
641
+ }
642
+
643
+ const input = checkForInput(this.data.inputs, inputIndex);
644
+ if (isTaprootInput(input)) {
563
645
  return this._signTaprootInput(
564
646
  inputIndex,
565
647
  input,
@@ -567,17 +649,21 @@ class Psbt {
567
649
  tapLeafHashToSign,
568
650
  sighashTypes,
569
651
  );
652
+ }
653
+
570
654
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
571
655
  }
572
- signInputAsync(inputIndex, keyPair, sighashTypes) {
656
+
657
+ signInputAsync(
658
+ inputIndex: number,
659
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
660
+ sighashTypes?: number[],
661
+ ): Promise<void> {
573
662
  return Promise.resolve().then(() => {
574
- if (!keyPair || !keyPair.publicKey)
575
- throw new Error('Need Signer to sign input');
576
- const input = (0, utils_1.checkForInput)(
577
- this.data.inputs,
578
- inputIndex,
579
- );
580
- if ((0, bip371_1.isTaprootInput)(input))
663
+ if (!keyPair || !keyPair.publicKey) throw new Error('Need Signer to sign input');
664
+
665
+ const input = checkForInput(this.data.inputs, inputIndex);
666
+ if (isTaprootInput(input))
581
667
  return this._signTaprootInputAsync(
582
668
  inputIndex,
583
669
  input,
@@ -585,18 +671,22 @@ class Psbt {
585
671
  undefined,
586
672
  sighashTypes,
587
673
  );
674
+
588
675
  return this._signInputAsync(inputIndex, keyPair, sighashTypes);
589
676
  });
590
677
  }
591
- signTaprootInputAsync(inputIndex, keyPair, tapLeafHash, sighashTypes) {
678
+
679
+ signTaprootInputAsync(
680
+ inputIndex: number,
681
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
682
+ tapLeafHash?: Buffer,
683
+ sighashTypes?: number[],
684
+ ): Promise<void> {
592
685
  return Promise.resolve().then(() => {
593
- if (!keyPair || !keyPair.publicKey)
594
- throw new Error('Need Signer to sign input');
595
- const input = (0, utils_1.checkForInput)(
596
- this.data.inputs,
597
- inputIndex,
598
- );
599
- if ((0, bip371_1.isTaprootInput)(input))
686
+ if (!keyPair || !keyPair.publicKey) throw new Error('Need Signer to sign input');
687
+
688
+ const input = checkForInput(this.data.inputs, inputIndex);
689
+ if (isTaprootInput(input))
600
690
  return this._signTaprootInputAsync(
601
691
  inputIndex,
602
692
  input,
@@ -604,78 +694,113 @@ class Psbt {
604
694
  tapLeafHash,
605
695
  sighashTypes,
606
696
  );
697
+
607
698
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
608
699
  });
609
700
  }
610
- toBuffer() {
701
+
702
+ toBuffer(): Buffer {
611
703
  checkCache(this.__CACHE);
612
704
  return this.data.toBuffer();
613
705
  }
614
- toHex() {
706
+
707
+ toHex(): string {
615
708
  checkCache(this.__CACHE);
616
709
  return this.data.toHex();
617
710
  }
618
- toBase64() {
711
+
712
+ toBase64(): string {
619
713
  checkCache(this.__CACHE);
620
714
  return this.data.toBase64();
621
715
  }
622
- updateGlobal(updateData) {
716
+
717
+ updateGlobal(updateData: PsbtGlobalUpdate): this {
623
718
  this.data.updateGlobal(updateData);
624
719
  return this;
625
720
  }
626
- updateInput(inputIndex, updateData) {
627
- if (updateData.witnessScript)
628
- checkInvalidP2WSH(updateData.witnessScript);
629
- (0, bip371_1.checkTaprootInputFields)(
630
- this.data.inputs[inputIndex],
631
- updateData,
632
- 'updateInput',
633
- );
721
+
722
+ updateInput(inputIndex: number, updateData: PsbtInputUpdate): this {
723
+ if (updateData.witnessScript) checkInvalidP2WSH(updateData.witnessScript);
724
+ checkTaprootInputFields(this.data.inputs[inputIndex], updateData, 'updateInput');
634
725
  this.data.updateInput(inputIndex, updateData);
635
726
  if (updateData.nonWitnessUtxo) {
636
- addNonWitnessTxCache(
637
- this.__CACHE,
638
- this.data.inputs[inputIndex],
639
- inputIndex,
640
- );
727
+ addNonWitnessTxCache(this.__CACHE, this.data.inputs[inputIndex], inputIndex);
641
728
  }
642
729
  return this;
643
730
  }
644
- updateOutput(outputIndex, updateData) {
731
+
732
+ updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this {
645
733
  const outputData = this.data.outputs[outputIndex];
646
- (0, bip371_1.checkTaprootOutputFields)(
647
- outputData,
648
- updateData,
649
- 'updateOutput',
650
- );
734
+ checkTaprootOutputFields(outputData, updateData, 'updateOutput');
735
+
651
736
  this.data.updateOutput(outputIndex, updateData);
652
737
  return this;
653
738
  }
654
- addUnknownKeyValToGlobal(keyVal) {
739
+
740
+ addUnknownKeyValToGlobal(keyVal: KeyValue): this {
655
741
  this.data.addUnknownKeyValToGlobal(keyVal);
656
742
  return this;
657
743
  }
658
- addUnknownKeyValToInput(inputIndex, keyVal) {
744
+
745
+ addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this {
659
746
  this.data.addUnknownKeyValToInput(inputIndex, keyVal);
660
747
  return this;
661
748
  }
662
- addUnknownKeyValToOutput(outputIndex, keyVal) {
749
+
750
+ addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this {
663
751
  this.data.addUnknownKeyValToOutput(outputIndex, keyVal);
664
752
  return this;
665
753
  }
666
- clearFinalizedInput(inputIndex) {
754
+
755
+ clearFinalizedInput(inputIndex: number): this {
667
756
  this.data.clearFinalizedInput(inputIndex);
668
757
  return this;
669
758
  }
670
- _finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts) {
759
+
760
+ public checkTaprootHashesForSig(
761
+ inputIndex: number,
762
+ input: PsbtInput,
763
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
764
+ tapLeafHashToSign?: Buffer,
765
+ allowedSighashTypes?: number[],
766
+ ): { hash: Buffer; leafHash?: Buffer }[] {
767
+ if (typeof keyPair.signSchnorr !== 'function')
768
+ throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
769
+
770
+ const hashesForSig = getTaprootHashesForSig(
771
+ inputIndex,
772
+ input,
773
+ this.data.inputs,
774
+ keyPair.publicKey,
775
+ this.__CACHE,
776
+ tapLeafHashToSign,
777
+ allowedSighashTypes,
778
+ );
779
+
780
+ if (!hashesForSig || !hashesForSig.length)
781
+ throw new Error(
782
+ `Can not sign for input #${inputIndex} with the key ${keyPair.publicKey.toString(
783
+ 'hex',
784
+ )}`,
785
+ );
786
+
787
+ return hashesForSig;
788
+ }
789
+
790
+ private _finalizeInput(
791
+ inputIndex: number,
792
+ input: PsbtInput,
793
+ finalScriptsFunc: FinalScriptsFunc = getFinalScripts,
794
+ ): this {
671
795
  const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
672
796
  inputIndex,
673
797
  input,
674
798
  this.__CACHE,
675
799
  );
676
- if (!script)
677
- throw new Error(`No script found for input #${inputIndex}`);
800
+ if (!script) throw new Error(`No script found for input #${inputIndex}`);
801
+
678
802
  checkPartialSigSighashes(input);
803
+
679
804
  const { finalScriptSig, finalScriptWitness } = finalScriptsFunc(
680
805
  inputIndex,
681
806
  input,
@@ -684,33 +809,32 @@ class Psbt {
684
809
  isP2SH,
685
810
  isP2WSH,
686
811
  );
687
- if (finalScriptSig)
688
- this.data.updateInput(inputIndex, { finalScriptSig });
689
- if (finalScriptWitness)
690
- this.data.updateInput(inputIndex, { finalScriptWitness });
812
+
813
+ if (finalScriptSig) this.data.updateInput(inputIndex, { finalScriptSig });
814
+ if (finalScriptWitness) this.data.updateInput(inputIndex, { finalScriptWitness });
691
815
  if (!finalScriptSig && !finalScriptWitness)
692
816
  throw new Error(`Unknown error finalizing input #${inputIndex}`);
817
+
693
818
  this.data.clearFinalizedInput(inputIndex);
694
819
  return this;
695
820
  }
696
- _finalizeTaprootInput(
697
- inputIndex,
698
- input,
699
- tapLeafHashToFinalize,
700
- finalScriptsFunc = bip371_1.tapScriptFinalizer,
701
- ) {
821
+
822
+ private _finalizeTaprootInput(
823
+ inputIndex: number,
824
+ input: PsbtInput,
825
+ tapLeafHashToFinalize?: Buffer,
826
+ finalScriptsFunc = tapScriptFinalizer,
827
+ ): this {
702
828
  if (!input.witnessUtxo)
703
- throw new Error(
704
- `Cannot finalize input #${inputIndex}. Missing withness utxo.`,
705
- );
829
+ throw new Error(`Cannot finalize input #${inputIndex}. Missing witness utxo.`);
830
+
706
831
  // Check key spend first. Increased privacy and reduced block space.
707
832
  if (input.tapKeySig) {
708
833
  const payment = payments.p2tr({
709
834
  output: input.witnessUtxo.script,
710
835
  signature: input.tapKeySig,
711
836
  });
712
- const finalScriptWitness = (0,
713
- psbtutils_1.witnessStackToScriptWitness)(payment.witness);
837
+ const finalScriptWitness = witnessStackToScriptWitness(payment.witness!);
714
838
  this.data.updateInput(inputIndex, { finalScriptWitness });
715
839
  } else {
716
840
  const { finalScriptWitness } = finalScriptsFunc(
@@ -720,28 +844,33 @@ class Psbt {
720
844
  );
721
845
  this.data.updateInput(inputIndex, { finalScriptWitness });
722
846
  }
847
+
723
848
  this.data.clearFinalizedInput(inputIndex);
849
+
724
850
  return this;
725
851
  }
726
- _validateSignaturesOfInput(inputIndex, validator, pubkey) {
852
+
853
+ private _validateSignaturesOfInput(
854
+ inputIndex: number,
855
+ validator: ValidateSigFunction,
856
+ pubkey?: Buffer,
857
+ ): boolean {
727
858
  const input = this.data.inputs[inputIndex];
728
859
  const partialSig = (input || {}).partialSig;
729
860
  if (!input || !partialSig || partialSig.length < 1)
730
861
  throw new Error('No signatures to validate');
731
862
  if (typeof validator !== 'function')
732
863
  throw new Error('Need validator function to validate signatures');
733
- const mySigs = pubkey
734
- ? partialSig.filter(sig => sig.pubkey.equals(pubkey))
735
- : partialSig;
864
+ const mySigs = pubkey ? partialSig.filter((sig) => sig.pubkey.equals(pubkey)) : partialSig;
736
865
  if (mySigs.length < 1) throw new Error('No signatures for this pubkey');
737
- const results = [];
738
- let hashCache;
739
- let scriptCache;
740
- let sighashCache;
866
+ const results: boolean[] = [];
867
+ let hashCache: Buffer;
868
+ let scriptCache: Buffer;
869
+ let sighashCache: number;
741
870
  for (const pSig of mySigs) {
742
871
  const sig = bscript.signature.decode(pSig.signature);
743
872
  const { hash, script } =
744
- sighashCache !== sig.hashType
873
+ sighashCache! !== sig.hashType
745
874
  ? getHashForSig(
746
875
  inputIndex,
747
876
  Object.assign({}, input, {
@@ -750,16 +879,21 @@ class Psbt {
750
879
  this.__CACHE,
751
880
  true,
752
881
  )
753
- : { hash: hashCache, script: scriptCache };
882
+ : { hash: hashCache!, script: scriptCache! };
754
883
  sighashCache = sig.hashType;
755
884
  hashCache = hash;
756
885
  scriptCache = script;
757
886
  checkScriptForPubkey(pSig.pubkey, script, 'verify');
758
887
  results.push(validator(pSig.pubkey, hash, sig.signature));
759
888
  }
760
- return results.every(res => res === true);
761
- }
762
- validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
889
+ return results.every((res) => res === true);
890
+ }
891
+
892
+ private validateSignaturesOfTaprootInput(
893
+ inputIndex: number,
894
+ validator: ValidateSigFunction,
895
+ pubkey?: Buffer,
896
+ ): boolean {
763
897
  const input = this.data.inputs[inputIndex];
764
898
  const tapKeySig = (input || {}).tapKeySig;
765
899
  const tapScriptSig = (input || {}).tapScriptSig;
@@ -767,24 +901,15 @@ class Psbt {
767
901
  throw new Error('No signatures to validate');
768
902
  if (typeof validator !== 'function')
769
903
  throw new Error('Need validator function to validate signatures');
770
- pubkey = pubkey && (0, bip371_1.toXOnly)(pubkey);
904
+
905
+ pubkey = pubkey && toXOnly(pubkey);
771
906
  const allHashses = pubkey
772
- ? getTaprootHashesForSig(
773
- inputIndex,
774
- input,
775
- this.data.inputs,
776
- pubkey,
777
- this.__CACHE,
778
- )
779
- : getAllTaprootHashesForSig(
780
- inputIndex,
781
- input,
782
- this.data.inputs,
783
- this.__CACHE,
784
- );
785
- if (!allHashses.length)
786
- throw new Error('No signatures for this pubkey');
787
- const tapKeyHash = allHashses.find(h => !h.leafHash);
907
+ ? getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.__CACHE)
908
+ : getAllTaprootHashesForSig(inputIndex, input, this.data.inputs, this.__CACHE);
909
+
910
+ if (!allHashses.length) throw new Error('No signatures for this pubkey');
911
+
912
+ const tapKeyHash = allHashses.find((h) => !h.leafHash);
788
913
  let validationResultCount = 0;
789
914
  if (tapKeySig && tapKeyHash) {
790
915
  const isValidTapkeySig = validator(
@@ -795,11 +920,10 @@ class Psbt {
795
920
  if (!isValidTapkeySig) return false;
796
921
  validationResultCount++;
797
922
  }
923
+
798
924
  if (tapScriptSig) {
799
925
  for (const tapSig of tapScriptSig) {
800
- const tapSigHash = allHashses.find(h =>
801
- tapSig.pubkey.equals(h.pubkey),
802
- );
926
+ const tapSigHash = allHashses.find((h) => tapSig.pubkey.equals(h.pubkey));
803
927
  if (tapSigHash) {
804
928
  const isValidTapScriptSig = validator(
805
929
  tapSig.pubkey,
@@ -811,14 +935,17 @@ class Psbt {
811
935
  }
812
936
  }
813
937
  }
938
+
814
939
  return validationResultCount > 0;
815
940
  }
816
- _signInput(
817
- inputIndex,
818
- keyPair,
819
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
820
- ) {
821
- (0, HookedSigner_js_1.hookSigner)(keyPair);
941
+
942
+ private _signInput(
943
+ inputIndex: number,
944
+ keyPair: Signer | SignerAlternative | BIP32Interface | ECPairInterface,
945
+ sighashTypes: number[] = [Transaction.SIGHASH_ALL],
946
+ ): this {
947
+ hookSigner(keyPair);
948
+
822
949
  const { hash, sighashType } = getHashAndSighashType(
823
950
  this.data.inputs,
824
951
  inputIndex,
@@ -826,26 +953,27 @@ class Psbt {
826
953
  this.__CACHE,
827
954
  sighashTypes,
828
955
  );
956
+
829
957
  const partialSig = [
830
958
  {
831
959
  pubkey: keyPair.publicKey,
832
- signature: bscript.signature.encode(
833
- keyPair.sign(hash),
834
- sighashType,
835
- ),
960
+ signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
836
961
  },
837
962
  ];
963
+
838
964
  this.data.updateInput(inputIndex, { partialSig });
839
965
  return this;
840
966
  }
841
- _signTaprootInput(
842
- inputIndex,
843
- input,
844
- keyPair,
845
- tapLeafHashToSign,
846
- allowedSighashTypes = [transaction_1.Transaction.SIGHASH_DEFAULT],
847
- ) {
848
- (0, HookedSigner_js_1.hookSigner)(keyPair);
967
+
968
+ private _signTaprootInput(
969
+ inputIndex: number,
970
+ input: PsbtInput,
971
+ keyPair: Signer | SignerAlternative | BIP32Interface | ECPairInterface,
972
+ tapLeafHashToSign?: Buffer,
973
+ allowedSighashTypes: number[] = [Transaction.SIGHASH_DEFAULT],
974
+ ): this {
975
+ hookSigner(keyPair);
976
+
849
977
  const hashesForSig = this.checkTaprootHashesForSig(
850
978
  inputIndex,
851
979
  input,
@@ -853,38 +981,45 @@ class Psbt {
853
981
  tapLeafHashToSign,
854
982
  allowedSighashTypes,
855
983
  );
856
- const tapKeySig = hashesForSig
857
- .filter(h => !h.leafHash)
858
- .map(h =>
859
- (0, bip371_1.serializeTaprootSignature)(
860
- keyPair.signSchnorr(h.hash),
861
- input.sighashType,
862
- ),
984
+
985
+ const tapKeySig: TapKeySig = hashesForSig
986
+ .filter((h) => !h.leafHash)
987
+ .map((h) =>
988
+ serializeTaprootSignature(keyPair.signSchnorr!(h.hash), input.sighashType),
863
989
  )[0];
864
- const tapScriptSig = hashesForSig
865
- .filter(h => !!h.leafHash)
866
- .map(h => ({
867
- pubkey: (0, bip371_1.toXOnly)(keyPair.publicKey),
868
- signature: (0, bip371_1.serializeTaprootSignature)(
869
- keyPair.signSchnorr(h.hash),
870
- input.sighashType,
871
- ),
872
- leafHash: h.leafHash,
873
- }));
990
+
991
+ const tapScriptSig: TapScriptSig[] = hashesForSig
992
+ .filter((h) => !!h.leafHash)
993
+ .map(
994
+ (h) =>
995
+ ({
996
+ pubkey: toXOnly(keyPair.publicKey),
997
+ signature: serializeTaprootSignature(
998
+ keyPair.signSchnorr!(h.hash),
999
+ input.sighashType,
1000
+ ),
1001
+ leafHash: h.leafHash,
1002
+ }) as TapScriptSig,
1003
+ );
1004
+
874
1005
  if (tapKeySig) {
875
1006
  this.data.updateInput(inputIndex, { tapKeySig });
876
1007
  }
1008
+
877
1009
  if (tapScriptSig.length) {
878
1010
  this.data.updateInput(inputIndex, { tapScriptSig });
879
1011
  }
1012
+
880
1013
  return this;
881
1014
  }
882
- _signInputAsync(
883
- inputIndex,
884
- keyPair,
885
- sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
886
- ) {
887
- (0, HookedSigner_js_1.hookSigner)(keyPair);
1015
+
1016
+ private _signInputAsync(
1017
+ inputIndex: number,
1018
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
1019
+ sighashTypes: number[] = [Transaction.SIGHASH_ALL],
1020
+ ): Promise<void> {
1021
+ hookSigner(keyPair);
1022
+
888
1023
  const { hash, sighashType } = getHashAndSighashType(
889
1024
  this.data.inputs,
890
1025
  inputIndex,
@@ -892,24 +1027,28 @@ class Psbt {
892
1027
  this.__CACHE,
893
1028
  sighashTypes,
894
1029
  );
895
- return Promise.resolve(keyPair.sign(hash)).then(signature => {
1030
+
1031
+ return Promise.resolve(keyPair.sign(hash)).then((signature) => {
896
1032
  const partialSig = [
897
1033
  {
898
1034
  pubkey: keyPair.publicKey,
899
1035
  signature: bscript.signature.encode(signature, sighashType),
900
1036
  },
901
1037
  ];
1038
+
902
1039
  this.data.updateInput(inputIndex, { partialSig });
903
1040
  });
904
1041
  }
905
- async _signTaprootInputAsync(
906
- inputIndex,
907
- input,
908
- keyPair,
909
- tapLeafHash,
910
- sighashTypes = [transaction_1.Transaction.SIGHASH_DEFAULT],
911
- ) {
912
- (0, HookedSigner_js_1.hookSigner)(keyPair);
1042
+
1043
+ private async _signTaprootInputAsync(
1044
+ inputIndex: number,
1045
+ input: PsbtInput,
1046
+ keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface,
1047
+ tapLeafHash?: Buffer,
1048
+ sighashTypes: number[] = [Transaction.SIGHASH_DEFAULT],
1049
+ ): Promise<void> {
1050
+ hookSigner(keyPair);
1051
+
913
1052
  const hashesForSig = this.checkTaprootHashesForSig(
914
1053
  inputIndex,
915
1054
  input,
@@ -917,101 +1056,187 @@ class Psbt {
917
1056
  tapLeafHash,
918
1057
  sighashTypes,
919
1058
  );
920
- const signaturePromises = [];
921
- const tapKeyHash = hashesForSig.filter(h => !h.leafHash)[0];
1059
+
1060
+ const signaturePromises: Promise<
1061
+ { tapKeySig: Buffer } | { tapScriptSig: TapScriptSig[] }
1062
+ >[] = [];
1063
+
1064
+ const tapKeyHash = hashesForSig.filter((h) => !h.leafHash)[0];
922
1065
  if (tapKeyHash) {
923
- const tapKeySigPromise = Promise.resolve(
924
- keyPair.signSchnorr(tapKeyHash.hash),
925
- ).then(sig => {
926
- return {
927
- tapKeySig: (0, bip371_1.serializeTaprootSignature)(
928
- sig,
929
- input.sighashType,
930
- ),
931
- };
932
- });
1066
+ const tapKeySigPromise = Promise.resolve(keyPair.signSchnorr!(tapKeyHash.hash)).then(
1067
+ (sig) => {
1068
+ return {
1069
+ tapKeySig: serializeTaprootSignature(sig, input.sighashType),
1070
+ };
1071
+ },
1072
+ );
933
1073
  signaturePromises.push(tapKeySigPromise);
934
1074
  }
935
- const tapScriptHashes = hashesForSig.filter(h => !!h.leafHash);
1075
+
1076
+ const tapScriptHashes = hashesForSig.filter((h) => !!h.leafHash);
936
1077
  if (tapScriptHashes.length) {
937
- const tapScriptSigPromises = tapScriptHashes.map(async tsh => {
938
- const signature = await keyPair.signSchnorr(tsh.hash);
1078
+ const tapScriptSigPromises = tapScriptHashes.map(async (tsh) => {
1079
+ const signature = await keyPair.signSchnorr!(tsh.hash);
1080
+
939
1081
  const tapScriptSig = [
940
1082
  {
941
- pubkey: (0, bip371_1.toXOnly)(keyPair.publicKey),
942
- signature: (0, bip371_1.serializeTaprootSignature)(
943
- signature,
944
- input.sighashType,
945
- ),
1083
+ pubkey: toXOnly(keyPair.publicKey),
1084
+ signature: serializeTaprootSignature(signature, input.sighashType),
946
1085
  leafHash: tsh.leafHash,
947
- },
1086
+ } as TapScriptSig,
948
1087
  ];
1088
+
949
1089
  return { tapScriptSig };
950
1090
  });
951
1091
  signaturePromises.push(...tapScriptSigPromises);
952
1092
  }
1093
+
953
1094
  const results = await Promise.all(signaturePromises);
954
1095
  for (const v of results) {
955
1096
  this.data.updateInput(inputIndex, v);
956
1097
  }
957
1098
  }
958
- checkTaprootHashesForSig(
959
- inputIndex,
960
- input,
961
- keyPair,
962
- tapLeafHashToSign,
963
- allowedSighashTypes,
964
- ) {
965
- if (typeof keyPair.signSchnorr !== 'function')
966
- throw new Error(
967
- `Need Schnorr Signer to sign taproot input #${inputIndex}.`,
968
- );
969
- const hashesForSig = getTaprootHashesForSig(
970
- inputIndex,
971
- input,
972
- this.data.inputs,
973
- keyPair.publicKey,
974
- this.__CACHE,
975
- tapLeafHashToSign,
976
- allowedSighashTypes,
977
- );
978
- if (!hashesForSig || !hashesForSig.length)
979
- throw new Error(
980
- `Can not sign for input #${inputIndex} with the key ${keyPair.publicKey.toString(
981
- 'hex',
982
- )}`,
983
- );
984
- return hashesForSig;
985
- }
986
1099
  }
987
- exports.Psbt = Psbt;
1100
+
1101
+ interface PsbtCache {
1102
+ __NON_WITNESS_UTXO_TX_CACHE: Transaction[];
1103
+ __NON_WITNESS_UTXO_BUF_CACHE: Buffer[];
1104
+ __TX_IN_CACHE: { [index: string]: number };
1105
+ __TX: Transaction;
1106
+ __FEE_RATE?: number;
1107
+ __FEE?: number;
1108
+ __EXTRACTED_TX?: Transaction;
1109
+ __UNSAFE_SIGN_NONSEGWIT: boolean;
1110
+ }
1111
+
1112
+ export interface PsbtOptsOptional {
1113
+ network?: Network;
1114
+ maximumFeeRate?: number;
1115
+ }
1116
+
1117
+ export interface PsbtOpts {
1118
+ network: Network;
1119
+ maximumFeeRate: number;
1120
+ }
1121
+
1122
+ export interface PsbtInputExtended extends PsbtInput, TransactionInput {}
1123
+
1124
+ export type PsbtOutputExtended = PsbtOutputExtendedAddress | PsbtOutputExtendedScript;
1125
+
1126
+ export interface PsbtOutputExtendedAddress extends PsbtOutput {
1127
+ address: string;
1128
+ value: number;
1129
+ }
1130
+
1131
+ export interface PsbtOutputExtendedScript extends PsbtOutput {
1132
+ script: Buffer;
1133
+ value: number;
1134
+ }
1135
+
1136
+ interface HDSignerBase {
1137
+ /**
1138
+ * DER format compressed publicKey buffer
1139
+ */
1140
+ publicKey: Buffer;
1141
+ /**
1142
+ * The first 4 bytes of the sha256-ripemd160 of the publicKey
1143
+ */
1144
+ fingerprint: Buffer;
1145
+ }
1146
+
1147
+ export interface HDSigner extends HDSignerBase {
1148
+ /**
1149
+ * The path string must match /^m(\/\d+'?)+$/
1150
+ * ex. m/44'/0'/0'/1/23 levels with ' must be hard derivations
1151
+ */
1152
+ derivePath(path: string): HDSigner;
1153
+
1154
+ /**
1155
+ * Input hash (the "message digest") for the signature algorithm
1156
+ * Return a 64 byte signature (32 byte r and 32 byte s in that order)
1157
+ */
1158
+ sign(hash: Buffer): Buffer;
1159
+ }
1160
+
1161
+ /**
1162
+ * Same as above but with async sign method
1163
+ */
1164
+ export interface HDSignerAsync extends HDSignerBase {
1165
+ derivePath(path: string): HDSignerAsync;
1166
+
1167
+ sign(hash: Buffer): Promise<Buffer>;
1168
+ }
1169
+
1170
+ export interface SignerAlternative {
1171
+ publicKey: Buffer;
1172
+ lowR: boolean;
1173
+
1174
+ sign(hash: Buffer, lowR?: boolean): Buffer;
1175
+
1176
+ verify(hash: Buffer, signature: Buffer): boolean;
1177
+
1178
+ signSchnorr(hash: Buffer): Buffer;
1179
+
1180
+ verifySchnorr(hash: Buffer, signature: Buffer): boolean;
1181
+ }
1182
+
1183
+ export interface Signer {
1184
+ publicKey: Buffer;
1185
+ network?: Network;
1186
+
1187
+ sign(hash: Buffer, lowR?: boolean): Buffer;
1188
+
1189
+ signSchnorr?(hash: Buffer): Buffer;
1190
+
1191
+ getPublicKey?(): Buffer;
1192
+ }
1193
+
1194
+ export interface SignerAsync {
1195
+ publicKey: Buffer;
1196
+ network?: Network;
1197
+
1198
+ sign(hash: Buffer, lowR?: boolean): Promise<Buffer>;
1199
+
1200
+ signSchnorr?(hash: Buffer): Promise<Buffer>;
1201
+
1202
+ getPublicKey?(): Buffer;
1203
+ }
1204
+
988
1205
  /**
989
1206
  * This function is needed to pass to the bip174 base class's fromBuffer.
990
1207
  * It takes the "transaction buffer" portion of the psbt buffer and returns a
991
1208
  * Transaction (From the bip174 library) interface.
992
1209
  */
993
- const transactionFromBuffer = buffer => new PsbtTransaction(buffer);
1210
+ const transactionFromBuffer: TransactionFromBuffer = (buffer: Buffer): ITransaction =>
1211
+ new PsbtTransaction(buffer);
1212
+
994
1213
  /**
995
1214
  * This class implements the Transaction interface from bip174 library.
996
1215
  * It contains a bitcoinjs-lib Transaction object.
997
1216
  */
998
- class PsbtTransaction {
999
- tx;
1000
- constructor(buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
1001
- this.tx = transaction_1.Transaction.fromBuffer(buffer);
1217
+ class PsbtTransaction implements ITransaction {
1218
+ tx: Transaction;
1219
+
1220
+ constructor(buffer: Buffer = Buffer.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0])) {
1221
+ this.tx = Transaction.fromBuffer(buffer);
1002
1222
  checkTxEmpty(this.tx);
1003
1223
  Object.defineProperty(this, 'tx', {
1004
1224
  enumerable: false,
1005
1225
  writable: true,
1006
1226
  });
1007
1227
  }
1008
- getInputOutputCounts() {
1228
+
1229
+ getInputOutputCounts(): {
1230
+ inputCount: number;
1231
+ outputCount: number;
1232
+ } {
1009
1233
  return {
1010
1234
  inputCount: this.tx.ins.length,
1011
1235
  outputCount: this.tx.outs.length,
1012
1236
  };
1013
1237
  }
1014
- addInput(input) {
1238
+
1239
+ addInput(input: TransactionInput): void {
1015
1240
  if (
1016
1241
  input.hash === undefined ||
1017
1242
  input.index === undefined ||
@@ -1022,13 +1247,13 @@ class PsbtTransaction {
1022
1247
  }
1023
1248
  const hash =
1024
1249
  typeof input.hash === 'string'
1025
- ? (0, bufferutils_1.reverseBuffer)(
1026
- Buffer.from(input.hash, 'hex'),
1027
- )
1250
+ ? reverseBuffer(Buffer.from(input.hash, 'hex'))
1028
1251
  : input.hash;
1252
+
1029
1253
  this.tx.addInput(hash, input.index, input.sequence);
1030
1254
  }
1031
- addOutput(output) {
1255
+
1256
+ addOutput(output: TransactionOutput): void {
1032
1257
  if (
1033
1258
  output.script === undefined ||
1034
1259
  output.value === undefined ||
@@ -1039,11 +1264,13 @@ class PsbtTransaction {
1039
1264
  }
1040
1265
  this.tx.addOutput(output.script, output.value);
1041
1266
  }
1042
- toBuffer() {
1267
+
1268
+ toBuffer(): Buffer {
1043
1269
  return this.tx.toBuffer();
1044
1270
  }
1045
1271
  }
1046
- function canFinalize(input, script, scriptType) {
1272
+
1273
+ function canFinalize(input: PsbtInput, script: Buffer, scriptType: string): boolean {
1047
1274
  switch (scriptType) {
1048
1275
  case 'pubkey':
1049
1276
  case 'pubkeyhash':
@@ -1051,61 +1278,60 @@ function canFinalize(input, script, scriptType) {
1051
1278
  return hasSigs(1, input.partialSig);
1052
1279
  case 'multisig':
1053
1280
  const p2ms = payments.p2ms({ output: script });
1054
- return hasSigs(p2ms.m, input.partialSig, p2ms.pubkeys);
1281
+ return hasSigs(p2ms.m!, input.partialSig, p2ms.pubkeys);
1055
1282
  default:
1056
1283
  return false;
1057
1284
  }
1058
1285
  }
1059
- function checkCache(cache) {
1286
+
1287
+ function checkCache(cache: PsbtCache): void {
1060
1288
  if (cache.__UNSAFE_SIGN_NONSEGWIT !== false) {
1061
1289
  throw new Error('Not BIP174 compliant, can not export');
1062
1290
  }
1063
1291
  }
1064
- function hasSigs(neededSigs, partialSig, pubkeys) {
1292
+
1293
+ function hasSigs(neededSigs: number, partialSig?: any[], pubkeys?: Buffer[]): boolean {
1065
1294
  if (!partialSig) return false;
1066
- let sigs;
1295
+ let sigs: any;
1067
1296
  if (pubkeys) {
1068
1297
  sigs = pubkeys
1069
- .map(pkey => {
1298
+ .map((pkey) => {
1070
1299
  const pubkey = compressPubkey(pkey);
1071
- return partialSig.find(pSig => pSig.pubkey.equals(pubkey));
1300
+ return partialSig.find((pSig) => pSig.pubkey.equals(pubkey));
1072
1301
  })
1073
- .filter(v => !!v);
1302
+ .filter((v) => !!v);
1074
1303
  } else {
1075
1304
  sigs = partialSig;
1076
1305
  }
1077
1306
  if (sigs.length > neededSigs) throw new Error('Too many signatures');
1078
1307
  return sigs.length === neededSigs;
1079
1308
  }
1080
- function isFinalized(input) {
1309
+
1310
+ function isFinalized(input: PsbtInput): boolean {
1081
1311
  return !!input.finalScriptSig || !!input.finalScriptWitness;
1082
1312
  }
1083
- function bip32DerivationIsMine(root) {
1084
- return d => {
1313
+
1314
+ function bip32DerivationIsMine(root: HDSigner): (d: Bip32Derivation) => boolean {
1315
+ return (d: Bip32Derivation): boolean => {
1085
1316
  if (!d.masterFingerprint.equals(root.fingerprint)) return false;
1086
1317
  if (!root.derivePath(d.path).publicKey.equals(d.pubkey)) return false;
1087
1318
  return true;
1088
1319
  };
1089
1320
  }
1090
- function check32Bit(num) {
1091
- if (
1092
- typeof num !== 'number' ||
1093
- num !== Math.floor(num) ||
1094
- num > 0xffffffff ||
1095
- num < 0
1096
- ) {
1321
+
1322
+ function check32Bit(num: number): void {
1323
+ if (typeof num !== 'number' || num !== Math.floor(num) || num > 0xffffffff || num < 0) {
1097
1324
  throw new Error('Invalid 32 bit integer');
1098
1325
  }
1099
1326
  }
1100
- function checkFees(psbt, cache, opts) {
1327
+
1328
+ function checkFees(psbt: Psbt, cache: PsbtCache, opts: PsbtOpts): void {
1101
1329
  const feeRate = cache.__FEE_RATE || psbt.getFeeRate();
1102
- const vsize = cache.__EXTRACTED_TX.virtualSize();
1330
+ const vsize = cache.__EXTRACTED_TX!.virtualSize();
1103
1331
  const satoshis = feeRate * vsize;
1104
1332
  if (feeRate >= opts.maximumFeeRate) {
1105
1333
  throw new Error(
1106
- `Warning: You are paying around ${(satoshis / 1e8).toFixed(
1107
- 8,
1108
- )} in ` +
1334
+ `Warning: You are paying around ${(satoshis / 1e8).toFixed(8)} in ` +
1109
1335
  `fees, which is ${feeRate} satoshi per byte for a transaction ` +
1110
1336
  `with a VSize of ${vsize} bytes (segwit counted as 0.25 byte per ` +
1111
1337
  `byte). Use setMaximumFeeRate method to raise your threshold, or ` +
@@ -1113,39 +1339,36 @@ function checkFees(psbt, cache, opts) {
1113
1339
  );
1114
1340
  }
1115
1341
  }
1116
- function checkInputsForPartialSig(inputs, action) {
1117
- inputs.forEach(input => {
1118
- const throws = (0, bip371_1.isTaprootInput)(input)
1119
- ? (0, bip371_1.checkTaprootInputForSigs)(input, action)
1120
- : (0, psbtutils_1.checkInputForSig)(input, action);
1121
- if (throws)
1122
- throw new Error('Can not modify transaction, signatures exist.');
1342
+
1343
+ function checkInputsForPartialSig(inputs: PsbtInput[], action: string): void {
1344
+ inputs.forEach((input) => {
1345
+ const throws = isTaprootInput(input)
1346
+ ? checkTaprootInputForSigs(input, action)
1347
+ : checkInputForSig(input, action);
1348
+ if (throws) throw new Error('Can not modify transaction, signatures exist.');
1123
1349
  });
1124
1350
  }
1125
- function checkPartialSigSighashes(input) {
1351
+
1352
+ function checkPartialSigSighashes(input: PsbtInput): void {
1126
1353
  if (!input.sighashType || !input.partialSig) return;
1127
1354
  const { partialSig, sighashType } = input;
1128
- partialSig.forEach(pSig => {
1355
+ partialSig.forEach((pSig) => {
1129
1356
  const { hashType } = bscript.signature.decode(pSig.signature);
1130
1357
  if (sighashType !== hashType) {
1131
- throw new Error(
1132
- 'Signature sighash does not match input sighash type',
1133
- );
1358
+ throw new Error('Signature sighash does not match input sighash type');
1134
1359
  }
1135
1360
  });
1136
1361
  }
1137
- function checkScriptForPubkey(pubkey, script, action) {
1138
- if (!(0, psbtutils_1.pubkeyInScript)(pubkey, script)) {
1139
- throw new Error(
1140
- `Can not ${action} for this input with the key ${pubkey.toString(
1141
- 'hex',
1142
- )}`,
1143
- );
1362
+
1363
+ function checkScriptForPubkey(pubkey: Buffer, script: Buffer, action: string): void {
1364
+ if (!pubkeyInScript(pubkey, script)) {
1365
+ throw new Error(`Can not ${action} for this input with the key ${pubkey.toString('hex')}`);
1144
1366
  }
1145
1367
  }
1146
- function checkTxEmpty(tx) {
1368
+
1369
+ function checkTxEmpty(tx: Transaction): void {
1147
1370
  const isEmpty = tx.ins.every(
1148
- input =>
1371
+ (input) =>
1149
1372
  input.script &&
1150
1373
  input.script.length === 0 &&
1151
1374
  input.witness &&
@@ -1155,26 +1378,33 @@ function checkTxEmpty(tx) {
1155
1378
  throw new Error('Format Error: Transaction ScriptSigs are not empty');
1156
1379
  }
1157
1380
  }
1158
- function checkTxForDupeIns(tx, cache) {
1159
- tx.ins.forEach(input => {
1381
+
1382
+ function checkTxForDupeIns(tx: Transaction, cache: PsbtCache): void {
1383
+ tx.ins.forEach((input) => {
1160
1384
  checkTxInputCache(cache, input);
1161
1385
  });
1162
1386
  }
1163
- function checkTxInputCache(cache, input) {
1164
- const key =
1165
- (0, bufferutils_1.reverseBuffer)(Buffer.from(input.hash)).toString(
1166
- 'hex',
1167
- ) +
1168
- ':' +
1169
- input.index;
1387
+
1388
+ function checkTxInputCache(cache: PsbtCache, input: { hash: Buffer; index: number }): void {
1389
+ const key = reverseBuffer(Buffer.from(input.hash)).toString('hex') + ':' + input.index;
1170
1390
  if (cache.__TX_IN_CACHE[key]) throw new Error('Duplicate input detected.');
1171
1391
  cache.__TX_IN_CACHE[key] = 1;
1172
1392
  }
1173
- function scriptCheckerFactory(payment, paymentScriptName) {
1174
- return (inputIndex, scriptPubKey, redeemScript, ioType) => {
1393
+
1394
+ function scriptCheckerFactory(
1395
+ payment: (a: Payment, opts?: PaymentOpts) => Payment,
1396
+ paymentScriptName: string,
1397
+ ): (idx: number, scriptPubKey: Buffer, redeemScript: Buffer, ioType: 'input' | 'output') => void {
1398
+ return (
1399
+ inputIndex: number,
1400
+ scriptPubKey: Buffer,
1401
+ redeemScript: Buffer,
1402
+ ioType: 'input' | 'output',
1403
+ ): void => {
1175
1404
  const redeemScriptOutput = payment({
1176
1405
  redeem: { output: redeemScript },
1177
- }).output;
1406
+ }).output as Buffer;
1407
+
1178
1408
  if (!scriptPubKey.equals(redeemScriptOutput)) {
1179
1409
  throw new Error(
1180
1410
  `${paymentScriptName} for ${ioType} #${inputIndex} doesn't match the scriptPubKey in the prevout`,
@@ -1182,17 +1412,23 @@ function scriptCheckerFactory(payment, paymentScriptName) {
1182
1412
  }
1183
1413
  };
1184
1414
  }
1415
+
1185
1416
  const checkRedeemScript = scriptCheckerFactory(payments.p2sh, 'Redeem script');
1186
- const checkWitnessScript = scriptCheckerFactory(
1187
- payments.p2wsh,
1188
- 'Witness script',
1189
- );
1190
- function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
1191
- if (!inputs.every(isFinalized))
1192
- throw new Error(`PSBT must be finalized to calculate ${name}`);
1417
+ const checkWitnessScript = scriptCheckerFactory(payments.p2wsh, 'Witness script');
1418
+
1419
+ type TxCacheNumberKey = '__FEE_RATE' | '__FEE';
1420
+
1421
+ function getTxCacheValue(
1422
+ key: TxCacheNumberKey,
1423
+ name: string,
1424
+ inputs: PsbtInput[],
1425
+ c: PsbtCache,
1426
+ disableOutputChecks: boolean = false,
1427
+ ): number | undefined {
1428
+ if (!inputs.every(isFinalized)) throw new Error(`PSBT must be finalized to calculate ${name}`);
1193
1429
  if (key === '__FEE_RATE' && c.__FEE_RATE) return c.__FEE_RATE;
1194
1430
  if (key === '__FEE' && c.__FEE) return c.__FEE;
1195
- let tx;
1431
+ let tx: Transaction;
1196
1432
  let mustFinalize = true;
1197
1433
  if (c.__EXTRACTED_TX) {
1198
1434
  tx = c.__EXTRACTED_TX;
@@ -1201,46 +1437,76 @@ function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
1201
1437
  tx = c.__TX.clone();
1202
1438
  }
1203
1439
  inputFinalizeGetAmts(inputs, tx, c, mustFinalize, disableOutputChecks);
1204
- if (key === '__FEE_RATE') return c.__FEE_RATE;
1205
- else if (key === '__FEE') return c.__FEE;
1440
+ if (key === '__FEE_RATE') return c.__FEE_RATE!;
1441
+ else if (key === '__FEE') return c.__FEE!;
1206
1442
  }
1207
- function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH) {
1443
+
1444
+ /**
1445
+ * This function must do two things:
1446
+ * 1. Check if the `input` can be finalized. If it can not be finalized, throw.
1447
+ * ie. `Can not finalize input #${inputIndex}`
1448
+ * 2. Create the finalScriptSig and finalScriptWitness Buffers.
1449
+ */
1450
+ type FinalScriptsFunc = (
1451
+ inputIndex: number, // Which input is it?
1452
+ input: PsbtInput, // The PSBT input contents
1453
+ script: Buffer, // The "meaningful" locking script Buffer (redeemScript for P2SH etc.)
1454
+ isSegwit: boolean, // Is it segwit?
1455
+ isP2SH: boolean, // Is it P2SH?
1456
+ isP2WSH: boolean, // Is it P2WSH?
1457
+ ) => {
1458
+ finalScriptSig: Buffer | undefined;
1459
+ finalScriptWitness: Buffer | undefined;
1460
+ };
1461
+ type FinalTaprootScriptsFunc = (
1462
+ inputIndex: number, // Which input is it?
1463
+ input: PsbtInput, // The PSBT input contents
1464
+ tapLeafHashToFinalize?: Buffer, // Only finalize this specific leaf
1465
+ ) => {
1466
+ finalScriptWitness: Buffer | undefined;
1467
+ };
1468
+
1469
+ export function getFinalScripts(
1470
+ inputIndex: number,
1471
+ input: PsbtInput,
1472
+ script: Buffer,
1473
+ isSegwit: boolean,
1474
+ isP2SH: boolean,
1475
+ isP2WSH: boolean,
1476
+ ): {
1477
+ finalScriptSig: Buffer | undefined;
1478
+ finalScriptWitness: Buffer | undefined;
1479
+ } {
1208
1480
  const scriptType = classifyScript(script);
1209
1481
  if (!canFinalize(input, script, scriptType))
1210
1482
  throw new Error(`Can not finalize input #${inputIndex}`);
1211
- return prepareFinalScripts(
1212
- script,
1213
- scriptType,
1214
- input.partialSig,
1215
- isSegwit,
1216
- isP2SH,
1217
- isP2WSH,
1218
- );
1483
+ return prepareFinalScripts(script, scriptType, input.partialSig!, isSegwit, isP2SH, isP2WSH);
1219
1484
  }
1220
- exports.getFinalScripts = getFinalScripts;
1221
- function prepareFinalScripts(
1222
- script,
1223
- scriptType,
1224
- partialSig,
1225
- isSegwit,
1226
- isP2SH,
1227
- isP2WSH,
1228
- ) {
1229
- let finalScriptSig;
1230
- let finalScriptWitness;
1485
+
1486
+ export function prepareFinalScripts(
1487
+ script: Buffer,
1488
+ scriptType: string,
1489
+ partialSig: PartialSig[],
1490
+ isSegwit: boolean,
1491
+ isP2SH: boolean,
1492
+ isP2WSH: boolean,
1493
+ ): {
1494
+ finalScriptSig: Buffer | undefined;
1495
+ finalScriptWitness: Buffer | undefined;
1496
+ } {
1497
+ let finalScriptSig: Buffer | undefined;
1498
+ let finalScriptWitness: Buffer | undefined;
1499
+
1231
1500
  // Wow, the payments API is very handy
1232
- const payment = getPayment(script, scriptType, partialSig);
1501
+ const payment: payments.Payment = getPayment(script, scriptType, partialSig);
1233
1502
  const p2wsh = !isP2WSH ? null : payments.p2wsh({ redeem: payment });
1234
1503
  const p2sh = !isP2SH ? null : payments.p2sh({ redeem: p2wsh || payment });
1504
+
1235
1505
  if (isSegwit) {
1236
1506
  if (p2wsh) {
1237
- finalScriptWitness = (0, psbtutils_1.witnessStackToScriptWitness)(
1238
- p2wsh.witness,
1239
- );
1507
+ finalScriptWitness = witnessStackToScriptWitness(p2wsh.witness!);
1240
1508
  } else {
1241
- finalScriptWitness = (0, psbtutils_1.witnessStackToScriptWitness)(
1242
- payment.witness,
1243
- );
1509
+ finalScriptWitness = witnessStackToScriptWitness(payment.witness!);
1244
1510
  }
1245
1511
  if (p2sh) {
1246
1512
  finalScriptSig = p2sh.input;
@@ -1257,15 +1523,18 @@ function prepareFinalScripts(
1257
1523
  finalScriptWitness,
1258
1524
  };
1259
1525
  }
1260
- exports.prepareFinalScripts = prepareFinalScripts;
1526
+
1261
1527
  function getHashAndSighashType(
1262
- inputs,
1263
- inputIndex,
1264
- pubkey,
1265
- cache,
1266
- sighashTypes,
1267
- ) {
1268
- const input = (0, utils_1.checkForInput)(inputs, inputIndex);
1528
+ inputs: PsbtInput[],
1529
+ inputIndex: number,
1530
+ pubkey: Buffer,
1531
+ cache: PsbtCache,
1532
+ sighashTypes: number[],
1533
+ ): {
1534
+ hash: Buffer;
1535
+ sighashType: number;
1536
+ } {
1537
+ const input = checkForInput(inputs, inputIndex);
1269
1538
  const { hash, sighashType, script } = getHashForSig(
1270
1539
  inputIndex,
1271
1540
  input,
@@ -1273,40 +1542,53 @@ function getHashAndSighashType(
1273
1542
  false,
1274
1543
  sighashTypes,
1275
1544
  );
1545
+
1276
1546
  checkScriptForPubkey(pubkey, script, 'sign');
1277
1547
  return {
1278
1548
  hash,
1279
1549
  sighashType,
1280
1550
  };
1281
1551
  }
1282
- function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
1552
+
1553
+ function getHashForSig(
1554
+ inputIndex: number,
1555
+ input: PsbtInput,
1556
+ cache: PsbtCache,
1557
+ forValidate: boolean,
1558
+ sighashTypes?: number[],
1559
+ ): {
1560
+ script: Buffer;
1561
+ hash: Buffer;
1562
+ sighashType: number;
1563
+ } {
1283
1564
  const unsignedTx = cache.__TX;
1284
- const sighashType =
1285
- input.sighashType || transaction_1.Transaction.SIGHASH_ALL;
1565
+ const sighashType = input.sighashType || Transaction.SIGHASH_ALL;
1286
1566
  checkSighashTypeAllowed(sighashType, sighashTypes);
1287
- let hash;
1288
- let prevout;
1567
+
1568
+ let hash: Buffer;
1569
+ let prevout: Output;
1570
+
1289
1571
  if (input.nonWitnessUtxo) {
1290
- const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
1291
- cache,
1292
- input,
1293
- inputIndex,
1294
- );
1572
+ const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
1573
+
1295
1574
  const prevoutHash = unsignedTx.ins[inputIndex].hash;
1296
1575
  const utxoHash = nonWitnessUtxoTx.getHash();
1576
+
1297
1577
  // If a non-witness UTXO is provided, its hash must match the hash specified in the prevout
1298
1578
  if (!prevoutHash.equals(utxoHash)) {
1299
1579
  throw new Error(
1300
1580
  `Non-witness UTXO hash for input #${inputIndex} doesn't match the hash specified in the prevout`,
1301
1581
  );
1302
1582
  }
1583
+
1303
1584
  const prevoutIndex = unsignedTx.ins[inputIndex].index;
1304
- prevout = nonWitnessUtxoTx.outs[prevoutIndex];
1585
+ prevout = nonWitnessUtxoTx.outs[prevoutIndex] as Output;
1305
1586
  } else if (input.witnessUtxo) {
1306
1587
  prevout = input.witnessUtxo;
1307
1588
  } else {
1308
1589
  throw new Error('Need a Utxo input item for signing');
1309
1590
  }
1591
+
1310
1592
  const { meaningfulScript, type } = getMeaningfulScript(
1311
1593
  prevout.script,
1312
1594
  inputIndex,
@@ -1314,6 +1596,7 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
1314
1596
  input.redeemScript,
1315
1597
  input.witnessScript,
1316
1598
  );
1599
+
1317
1600
  if (['p2sh-p2wsh', 'p2wsh'].indexOf(type) >= 0) {
1318
1601
  hash = unsignedTx.hashForWitnessV0(
1319
1602
  inputIndex,
@@ -1321,23 +1604,15 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
1321
1604
  prevout.value,
1322
1605
  sighashType,
1323
1606
  );
1324
- } else if ((0, psbtutils_1.isP2WPKH)(meaningfulScript)) {
1607
+ } else if (isP2WPKH(meaningfulScript)) {
1325
1608
  // P2WPKH uses the P2PKH template for prevoutScript when signing
1326
1609
  const signingScript = payments.p2pkh({
1327
1610
  hash: meaningfulScript.slice(2),
1328
- }).output;
1329
- hash = unsignedTx.hashForWitnessV0(
1330
- inputIndex,
1331
- signingScript,
1332
- prevout.value,
1333
- sighashType,
1334
- );
1611
+ }).output!;
1612
+ hash = unsignedTx.hashForWitnessV0(inputIndex, signingScript, prevout.value, sighashType);
1335
1613
  } else {
1336
1614
  // non-segwit
1337
- if (
1338
- input.nonWitnessUtxo === undefined &&
1339
- cache.__UNSAFE_SIGN_NONSEGWIT === false
1340
- )
1615
+ if (input.nonWitnessUtxo === undefined && cache.__UNSAFE_SIGN_NONSEGWIT === false)
1341
1616
  throw new Error(
1342
1617
  `Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
1343
1618
  `${meaningfulScript.toString('hex')}`,
@@ -1352,19 +1627,22 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
1352
1627
  'BIP174 compliant.\n*********************\nPROCEED WITH CAUTION!\n' +
1353
1628
  '*********************',
1354
1629
  );
1355
- hash = unsignedTx.hashForSignature(
1356
- inputIndex,
1357
- meaningfulScript,
1358
- sighashType,
1359
- );
1630
+ hash = unsignedTx.hashForSignature(inputIndex, meaningfulScript, sighashType);
1360
1631
  }
1632
+
1361
1633
  return {
1362
1634
  script: meaningfulScript,
1363
1635
  sighashType,
1364
1636
  hash,
1365
1637
  };
1366
1638
  }
1367
- function getAllTaprootHashesForSig(inputIndex, input, inputs, cache) {
1639
+
1640
+ function getAllTaprootHashesForSig(
1641
+ inputIndex: number,
1642
+ input: PsbtInput,
1643
+ inputs: PsbtInput[],
1644
+ cache: PsbtCache,
1645
+ ): { pubkey: Buffer; hash: Buffer; leafHash?: Buffer }[] {
1368
1646
  const allPublicKeys = [];
1369
1647
  if (input.tapInternalKey) {
1370
1648
  const key = getPrevoutTaprootKey(inputIndex, input, cache);
@@ -1372,45 +1650,56 @@ function getAllTaprootHashesForSig(inputIndex, input, inputs, cache) {
1372
1650
  allPublicKeys.push(key);
1373
1651
  }
1374
1652
  }
1653
+
1375
1654
  if (input.tapScriptSig) {
1376
- const tapScriptPubkeys = input.tapScriptSig.map(tss => tss.pubkey);
1655
+ const tapScriptPubkeys = input.tapScriptSig.map((tss) => tss.pubkey);
1377
1656
  allPublicKeys.push(...tapScriptPubkeys);
1378
1657
  }
1379
- const allHashes = allPublicKeys.map(pubicKey =>
1658
+
1659
+ const allHashes = allPublicKeys.map((pubicKey) =>
1380
1660
  getTaprootHashesForSig(inputIndex, input, inputs, pubicKey, cache),
1381
1661
  );
1662
+
1382
1663
  return allHashes.flat();
1383
1664
  }
1384
- function getPrevoutTaprootKey(inputIndex, input, cache) {
1665
+
1666
+ function getPrevoutTaprootKey(
1667
+ inputIndex: number,
1668
+ input: PsbtInput,
1669
+ cache: PsbtCache,
1670
+ ): Buffer | null {
1385
1671
  const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
1386
- return (0, psbtutils_1.isP2TR)(script) ? script.subarray(2, 34) : null;
1672
+ return isP2TR(script) ? script.subarray(2, 34) : null;
1387
1673
  }
1388
- function trimTaprootSig(signature) {
1674
+
1675
+ function trimTaprootSig(signature: Buffer): Buffer {
1389
1676
  return signature.length === 64 ? signature : signature.subarray(0, 64);
1390
1677
  }
1678
+
1391
1679
  function getTaprootHashesForSig(
1392
- inputIndex,
1393
- input,
1394
- inputs,
1395
- pubkey,
1396
- cache,
1397
- tapLeafHashToSign,
1398
- allowedSighashTypes,
1399
- ) {
1680
+ inputIndex: number,
1681
+ input: PsbtInput,
1682
+ inputs: PsbtInput[],
1683
+ pubkey: Buffer,
1684
+ cache: PsbtCache,
1685
+ tapLeafHashToSign?: Buffer,
1686
+ allowedSighashTypes?: number[],
1687
+ ): { pubkey: Buffer; hash: Buffer; leafHash?: Buffer }[] {
1400
1688
  const unsignedTx = cache.__TX;
1401
- const sighashType =
1402
- input.sighashType || transaction_1.Transaction.SIGHASH_DEFAULT;
1689
+
1690
+ const sighashType = input.sighashType || Transaction.SIGHASH_DEFAULT;
1403
1691
  checkSighashTypeAllowed(sighashType, allowedSighashTypes);
1404
- const prevOuts = inputs.map((i, index) =>
1692
+
1693
+ const prevOuts: Output[] = inputs.map((i, index) =>
1405
1694
  getScriptAndAmountFromUtxo(index, i, cache),
1406
1695
  );
1407
- const signingScripts = prevOuts.map(o => o.script);
1408
- const values = prevOuts.map(o => o.value);
1696
+ const signingScripts = prevOuts.map((o) => o.script);
1697
+ const values = prevOuts.map((o) => o.value);
1698
+
1409
1699
  const hashes = [];
1410
1700
  if (input.tapInternalKey && !tapLeafHashToSign) {
1411
- const outputKey =
1412
- getPrevoutTaprootKey(inputIndex, input, cache) || Buffer.from([]);
1413
- if ((0, bip371_1.toXOnly)(pubkey).equals(outputKey)) {
1701
+ const outputKey = getPrevoutTaprootKey(inputIndex, input, cache) || Buffer.from([]);
1702
+ if (toXOnly(pubkey).equals(outputKey)) {
1414
1703
  const tapKeyHash = unsignedTx.hashForWitnessV1(
1415
1704
  inputIndex,
1416
1705
  signingScripts,
@@ -1420,22 +1709,18 @@ function getTaprootHashesForSig(
1420
1709
  hashes.push({ pubkey, hash: tapKeyHash });
1421
1710
  }
1422
1711
  }
1712
+
1423
1713
  const tapLeafHashes = (input.tapLeafScript || [])
1424
- .filter(tapLeaf =>
1425
- (0, psbtutils_1.pubkeyInScript)(pubkey, tapLeaf.script),
1426
- )
1427
- .map(tapLeaf => {
1428
- const hash = (0, bip341_1.tapleafHash)({
1714
+ .filter((tapLeaf) => pubkeyInScript(pubkey, tapLeaf.script))
1715
+ .map((tapLeaf) => {
1716
+ const hash = tapleafHash({
1429
1717
  output: tapLeaf.script,
1430
1718
  version: tapLeaf.leafVersion,
1431
1719
  });
1432
1720
  return Object.assign({ hash }, tapLeaf);
1433
1721
  })
1434
- .filter(
1435
- tapLeaf =>
1436
- !tapLeafHashToSign || tapLeafHashToSign.equals(tapLeaf.hash),
1437
- )
1438
- .map(tapLeaf => {
1722
+ .filter((tapLeaf) => !tapLeafHashToSign || tapLeafHashToSign.equals(tapLeaf.hash))
1723
+ .map((tapLeaf) => {
1439
1724
  const tapScriptHash = unsignedTx.hashForWitnessV1(
1440
1725
  inputIndex,
1441
1726
  signingScripts,
@@ -1443,15 +1728,18 @@ function getTaprootHashesForSig(
1443
1728
  sighashType,
1444
1729
  tapLeaf.hash,
1445
1730
  );
1731
+
1446
1732
  return {
1447
1733
  pubkey,
1448
1734
  hash: tapScriptHash,
1449
1735
  leafHash: tapLeaf.hash,
1450
1736
  };
1451
1737
  });
1738
+
1452
1739
  return hashes.concat(tapLeafHashes);
1453
1740
  }
1454
- function checkSighashTypeAllowed(sighashType, sighashTypes) {
1741
+
1742
+ function checkSighashTypeAllowed(sighashType: number, sighashTypes?: number[]): void {
1455
1743
  if (sighashTypes && sighashTypes.indexOf(sighashType) < 0) {
1456
1744
  const str = sighashTypeToString(sighashType);
1457
1745
  throw new Error(
@@ -1460,8 +1748,13 @@ function checkSighashTypeAllowed(sighashType, sighashTypes) {
1460
1748
  );
1461
1749
  }
1462
1750
  }
1463
- function getPayment(script, scriptType, partialSig) {
1464
- let payment;
1751
+
1752
+ function getPayment(
1753
+ script: Buffer,
1754
+ scriptType: string,
1755
+ partialSig: PartialSig[],
1756
+ ): payments.Payment {
1757
+ let payment: payments.Payment;
1465
1758
  switch (scriptType) {
1466
1759
  case 'multisig':
1467
1760
  const sigs = getSortedSigs(script, partialSig);
@@ -1491,11 +1784,23 @@ function getPayment(script, scriptType, partialSig) {
1491
1784
  });
1492
1785
  break;
1493
1786
  }
1494
- return payment;
1787
+ return payment!;
1495
1788
  }
1496
- function getScriptFromInput(inputIndex, input, cache) {
1789
+
1790
+ interface GetScriptReturn {
1791
+ script: Buffer | null;
1792
+ isSegwit: boolean;
1793
+ isP2SH: boolean;
1794
+ isP2WSH: boolean;
1795
+ }
1796
+
1797
+ function getScriptFromInput(
1798
+ inputIndex: number,
1799
+ input: PsbtInput,
1800
+ cache: PsbtCache,
1801
+ ): GetScriptReturn {
1497
1802
  const unsignedTx = cache.__TX;
1498
- const res = {
1803
+ const res: GetScriptReturn = {
1499
1804
  script: null,
1500
1805
  isSegwit: false,
1501
1806
  isP2SH: false,
@@ -1509,116 +1814,124 @@ function getScriptFromInput(inputIndex, input, cache) {
1509
1814
  res.script = input.redeemScript;
1510
1815
  } else {
1511
1816
  if (input.nonWitnessUtxo) {
1512
- const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
1513
- cache,
1514
- input,
1515
- inputIndex,
1516
- );
1817
+ const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
1517
1818
  const prevoutIndex = unsignedTx.ins[inputIndex].index;
1518
1819
  res.script = nonWitnessUtxoTx.outs[prevoutIndex].script;
1519
1820
  } else if (input.witnessUtxo) {
1520
1821
  res.script = input.witnessUtxo.script;
1521
1822
  }
1522
1823
  }
1523
- if (input.witnessScript || (0, psbtutils_1.isP2WPKH)(res.script)) {
1824
+ if (input.witnessScript || isP2WPKH(res.script!)) {
1524
1825
  res.isSegwit = true;
1525
1826
  }
1526
1827
  return res;
1527
1828
  }
1528
- function getSignersFromHD(inputIndex, inputs, hdKeyPair) {
1529
- const input = (0, utils_1.checkForInput)(inputs, inputIndex);
1829
+
1830
+ function getSignersFromHD(
1831
+ inputIndex: number,
1832
+ inputs: PsbtInput[],
1833
+ hdKeyPair: HDSigner | HDSignerAsync,
1834
+ ): (HDSigner | HDSignerAsync)[] {
1835
+ const input = checkForInput(inputs, inputIndex);
1530
1836
  if (!input.bip32Derivation || input.bip32Derivation.length === 0) {
1531
1837
  throw new Error('Need bip32Derivation to sign with HD');
1532
1838
  }
1533
1839
  const myDerivations = input.bip32Derivation
1534
- .map(bipDv => {
1840
+ .map((bipDv) => {
1535
1841
  if (bipDv.masterFingerprint.equals(hdKeyPair.fingerprint)) {
1536
1842
  return bipDv;
1537
1843
  } else {
1538
1844
  return;
1539
1845
  }
1540
1846
  })
1541
- .filter(v => !!v);
1847
+ .filter((v) => !!v);
1542
1848
  if (myDerivations.length === 0) {
1543
1849
  throw new Error(
1544
1850
  'Need one bip32Derivation masterFingerprint to match the HDSigner fingerprint',
1545
1851
  );
1546
1852
  }
1547
- return myDerivations.map(bipDv => {
1548
- const node = hdKeyPair.derivePath(bipDv.path);
1549
- if (!bipDv.pubkey.equals(node.publicKey)) {
1853
+
1854
+ return myDerivations.map((bipDv) => {
1855
+ const node = hdKeyPair.derivePath(bipDv!.path);
1856
+ if (!bipDv!.pubkey.equals(node.publicKey)) {
1550
1857
  throw new Error('pubkey did not match bip32Derivation');
1551
1858
  }
1552
1859
  return node;
1553
1860
  });
1554
1861
  }
1555
- function getSortedSigs(script, partialSig) {
1862
+
1863
+ function getSortedSigs(script: Buffer, partialSig: PartialSig[]): Buffer[] {
1556
1864
  const p2ms = payments.p2ms({ output: script });
1557
1865
  // for each pubkey in order of p2ms script
1558
- return p2ms.pubkeys
1559
- .map(pk => {
1866
+ return p2ms
1867
+ .pubkeys!.map((pk) => {
1560
1868
  // filter partialSig array by pubkey being equal
1561
1869
  return (
1562
- partialSig.filter(ps => {
1870
+ partialSig.filter((ps) => {
1563
1871
  return ps.pubkey.equals(pk);
1564
1872
  })[0] || {}
1565
1873
  ).signature;
1566
1874
  // Any pubkey without a match will return undefined
1567
1875
  // this last filter removes all the undefined items in the array.
1568
1876
  })
1569
- .filter(v => !!v);
1877
+ .filter((v) => !!v);
1570
1878
  }
1571
- function scriptWitnessToWitnessStack(buffer) {
1879
+
1880
+ function scriptWitnessToWitnessStack(buffer: Buffer): Buffer[] {
1572
1881
  let offset = 0;
1573
- function readSlice(n) {
1882
+
1883
+ function readSlice(n: number): Buffer {
1574
1884
  offset += n;
1575
1885
  return buffer.slice(offset - n, offset);
1576
1886
  }
1577
- function readVarInt() {
1887
+
1888
+ function readVarInt(): number {
1578
1889
  const vi = varuint.decode(buffer, offset);
1579
- offset += varuint.decode.bytes;
1890
+ offset += (varuint.decode as any).bytes;
1580
1891
  return vi;
1581
1892
  }
1582
- function readVarSlice() {
1893
+
1894
+ function readVarSlice(): Buffer {
1583
1895
  return readSlice(readVarInt());
1584
1896
  }
1585
- function readVector() {
1897
+
1898
+ function readVector(): Buffer[] {
1586
1899
  const count = readVarInt();
1587
- const vector = [];
1900
+ const vector: Buffer[] = [];
1588
1901
  for (let i = 0; i < count; i++) vector.push(readVarSlice());
1589
1902
  return vector;
1590
1903
  }
1904
+
1591
1905
  return readVector();
1592
1906
  }
1593
- function sighashTypeToString(sighashType) {
1594
- let text =
1595
- sighashType & transaction_1.Transaction.SIGHASH_ANYONECANPAY
1596
- ? 'SIGHASH_ANYONECANPAY | '
1597
- : '';
1907
+
1908
+ function sighashTypeToString(sighashType: number): string {
1909
+ let text = sighashType & Transaction.SIGHASH_ANYONECANPAY ? 'SIGHASH_ANYONECANPAY | ' : '';
1598
1910
  const sigMod = sighashType & 0x1f;
1599
1911
  switch (sigMod) {
1600
- case transaction_1.Transaction.SIGHASH_ALL:
1912
+ case Transaction.SIGHASH_ALL:
1601
1913
  text += 'SIGHASH_ALL';
1602
1914
  break;
1603
- case transaction_1.Transaction.SIGHASH_SINGLE:
1915
+ case Transaction.SIGHASH_SINGLE:
1604
1916
  text += 'SIGHASH_SINGLE';
1605
1917
  break;
1606
- case transaction_1.Transaction.SIGHASH_NONE:
1918
+ case Transaction.SIGHASH_NONE:
1607
1919
  text += 'SIGHASH_NONE';
1608
1920
  break;
1609
1921
  }
1610
1922
  return text;
1611
1923
  }
1612
- function addNonWitnessTxCache(cache, input, inputIndex) {
1613
- cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo;
1614
- const tx = transaction_1.Transaction.fromBuffer(input.nonWitnessUtxo);
1615
- cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx;
1924
+
1925
+ function addNonWitnessTxCache(cache: PsbtCache, input: PsbtInput, inputIndex: number): void {
1926
+ cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo!;
1927
+ cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = Transaction.fromBuffer(input.nonWitnessUtxo!);
1928
+
1616
1929
  const self = cache;
1617
1930
  const selfIndex = inputIndex;
1618
1931
  delete input.nonWitnessUtxo;
1619
1932
  Object.defineProperty(input, 'nonWitnessUtxo', {
1620
1933
  enumerable: true,
1621
- get() {
1934
+ get(): Buffer {
1622
1935
  const buf = self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
1623
1936
  const txCache = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex];
1624
1937
  if (buf !== undefined) {
@@ -1629,37 +1942,35 @@ function addNonWitnessTxCache(cache, input, inputIndex) {
1629
1942
  return newBuf;
1630
1943
  }
1631
1944
  },
1632
- set(data) {
1945
+ set(data: Buffer): void {
1633
1946
  self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data;
1634
1947
  },
1635
1948
  });
1636
1949
  }
1950
+
1637
1951
  function inputFinalizeGetAmts(
1638
- inputs,
1639
- tx,
1640
- cache,
1641
- mustFinalize,
1642
- disableOutputChecks,
1643
- ) {
1952
+ inputs: PsbtInput[],
1953
+ tx: Transaction,
1954
+ cache: PsbtCache,
1955
+ mustFinalize: boolean,
1956
+ disableOutputChecks?: boolean,
1957
+ ): void {
1644
1958
  let inputAmount = 0;
1645
1959
  inputs.forEach((input, idx) => {
1646
- if (mustFinalize && input.finalScriptSig)
1647
- tx.ins[idx].script = input.finalScriptSig;
1960
+ if (mustFinalize && input.finalScriptSig) tx.ins[idx].script = input.finalScriptSig;
1648
1961
  if (mustFinalize && input.finalScriptWitness) {
1649
- tx.ins[idx].witness = scriptWitnessToWitnessStack(
1650
- input.finalScriptWitness,
1651
- );
1962
+ tx.ins[idx].witness = scriptWitnessToWitnessStack(input.finalScriptWitness);
1652
1963
  }
1653
1964
  if (input.witnessUtxo) {
1654
1965
  inputAmount += input.witnessUtxo.value;
1655
1966
  } else if (input.nonWitnessUtxo) {
1656
1967
  const nwTx = nonWitnessUtxoTxFromCache(cache, input, idx);
1657
1968
  const vout = tx.ins[idx].index;
1658
- const out = nwTx.outs[vout];
1969
+ const out = nwTx.outs[vout] as Output;
1659
1970
  inputAmount += out.value;
1660
1971
  }
1661
1972
  });
1662
- const outputAmount = tx.outs.reduce((total, o) => total + o.value, 0);
1973
+ const outputAmount = (tx.outs as Output[]).reduce((total, o) => total + o.value, 0);
1663
1974
  const fee = inputAmount - outputAmount;
1664
1975
  if (!disableOutputChecks) {
1665
1976
  if (fee < 0) {
@@ -1671,36 +1982,49 @@ function inputFinalizeGetAmts(
1671
1982
  cache.__EXTRACTED_TX = tx;
1672
1983
  cache.__FEE_RATE = Math.floor(fee / bytes);
1673
1984
  }
1674
- function nonWitnessUtxoTxFromCache(cache, input, inputIndex) {
1985
+
1986
+ function nonWitnessUtxoTxFromCache(
1987
+ cache: PsbtCache,
1988
+ input: PsbtInput,
1989
+ inputIndex: number,
1990
+ ): Transaction {
1675
1991
  const c = cache.__NON_WITNESS_UTXO_TX_CACHE;
1676
1992
  if (!c[inputIndex]) {
1677
1993
  addNonWitnessTxCache(cache, input, inputIndex);
1678
1994
  }
1679
1995
  return c[inputIndex];
1680
1996
  }
1681
- function getScriptFromUtxo(inputIndex, input, cache) {
1997
+
1998
+ function getScriptFromUtxo(inputIndex: number, input: PsbtInput, cache: PsbtCache): Buffer {
1682
1999
  const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
1683
2000
  return script;
1684
2001
  }
1685
- function getScriptAndAmountFromUtxo(inputIndex, input, cache) {
2002
+
2003
+ function getScriptAndAmountFromUtxo(
2004
+ inputIndex: number,
2005
+ input: PsbtInput,
2006
+ cache: PsbtCache,
2007
+ ): { script: Buffer; value: number } {
1686
2008
  if (input.witnessUtxo !== undefined) {
1687
2009
  return {
1688
2010
  script: input.witnessUtxo.script,
1689
2011
  value: input.witnessUtxo.value,
1690
2012
  };
1691
2013
  } else if (input.nonWitnessUtxo !== undefined) {
1692
- const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
1693
- cache,
1694
- input,
1695
- inputIndex,
1696
- );
2014
+ const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(cache, input, inputIndex);
1697
2015
  const o = nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index];
1698
2016
  return { script: o.script, value: o.value };
1699
2017
  } else {
1700
2018
  throw new Error("Can't find pubkey in input without Utxo data");
1701
2019
  }
1702
2020
  }
1703
- function pubkeyInInput(pubkey, input, inputIndex, cache) {
2021
+
2022
+ function pubkeyInInput(
2023
+ pubkey: Buffer,
2024
+ input: PsbtInput,
2025
+ inputIndex: number,
2026
+ cache: PsbtCache,
2027
+ ): boolean {
1704
2028
  const script = getScriptFromUtxo(inputIndex, input, cache);
1705
2029
  const { meaningfulScript } = getMeaningfulScript(
1706
2030
  script,
@@ -1709,9 +2033,15 @@ function pubkeyInInput(pubkey, input, inputIndex, cache) {
1709
2033
  input.redeemScript,
1710
2034
  input.witnessScript,
1711
2035
  );
1712
- return (0, psbtutils_1.pubkeyInScript)(pubkey, meaningfulScript);
2036
+ return pubkeyInScript(pubkey, meaningfulScript);
1713
2037
  }
1714
- function pubkeyInOutput(pubkey, output, outputIndex, cache) {
2038
+
2039
+ function pubkeyInOutput(
2040
+ pubkey: Buffer,
2041
+ output: PsbtOutput,
2042
+ outputIndex: number,
2043
+ cache: PsbtCache,
2044
+ ): boolean {
1715
2045
  const script = cache.__TX.outs[outputIndex].script;
1716
2046
  const { meaningfulScript } = getMeaningfulScript(
1717
2047
  script,
@@ -1720,24 +2050,21 @@ function pubkeyInOutput(pubkey, output, outputIndex, cache) {
1720
2050
  output.redeemScript,
1721
2051
  output.witnessScript,
1722
2052
  );
1723
- return (0, psbtutils_1.pubkeyInScript)(pubkey, meaningfulScript);
2053
+ return pubkeyInScript(pubkey, meaningfulScript);
1724
2054
  }
1725
- function redeemFromFinalScriptSig(finalScript) {
2055
+
2056
+ function redeemFromFinalScriptSig(finalScript: Buffer | undefined): Buffer | undefined {
1726
2057
  if (!finalScript) return;
1727
2058
  const decomp = bscript.decompile(finalScript);
1728
2059
  if (!decomp) return;
1729
2060
  const lastItem = decomp[decomp.length - 1];
1730
- if (
1731
- !Buffer.isBuffer(lastItem) ||
1732
- isPubkeyLike(lastItem) ||
1733
- isSigLike(lastItem)
1734
- )
1735
- return;
2061
+ if (!Buffer.isBuffer(lastItem) || isPubkeyLike(lastItem) || isSigLike(lastItem)) return;
1736
2062
  const sDecomp = bscript.decompile(lastItem);
1737
2063
  if (!sDecomp) return;
1738
2064
  return lastItem;
1739
2065
  }
1740
- function redeemFromFinalWitnessScript(finalScript) {
2066
+
2067
+ function redeemFromFinalWitnessScript(finalScript: Buffer | undefined): Buffer | undefined {
1741
2068
  if (!finalScript) return;
1742
2069
  const decomp = scriptWitnessToWitnessStack(finalScript);
1743
2070
  const lastItem = decomp[decomp.length - 1];
@@ -1746,7 +2073,8 @@ function redeemFromFinalWitnessScript(finalScript) {
1746
2073
  if (!sDecomp) return;
1747
2074
  return lastItem;
1748
2075
  }
1749
- function compressPubkey(pubkey) {
2076
+
2077
+ function compressPubkey(pubkey: Buffer): Buffer {
1750
2078
  if (pubkey.length === 65) {
1751
2079
  const parity = pubkey[64] & 1;
1752
2080
  const newKey = pubkey.slice(0, 33);
@@ -1755,71 +2083,92 @@ function compressPubkey(pubkey) {
1755
2083
  }
1756
2084
  return pubkey.slice();
1757
2085
  }
1758
- function isPubkeyLike(buf) {
2086
+
2087
+ function isPubkeyLike(buf: Buffer): boolean {
1759
2088
  return buf.length === 33 && bscript.isCanonicalPubKey(buf);
1760
2089
  }
1761
- function isSigLike(buf) {
2090
+
2091
+ function isSigLike(buf: Buffer): boolean {
1762
2092
  return bscript.isCanonicalScriptSignature(buf);
1763
2093
  }
2094
+
1764
2095
  function getMeaningfulScript(
1765
- script,
1766
- index,
1767
- ioType,
1768
- redeemScript,
1769
- witnessScript,
1770
- ) {
1771
- const isP2SH = (0, psbtutils_1.isP2SHScript)(script);
1772
- const isP2SHP2WSH =
1773
- isP2SH && redeemScript && (0, psbtutils_1.isP2WSHScript)(redeemScript);
1774
- const isP2WSH = (0, psbtutils_1.isP2WSHScript)(script);
2096
+ script: Buffer,
2097
+ index: number,
2098
+ ioType: 'input' | 'output',
2099
+ redeemScript?: Buffer,
2100
+ witnessScript?: Buffer,
2101
+ ): {
2102
+ meaningfulScript: Buffer;
2103
+ type: 'p2sh' | 'p2wsh' | 'p2sh-p2wsh' | 'raw';
2104
+ } {
2105
+ const isP2SH = isP2SHScript(script);
2106
+ const isP2SHP2WSH = isP2SH && redeemScript && isP2WSHScript(redeemScript);
2107
+ const isP2WSH = isP2WSHScript(script);
2108
+
1775
2109
  if (isP2SH && redeemScript === undefined)
1776
2110
  throw new Error('scriptPubkey is P2SH but redeemScript missing');
1777
2111
  if ((isP2WSH || isP2SHP2WSH) && witnessScript === undefined)
1778
- throw new Error(
1779
- 'scriptPubkey or redeemScript is P2WSH but witnessScript missing',
1780
- );
1781
- let meaningfulScript;
2112
+ throw new Error('scriptPubkey or redeemScript is P2WSH but witnessScript missing');
2113
+
2114
+ let meaningfulScript: Buffer;
2115
+
1782
2116
  if (isP2SHP2WSH) {
1783
- meaningfulScript = witnessScript;
1784
- checkRedeemScript(index, script, redeemScript, ioType);
1785
- checkWitnessScript(index, redeemScript, witnessScript, ioType);
2117
+ meaningfulScript = witnessScript!;
2118
+ checkRedeemScript(index, script, redeemScript!, ioType);
2119
+ checkWitnessScript(index, redeemScript!, witnessScript!, ioType);
1786
2120
  checkInvalidP2WSH(meaningfulScript);
1787
2121
  } else if (isP2WSH) {
1788
- meaningfulScript = witnessScript;
1789
- checkWitnessScript(index, script, witnessScript, ioType);
2122
+ meaningfulScript = witnessScript!;
2123
+ checkWitnessScript(index, script, witnessScript!, ioType);
1790
2124
  checkInvalidP2WSH(meaningfulScript);
1791
2125
  } else if (isP2SH) {
1792
- meaningfulScript = redeemScript;
1793
- checkRedeemScript(index, script, redeemScript, ioType);
2126
+ meaningfulScript = redeemScript!;
2127
+ checkRedeemScript(index, script, redeemScript!, ioType);
1794
2128
  } else {
1795
2129
  meaningfulScript = script;
1796
2130
  }
1797
2131
  return {
1798
2132
  meaningfulScript,
1799
- type: isP2SHP2WSH
1800
- ? 'p2sh-p2wsh'
1801
- : isP2SH
1802
- ? 'p2sh'
1803
- : isP2WSH
1804
- ? 'p2wsh'
1805
- : 'raw',
2133
+ type: isP2SHP2WSH ? 'p2sh-p2wsh' : isP2SH ? 'p2sh' : isP2WSH ? 'p2wsh' : 'raw',
1806
2134
  };
1807
2135
  }
1808
- function checkInvalidP2WSH(script) {
1809
- if (
1810
- (0, psbtutils_1.isP2WPKH)(script) ||
1811
- (0, psbtutils_1.isP2SHScript)(script)
1812
- ) {
2136
+
2137
+ function checkInvalidP2WSH(script: Buffer): void {
2138
+ if (isP2WPKH(script) || isP2SHScript(script)) {
1813
2139
  throw new Error('P2WPKH or P2SH can not be contained within P2WSH');
1814
2140
  }
1815
2141
  }
1816
- function classifyScript(script) {
1817
- if ((0, psbtutils_1.isP2WPKH)(script)) return 'witnesspubkeyhash';
1818
- if ((0, psbtutils_1.isP2PKH)(script)) return 'pubkeyhash';
1819
- if ((0, psbtutils_1.isP2MS)(script)) return 'multisig';
1820
- if ((0, psbtutils_1.isP2PK)(script)) return 'pubkey';
2142
+
2143
+ type AllScriptType =
2144
+ | 'witnesspubkeyhash'
2145
+ | 'pubkeyhash'
2146
+ | 'multisig'
2147
+ | 'pubkey'
2148
+ | 'nonstandard'
2149
+ | 'p2sh-witnesspubkeyhash'
2150
+ | 'p2sh-pubkeyhash'
2151
+ | 'p2sh-multisig'
2152
+ | 'p2sh-pubkey'
2153
+ | 'p2sh-nonstandard'
2154
+ | 'p2wsh-pubkeyhash'
2155
+ | 'p2wsh-multisig'
2156
+ | 'p2wsh-pubkey'
2157
+ | 'p2wsh-nonstandard'
2158
+ | 'p2sh-p2wsh-pubkeyhash'
2159
+ | 'p2sh-p2wsh-multisig'
2160
+ | 'p2sh-p2wsh-pubkey'
2161
+ | 'p2sh-p2wsh-nonstandard';
2162
+ type ScriptType = 'witnesspubkeyhash' | 'pubkeyhash' | 'multisig' | 'pubkey' | 'nonstandard';
2163
+
2164
+ function classifyScript(script: Buffer): ScriptType {
2165
+ if (isP2WPKH(script)) return 'witnesspubkeyhash';
2166
+ if (isP2PKH(script)) return 'pubkeyhash';
2167
+ if (isP2MS(script)) return 'multisig';
2168
+ if (isP2PK(script)) return 'pubkey';
1821
2169
  return 'nonstandard';
1822
2170
  }
1823
- function range(n) {
2171
+
2172
+ function range(n: number): number[] {
1824
2173
  return [...Array(n).keys()];
1825
2174
  }