use crate::{extended_key::private_key::Error as XPrvError, DerivationPath, ExtendedPrivateKey, PrivateKey}; use keyfork_mnemonic_util::Mnemonic; use serde::{Deserialize, Serialize}; #[derive(Debug, thiserror::Error)] pub enum DerivationError { #[error("algorithm not supported")] Algorithm, #[error("{0}")] ExtendedPrivateKey(#[from] XPrvError), } pub type Result = std::result::Result; #[derive(Serialize, Deserialize, Clone, Debug)] pub enum DerivationAlgorithm { Ed25519, Secp256k1, } impl DerivationAlgorithm { pub fn derive(&self, seed: Vec, path: &DerivationPath) -> Result { match self { #[cfg(feature = "ed25519")] Self::Ed25519 => { let key = ExtendedPrivateKey::::new(seed)?; let derived_key = key.derive_path(path)?; Ok(DerivationResponse { algorithm: self.clone(), data: PrivateKey::to_bytes(&derived_key.private_key).to_vec(), }) } #[cfg(feature = "secp256k1")] Self::Secp256k1 => { let key = ExtendedPrivateKey::::new(seed)?; let derived_key = key.derive_path(path)?; Ok(DerivationResponse { algorithm: self.clone(), data: PrivateKey::to_bytes(&derived_key.private_key).to_vec(), }) } #[allow(unreachable_patterns)] _ => Err(DerivationError::Algorithm), } } } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct DerivationRequest { algorithm: DerivationAlgorithm, path: DerivationPath, } impl DerivationRequest { pub fn new(algorithm: DerivationAlgorithm, path: DerivationPath) -> Self { Self { algorithm, path } } pub fn derive_with_mnemonic(&self, mnemonic: &Mnemonic) -> Result { self.derive_with_master_seed(mnemonic.seed()) } pub fn derive_with_master_seed(&self, seed: Vec) -> Result { self.algorithm.derive(seed, &self.path) } } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct DerivationResponse { pub algorithm: DerivationAlgorithm, pub data: Vec, }