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 ) -> Result<xdr::ScAddress, Error> {
48 let alias = match self {
49 UnresolvedScAddress::Resolved(addr) => return Ok(addr),
50 UnresolvedScAddress::Alias(alias) => alias,
51 };
52 let contract = UnresolvedContract::resolve_alias(&alias, locator, network_passphrase);
53 let key = locator.read_key(&alias);
54 match (contract, key) {
55 (Ok(contract), Ok(_)) => {
56 eprintln!(
57 "Warning: ScAddress alias {alias} is ambiguous, assuming it is a contract"
58 );
59 Ok(xdr::ScAddress::Contract(stellar_xdr::curr::ContractId(
60 xdr::Hash(contract.0),
61 )))
62 }
63 (Ok(contract), _) => Ok(xdr::ScAddress::Contract(stellar_xdr::curr::ContractId(
64 xdr::Hash(contract.0),
65 ))),
66 (_, Ok(key)) => Ok(xdr::ScAddress::Account(
67 key.muxed_account(None)?.account_id(),
68 )),
69 _ => Err(Error::AccountAliasNotFound(alias)),
70 }
71 }
72}