Skip to content
This repository has been archived by the owner on Nov 25, 2024. It is now read-only.

Commit

Permalink
feat: impl wallet_ namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
onbjerg committed Oct 4, 2024
1 parent 1f294b1 commit 886ba01
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ tracing = "0.1.0"
serde = "1"
serde_json = "1"
once_cell = "1.19"
thiserror = "1"

# misc-testing
rstest = "0.18.2"
1 change: 1 addition & 0 deletions bin/alphanet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ workspace = true

[dependencies]
alphanet-node.workspace = true
alphanet-wallet.workspace = true
tracing.workspace = true
reth-cli-util.workspace = true
reth-node-builder.workspace = true
Expand Down
22 changes: 18 additions & 4 deletions bin/alphanet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//! - `min-trace-logs`: Disables all logs below `trace` level.

use alphanet_node::{chainspec::AlphanetChainSpecParser, node::AlphaNetNode};
use alphanet_wallet::{AlphaNetWallet, AlphaNetWalletApiServer};
use clap::Parser;
use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher};
use reth_optimism_cli::Cli;
Expand Down Expand Up @@ -53,13 +54,26 @@ fn main() {
.with_components(AlphaNetNode::components(rollup_args.clone()))
.with_add_ons::<OptimismAddOns>()
.extend_rpc_modules(move |ctx| {
let sequencer_client = rollup_args
.sequencer_http
.map(|sequencer_http| SequencerClient::new(sequencer_http));

// register sequencer tx forwarder
if let Some(sequencer_http) = rollup_args.sequencer_http.clone() {
ctx.registry
.eth_api()
.set_sequencer_client(SequencerClient::new(sequencer_http))?;
if let Some(sequencer_client) = sequencer_client.clone() {
ctx.registry.eth_api().set_sequencer_client(sequencer_client)?;
}

// register alphanet wallet namespace
ctx.modules.merge_configured(
AlphaNetWallet::new(
ctx.pool().clone(),
sequencer_client.clone(),
ctx.config().chain.chain().id(),
Vec::new(),
)
.into_rpc(),
)?;

Ok(())
})
.launch_with_fn(|builder| {
Expand Down
4 changes: 4 additions & 0 deletions crates/wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ categories.workspace = true
alloy-primitives.workspace = true
alloy-rpc-types.workspace = true
jsonrpsee = { workspace = true, features = ["server", "macros"] }
reth-transaction-pool.workspace = true
reth-optimism-rpc.workspace = true
serde = { workspace = true, features = ["derive"] }
thiserror.workspace = true
tracing.workspace = true

[lints]
workspace = true
94 changes: 93 additions & 1 deletion crates/wallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

#![cfg_attr(not(test), warn(unused_crate_dependencies))]

use alloy_primitives::{map::HashMap, Address, ChainId, TxHash};
use alloy_primitives::{map::HashMap, Address, ChainId, TxHash, U256};
use alloy_rpc_types::TransactionRequest;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth_optimism_rpc::SequencerClient;
use reth_transaction_pool::TransactionPool;
use serde::{Deserialize, Serialize};
use tracing::trace;

/// The capability to perform [EIP-7702][eip-7702] delegations, sponsored by the sequencer.
///
Expand Down Expand Up @@ -77,3 +80,92 @@ pub trait AlphaNetWalletApi {
#[method(name = "sendTransaction")]
fn send_transaction(&self, request: TransactionRequest) -> RpcResult<TxHash>;
}

#[derive(Debug, thiserror::Error)]
pub enum AlphaNetWalletError {
#[error("tx value not zero")]
ValueNotZero,
#[error("tx from field is set")]
FromSet,
#[error("tx nonce is set")]
NonceSet,
#[error("invalid authorization address")]
InvalidAuthorization,
#[error("the authority of an authorization item is the sequencer")]
AuthorityIsSequencer,
}

impl From<AlphaNetWalletError> for jsonrpsee::types::error::ErrorObject<'static> {
fn from(error: AlphaNetWalletError) -> Self {
jsonrpsee::types::error::ErrorObject::owned::<()>(
jsonrpsee::types::error::INVALID_PARAMS_CODE,
error.to_string(),
None,
)
}
}

pub struct AlphaNetWallet<Pool> {
pool: Pool,
sequencer_client: Option<SequencerClient>,
capabilities: WalletCapabilities,
}

impl<Pool> AlphaNetWallet<Pool> {
pub fn new(
pool: Pool,
sequencer_client: Option<SequencerClient>,
chain_id: ChainId,
valid_designations: Vec<Address>,
) -> Self {
let mut caps = HashMap::default();
caps.insert(
chain_id,
Capabilities { delegation: DelegationCapability { addresses: valid_designations } },
);

Self { pool, sequencer_client, capabilities: WalletCapabilities(caps) }
}
}

impl<Pool> AlphaNetWalletApiServer for AlphaNetWallet<Pool>
where
Pool: TransactionPool + Clone + 'static,
{
fn get_capabilities(&self) -> RpcResult<WalletCapabilities> {
trace!(target: "rpc::wallet", "Serving wallet_getCapabilities");
Ok(self.capabilities.clone())
}

fn send_transaction(&self, request: TransactionRequest) -> RpcResult<TxHash> {
trace!(target: "rpc::wallet", ?request, "Serving wallet_sendTransaction");

// reject transactions that have a non-zero value to prevent draining the sequencer.
if request.value.is_some_and(|val| val > U256::ZERO) {
return Err(AlphaNetWalletError::ValueNotZero.into());
}

// reject transactions that have from set, as this will be the sequencer.
if request.from.is_some() {
return Err(AlphaNetWalletError::FromSet.into());
}

// reject transaction requests that have nonce set, as this is managed by the sequencer.
if request.nonce.is_some() {
return Err(AlphaNetWalletError::NonceSet.into());
}
// set nonce

if let Some(authorizations) = request.authorization_list {
// todo: check auth.address is valid
// todo: disallow eip-7702 item containing sequencer addr
if authorizations.iter().any(|auth| false) {
// reject, invalid contract
}
}

// build and sign
// add to pool, or send to sequencer
todo!()
}
}

0 comments on commit 886ba01

Please sign in to comment.