use crate::{
derive_child::{derive_child_key, generate_public_key},
prelude::*,
};
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(deserialize_with = "deserialize_from_hex")]
root_key_bytes: [u8; 32],
#[serde(deserialize_with = "deserialize_from_hex")]
root_chain_code: [u8; 32],
}
pub static CONFIG: Lazy<Config> = Lazy::new(|| envy::from_env().expect("some env vars missing"));
fn deserialize_from_hex<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
let hex_string: String = serde::Deserialize::deserialize(deserializer)?;
hex_to_slice(hex_string).map_err(D::Error::custom)
}
pub fn hex_to_slice(hex_string: String) -> Result<[u8; 32], &'static str> {
Vec::from_hex(hex_string)
.map_err(|_e| "Invalid byte array size")?
.try_into()
.map_err(|_e| "Invalid byte array size")
}
impl Config {
pub fn derive_child_key(&self, index: u32) -> (SecretKey, [u8; 32], PublicKey) {
let Config {
root_key_bytes,
root_chain_code,
} = *self;
let (child_key, child_chain_code) =
derive_child_key(&root_key_bytes, &root_chain_code, index);
let child_public_key = generate_public_key(&child_key);
(child_key, child_chain_code, child_public_key)
}
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
use crate::CONFIG;
#[test]
fn show_config_with_root_public() {
dotenv().ok();
assert_debug_snapshot!(CONFIG.derive_child_key(0).2);
}
#[test]
fn ascii_to_hex() {
let hex_string = hex::encode("s1");
dbg!(hex_string);
let hex_string = hex::encode("s2");
dbg!(hex_string);
}
}