From d6961615ec93355243bf9d0d708ddd78ad033e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Wed, 26 Nov 2025 17:18:07 -0300 Subject: [PATCH 1/4] add helper function for the batch number endpoint --- crates/l2/networking/rpc/clients.rs | 26 ++++++++++++++++++++- crates/networking/rpc/clients/eth/errors.rs | 12 ++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 386fd58b4a7..94445740e28 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -14,7 +14,10 @@ use ethrex_rpc::{ EthClientError, eth::{ RpcResponse, - errors::{GetBaseFeeVaultAddressError, GetBatchByNumberError, GetMessageProofError}, + errors::{ + GetBaseFeeVaultAddressError, GetBatchByNumberError, GetBatchNumberError, + GetMessageProofError, + }, }, }, utils::RpcRequest, @@ -55,6 +58,27 @@ pub async fn get_batch_by_number( } } +pub async fn get_batch_number(client: &EthClient) -> Result { + let request = RpcRequest::new("ethrex_batchNumber", None); + + match client.send_request(request).await? { + RpcResponse::Success(result) => { + let batch_number_hex: String = serde_json::from_value(result.result) + .map_err(GetBatchNumberError::SerdeJSONError) + .map_err(EthClientError::from)?; + let hex_str = batch_number_hex + .strip_prefix("0x") + .unwrap_or(&batch_number_hex); + u64::from_str_radix(hex_str, 16) + .map_err(GetBatchNumberError::ParseIntError) + .map_err(EthClientError::from) + } + RpcResponse::Error(error_response) => { + Err(GetBatchNumberError::RPCError(error_response.error.message).into()) + } + } +} + pub async fn get_base_fee_vault_address( client: &EthClient, block: BlockIdentifier, diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index 98b2d5febae..a77fd661ddc 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -65,6 +65,8 @@ pub enum EthClientError { FailedToGetTxPool(#[from] TxPoolContentError), #[error("ethrex_getBatchByNumber request error: {0}")] GetBatchByNumberError(#[from] GetBatchByNumberError), + #[error("ethrex_batchNumber request error: {0}")] + GetBatchNumberError(#[from] GetBatchNumberError), #[error("ethrex_getBlobBaseFee request error: {0}")] GetBlobBaseFeeError(#[from] GetBlobBaseFeeRequestError), #[error("All RPC calls failed")] @@ -327,6 +329,16 @@ pub enum GetBatchByNumberError { RPCError(String), } +#[derive(Debug, thiserror::Error)] +pub enum GetBatchNumberError { + #[error("{0}")] + SerdeJSONError(#[from] serde_json::Error), + #[error("{0}")] + RPCError(String), + #[error("{0}")] + ParseIntError(#[from] std::num::ParseIntError), +} + #[derive(Debug, thiserror::Error)] pub enum GetEthConfigError { #[error("{0}")] From 32fe10c0b4e53c3d594b0acf746a19ac22f4ccae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Thu, 27 Nov 2025 11:47:35 -0300 Subject: [PATCH 2/4] add send transaction for ethrex --- crates/l2/networking/rpc/clients.rs | 33 +++++++++++++++++++++ crates/networking/rpc/clients/eth/errors.rs | 12 ++++++++ 2 files changed, 45 insertions(+) diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 94445740e28..87a1c03bc01 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -1,12 +1,17 @@ +use std::str::FromStr; + use crate::l2::batch::RpcBatch; +use bytes::Bytes; use ethrex_common::Address; use ethrex_common::H256; use ethrex_common::U256; +use ethrex_common::types::AuthorizationList; use ethrex_l2_common::l1_messages::L1MessageProof; use ethrex_rpc::clients::eth::errors::GetL1BlobBaseFeeRequestError; use ethrex_rpc::clients::eth::errors::GetL1FeeVaultAddressError; use ethrex_rpc::clients::eth::errors::GetOperatorFeeError; use ethrex_rpc::clients::eth::errors::GetOperatorFeeVaultAddressError; +use ethrex_rpc::clients::eth::errors::SendEthrexTransactionError; use ethrex_rpc::types::block_identifier::BlockIdentifier; use ethrex_rpc::{ EthClient, @@ -163,3 +168,31 @@ pub async fn get_l1_blob_base_fee_per_gas( } } } + +pub async fn send_ethrex_transaction( + client: &EthClient, + to: Address, + data: Bytes, + authorization_list: Option, +) -> Result { + let payload = json!({ + "to": format!("{to:#x}"), + "data": format!("0x{}", hex::encode(data)), + "authorizationList": authorization_list, + }); + let request = RpcRequest::new("ethrex_sendTransaction", Some(vec![payload])); + + match client.send_request(request).await? { + RpcResponse::Success(result) => { + let tx_hash_str: String = serde_json::from_value(result.result) + .map_err(SendEthrexTransactionError::SerdeJSONError) + .map_err(EthClientError::from)?; + H256::from_str(&tx_hash_str) + .map_err(|e| SendEthrexTransactionError::ParseHashError(e.to_string())) + .map_err(EthClientError::from) + } + RpcResponse::Error(error_response) => { + Err(SendEthrexTransactionError::RPCError(error_response.error.message).into()) + } + } +} diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index a77fd661ddc..6f8ade19ffc 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -85,6 +85,8 @@ pub enum EthClientError { GetL1FeeVaultAddressError(#[from] GetL1FeeVaultAddressError), #[error("ethrex_getL1BlobBaseFee request error: {0}")] GetL1BlobBaseFeeError(#[from] GetL1BlobBaseFeeRequestError), + #[error("ethrex_sendTransaction request error: {0}")] + GetL1BlobBaseFeeError(#[from] SendEthrexTransactionError), } #[derive(Debug, thiserror::Error)] @@ -386,3 +388,13 @@ pub enum GetL1BlobBaseFeeRequestError { #[error("{0}")] ParseIntError(#[from] std::num::ParseIntError), } + +#[derive(Debug, thiserror::Error)] +pub enum SendEthrexTransactionError { + #[error("{0}")] + SerdeJSONError(#[from] serde_json::Error), + #[error("{0}")] + RPCError(String), + #[error("{0}")] + ParseHashError(String), +} From 0562b2495dbc9d5153032a89a8bf307669afd599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Thu, 27 Nov 2025 11:53:21 -0300 Subject: [PATCH 3/4] fix compile --- crates/networking/rpc/clients/eth/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/networking/rpc/clients/eth/errors.rs b/crates/networking/rpc/clients/eth/errors.rs index 6f8ade19ffc..7210f15a72c 100644 --- a/crates/networking/rpc/clients/eth/errors.rs +++ b/crates/networking/rpc/clients/eth/errors.rs @@ -86,7 +86,7 @@ pub enum EthClientError { #[error("ethrex_getL1BlobBaseFee request error: {0}")] GetL1BlobBaseFeeError(#[from] GetL1BlobBaseFeeRequestError), #[error("ethrex_sendTransaction request error: {0}")] - GetL1BlobBaseFeeError(#[from] SendEthrexTransactionError), + SendEthrexTransactionError(#[from] SendEthrexTransactionError), } #[derive(Debug, thiserror::Error)] From ea443366ce4506be868a45b0eee2361b7834ef0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Paradelo?= Date: Thu, 27 Nov 2025 14:49:14 -0300 Subject: [PATCH 4/4] add type --- crates/common/types/transaction.rs | 4 +++- crates/l2/networking/rpc/clients.rs | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/common/types/transaction.rs b/crates/common/types/transaction.rs index d080b0d26cb..09c5727f234 100644 --- a/crates/common/types/transaction.rs +++ b/crates/common/types/transaction.rs @@ -7,7 +7,9 @@ use ethrex_crypto::keccak::keccak_hash; pub use mempool::MempoolTransaction; use rkyv::{Archive, Deserialize as RDeserialize, Serialize as RSerialize}; use serde::{Serialize, ser::SerializeStruct}; -pub use serde_impl::{AccessListEntry, GenericTransaction, GenericTransactionError}; +pub use serde_impl::{ + AccessListEntry, AuthorizationTupleEntry, GenericTransaction, GenericTransactionError, +}; /// The serialized length of a default eip1559 transaction pub const EIP1559_DEFAULT_SERIALIZED_LENGTH: usize = 15; diff --git a/crates/l2/networking/rpc/clients.rs b/crates/l2/networking/rpc/clients.rs index 87a1c03bc01..1f7273569b6 100644 --- a/crates/l2/networking/rpc/clients.rs +++ b/crates/l2/networking/rpc/clients.rs @@ -5,7 +5,7 @@ use bytes::Bytes; use ethrex_common::Address; use ethrex_common::H256; use ethrex_common::U256; -use ethrex_common::types::AuthorizationList; +use ethrex_common::types::{AuthorizationList, AuthorizationTupleEntry}; use ethrex_l2_common::l1_messages::L1MessageProof; use ethrex_rpc::clients::eth::errors::GetL1BlobBaseFeeRequestError; use ethrex_rpc::clients::eth::errors::GetL1FeeVaultAddressError; @@ -27,6 +27,7 @@ use ethrex_rpc::{ }, utils::RpcRequest, }; +use hex; use serde_json::json; pub async fn get_message_proof( @@ -175,6 +176,12 @@ pub async fn send_ethrex_transaction( data: Bytes, authorization_list: Option, ) -> Result { + let authorization_list = authorization_list.map(|list| { + list.iter() + .map(AuthorizationTupleEntry::from) + .collect::>() + }); + let payload = json!({ "to": format!("{to:#x}"), "data": format!("0x{}", hex::encode(data)),