@@ -1338,6 +1338,26 @@ impl TransactionBuilder {
13381338 /// Editing inputs, outputs, mint, etc. after change been calculated
13391339 /// might cause a mismatch in calculated fee versus the required fee
13401340 pub fn add_change_if_needed ( & mut self , address : & Address ) -> Result < bool , JsError > {
1341+ self . add_change_if_needed_with_optional_script_and_datum ( address, None , None )
1342+ }
1343+
1344+ pub fn add_change_if_needed_with_datum ( & mut self ,
1345+ address : & Address ,
1346+ plutus_data : & OutputDatum )
1347+ -> Result < bool , JsError >
1348+ {
1349+ self . add_change_if_needed_with_optional_script_and_datum (
1350+ address,
1351+ Some ( plutus_data. 0 . clone ( ) ) ,
1352+ None )
1353+ }
1354+
1355+
1356+ fn add_change_if_needed_with_optional_script_and_datum ( & mut self , address : & Address ,
1357+ plutus_data : Option < DataOption > ,
1358+ script_ref : Option < ScriptRef > )
1359+ -> Result < bool , JsError >
1360+ {
13411361 let fee = match & self . fee {
13421362 None => self . min_fee ( ) ,
13431363 // generating the change output involves changing the fee
@@ -1348,11 +1368,6 @@ impl TransactionBuilder {
13481368 }
13491369 } ?;
13501370
1351- // note: can't add plutus data or data hash and script to change
1352- // because we don't know how many change outputs will need to be created
1353- let plutus_data: Option < DataOption > = None ;
1354- let script_ref: Option < ScriptRef > = None ;
1355-
13561371 let input_total = self . get_total_input ( ) ?;
13571372 let output_total = self . get_total_output ( ) ?;
13581373
@@ -1941,7 +1956,7 @@ impl TransactionBuilder {
19411956mod tests {
19421957 use super :: output_builder:: TransactionOutputBuilder ;
19431958 use super :: * ;
1944- use crate :: fakes:: { fake_base_address, fake_bytes_32, fake_key_hash, fake_policy_id, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2} ;
1959+ use crate :: fakes:: { fake_base_address, fake_bytes_32, fake_data_hash , fake_key_hash, fake_policy_id, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2} ;
19451960 use crate :: tx_builder_constants:: TxBuilderConstants ;
19461961 use fees:: * ;
19471962 use crate :: tx_builder:: tx_inputs_builder:: { InputsWithScriptWitness , InputWithScriptWitness , PlutusScriptSource } ;
@@ -2154,6 +2169,87 @@ mod tests {
21542169 let _final_tx = tx_builder. build ( ) ; // just test that it doesn't throw
21552170 }
21562171
2172+ #[ test]
2173+ fn build_tx_with_change_with_datum ( ) {
2174+ let mut tx_builder = create_default_tx_builder ( ) ;
2175+ let spend = root_key_15 ( )
2176+ . derive ( harden ( 1852 ) )
2177+ . derive ( harden ( 1815 ) )
2178+ . derive ( harden ( 0 ) )
2179+ . derive ( 0 )
2180+ . derive ( 0 )
2181+ . to_public ( ) ;
2182+ let change_key = root_key_15 ( )
2183+ . derive ( harden ( 1852 ) )
2184+ . derive ( harden ( 1815 ) )
2185+ . derive ( harden ( 0 ) )
2186+ . derive ( 1 )
2187+ . derive ( 0 )
2188+ . to_public ( ) ;
2189+ let stake = root_key_15 ( )
2190+ . derive ( harden ( 1852 ) )
2191+ . derive ( harden ( 1815 ) )
2192+ . derive ( harden ( 0 ) )
2193+ . derive ( 2 )
2194+ . derive ( 0 )
2195+ . to_public ( ) ;
2196+
2197+ let spend_cred = StakeCredential :: from_keyhash ( & spend. to_raw_key ( ) . hash ( ) ) ;
2198+ let stake_cred = StakeCredential :: from_keyhash ( & stake. to_raw_key ( ) . hash ( ) ) ;
2199+ let addr_net_0 = BaseAddress :: new (
2200+ NetworkInfo :: testnet ( ) . network_id ( ) ,
2201+ & spend_cred,
2202+ & stake_cred,
2203+ )
2204+ . to_address ( ) ;
2205+ tx_builder. add_key_input (
2206+ & spend. to_raw_key ( ) . hash ( ) ,
2207+ & TransactionInput :: new ( & genesis_id ( ) , 0 ) ,
2208+ & Value :: new ( & to_bignum ( 1_000_000 ) ) ,
2209+ ) ;
2210+ tx_builder
2211+ . add_output (
2212+ & TransactionOutputBuilder :: new ( )
2213+ . with_address ( & addr_net_0)
2214+ . next ( )
2215+ . unwrap ( )
2216+ . with_coin ( & to_bignum ( 222 ) )
2217+ . build ( )
2218+ . unwrap ( ) ,
2219+ )
2220+ . unwrap ( ) ;
2221+ tx_builder. set_ttl ( 1000 ) ;
2222+
2223+ let datum_hash = fake_data_hash ( 20 ) ;
2224+ let data_option = OutputDatum :: new_data_hash ( & datum_hash) ;
2225+ let ( _, script_hash) = plutus_script_and_hash ( 15 ) ;
2226+ let change_cred = StakeCredential :: from_scripthash ( & script_hash) ;
2227+ let change_addr = BaseAddress :: new (
2228+ NetworkInfo :: testnet ( ) . network_id ( ) ,
2229+ & change_cred,
2230+ & stake_cred,
2231+ )
2232+ . to_address ( ) ;
2233+ let added_change = tx_builder. add_change_if_needed_with_datum ( & change_addr, & data_option) ;
2234+ assert ! ( added_change. unwrap( ) ) ;
2235+ assert_eq ! ( tx_builder. outputs. len( ) , 2 ) ;
2236+ assert_eq ! (
2237+ tx_builder
2238+ . get_explicit_input( )
2239+ . unwrap( )
2240+ . checked_add( & tx_builder. get_implicit_input( ) . unwrap( ) )
2241+ . unwrap( ) ,
2242+ tx_builder
2243+ . get_explicit_output( )
2244+ . unwrap( )
2245+ . checked_add( & Value :: new( & tx_builder. get_fee_if_set( ) . unwrap( ) ) )
2246+ . unwrap( )
2247+ ) ;
2248+ assert_eq ! ( tx_builder. full_size( ) . unwrap( ) , 319 ) ;
2249+ assert_eq ! ( tx_builder. output_sizes( ) , vec![ 62 , 99 ] ) ;
2250+ let _final_tx = tx_builder. build ( ) ; // just test that it doesn't throw
2251+ }
2252+
21572253 #[ test]
21582254 fn build_tx_without_change ( ) {
21592255 let mut tx_builder = create_default_tx_builder ( ) ;
0 commit comments