From 51bd239024ac524c76fe83ebb55f23ab17c36071 Mon Sep 17 00:00:00 2001
From: Awiteb
Date: Sat, 7 Jun 2025 19:54:40 +0000
Subject: [PATCH] feat: New `config pow` command to set the default PoW
difficulty
Signed-off-by: Awiteb
---
src/cli/commands/config/mod.rs | 39 +++++++++++++++++++++++++++++++
src/cli/commands/config/pow.rs | 37 +++++++++++++++++++++++++++++
src/cli/commands/issue/new.rs | 2 +-
src/cli/commands/mod.rs | 15 ++++++++++--
src/cli/commands/reply.rs | 2 +-
src/cli/commands/repo/announce.rs | 2 +-
src/cli/config.rs | 3 +++
src/cli/mod.rs | 7 ++++--
8 files changed, 100 insertions(+), 7 deletions(-)
create mode 100644 src/cli/commands/config/mod.rs
create mode 100644 src/cli/commands/config/pow.rs
diff --git a/src/cli/commands/config/mod.rs b/src/cli/commands/config/mod.rs
new file mode 100644
index 0000000..37c15a7
--- /dev/null
+++ b/src/cli/commands/config/mod.rs
@@ -0,0 +1,39 @@
+// n34 - A CLI to interact with NIP-34 and other stuff related to codes in nostr
+// Copyright (C) 2025 Awiteb
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+/// `config pow` subcommand
+mod pow;
+
+use clap::Subcommand;
+
+use self::pow::PowArgs;
+use super::CliOptions;
+use crate::{cli::traits::CommandRunner, error::N34Result};
+
+
+#[derive(Subcommand, Debug)]
+pub enum ConfigSubcommands {
+ /// Sets the default PoW difficulty (0 if not specified)
+ Pow(PowArgs),
+}
+
+impl CommandRunner for ConfigSubcommands {
+ async fn run(self, options: CliOptions) -> N34Result<()> {
+ match self {
+ Self::Pow(args) => args.run(options).await,
+ }
+ }
+}
diff --git a/src/cli/commands/config/pow.rs b/src/cli/commands/config/pow.rs
new file mode 100644
index 0000000..49ff1d5
--- /dev/null
+++ b/src/cli/commands/config/pow.rs
@@ -0,0 +1,37 @@
+// n34 - A CLI to interact with NIP-34 and other stuff related to codes in nostr
+// Copyright (C) 2025 Awiteb
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+use clap::Args;
+
+use crate::{
+ cli::{CliOptions, traits::CommandRunner},
+ error::N34Result,
+};
+
+#[derive(Args, Debug)]
+pub struct PowArgs {
+ /// The new default PoW difficulty
+ difficulty: u8,
+}
+
+impl CommandRunner for PowArgs {
+ async fn run(self, mut options: CliOptions) -> N34Result<()> {
+ // FIXME: The signer is not required here
+
+ options.config.pow = Some(self.difficulty);
+ options.config.dump()
+ }
+}
diff --git a/src/cli/commands/issue/new.rs b/src/cli/commands/issue/new.rs
index dbc0b67..205b3a8 100644
--- a/src/cli/commands/issue/new.rs
+++ b/src/cli/commands/issue/new.rs
@@ -126,7 +126,7 @@ impl CommandRunner for NewArgs {
self.label,
)?
.dedup_tags()
- .pow(options.pow)
+ .pow(options.pow.unwrap_or_default())
.tags(content_details.clone().into_tags())
// p-tag the reset of the reposotoies owners
.tags(naddrs_iter.clone().map(|n| Tag::public_key(n.public_key)))
diff --git a/src/cli/commands/mod.rs b/src/cli/commands/mod.rs
index adf03d8..ba34c2a 100644
--- a/src/cli/commands/mod.rs
+++ b/src/cli/commands/mod.rs
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+/// `config` subcommands
+pub mod config;
/// `issue` subcommands
pub mod issue;
/// `patch` subcommands
@@ -30,6 +32,7 @@ use std::fmt;
use clap::{ArgGroup, Args, Parser};
use nostr::key::{Keys, PublicKey, SecretKey};
+use self::config::ConfigSubcommands;
use self::issue::IssueSubcommands;
use self::patch::PatchSubcommands;
use self::reply::ReplyArgs;
@@ -64,8 +67,8 @@ pub struct CliOptions {
#[arg(short, long)]
pub relays: Vec,
/// Proof of Work difficulty when creatring events
- #[arg(long, default_value_t = 0)]
- pub pow: u8,
+ #[arg(long, value_name = "DIFFICULTY")]
+ pub pow: Option,
/// Config path [default: `$XDG_CONFIG_HOME` or `$HOME/.config`]
#[arg(long, value_name = "PATH", default_value = DEFAULT_FALLBACK_PATH,
hide_default_value = true, value_parser = parsers::parse_config_path
@@ -96,6 +99,11 @@ pub enum Commands {
#[command(subcommand)]
subcommands: PatchSubcommands,
},
+ /// Manage configuration
+ Config {
+ #[command(subcommand)]
+ subcommands: ConfigSubcommands,
+ },
/// Reply to issues and patches.
Reply(ReplyArgs),
}
@@ -111,6 +119,7 @@ impl CommandRunner for Commands {
Self::Reply(args) => args.run(options).await,
Self::Sets { subcommands } => subcommands.run(options).await,
Self::Patch { subcommands } => subcommands.run(options).await,
+ Self::Config { subcommands } => subcommands.run(options).await,
}
}
}
@@ -140,6 +149,8 @@ impl fmt::Debug for CliOptions {
f.debug_struct("CliOptions")
.field("secret_key", &self.secret_key.as_ref().map(|_| "*******"))
.field("relays", &self.relays)
+ .field("pow", &self.pow)
+ .field("config", &self.config)
.finish()
}
}
diff --git a/src/cli/commands/reply.rs b/src/cli/commands/reply.rs
index 733868b..c30c227 100644
--- a/src/cli/commands/reply.rs
+++ b/src/cli/commands/reply.rs
@@ -135,7 +135,7 @@ impl CommandRunner for ReplyArgs {
repos.first().and_then(|r| r.relays.first()).cloned(),
)
.dedup_tags()
- .pow(options.pow)
+ .pow(options.pow.unwrap_or_default())
.tags(content_details.clone().into_tags())
.build(user_pubk);
diff --git a/src/cli/commands/repo/announce.rs b/src/cli/commands/repo/announce.rs
index 150d8e7..65717a4 100644
--- a/src/cli/commands/repo/announce.rs
+++ b/src/cli/commands/repo/announce.rs
@@ -106,7 +106,7 @@ impl CommandRunner for AnnounceArgs {
self.force_id,
)?
.dedup_tags()
- .pow(options.pow)
+ .pow(options.pow.unwrap_or_default())
.build(user_pubk);
diff --git a/src/cli/config.rs b/src/cli/config.rs
index ed85985..667396a 100644
--- a/src/cli/config.rs
+++ b/src/cli/config.rs
@@ -57,6 +57,9 @@ pub struct CliConfig {
/// Groups of repositories and relays.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub sets: Vec,
+ /// The default PoW difficulty
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub pow: Option,
}
/// A named group of repositories and relays.
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 016f1b1..6bd0802 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -73,7 +73,10 @@ impl Cli {
}
/// Processes the CLI configuration and returns it if successful.
-pub fn post_cli(cli: Cli) -> N34Result {
- // TODO
+pub fn post_cli(mut cli: Cli) -> N34Result {
+ if cli.options.pow.is_none() && cli.options.config.pow.is_some() {
+ cli.options.pow = cli.options.config.pow;
+ }
+
Ok(cli)
}