use clap::ValueEnum;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(
"--auth-mode=enforce requires a transaction with existing authorization entries; use a different auth mode when building new transactions"
)]
EnforceRequiresExistingAuth,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum AuthMode {
Enforce,
Root,
#[value(name = "non-root")]
NonRoot,
}
impl AuthMode {
pub fn to_rpc(self) -> soroban_rpc::AuthMode {
match self {
AuthMode::Enforce => soroban_rpc::AuthMode::Enforce,
AuthMode::Root => soroban_rpc::AuthMode::Record,
AuthMode::NonRoot => soroban_rpc::AuthMode::RecordAllowNonRoot,
}
}
}
#[derive(Debug, clap::Args, Clone, Default)]
#[group(skip)]
pub struct Args {
#[arg(
long,
env = "STELLAR_AUTH_MODE",
help_heading = crate::commands::HEADING_RPC,
)]
pub auth_mode: Option<AuthMode>,
}
impl Args {
pub fn to_rpc(&self) -> Option<soroban_rpc::AuthMode> {
self.auth_mode.map(AuthMode::to_rpc)
}
pub fn validate_not_enforce(&self) -> Result<(), Error> {
if matches!(self.auth_mode, Some(AuthMode::Enforce)) {
return Err(Error::EnforceRequiresExistingAuth);
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unset_omits_rpc_auth_mode() {
assert!(Args::default().to_rpc().is_none());
}
#[test]
fn enforce_maps_to_enforce() {
assert!(matches!(
AuthMode::Enforce.to_rpc(),
soroban_rpc::AuthMode::Enforce
));
}
#[test]
fn root_maps_to_record() {
assert!(matches!(
AuthMode::Root.to_rpc(),
soroban_rpc::AuthMode::Record
));
}
#[test]
fn non_root_maps_to_record_allow_non_root() {
assert!(matches!(
AuthMode::NonRoot.to_rpc(),
soroban_rpc::AuthMode::RecordAllowNonRoot
));
}
#[test]
fn validate_not_enforce_requires_recording_mode() {
assert!(matches!(
Args {
auth_mode: Some(AuthMode::Enforce)
}
.validate_not_enforce(),
Err(Error::EnforceRequiresExistingAuth)
));
}
#[test]
fn validate_not_enforce_allows_recording_modes() {
assert!(Args {
auth_mode: Some(AuthMode::Root)
}
.validate_not_enforce()
.is_ok());
assert!(Args {
auth_mode: Some(AuthMode::NonRoot)
}
.validate_not_enforce()
.is_ok());
assert!(Args::default().validate_not_enforce().is_ok());
}
}