@btc-vision/transaction 1.0.88 → 1.0.90

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.
@@ -19,6 +19,8 @@ import { VaultUTXOs } from './processor/PsbtTransaction.js';
19
19
  import { UnwrapSegwitTransaction } from './builders/UnwrapSegwitTransaction.js';
20
20
  import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
21
21
  import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
22
+ import { TransactionBuilder } from './builders/TransactionBuilder.js';
23
+ import { TransactionType } from './enums/TransactionType.js';
22
24
 
23
25
  export interface DeploymentResult {
24
26
  readonly transaction: [string, string];
@@ -37,6 +39,20 @@ export interface WrapResult {
37
39
  readonly utxos: UTXO[];
38
40
  }
39
41
 
42
+ export interface FundingTransactionResponse {
43
+ readonly tx: Transaction;
44
+ readonly original: FundingTransaction;
45
+ readonly estimatedFees: bigint;
46
+ readonly nextUTXOs: UTXO[];
47
+ }
48
+
49
+ export interface BitcoinTransferResponse {
50
+ readonly tx: string;
51
+ readonly original: FundingTransaction;
52
+ readonly estimatedFees: bigint;
53
+ readonly nextUTXOs: UTXO[];
54
+ }
55
+
40
56
  export interface UnwrapResult {
41
57
  readonly fundingTransaction: string;
42
58
  readonly psbt: string;
@@ -403,11 +419,9 @@ export class TransactionFactory {
403
419
  * @param {IFundingTransactionParameters} parameters - The funding transaction parameters
404
420
  * @returns {Promise<{ estimatedFees: bigint; tx: string }>} - The signed transaction
405
421
  */
406
- public async createBTCTransfer(parameters: IFundingTransactionParameters): Promise<{
407
- estimatedFees: bigint;
408
- tx: string;
409
- nextUTXOs: UTXO[];
410
- }> {
422
+ public async createBTCTransfer(
423
+ parameters: IFundingTransactionParameters,
424
+ ): Promise<BitcoinTransferResponse> {
411
425
  if (!parameters.from) {
412
426
  throw new Error('Field "from" not provided.');
413
427
  }
@@ -416,16 +430,45 @@ export class TransactionFactory {
416
430
 
417
431
  return {
418
432
  estimatedFees: resp.estimatedFees,
433
+ original: resp.original,
419
434
  tx: resp.tx.toHex(),
420
- nextUTXOs: this.getUTXOAsTransaction(resp.tx, parameters.from, 1),
435
+ nextUTXOs: this.getAllNewUTXOs(resp.original, resp.tx, parameters.from),
421
436
  };
422
437
  }
423
438
 
424
- private async createFundTransaction(parameters: IFundingTransactionParameters): Promise<{
425
- tx: Transaction;
426
- original: FundingTransaction;
427
- estimatedFees: bigint;
428
- }> {
439
+ /**
440
+ * Get all new UTXOs of a generated transaction.
441
+ * @param {TransactionBuilder<TransactionType>} original - The original transaction
442
+ * @param {Transaction} tx - The transaction
443
+ * @param {Address} to - The address to filter
444
+ */
445
+ public getAllNewUTXOs(
446
+ original: TransactionBuilder<TransactionType>,
447
+ tx: Transaction,
448
+ to: Address,
449
+ ): UTXO[] {
450
+ const outputs = original.getOutputs();
451
+
452
+ const utxos: UTXO[] = [];
453
+ for (let i = 0; i < tx.outs.length; i++) {
454
+ const output = outputs[i];
455
+ if ('address' in output) {
456
+ if (output.address !== to) continue;
457
+ } else {
458
+ continue;
459
+ }
460
+
461
+ utxos.push(...this.getUTXOAsTransaction(tx, to, i));
462
+ }
463
+
464
+ return utxos;
465
+ }
466
+
467
+ private async createFundTransaction(
468
+ parameters: IFundingTransactionParameters,
469
+ ): Promise<FundingTransactionResponse> {
470
+ if (!parameters.to) throw new Error('Field "to" not provided.');
471
+
429
472
  const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
430
473
  const signedTransaction: Transaction = await fundingTransaction.signTransaction();
431
474
  if (!signedTransaction) {
@@ -435,7 +478,8 @@ export class TransactionFactory {
435
478
  return {
436
479
  tx: signedTransaction,
437
480
  original: fundingTransaction,
438
- estimatedFees: await fundingTransaction.estimateTransactionFees(),
481
+ estimatedFees: fundingTransaction.estimatedFees,
482
+ nextUTXOs: this.getUTXOAsTransaction(signedTransaction, parameters.to, 0),
439
483
  };
440
484
  }
441
485
 
@@ -6,13 +6,13 @@ import { TransactionBuilder } from './TransactionBuilder.js';
6
6
  export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDING> {
7
7
  public readonly type: TransactionType.FUNDING = TransactionType.FUNDING;
8
8
 
9
- protected childTransactionRequiredFees: bigint;
9
+ protected amount: bigint;
10
10
  protected splitInputsInto: number;
11
11
 
12
12
  constructor(parameters: IFundingTransactionParameters) {
13
13
  super(parameters);
14
14
 
15
- this.childTransactionRequiredFees = parameters.amount;
15
+ this.amount = parameters.amount;
16
16
  this.splitInputsInto = parameters.splitInputsInto ?? 1;
17
17
 
18
18
  this.internalInit();
@@ -25,10 +25,16 @@ export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDI
25
25
 
26
26
  this.addInputsFromUTXO();
27
27
 
28
- const amountSpent: bigint =
29
- this.getTransactionOPNetFee() + this.childTransactionRequiredFees;
28
+ let amountSpent: bigint = this.amount;
29
+ if (this.getTransactionOPNetFee() === TransactionBuilder.MINIMUM_DUST) {
30
+ if (amountSpent < TransactionBuilder.MINIMUM_DUST) {
31
+ amountSpent += TransactionBuilder.MINIMUM_DUST;
32
+ }
33
+ } else {
34
+ amountSpent += this.getTransactionOPNetFee();
35
+ }
30
36
 
31
- if(this.splitInputsInto > 1) {
37
+ if (this.splitInputsInto > 1) {
32
38
  await this.splitInputs(amountSpent);
33
39
  } else {
34
40
  this.addOutput({
@@ -222,6 +222,10 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
222
222
  * @throws {Error} - If something went wrong
223
223
  */
224
224
  public async signTransaction(): Promise<Transaction> {
225
+ if (!this.utxos.length) {
226
+ throw new Error('No UTXOs specified');
227
+ }
228
+
225
229
  if (this.to && !EcKeyPair.verifyContractAddress(this.to, this.network)) {
226
230
  throw new Error(
227
231
  'Invalid contract address. The contract address must be a taproot address.',
@@ -337,6 +341,10 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
337
341
  * @returns {Promise<bigint>} - The estimated transaction fees
338
342
  */
339
343
  public async estimateTransactionFees(): Promise<bigint> {
344
+ if (!this.utxos.length) {
345
+ throw new Error('No UTXOs specified');
346
+ }
347
+
340
348
  if (this.estimatedFees) return this.estimatedFees;
341
349
 
342
350
  const fakeTx = new Psbt({
@@ -372,6 +380,27 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
372
380
  this.transaction = psbt;
373
381
  }
374
382
 
383
+ /**
384
+ * Returns the inputs of the transaction.
385
+ * @protected
386
+ * @returns {PsbtInputExtended[]}
387
+ */
388
+ public getInputs(): PsbtInputExtended[] {
389
+ return this.inputs;
390
+ }
391
+
392
+ /**
393
+ * Returns the outputs of the transaction.
394
+ * @protected
395
+ * @returns {PsbtOutputExtended[]}
396
+ */
397
+ public getOutputs(): PsbtOutputExtended[] {
398
+ const outputs: PsbtOutputExtended[] = [...this.outputs];
399
+ if (this.feeOutput) outputs.push(this.feeOutput);
400
+
401
+ return outputs;
402
+ }
403
+
375
404
  /**
376
405
  * @description Adds the refund output to the transaction
377
406
  * @param {bigint} amountSpent - The amount spent
@@ -381,6 +410,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
381
410
  protected async addRefundOutput(amountSpent: bigint): Promise<void> {
382
411
  /** Add the refund output */
383
412
  const sendBackAmount: bigint = this.totalInputAmount - amountSpent;
413
+
384
414
  if (sendBackAmount >= TransactionBuilder.MINIMUM_DUST) {
385
415
  if (AddressVerificator.isValidP2TRAddress(this.from, this.network)) {
386
416
  await this.setFeeOutput({
@@ -548,27 +578,6 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
548
578
  return this.tapData.output;
549
579
  }
550
580
 
551
- /**
552
- * Returns the inputs of the transaction.
553
- * @protected
554
- * @returns {PsbtInputExtended[]}
555
- */
556
- protected getInputs(): PsbtInputExtended[] {
557
- return this.inputs;
558
- }
559
-
560
- /**
561
- * Returns the outputs of the transaction.
562
- * @protected
563
- * @returns {PsbtOutputExtended[]}
564
- */
565
- protected getOutputs(): PsbtOutputExtended[] {
566
- const outputs: PsbtOutputExtended[] = [...this.outputs];
567
- if (this.feeOutput) outputs.push(this.feeOutput);
568
-
569
- return outputs;
570
- }
571
-
572
581
  /**
573
582
  * Verifies that the utxos are valid.
574
583
  * @protected