cast/cmd/wallet/
list.rs
1use clap::Parser;
2use eyre::Result;
3
4use foundry_common::{fs, sh_err, sh_println};
5use foundry_config::Config;
6use foundry_wallets::multi_wallet::MultiWalletOptsBuilder;
7
8#[derive(Clone, Debug, Parser)]
10pub struct ListArgs {
11 #[arg(long, default_missing_value = "", num_args(0..=1))]
14 dir: Option<String>,
15
16 #[arg(long, short, group = "hw-wallets")]
18 ledger: bool,
19
20 #[arg(long, short, group = "hw-wallets")]
22 trezor: bool,
23
24 #[arg(long, hide = !cfg!(feature = "aws-kms"))]
26 aws: bool,
27
28 #[arg(long, group = "hw-wallets")]
30 all: bool,
31
32 #[arg(long, short, default_value = "3", requires = "hw-wallets")]
34 max_senders: Option<usize>,
35}
36
37impl ListArgs {
38 pub async fn run(self) -> Result<()> {
39 if self.dir.is_some() || self.all || (!self.ledger && !self.trezor && !self.aws) {
41 let _ = self.list_local_senders();
42 }
43
44 let list_opts = MultiWalletOptsBuilder::default()
46 .ledger(self.ledger || self.all)
47 .mnemonic_indexes(Some(vec![0]))
48 .trezor(self.trezor || self.all)
49 .aws(self.aws || self.all)
50 .interactives(0)
51 .build()
52 .expect("build multi wallet");
53
54 macro_rules! list_senders {
56 ($signers:expr, $label:literal) => {
57 match $signers.await {
58 Ok(signers) => {
59 for signer in signers.unwrap_or_default().iter() {
60 signer
61 .available_senders(self.max_senders.unwrap())
62 .await?
63 .iter()
64 .for_each(|sender| {
65 let _ = sh_println!("{} ({})", sender, $label);
66 })
67 }
68 }
69 Err(e) => {
70 if !self.all {
71 sh_err!("{}", e)?;
72 }
73 }
74 }
75 };
76 }
77
78 list_senders!(list_opts.ledgers(), "Ledger");
79 list_senders!(list_opts.trezors(), "Trezor");
80 list_senders!(list_opts.aws_signers(), "AWS");
81
82 Ok(())
83 }
84
85 fn list_local_senders(&self) -> Result<()> {
86 let keystore_path = self.dir.clone().unwrap_or_default();
87 let keystore_dir = if keystore_path.is_empty() {
88 let default_dir = Config::foundry_keystores_dir().unwrap();
90 fs::create_dir_all(&default_dir)?;
91 default_dir
92 } else {
93 dunce::canonicalize(keystore_path)?
94 };
95
96 for entry in std::fs::read_dir(keystore_dir)? {
98 let path = entry?.path();
99 if path.is_file() {
100 if let Some(file_name) = path.file_name() {
101 if let Some(name) = file_name.to_str() {
102 sh_println!("{name} (Local)")?;
103 }
104 }
105 }
106 }
107
108 Ok(())
109 }
110}