comment.rs (2801B)
1 //! Sealed authoring for strict NIP-22 Comment events. 2 3 use crate::{ 4 error::Error, 5 events::sealed::SealedBuilderCore, 6 types::{ 7 ExternalSigningRequest, RadrootsNostrEvent, RadrootsNostrKeys, RadrootsNostrPublicKey, 8 RadrootsNostrTimestamp, 9 }, 10 }; 11 use radroots_event::post::comment::AuthoredNip22Comment; 12 use radroots_event_codec::authoring::AuthoredEventBody; 13 14 /// A sealed builder for a validated strict NIP-22 Comment. 15 /// 16 /// The wrapper exposes no raw builder conversion or tag/content mutation. 17 /// 18 /// ```compile_fail 19 /// use radroots_nostr::event::Nip22CommentBuilder; 20 /// 21 /// fn expose_raw_builder(builder: Nip22CommentBuilder) { 22 /// let _: nostr::EventBuilder = builder.into(); 23 /// } 24 /// ``` 25 #[must_use = "NIP-22 Comment builders must be signed or published"] 26 pub struct Nip22CommentBuilder { 27 inner: SealedBuilderCore, 28 } 29 30 impl Nip22CommentBuilder { 31 pub fn custom_created_at(mut self, created_at: RadrootsNostrTimestamp) -> Self { 32 self.inner = self.inner.custom_created_at(created_at); 33 self 34 } 35 36 pub fn sign_with_keys(self, keys: &RadrootsNostrKeys) -> Result<RadrootsNostrEvent, Error> { 37 self.inner.sign_with_keys(keys) 38 } 39 40 pub fn into_external_signing_request( 41 self, 42 public_key: RadrootsNostrPublicKey, 43 ) -> Result<ExternalSigningRequest, Error> { 44 self.inner.into_external_signing_request(public_key) 45 } 46 } 47 48 pub fn build_nip22_comment_event( 49 comment: &AuthoredNip22Comment, 50 ) -> Result<Nip22CommentBuilder, Error> { 51 Ok(Nip22CommentBuilder { 52 inner: SealedBuilderCore::new(AuthoredEventBody::from_nip22_comment(comment)?), 53 }) 54 } 55 56 #[cfg(test)] 57 mod tests { 58 use super::*; 59 use crate::test_fixtures::FIXTURE_BOB_PUBLIC_KEY_HEX; 60 use radroots_event::{ 61 envelope::kind::{KIND_CLASSIFIED_LISTING, KIND_COMMENT}, 62 post::comment::{AuthoredNip22Comment, Nip22EventRootReference}, 63 }; 64 65 #[test] 66 fn typed_comment_builder_signs_exact_kind_and_tags() { 67 let root = Nip22EventRootReference::parse( 68 "a".repeat(64), 69 FIXTURE_BOB_PUBLIC_KEY_HEX, 70 KIND_CLASSIFIED_LISTING, 71 None, 72 ) 73 .expect("root"); 74 let comment = AuthoredNip22Comment::top_level_event("Comment", root).expect("comment"); 75 let keys = RadrootsNostrKeys::generate(); 76 let event = build_nip22_comment_event(&comment) 77 .expect("builder") 78 .custom_created_at(RadrootsNostrTimestamp::from_secs(1_800_000_000)) 79 .sign_with_keys(&keys) 80 .expect("signed event"); 81 assert_eq!(event.kind.as_u16(), KIND_COMMENT as u16); 82 assert_eq!(event.tags.len(), 6); 83 assert_eq!(event.content, "Comment"); 84 assert!(event.verify().is_ok()); 85 } 86 }