@@ -7,6 +7,7 @@ use alloy_rpc_types::{AccessList, TransactionInputKind, TransactionRequest};
77use alloy_serde:: { OtherFields , WithOtherFields } ;
88use derive_more:: { AsMut , AsRef , From , Into } ;
99use op_alloy_consensus:: { DEPOSIT_TX_TYPE_ID , TxDeposit } ;
10+ use op_revm:: transaction:: deposit:: DepositTransactionParts ;
1011use serde:: { Deserialize , Serialize } ;
1112
1213use super :: { FoundryTxEnvelope , FoundryTxType , FoundryTypedTx } ;
@@ -51,11 +52,6 @@ impl FoundryTransactionRequest {
5152 self . as_ref ( ) . transaction_type == Some ( DEPOSIT_TX_TYPE_ID )
5253 }
5354
54- /// Helper to access [`FoundryTransactionRequest`] custom fields
55- pub fn get_other_field < T : serde:: de:: DeserializeOwned > ( & self , key : & str ) -> Option < T > {
56- self . as_ref ( ) . other . get_deserialized :: < T > ( key) . transpose ( ) . ok ( ) . flatten ( )
57- }
58-
5955 /// Returns the minimal transaction type this request can be converted into based on the fields
6056 /// that are set. See [`TransactionRequest::preferred_type`].
6157 pub fn preferred_type ( & self ) -> FoundryTxType {
@@ -85,17 +81,7 @@ impl FoundryTransactionRequest {
8581 /// Check if all necessary keys are present to build a Deposit transaction, returning a list of
8682 /// keys that are missing.
8783 pub fn complete_deposit ( & self ) -> Result < ( ) , Vec < & ' static str > > {
88- let mut missing = Vec :: new ( ) ;
89- if self . get_other_field :: < B256 > ( "sourceHash" ) . is_none ( ) {
90- missing. push ( "sourceHash" ) ;
91- }
92- if self . get_other_field :: < u128 > ( "mint" ) . is_none ( ) {
93- missing. push ( "mint" ) ;
94- }
95- if self . get_other_field :: < bool > ( "isSystemTx" ) . is_none ( ) {
96- missing. push ( "isSystemTx" ) ;
97- }
98- if missing. is_empty ( ) { Ok ( ( ) ) } else { Err ( missing) }
84+ get_deposit_tx_parts ( & self . as_ref ( ) . other ) . map ( |_| ( ) )
9985 }
10086
10187 /// Return the tx type this request can be built as. Computed by checking
@@ -141,19 +127,15 @@ impl FoundryTransactionRequest {
141127 /// types.
142128 pub fn build_typed_tx ( self ) -> Result < FoundryTypedTx , Self > {
143129 // Handle deposit transactions
144- if let ( Some ( source_hash) , Some ( mint) , Some ( is_system_transaction) ) = (
145- self . get_other_field :: < B256 > ( "sourceHash" ) ,
146- self . get_other_field :: < U256 > ( "mint" ) . map ( |m| m. to :: < u128 > ( ) ) ,
147- self . get_other_field :: < bool > ( "isSystemTx" ) ,
148- ) {
130+ if let Ok ( deposit_tx_parts) = get_deposit_tx_parts ( & self . as_ref ( ) . other ) {
149131 Ok ( FoundryTypedTx :: Deposit ( TxDeposit {
150132 from : self . from ( ) . unwrap_or_default ( ) ,
151- source_hash,
133+ source_hash : deposit_tx_parts . source_hash ,
152134 to : self . kind ( ) . unwrap_or_default ( ) ,
153- mint,
135+ mint : deposit_tx_parts . mint . unwrap_or_default ( ) ,
154136 value : self . value ( ) . unwrap_or_default ( ) ,
155137 gas_limit : self . gas_limit ( ) . unwrap_or_default ( ) ,
156- is_system_transaction,
138+ is_system_transaction : deposit_tx_parts . is_system_transaction ,
157139 input : self . input ( ) . cloned ( ) . unwrap_or_default ( ) ,
158140 } ) )
159141 } else if self . as_ref ( ) . has_eip4844_fields ( ) && self . as_ref ( ) . blob_sidecar ( ) . is_none ( ) {
@@ -336,11 +318,7 @@ impl TransactionBuilder<FoundryNetwork> for FoundryTransactionRequest {
336318 }
337319
338320 fn can_build ( & self ) -> bool {
339- let deposit = self . get_other_field :: < B256 > ( "sourceHash" ) . is_some ( )
340- && self . get_other_field :: < u128 > ( "mint" ) . is_some ( )
341- && self . get_other_field :: < bool > ( "isSystemTx" ) . is_some ( ) ;
342-
343- self . as_ref ( ) . can_build ( ) || deposit
321+ self . as_ref ( ) . can_build ( ) || get_deposit_tx_parts ( & self . as_ref ( ) . other ) . is_ok ( )
344322 }
345323
346324 fn output_tx_type ( & self ) -> FoundryTxType {
@@ -406,3 +384,37 @@ impl TransactionBuilder<FoundryNetwork> for FoundryTransactionRequest {
406384 Ok ( wallet. sign_request ( self ) . await ?)
407385 }
408386}
387+
388+ /// Converts `OtherFields` to `DepositTransactionParts`, produces error with missing fields
389+ pub fn get_deposit_tx_parts (
390+ other : & OtherFields ,
391+ ) -> Result < DepositTransactionParts , Vec < & ' static str > > {
392+ let mut missing = Vec :: new ( ) ;
393+ let source_hash =
394+ other. get_deserialized :: < B256 > ( "sourceHash" ) . transpose ( ) . ok ( ) . flatten ( ) . unwrap_or_else (
395+ || {
396+ missing. push ( "sourceHash" ) ;
397+ Default :: default ( )
398+ } ,
399+ ) ;
400+ let mint = other
401+ . get_deserialized :: < U256 > ( "mint" )
402+ . transpose ( )
403+ . unwrap_or_else ( |_| {
404+ missing. push ( "mint" ) ;
405+ Default :: default ( )
406+ } )
407+ . map ( |value| value. to :: < u128 > ( ) ) ;
408+ let is_system_transaction =
409+ other. get_deserialized :: < bool > ( "isSystemTx" ) . transpose ( ) . ok ( ) . flatten ( ) . unwrap_or_else (
410+ || {
411+ missing. push ( "isSystemTx" ) ;
412+ Default :: default ( )
413+ } ,
414+ ) ;
415+ if missing. is_empty ( ) {
416+ Ok ( DepositTransactionParts { source_hash, mint, is_system_transaction } )
417+ } else {
418+ Err ( missing)
419+ }
420+ }
0 commit comments