diff --git a/.github/assets/check_wasm.sh b/.github/assets/check_wasm.sh
index 5504cb17e6..c5639c710d 100755
--- a/.github/assets/check_wasm.sh
+++ b/.github/assets/check_wasm.sh
@@ -58,6 +58,7 @@ exclude_crates=(
reth-ress-provider
# The following are not supposed to be working
reth # all of the crates below
+ reth-alloy-provider
reth-invalid-block-hooks # reth-provider
reth-libmdbx # mdbx
reth-mdbx-sys # mdbx
diff --git a/Cargo.lock b/Cargo.lock
index 81678ab067..d6791b9088 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7142,6 +7142,34 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "reth-alloy-provider"
+version = "1.4.8"
+dependencies = [
+ "alloy-consensus",
+ "alloy-eips",
+ "alloy-network",
+ "alloy-primitives",
+ "alloy-provider",
+ "alloy-rpc-types",
+ "alloy-rpc-types-engine",
+ "reth-chainspec",
+ "reth-db-api",
+ "reth-errors",
+ "reth-execution-types",
+ "reth-node-types",
+ "reth-primitives",
+ "reth-provider",
+ "reth-prune-types",
+ "reth-stages-types",
+ "reth-storage-api",
+ "reth-trie",
+ "revm",
+ "revm-primitives",
+ "tokio",
+ "tracing",
+]
+
[[package]]
name = "reth-basic-payload-builder"
version = "1.4.8"
diff --git a/Cargo.toml b/Cargo.toml
index c51099f5b7..89086c7027 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ exclude = [".github/"]
members = [
"bin/reth-bench/",
"bin/reth/",
+ "crates/alloy-provider/",
"crates/chain-state/",
"crates/chainspec/",
"crates/cli/cli/",
@@ -319,6 +320,7 @@ codegen-units = 1
# reth
op-reth = { path = "crates/optimism/bin" }
reth = { path = "bin/reth" }
+reth-alloy-provider = { path = "crates/alloy-provider" }
reth-basic-payload-builder = { path = "crates/payload/basic" }
reth-bench = { path = "bin/reth-bench" }
reth-chain-state = { path = "crates/chain-state" }
diff --git a/crates/alloy-provider/Cargo.toml b/crates/alloy-provider/Cargo.toml
new file mode 100644
index 0000000000..6eb47e1f4d
--- /dev/null
+++ b/crates/alloy-provider/Cargo.toml
@@ -0,0 +1,48 @@
+[package]
+name = "reth-alloy-provider"
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+description = "Alloy provider implementation for reth that fetches state via RPC"
+
+[lints]
+workspace = true
+
+[dependencies]
+# reth
+reth-storage-api.workspace = true
+reth-chainspec.workspace = true
+reth-primitives.workspace = true
+reth-provider.workspace = true
+reth-errors.workspace = true
+reth-execution-types.workspace = true
+reth-prune-types.workspace = true
+reth-node-types.workspace = true
+reth-trie.workspace = true
+reth-stages-types.workspace = true
+reth-db-api.workspace = true
+
+# alloy
+alloy-provider.workspace = true
+alloy-network.workspace = true
+alloy-primitives.workspace = true
+alloy-consensus.workspace = true
+alloy-rpc-types.workspace = true
+alloy-rpc-types-engine.workspace = true
+alloy-eips.workspace = true
+
+# async
+tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] }
+
+# other
+tracing.workspace = true
+
+# revm
+revm.workspace = true
+revm-primitives.workspace = true
+
+[dev-dependencies]
+tokio = { workspace = true, features = ["rt", "macros"] }
diff --git a/crates/alloy-provider/README.md b/crates/alloy-provider/README.md
new file mode 100644
index 0000000000..37a75f1b32
--- /dev/null
+++ b/crates/alloy-provider/README.md
@@ -0,0 +1,60 @@
+# Alloy Provider for Reth
+
+This crate provides an implementation of reth's `StateProviderFactory` and related traits that fetches state data via RPC instead of from a local database.
+
+Originally created by [cakevm](https://github.com/cakevm/alloy-reth-provider).
+
+## Features
+
+- Implements `StateProviderFactory` for remote RPC state access
+- Supports Ethereum networks
+- Useful for testing without requiring a full database
+- Can be used with reth ExEx (Execution Extensions) for testing
+
+## Usage
+
+```rust
+use alloy_provider::ProviderBuilder;
+use reth_alloy_provider::AlloyRethProvider;
+use reth_ethereum_node::EthereumNode;
+
+// Initialize provider
+let provider = ProviderBuilder::new()
+ .builtin("https://eth.merkle.io")
+ .await
+ .unwrap();
+
+// Create database provider with NodeTypes
+let db_provider = AlloyRethProvider::new(provider, EthereumNode);
+
+// Get state at specific block
+let state = db_provider.state_by_block_id(BlockId::number(16148323)).unwrap();
+```
+
+## Configuration
+
+The provider can be configured with custom settings:
+
+```rust
+use reth_alloy_provider::{AlloyRethProvider, AlloyRethProviderConfig};
+use reth_ethereum_node::EthereumNode;
+
+let config = AlloyRethProviderConfig {
+ compute_state_root: true, // Enable state root computation
+};
+
+let db_provider = AlloyRethProvider::new_with_config(provider, EthereumNode, config);
+```
+
+## Technical Details
+
+The provider uses `alloy_network::AnyNetwork` for network operations, providing compatibility with various Ethereum-based networks while maintaining the expected block structure with headers.
+
+## License
+
+Licensed under either of:
+
+- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
\ No newline at end of file
diff --git a/crates/alloy-provider/src/lib.rs b/crates/alloy-provider/src/lib.rs
new file mode 100644
index 0000000000..318ecec8b2
--- /dev/null
+++ b/crates/alloy-provider/src/lib.rs
@@ -0,0 +1,1460 @@
+//! # Alloy Provider for Reth
+//!
+//! This crate provides an implementation of reth's `StateProviderFactory` and related traits
+//! that fetches state data via RPC instead of from a local database.
+//!
+//! Originally created by [cakevm](https://github.com/cakevm/alloy-reth-provider).
+//!
+//! ## Features
+//!
+//! - Implements `StateProviderFactory` for remote RPC state access
+//! - Supports Ethereum and Optimism network
+//! - Useful for testing without requiring a full database
+//! - Can be used with reth ExEx (Execution Extensions) for testing
+
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
+ html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
+ issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
+)]
+#![cfg_attr(not(test), warn(unused_crate_dependencies))]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
+
+use alloy_consensus::BlockHeader;
+use alloy_network::{primitives::HeaderResponse, BlockResponse};
+use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, TxNumber, B256, U256};
+use alloy_provider::{network::Network, Provider};
+use alloy_rpc_types::BlockId;
+use alloy_rpc_types_engine::ForkchoiceState;
+use reth_chainspec::{ChainInfo, ChainSpecProvider};
+use reth_db_api::mock::{DatabaseMock, TxMock};
+use reth_errors::ProviderError;
+use reth_node_types::{BlockTy, HeaderTy, NodeTypes, PrimitivesTy, ReceiptTy, TxTy};
+use reth_primitives::{
+ Account, Bytecode, RecoveredBlock, SealedBlock, SealedHeader, TransactionMeta,
+};
+use reth_provider::{
+ AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, CanonChainTracker,
+ CanonStateNotification, CanonStateNotifications, CanonStateSubscriptions,
+ ChainStateBlockReader, ChainStateBlockWriter, ChangeSetReader, DatabaseProviderFactory,
+ HeaderProvider, PruneCheckpointReader, ReceiptProvider, StageCheckpointReader, StateProvider,
+ StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, StorageReader,
+ TransactionVariant, TransactionsProvider,
+};
+use reth_prune_types::{PruneCheckpoint, PruneSegment};
+use reth_stages_types::{StageCheckpoint, StageId};
+use reth_storage_api::{BlockBodyIndicesProvider, DBProvider, NodePrimitivesProvider, StatsReader};
+use reth_trie::{updates::TrieUpdates, AccountProof, HashedPostState, MultiProof, TrieInput};
+use std::{
+ collections::BTreeMap,
+ future::Future,
+ ops::{RangeBounds, RangeInclusive},
+ sync::Arc,
+};
+use tokio::{runtime::Handle, sync::broadcast};
+use tracing::trace;
+
+/// Configuration for `AlloyRethProvider`
+#[derive(Debug, Clone, Default)]
+pub struct AlloyRethProviderConfig {
+ /// Whether to compute state root when creating execution outcomes
+ pub compute_state_root: bool,
+}
+
+impl AlloyRethProviderConfig {
+ /// Sets whether to compute state root when creating execution outcomes
+ pub const fn with_compute_state_root(mut self, compute: bool) -> Self {
+ self.compute_state_root = compute;
+ self
+ }
+}
+
+/// A provider implementation that uses Alloy RPC to fetch state data
+///
+/// This provider implements reth's `StateProviderFactory` and related traits,
+/// allowing it to be used as a drop-in replacement for database-backed providers
+/// in scenarios where RPC access is preferred (e.g., testing).
+///
+/// The provider type is generic over the network type N (defaulting to `AnyNetwork`),
+/// but the current implementation is specialized for `alloy_network::AnyNetwork`
+/// as it needs to access block header fields directly.
+#[derive(Clone)]
+pub struct AlloyRethProvider
+where
+ Node: NodeTypes,
+{
+ /// The underlying Alloy provider
+ provider: P,
+ /// Node types marker
+ node_types: std::marker::PhantomData,
+ /// Network marker
+ network: std::marker::PhantomData,
+ /// Broadcast channel for canon state notifications
+ canon_state_notification: broadcast::Sender>>,
+ /// Configuration for the provider
+ config: AlloyRethProviderConfig,
+ /// Cached chain spec
+ chain_spec: Arc,
+}
+
+impl std::fmt::Debug for AlloyRethProvider
{
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("AlloyRethProvider").field("config", &self.config).finish()
+ }
+}
+
+impl
AlloyRethProvider
{
+ /// Creates a new `AlloyRethProvider` with default configuration
+ pub fn new(provider: P) -> Self
+ where
+ Node::ChainSpec: Default,
+ {
+ Self::new_with_config(provider, AlloyRethProviderConfig::default())
+ }
+
+ /// Creates a new `AlloyRethProvider` with custom configuration
+ pub fn new_with_config(provider: P, config: AlloyRethProviderConfig) -> Self
+ where
+ Node::ChainSpec: Default,
+ {
+ let (canon_state_notification, _) = broadcast::channel(1);
+ Self {
+ provider,
+ node_types: std::marker::PhantomData,
+ network: std::marker::PhantomData,
+ canon_state_notification,
+ config,
+ chain_spec: Arc::new(Node::ChainSpec::default()),
+ }
+ }
+
+ /// Helper function to execute async operations in a blocking context
+ fn block_on_async(&self, fut: F) -> T
+ where
+ F: Future