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