feat: Support relays and naddrs sets

This commit introduces support for 'sets', a feature that simplifies
referencing multiple relays or naddrs with a single word.

Sets are stored in the config directory under `n34` as `config.toml` in
`TOML` format. The config path follows the `$XDG_CONFIG_HOME` standard,
defaulting to `$HOME/.config` if unset.

The `n34 sets` command allows managing sets, adding, removing, updating,
or displaying them. When using the main `--relays` flag, a set name can
be provided to automatically expand its relays (an error occurs if the
set contains no relays). Similarly, any command accepting naddrs can
reference a set to extract its naddrs.

Sets can also be merged by updating a set while specifying another
set in `--repo` merges their naddrs, while `--set-relays` merges their
relays. Removal follows the same pattern.

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb
2025-06-01 12:00:49 +00:00
parent d6d3f8a52f
commit 4c6578ccb1
19 changed files with 1010 additions and 97 deletions

View File

@@ -17,13 +17,15 @@
use clap::{ArgGroup, Args};
use futures::future;
use nostr::{
event::{EventBuilder, Tag},
nips::nip19::Nip19Coordinate,
};
use nostr::event::{EventBuilder, Tag};
use crate::{
cli::{CliOptions, CommandRunner, parsers},
cli::{
CliConfig,
CliOptions,
CommandRunner,
types::{NaddrOrSet, OptionNaddrOrSetVecExt, RelayOrSetVecExt},
},
error::N34Result,
nostr_utils::{
NostrClient,
@@ -47,12 +49,12 @@ use crate::{
)
)]
pub struct NewArgs {
/// Repository address in `naddr` format or `<nip5>/repo_id`. e.g.
/// `4rs.nl/n34` and `_@4rs.nl/n34`
/// Repository address in `naddr` format (`naddr1...`), NIP-05 format
/// (`4rs.nl/n34` or `_@4rs.nl/n34`), or a set name like `kernel`.
///
/// If not provided, `n34` will look for the `nostr-address` file.
#[arg(value_name = "NADDR-OR-NIP05", long = "repo", value_parser = parsers::repo_naddr)]
naddrs: Option<Vec<Nip19Coordinate>>,
/// If omitted, looks for a `nostr-address` file.
#[arg(value_name = "NADDR-NIP05-OR-SET", long = "repo")]
naddrs: Option<Vec<NaddrOrSet>>,
/// Markdown content for the issue. Cannot be used together with the
/// `--editor` flag.
#[arg(short, long)]
@@ -95,9 +97,14 @@ impl NewArgs {
impl CommandRunner for NewArgs {
async fn run(self, options: CliOptions) -> N34Result<()> {
let client = NostrClient::init(&options).await;
let config = CliConfig::load_toml(&options.config_path)?;
let naddrs = utils::naddrs_or_file(
self.naddrs.flat_naddrs(&config.sets)?,
&utils::nostr_address_path()?,
)?;
let relays = options.relays.clone().flat_relays(&config.sets)?;
let client = NostrClient::init(&options, &relays).await;
let user_pubk = options.pubkey().await?;
let naddrs = utils::naddrs_or_file(self.naddrs.clone(), &utils::nostr_address_path()?)?;
let mut naddrs_iter = naddrs.clone().into_iter();
client.add_relays(&naddrs.extract_relays()).await;
@@ -128,7 +135,7 @@ impl CommandRunner for NewArgs {
let event_id = event.id.expect("There is an id");
let write_relays = [
options.relays,
relays,
utils::add_write_relays(relays_list.as_ref()),
client
.fetch_repos(&naddrs.into_coordinates())