Skip to main content

soroban_cli/commands/tx/new/
set_options.rs

1use clap::Parser;
2
3use crate::{commands::tx, config::address, xdr};
4
5#[derive(Parser, Debug, Clone)]
6#[group(skip)]
7pub struct Cmd {
8    #[command(flatten)]
9    pub tx: tx::Args,
10    #[clap(flatten)]
11    pub op: Args,
12}
13
14#[derive(Debug, clap::Args, Clone)]
15#[allow(clippy::struct_excessive_bools, clippy::doc_markdown)]
16pub struct Args {
17    #[arg(long)]
18    /// Account of the inflation destination.
19    pub inflation_dest: Option<address::UnresolvedMuxedAccount>,
20    #[arg(long)]
21    /// A number from 0-255 (inclusive) representing the weight of the master key. If the weight of the master key is updated to 0, it is effectively disabled.
22    pub master_weight: Option<u8>,
23    #[arg(long)]
24    /// A number from 0-255 (inclusive) representing the threshold this account sets on all operations it performs that have a low threshold.
25    /// https://developers.stellar.org/docs/learn/encyclopedia/security/signatures-multisig#multisig
26    pub low_threshold: Option<u8>,
27    #[arg(long)]
28    /// A number from 0-255 (inclusive) representing the threshold this account sets on all operations it performs that have a medium threshold.
29    /// https://developers.stellar.org/docs/learn/encyclopedia/security/signatures-multisig#multisig
30    pub med_threshold: Option<u8>,
31    #[arg(long)]
32    /// A number from 0-255 (inclusive) representing the threshold this account sets on all operations it performs that have a high threshold.
33    /// https://developers.stellar.org/docs/learn/encyclopedia/security/signatures-multisig#multisig
34    pub high_threshold: Option<u8>,
35    #[arg(long)]
36    /// Sets the home domain of an account. See https://developers.stellar.org/docs/learn/encyclopedia/network-configuration/federation.
37    pub home_domain: Option<xdr::StringM<32>>,
38    #[arg(long, requires = "signer_weight")]
39    /// Add, update, or remove a signer from an account.
40    pub signer: Option<address::UnresolvedMuxedAccount>,
41    #[arg(long = "signer-weight", requires = "signer")]
42    /// Signer weight is a number from 0-255 (inclusive). The signer is deleted if the weight is 0.
43    pub signer_weight: Option<u8>,
44    #[arg(long, conflicts_with = "clear_required")]
45    /// When enabled, an issuer must approve an account before that account can hold its asset.
46    /// https://developers.stellar.org/docs/tokens/control-asset-access#authorization-required-0x1
47    pub set_required: bool,
48    #[arg(long, conflicts_with = "clear_revocable")]
49    /// When enabled, an issuer can revoke an existing trustline's authorization, thereby freezing the asset held by an account.
50    /// https://developers.stellar.org/docs/tokens/control-asset-access#authorization-revocable-0x2
51    pub set_revocable: bool,
52    #[arg(long, conflicts_with = "clear_clawback_enabled")]
53    /// Enables the issuing account to take back (burning) all of the asset.
54    /// https://developers.stellar.org/docs/tokens/control-asset-access#clawback-enabled-0x8
55    pub set_clawback_enabled: bool,
56    #[arg(long, conflicts_with = "clear_immutable")]
57    /// With this setting, none of the other authorization flags (`AUTH_REQUIRED_FLAG`, `AUTH_REVOCABLE_FLAG`) can be set, and the issuing account can't be merged.
58    /// https://developers.stellar.org/docs/tokens/control-asset-access#authorization-immutable-0x4
59    pub set_immutable: bool,
60    #[arg(long)]
61    pub clear_required: bool,
62    #[arg(long)]
63    pub clear_revocable: bool,
64    #[arg(long)]
65    pub clear_immutable: bool,
66    #[arg(long)]
67    pub clear_clawback_enabled: bool,
68}
69
70impl TryFrom<&Cmd> for xdr::OperationBody {
71    type Error = tx::args::Error;
72    fn try_from(cmd: &Cmd) -> Result<Self, Self::Error> {
73        let tx = &cmd.tx;
74        let mut set_flags = None;
75        let mut set_flag = |flag: xdr::AccountFlags| {
76            *set_flags.get_or_insert(0) |= flag as u32;
77        };
78        let cmd = &cmd.op;
79
80        if cmd.set_required {
81            set_flag(xdr::AccountFlags::RequiredFlag);
82        }
83        if cmd.set_revocable {
84            set_flag(xdr::AccountFlags::RevocableFlag);
85        }
86        if cmd.set_immutable {
87            set_flag(xdr::AccountFlags::ImmutableFlag);
88        }
89        if cmd.set_clawback_enabled {
90            set_flag(xdr::AccountFlags::ClawbackEnabledFlag);
91        }
92
93        let mut clear_flags = None;
94        let mut clear_flag = |flag: xdr::AccountFlags| {
95            *clear_flags.get_or_insert(0) |= flag as u32;
96        };
97        if cmd.clear_required {
98            clear_flag(xdr::AccountFlags::RequiredFlag);
99        }
100        if cmd.clear_revocable {
101            clear_flag(xdr::AccountFlags::RevocableFlag);
102        }
103        if cmd.clear_immutable {
104            clear_flag(xdr::AccountFlags::ImmutableFlag);
105        }
106        if cmd.clear_clawback_enabled {
107            clear_flag(xdr::AccountFlags::ClawbackEnabledFlag);
108        }
109
110        let signer = if let (Some(signer_account), Some(signer_weight)) =
111            (cmd.signer.as_ref(), cmd.signer_weight.as_ref())
112        {
113            let signer_key = tx.resolve_signer_key(signer_account)?;
114            Some(xdr::Signer {
115                key: signer_key,
116                weight: u32::from(*signer_weight),
117            })
118        } else {
119            None
120        };
121        let inflation_dest: Option<xdr::AccountId> = cmd
122            .inflation_dest
123            .as_ref()
124            .map(|dest| tx.resolve_account_id(dest))
125            .transpose()?;
126        Ok(xdr::OperationBody::SetOptions(xdr::SetOptionsOp {
127            inflation_dest,
128            clear_flags,
129            set_flags,
130            master_weight: cmd.master_weight.map(Into::into),
131            low_threshold: cmd.low_threshold.map(Into::into),
132            med_threshold: cmd.med_threshold.map(Into::into),
133            high_threshold: cmd.high_threshold.map(Into::into),
134            home_domain: cmd.home_domain.clone().map(Into::into),
135            signer,
136        }))
137    }
138}