11use anyhow:: { bail, Result } ;
22use clap:: Args ;
33use dojo_utils:: { FeeConfig , TxnAction , TxnConfig } ;
4+ use starknet:: core:: types:: TransactionFinalityStatus ;
45
56#[ derive( Debug , Clone , Args , Default ) ]
67#[ command( next_help_heading = "Transaction options" ) ]
@@ -62,6 +63,15 @@ pub struct TransactionOptions {
6263 #[ arg( global = true ) ]
6364 #[ arg( default_value = "10" ) ]
6465 pub max_calls : Option < usize > ,
66+
67+ #[ arg( long) ]
68+ #[ arg( help = "The finality status to wait for. Since 0.14, the nodes syncing is sometime \
69+ not fast enough to propagate the transaction to the nodes in the \
70+ PRE-CONFIRMED state. The default is ACCEPTED_ON_L2. Available options are: \
71+ PRE-CONFIRMED, ACCEPTED_ON_L2, ACCEPTED_ON_L1.") ]
72+ #[ arg( global = true ) ]
73+ #[ arg( default_value = "ACCEPTED_ON_L2" ) ]
74+ pub finality_status : Option < String > ,
6575}
6676
6777impl TransactionOptions {
@@ -89,6 +99,7 @@ impl TransactionOptions {
8999 } ,
90100 walnut : self . walnut ,
91101 max_calls : self . max_calls ,
102+ finality_status : parse_finality_status ( self . finality_status . clone ( ) ) ?,
92103 } ) ,
93104 }
94105 }
@@ -111,10 +122,33 @@ impl TryFrom<TransactionOptions> for TxnConfig {
111122 l2_gas_price : value. l2_gas_price ,
112123 } ,
113124 max_calls : value. max_calls ,
125+ finality_status : parse_finality_status ( value. finality_status . clone ( ) ) ?,
114126 } )
115127 }
116128}
117129
130+ /// Parses the finality status from a string.
131+ /// If no status is provided, the default is ACCEPTED_ON_L2.
132+ /// # Arguments
133+ ///
134+ /// * `status` - The finality status to parse.
135+ ///
136+ /// # Returns
137+ ///
138+ /// The parsed finality status.
139+ fn parse_finality_status ( status : Option < String > ) -> Result < TransactionFinalityStatus > {
140+ if let Some ( status) = status {
141+ match status. to_uppercase ( ) . as_str ( ) {
142+ "PRE_CONFIRMED" => Ok ( TransactionFinalityStatus :: PreConfirmed ) ,
143+ "ACCEPTED_ON_L2" => Ok ( TransactionFinalityStatus :: AcceptedOnL2 ) ,
144+ "ACCEPTED_ON_L1" => Ok ( TransactionFinalityStatus :: AcceptedOnL1 ) ,
145+ _ => bail ! ( "Invalid finality status: {}" , status) ,
146+ }
147+ } else {
148+ Ok ( TransactionFinalityStatus :: AcceptedOnL2 )
149+ }
150+ }
151+
118152#[ cfg( test) ]
119153mod tests {
120154 use anyhow:: Result ;
@@ -134,6 +168,7 @@ mod tests {
134168 l2_gas_price : Some ( 1_000 ) ,
135169 walnut : false ,
136170 max_calls : Some ( 10 ) ,
171+ finality_status : Some ( "PRE_CONFIRMED" . to_string ( ) ) ,
137172 } ;
138173
139174 let config: TxnConfig = opts. try_into ( ) ?;
@@ -150,6 +185,32 @@ mod tests {
150185 assert_eq ! ( config. fee_config. l2_gas, Some ( 10_000 ) ) ;
151186 assert_eq ! ( config. fee_config. l2_gas_price, Some ( 1_000 ) ) ;
152187
188+ assert_eq ! ( config. finality_status, TransactionFinalityStatus :: PreConfirmed ) ;
189+
190+ Ok ( ( ) )
191+ }
192+
193+ #[ test]
194+ fn test_parse_finality_status ( ) -> Result < ( ) > {
195+ matches ! (
196+ parse_finality_status( Some ( "PRE_CONFIRMED" . to_string( ) ) ) ,
197+ Ok ( TransactionFinalityStatus :: PreConfirmed )
198+ ) ;
199+
200+ matches ! (
201+ parse_finality_status( Some ( "ACCEPTED_ON_L2" . to_string( ) ) ) ,
202+ Ok ( TransactionFinalityStatus :: AcceptedOnL2 )
203+ ) ;
204+
205+ matches ! (
206+ parse_finality_status( Some ( "ACCEPTED_ON_L1" . to_string( ) ) ) ,
207+ Ok ( TransactionFinalityStatus :: AcceptedOnL1 )
208+ ) ;
209+
210+ matches ! ( parse_finality_status( None ) , Ok ( TransactionFinalityStatus :: AcceptedOnL2 ) ) ;
211+
212+ assert ! ( parse_finality_status( Some ( "INVALID" . to_string( ) ) ) . is_err( ) ) ;
213+
153214 Ok ( ( ) )
154215 }
155216}
0 commit comments