Skip to main content

cast/
opts.rs

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