soroban_cli/config/
sign_with.rs1use crate::{
2 config::UnresolvedMuxedAccount,
3 print::Print,
4 signer::{self, ledger, Signer, SignerKind},
5 xdr::{self, TransactionEnvelope},
6};
7use clap::arg;
8
9use super::{
10 locator,
11 network::{self, Network},
12 secret,
13};
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(long, env = "STELLAR_SIGN_WITH_KEY")]
42 pub sign_with_key: Option<String>,
43
44 #[arg(long, conflicts_with = "sign_with_lab")]
45 pub hd_path: Option<usize>,
47
48 #[allow(clippy::doc_markdown)]
49 #[arg(long, conflicts_with = "sign_with_key", env = "STELLAR_SIGN_WITH_LAB")]
51 pub sign_with_lab: bool,
52
53 #[arg(
55 long,
56 conflicts_with = "sign_with_key",
57 conflicts_with = "sign_with_lab",
58 env = "STELLAR_SIGN_WITH_LEDGER"
59 )]
60 pub sign_with_ledger: bool,
61}
62
63impl Args {
64 pub async fn sign_tx_env(
66 &self,
67 tx: &TransactionEnvelope,
68 locator: &locator::Args,
69 network: &Network,
70 quiet: bool,
71 default_signer_account: Option<&UnresolvedMuxedAccount>,
72 ) -> Result<TransactionEnvelope, Error> {
73 let print = Print::new(quiet);
74 let signer = if self.sign_with_lab {
75 Signer {
76 kind: SignerKind::Lab,
77 print,
78 }
79 } else if self.sign_with_ledger {
80 let ledger = ledger::new(
81 self.hd_path
82 .unwrap_or_default()
83 .try_into()
84 .unwrap_or_default(),
85 )
86 .await?;
87 Signer {
88 kind: SignerKind::Ledger(ledger),
89 print,
90 }
91 } else {
92 let key_or_name = match self.sign_with_key.as_deref() {
94 Some(k) => k,
95 None => match default_signer_account {
96 Some(UnresolvedMuxedAccount::AliasOrSecret(ref s)) => s.as_str(),
97 _ => return Err(Error::NoSignWithKey),
98 },
99 };
100
101 let secret = locator.get_secret_key(key_or_name)?;
102 secret.signer(self.hd_path, print).await?
103 };
104 Ok(signer.sign_tx_env(tx, network).await?)
105 }
106}