@btc-vision/transaction 1.0.6 → 1.0.8

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 (179) hide show
  1. package/Deploy.md +186 -0
  2. package/README.md +5 -0
  3. package/Wrap.md +192 -0
  4. package/browser/_version.d.ts +1 -1
  5. package/browser/index.js +1 -1
  6. package/browser/index.js.LICENSE.txt +9 -0
  7. package/browser/opnet.d.ts +6 -1
  8. package/browser/tests/deploy.d.ts +1 -0
  9. package/browser/tests/wrap.d.ts +1 -0
  10. package/browser/tests/wrapTest.d.ts +1 -0
  11. package/browser/transaction/TransactionFactory.d.ts +15 -1
  12. package/browser/transaction/builders/DeploymentTransaction.d.ts +40 -0
  13. package/browser/transaction/builders/InteractionTransaction.d.ts +2 -35
  14. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  15. package/browser/transaction/builders/TransactionBuilder.d.ts +8 -1
  16. package/browser/transaction/builders/WrapTransaction.d.ts +27 -0
  17. package/browser/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  18. package/browser/utils/BitcoinUtils.d.ts +1 -0
  19. package/browser/utxo/OPNetLimitedProvider.d.ts +10 -0
  20. package/browser/wbtc/Generate.d.ts +13 -0
  21. package/browser/wbtc/WrappedGenerationParameters.d.ts +11 -0
  22. package/build/_version.d.ts +1 -1
  23. package/build/_version.js +1 -1
  24. package/build/bytecode/Compressor.js +4 -3
  25. package/build/generators/AddressGenerator.js +1 -1
  26. package/build/keypair/EcKeyPair.js +1 -1
  27. package/build/opnet.d.ts +6 -1
  28. package/build/opnet.js +6 -1
  29. package/build/signer/TweakedSigner.js +1 -1
  30. package/build/tests/deploy.d.ts +1 -0
  31. package/build/tests/deploy.js +60 -0
  32. package/build/tests/test.js +3 -3
  33. package/build/tests/transfer.js +2 -2
  34. package/build/tests/wrap.d.ts +1 -0
  35. package/build/tests/wrap.js +64 -0
  36. package/build/tests/wrapTest.d.ts +1 -0
  37. package/build/tests/wrapTest.js +64 -0
  38. package/build/tests/wrapTestg.d.ts +1 -0
  39. package/build/tests/wrapTestg.js +66 -0
  40. package/build/transaction/TransactionFactory.d.ts +15 -1
  41. package/build/transaction/TransactionFactory.js +68 -0
  42. package/build/transaction/builders/DeploymentTransaction.d.ts +40 -0
  43. package/build/transaction/builders/DeploymentTransaction.js +216 -0
  44. package/build/transaction/builders/FundingTransaction.js +4 -1
  45. package/build/transaction/builders/InteractionTransaction.d.ts +2 -35
  46. package/build/transaction/builders/InteractionTransaction.js +4 -207
  47. package/build/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  48. package/build/transaction/builders/SharedInteractionTransaction.js +213 -0
  49. package/build/transaction/builders/TransactionBuilder.d.ts +8 -1
  50. package/build/transaction/builders/TransactionBuilder.js +20 -12
  51. package/build/transaction/builders/WrapTransaction.d.ts +27 -0
  52. package/build/transaction/builders/WrapTransaction.js +132 -0
  53. package/build/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  54. package/build/utils/BitcoinUtils.d.ts +1 -0
  55. package/build/utils/BitcoinUtils.js +7 -0
  56. package/build/utxo/OPNetLimitedProvider.d.ts +10 -0
  57. package/build/utxo/OPNetLimitedProvider.js +85 -0
  58. package/build/utxo/OPNetUtils.d.ts +7 -0
  59. package/build/utxo/OPNetUtils.js +47 -0
  60. package/build/verification/TapscriptVerificator.js +3 -3
  61. package/build/wbtc/Generate.d.ts +13 -0
  62. package/build/wbtc/Generate.js +1 -0
  63. package/build/wbtc/WrappedGenerationParameters.d.ts +11 -0
  64. package/build/wbtc/WrappedGenerationParameters.js +16 -0
  65. package/bytecode/contract.wasm +0 -0
  66. package/cjs/_version.d.ts +1 -1
  67. package/cjs/_version.js +1 -1
  68. package/cjs/bytecode/Compressor.js +1 -1
  69. package/cjs/generators/AddressGenerator.d.ts +7 -0
  70. package/cjs/generators/AddressGenerator.js +48 -0
  71. package/cjs/generators/Generator.d.ts +1 -2
  72. package/cjs/generators/Generator.js +1 -3
  73. package/cjs/generators/builders/DeploymentGenerator.d.ts +1 -0
  74. package/cjs/generators/builders/DeploymentGenerator.js +10 -7
  75. package/cjs/keypair/Wallet.d.ts +1 -0
  76. package/cjs/keypair/Wallet.js +6 -0
  77. package/cjs/opnet.d.ts +23 -0
  78. package/cjs/opnet.js +37 -0
  79. package/cjs/tests/Regtest.d.ts +3 -0
  80. package/cjs/tests/Regtest.js +32 -0
  81. package/cjs/tests/gen.d.ts +1 -0
  82. package/cjs/tests/gen.js +17 -0
  83. package/cjs/tests/test.d.ts +1 -0
  84. package/cjs/tests/test.js +53 -0
  85. package/cjs/tests/transfer.d.ts +1 -0
  86. package/cjs/tests/transfer.js +76 -0
  87. package/cjs/transaction/TransactionFactory.js +7 -4
  88. package/cjs/transaction/builders/FundingTransaction.js +1 -1
  89. package/cjs/transaction/builders/InteractionTransaction.d.ts +2 -0
  90. package/cjs/transaction/builders/InteractionTransaction.js +11 -2
  91. package/cjs/transaction/builders/TransactionBuilder.d.ts +3 -2
  92. package/cjs/transaction/builders/TransactionBuilder.js +22 -7
  93. package/cjs/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  94. package/cjs/verification/TapscriptVerificator.d.ts +17 -0
  95. package/cjs/verification/TapscriptVerificator.js +70 -0
  96. package/docs/assets/navigation.js +1 -1
  97. package/docs/assets/search.js +1 -1
  98. package/docs/classes/AddressGenerator.html +2 -2
  99. package/docs/classes/BitcoinUtils.html +7 -3
  100. package/docs/classes/CalldataGenerator.html +10 -10
  101. package/docs/classes/Compressor.html +4 -4
  102. package/docs/classes/ContractBaseMetadata.html +4 -4
  103. package/docs/classes/DeploymentGenerator.html +9 -9
  104. package/docs/classes/DeploymentTransaction.html +368 -0
  105. package/docs/classes/EcKeyPair.html +16 -16
  106. package/docs/classes/FundingTransaction.html +50 -47
  107. package/docs/classes/Generator.html +9 -9
  108. package/docs/classes/InteractionTransaction.html +89 -109
  109. package/docs/classes/OPNetLimitedProvider.html +197 -0
  110. package/docs/classes/SharedInteractionTransaction.html +392 -0
  111. package/docs/classes/TapscriptVerificator.html +2 -2
  112. package/docs/classes/TransactionBuilder.html +53 -50
  113. package/docs/classes/TransactionFactory.html +11 -4
  114. package/docs/classes/TweakedSigner.html +2 -2
  115. package/docs/classes/Wallet.html +10 -10
  116. package/docs/classes/WrapTransaction.html +404 -0
  117. package/docs/classes/WrappedGeneration.html +187 -0
  118. package/docs/classes/wBTC.html +7 -7
  119. package/docs/enums/TransactionSequence.html +177 -0
  120. package/docs/enums/TransactionType.html +2 -2
  121. package/docs/hierarchy.html +1 -1
  122. package/docs/index.html +3 -1
  123. package/docs/interfaces/ContractAddressVerificationParams.html +2 -2
  124. package/docs/interfaces/DeploymentResult.html +177 -0
  125. package/docs/interfaces/FetchUTXOParams.html +2 -2
  126. package/docs/interfaces/GenerationConstraints.html +182 -0
  127. package/docs/interfaces/IDeploymentParameters.html +183 -0
  128. package/docs/interfaces/IFundingTransactionParameters.html +3 -3
  129. package/docs/interfaces/IInteractionParameters.html +4 -6
  130. package/docs/interfaces/ITransactionParameters.html +3 -3
  131. package/docs/interfaces/IWallet.html +4 -4
  132. package/docs/interfaces/IWrapParameters.html +186 -0
  133. package/docs/interfaces/NetworkInformation.html +2 -2
  134. package/docs/interfaces/PsbtInputExtended.html +1 -1
  135. package/docs/interfaces/PsbtOutputExtendedAddress.html +2 -2
  136. package/docs/interfaces/PsbtOutputExtendedScript.html +2 -2
  137. package/docs/interfaces/RawUTXOResponse.html +2 -2
  138. package/docs/interfaces/SharedInteractionParameters.html +183 -0
  139. package/docs/interfaces/TapLeafScript.html +2 -2
  140. package/docs/interfaces/TweakSettings.html +3 -3
  141. package/docs/interfaces/UTXO.html +2 -2
  142. package/docs/interfaces/UpdateInput.html +2 -2
  143. package/docs/interfaces/WrapResult.html +178 -0
  144. package/docs/interfaces/WrappedGenerationParameters.html +184 -0
  145. package/docs/modules.html +14 -4
  146. package/docs/types/PsbtOutputExtended.html +1 -1
  147. package/docs/variables/version.html +1 -1
  148. package/package.json +4 -5
  149. package/src/_version.ts +1 -1
  150. package/src/bytecode/Compressor.ts +27 -26
  151. package/src/generators/AddressGenerator.ts +1 -1
  152. package/src/keypair/EcKeyPair.ts +1 -1
  153. package/src/opnet.ts +8 -1
  154. package/src/signer/TweakedSigner.ts +1 -1
  155. package/src/tests/deploy.ts +81 -0
  156. package/src/tests/test.ts +3 -3
  157. package/src/tests/transfer.ts +2 -2
  158. package/src/tests/wrap.ts +89 -0
  159. package/src/tests/wrapTest.ts +88 -0
  160. package/src/transaction/TransactionFactory.ts +119 -1
  161. package/src/transaction/builders/DeploymentTransaction.ts +418 -0
  162. package/src/transaction/builders/FundingTransaction.ts +5 -1
  163. package/src/transaction/builders/InteractionTransaction.ts +5 -404
  164. package/src/transaction/builders/SharedInteractionTransaction.ts +432 -0
  165. package/src/transaction/builders/TransactionBuilder.ts +41 -16
  166. package/src/transaction/builders/WrapTransaction.ts +286 -0
  167. package/src/transaction/interfaces/ITransactionParameters.ts +20 -13
  168. package/src/utils/BitcoinUtils.ts +16 -0
  169. package/src/utxo/{UTXOManager.ts → OPNetLimitedProvider.ts} +53 -2
  170. package/src/verification/TapscriptVerificator.ts +3 -3
  171. package/src/wbtc/Generate.ts +30 -0
  172. package/src/wbtc/WrappedGenerationParameters.ts +33 -0
  173. package/tests/TransactionBuilder.test.ts +58 -58
  174. package/tsconfig.webpack.json +7 -1
  175. package/webpack.config.js +3 -1
  176. package/browser/873e754d6c7c6e9361f1.module.wasm +0 -0
  177. package/docs/classes/UTXOManager.html +0 -187
  178. package/docs/interfaces/ITransactionDataContractDeployment.html +0 -184
  179. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +0 -186
@@ -0,0 +1,432 @@
1
+ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
2
+ import { address, Payment, Psbt, Signer } from 'bitcoinjs-lib';
3
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
4
+ import { ECPairInterface } from 'ecpair';
5
+ import { TransactionBuilder } from './TransactionBuilder.js';
6
+ import { TransactionType } from '../enums/TransactionType.js';
7
+ import { PsbtInputExtended, TapLeafScript } from '../interfaces/Tap.js';
8
+ import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
9
+ import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
10
+ import { Compressor } from '../../bytecode/Compressor.js';
11
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
12
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
13
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
14
+ import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
15
+
16
+ /**
17
+ * Shared interaction transaction
18
+ * @class SharedInteractionTransaction
19
+ */
20
+ export abstract class SharedInteractionTransaction<
21
+ T extends TransactionType,
22
+ > extends TransactionBuilder<T> {
23
+ /**
24
+ * Random salt for the interaction
25
+ * @type {Buffer}
26
+ */
27
+ public readonly randomBytes: Buffer;
28
+
29
+ protected targetScriptRedeem: Payment | null = null;
30
+ protected leftOverFundsScriptRedeem: Payment | null = null;
31
+
32
+ protected abstract readonly compiledTargetScript: Buffer;
33
+ protected abstract readonly scriptTree: Taptree;
34
+
35
+ protected tapLeafScript: TapLeafScript | null = null;
36
+ protected readonly calldataGenerator: CalldataGenerator;
37
+
38
+ /**
39
+ * Calldata for the interaction
40
+ * @protected
41
+ */
42
+ protected readonly calldata: Buffer;
43
+
44
+ /**
45
+ * Contract secret for the interaction
46
+ * @protected
47
+ */
48
+ protected abstract readonly contractSecret: Buffer;
49
+
50
+ /**
51
+ * The tweaked signer for the interaction (if any)
52
+ * @protected
53
+ */
54
+ protected tweakedSigner?: Signer;
55
+
56
+ /**
57
+ * Script signer for the interaction
58
+ * @protected
59
+ */
60
+ protected readonly scriptSigner: Signer;
61
+
62
+ /**
63
+ * Public keys specified in the interaction
64
+ * @protected
65
+ */
66
+ protected readonly interactionPubKeys: Buffer[] = [];
67
+
68
+ /**
69
+ * Minimum signatures required for the interaction
70
+ * @protected
71
+ */
72
+ protected readonly minimumSignatures: number = 0;
73
+
74
+ protected constructor(parameters: SharedInteractionParameters) {
75
+ super(parameters);
76
+
77
+ if (!parameters.calldata) {
78
+ throw new Error('Calldata is required');
79
+ }
80
+
81
+ this.calldata = Compressor.compress(parameters.calldata);
82
+
83
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
84
+ this.scriptSigner = this.generateKeyPairFromSeed();
85
+
86
+ this.calldataGenerator = new CalldataGenerator(
87
+ this.internalPubKeyToXOnly(),
88
+ this.scriptSignerXOnlyPubKey(),
89
+ this.network,
90
+ );
91
+ }
92
+
93
+ /**
94
+ * Get the contract secret
95
+ * @returns {Buffer} The contract secret
96
+ */
97
+ public getContractSecret(): Buffer {
98
+ return this.contractSecret;
99
+ }
100
+
101
+ /**
102
+ * Get the random bytes used for the interaction
103
+ * @returns {Buffer} The random bytes
104
+ */
105
+ public getRndBytes(): Buffer {
106
+ return this.randomBytes;
107
+ }
108
+
109
+ /**
110
+ * Generate the secret for the interaction
111
+ * @protected
112
+ * @returns {Buffer} The secret
113
+ * @throws {Error} If the to address is invalid
114
+ */
115
+ protected generateSecret(): Buffer {
116
+ if (!this.to) throw new Error('To address is required');
117
+
118
+ return address.fromBech32(this.to).data;
119
+ }
120
+
121
+ /**
122
+ * Tweak the signer for the interaction
123
+ * @protected
124
+ */
125
+ protected tweakSigner(): void {
126
+ this.tweakedSigner = this.getTweakedSigner();
127
+ }
128
+
129
+ /**
130
+ * Get the internal pubkey as an x-only key
131
+ * @protected
132
+ * @returns {Buffer} The internal pubkey as an x-only key
133
+ */
134
+ protected scriptSignerXOnlyPubKey(): Buffer {
135
+ return toXOnly(this.scriptSigner.publicKey);
136
+ }
137
+
138
+ /**
139
+ * Generate a key pair from the seed
140
+ * @protected
141
+ *
142
+ * @returns {ECPairInterface} The key pair
143
+ */
144
+ protected generateKeyPairFromSeed(): ECPairInterface {
145
+ return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
146
+ }
147
+
148
+ /**
149
+ * Add inputs from the UTXO
150
+ * @protected
151
+ *
152
+ * @throws {Error} If the tap leaf script is required
153
+ */
154
+ protected override addInputsFromUTXO(): void {
155
+ if (!this.tapLeafScript) throw new Error('Tap leaf script is required');
156
+
157
+ for (let utxo of this.utxos) {
158
+ const input: PsbtInputExtended = {
159
+ hash: utxo.transactionId,
160
+ index: utxo.outputIndex,
161
+ witnessUtxo: {
162
+ value: Number(utxo.value),
163
+ script: this.getTapOutput(),
164
+ },
165
+ tapLeafScript: [this.tapLeafScript],
166
+ sequence: this.sequence,
167
+ };
168
+
169
+ this.addInput(input);
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Build the transaction
175
+ * @protected
176
+ *
177
+ * @throws {Error} If the left over funds script redeem is required
178
+ * @throws {Error} If the left over funds script redeem version is required
179
+ * @throws {Error} If the left over funds script redeem output is required
180
+ * @throws {Error} If the to address is required
181
+ */
182
+ protected override buildTransaction(): void {
183
+ if (!this.to) throw new Error('To address is required');
184
+
185
+ const selectedRedeem = !!this.scriptSigner
186
+ ? this.targetScriptRedeem
187
+ : this.leftOverFundsScriptRedeem;
188
+
189
+ if (!selectedRedeem) {
190
+ throw new Error('Left over funds script redeem is required');
191
+ }
192
+
193
+ if (!selectedRedeem.redeemVersion) {
194
+ throw new Error('Left over funds script redeem version is required');
195
+ }
196
+
197
+ if (!selectedRedeem.output) {
198
+ throw new Error('Left over funds script redeem output is required');
199
+ }
200
+
201
+ this.tapLeafScript = {
202
+ leafVersion: selectedRedeem.redeemVersion,
203
+ script: selectedRedeem.output,
204
+ controlBlock: this.getWitness(),
205
+ };
206
+
207
+ this.addInputsFromUTXO();
208
+
209
+ const amountSpent: bigint = this.getTransactionOPNetFee();
210
+ this.addOutput({
211
+ value: Number(amountSpent),
212
+ address: this.to,
213
+ });
214
+
215
+ this.addRefundOutput(amountSpent);
216
+ }
217
+
218
+ /**
219
+ * Sign the inputs
220
+ * @param {Psbt} transaction The transaction to sign
221
+ * @protected
222
+ */
223
+ protected signInputs(transaction: Psbt): void {
224
+ if (!this.scriptSigner) {
225
+ super.signInputs(transaction);
226
+
227
+ return;
228
+ }
229
+
230
+ transaction.signInput(0, this.scriptSigner);
231
+ transaction.signInput(0, this.getSignerKey());
232
+
233
+ transaction.finalizeInput(0, this.customFinalizer);
234
+ }
235
+
236
+ /**
237
+ * Get the signer
238
+ * @protected
239
+ *
240
+ * @returns {Signer} The signer
241
+ */
242
+ protected getSignerKey(): Signer {
243
+ if (this.tweakedSigner) {
244
+ return this.tweakedSigner;
245
+ }
246
+
247
+ return this.signer;
248
+ }
249
+
250
+ protected override generateScriptAddress(): Payment {
251
+ return {
252
+ internalPubkey: this.internalPubKeyToXOnly(),
253
+ network: this.network,
254
+ scriptTree: this.scriptTree,
255
+ };
256
+ }
257
+
258
+ protected override generateTapData(): Payment {
259
+ const selectedRedeem = !!this.scriptSigner
260
+ ? this.targetScriptRedeem
261
+ : this.leftOverFundsScriptRedeem;
262
+
263
+ if (!selectedRedeem) {
264
+ throw new Error('Left over funds script redeem is required');
265
+ }
266
+
267
+ if (!this.scriptTree) {
268
+ throw new Error('Script tree is required');
269
+ }
270
+
271
+ return {
272
+ internalPubkey: this.internalPubKeyToXOnly(),
273
+ network: this.network,
274
+ scriptTree: this.scriptTree,
275
+ redeem: selectedRedeem,
276
+ };
277
+ }
278
+
279
+ /**
280
+ * Generate the script solution
281
+ * @param {PsbtInput} input The input
282
+ * @protected
283
+ *
284
+ * @returns {Buffer[]} The script solution
285
+ */
286
+ protected getScriptSolution(input: PsbtInput): Buffer[] {
287
+ if (!input.tapScriptSig) {
288
+ throw new Error('Tap script signature is required');
289
+ }
290
+
291
+ return [
292
+ this.contractSecret,
293
+ this.internalPubKeyToXOnly(),
294
+ input.tapScriptSig[0].signature,
295
+ input.tapScriptSig[1].signature,
296
+ ];
297
+ }
298
+
299
+ /**
300
+ * Get the script tree
301
+ * @private
302
+ *
303
+ * @returns {Taptree} The script tree
304
+ */
305
+ protected getScriptTree(): Taptree {
306
+ if (!this.calldata) {
307
+ throw new Error('Calldata is required');
308
+ }
309
+
310
+ this.generateRedeemScripts();
311
+
312
+ return [
313
+ {
314
+ output: this.compiledTargetScript,
315
+ version: 192,
316
+ },
317
+ {
318
+ output: this.getLeafScript(),
319
+ version: 192,
320
+ },
321
+ ];
322
+ }
323
+
324
+ /**
325
+ * Get the public keys
326
+ * @private
327
+ *
328
+ * @returns {Buffer[]} The public keys
329
+ */
330
+ private getPubKeys(): Buffer[] {
331
+ const pubkeys = [this.signer.publicKey];
332
+
333
+ if (this.scriptSigner) {
334
+ pubkeys.push(this.scriptSigner.publicKey);
335
+ }
336
+
337
+ return pubkeys;
338
+ }
339
+
340
+ /**
341
+ * Transaction finalizer
342
+ * @param {number} _inputIndex The input index
343
+ * @param {PsbtInput} input The input
344
+ */
345
+ private customFinalizer = (_inputIndex: number, input: PsbtInput) => {
346
+ if (!this.tapLeafScript) {
347
+ throw new Error('Tap leaf script is required');
348
+ }
349
+
350
+ if (!input.tapScriptSig) {
351
+ throw new Error('Tap script signature is required');
352
+ }
353
+
354
+ if (!this.contractSecret) {
355
+ throw new Error('Contract secret is required');
356
+ }
357
+
358
+ const scriptSolution = this.getScriptSolution(input);
359
+
360
+ const witness = scriptSolution
361
+ .concat(this.tapLeafScript.script)
362
+ .concat(this.tapLeafScript.controlBlock);
363
+
364
+ return {
365
+ finalScriptWitness: this.witnessStackToScriptWitness(witness),
366
+ };
367
+ };
368
+
369
+ /**
370
+ * Get the tweaked hash
371
+ * @private
372
+ *
373
+ * @returns {Buffer | undefined} The tweaked hash
374
+ */
375
+ private getTweakerHash(): Buffer | undefined {
376
+ return this.tapData?.hash;
377
+ }
378
+
379
+ /**
380
+ * Get the tweaked signer
381
+ * @param {boolean} useTweakedHash Whether to use the tweaked hash
382
+ * @private
383
+ *
384
+ * @returns {Signer} The tweaked signer
385
+ */
386
+ private getTweakedSigner(useTweakedHash: boolean = false): Signer {
387
+ const settings: TweakSettings = {
388
+ network: this.network,
389
+ };
390
+
391
+ if (useTweakedHash) {
392
+ settings.tweakHash = this.getTweakerHash();
393
+ }
394
+
395
+ return TweakedSigner.tweakSigner(this.signer, settings);
396
+ }
397
+
398
+ /**
399
+ * Generate the redeem scripts
400
+ * @private
401
+ *
402
+ * @throws {Error} If the public keys are required
403
+ * @throws {Error} If the leaf script is required
404
+ * @throws {Error} If the leaf script version is required
405
+ * @throws {Error} If the leaf script output is required
406
+ * @throws {Error} If the target script redeem is required
407
+ */
408
+ private generateRedeemScripts(): void {
409
+ this.targetScriptRedeem = {
410
+ pubkeys: this.getPubKeys(),
411
+ output: this.compiledTargetScript,
412
+ redeemVersion: 192,
413
+ };
414
+
415
+ this.leftOverFundsScriptRedeem = {
416
+ pubkeys: this.getPubKeys(),
417
+ output: this.getLeafScript(),
418
+ redeemVersion: 192,
419
+ };
420
+ }
421
+
422
+ /**
423
+ * Get the second leaf script
424
+ * @private
425
+ *
426
+ * @returns {Buffer} The leaf script
427
+ */
428
+ private getLeafScript(): Buffer {
429
+ // For now, we disable this.
430
+ return SharedInteractionTransaction.LOCK_LEAF_SCRIPT;
431
+ }
432
+ }
@@ -1,7 +1,7 @@
1
1
  import { initEccLib, Network, opcodes, Payment, payments, Psbt, script, Signer, Transaction } from 'bitcoinjs-lib';
2
2
  import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
3
3
  import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
4
- import * as ecc from 'tiny-secp256k1';
4
+ import * as ecc from '@bitcoinerlab/secp256k1';
5
5
  import { PsbtInputExtended, PsbtOutputExtended, UpdateInput } from '../interfaces/Tap.js';
6
6
  import { TransactionType } from '../enums/TransactionType.js';
7
7
  import { IFundingTransactionParameters, ITransactionParameters } from '../interfaces/ITransactionParameters.js';
@@ -11,6 +11,14 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
11
11
  import { ECPairInterface } from 'ecpair';
12
12
  import { Logger } from '@btc-vision/logger';
13
13
 
14
+ /**
15
+ * The transaction sequence
16
+ */
17
+ export enum TransactionSequence {
18
+ REPLACE_BY_FEE = 0xfffffffd,
19
+ FINAL = 0xffffffff,
20
+ }
21
+
14
22
  /**
15
23
  * Allows to build a transaction like you would on Ethereum.
16
24
  * @description The transaction builder class
@@ -27,11 +35,15 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
27
35
 
28
36
  public abstract readonly type: T;
29
37
  public readonly logColor: string = '#785def';
30
-
31
38
  /**
32
39
  * @description Cost in satoshis of the transaction fee
33
40
  */
34
41
  public transactionFee: bigint = 0n;
42
+ /**
43
+ * @description The sequence of the transaction
44
+ * @protected
45
+ */
46
+ protected sequence: number = TransactionSequence.REPLACE_BY_FEE;
35
47
  /**
36
48
  * @description The transaction itself.
37
49
  */
@@ -93,7 +105,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
93
105
  * @description The address where the transaction is sent to
94
106
  * @protected
95
107
  */
96
- protected to: Address;
108
+ protected to: Address | undefined;
97
109
 
98
110
  /**
99
111
  * @description The address where the transaction is sent from
@@ -117,10 +129,13 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
117
129
  this.feeRate = parameters.feeRate;
118
130
  this.priorityFee = parameters.priorityFee;
119
131
  this.utxos = parameters.utxos;
120
- this.to = parameters.to;
121
- this.from =
122
- parameters.from ||
123
- EcKeyPair.getTaprootAddress(this.signer as ECPairInterface, this.network);
132
+ this.to = parameters.to || undefined;
133
+
134
+ this.from = TransactionBuilder.getFrom(
135
+ parameters.from,
136
+ this.signer as ECPairInterface,
137
+ this.network,
138
+ );
124
139
 
125
140
  this.totalInputAmount = this.calculateTotalUTXOAmount();
126
141
  const totalVOut: bigint = this.calculateTotalVOutAmount();
@@ -138,6 +153,14 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
138
153
  });
139
154
  }
140
155
 
156
+ public static getFrom(
157
+ from: string | undefined,
158
+ keypair: ECPairInterface,
159
+ network: Network,
160
+ ): Address {
161
+ return from || EcKeyPair.getTaprootAddress(keypair, network);
162
+ }
163
+
141
164
  public getFundingTransactionParameters(): IFundingTransactionParameters {
142
165
  return {
143
166
  utxos: this.utxos,
@@ -147,7 +170,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
147
170
  feeRate: this.feeRate,
148
171
  priorityFee: this.priorityFee,
149
172
  from: this.from,
150
- childTransactionRequiredFees: this.transactionFee,
173
+ childTransactionRequiredValue: this.transactionFee,
151
174
  };
152
175
  }
153
176
 
@@ -175,12 +198,12 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
175
198
  * @throws {Error} - If something went wrong
176
199
  */
177
200
  public signTransaction(): Transaction {
178
- if (!this.to) throw new Error('Transaction must have a recipient');
179
-
180
- if (!EcKeyPair.verifyContractAddress(this.to, this.network)) {
181
- throw new Error(
182
- 'Invalid contract address. The contract address must be a taproot address.',
183
- );
201
+ if (this.to) {
202
+ if (!EcKeyPair.verifyContractAddress(this.to, this.network)) {
203
+ throw new Error(
204
+ 'Invalid contract address. The contract address must be a taproot address.',
205
+ );
206
+ }
184
207
  }
185
208
 
186
209
  if (this.signed) throw new Error('Transaction is already signed');
@@ -222,8 +245,10 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
222
245
  public disableRBF(): void {
223
246
  if (this.signed) throw new Error('Transaction is already signed');
224
247
 
248
+ this.sequence = TransactionSequence.FINAL;
249
+
225
250
  for (let input of this.inputs) {
226
- input.sequence = 0xffffffff;
251
+ input.sequence = TransactionSequence.FINAL;
227
252
  }
228
253
  }
229
254
 
@@ -344,7 +369,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Logg
344
369
  value: Number(utxo.value),
345
370
  script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
346
371
  },
347
- sequence: 0xfffffffd,
372
+ sequence: this.sequence,
348
373
  };
349
374
 
350
375
  this.addInput(input);