Skip to main content

cast/
opts.rs

1#[cfg(feature = "optimism")]
2use crate::cmd::da_estimate::DAEstimateArgs;
3use crate::cmd::{
4    access_list::AccessListArgs,
5    artifact::ArtifactArgs,
6    b2e_payload::B2EPayloadArgs,
7    batch_mktx::BatchMakeTxArgs,
8    batch_send::BatchSendArgs,
9    bind::BindArgs,
10    call::CallArgs,
11    call_overrides::CallOverrideOpts,
12    constructor_args::ConstructorArgsArgs,
13    create2::Create2Args,
14    creation_code::CreationCodeArgs,
15    erc20::Erc20Subcommand,
16    estimate::EstimateArgs,
17    events::EventsArgs,
18    find_block::FindBlockArgs,
19    interface::InterfaceArgs,
20    keychain::{KeyAuthorizationSubcommand, KeychainSubcommand},
21    logs::LogsArgs,
22    mktx::MakeTxArgs,
23    receive_policy::ReceivePolicySubcommand,
24    rpc::RpcArgs,
25    run::RunArgs,
26    send::SendTxArgs,
27    storage::StorageArgs,
28    storage_credits::StorageCreditsSubcommand,
29    tempo::TempoSubcommand,
30    tip20::Tip20Subcommand,
31    tip403::Tip403Subcommand,
32    trace::TraceArgs,
33    txpool::TxPoolSubcommands,
34    vaddr::VaddrSubcommand,
35    wallet::WalletSubcommands,
36};
37use alloy_ens::NameOrAddress;
38use alloy_primitives::{Address, B256, Selector, U256};
39use alloy_rpc_types::BlockId;
40use clap::{ArgAction, Parser, Subcommand, ValueHint};
41use eyre::Result;
42use foundry_cli::opts::{EtherscanOpts, GlobalArgs, RpcOpts};
43use foundry_common::version::{LONG_VERSION, SHORT_VERSION};
44use foundry_evm_networks::NetworkVariant;
45use std::{path::PathBuf, str::FromStr};
46/// A Swiss Army knife for interacting with Ethereum applications from the command line.
47#[derive(Parser)]
48#[command(
49    name = "cast",
50    version = SHORT_VERSION,
51    long_version = LONG_VERSION,
52    after_help = "Find more information in the book: https://getfoundry.sh/cast/overview",
53    next_display_order = None,
54)]
55pub struct Cast {
56    /// Include the global arguments.
57    #[command(flatten)]
58    pub global: GlobalArgs,
59
60    #[command(subcommand)]
61    pub cmd: CastSubcommand,
62}
63
64#[derive(Subcommand)]
65pub enum CastSubcommand {
66    /// Prints the maximum value of the given integer type.
67    #[command(visible_aliases = &["--max-int", "maxi"])]
68    MaxInt {
69        /// The integer type to get the maximum value of.
70        #[arg(default_value = "int256")]
71        r#type: String,
72    },
73
74    /// Prints the minimum value of the given integer type.
75    #[command(visible_aliases = &["--min-int", "mini"])]
76    MinInt {
77        /// The integer type to get the minimum value of.
78        #[arg(default_value = "int256")]
79        r#type: String,
80    },
81
82    /// Prints the maximum value of the given integer type.
83    #[command(visible_aliases = &["--max-uint", "maxu"])]
84    MaxUint {
85        /// The unsigned integer type to get the maximum value of.
86        #[arg(default_value = "uint256")]
87        r#type: String,
88    },
89
90    /// Prints the zero address.
91    #[command(visible_aliases = &["--address-zero", "az"])]
92    AddressZero,
93
94    /// Prints the zero hash.
95    #[command(visible_aliases = &["--hash-zero", "hz"])]
96    HashZero,
97
98    /// Convert UTF8 text to hex.
99    #[command(
100        visible_aliases = &[
101        "--from-ascii",
102        "--from-utf8",
103        "from-ascii",
104        "fu",
105        "fa"]
106    )]
107    FromUtf8 {
108        /// The text to convert.
109        text: Option<String>,
110    },
111
112    /// Concatenate hex strings.
113    #[command(visible_aliases = &["--concat-hex", "ch"])]
114    ConcatHex {
115        /// The data to concatenate.
116        data: Vec<String>,
117    },
118
119    /// Convert binary data into hex data.
120    #[command(visible_aliases = &["--from-bin", "from-binx", "fb"])]
121    FromBin,
122
123    /// Normalize the input to lowercase, 0x-prefixed hex.
124    ///
125    /// The input can be:
126    /// - mixed case hex with or without 0x prefix
127    /// - 0x prefixed hex, concatenated with a ':'
128    /// - an absolute path to file
129    /// - @tag, where the tag is defined in an environment variable
130    #[command(visible_aliases = &["--to-hexdata", "thd", "2hd"])]
131    ToHexdata {
132        /// The input to normalize.
133        input: Option<String>,
134    },
135
136    /// Convert an address to a checksummed format (EIP-55).
137    #[command(
138        visible_aliases = &["--to-checksum-address",
139        "--to-checksum",
140        "to-checksum",
141        "ta",
142        "2a"]
143    )]
144    ToCheckSumAddress {
145        /// The address to convert.
146        address: Option<Address>,
147        /// EIP-155 chain ID to encode the address using EIP-1191.
148        chain_id: Option<u64>,
149    },
150
151    /// Convert hex data to an ASCII string.
152    #[command(visible_aliases = &["--to-ascii", "tas", "2as"])]
153    ToAscii {
154        /// The hex data to convert.
155        hexdata: Option<String>,
156    },
157
158    /// Convert hex data to a utf-8 string.
159    #[command(visible_aliases = &["--to-utf8", "tu8", "2u8"])]
160    ToUtf8 {
161        /// The hex data to convert.
162        hexdata: Option<String>,
163    },
164
165    /// Convert a fixed point number into an integer.
166    #[command(visible_aliases = &["--from-fix", "ff"])]
167    FromFixedPoint {
168        /// The number of decimals to use.
169        decimals: Option<String>,
170
171        /// The value to convert.
172        #[arg(allow_hyphen_values = true)]
173        value: Option<String>,
174    },
175
176    /// Right-pads hex data to 32 bytes.
177    #[command(visible_aliases = &["--to-bytes32", "tb", "2b"])]
178    ToBytes32 {
179        /// The hex data to convert.
180        bytes: Option<String>,
181    },
182
183    /// Convert hex data to the word-aligned layout of a Solidity `bytes memory` value.
184    ///
185    /// The output contains a 32-byte length prefix followed by the data, right-padded with zeros
186    /// to a whole number of 32-byte words.
187    #[command(visible_alias = "tbm")]
188    ToBytesMemory {
189        /// The hex data to convert.
190        data: Option<String>,
191    },
192
193    /// Pads hex data to a specified length.
194    #[command(visible_aliases = &["pd"])]
195    Pad {
196        /// The hex data to pad.
197        data: Option<String>,
198
199        /// Right-pad the data (instead of left-pad).
200        #[arg(long)]
201        right: bool,
202
203        /// Left-pad the data (default).
204        #[arg(long, conflicts_with = "right")]
205        left: bool,
206
207        /// Target length in bytes (default: 32).
208        #[arg(long, default_value = "32")]
209        len: usize,
210    },
211
212    /// Convert an integer into a fixed point number.
213    #[command(visible_aliases = &["--to-fix", "tf", "2f"])]
214    ToFixedPoint {
215        /// The number of decimals to use.
216        decimals: Option<String>,
217
218        /// The value to convert.
219        #[arg(allow_hyphen_values = true)]
220        value: Option<String>,
221    },
222
223    /// Convert a number to a hex-encoded uint256.
224    #[command(name = "to-uint256", visible_aliases = &["--to-uint256", "tu", "2u"])]
225    ToUint256 {
226        /// The value to convert.
227        value: Option<String>,
228    },
229
230    /// Convert a number to a hex-encoded int256.
231    #[command(name = "to-int256", visible_aliases = &["--to-int256", "ti", "2i"])]
232    ToInt256 {
233        /// The value to convert.
234        value: Option<String>,
235    },
236
237    /// Perform a left shifting operation
238    #[command(name = "shl")]
239    LeftShift {
240        /// The value to shift.
241        value: String,
242
243        /// The number of bits to shift.
244        bits: String,
245
246        /// The input base.
247        #[arg(long)]
248        base_in: Option<String>,
249
250        /// The output base.
251        #[arg(long, default_value = "16")]
252        base_out: String,
253    },
254
255    /// Perform a right shifting operation
256    #[command(name = "shr")]
257    RightShift {
258        /// The value to shift.
259        value: String,
260
261        /// The number of bits to shift.
262        bits: String,
263
264        /// The input base,
265        #[arg(long)]
266        base_in: Option<String>,
267
268        /// The output base,
269        #[arg(long, default_value = "16")]
270        base_out: String,
271    },
272
273    /// Convert an ETH amount into another unit (ether, gwei or wei)
274    ///
275    /// Examples:
276    /// - 1ether wei
277    /// - "1 ether" wei
278    /// - 1ether
279    /// - 1 gwei
280    /// - 1gwei ether
281    #[command(verbatim_doc_comment, visible_aliases = &["--to-unit", "tun", "2un"])]
282    ToUnit {
283        /// The value to convert.
284        value: Option<String>,
285
286        /// The unit to convert to (ether, gwei, wei).
287        #[arg(default_value = "wei")]
288        unit: String,
289    },
290
291    /// Convert a number from decimal to smallest unit with arbitrary decimals
292    ///
293    /// Examples:
294    /// - 1.0 6    (for USDC, result: 1000000)
295    /// - 2.5 12   (for 12 decimals token, result: 2500000000000)
296    /// - 1.23 3   (for 3 decimals token, result: 1230)
297    #[command(verbatim_doc_comment, visible_aliases = &["--parse-units", "pun"])]
298    ParseUnits {
299        /// The value to convert.
300        value: Option<String>,
301
302        /// The unit to convert to.
303        #[arg(default_value = "18")]
304        unit: u8,
305    },
306
307    /// Format a number from smallest unit to decimal with arbitrary decimals
308    ///
309    /// Examples:
310    /// - 1000000 6       (for USDC, result: 1.0)
311    /// - 2500000000000 12 (for 12 decimals, result: 2.5)
312    /// - 1230 3          (for 3 decimals, result: 1.23)
313    #[command(verbatim_doc_comment, visible_aliases = &["--format-units", "fun"])]
314    FormatUnits {
315        /// The value to format.
316        value: Option<String>,
317
318        /// The unit to format to.
319        #[arg(default_value = "18")]
320        unit: u8,
321    },
322
323    /// Convert an ETH amount to wei.
324    ///
325    /// Consider using --to-unit.
326    #[command(visible_aliases = &["--to-wei", "tw", "2w"])]
327    ToWei {
328        /// The value to convert.
329        #[arg(allow_hyphen_values = true)]
330        value: Option<String>,
331
332        /// The unit to convert from (ether, gwei, wei).
333        #[arg(default_value = "eth")]
334        unit: String,
335    },
336
337    /// Convert wei into an ETH amount.
338    ///
339    /// Consider using --to-unit.
340    #[command(visible_aliases = &["--from-wei", "fw"])]
341    FromWei {
342        /// The value to convert.
343        #[arg(allow_hyphen_values = true)]
344        value: Option<String>,
345
346        /// The unit to convert from (ether, gwei, wei).
347        #[arg(default_value = "eth")]
348        unit: String,
349    },
350
351    /// RLP encodes hex data, or an array of hex data
352    ///
353    /// Accepts a hex-encoded string, or an array of hex-encoded strings.
354    /// Can be arbitrarily recursive.
355    ///
356    /// Examples:
357    /// - `cast to-rlp "[]"` -> `0xc0`
358    /// - `cast to-rlp "0x22"` -> `0x22`
359    /// - `cast to-rlp "[\"0x61\"]"` -> `0xc161`
360    /// - `cast to-rlp "[\"0xf1\", \"f2\"]"` -> `0xc481f181f2`
361    #[command(verbatim_doc_comment, visible_aliases = &["--to-rlp"])]
362    ToRlp {
363        /// The value to convert.
364        ///
365        /// This is a hex-encoded string, or an array of hex-encoded strings.
366        /// Can be arbitrarily recursive.
367        value: Option<String>,
368    },
369
370    /// Decodes RLP hex-encoded data.
371    #[command(visible_aliases = &["--from-rlp"])]
372    FromRlp {
373        /// The RLP hex-encoded data.
374        value: Option<String>,
375
376        /// Decode the RLP data as int
377        #[arg(long, alias = "int")]
378        as_int: bool,
379    },
380
381    /// Converts a number of one base to another
382    #[command(visible_aliases = &["--to-hex", "th", "2h"])]
383    ToHex(ToBaseArgs),
384
385    /// Converts a number of one base to decimal
386    #[command(visible_aliases = &["--to-dec", "td", "2d"])]
387    ToDec(ToBaseArgs),
388
389    /// Converts a number of one base to another
390    #[command(
391        visible_aliases = &["--to-base",
392        "--to-radix",
393        "to-radix",
394        "tr",
395        "2r"]
396    )]
397    ToBase {
398        #[command(flatten)]
399        base: ToBaseArgs,
400
401        /// The output base.
402        #[arg(value_name = "BASE")]
403        base_out: Option<String>,
404    },
405    /// Create an access list for a transaction
406    ///
407    /// Examples:
408    /// - cast access-list vitalik.eth --value 0.1ether
409    /// - cast access-list $TOKEN "transfer(address,uint256)" vitalik.eth 100
410    #[command(verbatim_doc_comment, visible_aliases = &["ac", "acl"])]
411    AccessList(AccessListArgs),
412    /// Get logs by signature or topic
413    ///
414    /// Examples:
415    /// - cast logs "Transfer(address indexed from, address indexed to, uint256 value)"
416    /// - cast logs --address $TOKEN --from-block 21000000 --to-block latest $TOPIC_0
417    #[command(verbatim_doc_comment, visible_alias = "l")]
418    Logs(LogsArgs),
419    /// Fetch and decode events from a transaction receipt or log filter.
420    ///
421    /// Examples:
422    /// - cast events $TX_HASH
423    /// - cast events --tx-hash $TX_HASH
424    /// - cast events --address $TOKEN --from-block 21000000 --to-block latest
425    /// - cast events --address $TOKEN "Transfer(address indexed,address indexed,uint256)"
426    ///
427    /// A lone 32-byte positional value is treated as a transaction hash. Qualify a raw topic with
428    /// an address, block range, additional topic, or query size.
429    #[command(verbatim_doc_comment, visible_alias = "ev")]
430    Events(EventsArgs),
431    /// Get information about a block
432    ///
433    /// Examples:
434    /// - cast block latest
435    /// - cast block 21000000 --field timestamp
436    /// - cast block latest --json
437    #[command(verbatim_doc_comment, visible_alias = "bl")]
438    Block {
439        /// The block height to query at.
440        ///
441        /// Can also be the tags earliest, finalized, safe, latest, or pending.
442        block: Option<BlockId>,
443
444        /// If specified, only get the given field of the block.
445        #[arg(short, long = "field", aliases = ["fields"], num_args = 0.., action = ArgAction::Append, value_delimiter = ',')]
446        fields: Vec<String>,
447
448        /// Print the raw RLP encoded block header.
449        #[arg(long, conflicts_with = "fields")]
450        raw: bool,
451
452        #[arg(long, env = "CAST_FULL_BLOCK")]
453        full: bool,
454
455        #[command(flatten)]
456        rpc: RpcOpts,
457
458        /// Specify the Network for correct encoding.
459        #[arg(long, short, num_args = 1, value_name = "NETWORK")]
460        network: Option<NetworkVariant>,
461    },
462
463    /// Get the latest block number.
464    #[command(visible_alias = "bn")]
465    BlockNumber {
466        /// The hash or tag to query. If not specified, the latest number is returned.
467        block: Option<BlockId>,
468        #[command(flatten)]
469        rpc: RpcOpts,
470    },
471
472    /// Perform a call on an account without publishing a transaction
473    ///
474    /// Examples:
475    /// - cast call $TOKEN "balanceOf(address)(uint256)" vitalik.eth
476    /// - cast call $TOKEN "transfer(address,uint256)" vitalik.eth 100 --trace
477    #[command(verbatim_doc_comment, visible_alias = "c")]
478    Call(CallArgs),
479
480    /// ABI-encode a function with arguments.
481    #[command(name = "calldata", visible_alias = "cd")]
482    CalldataEncode {
483        /// The function signature in the format `<name>(<in-types>)(<out-types>)`
484        sig: String,
485
486        /// The arguments to encode.
487        #[arg(allow_hyphen_values = true)]
488        args: Vec<String>,
489
490        // Path to file containing arguments to encode.
491        #[arg(long, value_name = "PATH")]
492        file: Option<PathBuf>,
493    },
494
495    /// Get the symbolic name of the current chain.
496    Chain {
497        #[command(flatten)]
498        rpc: RpcOpts,
499    },
500
501    /// Get the Ethereum chain ID.
502    #[command(visible_aliases = &["ci", "cid"])]
503    ChainId {
504        #[command(flatten)]
505        rpc: RpcOpts,
506    },
507
508    /// Get the current client version.
509    #[command(visible_alias = "cl")]
510    Client {
511        #[command(flatten)]
512        rpc: RpcOpts,
513    },
514
515    /// Compute the contract address from a given nonce and deployer address.
516    #[command(visible_alias = "ca")]
517    ComputeAddress {
518        /// The deployer address.
519        address: Option<Address>,
520
521        /// The nonce of the deployer address.
522        #[arg(
523            long,
524            conflicts_with = "salt",
525            conflicts_with = "init_code",
526            conflicts_with = "init_code_hash"
527        )]
528        nonce: Option<u64>,
529
530        /// The salt for CREATE2 address computation.
531        #[arg(long, conflicts_with = "nonce")]
532        salt: Option<B256>,
533
534        /// The init code for CREATE2 address computation.
535        #[arg(
536            long,
537            requires = "salt",
538            conflicts_with = "init_code_hash",
539            conflicts_with = "nonce"
540        )]
541        init_code: Option<String>,
542
543        /// The init code hash for CREATE2 address computation.
544        #[arg(long, requires = "salt", conflicts_with = "init_code", conflicts_with = "nonce")]
545        init_code_hash: Option<B256>,
546
547        #[command(flatten)]
548        rpc: RpcOpts,
549    },
550
551    /// Disassembles a hex-encoded bytecode into a human-readable representation.
552    #[command(visible_alias = "da")]
553    Disassemble {
554        /// The hex-encoded bytecode.
555        bytecode: Option<String>,
556    },
557
558    /// Build and sign a transaction
559    ///
560    /// Examples:
561    /// - cast mktx vitalik.eth --value 0.1ether --private-key $PK
562    /// - cast mktx $TOKEN "transfer(address,uint256)" vitalik.eth 100 --account dev
563    #[command(verbatim_doc_comment, name = "mktx", visible_alias = "m")]
564    MakeTx(MakeTxArgs),
565
566    /// Classify a raw transaction as Tempo T5 payment/general lane.
567    Classify {
568        /// The raw signed transaction.
569        raw_tx: Option<String>,
570    },
571
572    /// Calculate the ENS namehash of a name.
573    #[command(visible_aliases = &["na", "nh"])]
574    Namehash { name: Option<String> },
575
576    /// Get information about a transaction
577    ///
578    /// Examples:
579    /// - cast tx $TX_HASH
580    /// - cast tx $TX_HASH blockNumber (only print the blockNumber field)
581    /// - cast tx $TX_HASH --raw
582    #[command(verbatim_doc_comment, visible_alias = "t")]
583    Tx {
584        /// The transaction hash.
585        tx_hash: Option<String>,
586
587        /// The sender of the transaction.
588        #[arg(long, value_parser = NameOrAddress::from_str)]
589        from: Option<NameOrAddress>,
590
591        /// Nonce of the transaction.
592        #[arg(long)]
593        nonce: Option<u64>,
594
595        /// If specified, only get the given field of the transaction. If "raw", the RLP encoded
596        /// transaction will be printed.
597        field: Option<String>,
598
599        /// Print the raw RLP encoded transaction.
600        #[arg(long, conflicts_with = "field")]
601        raw: bool,
602
603        /// Classify the transaction as Tempo T5 payment/general lane.
604        #[arg(long, conflicts_with_all = ["field", "raw", "to_request"])]
605        lane: bool,
606
607        #[command(flatten)]
608        rpc: RpcOpts,
609
610        /// If specified, the transaction will be converted to a TransactionRequest JSON format.
611        #[arg(long)]
612        to_request: bool,
613
614        /// Specify the Network for correct encoding.
615        #[arg(long, short, num_args = 1, value_name = "NETWORK")]
616        network: Option<NetworkVariant>,
617    },
618
619    /// Get the transaction receipt for a transaction
620    ///
621    /// Examples:
622    /// - cast receipt $TX_HASH
623    /// - cast receipt $TX_HASH status (only print the status field)
624    #[command(verbatim_doc_comment, visible_alias = "re")]
625    Receipt {
626        /// The transaction hash.
627        tx_hash: String,
628
629        /// If specified, only get the given field of the transaction.
630        field: Option<String>,
631
632        /// The number of confirmations until the receipt is fetched
633        #[arg(long, default_value = "1")]
634        confirmations: u64,
635
636        /// Exit immediately if the transaction was not found.
637        #[arg(id = "async", long = "async", env = "CAST_ASYNC", alias = "cast-async")]
638        cast_async: bool,
639
640        #[command(flatten)]
641        rpc: RpcOpts,
642    },
643
644    /// Sign and publish a transaction
645    ///
646    /// Examples:
647    /// - cast send vitalik.eth --value 0.1ether --private-key $PK (transfer ETH)
648    /// - cast send $TOKEN "transfer(address,uint256)" vitalik.eth 100 --account dev
649    /// - cast send --private-key $PK --create $BYTECODE (deploy a contract)
650    #[command(verbatim_doc_comment, name = "send", visible_alias = "s")]
651    SendTx(SendTxArgs),
652
653    /// Build and sign a batch transaction (Tempo).
654    #[command(name = "batch-mktx", visible_alias = "bm")]
655    BatchMakeTx(BatchMakeTxArgs),
656
657    /// Sign and publish a batch transaction (Tempo).
658    #[command(name = "batch-send", visible_alias = "bs")]
659    BatchSend(BatchSendArgs),
660
661    /// Publish a raw transaction to the network.
662    #[command(name = "publish", visible_alias = "p")]
663    PublishTx {
664        /// The raw transaction
665        raw_tx: String,
666
667        /// Only print the transaction hash and exit immediately.
668        #[arg(id = "async", long = "async", env = "CAST_ASYNC", alias = "cast-async")]
669        cast_async: bool,
670
671        #[command(flatten)]
672        rpc: RpcOpts,
673    },
674
675    /// Estimate the gas cost of a transaction
676    ///
677    /// Examples:
678    /// - cast estimate vitalik.eth --value 0.1ether
679    /// - cast estimate $CONTRACT "deposit()" --value 1ether
680    #[command(verbatim_doc_comment, visible_alias = "e")]
681    Estimate(EstimateArgs),
682
683    /// Decode ABI-encoded input data
684    ///
685    /// Similar to `abi-decode --input`, but function selector MUST be prefixed in `calldata`.
686    ///
687    /// Examples:
688    /// - cast decode-calldata "transfer(address,uint256)" $CALLDATA
689    /// - cast decode-calldata --json "transfer(address,uint256)" $CALLDATA
690    #[command(verbatim_doc_comment, visible_aliases = &["calldata-decode", "--calldata-decode", "cdd"])]
691    DecodeCalldata {
692        /// The function signature in the format `<name>(<in-types>)(<out-types>)`.
693        sig: String,
694
695        /// The ABI-encoded calldata.
696        #[arg(required_unless_present = "file", index = 2)]
697        calldata: Option<String>,
698
699        /// Load ABI-encoded calldata from a file instead.
700        #[arg(long = "file", short = 'f', conflicts_with = "calldata")]
701        file: Option<PathBuf>,
702    },
703
704    /// Decode ABI-encoded string.
705    ///
706    /// Similar to `calldata-decode --input`, but the function argument is a `string`
707    #[command(visible_aliases = &["string-decode", "--string-decode", "sd"])]
708    DecodeString {
709        /// The ABI-encoded string.
710        data: String,
711    },
712
713    /// Decode event data
714    ///
715    /// Examples:
716    /// - cast decode-event --sig "Transfer(address,address,uint256)" $DATA
717    /// - cast decode-event $DATA (topic0-prefixed data; looks up the signature)
718    #[command(verbatim_doc_comment, visible_aliases = &["event-decode", "--event-decode", "ed"])]
719    DecodeEvent {
720        /// The event signature. If none provided then tries to decode from local cache or <https://api.openchain.xyz>.
721        #[arg(long, visible_alias = "event-sig")]
722        sig: Option<String>,
723        /// The event data to decode.
724        data: String,
725    },
726
727    /// Decode custom error data.
728    #[command(visible_aliases = &["error-decode", "--error-decode", "erd"])]
729    DecodeError {
730        /// The error signature. If none provided then tries to decode from local cache or <https://api.openchain.xyz>.
731        #[arg(long, visible_alias = "error-sig")]
732        sig: Option<String>,
733        /// The error data to decode.
734        data: String,
735    },
736
737    /// Decode ABI-encoded input or output data
738    ///
739    /// Defaults to decoding output data. To decode input data pass --input.
740    ///
741    /// When passing `--input`, function selector must NOT be prefixed in `calldata` string.
742    ///
743    /// Examples:
744    /// - cast decode-abi "balanceOf(address)(uint256)" $DATA
745    /// - cast decode-abi --input "transfer(address,uint256)" $CALLDATA
746    #[command(verbatim_doc_comment, name = "decode-abi", visible_aliases = &["abi-decode", "--abi-decode", "ad"])]
747    DecodeAbi {
748        /// The function signature in the format `<name>(<in-types>)(<out-types>)`.
749        sig: String,
750
751        /// The ABI-encoded calldata.
752        calldata: String,
753
754        /// Whether to decode the input or output data.
755        #[arg(long, short, help_heading = "Decode input data instead of output data")]
756        input: bool,
757    },
758
759    /// ABI encode the given function argument, excluding the selector
760    ///
761    /// Examples:
762    /// - cast abi-encode "transfer(address,uint256)" $ADDRESS 100
763    /// - cast abi-encode --packed "f(string,uint64)" hello 100
764    #[command(verbatim_doc_comment, visible_alias = "ae")]
765    AbiEncode {
766        /// The function signature.
767        sig: String,
768
769        /// Whether to use packed encoding.
770        #[arg(long)]
771        packed: bool,
772
773        /// The arguments of the function.
774        #[arg(allow_hyphen_values = true)]
775        args: Vec<String>,
776    },
777
778    /// ABI encode an event and its arguments to generate topics and data.
779    #[command(visible_alias = "aee")]
780    AbiEncodeEvent {
781        /// The event signature.
782        sig: String,
783
784        /// The arguments of the event.
785        #[arg(allow_hyphen_values = true)]
786        args: Vec<String>,
787    },
788
789    /// Compute the storage slot for an entry in a mapping.
790    #[command(visible_alias = "in")]
791    Index {
792        /// The mapping key type.
793        key_type: String,
794
795        /// The mapping key.
796        key: String,
797
798        /// The storage slot of the mapping.
799        slot_number: String,
800    },
801
802    /// Compute storage slots as specified by `ERC-7201: Namespaced Storage Layout`.
803    #[command(name = "index-erc7201", alias = "index-erc-7201", visible_aliases = &["index7201", "in7201"])]
804    IndexErc7201 {
805        /// The arbitrary identifier.
806        id: Option<String>,
807        /// The formula ID. Currently the only supported formula is `erc7201`.
808        #[arg(long, default_value = "erc7201")]
809        formula_id: String,
810    },
811
812    /// Fetch the EIP-1967 implementation for a contract
813    /// Can read from the implementation slot or the beacon slot.
814    #[command(visible_alias = "impl")]
815    Implementation {
816        /// The block height to query at.
817        ///
818        /// Can also be the tags earliest, finalized, safe, latest, or pending.
819        #[arg(long, short = 'B')]
820        block: Option<BlockId>,
821
822        /// Fetch the implementation from the beacon slot.
823        ///
824        /// If not specified, the implementation slot is used.
825        #[arg(long)]
826        beacon: bool,
827
828        /// The address for which the implementation will be fetched.
829        #[arg(value_parser = NameOrAddress::from_str)]
830        who: NameOrAddress,
831
832        #[command(flatten)]
833        rpc: RpcOpts,
834    },
835
836    /// Fetch the EIP-1967 admin account
837    #[command(visible_alias = "adm")]
838    Admin {
839        /// The block height to query at.
840        ///
841        /// Can also be the tags earliest, finalized, safe, latest, or pending.
842        #[arg(long, short = 'B')]
843        block: Option<BlockId>,
844
845        /// The address from which the admin account will be fetched.
846        #[arg(value_parser = NameOrAddress::from_str)]
847        who: NameOrAddress,
848
849        #[command(flatten)]
850        rpc: RpcOpts,
851    },
852
853    /// Get the function signatures for the given selector from <https://openchain.xyz>.
854    #[command(name = "4byte", visible_aliases = &["4", "4b"])]
855    FourByte {
856        /// The function selector.
857        selector: Option<Selector>,
858    },
859
860    /// Decode ABI-encoded calldata using <https://openchain.xyz>.
861    #[command(name = "4byte-calldata", aliases = &["4byte-decode", "4d", "4bd"], visible_aliases = &["4c", "4bc"])]
862    FourByteCalldata {
863        /// The ABI-encoded calldata.
864        calldata: Option<String>,
865    },
866
867    /// Get the event signature for a given topic 0 from <https://openchain.xyz>.
868    #[command(name = "4byte-event", visible_aliases = &["4e", "4be", "topic0-event", "t0e"])]
869    FourByteEvent {
870        /// Topic 0
871        #[arg(value_name = "TOPIC_0")]
872        topic: Option<B256>,
873    },
874
875    /// Upload the given signatures to <https://openchain.xyz>.
876    ///
877    /// Example inputs:
878    /// - "transfer(address,uint256)"
879    /// - "function transfer(address,uint256)"
880    /// - "function transfer(address,uint256)" "event Transfer(address,address,uint256)"
881    /// - "./out/Contract.sol/Contract.json"
882    #[command(visible_aliases = &["ups"])]
883    UploadSignature {
884        /// The signatures to upload.
885        ///
886        /// Prefix with 'function', 'event', or 'error'. Defaults to function if no prefix given.
887        /// Can also take paths to contract artifact JSON.
888        signatures: Vec<String>,
889    },
890
891    /// Pretty print calldata.
892    ///
893    /// Tries to decode the calldata using <https://openchain.xyz> unless --offline is passed.
894    #[command(visible_alias = "pc")]
895    PrettyCalldata {
896        /// The calldata.
897        calldata: Option<String>,
898
899        /// Skip the <https://openchain.xyz> lookup.
900        #[arg(long, short)]
901        offline: bool,
902    },
903
904    /// Get the timestamp of a block.
905    #[command(visible_alias = "a")]
906    Age {
907        /// The block height to query at.
908        ///
909        /// Can also be the tags earliest, finalized, safe, latest, or pending.
910        block: Option<BlockId>,
911
912        #[command(flatten)]
913        rpc: RpcOpts,
914    },
915
916    /// Get the balance of an account in wei
917    ///
918    /// Examples:
919    /// - cast balance vitalik.eth --ether
920    /// - cast balance vitalik.eth --erc20 0x6B175474E89094C44Da98b954EedeAC495271d0F
921    #[command(verbatim_doc_comment, visible_alias = "b")]
922    Balance {
923        /// The block height to query at.
924        ///
925        /// Can also be the tags earliest, finalized, safe, latest, or pending.
926        #[arg(long, short = 'B')]
927        block: Option<BlockId>,
928
929        /// The account to query.
930        #[arg(value_parser = NameOrAddress::from_str)]
931        who: NameOrAddress,
932
933        /// Format the balance in ether.
934        #[arg(long, short)]
935        ether: bool,
936
937        #[command(flatten)]
938        rpc: RpcOpts,
939
940        /// erc20 address to query, with the method `balanceOf(address) return (uint256)`, alias
941        /// with '--erc721'
942        #[arg(long, alias = "erc721")]
943        erc20: Option<Address>,
944
945        #[command(flatten)]
946        overrides: CallOverrideOpts,
947    },
948
949    /// Get the basefee of a block.
950    #[command(visible_aliases = &["ba", "fee", "basefee"])]
951    BaseFee {
952        /// The block height to query at.
953        ///
954        /// Can also be the tags earliest, finalized, safe, latest, or pending.
955        block: Option<BlockId>,
956
957        #[command(flatten)]
958        rpc: RpcOpts,
959    },
960
961    /// Get the runtime bytecode of a contract
962    ///
963    /// Examples:
964    /// - cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
965    /// - cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --disassemble
966    #[command(verbatim_doc_comment, visible_alias = "co")]
967    Code {
968        /// The block height to query at.
969        ///
970        /// Can also be the tags earliest, finalized, safe, latest, or pending.
971        #[arg(long, short = 'B')]
972        block: Option<BlockId>,
973
974        /// The contract address.
975        #[arg(value_parser = NameOrAddress::from_str)]
976        who: NameOrAddress,
977
978        /// Disassemble bytecodes.
979        #[arg(long, short)]
980        disassemble: bool,
981
982        #[command(flatten)]
983        rpc: RpcOpts,
984    },
985
986    /// Get the runtime bytecode size of a contract.
987    #[command(visible_alias = "cs")]
988    Codesize {
989        /// The block height to query at.
990        ///
991        /// Can also be the tags earliest, finalized, safe, latest, or pending.
992        #[arg(long, short = 'B')]
993        block: Option<BlockId>,
994
995        /// The contract address.
996        #[arg(value_parser = NameOrAddress::from_str)]
997        who: NameOrAddress,
998
999        #[command(flatten)]
1000        rpc: RpcOpts,
1001    },
1002
1003    /// Get the current gas price.
1004    #[command(visible_alias = "g")]
1005    GasPrice {
1006        #[command(flatten)]
1007        rpc: RpcOpts,
1008    },
1009
1010    /// Generate event signatures from event string.
1011    #[command(visible_alias = "se")]
1012    SigEvent {
1013        /// The event string.
1014        event_string: Option<String>,
1015    },
1016
1017    /// Hash arbitrary data using Keccak-256
1018    ///
1019    /// Examples:
1020    /// - cast keccak "hello world"
1021    /// - cast keccak 0xdeadbeef
1022    /// - echo -n "some data" | cast keccak (hash data from stdin)
1023    #[command(verbatim_doc_comment, visible_aliases = &["k", "keccak256"])]
1024    Keccak {
1025        /// The data to hash.
1026        data: Option<String>,
1027    },
1028
1029    /// Hash a message according to EIP-191.
1030    #[command(visible_aliases = &["--hash-message", "hm"])]
1031    HashMessage {
1032        /// The message to hash.
1033        message: Option<String>,
1034    },
1035
1036    /// Perform an ENS lookup.
1037    #[command(visible_alias = "rn")]
1038    ResolveName {
1039        /// The name to lookup.
1040        who: Option<String>,
1041
1042        /// Perform a reverse lookup to verify that the name is correct.
1043        #[arg(long)]
1044        verify: bool,
1045
1046        #[command(flatten)]
1047        rpc: RpcOpts,
1048    },
1049
1050    /// Perform an ENS reverse lookup.
1051    #[command(visible_alias = "la")]
1052    LookupAddress {
1053        /// The account to perform the lookup for.
1054        who: Option<Address>,
1055
1056        /// Perform a normal lookup to verify that the address is correct.
1057        #[arg(long)]
1058        verify: bool,
1059
1060        #[command(flatten)]
1061        rpc: RpcOpts,
1062    },
1063
1064    /// Get the raw value of a contract's storage slot
1065    ///
1066    /// Examples:
1067    /// - cast storage 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 0
1068    /// - cast storage $TOKEN --etherscan-api-key $KEY (decode the full storage layout)
1069    #[command(verbatim_doc_comment, visible_alias = "st")]
1070    Storage(StorageArgs),
1071
1072    /// Generate a storage proof for a given storage slot.
1073    #[command(visible_alias = "pr")]
1074    Proof {
1075        /// The contract address.
1076        #[arg(value_parser = NameOrAddress::from_str)]
1077        address: NameOrAddress,
1078
1079        /// The storage slot numbers (hex or decimal).
1080        #[arg(value_parser = parse_slot)]
1081        slots: Vec<B256>,
1082
1083        /// The block height to query at.
1084        ///
1085        /// Can also be the tags earliest, finalized, safe, latest, or pending.
1086        #[arg(long, short = 'B')]
1087        block: Option<BlockId>,
1088
1089        #[command(flatten)]
1090        rpc: RpcOpts,
1091    },
1092
1093    /// Get the nonce for an account.
1094    #[command(visible_alias = "n")]
1095    Nonce {
1096        /// The block height to query at.
1097        ///
1098        /// Can also be the tags earliest, finalized, safe, latest, or pending.
1099        #[arg(long, short = 'B')]
1100        block: Option<BlockId>,
1101
1102        /// The address to get the nonce for.
1103        #[arg(value_parser = NameOrAddress::from_str)]
1104        who: NameOrAddress,
1105
1106        #[command(flatten)]
1107        rpc: RpcOpts,
1108    },
1109
1110    /// Get the codehash for an account.
1111    #[command()]
1112    Codehash {
1113        /// The block height to query at.
1114        ///
1115        /// Can also be the tags earliest, finalized, safe, latest, or pending.
1116        #[arg(long, short = 'B')]
1117        block: Option<BlockId>,
1118
1119        /// The address to get the codehash for.
1120        #[arg(value_parser = NameOrAddress::from_str)]
1121        who: NameOrAddress,
1122
1123        /// The storage slot numbers (hex or decimal).
1124        #[arg(value_parser = parse_slot)]
1125        slots: Vec<B256>,
1126
1127        #[command(flatten)]
1128        rpc: RpcOpts,
1129    },
1130
1131    /// Get the storage root for an account.
1132    #[command(visible_alias = "sr")]
1133    StorageRoot {
1134        /// The block height to query at.
1135        ///
1136        /// Can also be the tags earliest, finalized, safe, latest, or pending.
1137        #[arg(long, short = 'B')]
1138        block: Option<BlockId>,
1139
1140        /// The address to get the storage root for.
1141        #[arg(value_parser = NameOrAddress::from_str)]
1142        who: NameOrAddress,
1143
1144        /// The storage slot numbers (hex or decimal).
1145        #[arg(value_parser = parse_slot)]
1146        slots: Vec<B256>,
1147
1148        #[command(flatten)]
1149        rpc: RpcOpts,
1150    },
1151
1152    /// Compute a Tempo TIP-20 channel reserve channel ID.
1153    #[command(name = "channel-id")]
1154    ChannelId {
1155        /// Channel payer address.
1156        #[arg(value_parser = NameOrAddress::from_str)]
1157        payer: NameOrAddress,
1158
1159        /// Channel payee address.
1160        #[arg(value_parser = NameOrAddress::from_str)]
1161        payee: NameOrAddress,
1162
1163        /// TIP-20 token address locked by the channel.
1164        #[arg(value_parser = NameOrAddress::from_str)]
1165        token: NameOrAddress,
1166
1167        /// User-supplied channel salt.
1168        salt: B256,
1169
1170        /// Optional relayer allowed to submit settlements for the payee.
1171        #[arg(long, value_parser = NameOrAddress::from_str)]
1172        operator: Option<NameOrAddress>,
1173
1174        /// Optional voucher signer. Defaults to the zero address, meaning the payer signs.
1175        #[arg(long, value_parser = NameOrAddress::from_str)]
1176        authorized_signer: Option<NameOrAddress>,
1177
1178        /// Transaction-derived expiring nonce hash from ChannelOpened.
1179        #[arg(long, default_value_t = B256::ZERO)]
1180        expiring_nonce_hash: B256,
1181
1182        /// Channel reserve precompile address.
1183        #[arg(long, value_parser = NameOrAddress::from_str)]
1184        reserve: Option<NameOrAddress>,
1185
1186        /// The block height to query at.
1187        ///
1188        /// Can also be the tags earliest, finalized, safe, latest, or pending.
1189        #[arg(long, short = 'B')]
1190        block: Option<BlockId>,
1191
1192        #[command(flatten)]
1193        rpc: RpcOpts,
1194    },
1195
1196    /// Get the source code of a contract from a block explorer.
1197    #[command(visible_aliases = &["et", "src"])]
1198    Source {
1199        /// The contract's address.
1200        address: String,
1201
1202        /// Whether to flatten the source code.
1203        #[arg(long, short)]
1204        flatten: bool,
1205
1206        /// The output directory/file to expand source tree into.
1207        #[arg(short, value_hint = ValueHint::DirPath, alias = "path")]
1208        directory: Option<PathBuf>,
1209
1210        #[command(flatten)]
1211        etherscan: EtherscanOpts,
1212
1213        /// Alternative explorer API URL to use that adheres to the Etherscan API. If not provided,
1214        /// defaults to Etherscan.
1215        #[arg(long, env = "EXPLORER_API_URL")]
1216        explorer_api_url: Option<String>,
1217
1218        /// Alternative explorer browser URL.
1219        #[arg(long, env = "EXPLORER_URL")]
1220        explorer_url: Option<String>,
1221    },
1222
1223    /// Wallet management utilities.
1224    #[command(visible_alias = "w")]
1225    Wallet {
1226        #[command(subcommand)]
1227        command: WalletSubcommands,
1228    },
1229
1230    /// Download a contract creation code from Etherscan and RPC.
1231    #[command(visible_alias = "cc")]
1232    CreationCode(CreationCodeArgs),
1233
1234    /// Generate an artifact file, that can be used to deploy a contract locally.
1235    #[command(visible_alias = "ar")]
1236    Artifact(ArtifactArgs),
1237
1238    /// Display constructor arguments used for the contract initialization.
1239    #[command(visible_alias = "cra")]
1240    ConstructorArgs(ConstructorArgsArgs),
1241
1242    /// Generate a Solidity interface from a given ABI
1243    ///
1244    /// Currently does not support ABI encoder v2.
1245    ///
1246    /// Examples:
1247    /// - cast interface $TOKEN --etherscan-api-key $KEY (fetch the ABI from Etherscan)
1248    /// - cast interface ./out/Counter.sol/Counter.json (load a local ABI file)
1249    #[command(verbatim_doc_comment, visible_alias = "i")]
1250    Interface(InterfaceArgs),
1251
1252    /// Generate a rust binding from a given ABI.
1253    #[command(visible_alias = "bi")]
1254    Bind(BindArgs),
1255
1256    /// Convert Beacon payload to execution payload.
1257    #[command(visible_alias = "b2e")]
1258    B2EPayload(B2EPayloadArgs),
1259
1260    /// Get the selector for a function
1261    ///
1262    /// Examples:
1263    /// - cast sig "transfer(address,uint256)"
1264    /// - cast sig "deposit(uint256)" 2 (optimize for 2 leading zero bytes)
1265    #[command(verbatim_doc_comment, visible_alias = "si")]
1266    Sig {
1267        /// The function signature, e.g. transfer(address,uint256).
1268        sig: Option<String>,
1269
1270        /// Optimize signature to contain provided amount of leading zeroes in selector.
1271        #[arg(conflicts_with = "json")]
1272        optimize: Option<usize>,
1273    },
1274
1275    /// Generate a deterministic contract address using CREATE2.
1276    #[command(visible_alias = "c2")]
1277    Create2(Create2Args),
1278
1279    /// Get the block number closest to the provided timestamp.
1280    #[command(visible_alias = "f")]
1281    FindBlock(FindBlockArgs),
1282
1283    /// Generate shell completions script.
1284    #[command(visible_alias = "com")]
1285    Completions {
1286        #[arg(value_enum)]
1287        shell: foundry_cli::clap::Shell,
1288    },
1289
1290    /// Runs a published transaction in a local environment and prints the trace
1291    ///
1292    /// Examples:
1293    /// - cast run $TX_HASH
1294    /// - cast run $TX_HASH --quick (only use the state from the previous block)
1295    /// - cast run $TX_HASH --debug (open the transaction in the debugger)
1296    #[command(verbatim_doc_comment, visible_alias = "r")]
1297    Run(RunArgs),
1298
1299    /// Perform a raw JSON-RPC request
1300    ///
1301    /// Examples:
1302    /// - cast rpc eth_blockNumber
1303    /// - cast rpc eth_getBlockByNumber 0x123 false
1304    /// - cast rpc eth_getBlockByNumber '["0x123", false]' --raw
1305    #[command(verbatim_doc_comment, visible_alias = "rp")]
1306    Rpc(RpcArgs),
1307
1308    /// Formats a string into bytes32 encoding.
1309    #[command(name = "format-bytes32-string", visible_aliases = &["--format-bytes32-string"])]
1310    FormatBytes32String {
1311        /// The string to format.
1312        string: Option<String>,
1313    },
1314
1315    /// Parses a string from bytes32 encoding.
1316    #[command(name = "parse-bytes32-string", visible_aliases = &["--parse-bytes32-string"])]
1317    ParseBytes32String {
1318        /// The string to parse.
1319        bytes: Option<String>,
1320    },
1321    #[command(name = "parse-bytes32-address", visible_aliases = &["--parse-bytes32-address"])]
1322    #[command(about = "Parses a checksummed address from bytes32 encoding.")]
1323    ParseBytes32Address {
1324        #[arg(value_name = "BYTES")]
1325        bytes: Option<String>,
1326    },
1327
1328    /// Decodes a raw signed EIP 2718 typed transaction
1329    #[command(visible_aliases = &["dt", "decode-tx"])]
1330    DecodeTransaction {
1331        /// Encoded transaction
1332        tx: Option<String>,
1333
1334        /// Override the network used to decode the transaction.
1335        ///
1336        /// By default, cast decodes with Foundry's transaction envelope, which recognizes
1337        /// standard Ethereum txs and Foundry-supported network-specific tx types such as Tempo.
1338        #[arg(long, short, num_args = 1, value_name = "NETWORK")]
1339        network: Option<NetworkVariant>,
1340    },
1341
1342    /// Recovery an EIP-7702 authority from a Authorization JSON string.
1343    #[command(visible_aliases = &["decode-auth"])]
1344    RecoverAuthority { auth: String },
1345
1346    /// Extracts function selectors and arguments from bytecode
1347    #[command(visible_alias = "sel")]
1348    Selectors {
1349        /// The hex-encoded bytecode.
1350        bytecode: Option<String>,
1351
1352        /// Resolve the function signatures for the extracted selectors using <https://openchain.xyz>
1353        #[arg(long, short)]
1354        resolve: bool,
1355    },
1356
1357    /// Inspect the TxPool of a node.
1358    #[command(visible_alias = "tp")]
1359    TxPool {
1360        #[command(subcommand)]
1361        command: TxPoolSubcommands,
1362    },
1363    /// Estimates the data availability size of a given opstack block.
1364    #[cfg(feature = "optimism")]
1365    #[command(name = "da-estimate")]
1366    DAEstimate(DAEstimateArgs),
1367
1368    /// ERC20 token operations.
1369    #[command(visible_alias = "erc20")]
1370    Erc20Token {
1371        #[command(subcommand)]
1372        command: Erc20Subcommand,
1373    },
1374
1375    /// TIP-20 token operations (Tempo).
1376    #[command(visible_alias = "tip20")]
1377    Tip20Token {
1378        #[command(subcommand)]
1379        command: Tip20Subcommand,
1380    },
1381
1382    /// Account-level receive policy operations (Tempo).
1383    #[command(name = "receive-policy")]
1384    ReceivePolicy {
1385        #[command(subcommand)]
1386        command: ReceivePolicySubcommand,
1387    },
1388
1389    /// TIP-403 policy registry operations (Tempo).
1390    #[command(name = "tip403")]
1391    Tip403 {
1392        #[command(subcommand)]
1393        command: Tip403Subcommand,
1394    },
1395
1396    /// T7 storage credits operations (Tempo).
1397    #[command(name = "storage-credits", visible_alias = "sc")]
1398    StorageCredits {
1399        #[command(subcommand)]
1400        command: StorageCreditsSubcommand,
1401    },
1402
1403    /// Tempo keychain (access key) management.
1404    #[command(visible_alias = "kc")]
1405    Keychain {
1406        #[command(subcommand)]
1407        command: KeychainSubcommand,
1408    },
1409
1410    /// Tempo key authorization RLP helpers.
1411    #[command(name = "key-authorization", visible_alias = "key-auth")]
1412    KeyAuthorization {
1413        #[command(subcommand)]
1414        command: KeyAuthorizationSubcommand,
1415    },
1416
1417    /// Tempo wallet integration (login, etc.).
1418    Tempo {
1419        #[command(subcommand)]
1420        command: TempoSubcommand,
1421    },
1422
1423    /// TIP-1022 virtual address registry operations (Tempo).
1424    #[command(visible_alias = "vaddr")]
1425    VirtualAddress {
1426        #[command(subcommand)]
1427        command: VaddrSubcommand,
1428    },
1429
1430    #[command(name = "trace")]
1431    Trace(TraceArgs),
1432}
1433
1434/// CLI arguments for `cast --to-base`.
1435#[derive(Debug, Parser)]
1436pub struct ToBaseArgs {
1437    /// The value to convert.
1438    #[arg(allow_hyphen_values = true)]
1439    pub value: Option<String>,
1440
1441    /// The input base.
1442    #[arg(long, short = 'i')]
1443    pub base_in: Option<String>,
1444}
1445
1446pub fn parse_slot(s: &str) -> Result<B256> {
1447    let slot = U256::from_str(s).map_err(|e| eyre::eyre!("Could not parse slot number: {e}"))?;
1448    Ok(B256::from(slot))
1449}
1450
1451#[cfg(test)]
1452mod tests {
1453    use super::*;
1454    use crate::SimpleCast;
1455    use alloy_rpc_types::{BlockNumberOrTag, RpcBlockHash};
1456    use clap::CommandFactory;
1457
1458    #[test]
1459    fn verify_cli() {
1460        Cast::command().debug_assert();
1461    }
1462
1463    #[test]
1464    fn parse_proof_slot() {
1465        let args: Cast = Cast::parse_from([
1466            "foundry-cli",
1467            "proof",
1468            "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
1469            "0",
1470            "1",
1471            "0x0000000000000000000000000000000000000000000000000000000000000000",
1472            "0x1",
1473            "0x01",
1474        ]);
1475        match args.cmd {
1476            CastSubcommand::Proof { slots, .. } => {
1477                assert_eq!(
1478                    slots,
1479                    vec![
1480                        B256::ZERO,
1481                        U256::from(1).into(),
1482                        B256::ZERO,
1483                        U256::from(1).into(),
1484                        U256::from(1).into()
1485                    ]
1486                );
1487            }
1488            _ => unreachable!(),
1489        };
1490    }
1491
1492    #[test]
1493    fn parse_call_data() {
1494        let args: Cast = Cast::parse_from([
1495            "foundry-cli",
1496            "calldata",
1497            "f()",
1498            "5c9d55b78febcc2061715ba4f57ecf8ea2711f2c",
1499            "2",
1500        ]);
1501        match args.cmd {
1502            CastSubcommand::CalldataEncode { args, .. } => {
1503                assert_eq!(
1504                    args,
1505                    vec!["5c9d55b78febcc2061715ba4f57ecf8ea2711f2c".to_string(), "2".to_string()]
1506                )
1507            }
1508            _ => unreachable!(),
1509        };
1510    }
1511
1512    #[test]
1513    fn parse_call_data_with_file() {
1514        let args: Cast = Cast::parse_from(["foundry-cli", "calldata", "f()", "--file", "test.txt"]);
1515        match args.cmd {
1516            CastSubcommand::CalldataEncode { sig, file, args } => {
1517                assert_eq!(sig, "f()".to_string());
1518                assert_eq!(file, Some(PathBuf::from("test.txt")));
1519                assert!(args.is_empty());
1520            }
1521            _ => unreachable!(),
1522        };
1523    }
1524
1525    // <https://github.com/foundry-rs/book/issues/1019>
1526    #[test]
1527    fn parse_signature() {
1528        let args: Cast = Cast::parse_from([
1529            "foundry-cli",
1530            "sig",
1531            "__$_$__$$$$$__$$_$$$_$$__$$___$$(address,address,uint256)",
1532        ]);
1533        match args.cmd {
1534            CastSubcommand::Sig { sig, .. } => {
1535                let sig = sig.unwrap();
1536                assert_eq!(
1537                    sig,
1538                    "__$_$__$$$$$__$$_$$$_$$__$$___$$(address,address,uint256)".to_string()
1539                );
1540
1541                let selector = SimpleCast::get_selector(&sig, 0).unwrap();
1542                assert_eq!(selector.0, "0x23b872dd".to_string());
1543            }
1544            _ => unreachable!(),
1545        };
1546    }
1547
1548    #[test]
1549    fn parse_block_ids() {
1550        struct TestCase {
1551            input: String,
1552            expect: BlockId,
1553        }
1554
1555        let test_cases = [
1556            TestCase {
1557                input: "0".to_string(),
1558                expect: BlockId::Number(BlockNumberOrTag::Number(0u64)),
1559            },
1560            TestCase {
1561                input: "0x56462c47c03df160f66819f0a79ea07def1569f8aac0fe91bb3a081159b61b4a"
1562                    .to_string(),
1563                expect: BlockId::Hash(RpcBlockHash::from_hash(
1564                    "0x56462c47c03df160f66819f0a79ea07def1569f8aac0fe91bb3a081159b61b4a"
1565                        .parse()
1566                        .unwrap(),
1567                    None,
1568                )),
1569            },
1570            TestCase {
1571                input: "latest".to_string(),
1572                expect: BlockId::Number(BlockNumberOrTag::Latest),
1573            },
1574            TestCase {
1575                input: "earliest".to_string(),
1576                expect: BlockId::Number(BlockNumberOrTag::Earliest),
1577            },
1578            TestCase {
1579                input: "pending".to_string(),
1580                expect: BlockId::Number(BlockNumberOrTag::Pending),
1581            },
1582            TestCase { input: "safe".to_string(), expect: BlockId::Number(BlockNumberOrTag::Safe) },
1583            TestCase {
1584                input: "finalized".to_string(),
1585                expect: BlockId::Number(BlockNumberOrTag::Finalized),
1586            },
1587        ];
1588
1589        for test in test_cases {
1590            let result: BlockId = test.input.parse().unwrap();
1591            assert_eq!(result, test.expect);
1592        }
1593    }
1594}