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