notedeck

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

commit 307b8af8f19498db514fee3e0effc4fbb7090cef
parent a16d5b3a058c2517e0960b94dd3f05c4ff43907a
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  1 Jul 2024 06:38:08 -0700

enostr: rename Event to Note

we will likely replace Note with nostrdb::Note in the future,
this just helps with that transition

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Menostr/src/client/message.rs | 16+++++++++++-----
Denostr/src/event.rs | 122-------------------------------------------------------------------------------
Menostr/src/filter.rs | 10+++++-----
Menostr/src/lib.rs | 3+--
Menostr/src/note.rs | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/app.rs | 4++--
Asrc/note.rs | 1+
7 files changed, 130 insertions(+), 136 deletions(-)

diff --git 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<Filter>) -> 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 @@ -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<Vec<String>>, - /// 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<H: Hasher>(&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<Self, Error> { - serde_json::from_str(s).map_err(Into::into) - } - - pub fn verify(&self) -> Result<Self, Error> { - 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<Vec<String>>, - content: &str, - sig: &str, - ) -> Result<Self, Error> { - 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<Self, Error> { - 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<Self, Error> { - 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - serializer.serialize_str(&self.hex()) - } -} - -// Custom deserialize function for Pubkey -impl<'de> Deserialize<'de> for EventId { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - 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 @@ -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<Vec<EventId>>, + pub ids: Option<Vec<NoteId>>, #[serde(skip_serializing_if = "Option::is_none")] pub authors: Option<Vec<Pubkey>>, #[serde(skip_serializing_if = "Option::is_none")] pub kinds: Option<Vec<u64>>, #[serde(rename = "#e")] #[serde(skip_serializing_if = "Option::is_none")] - pub events: Option<Vec<EventId>>, + pub events: Option<Vec<NoteId>>, #[serde(rename = "#p")] #[serde(skip_serializing_if = "Option::is_none")] pub pubkeys: Option<Vec<Pubkey>>, @@ -49,7 +49,7 @@ impl Filter { 150 } - pub fn ids(mut self, ids: Vec<EventId>) -> Self { + pub fn ids(mut self, ids: Vec<NoteId>) -> Self { self.ids = Some(ids); self } @@ -64,7 +64,7 @@ impl Filter { self } - pub fn events(mut self, events: Vec<EventId>) -> Self { + pub fn events(mut self, events: Vec<NoteId>) -> Self { self.events = Some(events); self } diff --git 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 @@ -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<Self, Error> { + 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<Vec<String>>, + /// 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<H: Hasher>(&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<Self, Error> { + serde_json::from_str(s).map_err(Into::into) + } + + pub fn verify(&self) -> Result<Self, Error> { + 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<Vec<String>>, + content: &str, + sig: &str, + ) -> Result<Self, Error> { + 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<Self, Error> { + Note::from_json(s) + } +} + +// Custom serialize function for Pubkey +impl Serialize for NoteId { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.hex()) + } +} + +// Custom deserialize function for Pubkey +impl<'de> Deserialize<'de> for NoteId { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + 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 @@ -582,9 +582,9 @@ fn get_unknown_ids_filter(ids: &[UnknownId<'_>]) -> Option<Vec<Filter>> { filters.push(pk_filter); } - let note_ids: Vec<enostr::EventId> = ids + let note_ids: Vec<enostr::NoteId> = 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 @@ -0,0 +1 @@ +