@btc-vision/transaction 1.7.19 → 1.7.22

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 (92) hide show
  1. package/LICENSE +190 -21
  2. package/README.md +1 -1
  3. package/browser/_version.d.ts +1 -1
  4. package/browser/generators/builders/HashCommitmentGenerator.d.ts +49 -0
  5. package/browser/index.js +1 -1
  6. package/browser/keypair/Address.d.ts +3 -1
  7. package/browser/opnet.d.ts +6 -1
  8. package/browser/signer/AddressRotation.d.ts +12 -0
  9. package/browser/transaction/TransactionFactory.d.ts +14 -0
  10. package/browser/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
  11. package/browser/transaction/enums/TransactionType.d.ts +3 -1
  12. package/browser/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
  13. package/browser/transaction/interfaces/ITransactionParameters.d.ts +2 -0
  14. package/browser/transaction/offline/OfflineTransactionManager.d.ts +69 -0
  15. package/browser/transaction/offline/TransactionReconstructor.d.ts +28 -0
  16. package/browser/transaction/offline/TransactionSerializer.d.ts +50 -0
  17. package/browser/transaction/offline/TransactionStateCapture.d.ts +52 -0
  18. package/browser/transaction/offline/index.d.ts +5 -0
  19. package/browser/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
  20. package/browser/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
  21. package/browser/transaction/offline/interfaces/index.d.ts +2 -0
  22. package/browser/transaction/shared/TweakedTransaction.d.ts +12 -1
  23. package/browser/utxo/interfaces/IUTXO.d.ts +2 -0
  24. package/build/_version.d.ts +1 -1
  25. package/build/_version.js +1 -1
  26. package/build/generators/builders/HashCommitmentGenerator.d.ts +49 -0
  27. package/build/generators/builders/HashCommitmentGenerator.js +229 -0
  28. package/build/keypair/Address.d.ts +3 -1
  29. package/build/keypair/Address.js +87 -54
  30. package/build/opnet.d.ts +6 -1
  31. package/build/opnet.js +6 -1
  32. package/build/signer/AddressRotation.d.ts +12 -0
  33. package/build/signer/AddressRotation.js +16 -0
  34. package/build/transaction/TransactionFactory.d.ts +14 -0
  35. package/build/transaction/TransactionFactory.js +36 -0
  36. package/build/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
  37. package/build/transaction/builders/ConsolidatedInteractionTransaction.js +259 -0
  38. package/build/transaction/builders/TransactionBuilder.js +2 -0
  39. package/build/transaction/enums/TransactionType.d.ts +3 -1
  40. package/build/transaction/enums/TransactionType.js +2 -0
  41. package/build/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
  42. package/build/transaction/interfaces/IConsolidatedTransactionParameters.js +1 -0
  43. package/build/transaction/interfaces/ITransactionParameters.d.ts +2 -0
  44. package/build/transaction/offline/OfflineTransactionManager.d.ts +69 -0
  45. package/build/transaction/offline/OfflineTransactionManager.js +255 -0
  46. package/build/transaction/offline/TransactionReconstructor.d.ts +28 -0
  47. package/build/transaction/offline/TransactionReconstructor.js +243 -0
  48. package/build/transaction/offline/TransactionSerializer.d.ts +50 -0
  49. package/build/transaction/offline/TransactionSerializer.js +700 -0
  50. package/build/transaction/offline/TransactionStateCapture.d.ts +52 -0
  51. package/build/transaction/offline/TransactionStateCapture.js +275 -0
  52. package/build/transaction/offline/index.d.ts +5 -0
  53. package/build/transaction/offline/index.js +5 -0
  54. package/build/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
  55. package/build/transaction/offline/interfaces/ISerializableState.js +2 -0
  56. package/build/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
  57. package/build/transaction/offline/interfaces/ITypeSpecificData.js +19 -0
  58. package/build/transaction/offline/interfaces/index.d.ts +2 -0
  59. package/build/transaction/offline/interfaces/index.js +2 -0
  60. package/build/transaction/shared/TweakedTransaction.d.ts +12 -1
  61. package/build/transaction/shared/TweakedTransaction.js +75 -8
  62. package/build/utxo/interfaces/IUTXO.d.ts +2 -0
  63. package/documentation/README.md +5 -0
  64. package/documentation/offline-transaction-signing.md +650 -0
  65. package/documentation/transaction-building.md +603 -0
  66. package/package.json +2 -2
  67. package/src/_version.ts +1 -1
  68. package/src/generators/builders/HashCommitmentGenerator.ts +495 -0
  69. package/src/keypair/Address.ts +123 -70
  70. package/src/opnet.ts +8 -1
  71. package/src/signer/AddressRotation.ts +72 -0
  72. package/src/transaction/TransactionFactory.ts +90 -0
  73. package/src/transaction/builders/CancelTransaction.ts +4 -2
  74. package/src/transaction/builders/ConsolidatedInteractionTransaction.ts +568 -0
  75. package/src/transaction/builders/CustomScriptTransaction.ts +4 -2
  76. package/src/transaction/builders/MultiSignTransaction.ts +4 -2
  77. package/src/transaction/builders/TransactionBuilder.ts +8 -2
  78. package/src/transaction/enums/TransactionType.ts +2 -0
  79. package/src/transaction/interfaces/IConsolidatedTransactionParameters.ts +78 -0
  80. package/src/transaction/interfaces/ITransactionParameters.ts +8 -0
  81. package/src/transaction/offline/OfflineTransactionManager.ts +630 -0
  82. package/src/transaction/offline/TransactionReconstructor.ts +402 -0
  83. package/src/transaction/offline/TransactionSerializer.ts +920 -0
  84. package/src/transaction/offline/TransactionStateCapture.ts +469 -0
  85. package/src/transaction/offline/index.ts +8 -0
  86. package/src/transaction/offline/interfaces/ISerializableState.ts +141 -0
  87. package/src/transaction/offline/interfaces/ITypeSpecificData.ts +172 -0
  88. package/src/transaction/offline/interfaces/index.ts +2 -0
  89. package/src/transaction/shared/TweakedTransaction.ts +156 -9
  90. package/src/utxo/interfaces/IUTXO.ts +8 -0
  91. package/test/address-rotation.test.ts +553 -0
  92. package/test/offline-transaction.test.ts +2065 -0
@@ -36,6 +36,10 @@ export class TweakedTransaction extends Logger {
36
36
  this.txVersion = 2;
37
37
  this._mldsaSigner = null;
38
38
  this._hashedPublicKey = null;
39
+ this.addressRotationEnabled = false;
40
+ this.signerMap = new Map();
41
+ this.inputSignerMap = new Map();
42
+ this.tweakedSignerCache = new Map();
39
43
  this.customFinalizerP2SH = (inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH) => {
40
44
  const inputDecoded = this.inputs[inputIndex];
41
45
  if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
@@ -84,6 +88,10 @@ export class TweakedTransaction extends Logger {
84
88
  this._mldsaSigner = data.mldsaSigner;
85
89
  this._hashedPublicKey = MessageSigner.sha256(this._mldsaSigner.publicKey);
86
90
  }
91
+ if (data.addressRotation?.enabled) {
92
+ this.addressRotationEnabled = true;
93
+ this.signerMap = data.addressRotation.signerMap;
94
+ }
87
95
  }
88
96
  get mldsaSigner() {
89
97
  if (!this._mldsaSigner) {
@@ -153,6 +161,9 @@ export class TweakedTransaction extends Logger {
153
161
  }
154
162
  return signHash || 0;
155
163
  }
164
+ isAddressRotationEnabled() {
165
+ return this.addressRotationEnabled;
166
+ }
156
167
  ignoreSignatureError() {
157
168
  this.ignoreSignatureErrors = true;
158
169
  }
@@ -198,6 +209,53 @@ export class TweakedTransaction extends Logger {
198
209
  const vSize = weight / 4n;
199
210
  return vSize * feeRate;
200
211
  }
212
+ getSignerForInput(inputIndex) {
213
+ if (this.addressRotationEnabled) {
214
+ const inputSigner = this.inputSignerMap.get(inputIndex);
215
+ if (inputSigner) {
216
+ return inputSigner;
217
+ }
218
+ }
219
+ return this.signer;
220
+ }
221
+ registerInputSigner(inputIndex, utxo) {
222
+ if (!this.addressRotationEnabled) {
223
+ return;
224
+ }
225
+ if (utxo.signer) {
226
+ this.inputSignerMap.set(inputIndex, utxo.signer);
227
+ return;
228
+ }
229
+ const address = utxo.scriptPubKey?.address;
230
+ if (address && this.signerMap.has(address)) {
231
+ const signer = this.signerMap.get(address);
232
+ if (signer) {
233
+ this.inputSignerMap.set(inputIndex, signer);
234
+ return;
235
+ }
236
+ }
237
+ }
238
+ internalPubKeyToXOnlyForInput(inputIndex) {
239
+ const signer = this.getSignerForInput(inputIndex);
240
+ return toXOnly(Buffer.from(signer.publicKey));
241
+ }
242
+ getTweakedSignerForInput(inputIndex, useTweakedHash = false) {
243
+ if (!this.addressRotationEnabled) {
244
+ if (useTweakedHash) {
245
+ this.tweakSigner();
246
+ return this.tweakedSigner;
247
+ }
248
+ return this.getTweakedSigner(useTweakedHash);
249
+ }
250
+ const cacheKey = inputIndex * 2 + (useTweakedHash ? 1 : 0);
251
+ if (this.tweakedSignerCache.has(cacheKey)) {
252
+ return this.tweakedSignerCache.get(cacheKey);
253
+ }
254
+ const signer = this.getSignerForInput(inputIndex);
255
+ const tweaked = this.getTweakedSigner(useTweakedHash, signer);
256
+ this.tweakedSignerCache.set(cacheKey, tweaked);
257
+ return tweaked;
258
+ }
201
259
  generateTapData() {
202
260
  return {
203
261
  internalPubkey: this.internalPubKeyToXOnly(),
@@ -289,7 +347,8 @@ export class TweakedTransaction extends Logger {
289
347
  const index = offset + j;
290
348
  const input = batch[j];
291
349
  try {
292
- promises.push(this.signInput(transaction, input, index, this.signer));
350
+ const inputSigner = this.getSignerForInput(index);
351
+ promises.push(this.signInput(transaction, input, index, inputSigner));
293
352
  }
294
353
  catch (e) {
295
354
  this.log(`Failed to sign input ${index}: ${e.stack}`);
@@ -370,10 +429,13 @@ export class TweakedTransaction extends Logger {
370
429
  }
371
430
  return;
372
431
  }
373
- generateP2SHP2PKHRedeemScript(inputAddr) {
374
- const pubkey = Buffer.isBuffer(this.signer.publicKey)
375
- ? this.signer.publicKey
376
- : Buffer.from(this.signer.publicKey, 'hex');
432
+ generateP2SHP2PKHRedeemScript(inputAddr, inputIndex) {
433
+ const signer = this.addressRotationEnabled && inputIndex !== undefined
434
+ ? this.getSignerForInput(inputIndex)
435
+ : this.signer;
436
+ const pubkey = Buffer.isBuffer(signer.publicKey)
437
+ ? signer.publicKey
438
+ : Buffer.from(signer.publicKey, 'hex');
377
439
  const w = payments.p2wpkh({
378
440
  pubkey: pubkey,
379
441
  network: this.network,
@@ -432,7 +494,7 @@ export class TweakedTransaction extends Logger {
432
494
  if (!utxo.scriptPubKey.address) {
433
495
  throw new Error('Missing redeemScript and no address to regenerate it for P2SH UTXO');
434
496
  }
435
- const legacyScripts = this.generateP2SHP2PKHRedeemScript(utxo.scriptPubKey.address);
497
+ const legacyScripts = this.generateP2SHP2PKHRedeemScript(utxo.scriptPubKey.address, i);
436
498
  if (!legacyScripts) {
437
499
  throw new Error('Missing redeemScript for P2SH UTXO and unable to regenerate');
438
500
  }
@@ -469,8 +531,13 @@ export class TweakedTransaction extends Logger {
469
531
  if (inputSign)
470
532
  input.sighashType = inputSign;
471
533
  }
472
- this.tweakSigner();
473
- input.tapInternalKey = this.internalPubKeyToXOnly();
534
+ if (this.addressRotationEnabled) {
535
+ input.tapInternalKey = this.internalPubKeyToXOnlyForInput(i);
536
+ }
537
+ else {
538
+ this.tweakSigner();
539
+ input.tapInternalKey = this.internalPubKeyToXOnly();
540
+ }
474
541
  }
475
542
  else if (isP2A(scriptPub)) {
476
543
  this.anchorInputIndices.add(i);
@@ -1,4 +1,5 @@
1
1
  import { ScriptPubKey } from '@btc-vision/bitcoin-rpc';
2
+ import { RotationSigner } from '../../signer/AddressRotation.js';
2
3
  export interface UTXO {
3
4
  readonly transactionId: string;
4
5
  readonly outputIndex: number;
@@ -7,6 +8,7 @@ export interface UTXO {
7
8
  redeemScript?: string | Buffer;
8
9
  witnessScript?: string | Buffer;
9
10
  nonWitnessUtxo?: string | Buffer;
11
+ signer?: RotationSigner;
10
12
  }
11
13
  export interface FetchUTXOParams {
12
14
  readonly address: string;
@@ -19,6 +19,11 @@ Complete documentation for the OPNet Transaction Library - Bitcoin transaction b
19
19
  - **Universal Public Key** - `address.toHex()` returns the SHA256 hash of ML-DSA public key (32 bytes)
20
20
  - This is the user's universal identifier across the OPNet protocol
21
21
 
22
+ ### Transaction Building
23
+
24
+ - **[Transaction Building Guide](./transaction-building.md)** - Complete guide to TransactionFactory, UTXO flow, fee calculation, signing, and all transaction types
25
+ - **[Offline Transaction Signing](./offline-transaction-signing.md)** - Serialize transactions for offline/air-gapped signing, fee bumping (RBF), address rotation, and MultiSig support
26
+
22
27
  ### Quantum Support (ML-DSA)
23
28
 
24
29
  **[Complete Quantum Support Guide](./quantum-support/README.md)**