@btc-vision/bitcoin 7.0.0-beta.0 → 7.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +112 -13
  2. package/benchmark-compare/BENCHMARK.md +74 -59
  3. package/benchmark-compare/compare.bench.ts +249 -96
  4. package/benchmark-compare/harness.ts +23 -25
  5. package/benchmark-compare/package.json +1 -0
  6. package/browser/address.d.ts +4 -4
  7. package/browser/address.d.ts.map +1 -1
  8. package/browser/chunks/{psbt-parallel-B-dfm5GZ.js → psbt-parallel-jZ6QcCnM.js} +3128 -2731
  9. package/browser/index.d.ts +1 -1
  10. package/browser/index.d.ts.map +1 -1
  11. package/browser/index.js +603 -585
  12. package/browser/io/base58check.d.ts +1 -25
  13. package/browser/io/base58check.d.ts.map +1 -1
  14. package/browser/io/base64.d.ts.map +1 -1
  15. package/browser/networks.d.ts +1 -0
  16. package/browser/networks.d.ts.map +1 -1
  17. package/browser/payments/bip341.d.ts +17 -0
  18. package/browser/payments/bip341.d.ts.map +1 -1
  19. package/browser/payments/index.d.ts +3 -2
  20. package/browser/payments/index.d.ts.map +1 -1
  21. package/browser/payments/p2mr.d.ts +169 -0
  22. package/browser/payments/p2mr.d.ts.map +1 -0
  23. package/browser/payments/types.d.ts +11 -1
  24. package/browser/payments/types.d.ts.map +1 -1
  25. package/browser/psbt/bip371.d.ts +30 -0
  26. package/browser/psbt/bip371.d.ts.map +1 -1
  27. package/browser/psbt/psbtutils.d.ts +1 -0
  28. package/browser/psbt/psbtutils.d.ts.map +1 -1
  29. package/browser/psbt.d.ts.map +1 -1
  30. package/browser/workers/index.js +9 -9
  31. package/build/address.d.ts +4 -4
  32. package/build/address.d.ts.map +1 -1
  33. package/build/address.js +11 -1
  34. package/build/address.js.map +1 -1
  35. package/build/index.d.ts +1 -1
  36. package/build/index.d.ts.map +1 -1
  37. package/build/index.js.map +1 -1
  38. package/build/io/base58check.d.ts +1 -25
  39. package/build/io/base58check.d.ts.map +1 -1
  40. package/build/io/base58check.js +1 -31
  41. package/build/io/base58check.js.map +1 -1
  42. package/build/io/base64.d.ts.map +1 -1
  43. package/build/io/base64.js +3 -0
  44. package/build/io/base64.js.map +1 -1
  45. package/build/networks.d.ts +1 -0
  46. package/build/networks.d.ts.map +1 -1
  47. package/build/networks.js +12 -0
  48. package/build/networks.js.map +1 -1
  49. package/build/payments/bip341.d.ts +17 -0
  50. package/build/payments/bip341.d.ts.map +1 -1
  51. package/build/payments/bip341.js +32 -1
  52. package/build/payments/bip341.js.map +1 -1
  53. package/build/payments/index.d.ts +3 -2
  54. package/build/payments/index.d.ts.map +1 -1
  55. package/build/payments/index.js +2 -1
  56. package/build/payments/index.js.map +1 -1
  57. package/build/payments/p2mr.d.ts +178 -0
  58. package/build/payments/p2mr.d.ts.map +1 -0
  59. package/build/payments/p2mr.js +555 -0
  60. package/build/payments/p2mr.js.map +1 -0
  61. package/build/payments/types.d.ts +11 -1
  62. package/build/payments/types.d.ts.map +1 -1
  63. package/build/payments/types.js +1 -0
  64. package/build/payments/types.js.map +1 -1
  65. package/build/psbt/bip371.d.ts +30 -0
  66. package/build/psbt/bip371.d.ts.map +1 -1
  67. package/build/psbt/bip371.js +80 -15
  68. package/build/psbt/bip371.js.map +1 -1
  69. package/build/psbt/psbtutils.d.ts +1 -0
  70. package/build/psbt/psbtutils.d.ts.map +1 -1
  71. package/build/psbt/psbtutils.js +2 -0
  72. package/build/psbt/psbtutils.js.map +1 -1
  73. package/build/psbt.d.ts.map +1 -1
  74. package/build/psbt.js +3 -2
  75. package/build/psbt.js.map +1 -1
  76. package/build/pubkey.js +1 -1
  77. package/build/pubkey.js.map +1 -1
  78. package/build/tsconfig.build.tsbuildinfo +1 -1
  79. package/documentation/README.md +122 -0
  80. package/documentation/address.md +820 -0
  81. package/documentation/block.md +679 -0
  82. package/documentation/crypto.md +461 -0
  83. package/documentation/ecc.md +584 -0
  84. package/documentation/errors.md +656 -0
  85. package/documentation/io.md +942 -0
  86. package/documentation/networks.md +625 -0
  87. package/documentation/p2mr.md +380 -0
  88. package/documentation/payments.md +1485 -0
  89. package/documentation/psbt.md +1400 -0
  90. package/documentation/script.md +730 -0
  91. package/documentation/taproot.md +670 -0
  92. package/documentation/transaction.md +943 -0
  93. package/documentation/types.md +587 -0
  94. package/documentation/workers.md +1007 -0
  95. package/eslint.config.js +3 -0
  96. package/package.json +17 -14
  97. package/src/address.ts +22 -10
  98. package/src/index.ts +1 -0
  99. package/src/io/base58check.ts +1 -35
  100. package/src/io/base64.ts +5 -0
  101. package/src/networks.ts +13 -0
  102. package/src/payments/bip341.ts +36 -1
  103. package/src/payments/index.ts +4 -0
  104. package/src/payments/p2mr.ts +660 -0
  105. package/src/payments/types.ts +12 -0
  106. package/src/psbt/bip371.ts +84 -13
  107. package/src/psbt/psbtutils.ts +2 -0
  108. package/src/psbt.ts +4 -2
  109. package/src/pubkey.ts +1 -1
  110. package/test/bitcoin.core.spec.ts +1 -1
  111. package/test/fixtures/p2mr.json +270 -0
  112. package/test/integration/taproot.spec.ts +7 -3
  113. package/test/opnetTestnet.spec.ts +302 -0
  114. package/test/payments.spec.ts +3 -1
  115. package/test/psbt.spec.ts +297 -2
  116. package/test/tsconfig.json +2 -2
@@ -0,0 +1,943 @@
1
+ # Transaction
2
+
3
+ The `Transaction` class represents a Bitcoin transaction. It handles parsing, serialization, cloning, and producing the various sighash digests needed for legacy, SegWit v0, and Taproot (SegWit v1) signing.
4
+
5
+ ## Overview
6
+
7
+ | Property | Description |
8
+ |----------|-------------|
9
+ | Module | `@btc-vision/bitcoin` |
10
+ | Export | `Transaction` |
11
+ | Witness support | Yes (BIP 141 serialization) |
12
+ | Signing support | Legacy (`hashForSignature`), SegWit v0 (`hashForWitnessV0`), Taproot (`hashForWitnessV1`) |
13
+ | TRUC support | Version 3 transactions (Topologically Restricted Until Confirmation) |
14
+
15
+ ---
16
+
17
+ ## Static Constants
18
+
19
+ ### Sighash Types
20
+
21
+ | Constant | Value | Description |
22
+ |----------|-------|-------------|
23
+ | `SIGHASH_DEFAULT` | `0x00` | Taproot-only default, semantically equivalent to `SIGHASH_ALL` |
24
+ | `SIGHASH_ALL` | `0x01` | Sign all inputs and outputs |
25
+ | `SIGHASH_NONE` | `0x02` | Sign all inputs, no outputs (wildcard payee) |
26
+ | `SIGHASH_SINGLE` | `0x03` | Sign all inputs, only the output at the same index |
27
+ | `SIGHASH_ANYONECANPAY` | `0x80` | Combined with the above via bitwise OR; sign only the current input |
28
+ | `SIGHASH_OUTPUT_MASK` | `0x03` | Bitmask to extract the output sighash type |
29
+ | `SIGHASH_INPUT_MASK` | `0x80` | Bitmask to extract the input sighash type |
30
+
31
+ ### Sequence and Serialization
32
+
33
+ | Constant | Value | Description |
34
+ |----------|-------|-------------|
35
+ | `DEFAULT_SEQUENCE` | `0xffffffff` | Default sequence number (no RBF, no relative timelock) |
36
+ | `ADVANCED_TRANSACTION_MARKER` | `0x00` | SegWit marker byte in serialized transactions |
37
+ | `ADVANCED_TRANSACTION_FLAG` | `0x01` | SegWit flag byte in serialized transactions |
38
+
39
+ ### TRUC (Topologically Restricted Until Confirmation)
40
+
41
+ | Constant | Value | Description |
42
+ |----------|-------|-------------|
43
+ | `TRUC_VERSION` | `3` | Transaction version for TRUC transactions |
44
+ | `TRUC_MAX_VSIZE` | `10000` | Maximum virtual size in vbytes for a TRUC parent transaction |
45
+ | `TRUC_CHILD_MAX_VSIZE` | `1000` | Maximum virtual size in vbytes for a TRUC child transaction |
46
+
47
+ ---
48
+
49
+ ## Interfaces
50
+
51
+ ### Input
52
+
53
+ Represents a transaction input (a reference to a previous output being spent).
54
+
55
+ ```typescript
56
+ interface Input {
57
+ readonly hash: Bytes32; // 32-byte hash of the previous transaction
58
+ readonly index: number; // Output index in the previous transaction
59
+ script: Script; // Input script (scriptSig)
60
+ sequence: number; // Sequence number
61
+ witness: Uint8Array[]; // Witness data stack
62
+ }
63
+ ```
64
+
65
+ ### Output
66
+
67
+ Represents a transaction output (a locking script with an associated value).
68
+
69
+ ```typescript
70
+ interface Output {
71
+ readonly script: Script; // Output script (scriptPubKey / locking script)
72
+ readonly value: Satoshi; // Value in satoshis (bigint)
73
+ }
74
+ ```
75
+
76
+ ### TaprootHashCache
77
+
78
+ Cache for Taproot sighash intermediate values. These are identical for all inputs when using `SIGHASH_ALL`, so they can be computed once and reused across inputs.
79
+
80
+ ```typescript
81
+ interface TaprootHashCache {
82
+ readonly hashPrevouts: Bytes32;
83
+ readonly hashAmounts: Bytes32;
84
+ readonly hashScriptPubKeys: Bytes32;
85
+ readonly hashSequences: Bytes32;
86
+ readonly hashOutputs: Bytes32;
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Instance Properties
93
+
94
+ | Property | Type | Default | Description |
95
+ |----------|------|---------|-------------|
96
+ | `version` | `number` | `1` | Transaction version |
97
+ | `locktime` | `number` | `0` | Transaction locktime |
98
+ | `ins` | `Input[]` | `[]` | Array of transaction inputs |
99
+ | `outs` | `Output[]` | `[]` | Array of transaction outputs |
100
+
101
+ ---
102
+
103
+ ## Static Methods
104
+
105
+ ### fromBuffer
106
+
107
+ Parse a transaction from a raw `Uint8Array` buffer.
108
+
109
+ ```typescript
110
+ static fromBuffer(buffer: Uint8Array, _NO_STRICT?: boolean): Transaction
111
+ ```
112
+
113
+ | Parameter | Type | Required | Description |
114
+ |-----------|------|----------|-------------|
115
+ | `buffer` | `Uint8Array` | Yes | The raw transaction bytes |
116
+ | `_NO_STRICT` | `boolean` | No | If `true`, allow extra trailing data after the transaction |
117
+
118
+ Returns a fully parsed `Transaction` instance. Automatically detects SegWit transactions by checking for the marker and flag bytes. Throws if the buffer contains superfluous witness data or unexpected trailing bytes (unless `_NO_STRICT` is set).
119
+
120
+ ```typescript
121
+ import { Transaction, fromHex } from '@btc-vision/bitcoin';
122
+
123
+ const rawTx = fromHex('0200000001abcdef...');
124
+ const tx = Transaction.fromBuffer(rawTx);
125
+ console.log(tx.version); // 2
126
+ console.log(tx.ins.length);
127
+ console.log(tx.outs.length);
128
+ ```
129
+
130
+ ---
131
+
132
+ ### fromHex
133
+
134
+ Parse a transaction from a hex string. A convenience wrapper around `fromBuffer`.
135
+
136
+ ```typescript
137
+ static fromHex(hex: string): Transaction
138
+ ```
139
+
140
+ | Parameter | Type | Required | Description |
141
+ |-----------|------|----------|-------------|
142
+ | `hex` | `string` | Yes | The transaction as a hex-encoded string |
143
+
144
+ Returns a fully parsed `Transaction` instance.
145
+
146
+ ```typescript
147
+ import { Transaction } from '@btc-vision/bitcoin';
148
+
149
+ const tx = Transaction.fromHex('0200000001abcdef...');
150
+ console.log(tx.getId());
151
+ ```
152
+
153
+ ---
154
+
155
+ ### isCoinbaseHash
156
+
157
+ Check if a 32-byte hash is a coinbase hash (all zeros).
158
+
159
+ ```typescript
160
+ static isCoinbaseHash(hash: Bytes32): boolean
161
+ ```
162
+
163
+ | Parameter | Type | Required | Description |
164
+ |-----------|------|----------|-------------|
165
+ | `hash` | `Bytes32` | Yes | 32-byte hash to check |
166
+
167
+ Returns `true` if every byte is `0x00`. Throws `TypeError` if the hash is not exactly 32 bytes.
168
+
169
+ ---
170
+
171
+ ## Instance Methods
172
+
173
+ ### addInput
174
+
175
+ Add an input to the transaction.
176
+
177
+ ```typescript
178
+ addInput(hash: Bytes32, index: number, sequence?: number, scriptSig?: Script): number
179
+ ```
180
+
181
+ | Parameter | Type | Required | Description |
182
+ |-----------|------|----------|-------------|
183
+ | `hash` | `Bytes32` | Yes | 32-byte hash of the previous transaction |
184
+ | `index` | `number` | Yes | Output index in the previous transaction (uint32) |
185
+ | `sequence` | `number` | No | Sequence number (defaults to `0xffffffff`) |
186
+ | `scriptSig` | `Script` | No | Input script (defaults to empty) |
187
+
188
+ Returns the index of the newly added input. The witness field is initialized to an empty array.
189
+
190
+ ```typescript
191
+ import { Transaction, fromHex } from '@btc-vision/bitcoin';
192
+ import type { Bytes32, Script } from '@btc-vision/bitcoin';
193
+
194
+ const tx = new Transaction();
195
+
196
+ // Previous transaction hash (in internal byte order)
197
+ const prevTxHash = fromHex(
198
+ 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2'
199
+ ) as Bytes32;
200
+
201
+ const inputIndex = tx.addInput(prevTxHash, 0);
202
+ console.log(inputIndex); // 0
203
+
204
+ // With custom sequence (e.g. for RBF)
205
+ tx.addInput(prevTxHash, 1, 0xfffffffd);
206
+ ```
207
+
208
+ ---
209
+
210
+ ### addOutput
211
+
212
+ Add an output to the transaction.
213
+
214
+ ```typescript
215
+ addOutput(scriptPubKey: Script, value: Satoshi): number
216
+ ```
217
+
218
+ | Parameter | Type | Required | Description |
219
+ |-----------|------|----------|-------------|
220
+ | `scriptPubKey` | `Script` | Yes | Output script (locking script) |
221
+ | `value` | `Satoshi` | Yes | Output value in satoshis (`bigint`, range `0` to `2^63 - 1`) |
222
+
223
+ Returns the index of the newly added output.
224
+
225
+ ```typescript
226
+ import { Transaction, address } from '@btc-vision/bitcoin';
227
+ import type { Satoshi } from '@btc-vision/bitcoin';
228
+
229
+ const tx = new Transaction();
230
+ const scriptPubKey = address.toOutputScript('bc1qexampleaddress...');
231
+ const outputIndex = tx.addOutput(scriptPubKey, 50000n as Satoshi);
232
+ console.log(outputIndex); // 0
233
+ ```
234
+
235
+ ---
236
+
237
+ ### clone
238
+
239
+ Create a deep copy of the transaction. All inputs and outputs are duplicated.
240
+
241
+ ```typescript
242
+ clone(): Transaction
243
+ ```
244
+
245
+ Returns a new `Transaction` instance with identical version, locktime, inputs, and outputs.
246
+
247
+ ```typescript
248
+ const original = Transaction.fromHex('0200000001...');
249
+ const copy = original.clone();
250
+
251
+ // Modifying the copy does not affect the original
252
+ copy.locktime = 800000;
253
+ console.log(original.locktime); // unchanged
254
+ ```
255
+
256
+ ---
257
+
258
+ ### toBuffer
259
+
260
+ Serialize the transaction to a `Uint8Array` buffer. Includes witness data if present.
261
+
262
+ ```typescript
263
+ toBuffer(buffer?: Uint8Array, initialOffset?: number): Uint8Array
264
+ ```
265
+
266
+ | Parameter | Type | Required | Description |
267
+ |-----------|------|----------|-------------|
268
+ | `buffer` | `Uint8Array` | No | Pre-allocated buffer (auto-allocated if omitted) |
269
+ | `initialOffset` | `number` | No | Starting offset within the buffer |
270
+
271
+ Returns the serialized transaction bytes. If witness data is present, the output uses the BIP 141 serialization format with marker and flag bytes.
272
+
273
+ ```typescript
274
+ const tx = new Transaction();
275
+ // ... add inputs and outputs ...
276
+ const raw = tx.toBuffer();
277
+ console.log(raw.length); // byte length of the serialized transaction
278
+ ```
279
+
280
+ ---
281
+
282
+ ### toHex
283
+
284
+ Serialize the transaction to a hex string. A convenience wrapper around `toBuffer`.
285
+
286
+ ```typescript
287
+ toHex(): string
288
+ ```
289
+
290
+ Returns the full transaction as a hex-encoded string.
291
+
292
+ ```typescript
293
+ const tx = new Transaction();
294
+ // ... add inputs and outputs ...
295
+ const hex = tx.toHex();
296
+ console.log(hex); // "0200000001..."
297
+ ```
298
+
299
+ ---
300
+
301
+ ### getHash
302
+
303
+ Compute the transaction hash (double SHA-256 of the serialized data).
304
+
305
+ ```typescript
306
+ getHash(forWitness?: boolean): Bytes32
307
+ ```
308
+
309
+ | Parameter | Type | Required | Description |
310
+ |-----------|------|----------|-------------|
311
+ | `forWitness` | `boolean` | No | If `true`, include witness data to produce the wtxid |
312
+
313
+ Returns a 32-byte hash. When `forWitness` is `false` or omitted, witness data is excluded from the hash (producing the txid). When `forWitness` is `true`, witness data is included (producing the wtxid). For coinbase transactions with `forWitness = true`, always returns 32 zero bytes.
314
+
315
+ ---
316
+
317
+ ### getId
318
+
319
+ Get the transaction ID (txid) as a hex string in the conventional display order (reversed).
320
+
321
+ ```typescript
322
+ getId(): string
323
+ ```
324
+
325
+ Returns the txid as a 64-character hex string. Bitcoin transaction IDs are displayed in reversed byte order relative to the internal hash.
326
+
327
+ ```typescript
328
+ const tx = Transaction.fromHex('0200000001...');
329
+ console.log(tx.getId()); // "d4e5f6a1b2c3..."
330
+ ```
331
+
332
+ ---
333
+
334
+ ### weight
335
+
336
+ Calculate the transaction weight as defined by BIP 141.
337
+
338
+ ```typescript
339
+ weight(): number
340
+ ```
341
+
342
+ Returns the weight in weight units. The formula is `base_size * 3 + total_size`, where `base_size` is the serialized size without witness data and `total_size` includes witness data.
343
+
344
+ ---
345
+
346
+ ### virtualSize
347
+
348
+ Calculate the virtual size (vsize) of the transaction in virtual bytes.
349
+
350
+ ```typescript
351
+ virtualSize(): number
352
+ ```
353
+
354
+ Returns `Math.ceil(weight() / 4)`. This is the value used for fee rate calculations.
355
+
356
+ ```typescript
357
+ const tx = Transaction.fromHex('0200000001...');
358
+ console.log(tx.virtualSize()); // e.g. 141
359
+ ```
360
+
361
+ ---
362
+
363
+ ### byteLength
364
+
365
+ Calculate the serialized byte length of the transaction.
366
+
367
+ ```typescript
368
+ byteLength(_ALLOW_WITNESS?: boolean): number
369
+ ```
370
+
371
+ | Parameter | Type | Required | Description |
372
+ |-----------|------|----------|-------------|
373
+ | `_ALLOW_WITNESS` | `boolean` | No | If `true` (default), include witness data in the calculation |
374
+
375
+ Returns the byte count. When `_ALLOW_WITNESS` is `true` and the transaction has witness data, the count includes the marker, flag, and all witness stacks.
376
+
377
+ ---
378
+
379
+ ### isCoinbase
380
+
381
+ Check if this transaction is a coinbase transaction.
382
+
383
+ ```typescript
384
+ isCoinbase(): boolean
385
+ ```
386
+
387
+ Returns `true` if the transaction has exactly one input and that input's hash is all zeros (the defining characteristic of a coinbase transaction).
388
+
389
+ ```typescript
390
+ const tx = Transaction.fromHex('0100000001000000000000000000000000...');
391
+ console.log(tx.isCoinbase()); // true
392
+ ```
393
+
394
+ ---
395
+
396
+ ### hasWitnesses
397
+
398
+ Check if any input in the transaction has witness data.
399
+
400
+ ```typescript
401
+ hasWitnesses(): boolean
402
+ ```
403
+
404
+ Returns `true` if at least one input has a non-empty witness stack.
405
+
406
+ ---
407
+
408
+ ### setInputScript
409
+
410
+ Set the scriptSig for a specific input.
411
+
412
+ ```typescript
413
+ setInputScript(index: number, scriptSig: Script): void
414
+ ```
415
+
416
+ | Parameter | Type | Required | Description |
417
+ |-----------|------|----------|-------------|
418
+ | `index` | `number` | Yes | Input index |
419
+ | `scriptSig` | `Script` | Yes | The script to set |
420
+
421
+ ---
422
+
423
+ ### setWitness
424
+
425
+ Set the witness data for a specific input.
426
+
427
+ ```typescript
428
+ setWitness(index: number, witness: Uint8Array[]): void
429
+ ```
430
+
431
+ | Parameter | Type | Required | Description |
432
+ |-----------|------|----------|-------------|
433
+ | `index` | `number` | Yes | Input index |
434
+ | `witness` | `Uint8Array[]` | Yes | Array of witness stack elements |
435
+
436
+ ---
437
+
438
+ ## Signing Methods
439
+
440
+ ### hashForSignature
441
+
442
+ Produce the sighash digest for signing a legacy (pre-SegWit) input. This method clones the transaction, modifies it according to the sighash type, serializes it with the hash type appended, and returns the double SHA-256 hash.
443
+
444
+ ```typescript
445
+ hashForSignature(inIndex: number, prevOutScript: Script, hashType: number): MessageHash
446
+ ```
447
+
448
+ | Parameter | Type | Required | Description |
449
+ |-----------|------|----------|-------------|
450
+ | `inIndex` | `number` | Yes | Index of the input being signed |
451
+ | `prevOutScript` | `Script` | Yes | The scriptPubKey of the output being spent |
452
+ | `hashType` | `number` | Yes | Sighash type (combination of `SIGHASH_*` constants) |
453
+
454
+ Returns a 32-byte `MessageHash`. In two specific cases, the method returns the constant `ONE` (32-byte value `0x0000...0001`) instead of computing a normal sighash:
455
+
456
+ 1. **`inIndex >= ins.length`**: The input index is out of range (any sighash type).
457
+ 2. **`SIGHASH_SINGLE` with `inIndex >= outs.length`**: The output at the matching index does not exist.
458
+
459
+ Both cases are well-known Bitcoin consensus quirks — the method returns the literal 32-byte value `0x0000000000000000000000000000000000000000000000000000000000000001`, **not** a hash of `0x01`.
460
+
461
+ The method automatically strips `OP_CODESEPARATOR` from the previous output script.
462
+
463
+ ```typescript
464
+ import { Transaction } from '@btc-vision/bitcoin';
465
+
466
+ const tx = Transaction.fromHex('0200000001...');
467
+ const sighash = tx.hashForSignature(
468
+ 0, // input index
469
+ prevOutScript, // scriptPubKey of the UTXO
470
+ Transaction.SIGHASH_ALL, // sighash type
471
+ );
472
+ // Sign `sighash` with your private key
473
+ ```
474
+
475
+ ---
476
+
477
+ ### hashForWitnessV0
478
+
479
+ Produce the sighash digest for signing a SegWit v0 input (P2WPKH or P2WSH), as defined by BIP 143.
480
+
481
+ ```typescript
482
+ hashForWitnessV0(
483
+ inIndex: number,
484
+ prevOutScript: Script,
485
+ value: Satoshi,
486
+ hashType: number,
487
+ ): MessageHash
488
+ ```
489
+
490
+ | Parameter | Type | Required | Description |
491
+ |-----------|------|----------|-------------|
492
+ | `inIndex` | `number` | Yes | Index of the input being signed |
493
+ | `prevOutScript` | `Script` | Yes | The scriptCode of the output being spent |
494
+ | `value` | `Satoshi` | Yes | Value of the output being spent (bigint satoshis) |
495
+ | `hashType` | `number` | Yes | Sighash type (combination of `SIGHASH_*` constants) |
496
+
497
+ Returns a 32-byte `MessageHash`. Unlike legacy signing, the BIP 143 algorithm commits to the value of the input being spent, which prevents certain fee-related attacks.
498
+
499
+ ```typescript
500
+ import { Transaction } from '@btc-vision/bitcoin';
501
+ import type { Satoshi, Script } from '@btc-vision/bitcoin';
502
+
503
+ const tx = new Transaction();
504
+ tx.version = 2;
505
+ // ... add inputs and outputs ...
506
+
507
+ const sighash = tx.hashForWitnessV0(
508
+ 0, // input index
509
+ prevOutScript as Script, // scriptCode of the UTXO
510
+ 100000n as Satoshi, // value of the UTXO in satoshis
511
+ Transaction.SIGHASH_ALL, // sighash type
512
+ );
513
+ // Sign `sighash` with your private key
514
+ ```
515
+
516
+ ---
517
+
518
+ ### hashForWitnessV1
519
+
520
+ Produce the sighash digest for signing a Taproot (SegWit v1) input, as defined by BIP 341 and BIP 342.
521
+
522
+ ```typescript
523
+ hashForWitnessV1(
524
+ inIndex: number,
525
+ prevOutScripts: readonly Script[],
526
+ values: readonly Satoshi[],
527
+ hashType: number,
528
+ leafHash?: Bytes32,
529
+ annex?: Uint8Array,
530
+ taprootCache?: TaprootHashCache,
531
+ ): MessageHash
532
+ ```
533
+
534
+ | Parameter | Type | Required | Description |
535
+ |-----------|------|----------|-------------|
536
+ | `inIndex` | `number` | Yes | Index of the input being signed |
537
+ | `prevOutScripts` | `readonly Script[]` | Yes | Scripts of ALL inputs being spent |
538
+ | `values` | `readonly Satoshi[]` | Yes | Values of ALL inputs being spent |
539
+ | `hashType` | `number` | Yes | Sighash type (`SIGHASH_DEFAULT`, or combination of `SIGHASH_*` constants) |
540
+ | `leafHash` | `Bytes32` | No | Leaf hash for script-path spending (BIP 342) |
541
+ | `annex` | `Uint8Array` | No | Optional annex data |
542
+ | `taprootCache` | `TaprootHashCache` | No | Pre-computed intermediate hashes (from `getTaprootHashCache`) |
543
+
544
+ Returns a 32-byte `MessageHash`. The Taproot sighash algorithm commits to the scripts and values of ALL inputs (not just the one being signed), providing stronger security guarantees. The hash is produced using the `TapSighash` tagged hash.
545
+
546
+ For key-path spending, omit `leafHash`. For script-path spending (BIP 342), pass the `leafHash` of the tapleaf being executed.
547
+
548
+ ```typescript
549
+ import { Transaction } from '@btc-vision/bitcoin';
550
+ import type { Satoshi, Script } from '@btc-vision/bitcoin';
551
+
552
+ const tx = new Transaction();
553
+ tx.version = 2;
554
+ // ... add inputs and outputs ...
555
+
556
+ const prevOutScripts: Script[] = [scriptPubKey0, scriptPubKey1];
557
+ const values: Satoshi[] = [50000n as Satoshi, 75000n as Satoshi];
558
+
559
+ // Key-path spending
560
+ const sighash = tx.hashForWitnessV1(
561
+ 0, // input index
562
+ prevOutScripts, // scripts of ALL inputs
563
+ values, // values of ALL inputs
564
+ Transaction.SIGHASH_DEFAULT, // sighash type
565
+ );
566
+
567
+ // Script-path spending (with leaf hash)
568
+ const scriptPathHash = tx.hashForWitnessV1(
569
+ 0,
570
+ prevOutScripts,
571
+ values,
572
+ Transaction.SIGHASH_DEFAULT,
573
+ leafHash, // 32-byte tapleaf hash
574
+ );
575
+ ```
576
+
577
+ ---
578
+
579
+ ### getTaprootHashCache
580
+
581
+ Pre-compute the intermediate hash values used during Taproot signing. When signing multiple inputs in the same transaction, calling this once and passing the result to each `hashForWitnessV1` call avoids redundant O(n) hashing per input, reducing overall complexity from O(n^2) to O(n).
582
+
583
+ ```typescript
584
+ getTaprootHashCache(
585
+ prevOutScripts: readonly Script[],
586
+ values: readonly Satoshi[],
587
+ ): TaprootHashCache
588
+ ```
589
+
590
+ | Parameter | Type | Required | Description |
591
+ |-----------|------|----------|-------------|
592
+ | `prevOutScripts` | `readonly Script[]` | Yes | Array of previous output scripts for all inputs |
593
+ | `values` | `readonly Satoshi[]` | Yes | Array of previous output values for all inputs |
594
+
595
+ Returns a `TaprootHashCache` object containing five 32-byte intermediate hashes.
596
+
597
+ ```typescript
598
+ import { Transaction } from '@btc-vision/bitcoin';
599
+ import type { Satoshi, Script } from '@btc-vision/bitcoin';
600
+
601
+ const tx = new Transaction();
602
+ tx.version = 2;
603
+ // ... add multiple inputs and outputs ...
604
+
605
+ const prevOutScripts: Script[] = [script0, script1, script2];
606
+ const values: Satoshi[] = [10000n as Satoshi, 20000n as Satoshi, 30000n as Satoshi];
607
+
608
+ // Compute cache once
609
+ const cache = tx.getTaprootHashCache(prevOutScripts, values);
610
+
611
+ // Sign each input using the cache
612
+ for (let i = 0; i < tx.ins.length; i++) {
613
+ const sighash = tx.hashForWitnessV1(
614
+ i,
615
+ prevOutScripts,
616
+ values,
617
+ Transaction.SIGHASH_DEFAULT,
618
+ undefined, // no leafHash (key-path spend)
619
+ undefined, // no annex
620
+ cache, // reuse pre-computed hashes
621
+ );
622
+ // Sign sighash with the private key for input i
623
+ }
624
+ ```
625
+
626
+ ---
627
+
628
+ ## Sighash Types Explained
629
+
630
+ The sighash type controls which parts of the transaction are covered by the signature. It is a single byte composed of an output mode (lower bits) and an optional input modifier (upper bit).
631
+
632
+ ### Output Modes
633
+
634
+ | Type | Value | Inputs Signed | Outputs Signed |
635
+ |------|-------|---------------|----------------|
636
+ | `SIGHASH_ALL` | `0x01` | All | All |
637
+ | `SIGHASH_NONE` | `0x02` | All | None |
638
+ | `SIGHASH_SINGLE` | `0x03` | All | Only the output at the same index as the signed input |
639
+
640
+ ### Input Modifier
641
+
642
+ | Modifier | Value | Effect |
643
+ |----------|-------|--------|
644
+ | `SIGHASH_ANYONECANPAY` | `0x80` | Only sign the current input (others may be added/removed) |
645
+
646
+ ### Taproot-Specific
647
+
648
+ | Type | Value | Description |
649
+ |------|-------|-------------|
650
+ | `SIGHASH_DEFAULT` | `0x00` | Taproot only. Semantically identical to `SIGHASH_ALL` but produces a different byte in the signature serialization. A 64-byte Schnorr signature (without appended sighash byte) implicitly means `SIGHASH_DEFAULT`. |
651
+
652
+ ### Combining Modifiers
653
+
654
+ Combine an output mode with the input modifier using bitwise OR:
655
+
656
+ ```typescript
657
+ // Sign only this input, and only the matching output
658
+ const hashType = Transaction.SIGHASH_SINGLE | Transaction.SIGHASH_ANYONECANPAY;
659
+ // hashType === 0x83
660
+ ```
661
+
662
+ ### All Valid Combinations
663
+
664
+ | Combination | Value | Description |
665
+ |-------------|-------|-------------|
666
+ | `SIGHASH_ALL` | `0x01` | All inputs, all outputs |
667
+ | `SIGHASH_NONE` | `0x02` | All inputs, no outputs |
668
+ | `SIGHASH_SINGLE` | `0x03` | All inputs, matching output |
669
+ | `SIGHASH_ALL \| SIGHASH_ANYONECANPAY` | `0x81` | This input only, all outputs |
670
+ | `SIGHASH_NONE \| SIGHASH_ANYONECANPAY` | `0x82` | This input only, no outputs |
671
+ | `SIGHASH_SINGLE \| SIGHASH_ANYONECANPAY` | `0x83` | This input only, matching output |
672
+
673
+ ---
674
+
675
+ ## Complete Examples
676
+
677
+ ### Creating a Transaction from Scratch
678
+
679
+ ```typescript
680
+ import { Transaction, address, fromHex } from '@btc-vision/bitcoin';
681
+ import type { Bytes32, Satoshi, Script } from '@btc-vision/bitcoin';
682
+
683
+ // Create a new transaction
684
+ const tx = new Transaction();
685
+ tx.version = 2;
686
+
687
+ // Add an input referencing a previous transaction output
688
+ const prevTxHash = fromHex(
689
+ 'a1b2c3d4e5f6071829304a5b6c7d8e9f0011223344556677a1b2c3d4e5f60718'
690
+ ) as Bytes32;
691
+ tx.addInput(prevTxHash, 0);
692
+
693
+ // Optionally set a custom sequence for RBF (replace-by-fee)
694
+ tx.addInput(prevTxHash, 1, 0xfffffffd);
695
+
696
+ // Add outputs
697
+ const outputScript = address.toOutputScript('bc1qexampleaddress...');
698
+ tx.addOutput(outputScript, 49000n as Satoshi);
699
+
700
+ // Set locktime (optional)
701
+ tx.locktime = 800000;
702
+
703
+ console.log(tx.ins.length); // 2
704
+ console.log(tx.outs.length); // 1
705
+ ```
706
+
707
+ ### Serializing and Deserializing
708
+
709
+ ```typescript
710
+ import { Transaction } from '@btc-vision/bitcoin';
711
+
712
+ // Serialize to hex
713
+ const tx = new Transaction();
714
+ tx.version = 2;
715
+ // ... add inputs and outputs ...
716
+ const hex = tx.toHex();
717
+
718
+ // Deserialize from hex
719
+ const parsed = Transaction.fromHex(hex);
720
+ console.log(parsed.version); // 2
721
+ console.log(parsed.getId()); // txid as hex string
722
+
723
+ // Serialize to buffer
724
+ const buffer = tx.toBuffer();
725
+
726
+ // Deserialize from buffer
727
+ const parsed2 = Transaction.fromBuffer(buffer);
728
+ ```
729
+
730
+ ### Cloning a Transaction
731
+
732
+ ```typescript
733
+ import { Transaction } from '@btc-vision/bitcoin';
734
+
735
+ const original = Transaction.fromHex('0200000001...');
736
+ const clone = original.clone();
737
+
738
+ // The clone is independent of the original
739
+ clone.locktime = 900000;
740
+ console.log(original.locktime !== clone.locktime); // true
741
+ ```
742
+
743
+ ### Computing Transaction Size and Weight
744
+
745
+ ```typescript
746
+ import { Transaction } from '@btc-vision/bitcoin';
747
+
748
+ const tx = Transaction.fromHex('0200000001...');
749
+
750
+ // Size without witness data
751
+ const baseSize = tx.byteLength(false);
752
+
753
+ // Size with witness data (if present)
754
+ const totalSize = tx.byteLength(true);
755
+
756
+ // BIP 141 weight
757
+ const weight = tx.weight();
758
+
759
+ // Virtual size for fee calculation
760
+ const vsize = tx.virtualSize();
761
+
762
+ console.log(`Base size: ${baseSize} bytes`);
763
+ console.log(`Total size: ${totalSize} bytes`);
764
+ console.log(`Weight: ${weight} WU`);
765
+ console.log(`Virtual size: ${vsize} vbytes`);
766
+ ```
767
+
768
+ ### Legacy Input Signing
769
+
770
+ ```typescript
771
+ import { Transaction } from '@btc-vision/bitcoin';
772
+ import type { Script } from '@btc-vision/bitcoin';
773
+
774
+ const tx = new Transaction();
775
+ tx.version = 1;
776
+ // ... add inputs and outputs ...
777
+
778
+ // Produce the sighash for legacy signing
779
+ const sighash = tx.hashForSignature(
780
+ 0, // input index
781
+ prevOutScript as Script, // the scriptPubKey of the UTXO being spent
782
+ Transaction.SIGHASH_ALL,
783
+ );
784
+
785
+ // Sign the sighash with an ECDSA private key
786
+ // const signature = ecpair.sign(sighash);
787
+
788
+ // Set the scriptSig with the signature and public key
789
+ // tx.setInputScript(0, scriptSig);
790
+ ```
791
+
792
+ ### SegWit v0 Input Signing
793
+
794
+ ```typescript
795
+ import { Transaction } from '@btc-vision/bitcoin';
796
+ import type { Satoshi, Script } from '@btc-vision/bitcoin';
797
+
798
+ const tx = new Transaction();
799
+ tx.version = 2;
800
+ // ... add inputs and outputs ...
801
+
802
+ // BIP 143 sighash commits to the input value
803
+ const sighash = tx.hashForWitnessV0(
804
+ 0, // input index
805
+ prevOutScript as Script, // scriptCode for this input
806
+ 100000n as Satoshi, // value of the UTXO being spent
807
+ Transaction.SIGHASH_ALL,
808
+ );
809
+
810
+ // Sign and set witness
811
+ // const signature = ecpair.sign(sighash);
812
+ // tx.setWitness(0, [signature, publicKey]);
813
+ ```
814
+
815
+ ### Taproot Key-Path Signing
816
+
817
+ ```typescript
818
+ import { Transaction } from '@btc-vision/bitcoin';
819
+ import type { Satoshi, Script } from '@btc-vision/bitcoin';
820
+
821
+ const tx = new Transaction();
822
+ tx.version = 2;
823
+ // ... add inputs and outputs ...
824
+
825
+ // Taproot sighash requires scripts and values for ALL inputs
826
+ const prevOutScripts: Script[] = [utxo0ScriptPubKey, utxo1ScriptPubKey];
827
+ const values: Satoshi[] = [50000n as Satoshi, 75000n as Satoshi];
828
+
829
+ // Key-path spend: no leafHash
830
+ const sighash = tx.hashForWitnessV1(
831
+ 0, // input index
832
+ prevOutScripts,
833
+ values,
834
+ Transaction.SIGHASH_DEFAULT, // 0x00 for default key-path
835
+ );
836
+
837
+ // Sign with Schnorr signature
838
+ // const schnorrSig = tweakedKeypair.signSchnorr(sighash);
839
+ // tx.setWitness(0, [schnorrSig]);
840
+ ```
841
+
842
+ ### Taproot Script-Path Signing with Cache
843
+
844
+ ```typescript
845
+ import { Transaction } from '@btc-vision/bitcoin';
846
+ import type { Bytes32, Satoshi, Script } from '@btc-vision/bitcoin';
847
+
848
+ const tx = new Transaction();
849
+ tx.version = 2;
850
+ // ... add inputs and outputs ...
851
+
852
+ const prevOutScripts: Script[] = [script0, script1, script2];
853
+ const values: Satoshi[] = [10000n as Satoshi, 20000n as Satoshi, 30000n as Satoshi];
854
+
855
+ // Pre-compute intermediate hashes once
856
+ const cache = tx.getTaprootHashCache(prevOutScripts, values);
857
+
858
+ // Sign each input with the cache for O(n) total performance
859
+ for (let i = 0; i < tx.ins.length; i++) {
860
+ const sighash = tx.hashForWitnessV1(
861
+ i,
862
+ prevOutScripts,
863
+ values,
864
+ Transaction.SIGHASH_DEFAULT,
865
+ leafHash as Bytes32, // tapleaf hash for script-path spend
866
+ undefined, // no annex
867
+ cache, // reuse pre-computed hashes
868
+ );
869
+ // Sign sighash and set witness for input i
870
+ }
871
+ ```
872
+
873
+ ### Checking for Coinbase Transactions
874
+
875
+ ```typescript
876
+ import { Transaction } from '@btc-vision/bitcoin';
877
+
878
+ const tx = Transaction.fromHex('0100000001000000000000000000000000...');
879
+
880
+ if (tx.isCoinbase()) {
881
+ console.log('This is a coinbase transaction (block reward)');
882
+ }
883
+
884
+ // Static method to check a hash directly
885
+ import type { Bytes32 } from '@btc-vision/bitcoin';
886
+ const hash = new Uint8Array(32) as Bytes32; // all zeros
887
+ console.log(Transaction.isCoinbaseHash(hash)); // true
888
+ ```
889
+
890
+ ### Setting Witness Data
891
+
892
+ ```typescript
893
+ import { Transaction, fromHex } from '@btc-vision/bitcoin';
894
+
895
+ const tx = Transaction.fromHex('0200000001...');
896
+
897
+ // Set witness for a P2WPKH input
898
+ tx.setWitness(0, [
899
+ fromHex('3045022100...'), // DER-encoded signature
900
+ fromHex('02abcdef...'), // compressed public key
901
+ ]);
902
+
903
+ // Verify witness is set
904
+ console.log(tx.hasWitnesses()); // true
905
+ console.log(tx.ins[0].witness.length); // 2
906
+ ```
907
+
908
+ ---
909
+
910
+ ## Transaction Serialization Format
911
+
912
+ ### Legacy Format
913
+
914
+ ```
915
+ [version: 4 bytes]
916
+ [input count: varint]
917
+ [prev tx hash: 32 bytes][prev output index: 4 bytes][scriptSig: varint + bytes][sequence: 4 bytes]
918
+ ...
919
+ [output count: varint]
920
+ [value: 8 bytes][scriptPubKey: varint + bytes]
921
+ ...
922
+ [locktime: 4 bytes]
923
+ ```
924
+
925
+ ### SegWit Format (BIP 141)
926
+
927
+ ```
928
+ [version: 4 bytes]
929
+ [marker: 0x00][flag: 0x01]
930
+ [input count: varint]
931
+ [prev tx hash: 32 bytes][prev output index: 4 bytes][scriptSig: varint + bytes][sequence: 4 bytes]
932
+ ...
933
+ [output count: varint]
934
+ [value: 8 bytes][scriptPubKey: varint + bytes]
935
+ ...
936
+ [witness data]
937
+ [witness stack for input 0: varint count + varint-length items]
938
+ [witness stack for input 1: ...]
939
+ ...
940
+ [locktime: 4 bytes]
941
+ ```
942
+
943
+ The `marker` (`0x00`) and `flag` (`0x01`) bytes distinguish SegWit transactions from legacy ones during parsing. The `Transaction` class handles this automatically in both `fromBuffer` and `toBuffer`.