cast/cmd/
rpc.rs

1use crate::Cast;
2use clap::Parser;
3use eyre::Result;
4use foundry_cli::{opts::RpcOpts, utils, utils::LoadConfig};
5use foundry_common::shell;
6use itertools::Itertools;
7
8/// CLI arguments for `cast rpc`.
9#[derive(Clone, Debug, Parser)]
10pub struct RpcArgs {
11    /// RPC method name
12    method: String,
13
14    /// RPC parameters
15    ///
16    /// Interpreted as JSON:
17    ///
18    /// cast rpc eth_getBlockByNumber 0x123 false
19    /// => {"method": "eth_getBlockByNumber", "params": ["0x123", false] ... }
20    params: Vec<String>,
21
22    /// Send raw JSON parameters
23    ///
24    /// The first param will be interpreted as a raw JSON array of params.
25    /// If no params are given, stdin will be used. For example:
26    ///
27    /// cast rpc eth_getBlockByNumber '["0x123", false]' --raw
28    ///     => {"method": "eth_getBlockByNumber", "params": ["0x123", false] ... }
29    #[arg(long, short = 'w')]
30    raw: bool,
31
32    #[command(flatten)]
33    rpc: RpcOpts,
34}
35
36impl RpcArgs {
37    pub async fn run(self) -> Result<()> {
38        let Self { raw, method, params, rpc } = self;
39
40        let config = rpc.load_config()?;
41        let provider = utils::get_provider(&config)?;
42
43        let params = if raw {
44            if params.is_empty() {
45                serde_json::Deserializer::from_reader(std::io::stdin())
46                    .into_iter()
47                    .next()
48                    .transpose()?
49                    .ok_or_else(|| eyre::format_err!("Empty JSON parameters"))?
50            } else {
51                value_or_string(params.into_iter().join(" "))
52            }
53        } else {
54            serde_json::Value::Array(params.into_iter().map(value_or_string).collect())
55        };
56        let result = Cast::new(provider).rpc(&method, params).await?;
57        if shell::is_json() {
58            let result: serde_json::Value = serde_json::from_str(&result)?;
59            sh_println!("{}", serde_json::to_string_pretty(&result)?)?;
60        } else {
61            sh_println!("{}", result)?;
62        }
63        Ok(())
64    }
65}
66
67fn value_or_string(value: String) -> serde_json::Value {
68    serde_json::from_str(&value).unwrap_or(serde_json::Value::String(value))
69}