Skip to main content

reth_rpc_traits/
signable.rs

1use core::{fmt::Debug, future::Future};
2
3use alloy_consensus::{EthereumTxEnvelope, SignableTransaction, TxEip4844};
4use alloy_network::TxSigner;
5use alloy_primitives::Signature;
6use alloy_rpc_types_eth::TransactionRequest;
7
8/// Error for [`SignableTxRequest`] trait.
9#[derive(Debug, thiserror::Error)]
10pub enum SignTxRequestError {
11    /// The transaction request is invalid.
12    #[error("invalid transaction request")]
13    InvalidTransactionRequest,
14
15    /// The signer is not supported.
16    #[error(transparent)]
17    SignerNotSupported(#[from] alloy_signer::Error),
18}
19
20/// An abstraction over transaction requests that can be signed.
21pub trait SignableTxRequest<T>: Send + Sync + 'static {
22    /// Attempts to build a transaction request and sign it with the given signer.
23    fn try_build_and_sign(
24        self,
25        signer: impl TxSigner<Signature> + Send,
26    ) -> impl Future<Output = Result<T, SignTxRequestError>> + Send;
27}
28
29impl SignableTxRequest<EthereumTxEnvelope<TxEip4844>> for TransactionRequest {
30    async fn try_build_and_sign(
31        self,
32        signer: impl TxSigner<Signature> + Send,
33    ) -> Result<EthereumTxEnvelope<TxEip4844>, SignTxRequestError> {
34        let mut tx =
35            self.build_typed_tx().map_err(|_| SignTxRequestError::InvalidTransactionRequest)?;
36        let signature = signer.sign_transaction(&mut tx).await?;
37        Ok(tx.into_signed(signature).into())
38    }
39}