diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index 8b4368a121..6fdd477dd3 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,8 +1,8 @@ //! Common conversions from alloy types. use crate::{ - Block, Header, Transaction, TransactionSigned, TxEip1559, TxEip2930, TxEip4844, TxLegacy, - TxType, + transaction::extract_chain_id, Block, Header, Signature, Transaction, TransactionSigned, + TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxLegacy, TxType, }; use alloy_primitives::TxKind; use alloy_rlp::Error as RlpError; @@ -115,7 +115,7 @@ impl TryFrom for Transaction { return Err(ConversionError::Eip2718Error( RlpError::Custom("EIP-1559 fields are present in a legacy transaction") .into(), - )) + )); } Ok(Transaction::Legacy(TxLegacy { chain_id: tx.chain_id, @@ -199,3 +199,64 @@ impl TryFrom for Transaction { } } } + +impl TryFrom for TransactionSigned { + type Error = alloy_rpc_types::ConversionError; + + fn try_from(tx: alloy_rpc_types::Transaction) -> Result { + use alloy_rpc_types::ConversionError; + + let signature = tx.signature.ok_or(ConversionError::MissingSignature)?; + let transaction: Transaction = tx.try_into()?; + + Ok(TransactionSigned::from_transaction_and_signature( + transaction.clone(), + Signature { + r: signature.r, + s: signature.s, + odd_y_parity: if let Some(y_parity) = signature.y_parity { + y_parity.0 + } else { + match transaction.tx_type() { + // If the transaction type is Legacy, adjust the v component of the + // signature according to the Ethereum specification + TxType::Legacy => { + extract_chain_id(signature.v.to()) + .map_err(|_| ConversionError::InvalidSignature)? + .0 + } + _ => !signature.v.is_zero(), + } + }, + }, + )) + } +} + +impl TryFrom for TransactionSignedEcRecovered { + type Error = alloy_rpc_types::ConversionError; + + fn try_from(tx: alloy_rpc_types::Transaction) -> Result { + use alloy_rpc_types::ConversionError; + + let transaction: TransactionSigned = tx.try_into()?; + + transaction.try_into_ecrecovered().map_err(|_| ConversionError::InvalidSignature) + } +} + +impl TryFrom for Signature { + type Error = alloy_rpc_types::ConversionError; + + fn try_from(signature: alloy_rpc_types::Signature) -> Result { + use alloy_rpc_types::ConversionError; + + let odd_y_parity = if let Some(y_parity) = signature.y_parity { + y_parity.0 + } else { + extract_chain_id(signature.v.to()).map_err(|_| ConversionError::InvalidSignature)?.0 + }; + + Ok(Self { r: signature.r, s: signature.s, odd_y_parity }) + } +} diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 3117615e84..c441a32774 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -1615,42 +1615,6 @@ impl IntoRecoveredTransaction for TransactionSignedEcRecovered { } } -#[cfg(feature = "alloy-compat")] -impl TryFrom for TransactionSignedEcRecovered { - type Error = alloy_rpc_types::ConversionError; - - fn try_from(tx: alloy_rpc_types::Transaction) -> Result { - use alloy_rpc_types::ConversionError; - let signature = tx.signature.ok_or(ConversionError::MissingSignature)?; - - let transaction: Transaction = tx.try_into()?; - - TransactionSigned::from_transaction_and_signature( - transaction.clone(), - Signature { - r: signature.r, - s: signature.s, - odd_y_parity: if let Some(y_parity) = signature.y_parity { - y_parity.0 - } else { - match transaction.tx_type() { - // If the transaction type is Legacy, adjust the v component of the - // signature according to the Ethereum specification - TxType::Legacy => { - extract_chain_id(signature.v.to()) - .map_err(|_| ConversionError::InvalidSignature)? - .0 - } - _ => !signature.v.is_zero(), - } - }, - }, - ) - .try_into_ecrecovered() - .map_err(|_| ConversionError::InvalidSignature) - } -} - #[cfg(test)] mod tests { use crate::{