#[cfg(test)]
mod unit_tests;
use crate::{
config::ConfigValidation,
core::{KeyPair, KeyStorage},
crypto::translator::KeyPairInstance,
errors::{KeyManagementError, Result},
KeyIdentifier, KeyType, NewKeyId,
};
use secrecy::Secret;
use std::collections::HashMap;
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct InMemoryKeyManagerConfig {
pub initial_keys: Vec<(KeyType, String)>,
}
impl ConfigValidation for InMemoryKeyManagerConfig {
fn validate(&self) -> Result<()> {
for (key_type, secret) in &self.initial_keys {
KeyPairInstance::from_secret(Secret::new(secret.clone()), *key_type)?;
}
Ok(())
}
}
pub(crate) struct InMemoryKeyManager {
pub(crate) keypairs: HashMap<KeyIdentifier, KeyPairInstance>,
}
impl InMemoryKeyManager {
pub(crate) fn new(config: InMemoryKeyManagerConfig) -> Self {
let keypairs: HashMap<KeyIdentifier, KeyPairInstance> = config
.initial_keys
.into_iter()
.map(|(key_type, secret)| {
let translator =
KeyPairInstance::from_secret(Secret::new(secret), key_type).unwrap();
let address = translator.identifier();
(address, translator)
})
.collect();
InMemoryKeyManager { keypairs }
}
}
impl KeyStorage for InMemoryKeyManager {
fn store_has_key(&self, id: &KeyIdentifier) -> Result<bool> {
Ok(self.keypairs.contains_key(id))
}
fn get_key(&self, id: &KeyIdentifier) -> Result<KeyPairInstance> {
let key_pair = self
.keypairs
.get(id)
.ok_or(KeyManagementError::AddressNotFound {
address: id.value.clone(),
})?;
let secret = key_pair.to_secret()?;
let key_type = key_pair.get_key_type();
KeyPairInstance::from_secret(secret, key_type)
}
fn get_keys(&self) -> Result<Vec<KeyIdentifier>> {
Ok(self.keypairs.keys().cloned().collect())
}
fn save_key(&mut self, key_pair: &KeyPairInstance) -> Result<NewKeyId> {
let id = key_pair.identifier();
let secret = key_pair.to_secret()?;
let key_type = key_pair.get_key_type();
let persisted = KeyPairInstance::from_secret(secret, key_type)?;
self.keypairs.insert(id.clone(), persisted);
Ok(NewKeyId {
id,
pubkey: key_pair.public(),
})
}
}