diff --git a/enostr/src/client/message.rs b/enostr/src/client/message.rs index 7bd0087..10bf8ee 100644 --- a/enostr/src/client/message.rs +++ b/enostr/src/client/message.rs @@ -1,11 +1,11 @@ -use crate::{Event, Filter}; +use crate::{Filter, Note}; use serde_json::json; /// Messages sent by clients, received by relays #[derive(Debug, Eq, PartialEq)] pub enum ClientMessage { Event { - event: Event, + note: Note, }, Req { sub_id: String, @@ -14,11 +14,16 @@ pub enum ClientMessage { Close { sub_id: String, }, + Raw(String), } impl ClientMessage { - pub fn event(event: Event) -> Self { - ClientMessage::Event { event } + pub fn event(note: Note) -> Self { + ClientMessage::Event { note } + } + + pub fn raw(raw: String) -> Self { + ClientMessage::Raw(raw) } pub fn req(sub_id: String, filters: Vec) -> Self { @@ -31,7 +36,8 @@ impl ClientMessage { pub fn to_json(&self) -> String { match self { - Self::Event { event } => json!(["EVENT", event]).to_string(), + Self::Event { note } => json!(["EVENT", note]).to_string(), + Self::Raw(raw) => raw.clone(), Self::Req { sub_id, filters } => { let mut json = json!(["REQ", sub_id]); let mut filters = json!(filters); diff --git a/enostr/src/event.rs b/enostr/src/event.rs deleted file mode 100644 index f3d2689..0000000 --- a/enostr/src/event.rs +++ /dev/null @@ -1,122 +0,0 @@ -use crate::{Error, Pubkey}; - -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::hash::{Hash, Hasher}; - -/// Event is the struct used to represent a Nostr event -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Event { - /// 32-bytes sha256 of the the serialized event data - pub id: EventId, - /// 32-bytes hex-encoded public key of the event creator - pub pubkey: Pubkey, - /// unix timestamp in seconds - pub created_at: u64, - /// integer - /// 0: NostrEvent - pub kind: u64, - /// Tags - pub tags: Vec>, - /// arbitrary string - pub content: String, - /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field - pub sig: String, -} - -// Implement Hash trait -impl Hash for Event { - fn hash(&self, state: &mut H) { - self.id.0.hash(state); - } -} - -impl PartialEq for Event { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - } -} - -impl Eq for Event {} - -impl Event { - pub fn from_json(s: &str) -> Result { - serde_json::from_str(s).map_err(Into::into) - } - - pub fn verify(&self) -> Result { - return Err(Error::InvalidSignature); - } - - /// This is just for serde sanity checking - #[allow(dead_code)] - pub(crate) fn new_dummy( - id: &str, - pubkey: &str, - created_at: u64, - kind: u64, - tags: Vec>, - content: &str, - sig: &str, - ) -> Result { - Ok(Event { - id: EventId::from_hex(id)?, - pubkey: Pubkey::from_hex(pubkey)?, - created_at, - kind, - tags, - content: content.to_string(), - sig: sig.to_string(), - }) - } -} - -impl std::str::FromStr for Event { - type Err = Error; - - fn from_str(s: &str) -> Result { - Event::from_json(s) - } -} - -#[derive(Debug, Eq, PartialEq, Clone, Hash)] -pub struct EventId([u8; 32]); - -impl EventId { - pub fn new(id: [u8; 32]) -> Self { - EventId(id) - } - - pub fn hex(&self) -> String { - hex::encode(self.bytes()) - } - - pub fn bytes(&self) -> &[u8; 32] { - &self.0 - } - - pub fn from_hex(hex_str: &str) -> Result { - let evid = EventId(hex::decode(hex_str)?.as_slice().try_into().unwrap()); - Ok(evid) - } -} - -// Custom serialize function for Pubkey -impl Serialize for EventId { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.hex()) - } -} - -// Custom deserialize function for Pubkey -impl<'de> Deserialize<'de> for EventId { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - EventId::from_hex(&s).map_err(serde::de::Error::custom) - } -} diff --git a/enostr/src/filter.rs b/enostr/src/filter.rs index 984ea40..c189969 100644 --- a/enostr/src/filter.rs +++ b/enostr/src/filter.rs @@ -1,17 +1,17 @@ -use crate::{EventId, Pubkey}; +use crate::{NoteId, Pubkey}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct Filter { #[serde(skip_serializing_if = "Option::is_none")] - pub ids: Option>, + pub ids: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub authors: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub kinds: Option>, #[serde(rename = "#e")] #[serde(skip_serializing_if = "Option::is_none")] - pub events: Option>, + pub events: Option>, #[serde(rename = "#p")] #[serde(skip_serializing_if = "Option::is_none")] pub pubkeys: Option>, @@ -49,7 +49,7 @@ impl Filter { 150 } - pub fn ids(mut self, ids: Vec) -> Self { + pub fn ids(mut self, ids: Vec) -> Self { self.ids = Some(ids); self } @@ -64,7 +64,7 @@ impl Filter { self } - pub fn events(mut self, events: Vec) -> Self { + pub fn events(mut self, events: Vec) -> Self { self.events = Some(events); self } diff --git a/enostr/src/lib.rs b/enostr/src/lib.rs index 4dd122d..0d03b51 100644 --- a/enostr/src/lib.rs +++ b/enostr/src/lib.rs @@ -10,12 +10,11 @@ mod relay; pub use client::ClientMessage; pub use error::Error; -pub use event::{Event, EventId}; pub use ewebsock; pub use filter::Filter; pub use keypair::{FullKeypair, Keypair}; pub use nostr::SecretKey; -pub use note::NoteId; +pub use note::{Note, NoteId}; pub use profile::Profile; pub use pubkey::Pubkey; pub use relay::message::{RelayEvent, RelayMessage}; diff --git a/enostr/src/note.rs b/enostr/src/note.rs index 6698f28..126b30b 100644 --- a/enostr/src/note.rs +++ b/enostr/src/note.rs @@ -1,3 +1,8 @@ +use crate::{Error, Pubkey}; + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::hash::{Hash, Hasher}; + #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct NoteId([u8; 32]); @@ -9,4 +14,109 @@ impl NoteId { pub fn bytes(&self) -> &[u8; 32] { &self.0 } + + pub fn hex(&self) -> String { + hex::encode(self.bytes()) + } + + pub fn from_hex(hex_str: &str) -> Result { + let evid = NoteId(hex::decode(hex_str)?.as_slice().try_into().unwrap()); + Ok(evid) + } +} + +/// Event is the struct used to represent a Nostr event +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Note { + /// 32-bytes sha256 of the the serialized event data + pub id: NoteId, + /// 32-bytes hex-encoded public key of the event creator + pub pubkey: Pubkey, + /// unix timestamp in seconds + pub created_at: u64, + /// integer + /// 0: NostrEvent + pub kind: u64, + /// Tags + pub tags: Vec>, + /// arbitrary string + pub content: String, + /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field + pub sig: String, +} + +// Implement Hash trait +impl Hash for Note { + fn hash(&self, state: &mut H) { + self.id.0.hash(state); + } +} + +impl PartialEq for Note { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for Note {} + +impl Note { + pub fn from_json(s: &str) -> Result { + serde_json::from_str(s).map_err(Into::into) + } + + pub fn verify(&self) -> Result { + return Err(Error::InvalidSignature); + } + + /// This is just for serde sanity checking + #[allow(dead_code)] + pub(crate) fn new_dummy( + id: &str, + pubkey: &str, + created_at: u64, + kind: u64, + tags: Vec>, + content: &str, + sig: &str, + ) -> Result { + Ok(Note { + id: NoteId::from_hex(id)?, + pubkey: Pubkey::from_hex(pubkey)?, + created_at, + kind, + tags, + content: content.to_string(), + sig: sig.to_string(), + }) + } +} + +impl std::str::FromStr for Note { + type Err = Error; + + fn from_str(s: &str) -> Result { + Note::from_json(s) + } +} + +// Custom serialize function for Pubkey +impl Serialize for NoteId { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.hex()) + } +} + +// Custom deserialize function for Pubkey +impl<'de> Deserialize<'de> for NoteId { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + NoteId::from_hex(&s).map_err(serde::de::Error::custom) + } } diff --git a/src/app.rs b/src/app.rs index 52aa1d9..759cfbb 100644 --- a/src/app.rs +++ b/src/app.rs @@ -582,9 +582,9 @@ fn get_unknown_ids_filter(ids: &[UnknownId<'_>]) -> Option> { filters.push(pk_filter); } - let note_ids: Vec = ids + let note_ids: Vec = ids .iter() - .flat_map(|id| id.is_id().map(|id| enostr::EventId::new(*id))) + .flat_map(|id| id.is_id().map(|id| enostr::NoteId::new(*id))) .collect(); if !note_ids.is_empty() { filters.push(Filter::new().ids(note_ids)); diff --git a/src/note.rs b/src/note.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/note.rs @@ -0,0 +1 @@ +