use crate::{Result, SignerRemoteResource};
use base64::{prelude::BASE64_URL_SAFE, Engine};
use schnorrkel::MiniSecretKey;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SignerUser {
pub public: SignerUserPublic,
pub prv_key: String,
}
impl SignerUser {
pub fn generete(username: &str) -> Result<Self> {
let mini_secret = schnorrkel::MiniSecretKey::generate();
let mut u = Self::from_mini_secret_key(mini_secret)?;
u.public.username = username.to_string();
Ok(u)
}
pub fn from_secret(secret: &str) -> Result<Self> {
let mini_secret =
schnorrkel::MiniSecretKey::from_bytes(&BASE64_URL_SAFE.decode(secret)?)
.map_err(|e| crate::SignerError::Msg(format!("decode secret failed: {:?}", e)))?;
Self::from_mini_secret_key(mini_secret)
}
pub(crate) fn from_mini_secret_key(mini_secret: MiniSecretKey) -> Result<Self> {
let keypair = mini_secret.expand_to_keypair(MiniSecretKey::UNIFORM_MODE);
let pub_key = BASE64_URL_SAFE.encode(keypair.public.as_ref());
let prv_key = BASE64_URL_SAFE.encode(mini_secret.as_bytes());
Ok(SignerUser {
public: SignerUserPublic {
username: String::new(),
pub_key,
..Default::default()
},
prv_key,
})
}
pub(crate) fn to_keypair(&self) -> Result<schnorrkel::Keypair> {
let keypair = schnorrkel::MiniSecretKey::from_bytes(
&base64::prelude::BASE64_URL_SAFE.decode(&self.prv_key)?,
)
.map_err(|e| crate::SignerError::Msg(format!("parse schnorrkel secret key failed {}", e)))?
.expand_to_keypair(MiniSecretKey::UNIFORM_MODE);
Ok(keypair)
}
}
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct SignerUserPublic {
pub pub_key: String,
pub username: String,
#[serde(default)]
pub avatar: Option<SignerRemoteResource>,
#[serde(default)]
pub update_time: i64,
#[serde(default)]
pub allow_endpoints: Vec<String>,
}