Skip to main content

soroban_cli/commands/keys/
rm.rs

1use std::io::{self, BufRead, IsTerminal};
2
3use crate::commands::global;
4use crate::config::address::KeyName;
5use crate::config::locator::{self, KeyType};
6use crate::print::Print;
7
8#[derive(thiserror::Error, Debug)]
9pub enum Error {
10    #[error(transparent)]
11    Locator(#[from] locator::Error),
12    #[error("removal cancelled by user")]
13    Cancelled,
14    #[error(transparent)]
15    Io(#[from] io::Error),
16}
17
18#[derive(Debug, clap::Parser, Clone)]
19#[group(skip)]
20pub struct Cmd {
21    /// Identity to remove
22    pub name: KeyName,
23
24    /// Skip confirmation prompt
25    #[arg(long)]
26    pub force: bool,
27
28    #[command(flatten)]
29    pub config: locator::Args,
30}
31
32impl Cmd {
33    pub fn run(&self, global_args: &global::Args) -> Result<(), Error> {
34        if !self.force {
35            let print = Print::new(false);
36            let stdin = io::stdin();
37
38            // Check that the key exists before asking for confirmation
39            self.config.read_identity(&self.name)?;
40
41            // Show the prompt only when the user can see it
42            if stdin.is_terminal() {
43                let config_path = KeyType::Identity.path(&self.config.config_dir()?, &self.name);
44                print.warnln(format!(
45                    "Are you sure you want to remove the key '{}' at '{}'? This action cannot be undone. (y/N)",
46                    self.name,
47                    config_path.display()
48                ));
49            }
50            let mut response = String::new();
51            stdin.lock().read_line(&mut response)?;
52            if !response.trim().eq_ignore_ascii_case("y") {
53                return Err(Error::Cancelled);
54            }
55        }
56        Ok(self.config.remove_identity(&self.name, global_args)?)
57    }
58}