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#[derive(Clone, Debug, Parser)]
9pub struct RpcArgs {
10 method: String,
12
13 params: Vec<String>,
20
21 #[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}