local_signer.rs (3442B)
1 #![forbid(unsafe_code)] 2 3 use crate::{RadrootsAuthorityError, RadrootsEventSigner, RadrootsSignerError}; 4 use radroots_events::draft::{RadrootsFrozenEventDraft, RadrootsSignedNostrEvent}; 5 use radroots_events::ids::RadrootsPublicKey; 6 use radroots_nostr::prelude::{RadrootsNostrKeys, radroots_nostr_sign_frozen_draft}; 7 8 pub struct RadrootsLocalEventSigner { 9 keys: RadrootsNostrKeys, 10 pubkey: RadrootsPublicKey, 11 } 12 13 impl RadrootsLocalEventSigner { 14 pub fn new(keys: RadrootsNostrKeys) -> Result<Self, RadrootsAuthorityError> { 15 let pubkey = RadrootsPublicKey::parse(keys.public_key().to_hex()) 16 .map_err(|_| RadrootsAuthorityError::InvalidSignerPubkey)?; 17 Ok(Self { keys, pubkey }) 18 } 19 } 20 21 impl RadrootsEventSigner for RadrootsLocalEventSigner { 22 fn pubkey(&self) -> &RadrootsPublicKey { 23 &self.pubkey 24 } 25 26 fn sign_frozen_draft( 27 &self, 28 draft: &RadrootsFrozenEventDraft, 29 ) -> Result<RadrootsSignedNostrEvent, RadrootsSignerError> { 30 radroots_nostr_sign_frozen_draft(&self.keys, draft).map_err(|error| { 31 RadrootsSignerError::SigningFailed { 32 message: error.to_string(), 33 } 34 }) 35 } 36 } 37 38 #[cfg(test)] 39 mod tests { 40 use super::*; 41 use radroots_events::RadrootsNostrEvent; 42 use radroots_events::kinds::KIND_POST; 43 use radroots_nostr::prelude::{ 44 RadrootsNostrEventVerification, RadrootsNostrSecretKey, radroots_nostr_verify_event, 45 }; 46 47 const FIXTURE_ALICE_SECRET_KEY_HEX: &str = 48 "10c5304d6c9ae3a1a16f7860f1cc8f5e3a76225a2663b3a989a0d775919b7df5"; 49 const FIXTURE_ALICE_PUBLIC_KEY_HEX: &str = 50 "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df"; 51 52 fn fixture_keys() -> RadrootsNostrKeys { 53 let secret_key = 54 RadrootsNostrSecretKey::from_hex(FIXTURE_ALICE_SECRET_KEY_HEX).expect("secret key"); 55 RadrootsNostrKeys::new(secret_key) 56 } 57 58 fn post_draft() -> RadrootsFrozenEventDraft { 59 RadrootsFrozenEventDraft::new( 60 "radroots.social.post.v1", 61 KIND_POST, 62 1_700_000_000, 63 vec![vec!["t".to_owned(), "soil".to_owned()]], 64 "hello", 65 FIXTURE_ALICE_PUBLIC_KEY_HEX, 66 ) 67 .expect("draft") 68 } 69 70 fn verification_event(signed: &RadrootsSignedNostrEvent) -> RadrootsNostrEvent { 71 RadrootsNostrEvent { 72 id: signed.id.clone(), 73 author: signed.pubkey.clone(), 74 created_at: signed.created_at, 75 kind: signed.kind, 76 tags: signed.tags.clone(), 77 content: signed.content.clone(), 78 sig: signed.sig.clone(), 79 } 80 } 81 82 #[test] 83 fn local_signer_reports_public_key() { 84 let signer = RadrootsLocalEventSigner::new(fixture_keys()).expect("signer"); 85 86 assert_eq!(signer.pubkey().as_str(), FIXTURE_ALICE_PUBLIC_KEY_HEX); 87 } 88 89 #[test] 90 fn local_signer_signs_and_verifies_frozen_drafts() { 91 let signer = RadrootsLocalEventSigner::new(fixture_keys()).expect("signer"); 92 let draft = post_draft(); 93 94 let signed = signer.sign_frozen_draft(&draft).expect("signed"); 95 96 assert_eq!(signed.id, draft.expected_event_id); 97 assert_eq!(signed.pubkey, draft.expected_pubkey); 98 assert_eq!( 99 radroots_nostr_verify_event(&verification_event(&signed)), 100 RadrootsNostrEventVerification::Verified 101 ); 102 } 103 }