mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(rpc): add anvil and hardhat and ganache trait bindings (#7495)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -377,6 +377,16 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloy-rpc-types-anvil"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/alloy-rs/alloy?rev=8cb0307#8cb0307b9bdb6cef9058d2d1a2219c8d212a7421"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-serde",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloy-rpc-types-engine"
|
||||
version = "0.1.0"
|
||||
@ -3452,7 +3462,7 @@ dependencies = [
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.6",
|
||||
"socket2 0.4.10",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@ -7300,6 +7310,7 @@ dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
"alloy-rpc-types",
|
||||
"alloy-rpc-types-anvil",
|
||||
"alloy-rpc-types-engine",
|
||||
"alloy-rpc-types-trace",
|
||||
"arbitrary",
|
||||
|
||||
@ -277,6 +277,7 @@ alloy-sol-types = "0.7.0"
|
||||
alloy-rlp = "0.3.4"
|
||||
alloy-trie = "0.3.1"
|
||||
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "8cb0307" }
|
||||
alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "8cb0307" }
|
||||
alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "8cb0307" }
|
||||
alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "8cb0307" }
|
||||
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "8cb0307" }
|
||||
|
||||
167
crates/rpc/rpc-api/src/anvil.rs
Normal file
167
crates/rpc/rpc-api/src/anvil.rs
Normal file
@ -0,0 +1,167 @@
|
||||
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
||||
|
||||
use reth_primitives::{Address, Bytes, B256, U256};
|
||||
use reth_rpc_types::{
|
||||
anvil::{Forking, Metadata, MineOptions, NodeInfo},
|
||||
Block,
|
||||
};
|
||||
|
||||
/// Anvil rpc interface.
|
||||
/// https://book.getfoundry.sh/reference/anvil/#custom-methods
|
||||
#[cfg_attr(not(feature = "client"), rpc(server, namespace = "anvil"))]
|
||||
#[cfg_attr(feature = "client", rpc(server, client, namespace = "anvil"))]
|
||||
pub trait AnvilApi {
|
||||
/// Sends transactions impersonating specific account and contract addresses.
|
||||
#[method(name = "impersonateAccount")]
|
||||
async fn anvil_impersonate_account(&self, address: Address) -> RpcResult<()>;
|
||||
|
||||
/// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
|
||||
#[method(name = "stopImpersonatingAccount")]
|
||||
async fn anvil_stop_impersonating_account(&self, address: Address) -> RpcResult<()>;
|
||||
|
||||
/// If set to true will make every account impersonated.
|
||||
#[method(name = "autoImpersonateAccount")]
|
||||
async fn anvil_auto_impersonate_account(&self, enabled: bool) -> RpcResult<()>;
|
||||
|
||||
/// Returns `true` if auto mining is enabled, and `false`.
|
||||
#[method(name = "getAutomine")]
|
||||
async fn anvil_get_automine(&self) -> RpcResult<bool>;
|
||||
|
||||
/// Mines a series of blocks.
|
||||
#[method(name = "mine")]
|
||||
async fn anvil_mine(&self, blocks: Option<U256>, interval: Option<U256>) -> RpcResult<()>;
|
||||
|
||||
/// Enables or disables, based on the single boolean argument, the automatic mining of new
|
||||
/// blocks with each new transaction submitted to the network.
|
||||
#[method(name = "setAutomine")]
|
||||
async fn anvil_set_automine(&self, enabled: bool) -> RpcResult<()>;
|
||||
|
||||
/// Sets the mining behavior to interval with the given interval (seconds).
|
||||
#[method(name = "setIntervalMining")]
|
||||
async fn anvil_set_interval_mining(&self, interval: u64) -> RpcResult<()>;
|
||||
|
||||
/// Removes transactions from the pool.
|
||||
#[method(name = "anvil_dropTransaction")]
|
||||
async fn anvil_drop_transaction(&self, tx_hash: B256) -> RpcResult<Option<B256>>;
|
||||
|
||||
/// Resets the fork to a fresh forked state, and optionally update the fork config.
|
||||
///
|
||||
/// If `forking` is `None` then this will disable forking entirely.
|
||||
#[method(name = "reset")]
|
||||
async fn anvil_reset(&self, fork: Option<Forking>) -> RpcResult<()>;
|
||||
|
||||
/// Sets the backend rpc url.
|
||||
#[method(name = "setRpcUrl")]
|
||||
async fn anvil_set_rpc_url(&self, url: String) -> RpcResult<()>;
|
||||
|
||||
/// Modifies the balance of an account.
|
||||
#[method(name = "setBalance")]
|
||||
async fn anvil_set_balance(&self, address: Address, balance: U256) -> RpcResult<()>;
|
||||
|
||||
/// Sets the code of a contract.
|
||||
#[method(name = "setCode")]
|
||||
async fn anvil_set_code(&self, address: Address, code: Bytes) -> RpcResult<()>;
|
||||
|
||||
/// Sets the nonce of an address.
|
||||
#[method(name = "setNonce")]
|
||||
async fn anvil_set_nonce(&self, address: Address, nonce: U256) -> RpcResult<()>;
|
||||
|
||||
/// Writes a single slot of the account's storage.
|
||||
#[method(name = "setStorageAt")]
|
||||
async fn anvil_set_storage_at(
|
||||
&self,
|
||||
address: Address,
|
||||
slot: U256,
|
||||
value: B256,
|
||||
) -> RpcResult<bool>;
|
||||
|
||||
/// Sets the coinbase address.
|
||||
#[method(name = "setCoinbase")]
|
||||
async fn anvil_set_coinbase(&self, address: Address) -> RpcResult<()>;
|
||||
|
||||
/// Sets the chain id.
|
||||
#[method(name = "setChainId")]
|
||||
async fn anvil_set_chain_id(&self, chain_id: u64) -> RpcResult<()>;
|
||||
|
||||
/// Enables or disable logging.
|
||||
#[method(name = "setLoggingEnabled")]
|
||||
async fn anvil_set_logging_enabled(&self, enabled: bool) -> RpcResult<()>;
|
||||
|
||||
/// Sets the minimum gas price for the node.
|
||||
#[method(name = "setMinGasPrice")]
|
||||
async fn anvil_set_min_gas_price(&self, gas_price: U256) -> RpcResult<()>;
|
||||
|
||||
/// Sets the base fee of the next block.
|
||||
#[method(name = "setNextBlockBaseFeePerGas")]
|
||||
async fn anvil_set_next_block_base_fee_per_gas(&self, base_fee: U256) -> RpcResult<()>;
|
||||
|
||||
/// Sets the minimum gas price for the node.
|
||||
#[method(name = "setTime")]
|
||||
async fn anvil_set_time(&self, timestamp: u64) -> RpcResult<u64>;
|
||||
|
||||
/// Creates a buffer that represents all state on the chain, which can be loaded to separate
|
||||
/// process by calling `anvil_loadState`.
|
||||
#[method(name = "dumpState")]
|
||||
async fn anvil_dump_state(&self) -> RpcResult<Bytes>;
|
||||
|
||||
/// Append chain state buffer to current chain.Will overwrite any conflicting addresses or
|
||||
/// storage.
|
||||
#[method(name = "loadState")]
|
||||
async fn anvil_load_state(&self, state: Bytes) -> RpcResult<bool>;
|
||||
|
||||
/// Retrieves the Anvil node configuration params.
|
||||
#[method(name = "nodeInfo")]
|
||||
async fn anvil_node_info(&self) -> RpcResult<NodeInfo>;
|
||||
|
||||
/// Retrieves metadata about the Anvil instance.
|
||||
#[method(name = "metadata")]
|
||||
async fn anvil_metadata(&self) -> RpcResult<Metadata>;
|
||||
|
||||
/// Snapshot the state of the blockchain at the current block.
|
||||
#[method(name = "snapshot")]
|
||||
async fn anvil_snapshot(&self) -> RpcResult<U256>;
|
||||
|
||||
/// Revert the state of the blockchain to a previous snapshot.
|
||||
/// Takes a single parameter, which is the snapshot id to revert to.
|
||||
#[method(name = "revert")]
|
||||
async fn anvil_revert(&self, id: U256) -> RpcResult<bool>;
|
||||
|
||||
/// Jump forward in time by the given amount of time, in seconds.
|
||||
#[method(name = "increaseTime")]
|
||||
async fn anvil_increase_time(&self, seconds: U256) -> RpcResult<i64>;
|
||||
|
||||
/// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block.
|
||||
#[method(name = "setNextBlockTimestamp")]
|
||||
async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> RpcResult<()>;
|
||||
|
||||
/// Sets the next block gas limit.
|
||||
#[method(name = "setBlockGasLimit")]
|
||||
async fn anvil_set_block_gas_limit(&self, gas_limit: U256) -> RpcResult<bool>;
|
||||
|
||||
/// Sets an interval for the block timestamp.
|
||||
#[method(name = "setBlockTimestampInterval")]
|
||||
async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> RpcResult<()>;
|
||||
|
||||
/// Sets an interval for the block timestamp.
|
||||
#[method(name = "removeBlockTimestampInterval")]
|
||||
async fn anvil_remove_block_timestamp_interval(&self) -> RpcResult<bool>;
|
||||
|
||||
/// Mine blocks, instantly and return the mined blocks.
|
||||
///
|
||||
/// This will mine the blocks regardless of the configured mining mode.
|
||||
///
|
||||
/// **Note**: This behaves exactly as `evm_mine` but returns different output, for
|
||||
/// compatibility reasons, this is a separate call since `evm_mine` is not an anvil original.
|
||||
/// and `ganache` may change the `0x0` placeholder.
|
||||
#[method(name = "mine_detailed")] // This method requires using `snake_case`.
|
||||
async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> RpcResult<Vec<Block>>;
|
||||
|
||||
/// Turn on call traces for transactions that are returned to the user when they execute a
|
||||
/// transaction (instead of just txhash/receipt).
|
||||
#[method(name = "enableTraces")]
|
||||
async fn anvil_enable_traces(&self) -> RpcResult<()>;
|
||||
|
||||
/// Removes all transactions for that address from the transaction pool.
|
||||
#[method(name = "removePoolTransactions")]
|
||||
async fn anvil_remove_pool_transactions(&self, address: Address) -> RpcResult<()>;
|
||||
}
|
||||
75
crates/rpc/rpc-api/src/ganache.rs
Normal file
75
crates/rpc/rpc-api/src/ganache.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
||||
use reth_primitives::U256;
|
||||
use reth_rpc_types::anvil::MineOptions;
|
||||
|
||||
/// Ganache rpc interface.
|
||||
/// https://github.com/trufflesuite/ganache/tree/develop/docs
|
||||
#[cfg_attr(not(feature = "client"), rpc(server, namespace = "evm"))]
|
||||
#[cfg_attr(feature = "client", rpc(server, client, namespace = "evm"))]
|
||||
pub trait GanacheApi {
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "addAccount")]
|
||||
// async fn evm_add_account(&self, address: Address, passphrase: B256) -> RpcResult<bool>;
|
||||
|
||||
/// Jump forward in time by the given amount of time, in seconds.
|
||||
///
|
||||
/// Returns the total time adjustment, in seconds.
|
||||
#[method(name = "increaseTime")]
|
||||
async fn evm_increase_time(&self, seconds: U256) -> RpcResult<i64>;
|
||||
|
||||
/// Force a single block to be mined.
|
||||
///
|
||||
/// Mines a block independent of whether or not mining is started or stopped. Will mine an empty
|
||||
/// block if there are no available transactions to mine.
|
||||
///
|
||||
/// Returns "0x0". May return additional meta-data in the future.
|
||||
#[method(name = "mine")]
|
||||
async fn evm_mine(&self, opts: Option<MineOptions>) -> RpcResult<String>;
|
||||
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "removeAccount")]
|
||||
// async fn evm_remove_account(address: Address, passphrase: B256) -> RpcResult<bool>;
|
||||
|
||||
/// Revert the state of the blockchain to a previous snapshot. Takes a single parameter, which
|
||||
/// is the snapshot id to revert to. This deletes the given snapshot, as well as any snapshots
|
||||
/// taken after (e.g.: reverting to id 0x1 will delete snapshots with ids 0x1, 0x2, etc.).
|
||||
///
|
||||
/// Reutnrs `true` if a snapshot was reverted, otherwise `false`.
|
||||
#[method(name = "revert")]
|
||||
async fn evm_revert(&self, snapshot_id: U256) -> RpcResult<bool>;
|
||||
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "setAccountBalance")]
|
||||
// async fn evm_set_account_balance(address: Address, balance: U256) -> RpcResult<bool>;
|
||||
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "setAccountCode")]
|
||||
// async fn evm_set_account_code(address: Address, code: Bytes) -> RpcResult<bool>;
|
||||
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "setAccountNonce")]
|
||||
// async fn evm_set_account_nonce(address: Address, nonce: U256) -> RpcResult<bool>;
|
||||
|
||||
// TODO Ganache is deprecated and this method is not implemented by Anvil and Hardhat.
|
||||
// #[method(name = "setAccountStorageAt")]
|
||||
// async fn evm_set_account_storage_at(address: Address, slot: U256, value: B256) ->
|
||||
// RpcResult<bool>;
|
||||
|
||||
/// Sets the internal clock time to the given timestamp.
|
||||
///
|
||||
/// **Warning** This will allow you to move backwards in time, which may cause new blocks to
|
||||
/// appear to be mined before old blocks. This will result in an invalid state.
|
||||
///
|
||||
/// Returns the amount of seconds between the given timestamp and now.
|
||||
#[method(name = "setTime")]
|
||||
async fn evm_set_time(&self, timestamp: u64) -> RpcResult<bool>;
|
||||
|
||||
/// Snapshot the state of the blockchain at the current block. Takes no parameters. Returns the
|
||||
/// id of the snapshot that was created. A snapshot can only be reverted once. After a
|
||||
/// successful evm_revert, the same snapshot id cannot be used again. Consider creating a new
|
||||
/// snapshot after each evm_revert if you need to revert to the same point multiple times.
|
||||
///
|
||||
/// Returns the hex-encoded identifier for this snapshot.
|
||||
#[method(name = "snapshot")]
|
||||
async fn evm_snapshot(&self) -> RpcResult<U256>;
|
||||
}
|
||||
83
crates/rpc/rpc-api/src/hardhat.rs
Normal file
83
crates/rpc/rpc-api/src/hardhat.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
||||
use reth_primitives::{Address, Bytes, B256, U256};
|
||||
use reth_rpc_types::anvil::{Forking, Metadata};
|
||||
|
||||
/// Hardhat rpc interface.
|
||||
/// https://hardhat.org/hardhat-network/docs/reference#hardhat-network-methods
|
||||
#[cfg_attr(not(feature = "client"), rpc(server, namespace = "hardhat"))]
|
||||
#[cfg_attr(feature = "client", rpc(server, client, namespace = "hardhat"))]
|
||||
pub trait HardhatApi {
|
||||
/// Removes the given transaction from the mempool, if it exists.
|
||||
///
|
||||
/// Returns `true` if successful, otherwise `false`.
|
||||
#[method(name = "hardhat_dropTransaction")]
|
||||
async fn hardhat_drop_transaction(&self, tx_hash: B256) -> RpcResult<bool>;
|
||||
|
||||
/// Allows Hardhat Network to sign transactions as the given address.
|
||||
#[method(name = "impersonateAccount")]
|
||||
async fn hardhat_impersonate_account(&self, address: Address) -> RpcResult<()>;
|
||||
|
||||
/// Returns `true` if automatic mining is enabled, and `false` otherwise.
|
||||
#[method(name = "getAutomine")]
|
||||
async fn hardhat_get_automine(&self) -> RpcResult<bool>;
|
||||
|
||||
/// Returns an object with metadata about the instance of the Hardhat network.
|
||||
#[method(name = "metadata")]
|
||||
async fn hardhat_metadata(&self) -> RpcResult<Metadata>;
|
||||
|
||||
/// Mines a specified number of blocks at a given interval.
|
||||
#[method(name = "mine")]
|
||||
async fn hardhat_mine(&self, blocks: Option<U256>, interval: Option<U256>) -> RpcResult<()>;
|
||||
|
||||
/// Resets back to a fresh forked state, fork from another block number or disable forking.
|
||||
#[method(name = "reset")]
|
||||
async fn hardhat_reset(&self, fork: Option<Forking>) -> RpcResult<()>;
|
||||
|
||||
/// Sets the balance for the given address.
|
||||
#[method(name = "setBalance")]
|
||||
async fn hardhat_set_balance(&self, address: Address, balance: U256) -> RpcResult<()>;
|
||||
|
||||
/// Modifies the bytecode stored at an account's address.
|
||||
#[method(name = "setCode")]
|
||||
async fn hardhat_set_code(&self, address: Address, code: Bytes) -> RpcResult<()>;
|
||||
|
||||
/// Sets the coinbase address to be used in new blocks.
|
||||
#[method(name = "setCoinbase")]
|
||||
async fn hardhat_set_coinbase(&self, address: Address) -> RpcResult<()>;
|
||||
|
||||
/// Enables or disables logging.
|
||||
#[method(name = "setLoggingEnabled")]
|
||||
async fn hardhat_set_logging_enabled(&self, enabled: bool) -> RpcResult<()>;
|
||||
|
||||
/// Changes the minimum gas price accepted by the network (in wei).
|
||||
#[method(name = "setMinGasPrice")]
|
||||
async fn hardhat_set_min_gas_price(&self, gas_price: U256) -> RpcResult<()>;
|
||||
|
||||
/// Sets the base fee of the next block.
|
||||
#[method(name = "setNextBlockBaseFeePerGas")]
|
||||
async fn hardhat_set_next_block_base_fee_per_gas(
|
||||
&self,
|
||||
base_fee_per_gas: U256,
|
||||
) -> RpcResult<()>;
|
||||
|
||||
/// Sets the `PREVRANDAO` value of the next block.
|
||||
#[method(name = "setPrevRandao")]
|
||||
async fn hardhat_set_prev_randao(&self, prev_randao: B256) -> RpcResult<()>;
|
||||
|
||||
/// Modifies an account's nonce by overwriting it.
|
||||
#[method(name = "setNonce")]
|
||||
async fn hardhat_set_nonce(&self, address: Address, nonce: U256) -> RpcResult<()>;
|
||||
|
||||
/// Writes a single position of an account's storage.
|
||||
#[method(name = "setStorageAt")]
|
||||
async fn hardhat_set_storage_at(
|
||||
&self,
|
||||
address: Address,
|
||||
slot: U256,
|
||||
value: B256,
|
||||
) -> RpcResult<()>;
|
||||
|
||||
/// Stops impersonating the given address.
|
||||
#[method(name = "stopImpersonatingAccount")]
|
||||
async fn hardhat_stop_impersonating_account(&self, address: Address) -> RpcResult<()>;
|
||||
}
|
||||
@ -15,12 +15,15 @@
|
||||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
||||
|
||||
mod admin;
|
||||
mod anvil;
|
||||
mod bundle;
|
||||
mod debug;
|
||||
mod engine;
|
||||
mod eth;
|
||||
mod eth_filter;
|
||||
mod eth_pubsub;
|
||||
mod ganache;
|
||||
mod hardhat;
|
||||
mod mev;
|
||||
mod net;
|
||||
mod otterscan;
|
||||
@ -65,11 +68,14 @@ pub use clients::*;
|
||||
pub mod clients {
|
||||
pub use crate::{
|
||||
admin::AdminApiClient,
|
||||
anvil::AnvilApiClient,
|
||||
bundle::{EthBundleApiClient, EthCallBundleApiClient},
|
||||
debug::DebugApiClient,
|
||||
engine::{EngineApiClient, EngineEthApiClient},
|
||||
eth::EthApiClient,
|
||||
eth_filter::EthFilterApiClient,
|
||||
ganache::GanacheApiClient,
|
||||
hardhat::HardhatApiClient,
|
||||
mev::MevApiClient,
|
||||
net::NetApiClient,
|
||||
otterscan::OtterscanClient,
|
||||
|
||||
@ -16,6 +16,7 @@ workspace = true
|
||||
alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] }
|
||||
alloy-primitives = { workspace = true, features = ["rand", "rlp", "serde"] }
|
||||
alloy-rpc-types = { workspace = true, features = ["jsonrpsee-types"] }
|
||||
alloy-rpc-types-anvil.workspace = true
|
||||
alloy-rpc-types-trace.workspace = true
|
||||
alloy-rpc-types-engine = { workspace = true, features = ["jsonrpsee-types"] }
|
||||
ethereum_ssz_derive = { version = "0.5", optional = true }
|
||||
|
||||
@ -27,6 +27,10 @@ pub mod trace {
|
||||
//! RPC types for trace endpoints and inspectors.
|
||||
pub use alloy_rpc_types_trace::*;
|
||||
}
|
||||
|
||||
// Anvil specific rpc types coming from alloy.
|
||||
pub use alloy_rpc_types_anvil as anvil;
|
||||
|
||||
// Ethereum specific rpc types related to typed transaction requests and the engine API.
|
||||
pub use eth::{
|
||||
engine,
|
||||
|
||||
Reference in New Issue
Block a user