@@ -5,21 +5,18 @@ use alloy_network::{
55} ;
66use alloy_primitives:: { hex, Address , Bytes , TxKind , U256 } ;
77use alloy_provider:: Provider ;
8- use alloy_rlp:: Decodable ;
98use alloy_rpc_types:: { AccessList , Authorization , TransactionInput , TransactionRequest } ;
109use alloy_serde:: WithOtherFields ;
1110use alloy_signer:: Signer ;
1211use alloy_transport:: Transport ;
13- use cast:: revm:: primitives:: SignedAuthorization ;
14- use eyre:: { Result , WrapErr } ;
12+ use eyre:: Result ;
1513use foundry_cli:: {
16- opts:: TransactionOpts ,
14+ opts:: { CliAuthorizationList , TransactionOpts } ,
1715 utils:: { self , parse_function_args} ,
1816} ;
1917use foundry_common:: ens:: NameOrAddress ;
2018use foundry_config:: { Chain , Config } ;
2119use foundry_wallets:: { WalletOpts , WalletSigner } ;
22- use serde_json;
2320
2421/// Different sender kinds used by [`CastTxBuilder`].
2522pub enum SenderKind < ' a > {
@@ -134,10 +131,10 @@ pub struct CastTxBuilder<T, P, S> {
134131 tx : WithOtherFields < TransactionRequest > ,
135132 legacy : bool ,
136133 blob : bool ,
137- auth : Option < String > ,
134+ auth : Option < CliAuthorizationList > ,
138135 chain : Chain ,
139136 etherscan_api_key : Option < String > ,
140- access_list : Option < Option < String > > ,
137+ access_list : Option < Option < AccessList > > ,
141138 state : S ,
142139 _t : std:: marker:: PhantomData < T > ,
143140}
@@ -319,24 +316,32 @@ where
319316 self . tx . set_from ( from) ;
320317 self . tx . set_chain_id ( self . chain . id ( ) ) ;
321318
322- if !fill {
323- return Ok ( ( self . tx , self . state . func ) ) ;
324- }
319+ let tx_nonce = if let Some ( nonce) = self . tx . nonce {
320+ nonce
321+ } else {
322+ let nonce = self . provider . get_transaction_count ( from) . await ?;
323+ if fill {
324+ self . tx . nonce = Some ( nonce) ;
325+ }
326+ nonce
327+ } ;
325328
326- if let Some ( access_list) = match self . access_list {
329+ self . resolve_auth ( sender, tx_nonce) . await ?;
330+
331+ if let Some ( access_list) = match self . access_list . take ( ) {
327332 None => None ,
328333 // --access-list provided with no value, call the provider to create it
329334 Some ( None ) => Some ( self . provider . create_access_list ( & self . tx ) . await ?. access_list ) ,
330335 // Access list provided as a string, attempt to parse it
331- Some ( Some ( ref s) ) => Some (
332- serde_json:: from_str :: < AccessList > ( s)
333- . map ( AccessList :: from)
334- . wrap_err ( "Failed to parse access list from string" ) ?,
335- ) ,
336+ Some ( Some ( access_list) ) => Some ( access_list) ,
336337 } {
337338 self . tx . set_access_list ( access_list) ;
338339 }
339340
341+ if !fill {
342+ return Ok ( ( self . tx , self . state . func ) ) ;
343+ }
344+
340345 if self . legacy && self . tx . gas_price . is_none ( ) {
341346 self . tx . gas_price = Some ( self . provider . get_gas_price ( ) . await ?) ;
342347 }
@@ -361,16 +366,6 @@ where
361366 }
362367 }
363368
364- let nonce = if let Some ( nonce) = self . tx . nonce {
365- nonce
366- } else {
367- let nonce = self . provider . get_transaction_count ( from) . await ?;
368- self . tx . nonce = Some ( nonce) ;
369- nonce
370- } ;
371-
372- self . resolve_auth ( sender, nonce) . await ?;
373-
374369 if self . tx . gas . is_none ( ) {
375370 self . tx . gas = Some ( self . provider . estimate_gas ( & self . tx ) . await ?) ;
376371 }
@@ -379,25 +374,27 @@ where
379374 }
380375
381376 /// Parses the passed --auth value and sets the authorization list on the transaction.
382- async fn resolve_auth ( & mut self , sender : SenderKind < ' _ > , nonce : u64 ) -> Result < ( ) > {
383- let Some ( auth) = & self . auth else { return Ok ( ( ) ) } ;
384-
385- let auth = hex:: decode ( auth) ?;
386- let auth = if let Ok ( address) = Address :: try_from ( auth. as_slice ( ) ) {
387- let auth =
388- Authorization { chain_id : U256 :: from ( self . chain . id ( ) ) , nonce : nonce + 1 , address } ;
389-
390- let Some ( signer) = sender. as_signer ( ) else {
391- eyre:: bail!( "No signer available to sign authorization" ) ;
392- } ;
393- let signature = signer. sign_hash ( & auth. signature_hash ( ) ) . await ?;
394-
395- auth. into_signed ( signature)
396- } else if let Ok ( auth) = SignedAuthorization :: decode ( & mut auth. as_ref ( ) ) {
397- auth
398- } else {
399- eyre:: bail!( "Failed to decode authorization" ) ;
377+ async fn resolve_auth ( & mut self , sender : SenderKind < ' _ > , tx_nonce : u64 ) -> Result < ( ) > {
378+ let Some ( auth) = self . auth . take ( ) else { return Ok ( ( ) ) } ;
379+
380+ let auth = match auth {
381+ CliAuthorizationList :: Address ( address) => {
382+ let auth = Authorization {
383+ chain_id : U256 :: from ( self . chain . id ( ) ) ,
384+ nonce : tx_nonce + 1 ,
385+ address,
386+ } ;
387+
388+ let Some ( signer) = sender. as_signer ( ) else {
389+ eyre:: bail!( "No signer available to sign authorization" ) ;
390+ } ;
391+ let signature = signer. sign_hash ( & auth. signature_hash ( ) ) . await ?;
392+
393+ auth. into_signed ( signature)
394+ }
395+ CliAuthorizationList :: Signed ( auth) => auth,
400396 } ;
397+
401398 self . tx . set_authorization_list ( vec ! [ auth] ) ;
402399
403400 Ok ( ( ) )
0 commit comments