test_support.rs (2047B)
1 use std::sync::atomic::{AtomicU8, Ordering}; 2 3 use harvestcircle_domain::{ 4 Npub, Nsec, PublicKey, SafeError, SafeErrorCode, SafeMessage, SecretKeyInput, 5 }; 6 7 use crate::{GeneratedKeyMaterial, ImportedKeyMaterial, KeyMaterialProvider}; 8 9 #[derive(Default)] 10 pub(crate) struct TestKeyMaterialProvider { 11 next: AtomicU8, 12 } 13 14 impl KeyMaterialProvider for TestKeyMaterialProvider { 15 fn generate(&self) -> Result<GeneratedKeyMaterial, SafeError> { 16 let public_key = (0..=u8::MAX) 17 .find_map(|_| { 18 let candidate = self.next.fetch_add(1, Ordering::Relaxed).wrapping_add(9); 19 PublicKey::from_bytes([candidate; 32]).ok() 20 }) 21 .ok_or_else(invalid_secret_key)?; 22 let secret_byte = public_key.as_bytes()[0]; 23 Ok(GeneratedKeyMaterial::new( 24 public_key, 25 Npub::derive(public_key)?, 26 SecretKeyInput::parse(format!("{secret_byte:02x}").repeat(32))?, 27 Nsec::from_encoded( 28 "nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5".to_owned(), 29 )?, 30 )) 31 } 32 33 fn import(&self, input: SecretKeyInput) -> Result<ImportedKeyMaterial, SafeError> { 34 let discriminator = input.with_exposed_secret(|value| value.as_bytes()[0]); 35 if input.with_exposed_secret(|value| value.starts_with("nsec1qq")) { 36 return Err(invalid_secret_key()); 37 } 38 let public_key = valid_test_public_key(discriminator)?; 39 Ok(ImportedKeyMaterial::new( 40 public_key, 41 Npub::derive(public_key)?, 42 input, 43 )) 44 } 45 } 46 47 pub(crate) fn valid_test_public_key(discriminator: u8) -> Result<PublicKey, SafeError> { 48 (0..=u8::MAX) 49 .find_map(|offset| PublicKey::from_bytes([discriminator.wrapping_add(offset); 32]).ok()) 50 .ok_or_else(invalid_secret_key) 51 } 52 53 const fn invalid_secret_key() -> SafeError { 54 SafeError::new( 55 SafeErrorCode::InvalidSecretKey, 56 SafeMessage::new("The Nostr secret key is invalid."), 57 ) 58 }