pcli/command/
threshold.rs

1use anyhow::Result;
2use penumbra_sdk_custody::threshold::Terminal;
3
4use crate::{
5    config::{CustodyConfig, GovernanceCustodyConfig},
6    terminal::ActualTerminal,
7    App,
8};
9
10#[derive(Debug, clap::Subcommand)]
11pub enum ThresholdCmd {
12    /// Contribute to signing a transaction with threshold custody
13    Sign,
14}
15
16impl ThresholdCmd {
17    pub fn offline(&self) -> bool {
18        match self {
19            ThresholdCmd::Sign => true,
20        }
21    }
22
23    #[tracing::instrument(skip(self, app))]
24    pub async fn exec(&self, app: &mut App) -> Result<()> {
25        let config = match app.config.custody.clone() {
26            CustodyConfig::Threshold(config) => Some(config),
27            CustodyConfig::Encrypted(config) => {
28                let password = ActualTerminal::default().get_password().await?;
29                config.convert_to_threshold(&password)?
30            }
31            _ => None, // If not threshold, we can't sign using threshold config
32        };
33        let governance_config = match &app.config.governance_custody {
34            Some(GovernanceCustodyConfig::Threshold(governance_config)) => {
35                Some(governance_config.clone())
36            }
37            None => config.clone(), // If no governance config, use regular one
38            _ => None,              // If not threshold, we can't sign using governance config
39        };
40        match self {
41            ThresholdCmd::Sign => {
42                penumbra_sdk_custody::threshold::follow(
43                    config.as_ref(),
44                    governance_config.as_ref(),
45                    &ActualTerminal::default(),
46                )
47                .await
48            }
49        }
50    }
51}