arb_rpc/
transaction.rs

1//! Arbitrum transaction request and conversion types.
2
3use alloy_consensus::{error::ValueError, SignableTransaction};
4use alloy_evm::rpc::TryIntoTxEnv;
5use alloy_primitives::Signature;
6use alloy_rpc_types_eth::request::TransactionRequest;
7use arb_primitives::ArbTransactionSigned;
8use reth_rpc_convert::{SignTxRequestError, SignableTxRequest, TryIntoSimTx};
9use serde::{Deserialize, Serialize};
10
11/// Arbitrum transaction request wrapping the standard Ethereum transaction request.
12///
13/// This newtype allows implementing Arbitrum-specific RPC traits while
14/// delegating serialization and most behavior to the inner type.
15#[derive(Clone, Debug, Serialize, Deserialize)]
16#[serde(transparent)]
17pub struct ArbTransactionRequest(pub TransactionRequest);
18
19impl AsRef<TransactionRequest> for ArbTransactionRequest {
20    fn as_ref(&self) -> &TransactionRequest {
21        &self.0
22    }
23}
24
25impl AsMut<TransactionRequest> for ArbTransactionRequest {
26    fn as_mut(&mut self) -> &mut TransactionRequest {
27        &mut self.0
28    }
29}
30
31impl SignableTxRequest<ArbTransactionSigned> for ArbTransactionRequest {
32    async fn try_build_and_sign(
33        self,
34        signer: impl alloy_network::TxSigner<Signature> + Send,
35    ) -> Result<ArbTransactionSigned, SignTxRequestError> {
36        // Build a standard typed transaction, sign it, then wrap as Arbitrum.
37        let mut tx = self
38            .0
39            .build_typed_tx()
40            .map_err(|_| SignTxRequestError::InvalidTransactionRequest)?;
41        let signature = signer.sign_transaction(&mut tx).await?;
42        let signed = tx.into_signed(signature);
43        Ok(ArbTransactionSigned::from_envelope(signed.into()))
44    }
45}
46
47impl TryIntoSimTx<ArbTransactionSigned> for ArbTransactionRequest {
48    fn try_into_sim_tx(self) -> Result<ArbTransactionSigned, ValueError<Self>> {
49        Err(ValueError::new(self, "simulate_v1 not yet supported"))
50    }
51}
52
53impl<Block: alloy_evm::env::BlockEnvironment> TryIntoTxEnv<arb_evm::ArbTransaction, Block>
54    for ArbTransactionRequest
55{
56    type Err = alloy_evm::rpc::EthTxEnvError;
57
58    fn try_into_tx_env<Spec>(
59        self,
60        evm_env: &alloy_evm::EvmEnv<Spec, Block>,
61    ) -> Result<arb_evm::ArbTransaction, Self::Err> {
62        let tx_env = self.0.try_into_tx_env(evm_env)?;
63        Ok(arb_evm::ArbTransaction(tx_env))
64    }
65}