soroban_cli/config/
sc_address.rs1use std::str::FromStr;
2
3use crate::xdr;
4
5use super::{key, locator, UnresolvedContract};
6
7#[allow(clippy::module_name_repetitions)]
9#[derive(Clone, Debug)]
10pub enum UnresolvedScAddress {
11 Resolved(xdr::ScAddress),
12 Alias(String),
13}
14
15impl Default for UnresolvedScAddress {
16 fn default() -> Self {
17 UnresolvedScAddress::Alias(String::default())
18 }
19}
20
21#[derive(thiserror::Error, Debug)]
22pub enum Error {
23 #[error(transparent)]
24 Locator(#[from] locator::Error),
25 #[error(transparent)]
26 Key(#[from] key::Error),
27 #[error("Account alias \"{0}\" not Found")]
28 AccountAliasNotFound(String),
29}
30
31impl FromStr for UnresolvedScAddress {
32 type Err = Error;
33
34 fn from_str(value: &str) -> Result<Self, Self::Err> {
35 Ok(xdr::ScAddress::from_str(value).map_or_else(
36 |_| UnresolvedScAddress::Alias(value.to_string()),
37 UnresolvedScAddress::Resolved,
38 ))
39 }
40}
41
42impl UnresolvedScAddress {
43 pub fn resolve(
44 self,
45 locator: &locator::Args,
46 network_passphrase: &str,
47 hd_path: Option<usize>,
48 ) -> Result<xdr::ScAddress, Error> {
49 let alias = match self {
50 UnresolvedScAddress::Resolved(addr) => return Ok(addr),
51 UnresolvedScAddress::Alias(alias) => alias,
52 };
53 let contract = UnresolvedContract::resolve_alias(&alias, locator, network_passphrase);
54 let key = locator.read_key(&alias);
55 match (contract, key) {
56 (Ok(contract), Ok(_)) => {
57 eprintln!(
58 "Warning: ScAddress alias {alias} is ambiguous, assuming it is a contract"
59 );
60 Ok(xdr::ScAddress::Contract(stellar_xdr::curr::ContractId(
61 xdr::Hash(contract.0),
62 )))
63 }
64 (Ok(contract), _) => Ok(xdr::ScAddress::Contract(stellar_xdr::curr::ContractId(
65 xdr::Hash(contract.0),
66 ))),
67 (_, Ok(key)) => Ok(xdr::ScAddress::Account(
68 key.muxed_account(hd_path)?.account_id(),
69 )),
70 _ => Err(Error::AccountAliasNotFound(alias)),
71 }
72 }
73}