diff --git a/crates/nostr/Cargo.toml b/crates/nostr/Cargo.toml index a3c94d9ec..e6ca33221 100644 --- a/crates/nostr/Cargo.toml +++ b/crates/nostr/Cargo.toml @@ -39,7 +39,6 @@ reqwest = { version = "0.11", default-features = false, features = ["json", "rus secp256k1 = { version = "0.27", features = ["global-context", "rand-std", "serde"] } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } -thiserror = "1.0" url = { version = "2", features = ["serde"] } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/crates/nostr/src/event/builder.rs b/crates/nostr/src/event/builder.rs index 873114b3a..80d396f5b 100644 --- a/crates/nostr/src/event/builder.rs +++ b/crates/nostr/src/event/builder.rs @@ -3,6 +3,7 @@ //! Event builder +use core::fmt; #[cfg(not(target_arch = "wasm32"))] use std::time::Instant; @@ -24,24 +25,65 @@ use crate::nips::nip46::Message as NostrConnectMessage; use crate::types::{ChannelId, Contact, Metadata, Timestamp}; /// [`EventBuilder`] error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Key error - #[error(transparent)] - Key(#[from] key::Error), - /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Key(key::Error), /// JSON error - #[error(transparent)] - Json(#[from] serde_json::Error), + Json(serde_json::Error), + /// Secp256k1 error + Secp256k1(secp256k1::Error), /// Unsigned event error - #[error(transparent)] - Unsigned(#[from] super::unsigned::Error), + Unsigned(super::unsigned::Error), /// NIP04 error #[cfg(feature = "nip04")] - #[error(transparent)] - NIP04(#[from] nip04::Error), + NIP04(nip04::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Key(e) => write!(f, "{e}"), + Self::Json(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::Unsigned(e) => write!(f, "{e}"), + #[cfg(feature = "nip04")] + Self::NIP04(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: key::Error) -> Self { + Self::Key(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: super::unsigned::Error) -> Self { + Self::Unsigned(e) + } +} + +#[cfg(feature = "nip04")] +impl From for Error { + fn from(e: nip04::Error) -> Self { + Self::NIP04(e) + } } /// [`Event`] builder diff --git a/crates/nostr/src/event/id.rs b/crates/nostr/src/event/id.rs index af87a075d..1af00562c 100644 --- a/crates/nostr/src/event/id.rs +++ b/crates/nostr/src/event/id.rs @@ -3,8 +3,8 @@ //! Event Id -use std::fmt; -use std::str::FromStr; +use core::fmt; +use core::str::FromStr; use bitcoin_hashes::sha256::Hash as Sha256Hash; use bitcoin_hashes::Hash; @@ -16,14 +16,35 @@ use super::{Kind, Tag}; use crate::Timestamp; /// [`EventId`] error -#[derive(Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Debug, PartialEq, Eq)] pub enum Error { /// Hex error - #[error(transparent)] - Hex(#[from] bitcoin_hashes::hex::Error), + Hex(bitcoin_hashes::hex::Error), /// Hash error - #[error(transparent)] - Hash(#[from] bitcoin_hashes::Error), + Hash(bitcoin_hashes::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Hex(e) => write!(f, "{e}"), + Self::Hash(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::hex::Error) -> Self { + Self::Hex(e) + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::Error) -> Self { + Self::Hash(e) + } } /// Event Id diff --git a/crates/nostr/src/event/mod.rs b/crates/nostr/src/event/mod.rs index b1dde38eb..dfa52a862 100644 --- a/crates/nostr/src/event/mod.rs +++ b/crates/nostr/src/event/mod.rs @@ -4,7 +4,8 @@ //! Event -use std::str::FromStr; +use core::fmt; +use core::str::FromStr; use secp256k1::schnorr::Signature; use secp256k1::{Message, XOnlyPublicKey}; @@ -25,24 +26,59 @@ pub use self::unsigned::UnsignedEvent; use crate::{Timestamp, SECP256K1}; /// [`Event`] error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Invalid signature - #[error("invalid signature")] InvalidSignature, /// Error serializing or deserializing JSON data - #[error(transparent)] - Json(#[from] serde_json::Error), + Json(serde_json::Error), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), /// Hex decoding error - #[error(transparent)] - Hex(#[from] bitcoin_hashes::hex::Error), + Hex(bitcoin_hashes::hex::Error), /// OpenTimestamps error #[cfg(feature = "nip03")] - #[error(transparent)] - OpenTimestamps(#[from] nostr_ots::Error), + OpenTimestamps(nostr_ots::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidSignature => write!(f, "Invalid signature"), + Self::Json(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::Hex(e) => write!(f, "{e}"), + #[cfg(feature = "nip03")] + Self::OpenTimestamps(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::hex::Error) -> Self { + Self::Hex(e) + } +} + +#[cfg(feature = "nip03")] +impl From for Error { + fn from(e: nostr_ots::Error) -> Self { + Self::OpenTimestamps(e) + } } /// [`Event`] struct diff --git a/crates/nostr/src/event/tag.rs b/crates/nostr/src/event/tag.rs index 7ea80cd41..015011c80 100644 --- a/crates/nostr/src/event/tag.rs +++ b/crates/nostr/src/event/tag.rs @@ -3,9 +3,9 @@ //! Tag -use std::fmt; -use std::num::ParseIntError; -use std::str::FromStr; +use core::fmt; +use core::num::ParseIntError; +use core::str::FromStr; use secp256k1::schnorr::Signature; use secp256k1::XOnlyPublicKey; @@ -14,48 +14,99 @@ use serde::ser::SerializeSeq; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use super::id::{self, EventId}; -use crate::nips::nip26::Conditions; +use crate::nips::nip26::{Conditions, Error as Nip26Error}; use crate::{Kind, Timestamp, UncheckedUrl}; /// [`Tag`] error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Impossible to parse [`Marker`] - #[error("impossible to parse marker")] MarkerParseError, /// Unknown [`Report`] - #[error("unknown report type")] UnknownReportType, /// Impossible to find tag kind - #[error("impossible to find tag kind")] KindNotFound, /// Invalid length - #[error("invalid length")] InvalidLength, + /// Invalid Zap Request + InvalidZapRequest, /// Impossible to parse integer - #[error(transparent)] - ParseIntError(#[from] ParseIntError), + ParseIntError(ParseIntError), /// Secp256k1 - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), /// Hex decoding error - #[error(transparent)] - Hex(#[from] bitcoin_hashes::hex::Error), + Hex(bitcoin_hashes::hex::Error), /// Url parse error - #[error("invalid url: {0}")] - Url(#[from] url::ParseError), + Url(url::ParseError), /// EventId error - #[error(transparent)] - EventId(#[from] id::Error), + EventId(id::Error), /// NIP26 error - #[error(transparent)] - Nip26(#[from] crate::nips::nip26::Error), + NIP26(Nip26Error), /// Event Error - #[error(transparent)] - Event(#[from] crate::event::Error), - /// Invalid Zap Request - #[error("Invalid Zap request")] - InvalidZapRequest, + Event(crate::event::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::MarkerParseError => write!(f, "impossible to parse marker"), + Self::UnknownReportType => write!(f, "unknown report type"), + Self::KindNotFound => write!(f, "impossible to find tag kind"), + Self::InvalidLength => write!(f, "invalid length"), + Self::InvalidZapRequest => write!(f, "invalid Zap request"), + Self::ParseIntError(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::Hex(e) => write!(f, "{e}"), + Self::Url(e) => write!(f, "{e}"), + Self::EventId(e) => write!(f, "{e}"), + Self::NIP26(e) => write!(f, "{e}"), + Self::Event(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: ParseIntError) -> Self { + Self::ParseIntError(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::hex::Error) -> Self { + Self::Hex(e) + } +} + +impl From for Error { + fn from(e: url::ParseError) -> Self { + Self::Url(e) + } +} + +impl From for Error { + fn from(e: id::Error) -> Self { + Self::EventId(e) + } +} + +impl From for Error { + fn from(e: Nip26Error) -> Self { + Self::NIP26(e) + } +} + +impl From for Error { + fn from(e: crate::event::Error) -> Self { + Self::Event(e) + } } /// Marker diff --git a/crates/nostr/src/event/unsigned.rs b/crates/nostr/src/event/unsigned.rs index ee73b3d1a..ef78e2165 100644 --- a/crates/nostr/src/event/unsigned.rs +++ b/crates/nostr/src/event/unsigned.rs @@ -3,6 +3,8 @@ //! Unsigned Event +use core::fmt; + use secp256k1::schnorr::Signature; use secp256k1::{Message, XOnlyPublicKey}; use serde::{Deserialize, Serialize}; @@ -10,20 +12,53 @@ use serde::{Deserialize, Serialize}; use crate::{Event, EventId, Keys, Kind, Tag, Timestamp}; /// [`UnsignedEvent`] error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Key error - #[error(transparent)] - Key(#[from] crate::key::Error), + Key(crate::key::Error), /// Error serializing or deserializing JSON data - #[error(transparent)] - Json(#[from] serde_json::Error), + Json(serde_json::Error), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), /// Event error - #[error(transparent)] - Event(#[from] super::Error), + Event(super::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Key(e) => write!(f, "{e}"), + Self::Json(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::Event(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: crate::key::Error) -> Self { + Self::Key(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: super::Error) -> Self { + Self::Event(e) + } } /// [`UnsignedEvent`] struct diff --git a/crates/nostr/src/key/mod.rs b/crates/nostr/src/key/mod.rs index ccce85bbe..c5fdc357f 100644 --- a/crates/nostr/src/key/mod.rs +++ b/crates/nostr/src/key/mod.rs @@ -6,8 +6,9 @@ //! //! This module defines the [`Keys`] structure. +use core::fmt; #[cfg(feature = "nip19")] -use std::str::FromStr; +use core::str::FromStr; use secp256k1::rand::rngs::OsRng; use secp256k1::rand::Rng; @@ -24,23 +25,38 @@ pub mod vanity; use crate::nips::nip19::FromBech32; /// [`Keys`] error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { /// Invalid secret key - #[error("Invalid secret key")] InvalidSecretKey, /// Invalid public key - #[error("Invalid public key")] InvalidPublicKey, - /// Secrete key missing - #[error("Secrete key missing")] + /// Secret key missing SkMissing, /// Unsupported char - #[error("Unsupported char: {0}")] InvalidChar(char), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidSecretKey => write!(f, "Invalid secret key"), + Self::InvalidPublicKey => write!(f, "Invalid public key"), + Self::SkMissing => write!(f, "Secret key missing"), + Self::InvalidChar(c) => write!(f, "Unsupported char: {c}"), + Self::Secp256k1(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } } /// Trait for [`Keys`] diff --git a/crates/nostr/src/key/vanity.rs b/crates/nostr/src/key/vanity.rs index 72af74347..d42ace481 100644 --- a/crates/nostr/src/key/vanity.rs +++ b/crates/nostr/src/key/vanity.rs @@ -3,7 +3,8 @@ //! Vanity -use std::sync::atomic::{AtomicBool, Ordering}; +use core::fmt; +use core::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{sync_channel, RecvError}; use std::sync::Arc; use std::thread; @@ -19,19 +20,34 @@ const BECH32_CHARS: &str = "023456789acdefghjklmnpqrstuvwxyz"; const HEX_CHARS: &str = "0123456789abcdef"; /// [`Keys`] vanity error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { /// Unsupported char - #[error("Unsupported char: {0}")] InvalidChar(char), /// RecvError - #[error(transparent)] - RecvError(#[from] RecvError), + RecvError(RecvError), /// Thread Join failed - #[error("Impossible to join threads")] JoinHandleError, } +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidChar(c) => write!(f, "Unsupported char: {c}"), + Self::RecvError(e) => write!(f, "{e}"), + Self::JoinHandleError => write!(f, "impossible to join threads"), + } + } +} + +impl From for Error { + fn from(e: RecvError) -> Self { + Self::RecvError(e) + } +} + impl Keys { /// Generate new vanity public key pub fn vanity(prefixes: Vec, bech32: bool, num_cores: usize) -> Result diff --git a/crates/nostr/src/message/client.rs b/crates/nostr/src/message/client.rs index fb5167910..3b5ac341b 100644 --- a/crates/nostr/src/message/client.rs +++ b/crates/nostr/src/message/client.rs @@ -12,21 +12,24 @@ use super::{Filter, MessageHandleError, SubscriptionId}; use crate::Event; /// Messages sent by clients, received by relays -#[allow(missing_docs)] #[derive(Debug, Clone, Eq, PartialEq)] pub enum ClientMessage { /// Event Event(Box), /// Req Req { + /// Subscription ID subscription_id: SubscriptionId, + /// Filters filters: Vec, }, /// Count /// /// Count { + /// Subscription ID subscription_id: SubscriptionId, + /// Filters filters: Vec, }, /// Close diff --git a/crates/nostr/src/message/mod.rs b/crates/nostr/src/message/mod.rs index 58217ca39..e8dd87adf 100644 --- a/crates/nostr/src/message/mod.rs +++ b/crates/nostr/src/message/mod.rs @@ -3,6 +3,8 @@ //! Messages +use core::fmt; + pub mod client; pub mod relay; pub mod subscription; @@ -12,15 +14,36 @@ pub use self::relay::RelayMessage; pub use self::subscription::{Filter, SubscriptionId}; /// Messages error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum MessageHandleError { /// Invalid message format - #[error("Message has an invalid format")] InvalidMessageFormat, /// Impossible to deserialize message - #[error("Json deserialization failed: {0}")] - Json(#[from] serde_json::Error), + Json(serde_json::Error), /// Event error - #[error(transparent)] - Event(#[from] crate::event::Error), + Event(crate::event::Error), +} + +impl std::error::Error for MessageHandleError {} + +impl fmt::Display for MessageHandleError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidMessageFormat => write!(f, "Message has an invalid format"), + Self::Json(e) => write!(f, "Json deserialization failed: {e}"), + Self::Event(e) => write!(f, "{e}"), + } + } +} + +impl From for MessageHandleError { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for MessageHandleError { + fn from(e: crate::event::Error) -> Self { + Self::Event(e) + } } diff --git a/crates/nostr/src/nips/nip04.rs b/crates/nostr/src/nips/nip04.rs index 36ff9ca34..454b99369 100644 --- a/crates/nostr/src/nips/nip04.rs +++ b/crates/nostr/src/nips/nip04.rs @@ -6,8 +6,9 @@ //! //! -use std::convert::From; -use std::str::FromStr; +use core::convert::From; +use core::fmt; +use core::str::FromStr; use aes::cipher::block_padding::Pkcs7; use aes::cipher::{BlockDecryptMut, BlockEncryptMut, KeyIvInit}; @@ -20,23 +21,41 @@ type Aes256CbcEnc = Encryptor; type Aes256CbcDec = Decryptor; /// `NIP04` error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { /// Invalid content format - #[error("Invalid content format")] InvalidContentFormat, /// Error while decoding from base64 - #[error("Error while decoding from base64")] Base64Decode, /// Error while encoding to UTF-8 - #[error("Error while encoding to UTF-8")] Utf8Encode, /// Wrong encryption block mode - #[error("Wrong encryption block mode. The content must be encrypted using CBC mode!")] WrongBlockMode, /// Secp256k1 error - #[error("secp256k1 error: {0}")] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidContentFormat => write!(f, "Invalid content format"), + Self::Base64Decode => write!(f, "Error while decoding from base64"), + Self::Utf8Encode => write!(f, "Error while encoding to UTF-8"), + Self::WrongBlockMode => write!( + f, + "Wrong encryption block mode. The content must be encrypted using CBC mode!" + ), + Self::Secp256k1(e) => write!(f, "secp256k1 error: {e}"), + } + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } } /// Entrypt diff --git a/crates/nostr/src/nips/nip05.rs b/crates/nostr/src/nips/nip05.rs index 79c433c93..1c43903f7 100644 --- a/crates/nostr/src/nips/nip05.rs +++ b/crates/nostr/src/nips/nip05.rs @@ -5,9 +5,10 @@ //! //! +use core::fmt; +use core::str::FromStr; #[cfg(not(target_arch = "wasm32"))] use std::net::SocketAddr; -use std::str::FromStr; #[cfg(not(target_arch = "wasm32"))] use reqwest::Proxy; @@ -17,23 +18,50 @@ use serde_json::Value; use crate::Profile; /// `NIP05` error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Invalid format - #[error("invalid format")] InvalidFormat, /// Impossible to verify - #[error("impossible to verify")] ImpossibleToVerify, /// Reqwest error - #[error(transparent)] - Reqwest(#[from] reqwest::Error), + Reqwest(reqwest::Error), /// Error deserializing JSON data - #[error("impossible to deserialize NIP05 data: {0}")] - Json(#[from] serde_json::Error), + Json(serde_json::Error), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidFormat => write!(f, "invalid format"), + Self::ImpossibleToVerify => write!(f, "impossible to verify"), + Self::Reqwest(e) => write!(f, "{e}"), + Self::Json(e) => write!(f, "impossible to deserialize NIP05 data: {e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: reqwest::Error) -> Self { + Self::Reqwest(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } } fn compose_url(nip05: &str) -> Result<(String, &str), Error> { diff --git a/crates/nostr/src/nips/nip06.rs b/crates/nostr/src/nips/nip06.rs index 6bd9cdb89..ba03949cc 100644 --- a/crates/nostr/src/nips/nip06.rs +++ b/crates/nostr/src/nips/nip06.rs @@ -5,7 +5,8 @@ //! //! -use std::str::FromStr; +use core::fmt; +use core::str::FromStr; use bip39::Mnemonic; use bitcoin::bip32::{DerivationPath, ExtendedPrivKey}; @@ -18,14 +19,35 @@ use secp256k1::rand::RngCore; use crate::{Keys, SECP256K1}; /// `NIP06` error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { /// BIP32 error - #[error(transparent)] - BIP32(#[from] bitcoin::bip32::Error), + BIP32(bitcoin::bip32::Error), /// BIP39 error - #[error(transparent)] - BIP39(#[from] bip39::Error), + BIP39(bip39::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::BIP32(e) => write!(f, "{e}"), + Self::BIP39(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: bitcoin::bip32::Error) -> Self { + Self::BIP32(e) + } +} + +impl From for Error { + fn from(e: bip39::Error) -> Self { + Self::BIP39(e) + } } #[allow(missing_docs)] diff --git a/crates/nostr/src/nips/nip11.rs b/crates/nostr/src/nips/nip11.rs index 8cf6b9b2a..e8db61898 100644 --- a/crates/nostr/src/nips/nip11.rs +++ b/crates/nostr/src/nips/nip11.rs @@ -6,6 +6,7 @@ //! //! +use core::fmt; #[cfg(not(target_arch = "wasm32"))] use std::net::SocketAddr; @@ -15,20 +16,39 @@ use serde::{Deserialize, Serialize}; use url::Url; /// `NIP11` error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { - /// Reqwest error - #[error(transparent)] - Reqwest(#[from] reqwest::Error), /// The relay information document is invalid - #[error("The relay information document is invalid")] InvalidInformationDocument, /// The relay information document is not accessible - #[error("The relay information document is not accessible")] InaccessibleInformationDocument, /// Provided URL scheme is not valid - #[error("Provided URL scheme is not valid")] InvalidScheme, + /// Reqwest error + Reqwest(reqwest::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidInformationDocument => { + write!(f, "The relay information document is invalid") + } + Self::InaccessibleInformationDocument => { + write!(f, "The relay information document is not accessible") + } + Self::InvalidScheme => write!(f, "Provided URL scheme is not valid"), + Self::Reqwest(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: reqwest::Error) -> Self { + Self::Reqwest(e) + } } /// Relay information document diff --git a/crates/nostr/src/nips/nip19.rs b/crates/nostr/src/nips/nip19.rs index d7dfbbb88..9b06a7503 100644 --- a/crates/nostr/src/nips/nip19.rs +++ b/crates/nostr/src/nips/nip19.rs @@ -7,6 +7,9 @@ #![allow(missing_docs)] +use core::fmt; +use std::string::FromUtf8Error; + use bech32::{self, FromBase32, ToBase32, Variant}; use bitcoin_hashes::Hash; use secp256k1::{SecretKey, XOnlyPublicKey}; @@ -29,35 +32,74 @@ pub const AUTHOR: u8 = 2; pub const KIND: u8 = 3; /// `NIP19` error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { + /// Bech32 error. + Bech32(bech32::Error), + /// UFT-8 error + UTF8(FromUtf8Error), + /// Secp256k1 error + Secp256k1(secp256k1::Error), + /// Hash error + Hash(bitcoin_hashes::Error), + /// EventId error + EventId(id::Error), /// Wrong prefix or variant - #[error("wrong prefix or variant")] WrongPrefixOrVariant, - /// Bech32 error. - #[error(transparent)] - Bech32(#[from] bech32::Error), /// Field missing - #[error("field missing: {0}")] FieldMissing(String), /// TLV error - #[error("type-length-value error")] TLV, - /// UFT-8 error - #[error(transparent)] - UTF8(#[from] std::string::FromUtf8Error), /// From slice error - #[error("impossible to perform conversion from slice")] TryFromSlice, - /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), - /// Hash error - #[error(transparent)] - Hash(#[from] bitcoin_hashes::Error), - /// EventId error - #[error(transparent)] - EventId(#[from] id::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Bech32(e) => write!(f, "{e}"), + Self::UTF8(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::Hash(e) => write!(f, "{e}"), + Self::EventId(e) => write!(f, "{e}"), + Self::WrongPrefixOrVariant => write!(f, "wrong prefix or variant"), + Self::FieldMissing(name) => write!(f, "field missing: {name}"), + Self::TLV => write!(f, "type-length-value error"), + Self::TryFromSlice => write!(f, "impossible to perform conversion from slice"), + } + } +} + +impl From for Error { + fn from(e: bech32::Error) -> Self { + Self::Bech32(e) + } +} + +impl From for Error { + fn from(e: FromUtf8Error) -> Self { + Self::UTF8(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::Error) -> Self { + Self::Hash(e) + } +} + +impl From for Error { + fn from(e: id::Error) -> Self { + Self::EventId(e) + } } pub trait FromBech32: Sized { diff --git a/crates/nostr/src/nips/nip26.rs b/crates/nostr/src/nips/nip26.rs index 06d84ea3f..4c0d041ea 100644 --- a/crates/nostr/src/nips/nip26.rs +++ b/crates/nostr/src/nips/nip26.rs @@ -5,8 +5,9 @@ //! //! -use std::fmt; -use std::str::FromStr; +use core::fmt; +use core::num::ParseIntError; +use core::str::FromStr; use bitcoin_hashes::sha256::Hash as Sha256Hash; use bitcoin_hashes::Hash; @@ -23,45 +24,91 @@ use crate::SECP256K1; const DELEGATION_KEYWORD: &str = "delegation"; /// `NIP26` error -#[derive(Debug, Eq, PartialEq, thiserror::Error)] +#[derive(Debug, Eq, PartialEq)] pub enum Error { /// Key error - #[error(transparent)] - Key(#[from] key::Error), + Key(key::Error), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), - /// Invalid condition in conditions string - #[error("Invalid condition in conditions string")] - ConditionsParseInvalidCondition, + Secp256k1(secp256k1::Error), /// Invalid condition, cannot parse expected number - #[error("Invalid condition, cannot parse expected number")] - ConditionsParseNumeric(#[from] std::num::ParseIntError), + ConditionsParseNumeric(ParseIntError), /// Conditions not satisfied - #[error("Conditions not satisfied")] - ConditionsValidation(#[from] ValidationError), + ConditionsValidation(ValidationError), + /// Invalid condition in conditions string + ConditionsParseInvalidCondition, /// Delegation tag parse error - #[error("Delegation tag parse error")] DelegationTagParse, } +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Key(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::ConditionsParseNumeric(_) => { + write!(f, "Invalid condition, cannot parse expected number") + } + Self::ConditionsValidation(_) => write!(f, "Conditions not satisfied"), + Self::ConditionsParseInvalidCondition => { + write!(f, "Invalid condition in conditions string") + } + Self::DelegationTagParse => write!(f, "Delegation tag parse error"), + } + } +} + +impl From for Error { + fn from(e: key::Error) -> Self { + Self::Key(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: ParseIntError) -> Self { + Self::ConditionsParseNumeric(e) + } +} + +impl From for Error { + fn from(e: ValidationError) -> Self { + Self::ConditionsValidation(e) + } +} + /// Tag validation errors -#[derive(Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Debug, PartialEq, Eq)] pub enum ValidationError { /// Signature does not match - #[error("Signature does not match")] InvalidSignature, /// Event kind does not match - #[error("Event kind does not match")] InvalidKind, /// Creation time is earlier than validity period - #[error("Creation time is earlier than validity period")] CreatedTooEarly, /// Creation time is later than validity period - #[error("Creation time is later than validity period")] CreatedTooLate, } +impl std::error::Error for ValidationError {} + +impl fmt::Display for ValidationError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidSignature => write!(f, "Signature does not match"), + Self::InvalidKind => write!(f, "Event kind does not match"), + Self::CreatedTooEarly => write!(f, "Creation time is earlier than validity period"), + Self::CreatedTooLate => write!(f, "Creation time is later than validity period"), + } + } +} + /// Sign delegation. /// See `create_delegation_tag` for more complete functionality. pub fn sign_delegation( diff --git a/crates/nostr/src/nips/nip46.rs b/crates/nostr/src/nips/nip46.rs index b3a647d3b..80ad4cdcf 100644 --- a/crates/nostr/src/nips/nip46.rs +++ b/crates/nostr/src/nips/nip46.rs @@ -5,9 +5,9 @@ //! //! +use core::fmt; +use core::str::FromStr; use std::borrow::Cow; -use std::fmt; -use std::str::FromStr; use bitcoin_hashes::sha256::Hash as Sha256Hash; use bitcoin_hashes::Hash; @@ -20,50 +20,101 @@ use url::Url; use super::nip04; use super::nip26::{self, sign_delegation, Conditions}; +use crate::event::unsigned::{self, UnsignedEvent}; use crate::key::{self, Keys}; -use crate::UnsignedEvent; /// NIP46 error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Key error - #[error(transparent)] - Key(#[from] key::Error), + Key(key::Error), /// JSON error - #[error(transparent)] - JSON(#[from] serde_json::Error), + Json(serde_json::Error), /// Url parse error - #[error(transparent)] - Url(#[from] url::ParseError), + Url(url::ParseError), /// Secp256k1 error - #[error(transparent)] - Secp256k1(#[from] secp256k1::Error), + Secp256k1(secp256k1::Error), /// NIP04 error - #[error(transparent)] - NIP04(#[from] nip04::Error), + NIP04(nip04::Error), /// NIP26 error - #[error(transparent)] - NIP26(#[from] nip26::Error), + NIP26(nip26::Error), /// Unsigned event error - #[error(transparent)] - UnsignedEvent(#[from] crate::event::unsigned::Error), + UnsignedEvent(unsigned::Error), /// Invalid request - #[error("invalid request")] InvalidRequest, /// Too many/few params - #[error("too many/few params")] InvalidParamsLength, /// Unsupported method - #[error("unsupported method: {0}")] UnsupportedMethod(String), /// Invalid URI - #[error("invalid uri")] InvalidURI, /// Invalid URI scheme - #[error("invalid uri scheme")] InvalidURIScheme, } +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Key(e) => write!(f, "{e}"), + Self::Json(e) => write!(f, "{e}"), + Self::Url(e) => write!(f, "{e}"), + Self::Secp256k1(e) => write!(f, "{e}"), + Self::NIP04(e) => write!(f, "{e}"), + Self::NIP26(e) => write!(f, "{e}"), + Self::UnsignedEvent(e) => write!(f, "{e}"), + Self::InvalidRequest => write!(f, "invalid request"), + Self::InvalidParamsLength => write!(f, "too many/few params"), + Self::UnsupportedMethod(name) => write!(f, "unsupported method: {name}"), + Self::InvalidURI => write!(f, "invalid uri"), + Self::InvalidURIScheme => write!(f, "invalid uri scheme"), + } + } +} + +impl From for Error { + fn from(e: key::Error) -> Self { + Self::Key(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } +} + +impl From for Error { + fn from(e: url::ParseError) -> Self { + Self::Url(e) + } +} + +impl From for Error { + fn from(e: secp256k1::Error) -> Self { + Self::Secp256k1(e) + } +} + +impl From for Error { + fn from(e: nip04::Error) -> Self { + Self::NIP04(e) + } +} + +impl From for Error { + fn from(e: nip26::Error) -> Self { + Self::NIP26(e) + } +} + +impl From for Error { + fn from(e: unsigned::Error) -> Self { + Self::UnsignedEvent(e) + } +} + /// Request #[derive(Debug, Clone)] pub enum Request { diff --git a/crates/nostr/src/nips/nip58.rs b/crates/nostr/src/nips/nip58.rs index f85d4819b..749ccfd97 100644 --- a/crates/nostr/src/nips/nip58.rs +++ b/crates/nostr/src/nips/nip58.rs @@ -2,23 +2,44 @@ //! //! +use core::fmt; + use secp256k1::XOnlyPublicKey; use crate::event::builder::Error as BuilderError; use crate::{Event, EventBuilder, Keys, Kind, Tag, UncheckedUrl}; -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] /// [`BadgeAward`] error pub enum Error { /// Invalid kind - #[error("invalid kind")] InvalidKind, /// Identifier tag not found - #[error("identifier tag not found")] IdentifierTagNotFound, - /// Event builder Error - #[error(transparent)] - Event(#[from] crate::event::builder::Error), + /// Event builder error + EventBuilder(crate::event::builder::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidKind => { + write!(f, "invalid kind") + } + Self::IdentifierTagNotFound => { + write!(f, "identifier tag not found") + } + Self::EventBuilder(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: crate::event::builder::Error) -> Self { + Self::EventBuilder(e) + } } /// Simple struct to hold `width` x `height. @@ -172,29 +193,50 @@ impl BadgeAward { pub struct ProfileBadgesEvent(Event); /// [`ProfileBadgesEvent`] errors -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum ProfileBadgesEventError { /// Invalid length - #[error("invalid length")] InvalidLength, /// Invalid kind - #[error("invalid kind")] InvalidKind, /// Mismatched badge definition or award - #[error("mismatched badge definition/award")] MismatchedBadgeDefinitionOrAward, /// Badge awards lack the awarded public key - #[error("badge award events lack the awarded public key")] BadgeAwardsLackAwardedPublicKey, /// Badge awards lack the awarded public key - #[error("badge award event lacks `a` tag")] BadgeAwardMissingATag, /// Badge Definition Event error - #[error(transparent)] - BadgeDefinitionError(#[from] Error), + BadgeDefinition(Error), /// Event builder Error - #[error(transparent)] - EventBuilder(#[from] crate::event::builder::Error), + EventBuilder(crate::event::builder::Error), +} + +impl std::error::Error for ProfileBadgesEventError {} + +impl fmt::Display for ProfileBadgesEventError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidLength => write!(f, "invalid length"), + Self::InvalidKind => write!(f, "invalid kind"), + Self::MismatchedBadgeDefinitionOrAward => write!(f, "mismatched badge definition/award"), + Self::BadgeAwardsLackAwardedPublicKey => write!(f, "badge award events lack the awarded public keybadge award events lack the awarded public key"), + Self::BadgeAwardMissingATag => write!(f, "badge award event lacks `a` tag"), + Self::BadgeDefinition(e) => write!(f, "{e}"), + Self::EventBuilder(e) => write!(f, "{e}"), + } + } +} + +impl From for ProfileBadgesEventError { + fn from(e: Error) -> Self { + Self::BadgeDefinition(e) + } +} + +impl From for ProfileBadgesEventError { + fn from(e: crate::event::builder::Error) -> Self { + Self::EventBuilder(e) + } } impl ProfileBadgesEvent { @@ -265,15 +307,14 @@ impl ProfileBadgesEvent { .map(|event| { let tags = core::mem::take(&mut event.tags); let id = Self::extract_identifier(tags).ok_or( - ProfileBadgesEventError::BadgeDefinitionError(Error::IdentifierTagNotFound), + ProfileBadgesEventError::BadgeDefinition(Error::IdentifierTagNotFound), )?; Ok((event.clone(), id)) }) .collect::, ProfileBadgesEventError>>(); - let badge_definitions_identifiers = badge_definitions_identifiers.map_err(|_| { - ProfileBadgesEventError::BadgeDefinitionError(Error::IdentifierTagNotFound) - })?; + let badge_definitions_identifiers = badge_definitions_identifiers + .map_err(|_| ProfileBadgesEventError::BadgeDefinition(Error::IdentifierTagNotFound))?; let badge_awards_identifiers = badge_awards .iter_mut() diff --git a/crates/nostr/src/types/channel_id.rs b/crates/nostr/src/types/channel_id.rs index 0e4aedf1f..a3cf1036a 100644 --- a/crates/nostr/src/types/channel_id.rs +++ b/crates/nostr/src/types/channel_id.rs @@ -3,7 +3,8 @@ //! Channel Id -use std::{fmt, str::FromStr}; +use core::fmt; +use core::str::FromStr; #[cfg(feature = "nip19")] use bech32::{self, FromBase32, ToBase32, Variant}; @@ -18,14 +19,35 @@ use crate::nips::nip19::{ use crate::EventId; /// [`ChannelId`] error -#[derive(Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Debug, PartialEq, Eq)] pub enum Error { /// Hex error - #[error(transparent)] - Hex(#[from] bitcoin_hashes::hex::Error), + Hex(bitcoin_hashes::hex::Error), /// Hash error - #[error(transparent)] - Hash(#[from] bitcoin_hashes::Error), + Hash(bitcoin_hashes::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Hex(e) => write!(f, "{e}"), + Self::Hash(e) => write!(f, "{e}"), + } + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::hex::Error) -> Self { + Self::Hex(e) + } +} + +impl From for Error { + fn from(e: bitcoin_hashes::Error) -> Self { + Self::Hash(e) + } } /// Channel Id diff --git a/crates/nostr/src/types/metadata.rs b/crates/nostr/src/types/metadata.rs index e9f868af8..2d6a9f068 100644 --- a/crates/nostr/src/types/metadata.rs +++ b/crates/nostr/src/types/metadata.rs @@ -3,15 +3,32 @@ //! Metadata +use core::fmt; + use serde::{Deserialize, Serialize}; use url::Url; /// [`Metadata`] error -#[derive(Debug, thiserror::Error)] +#[derive(Debug)] pub enum Error { /// Error serializing or deserializing JSON data - #[error("json error: {0}")] - Json(#[from] serde_json::Error), + Json(serde_json::Error), +} + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Json(e) => write!(f, "json error: {e}"), + } + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Self::Json(e) + } } /// Metadata