feat: Support signing using NIP-46 bunker

Suggested-by: DanConwayDev <DanConwayDev@protonmail.com>
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb
2025-07-18 21:18:26 +00:00
parent f0c20c3677
commit 4e0ecdceaf
11 changed files with 211 additions and 23 deletions

View File

@@ -33,11 +33,14 @@ pub mod types;
use clap::Parser;
use clap_verbosity_flag::Verbosity;
use nostr::key::Keys;
use nostr_keyring::NostrKeyring;
use types::RelayOrSet;
pub use self::commands::*;
pub use self::config::*;
use self::traits::CommandRunner;
use crate::error::N34Error;
use crate::error::N34Result;
/// Header message, used in the help message
@@ -51,6 +54,12 @@ Git repository: https://git.4rs.nl/awiteb/n34.git"#;
/// Footer message, used in the help message
const FOOTER: &str = r#"Please report bugs to <naddr1qqpkuve5qgsqqqqqq9g9uljgjfcyd6dm4fegk8em2yfz0c3qp3tc6mntkrrhawgrqsqqqauesksc39>."#;
/// Keyring service name of n34
const N34_KEYRING_SERVICE_NAME: &str = "n34";
/// Keyring entry name for the n34 keypair
const N34_KEY_PAIR_ENTRY: &str = "n34_keypair";
/// Name of the file storing the repository address
pub const NOSTR_ADDRESS_FILE: &str = "nostr-address";
@@ -75,6 +84,22 @@ impl Cli {
pub async fn run(self) -> N34Result<()> {
self.command.run(self.options).await
}
/// Gets the n34 keypair from the keyring or generates and stores a new one
/// if none exists.
pub fn n34_keypair() -> N34Result<Keys> {
let keyring = NostrKeyring::new(N34_KEYRING_SERVICE_NAME);
match keyring.get(N34_KEY_PAIR_ENTRY) {
Ok(keys) => Ok(keys),
Err(nostr_keyring::Error::Keyring(keyring::Error::NoEntry)) => {
let new_keys = Keys::generate();
keyring.set(N34_KEY_PAIR_ENTRY, &new_keys)?;
Ok(new_keys)
}
Err(err) => Err(N34Error::Keyring(err)),
}
}
}
/// Processes the CLI configuration by applying fallback values from config if
@@ -88,5 +113,11 @@ pub fn post_cli(mut cli: Cli) -> N34Result<Cli> {
cli.options.relays = relays.iter().cloned().map(RelayOrSet::Relay).collect();
}
if cli.options.bunker_url.is_none()
&& let Some(bunker_url) = &cli.options.config.bunker_url
{
cli.options.bunker_url = Some(bunker_url.clone());
}
Ok(cli)
}