use crate::config::turnkey::{Config, StoredQosOperatorKey};
use crate::pair::{HexSeed, LocalPair};
use anyhow::{anyhow, bail};
use std::path::PathBuf;
#[derive(Debug)]
pub enum OperatorSeedSource {
Value(HexSeed),
Path(PathBuf),
}
impl OperatorSeedSource {
pub fn from_args(seed: Option<HexSeed>, path: Option<PathBuf>) -> anyhow::Result<Option<Self>> {
match (seed, path) {
(Some(_), Some(_)) => {
bail!(
"--operator-seed and --operator-seed-path are mutually exclusive, \
please provide only one"
)
}
(Some(seed), None) => Ok(Some(Self::Value(seed))),
(None, Some(path)) => Ok(Some(Self::Path(path))),
(None, None) => Ok(None),
}
}
}
pub async fn load_operator_pair(source: Option<OperatorSeedSource>) -> anyhow::Result<LocalPair> {
match source {
Some(OperatorSeedSource::Value(seed)) => LocalPair::from_seed(&seed),
Some(OperatorSeedSource::Path(path)) => LocalPair::from_master_seed(&path).await,
None => {
let tvc_config = Config::load().await?;
let (alias, org_config) = tvc_config.active_org_config().ok_or_else(|| {
anyhow!(
"No active organization. Run `tvc login` first or provide \
--operator-seed or --operator-seed-path."
)
})?;
let operator_key = StoredQosOperatorKey::load(org_config)
.await?
.ok_or_else(|| {
anyhow!(
"No operator key found for org '{alias}'. Run `tvc login` first \
or provide --operator-seed or --operator-seed-path."
)
})?;
LocalPair::from_hex_seed(&operator_key.private_key)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn seed() -> HexSeed {
"ab".repeat(32).parse().unwrap()
}
#[test]
fn from_args_with_neither_is_none() {
assert!(OperatorSeedSource::from_args(None, None).unwrap().is_none());
}
#[test]
fn from_args_with_seed_is_value() {
let source = OperatorSeedSource::from_args(Some(seed()), None).unwrap();
assert!(matches!(source, Some(OperatorSeedSource::Value(_))));
}
#[test]
fn from_args_with_path_is_path() {
let source = OperatorSeedSource::from_args(None, Some(PathBuf::from("seed.hex"))).unwrap();
assert!(matches!(source, Some(OperatorSeedSource::Path(_))));
}
#[test]
fn from_args_with_both_is_an_error() {
let err = OperatorSeedSource::from_args(Some(seed()), Some(PathBuf::from("seed.hex")))
.unwrap_err();
assert!(err.to_string().contains("mutually exclusive"));
}
}