soroban_cli/commands/keys/
fund.rs1use crate::{commands::global, config::network, print::Print};
2
3use super::public_key;
4
5#[derive(thiserror::Error, Debug)]
6pub enum Error {
7 #[error(transparent)]
8 Address(#[from] public_key::Error),
9 #[error(transparent)]
10 Network(#[from] network::Error),
11}
12
13#[derive(Debug, clap::Parser, Clone)]
14#[group(skip)]
15pub struct Cmd {
16 #[command(flatten)]
17 pub network: network::Args,
18 #[command(flatten)]
20 pub address: public_key::Cmd,
21}
22
23impl Cmd {
24 pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
25 let print = Print::new(global_args.quiet);
26 let addr = self.address.public_key().await?;
27 let network = self.network.get(&self.address.locator)?;
28 let label = self
29 .address
30 .name
31 .as_ref()
32 .map_or_else(|| format!("{addr}"), ToString::to_string);
33 network.fund_address(&addr).await?;
34 print.checkln(format!(
35 "Account {} funded on {:?}",
36 label, network.network_passphrase
37 ));
38 Ok(())
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use clap::Parser;
46
47 const PUBLIC_KEY: &str = "GAKSH6AD2IPJQELTHIOWDAPYX74YELUOWJLI2L4RIPIPZH6YQIFNUSDC";
48
49 #[test]
50 fn ledger_flag_parses_without_name() {
51 let cmd = Cmd::try_parse_from(["fund", "--ledger"]).expect("--ledger alone parses");
52 assert!(cmd.address.ledger);
53 assert!(cmd.address.name.is_none());
54 }
55
56 #[test]
57 fn ledger_flag_with_hd_path_parses() {
58 let cmd = Cmd::try_parse_from(["fund", "--ledger", "--hd-path", "5"]).unwrap();
59 assert!(cmd.address.ledger);
60 assert_eq!(cmd.address.hd_path, Some(5));
61 }
62
63 #[test]
64 fn ledger_flag_conflicts_with_name() {
65 let err = Cmd::try_parse_from(["fund", PUBLIC_KEY, "--ledger"])
66 .expect_err("--ledger + name must conflict");
67 assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
68 }
69
70 #[test]
71 fn missing_name_without_ledger_is_rejected() {
72 let err = Cmd::try_parse_from(["fund"]).expect_err("name is required without --ledger");
73 assert_eq!(err.kind(), clap::error::ErrorKind::MissingRequiredArgument);
74 }
75}