soroban_cli/config/
sign_with.rs1use crate::{
2 config::UnresolvedMuxedAccount,
3 print::Print,
4 signer::{self, ledger::LedgerEntry, Signer, SignerKind},
5 xdr::{self, TransactionEnvelope},
6};
7
8use super::{
9 locator,
10 network::{self, Network},
11 secret,
12};
13use crate::commands::HEADING_SIGNING;
14
15#[derive(thiserror::Error, Debug)]
16pub enum Error {
17 #[error(transparent)]
18 Network(#[from] network::Error),
19 #[error(transparent)]
20 Signer(#[from] signer::Error),
21 #[error(transparent)]
22 Secret(#[from] secret::Error),
23 #[error(transparent)]
24 Locator(#[from] locator::Error),
25 #[error(transparent)]
26 Rpc(#[from] soroban_rpc::Error),
27 #[error("No sign with key provided")]
28 NoSignWithKey,
29 #[error(transparent)]
30 StrKey(#[from] stellar_strkey::DecodeError),
31 #[error(transparent)]
32 Xdr(#[from] xdr::Error),
33 #[error(transparent)]
34 Ledger(#[from] signer::ledger::Error),
35}
36
37#[derive(Debug, clap::Args, Clone, Default)]
38#[group(skip)]
39pub struct Args {
40 #[arg(
42 long,
43 env = "STELLAR_SIGN_WITH_KEY",
44 hide_env_values = true,
45 help_heading = HEADING_SIGNING
46 )]
47 pub sign_with_key: Option<String>,
48
49 #[arg(long, conflicts_with = "sign_with_lab", help_heading = HEADING_SIGNING)]
50 pub hd_path: Option<u32>,
52
53 #[allow(clippy::doc_markdown)]
54 #[arg(
56 long,
57 conflicts_with = "sign_with_key",
58 env = "STELLAR_SIGN_WITH_LAB",
59 help_heading = HEADING_SIGNING
60 )]
61 pub sign_with_lab: bool,
62
63 #[arg(
65 long,
66 conflicts_with = "sign_with_key",
67 conflicts_with = "sign_with_lab",
68 env = "STELLAR_SIGN_WITH_LEDGER",
69 help_heading = HEADING_SIGNING
70 )]
71 pub sign_with_ledger: bool,
72
73 #[arg(long, help_heading = HEADING_SIGNING)]
75 pub auto_sign: bool,
76}
77
78impl Args {
79 pub async fn sign_tx_env(
81 &self,
82 tx: &TransactionEnvelope,
83 locator: &locator::Args,
84 network: &Network,
85 quiet: bool,
86 default_signer_account: Option<&UnresolvedMuxedAccount>,
87 ) -> Result<TransactionEnvelope, Error> {
88 let print = Print::new(quiet);
89 let signer = if self.sign_with_lab {
90 Signer {
91 kind: SignerKind::Lab,
92 print,
93 }
94 } else if self.sign_with_ledger {
95 Signer {
96 kind: SignerKind::Ledger(LedgerEntry {
97 hd_path: self.hd_path.unwrap_or_default(),
98 public_key: None,
99 }),
100 print,
101 }
102 } else {
103 let key_or_name = match self.sign_with_key.as_deref() {
105 Some(k) => k,
106 None => match default_signer_account {
107 Some(UnresolvedMuxedAccount::AliasOrSecret(ref s)) => s.as_str(),
108 _ => return Err(Error::NoSignWithKey),
109 },
110 };
111
112 let secret = locator.get_secret_key_with_hd_path(key_or_name, self.hd_path)?;
113 secret.signer(self.hd_path, print)?
114 };
115 Ok(signer.sign_tx_env(tx, network).await?)
116 }
117}