Skip to main content

soroban_cli/config/
sc_address.rs

1use std::str::FromStr;
2
3use crate::xdr;
4
5use super::{key, locator, UnresolvedContract};
6
7/// `ScAddress` can be either a resolved `xdr::ScAddress` or an alias of a `Contract` or `MuxedAccount`.
8#[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}