cast/cmd/
estimate.rs
1use crate::tx::{CastTxBuilder, SenderKind};
2use alloy_primitives::U256;
3use alloy_provider::Provider;
4use alloy_rpc_types::BlockId;
5use clap::Parser;
6use eyre::Result;
7use foundry_cli::{
8 opts::{EthereumOpts, TransactionOpts},
9 utils::{self, parse_ether_value, LoadConfig},
10};
11use foundry_common::ens::NameOrAddress;
12use std::str::FromStr;
13
14#[derive(Debug, Parser)]
16pub struct EstimateArgs {
17 #[arg(value_parser = NameOrAddress::from_str)]
19 to: Option<NameOrAddress>,
20
21 sig: Option<String>,
23
24 args: Vec<String>,
26
27 #[arg(long, short = 'B')]
31 block: Option<BlockId>,
32
33 #[command(subcommand)]
34 command: Option<EstimateSubcommands>,
35
36 #[command(flatten)]
37 tx: TransactionOpts,
38
39 #[command(flatten)]
40 eth: EthereumOpts,
41}
42
43#[derive(Debug, Parser)]
44pub enum EstimateSubcommands {
45 #[command(name = "--create")]
47 Create {
48 code: String,
50
51 sig: Option<String>,
53
54 args: Vec<String>,
56
57 #[arg(long, value_parser = parse_ether_value)]
63 value: Option<U256>,
64 },
65}
66
67impl EstimateArgs {
68 pub async fn run(self) -> Result<()> {
69 let Self { to, mut sig, mut args, mut tx, block, eth, command } = self;
70
71 let config = eth.load_config()?;
72 let provider = utils::get_provider(&config)?;
73 let sender = SenderKind::from_wallet_opts(eth.wallet).await?;
74
75 let code = if let Some(EstimateSubcommands::Create {
76 code,
77 sig: create_sig,
78 args: create_args,
79 value,
80 }) = command
81 {
82 sig = create_sig;
83 args = create_args;
84 if let Some(value) = value {
85 tx.value = Some(value);
86 }
87 Some(code)
88 } else {
89 None
90 };
91
92 let (tx, _) = CastTxBuilder::new(&provider, tx, &config)
93 .await?
94 .with_to(to)
95 .await?
96 .with_code_sig_and_args(code, sig, args)
97 .await?
98 .build_raw(sender)
99 .await?;
100
101 let gas = provider.estimate_gas(tx).block(block.unwrap_or_default()).await?;
102 sh_println!("{gas}")?;
103 Ok(())
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn parse_estimate_value() {
113 let args: EstimateArgs = EstimateArgs::parse_from(["foundry-cli", "--value", "100"]);
114 assert!(args.tx.value.is_some());
115 }
116}