diff --git a/Cargo.lock b/Cargo.lock index 18f9a8f9b..21590c1dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2681,6 +2681,7 @@ dependencies = [ "instant", "negentropy", "once_cell", + "reqwest", "serde", "serde_json", "tracing", diff --git a/mutiny-core/Cargo.toml b/mutiny-core/Cargo.toml index c0bb19cda..fa77f407c 100644 --- a/mutiny-core/Cargo.toml +++ b/mutiny-core/Cargo.toml @@ -38,7 +38,7 @@ futures-util = { version = "0.3", default-features = false } reqwest = { version = "0.11", default-features = false, features = ["json"] } async-trait = "0.1.68" url = { version = "2.3.1", features = ["serde"] } -nostr = { version = "0.26.0", default-features = false, features = ["nip47"] } +nostr = { version = "0.26.0", default-features = false, features = ["nip05", "nip47"] } nostr-sdk = { version = "0.26.0", default-features = false } cbc = { version = "0.1", features = ["alloc"] } aes = { version = "0.8" } diff --git a/mutiny-core/src/error.rs b/mutiny-core/src/error.rs index fb5383bf2..d19de1e35 100644 --- a/mutiny-core/src/error.rs +++ b/mutiny-core/src/error.rs @@ -6,6 +6,7 @@ use lightning_invoice::payment::PaymentError; use lightning_invoice::ParseOrSemanticError; use lightning_rapid_gossip_sync::GraphSyncError; use lightning_transaction_sync::TxSyncError; +use nostr::nips::nip05; use std::string::FromUtf8Error; use thiserror::Error; @@ -462,6 +463,18 @@ impl From for MutinyError { } } +impl From for MutinyError { + fn from(e: nip05::Error) -> Self { + match e { + nip05::Error::InvalidFormat => Self::InvalidArgumentsError, + nip05::Error::ImpossibleToVerify => Self::NostrError, + nip05::Error::Reqwest(_) => Self::NostrError, + nip05::Error::Json(_) => Self::NostrError, + nip05::Error::Secp256k1(_) => Self::NostrError, + } + } +} + impl From for MutinyError { fn from(_e: nostr::nips::nip19::Error) -> Self { Self::InvalidArgumentsError diff --git a/mutiny-core/src/utils.rs b/mutiny-core/src/utils.rs index ee2733a9e..e164f904c 100644 --- a/mutiny-core/src/utils.rs +++ b/mutiny-core/src/utils.rs @@ -11,6 +11,7 @@ use lightning::routing::scoring::{LockableScore, ScoreLookUp, ScoreUpdate}; use lightning::util::ser::Writeable; use lightning::util::ser::Writer; use nostr::key::XOnlyPublicKey; +use nostr::nips::nip05; use nostr::{Event, FromBech32, JsonUtil, Metadata}; use reqwest::Client; use serde_json::Value; @@ -199,6 +200,19 @@ pub fn parse_npub(str: &str) -> Result { } } +pub async fn parse_npub_or_nip05(str: &str) -> Result { + match XOnlyPublicKey::from_str(str) { + Ok(x) => Ok(x), + Err(_) => match XOnlyPublicKey::from_bech32(str) { + Ok(x) => Ok(x), + Err(_) => { + let profile = nip05::get_profile(str, None).await?; + Ok(profile.public_key) + } + }, + } +} + /// Returns the version of a channel monitor from a serialized version /// of a channel monitor. pub fn get_monitor_version(bytes: &[u8]) -> u64 { diff --git a/mutiny-wasm/src/lib.rs b/mutiny-wasm/src/lib.rs index 56a9d3b0b..45cc1701f 100644 --- a/mutiny-wasm/src/lib.rs +++ b/mutiny-wasm/src/lib.rs @@ -34,7 +34,7 @@ use mutiny_core::lnurlauth::AuthManager; use mutiny_core::nostr::nip49::NIP49URI; use mutiny_core::nostr::nwc::{BudgetedSpendingConditions, NwcProfileTag, SpendingConditions}; use mutiny_core::storage::{DeviceLock, MutinyStorage, DEVICE_LOCK_KEY}; -use mutiny_core::utils::{now, parse_npub, sleep}; +use mutiny_core::utils::{now, parse_npub, parse_npub_or_nip05, sleep}; use mutiny_core::vss::MutinyVssClient; use mutiny_core::{encrypt::encryption_key_from_pass, InvoiceHandler, MutinyWalletConfigBuilder}; use mutiny_core::{labels::Contact, MutinyWalletBuilder}; @@ -43,6 +43,7 @@ use mutiny_core::{ nodemanager::{create_lsp_config, NodeManager}, }; use mutiny_core::{logging::MutinyLogger, nostr::ProfileType}; +use nostr::ToBech32; use std::str::FromStr; use std::sync::Arc; use std::{ @@ -1576,7 +1577,7 @@ impl MutinyWallet { primal_url: Option, npub_str: String, ) -> Result<(), MutinyJsError> { - let npub = parse_npub(&npub_str)?; + let npub = parse_npub_or_nip05(&npub_str).await?; self.inner .sync_nostr_contacts(primal_url.as_deref(), npub) .await?; @@ -1697,9 +1698,16 @@ impl MutinyWallet { /// Convert an npub string to a hex string #[wasm_bindgen] pub async fn npub_to_hexpub(npub: String) -> Result { - let npub = parse_npub(&npub)?; + let npub = parse_npub_or_nip05(&npub).await?; Ok(npub.to_hex()) } + + /// Convert an hex string to a npub string + #[wasm_bindgen] + pub async fn hexpub_to_npub(npub: String) -> Result { + let npub = parse_npub_or_nip05(&npub).await?; + Ok(npub.to_bech32().expect("bech32")) + } } #[cfg(test)]