From 6fc59bfe59207ec44e139a58e9191cbecbf2f838 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Tue, 6 May 2025 11:20:41 +0000
Subject: [PATCH] chore: Send the repo announce to the author relays list
Signed-off-by: Awiteb
---
src/cli/repo/announce.rs | 41 +++++++++++++++++++++--------------
src/error.rs | 2 ++
src/nostr_utils/mod.rs | 46 ++++++++++++++++++++++++++++------------
3 files changed, 59 insertions(+), 30 deletions(-)
diff --git a/src/cli/repo/announce.rs b/src/cli/repo/announce.rs
index f6dbf69..afecec6 100644
--- a/src/cli/repo/announce.rs
+++ b/src/cli/repo/announce.rs
@@ -15,21 +15,20 @@
// along with this program. If not, see .
use clap::Args;
-use convert_case::{Case, Casing};
use nostr::{
- event::{EventBuilder, Kind, Tag},
+ event::{EventBuilder, Kind},
key::PublicKey,
nips::{
nip01::Coordinate,
nip19::{Nip19Coordinate, Nip19Event, ToBech32},
- nip34::GitRepositoryAnnouncement,
+ nip65::{self, RelayMetadata},
},
types::Url,
};
use crate::{
cli::{CliOptions, CommandRunner},
- error::{N34Error, N34Result},
+ error::N34Result,
nostr_utils::{NostrClient, traits::NewGitRepositoryAnnouncement},
};
@@ -63,28 +62,43 @@ pub struct AnnounceArgs {
impl CommandRunner for AnnounceArgs {
async fn run(self, options: CliOptions) -> N34Result<()> {
let client = NostrClient::init(&options).await;
+ let user_pubk = options.pubkey().await;
let naddr = Nip19Coordinate::new(
- Coordinate::new(Kind::GitRepoAnnouncement, options.pubkey().await),
+ Coordinate::new(Kind::GitRepoAnnouncement, user_pubk),
options.relays.iter().take(3),
)
.expect("Valid relays");
+ let relays_list = client.user_relays_list(user_pubk).await?;
- let mut maintainers = vec![naddr.public_key];
+ let mut write_relays = options.relays.clone();
+ let mut maintainers = vec![user_pubk];
maintainers.extend(self.maintainers);
- let event_builder = EventBuilder::new_git_repo(
+ if let Some(event) = relays_list.clone() {
+ write_relays.extend(
+ nip65::extract_owned_relay_list(event)
+ .filter_map(|(r, m)| m.is_none_or(|m| m == RelayMetadata::Write).then_some(r)),
+ );
+ }
+
+ let event = EventBuilder::new_git_repo(
self.repo_id,
self.name,
self.description,
self.web,
self.clone,
- options.relays.clone(),
+ options.relays,
maintainers,
self.labels,
- )?;
+ )?
+ .build(user_pubk);
+ let nevent = Nip19Event::new(event.id.expect("There is an id"))
+ .relays(write_relays.iter().take(3).cloned())
+ .to_bech32()?;
+
let result = client
- .send_builder_to(event_builder, &options.relays)
+ .send_event_to(event, relays_list.as_ref(), write_relays)
.await?;
for relay in &result.success {
@@ -94,12 +108,7 @@ impl CommandRunner for AnnounceArgs {
tracing::warn!(relay = %relay, reason = %reason, "Failed to send event");
}
- println!(
- "Event: {}",
- Nip19Event::new(result.val)
- .relays(options.relays.into_iter().take(3))
- .to_bech32()?
- );
+ println!("Event: {nevent}",);
println!("Repo Address: {}", naddr.to_bech32()?);
Ok(())
diff --git a/src/error.rs b/src/error.rs
index 9d80f93..9691f2a 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -34,6 +34,8 @@ pub enum N34Error {
InvalidRepoId,
#[error("Bech32 error: {0}")]
Bech32(#[from] nostr::nips::nip19::Error),
+ #[error("Event error: {0}")]
+ Event(#[from] nostr::event::Error),
}
impl N34Error {
diff --git a/src/nostr_utils/mod.rs b/src/nostr_utils/mod.rs
index efd33c7..25fb521 100644
--- a/src/nostr_utils/mod.rs
+++ b/src/nostr_utils/mod.rs
@@ -22,9 +22,9 @@ pub mod utils;
use std::time::Duration;
use nostr::{
- event::{EventBuilder, EventId, Kind},
+ event::{Event, EventId, Kind, UnsignedEvent},
filter::Filter,
- key::Keys,
+ key::{Keys, PublicKey},
nips::{nip19::Nip19Coordinate, nip34::GitRepositoryAnnouncement},
types::RelayUrl,
};
@@ -35,6 +35,9 @@ use crate::{
error::{N34Error, N34Result},
};
+/// Timeout duration for the clinet.
+const CLIENT_TIMEOUT: Duration = Duration::from_millis(1500);
+
/// A client for interacting with the Nostr relays
pub struct NostrClient {
/// The underlying Nostr client implementation
@@ -73,28 +76,30 @@ impl NostrClient {
.add_read_relay(relay)
.await
.expect("It's a valid relay url");
- if let Err(err) = self
- .client
- .try_connect_relay(relay, Duration::from_millis(1500))
- .await
- {
+ if let Err(err) = self.client.try_connect_relay(relay, CLIENT_TIMEOUT).await {
tracing::error!("Failed to connect to relay '{relay}': {err}");
}
}
}
- /// Sends an event builder to the specified relays.
- pub async fn send_builder_to(
+ /// Sends an event to the specified relays.
+ pub async fn send_event_to(
&self,
- builder: EventBuilder,
- relays: &[RelayUrl],
+ event: UnsignedEvent,
+ relays_list: Option<&Event>,
+ mut relays: Vec,
) -> N34Result