use bip39::{Language, Mnemonic};
use hkdf::Hkdf;
use sha2::Sha256;
use subxt::ext::sp_core::{sr25519, Pair};
use x25519_dalek::StaticSecret;
use zeroize::Zeroize;
use crate::user::UserErr;
const KDF_SR25519: &[u8] = b"sr25519-threshold-account";
const KDF_X25519: &[u8] = b"X25519-keypair";
pub fn get_signer_and_x25519_secret(
mnemonic: &str,
) -> Result<(sr25519::Pair, [u8; 32], StaticSecret), UserErr> {
let hkdf = get_hkdf_from_mnemonic(mnemonic)?;
let (pair_signer, seed) = get_signer_from_hkdf(&hkdf)?;
let static_secret = get_x25519_secret_from_hkdf(&hkdf)?;
Ok((pair_signer, seed, static_secret))
}
fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result<Hkdf<Sha256>, UserErr> {
let mnemonic = Mnemonic::parse_in_normalized(Language::English, mnemonic)
.map_err(|e| UserErr::Mnemonic(e.to_string()))?;
Ok(Hkdf::<Sha256>::new(None, &mnemonic.to_seed("")))
}
pub fn get_signer_from_hkdf(hkdf: &Hkdf<Sha256>) -> Result<(sr25519::Pair, [u8; 32]), UserErr> {
let mut sr25519_seed = [0u8; 32];
hkdf.expand(KDF_SR25519, &mut sr25519_seed)?;
let pair = sr25519::Pair::from_seed(&sr25519_seed);
Ok((pair, sr25519_seed))
}
fn get_x25519_secret_from_hkdf(hkdf: &Hkdf<Sha256>) -> Result<StaticSecret, UserErr> {
let mut secret = [0u8; 32];
hkdf.expand(KDF_X25519, &mut secret)?;
let static_secret = StaticSecret::from(secret);
secret.zeroize();
Ok(static_secret)
}
#[cfg(any(test, feature = "test_helpers"))]
pub fn get_signer_and_x25519_secret_from_mnemonic(
mnemonic: &str,
) -> Result<(subxt::tx::PairSigner<crate::EntropyConfig, sr25519::Pair>, StaticSecret), UserErr> {
let hkdf = get_hkdf_from_mnemonic(mnemonic)?;
let (pair, _) = get_signer_from_hkdf(&hkdf)?;
let pair_signer = subxt::tx::PairSigner::new(pair);
let static_secret = get_x25519_secret_from_hkdf(&hkdf)?;
Ok((pair_signer, static_secret))
}