events.rs (4696B)
1 use std::fmt; 2 3 use secp256k1::{KeyPair, SECP256K1}; 4 use serde_derive::{Deserialize, Serialize}; 5 use serde_json::json; 6 7 use crate::Identity; 8 9 /// EventPrepare is the struct used to prepare an event before publishing it (signing it and assigning it an id) 10 #[derive(Serialize, Deserialize, Debug)] 11 pub struct EventPrepare { 12 /// 32-bytes hex-encoded public key of the event creator 13 #[serde(rename = "pubkey")] 14 pub pub_key: String, 15 /// unix timestamp in seconds 16 pub created_at: u64, 17 /// integer 18 /// 0: NostrEvent 19 pub kind: u8, 20 /// Tags 21 pub tags: Vec<Vec<String>>, 22 /// arbitrary string 23 pub content: String, 24 } 25 26 impl EventPrepare { 27 /// get_content returns the content of the event to be signed 28 /// # Example 29 /// ```rust 30 /// use nostr_rust::{events::EventPrepare, utils::get_timestamp}; 31 /// 32 /// let actual_time = get_timestamp(); 33 /// 34 /// let event = EventPrepare { 35 /// pub_key: env!("PUBLIC_KEY").to_string(), 36 /// created_at: get_timestamp(), 37 /// kind: 0, 38 /// tags: vec![], 39 /// content: "content".to_string(), 40 /// }; 41 /// 42 /// assert_eq!(event.get_content(), format!("[0,\"c5aec31e83bdf980939b5ef7c6bcaa2be8bd39d38667da58ba6dba240eb8b69d\",{},0,[],\"content\"]", actual_time)); 43 /// ``` 44 pub fn get_content(&self) -> String { 45 json!([ 46 0, 47 self.pub_key, 48 self.created_at, 49 self.kind, 50 self.tags, 51 self.content 52 ]) 53 .to_string() 54 } 55 56 /// Get the id of the event which is the sha256 hash of the content 57 /// # Example 58 /// ```rust 59 /// use nostr_rust::{events::EventPrepare}; 60 /// 61 /// let event = EventPrepare { 62 /// pub_key: env!("PUBLIC_KEY").to_string(), 63 /// created_at: 0, // Don't use this in production 64 /// kind: 0, 65 /// tags: vec![], 66 /// content: "content".to_string(), 67 /// }; 68 /// 69 /// assert_eq!(event.get_content_id(), "4a57aad22fc0fd374e8ceeaaaf8817fa6cb661ca2229c66309d7dba69dfe2359"); 70 /// ``` 71 pub fn get_content_id(&self) -> String { 72 sha256::digest(self.get_content()) 73 } 74 75 /// Transform the event to NostrEvent 76 /// # Example 77 /// ```rust 78 /// use std::str::FromStr; 79 /// use nostr_rust::{events::EventPrepare, Identity}; 80 /// 81 /// let event = EventPrepare { 82 /// pub_key: env!("PUBLIC_KEY").to_string(), 83 /// created_at: 0, // Don't use this in production 84 /// kind: 0, 85 /// tags: vec![], 86 /// content: "content".to_string(), 87 /// }; 88 /// 89 /// let identity = Identity::from_str(env!("SECRET_KEY")).unwrap(); 90 /// let nostr_event = event.to_event(&identity); 91 /// assert_eq!(nostr_event.id, "4a57aad22fc0fd374e8ceeaaaf8817fa6cb661ca2229c66309d7dba69dfe2359"); 92 /// assert_eq!(nostr_event.content, "content"); 93 /// assert_eq!(nostr_event.kind, 0); 94 /// assert_eq!(nostr_event.tags.len(), 0); 95 /// assert_eq!(nostr_event.created_at, 0); 96 /// assert_eq!(nostr_event.pub_key, env!("PUBLIC_KEY")); 97 /// assert_eq!(nostr_event.sig.len(), 128); 98 /// ``` 99 pub fn to_event(&self, secret_key: &Identity) -> Event { 100 let message = secp256k1::Message::from_hashed_data::<secp256k1::hashes::sha256::Hash>( 101 self.get_content().as_bytes(), 102 ); 103 104 let signature = SECP256K1 105 .sign_schnorr( 106 &message, 107 &KeyPair::from_secret_key(SECP256K1, &secret_key.secret_key), 108 ) 109 .to_string(); 110 111 Event { 112 id: self.get_content_id(), 113 pub_key: self.pub_key.clone(), 114 created_at: self.created_at, 115 kind: self.kind, 116 tags: self.tags.clone(), 117 content: self.content.clone(), 118 sig: signature, 119 } 120 } 121 } 122 123 /// Event is the struct used to represent a Nostr event 124 #[derive(Serialize, Deserialize, Debug, Clone)] 125 pub struct Event { 126 /// 32-bytes sha256 of the the serialized event data 127 pub id: String, 128 /// 32-bytes hex-encoded public key of the event creator 129 #[serde(rename = "pubkey")] 130 pub pub_key: String, 131 /// unix timestamp in seconds 132 pub created_at: u64, 133 /// integer 134 /// 0: NostrEvent 135 pub kind: u8, 136 /// Tags 137 pub tags: Vec<Vec<String>>, 138 /// arbitrary string 139 pub content: String, 140 /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field 141 pub sig: String, 142 } 143 144 impl fmt::Display for Event { 145 /// Return the serialized event 146 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 147 write!(f, "{}", serde_json::to_string(&self).unwrap()) 148 } 149 }