signer-core 0.3.2

Signer core package.
Documentation
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>,
}