nostr_rust

My fork of nostr_rust
git clone git://jb55.com/nostr_rust
Log | Files | Refs | README

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 }