From a324ba2ff74a4f07e4a50b1dc7ad3d9009f82127 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Mon, 19 May 2025 20:03:52 +0000
Subject: [PATCH] chore: Add comments helper functions
Signed-off-by: Awiteb
---
src/nostr_utils/mod.rs | 146 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 143 insertions(+), 3 deletions(-)
diff --git a/src/nostr_utils/mod.rs b/src/nostr_utils/mod.rs
index 26d221d..2e84d2c 100644
--- a/src/nostr_utils/mod.rs
+++ b/src/nostr_utils/mod.rs
@@ -19,17 +19,19 @@ pub mod traits;
/// Utility functions for nostr.
pub mod utils;
-use std::time::Duration;
+use std::{collections::HashSet, time::Duration};
use futures::future;
use nostr::{
- event::{Event, EventId, Kind, UnsignedEvent},
+ event::{Event, EventId, Kind, Tag, TagStandard, Tags, UnsignedEvent},
filter::Filter,
key::{Keys, PublicKey},
- nips::{nip01::Coordinate, nip34::GitRepositoryAnnouncement},
+ nips::{nip01::Coordinate, nip22, nip34::GitRepositoryAnnouncement},
+ parser::NostrParser,
types::RelayUrl,
};
use nostr_sdk::Client;
+use traits::TokenUtils;
use crate::{
cli::CliOptions,
@@ -39,12 +41,57 @@ use crate::{
/// Timeout duration for the clinet.
const CLIENT_TIMEOUT: Duration = Duration::from_millis(1500);
+/// Parsed content details
+pub struct ContentDetails {
+ /// Public keys of users mentioned in the content.
+ pub p_tagged: HashSet,
+ /// Event IDs and optional relay URLs for quoted events.
+ pub quotes: HashSet<(EventId, Option)>,
+ /// Hashtags found in the content.
+ pub hashtags: HashSet,
+ /// Relays where mentioned users and quoted authors are read.
+ pub write_relays: HashSet,
+}
+
/// A client for interacting with the Nostr relays
pub struct NostrClient {
/// The underlying Nostr client implementation
client: Client,
}
+impl ContentDetails {
+ /// Create a new [`ContentDetails`] instance
+ pub fn new(
+ users: impl IntoIterator- ,
+ quotes: impl IntoIterator
- )>,
+ hashtags: impl IntoIterator
- ,
+ write_relays: impl IntoIterator
- ,
+ ) -> Self {
+ Self {
+ p_tagged: HashSet::from_iter(users),
+ quotes: HashSet::from_iter(quotes),
+ hashtags: HashSet::from_iter(hashtags),
+ write_relays: HashSet::from_iter(write_relays),
+ }
+ }
+
+ /// Converts the instance into a list of tags including hashtags, p-tagged
+ /// users, and quoted events.
+ pub fn into_tags(self) -> Tags {
+ let mut tags = Tags::new();
+ tags.extend(self.hashtags.into_iter().map(Tag::hashtag));
+ tags.extend(self.p_tagged.into_iter().map(Tag::public_key));
+ tags.extend(self.quotes.into_iter().map(|(event_id, relay_url)| {
+ Tag::from_standardized(TagStandard::Quote {
+ event_id,
+ relay_url,
+ public_key: None,
+ })
+ }));
+ tags
+ }
+}
+
impl NostrClient {
/// Creates a new [`NostrClient`] with the given client and options.
const fn new(client: Client) -> Self {
@@ -93,6 +140,19 @@ impl NostrClient {
future::join_all(tasks).await;
}
+ /// Add a relay hint and connect to it
+ pub async fn add_relay_hint(&self, hint: Option) {
+ if let Some(relay) = hint {
+ self.add_relays(&[relay]).await
+ }
+ }
+
+ /// broadcast an event to the given relays
+ pub async fn broadcast(&self, event: &Event, relays: &[RelayUrl]) -> N34Result<()> {
+ self.client.send_event_to(relays, event).await?;
+ Ok(())
+ }
+
/// Broadcasts an unsigned event to given relays, optionally broadcast the
/// relays list event. Returns URLs of relays that successfully received
/// the event.
@@ -151,6 +211,47 @@ impl NostrClient {
.ok_or(N34Error::NotFoundRepo)
}
+ /// Finds the root issue or patch for a given event. If the event is already
+ /// a root (issue/patch), returns it directly. For comments, follows
+ /// parent/root references until finding the root or failing. Returns
+ /// None if no root can be found.
+ pub async fn find_root(&self, mut event: Event) -> N34Result