Skip to main content

cast/cmd/
rpc.rs

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