@@ -104,8 +104,6 @@ const SLOT_CONFIG_NETWORK = {
104
104
Custom : { zeroTime : 0 , zeroSlot : 0 , slotLength : 0 } ,
105
105
}
106
106
107
- const dummySignature = Ed25519SignatureHex ( '0' . repeat ( 128 ) )
108
-
109
107
/**
110
108
* A builder class for constructing Cardano transactions with various components like inputs, outputs, and scripts.
111
109
*/
@@ -523,9 +521,10 @@ export class TxBuilder {
523
521
let vkeyWitnesses = CborSet . fromCore ( [ ] , VkeyWitness . fromCore )
524
522
let requiredWitnesses : VkeyWitness [ ] = [ ]
525
523
for ( const val of this . requiredWitnesses . values ( ) ) {
526
- requiredWitnesses . push ( VkeyWitness . fromCore ( [ val , dummySignature ] ) )
524
+ requiredWitnesses . push ( VkeyWitness . fromCore ( [ Ed25519PublicKeyHex ( "0" . repeat ( 64 ) ) , Ed25519SignatureHex ( '0' . repeat ( 128 ) ) ] ) )
527
525
}
528
526
vkeyWitnesses . setValues ( requiredWitnesses )
527
+ tw . setVkeys ( vkeyWitnesses )
529
528
tw . setRedeemers ( this . redeemers )
530
529
// Process Plutus data
531
530
let plutusData = CborSet . fromCore ( [ ] , PlutusData . fromCore )
@@ -549,10 +548,10 @@ export class TxBuilder {
549
548
* @returns {Value } The net value that represents the transaction's pitch.
550
549
* @throws {Error } If a corresponding UTxO for an input cannot be found.
551
550
*/
552
- private getPitch ( ) {
551
+ private getPitch ( withSpare : boolean = true ) {
553
552
// Initialize values for input, output, and minted amounts.
554
553
let inputValue = new Value ( 0n )
555
- let outputValue = new Value ( 0n )
554
+ let outputValue = new Value ( this . fee )
556
555
let mintValue = new Value ( 0n , this . body . mint ( ) )
557
556
558
557
// Aggregate the total input value from all inputs.
@@ -572,20 +571,22 @@ export class TxBuilder {
572
571
inputValue = value . merge ( inputValue , utxo . output ( ) . amount ( ) )
573
572
}
574
573
574
+ this . body . outputs ( ) [ this . changeOutputIndex ! ] = new TransactionOutput ( this . changeAddress ! , value . zero )
575
575
// Aggregate the total output value from all outputs.
576
576
for ( const output of this . body . outputs ( ) . values ( ) ) {
577
577
outputValue = value . merge ( outputValue , output . amount ( ) )
578
578
}
579
579
580
580
// Calculate the net value by merging input, output (negated), and mint values.
581
581
// Subtract a fixed fee amount (5 ADA) to ensure enough is allocated for transaction fees.
582
- return value . merge (
583
- value . merge (
584
- value . merge ( inputValue , value . negate ( outputValue ) ) ,
585
- mintValue ,
586
- ) ,
587
- new Value ( - 5000000n ) , // Subtract 5 ADA from the excess.
582
+ const tilt = value . merge (
583
+ value . merge ( inputValue , value . negate ( outputValue ) ) ,
584
+ mintValue ,
588
585
)
586
+ if ( withSpare == true ) {
587
+ return value . merge ( tilt , new Value ( - 5000000n ) ) // Subtract 5 ADA from the excess.
588
+ }
589
+ return tilt
589
590
}
590
591
591
592
/**
@@ -693,7 +694,7 @@ export class TxBuilder {
693
694
private calculateFees ( draft_tx : Transaction , tw : TransactionWitnessSet ) {
694
695
// Calculate the fee based on the transaction size and minimum fee parameters.
695
696
this . fee =
696
- BigInt ( Math . ceil ( this . params . minFeeConstant + draft_tx . toCbor ( ) . length / 2 * this . params . minFeeCoefficient ) )
697
+ BigInt ( Math . ceil ( this . params . minFeeConstant + ( fromHex ( draft_tx . toCbor ( ) ) . length ) * this . params . minFeeCoefficient ) )
697
698
// Update the transaction body with the calculated fee.
698
699
this . body . setFee ( this . fee )
699
700
}
@@ -749,6 +750,10 @@ export class TxBuilder {
749
750
if ( ! this . changeAddress ) {
750
751
throw new Error ( 'balanceCollateralChange: change address not set' )
751
752
}
753
+ let collateral = this . body . collateral ( )
754
+ if ( ! collateral || collateral . size ( ) == 0 ) {
755
+ return
756
+ }
752
757
// Retrieve available UTXOs within scope.
753
758
let scope = [ ...this . utxoScope . values ( ) ]
754
759
// Calculate the total collateral based on the transaction fee and collateral percentage.
@@ -803,7 +808,7 @@ export class TxBuilder {
803
808
// Gather all inputs from the transaction body.
804
809
let inputs = [ ...this . body . inputs ( ) . values ( ) ]
805
810
// Perform initial checks and preparations for coin selection.
806
- let excessValue = this . getPitch ( )
811
+ let excessValue = this . getPitch ( true )
807
812
let spareInputs : TransactionUnspentOutput [ ] = [ ]
808
813
for ( const [ utxo ] of this . utxos . entries ( ) ) {
809
814
if ( ! inputs . includes ( utxo . input ( ) ) ) {
@@ -838,6 +843,7 @@ export class TxBuilder {
838
843
)
839
844
}
840
845
// Build the transaction witness set for fee estimation and script validation.
846
+ //excessValue = this.getPitch(false)
841
847
let tw = this . buildTransactionWitnessSet ( )
842
848
// Calculate and set the script data hash if necessary.
843
849
{
@@ -846,31 +852,38 @@ export class TxBuilder {
846
852
this . body . setScriptDataHash ( scriptDataHash )
847
853
}
848
854
}
855
+ this . balanceChange ( excessValue )
849
856
// Create a draft transaction for fee calculation.
850
857
let draft_tx = new Transaction ( this . body , tw )
851
858
// Calculate and set the transaction fee.
859
+ let draft_size = draft_tx . toCbor ( ) . length / 2
852
860
this . calculateFees ( draft_tx , tw )
853
- this . body . setFee ( this . fee )
854
861
excessValue = value . merge ( excessValue , new Value ( - this . fee ) )
855
862
this . balanceChange ( excessValue )
856
- this . prepareCollateral ( )
857
- let evaluationFee = this . evaluate ( draft_tx )
858
- this . fee += evaluationFee
859
- excessValue = value . merge ( excessValue , new Value ( - evaluationFee ) )
860
- this . balanceChange ( excessValue )
861
- tw . setRedeemers ( this . redeemers )
863
+ if ( this . redeemers . size ( ) > 0 ) {
864
+ this . prepareCollateral ( )
865
+ let evaluationFee = this . evaluate ( draft_tx )
866
+ this . fee += evaluationFee
867
+ excessValue = value . merge ( excessValue , new Value ( - evaluationFee ) )
868
+ tw . setRedeemers ( this . redeemers )
869
+ }
862
870
{
863
- let scriptDataHash = this . getScriptDataHash ( tw )
871
+ const scriptDataHash = this . getScriptDataHash ( tw )
864
872
if ( scriptDataHash ) {
865
873
this . body . setScriptDataHash ( scriptDataHash )
866
874
}
867
875
}
868
876
this . body . setFee ( this . fee )
869
877
// Merge the fee with the excess value and rebalance the change.
870
- excessValue = value . merge ( excessValue , new Value ( - this . fee ) )
878
+ this . balanceCollateralChange ( )
879
+ let final_size = draft_tx . toCbor ( ) . length / 2
880
+ this . fee += BigInt ( Math . ceil ( ( final_size - draft_size ) * this . params . minFeeCoefficient ) )
881
+ excessValue = this . getPitch ( false )
882
+ this . body . setFee ( this . fee )
871
883
this . balanceChange ( excessValue )
872
884
this . balanceCollateralChange ( )
873
885
// Return the fully constructed transaction.
886
+ tw . setVkeys ( CborSet . fromCore ( [ ] , VkeyWitness . fromCore ) )
874
887
return new Transaction ( this . body , tw )
875
888
}
876
889
0 commit comments