From 39008276db92671a0f786e591802e7c87dfee33a Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Mon, 4 Mar 2024 09:07:41 +0100 Subject: [PATCH] nostr: adapt `EventBuilder::repost` to last NIP18 changes Add `Tag::Kind` and `Kind::GenericRepost` --- bindings/nostr-ffi/src/event/builder.rs | 10 +++---- bindings/nostr-ffi/src/event/tag.rs | 11 +++++++ bindings/nostr-js/src/event/builder.rs | 6 ++-- bindings/nostr-sdk-ffi/src/client/mod.rs | 14 ++++++++- bindings/nostr-sdk-js/src/client/mod.rs | 11 ++----- crates/nostr-sdk/src/client/mod.rs | 10 +++---- crates/nostr/src/event/builder.rs | 37 +++++++++++++++++++----- crates/nostr/src/event/kind.rs | 4 +++ crates/nostr/src/event/tag.rs | 8 +++++ 9 files changed, 82 insertions(+), 29 deletions(-) diff --git a/bindings/nostr-ffi/src/event/builder.rs b/bindings/nostr-ffi/src/event/builder.rs index 6fffb40dc..876c5bdc6 100644 --- a/bindings/nostr-ffi/src/event/builder.rs +++ b/bindings/nostr-ffi/src/event/builder.rs @@ -160,13 +160,13 @@ impl EventBuilder { } #[uniffi::constructor] - pub fn repost(event_id: Arc, public_key: Arc) -> Arc { - Arc::new(Self { + pub fn repost(event: Arc, relay_url: Option) -> Self { + Self { inner: nostr::EventBuilder::repost( - event_id.as_ref().into(), - *public_key.as_ref().deref(), + event.as_ref().deref(), + relay_url.map(UncheckedUrl::from), ), - }) + } } /// Create delete event diff --git a/bindings/nostr-ffi/src/event/tag.rs b/bindings/nostr-ffi/src/event/tag.rs index ad1e663d1..dfd6edad9 100644 --- a/bindings/nostr-ffi/src/event/tag.rs +++ b/bindings/nostr-ffi/src/event/tag.rs @@ -175,6 +175,8 @@ pub enum TagKind { U, /// SHA256 X, + /// Kind + K, /// Relay RelayUrl, /// Nonce @@ -269,6 +271,7 @@ impl From for TagKind { tag::TagKind::M => Self::M, tag::TagKind::U => Self::U, tag::TagKind::X => Self::X, + tag::TagKind::K => Self::K, tag::TagKind::Relay => Self::RelayUrl, tag::TagKind::Nonce => Self::Nonce, tag::TagKind::Delegation => Self::Delegation, @@ -328,6 +331,7 @@ impl From for tag::TagKind { TagKind::M => Self::M, TagKind::U => Self::U, TagKind::X => Self::X, + TagKind::K => Self::K, TagKind::RelayUrl => Self::Relay, TagKind::Nonce => Self::Nonce, TagKind::Delegation => Self::Delegation, @@ -429,6 +433,9 @@ pub enum TagEnum { identifier: String, relay_url: Option, }, + Kind { + kind: u64, + }, RelayUrl { relay_url: String, }, @@ -637,6 +644,9 @@ impl From for TagEnum { tag::Tag::ExternalIdentity(identity) => Self::ExternalIdentityTag { identity: identity.into(), }, + tag::Tag::Kind(kind) => Self::Kind { + kind: kind.as_u64(), + }, tag::Tag::Relay(url) => Self::RelayUrl { relay_url: url.to_string(), }, @@ -810,6 +820,7 @@ impl TryFrom for tag::Tag { identifier, relay_url: relay_url.map(UncheckedUrl::from), }), + TagEnum::Kind { kind } => Ok(Self::Kind(Kind::from(kind))), TagEnum::RelayUrl { relay_url } => Ok(Self::Relay(UncheckedUrl::from(relay_url))), TagEnum::POW { nonce, difficulty } => Ok(Self::POW { nonce: nonce.parse()?, diff --git a/bindings/nostr-js/src/event/builder.rs b/bindings/nostr-js/src/event/builder.rs index a3b2a9bd6..3bfc5b895 100644 --- a/bindings/nostr-js/src/event/builder.rs +++ b/bindings/nostr-js/src/event/builder.rs @@ -122,10 +122,10 @@ impl JsEventBuilder { }) } - #[wasm_bindgen] - pub fn repost(event_id: &JsEventId, public_key: &JsPublicKey) -> Self { + /// Repost + pub fn repost(event: &JsEvent, relay_url: Option) -> Self { Self { - builder: EventBuilder::repost(event_id.into(), public_key.into()), + builder: EventBuilder::repost(&*event, relay_url.map(UncheckedUrl::from)), } } diff --git a/bindings/nostr-sdk-ffi/src/client/mod.rs b/bindings/nostr-sdk-ffi/src/client/mod.rs index 17e0204b1..b476c6ac3 100644 --- a/bindings/nostr-sdk-ffi/src/client/mod.rs +++ b/bindings/nostr-sdk-ffi/src/client/mod.rs @@ -15,7 +15,7 @@ use nostr_ffi::{ }; use nostr_sdk::client::Client as ClientSdk; use nostr_sdk::pool::RelayPoolNotification as RelayPoolNotificationSdk; -use nostr_sdk::{block_on, spawn_blocking}; +use nostr_sdk::{block_on, spawn_blocking, UncheckedUrl}; use uniffi::Object; mod builder; @@ -306,6 +306,18 @@ impl Client { }) } + /// Repost + pub fn repost(&self, event: Arc, relay_url: Option) -> Result> { + block_on(async move { + Ok(Arc::new( + self.inner + .repost(event.as_ref().deref(), relay_url.map(UncheckedUrl::from)) + .await? + .into(), + )) + }) + } + /// Send a Zap! /// /// This method automatically create a split zap to support Rust Nostr development. diff --git a/bindings/nostr-sdk-js/src/client/mod.rs b/bindings/nostr-sdk-js/src/client/mod.rs index eb22d1882..c06274ff7 100644 --- a/bindings/nostr-sdk-js/src/client/mod.rs +++ b/bindings/nostr-sdk-js/src/client/mod.rs @@ -403,15 +403,10 @@ impl JsClient { .map(|id| id.into()) } - /// Repost event - #[wasm_bindgen(js_name = repostEvent)] - pub async fn repost_event( - &self, - event_id: &JsEventId, - public_key: &JsPublicKey, - ) -> Result { + /// Repost + pub async fn repost(&self, event: &JsEvent, relay_url: Option) -> Result { self.inner - .repost_event(event_id.into(), public_key.into()) + .repost(&*event, relay_url.map(UncheckedUrl::from)) .await .map_err(into_err) .map(|id| id.into()) diff --git a/crates/nostr-sdk/src/client/mod.rs b/crates/nostr-sdk/src/client/mod.rs index 64090e016..4ea36a182 100644 --- a/crates/nostr-sdk/src/client/mod.rs +++ b/crates/nostr-sdk/src/client/mod.rs @@ -994,13 +994,13 @@ impl Client { self.send_event_builder(builder).await } - /// Repost event - pub async fn repost_event( + /// Repost + pub async fn repost( &self, - event_id: EventId, - public_key: PublicKey, + event: &Event, + relay_url: Option, ) -> Result { - let builder = EventBuilder::repost(event_id, public_key); + let builder = EventBuilder::repost(event, relay_url); self.send_event_builder(builder).await } diff --git a/crates/nostr/src/event/builder.rs b/crates/nostr/src/event/builder.rs index c3c16cad8..199dd07e4 100644 --- a/crates/nostr/src/event/builder.rs +++ b/crates/nostr/src/event/builder.rs @@ -482,13 +482,36 @@ impl EventBuilder { )) } - /// Repost event - pub fn repost(event_id: EventId, public_key: PublicKey) -> Self { - Self::new( - Kind::Repost, - String::new(), - [Tag::event(event_id), Tag::public_key(public_key)], - ) + /// Repost + pub fn repost(event: &Event, relay_url: Option) -> Self { + if event.kind == Kind::TextNote { + Self::new( + Kind::Repost, + event.as_json(), + [ + Tag::Event { + event_id: event.id(), + relay_url, + marker: None, + }, + Tag::public_key(event.author()), + ], + ) + } else { + Self::new( + Kind::GenericRepost, + event.as_json(), + [ + Tag::Event { + event_id: event.id(), + relay_url, + marker: None, + }, + Tag::public_key(event.author()), + Tag::Kind(event.kind()), + ], + ) + } } /// Create delete event diff --git a/crates/nostr/src/event/kind.rs b/crates/nostr/src/event/kind.rs index 5d15749f1..5e28d9f2a 100644 --- a/crates/nostr/src/event/kind.rs +++ b/crates/nostr/src/event/kind.rs @@ -46,6 +46,8 @@ pub enum Kind { EventDeletion, /// Repost (NIP18) Repost, + /// Generic Repost (NIP18) + GenericRepost, /// Reaction (NIP25) Reaction, /// Badge Award (NIP58) @@ -249,6 +251,7 @@ impl From for Kind { 4 => Self::EncryptedDirectMessage, 5 => Self::EventDeletion, 6 => Self::Repost, + 16 => Self::GenericRepost, 7 => Self::Reaction, 8 => Self::BadgeAward, 40 => Self::ChannelCreation, @@ -313,6 +316,7 @@ impl From for u64 { Kind::EncryptedDirectMessage => 4, Kind::EventDeletion => 5, Kind::Repost => 6, + Kind::GenericRepost => 16, Kind::Reaction => 7, Kind::BadgeAward => 8, Kind::ChannelCreation => 40, diff --git a/crates/nostr/src/event/tag.rs b/crates/nostr/src/event/tag.rs index e414dc62f..b912ce8e5 100644 --- a/crates/nostr/src/event/tag.rs +++ b/crates/nostr/src/event/tag.rs @@ -359,6 +359,8 @@ pub enum TagKind { U, /// SHA256 X, + /// Kind + K, /// Relay Relay, /// Nonce @@ -456,6 +458,7 @@ impl fmt::Display for TagKind { Self::M => write!(f, "m"), Self::U => write!(f, "u"), Self::X => write!(f, "x"), + Self::K => write!(f, "k"), Self::Relay => write!(f, "relay"), Self::Nonce => write!(f, "nonce"), Self::Delegation => write!(f, "delegation"), @@ -518,6 +521,7 @@ where "m" => Self::M, "u" => Self::U, "x" => Self::X, + "k" => Self::K, "relay" => Self::Relay, "nonce" => Self::Nonce, "delegation" => Self::Delegation, @@ -598,6 +602,7 @@ pub enum Tag { identifier: String, relay_url: Option, }, + Kind(Kind), Relay(UncheckedUrl), POW { nonce: u128, @@ -738,6 +743,7 @@ impl Tag { TagKind::T => Ok(Self::Hashtag(tag_1.to_owned())), TagKind::G => Ok(Self::Geohash(tag_1.to_owned())), TagKind::D => Ok(Self::Identifier(tag_1.to_owned())), + TagKind::K => Ok(Self::Kind(Kind::from_str(tag_1)?)), TagKind::Relay => Ok(Self::Relay(UncheckedUrl::from(tag_1))), TagKind::ContentWarning => Ok(Self::ContentWarning { reason: Some(tag_1.to_owned()), @@ -1020,6 +1026,7 @@ impl Tag { Self::Identifier(..) => TagKind::D, Self::ExternalIdentity(..) => TagKind::I, Self::A { .. } => TagKind::A, + Self::Kind(..) => TagKind::K, Self::Relay(..) => TagKind::Relay, Self::POW { .. } => TagKind::Nonce, Self::Delegation { .. } => TagKind::Delegation, @@ -1157,6 +1164,7 @@ impl From for Vec { vec } Tag::ExternalIdentity(identity) => identity.into(), + Tag::Kind(kind) => vec![TagKind::K.to_string(), kind.to_string()], Tag::Relay(url) => vec![TagKind::Relay.to_string(), url.to_string()], Tag::POW { nonce, difficulty } => vec![ TagKind::Nonce.to_string(),