soroban_cli/tx/builder/
asset.rs

1use std::str::FromStr;
2
3use crate::{
4    config::{address, locator},
5    xdr::{self, AlphaNum12, AlphaNum4, AssetCode},
6};
7
8#[derive(Clone, Debug)]
9pub enum Asset {
10    Asset(AssetCode, address::UnresolvedMuxedAccount),
11    Native,
12}
13
14#[derive(thiserror::Error, Debug)]
15pub enum Error {
16    #[error("cannot parse asset: {0}, expected format: 'native' or 'code:issuer'")]
17    CannotParseAsset(String),
18    #[error(transparent)]
19    Xdr(#[from] xdr::Error),
20    #[error(transparent)]
21    Address(#[from] address::Error),
22}
23
24impl FromStr for Asset {
25    type Err = Error;
26
27    fn from_str(value: &str) -> Result<Self, Self::Err> {
28        if value == "native" {
29            return Ok(Asset::Native);
30        }
31        let mut iter = value.splitn(2, ':');
32        let (Some(code), Some(issuer), None) = (iter.next(), iter.next(), iter.next()) else {
33            return Err(Error::CannotParseAsset(value.to_string()));
34        };
35        Ok(Asset::Asset(code.parse()?, issuer.parse()?))
36    }
37}
38
39impl Asset {
40    pub fn resolve(&self, locator: &locator::Args) -> Result<xdr::Asset, Error> {
41        Ok(match self {
42            Asset::Asset(code, issuer) => {
43                let issuer = issuer
44                    .resolve_muxed_account_sync(locator, None)?
45                    .account_id();
46                match code.clone() {
47                    AssetCode::CreditAlphanum4(asset_code) => {
48                        xdr::Asset::CreditAlphanum4(AlphaNum4 { asset_code, issuer })
49                    }
50                    AssetCode::CreditAlphanum12(asset_code) => {
51                        xdr::Asset::CreditAlphanum12(AlphaNum12 { asset_code, issuer })
52                    }
53                }
54            }
55            Asset::Native => xdr::Asset::Native,
56        })
57    }
58}