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