diff --git a/Cargo.lock b/Cargo.lock index 9491b873fa..882cbe5c8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4541,6 +4541,7 @@ dependencies = [ "reth-rpc-engine-api", "reth-rpc-types", "reth-transaction-pool", + "secp256k1 0.24.3", "serde", "serde_json", "thiserror", diff --git a/crates/net/rpc/Cargo.toml b/crates/net/rpc/Cargo.toml index 896f5755fb..9e5f4f9d62 100644 --- a/crates/net/rpc/Cargo.toml +++ b/crates/net/rpc/Cargo.toml @@ -28,6 +28,11 @@ async-trait = "0.1" tokio = { version = "1", features = ["sync"] } # misc +secp256k1 = { version = "0.24", features = [ + "global-context", + "rand-std", + "recovery", +] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" diff --git a/crates/net/rpc/src/eth/api/mod.rs b/crates/net/rpc/src/eth/api/mod.rs index eba7be2860..847eef925a 100644 --- a/crates/net/rpc/src/eth/api/mod.rs +++ b/crates/net/rpc/src/eth/api/mod.rs @@ -3,6 +3,7 @@ //! The entire implementation of the namespace is quite large, hence it is divided across several //! files. +use crate::eth::signer::EthSigner; use async_trait::async_trait; use reth_interfaces::Result; use reth_network_api::NetworkInfo; @@ -38,7 +39,8 @@ pub trait EthApiSpec: Send + Sync { /// are implemented separately in submodules. The rpc handler implementation can then delegate to /// the main impls. This way [`EthApi`] is not limited to [`jsonrpsee`] and can be used standalone /// or in other network handlers (for example ipc). -#[derive(Debug, Clone)] +#[derive(Clone)] +#[allow(missing_debug_implementations)] pub struct EthApi { /// All nested fields bundled together. inner: Arc>, @@ -47,7 +49,7 @@ pub struct EthApi { impl EthApi { /// Creates a new, shareable instance. pub fn new(client: Arc, pool: Pool, network: Network) -> Self { - let inner = EthApiInner { client, pool, network }; + let inner = EthApiInner { client, pool, network, signers: Default::default() }; Self { inner: Arc::new(inner) } } @@ -94,7 +96,6 @@ where } /// Container type `EthApi` -#[derive(Debug)] struct EthApiInner { /// The transaction pool. pool: Pool, @@ -102,4 +103,6 @@ struct EthApiInner { client: Arc, /// An interface to interact with the network network: Network, + /// All configured Signers + signers: Vec>, } diff --git a/crates/net/rpc/src/eth/mod.rs b/crates/net/rpc/src/eth/mod.rs index a1e70a12d6..29f45cb49f 100644 --- a/crates/net/rpc/src/eth/mod.rs +++ b/crates/net/rpc/src/eth/mod.rs @@ -3,6 +3,7 @@ mod api; pub(crate) mod error; mod pubsub; +mod signer; pub use api::{EthApi, EthApiSpec}; pub use pubsub::EthPubSub; diff --git a/crates/net/rpc/src/eth/signer.rs b/crates/net/rpc/src/eth/signer.rs new file mode 100644 index 0000000000..2c16e74866 --- /dev/null +++ b/crates/net/rpc/src/eth/signer.rs @@ -0,0 +1,58 @@ +//! An abstraction over ethereum signers. + +use jsonrpsee::core::RpcResult as Result; +use reth_primitives::{Address, Signature, TransactionSigned}; +use reth_rpc_types::TypedTransactionRequest; +use secp256k1::SecretKey; +use std::collections::HashMap; + +/// An Ethereum Signer used via RPC. +#[async_trait::async_trait] +pub(crate) trait EthSigner: Send + Sync { + /// Returns the available accounts for this signer. + fn accounts(&self) -> Vec
; + + /// Returns `true` whether this signer can sign for this address + fn is_signer_for(&self, addr: &Address) -> bool { + self.accounts().contains(addr) + } + + /// Returns the signature + async fn sign(&self, address: Address, message: &[u8]) -> Result; + + /// signs a transaction request using the given account in request + fn sign_transaction( + &self, + request: TypedTransactionRequest, + address: &Address, + ) -> Result; +} + +/// Holds developer keys +pub(crate) struct DevSigner { + addresses: Vec
, + accounts: HashMap, +} + +#[async_trait::async_trait] +impl EthSigner for DevSigner { + fn accounts(&self) -> Vec
{ + self.addresses.clone() + } + + fn is_signer_for(&self, addr: &Address) -> bool { + self.accounts.contains_key(addr) + } + + async fn sign(&self, _address: Address, _message: &[u8]) -> Result { + todo!() + } + + fn sign_transaction( + &self, + _request: TypedTransactionRequest, + _address: &Address, + ) -> Result { + todo!() + } +}