1use alloy_provider::Provider;
2use clap::Parser;
3use eyre::{Result, WrapErr};
4use foundry_cli::{
5 json::{print_json_success, print_json_value_or_scalar},
6 opts::RpcOpts,
7 utils,
8 utils::LoadConfig,
9};
10use foundry_common::shell;
11use serde_json::{Value, value::RawValue};
12
13#[derive(Clone, Debug, Parser)]
15pub struct RpcArgs {
16 method: String,
18
19 params: Vec<String>,
26
27 #[arg(long, short = 'w')]
35 raw: bool,
36
37 #[command(flatten)]
38 rpc: RpcOpts,
39}
40
41impl RpcArgs {
42 pub async fn run(self) -> Result<()> {
43 let Self { raw, method, params, rpc } = self;
44 let config = rpc.load_config()?;
45
46 let params = if !raw {
47 Value::Array(
49 params
50 .into_iter()
51 .map(|param| serde_json::from_str(¶m).unwrap_or(Value::String(param)))
52 .collect(),
53 )
54 } else if params.is_empty() {
55 serde_json::Deserializer::from_reader(std::io::stdin())
56 .into_iter()
57 .next()
58 .transpose()?
59 .ok_or_else(|| eyre::format_err!("Empty JSON parameters"))?
60 } else {
61 serde_json::from_str(¶ms.join(" ")).wrap_err("invalid raw JSON parameters")?
62 };
63
64 let result = utils::get_provider(&config)?
65 .raw_request::<_, Box<RawValue>>(method.into(), params)
66 .await?;
67
68 if result.get().contains([' ', '\t', '\n', '\r', '\\']) {
71 let result = serde_json::from_str::<Value>(result.get())?;
72 return print_json_value_or_scalar(result.to_string());
73 }
74 if shell::is_json() {
75 print_json_success(&*result)
76 } else {
77 sh_println!("{}", result.get())?;
78 Ok(())
79 }
80 }
81}