notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

event.rs (2954B)


      1 use crate::{Error, Pubkey};
      2 
      3 use serde::{Deserialize, Deserializer, Serialize, Serializer};
      4 use std::hash::{Hash, Hasher};
      5 
      6 /// Event is the struct used to represent a Nostr event
      7 #[derive(Serialize, Deserialize, Debug, Clone)]
      8 pub struct Event {
      9     /// 32-bytes sha256 of the the serialized event data
     10     pub id: EventId,
     11     /// 32-bytes hex-encoded public key of the event creator
     12     pub pubkey: Pubkey,
     13     /// unix timestamp in seconds
     14     pub created_at: u64,
     15     /// integer
     16     /// 0: NostrEvent
     17     pub kind: u64,
     18     /// Tags
     19     pub tags: Vec<Vec<String>>,
     20     /// arbitrary string
     21     pub content: String,
     22     /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field
     23     pub sig: String,
     24 }
     25 
     26 // Implement Hash trait
     27 impl Hash for Event {
     28     fn hash<H: Hasher>(&self, state: &mut H) {
     29         self.id.0.hash(state);
     30     }
     31 }
     32 
     33 impl PartialEq for Event {
     34     fn eq(&self, other: &Self) -> bool {
     35         self.id == other.id
     36     }
     37 }
     38 
     39 impl Eq for Event {}
     40 
     41 impl Event {
     42     pub fn from_json(s: &str) -> Result<Self, Error> {
     43         serde_json::from_str(s).map_err(Into::into)
     44     }
     45 
     46     pub fn verify(&self) -> Result<Self, Error> {
     47         return Err(Error::InvalidSignature);
     48     }
     49 
     50     /// This is just for serde sanity checking
     51     #[allow(dead_code)]
     52     pub(crate) fn new_dummy(
     53         id: &str,
     54         pubkey: &str,
     55         created_at: u64,
     56         kind: u64,
     57         tags: Vec<Vec<String>>,
     58         content: &str,
     59         sig: &str,
     60     ) -> Result<Self, Error> {
     61         Ok(Event {
     62             id: EventId::from_hex(id)?,
     63             pubkey: Pubkey::from_hex(pubkey)?,
     64             created_at,
     65             kind,
     66             tags,
     67             content: content.to_string(),
     68             sig: sig.to_string(),
     69         })
     70     }
     71 }
     72 
     73 impl std::str::FromStr for Event {
     74     type Err = Error;
     75 
     76     fn from_str(s: &str) -> Result<Self, Error> {
     77         Event::from_json(s)
     78     }
     79 }
     80 
     81 #[derive(Debug, Eq, PartialEq, Clone, Hash)]
     82 pub struct EventId([u8; 32]);
     83 
     84 impl EventId {
     85     pub fn new(id: [u8; 32]) -> Self {
     86         EventId(id)
     87     }
     88 
     89     pub fn hex(&self) -> String {
     90         hex::encode(self.bytes())
     91     }
     92 
     93     pub fn bytes(&self) -> &[u8; 32] {
     94         &self.0
     95     }
     96 
     97     pub fn from_hex(hex_str: &str) -> Result<Self, Error> {
     98         let evid = EventId(hex::decode(hex_str)?.as_slice().try_into().unwrap());
     99         Ok(evid)
    100     }
    101 }
    102 
    103 // Custom serialize function for Pubkey
    104 impl Serialize for EventId {
    105     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    106     where
    107         S: Serializer,
    108     {
    109         serializer.serialize_str(&self.hex())
    110     }
    111 }
    112 
    113 // Custom deserialize function for Pubkey
    114 impl<'de> Deserialize<'de> for EventId {
    115     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    116     where
    117         D: Deserializer<'de>,
    118     {
    119         let s = String::deserialize(deserializer)?;
    120         EventId::from_hex(&s).map_err(serde::de::Error::custom)
    121     }
    122 }