Переглянути джерело

refactor: remove mint and wallet error mods

thesimplekid 1 рік тому
батько
коміт
ce207953a1

+ 10 - 15
crates/cdk/src/dhke.rs

@@ -6,7 +6,7 @@ use bitcoin::hashes::sha256::Hash as Sha256Hash;
 use bitcoin::hashes::Hash;
 use bitcoin::secp256k1::{Parity, PublicKey as NormalizedPublicKey, Scalar, XOnlyPublicKey};
 
-use crate::error::{self, Error};
+use crate::error::Error;
 use crate::nuts::nut01::{PublicKey, SecretKey};
 use crate::nuts::nut12::ProofDleq;
 use crate::nuts::{BlindSignature, Keys, Proof, Proofs};
@@ -62,7 +62,7 @@ where
 pub fn blind_message(
     secret: &[u8],
     blinding_factor: Option<SecretKey>,
-) -> Result<(PublicKey, SecretKey), error::wallet::Error> {
+) -> Result<(PublicKey, SecretKey), Error> {
     let y: PublicKey = hash_to_curve(secret)?;
     let r: SecretKey = blinding_factor.unwrap_or_else(SecretKey::generate);
     Ok((y.combine(&r.public_key())?.into(), r))
@@ -77,7 +77,7 @@ pub fn unblind_message(
     r: &SecretKey,
     // K
     mint_pubkey: &PublicKey,
-) -> Result<PublicKey, error::wallet::Error> {
+) -> Result<PublicKey, Error> {
     let r: Scalar = Scalar::from(r.deref().to_owned());
 
     // a = r * K
@@ -94,15 +94,13 @@ pub fn construct_proofs(
     rs: Vec<SecretKey>,
     secrets: Vec<Secret>,
     keys: &Keys,
-) -> Result<Proofs, error::wallet::Error> {
+) -> Result<Proofs, Error> {
     let mut proofs = vec![];
     for ((blinded_signature, r), secret) in promises.into_iter().zip(rs).zip(secrets) {
         let blinded_c: PublicKey = blinded_signature.c;
-        let a: PublicKey =
-            keys.amount_key(blinded_signature.amount)
-                .ok_or(error::wallet::Error::CustomError(
-                    "Could not get proofs".to_string(),
-                ))?;
+        let a: PublicKey = keys
+            .amount_key(blinded_signature.amount)
+            .ok_or(Error::CustomError("Could not get proofs".to_string()))?;
 
         let unblinded_signature: PublicKey = unblind_message(&blinded_c, &r, &a)?;
 
@@ -129,10 +127,7 @@ pub fn construct_proofs(
 /// * `k` is the private key of mint (one for each amount)
 /// * `B_` is the blinded message
 #[inline]
-pub fn sign_message(
-    k: &SecretKey,
-    blinded_message: &PublicKey,
-) -> Result<PublicKey, error::mint::Error> {
+pub fn sign_message(k: &SecretKey, blinded_message: &PublicKey) -> Result<PublicKey, Error> {
     let k: Scalar = Scalar::from(k.deref().to_owned());
     Ok(blinded_message.mul_tweak(&SECP256K1, &k)?.into())
 }
@@ -142,7 +137,7 @@ pub fn verify_message(
     a: &SecretKey,
     unblinded_message: PublicKey,
     msg: &[u8],
-) -> Result<(), error::mint::Error> {
+) -> Result<(), Error> {
     // Y
     let y: PublicKey = hash_to_curve(msg)?;
 
@@ -154,7 +149,7 @@ pub fn verify_message(
         return Ok(());
     }
 
-    Err(error::mint::Error::TokenNotVerifed)
+    Err(Error::TokenNotVerifed)
 }
 
 #[cfg(test)]

+ 0 - 38
crates/cdk/src/error/mint.rs

@@ -1,38 +0,0 @@
-use thiserror::Error;
-
-use crate::nuts::nut01;
-
-#[derive(Debug, Error)]
-pub enum Error {
-    #[error("No key for amount")]
-    AmountKey,
-    #[error("Amount miss match")]
-    Amount,
-    #[error("Token Already Spent")]
-    TokenSpent,
-    /// Secp256k1 error
-    #[error(transparent)]
-    Secp256k1(#[from] bitcoin::secp256k1::Error),
-    /// NUT01 error
-    #[error(transparent)]
-    NUT01(#[from] nut01::Error),
-    #[error("`Token not verified`")]
-    TokenNotVerifed,
-    #[error("Invoice amount undefined")]
-    InvoiceAmountUndefined,
-    /// Duplicate Proofs sent in request
-    #[error("Duplicate proofs")]
-    DuplicateProofs,
-    /// Keyset id not active
-    #[error("Keyset id is not active")]
-    InactiveKeyset,
-    /// Keyset is not known
-    #[error("Unknown Keyset")]
-    UnknownKeySet,
-    #[error(transparent)]
-    Secret(#[from] crate::secret::Error),
-    #[error(transparent)]
-    Cashu(#[from] super::Error),
-    #[error("`{0}`")]
-    CustomError(String),
-}

+ 40 - 40
crates/cdk/src/error/mod.rs

@@ -1,3 +1,5 @@
+//! Errors
+
 use std::string::FromUtf8Error;
 
 use serde::{Deserialize, Serialize};
@@ -5,68 +7,66 @@ use thiserror::Error;
 
 use crate::util::hex;
 
-pub mod mint;
-pub mod wallet;
-
 #[derive(Debug, Error)]
 pub enum Error {
-    /// Parse Url Error
-    #[error(transparent)]
-    UrlParseError(#[from] url::ParseError),
-    /// Utf8 parse error
-    #[error(transparent)]
-    Utf8ParseError(#[from] FromUtf8Error),
-    /// Serde Json error
-    #[error(transparent)]
-    SerdeJsonError(#[from] serde_json::Error),
-    /// Base64 error
-    #[error(transparent)]
-    Base64Error(#[from] base64::DecodeError),
-    /// From hex error
-    #[error(transparent)]
-    HexError(#[from] hex::Error),
-    /// Secp256k1 error
-    #[error(transparent)]
-    Secp256k1(#[from] bitcoin::secp256k1::Error),
-    #[error("No Key for Amoun")]
+    /// Mint does not have a key for amount
+    #[error("No Key for Amount")]
     AmountKey,
+    /// Amount is not what expected
     #[error("Amount miss match")]
     Amount,
+    /// Token is already spent
     #[error("Token already spent")]
     TokenSpent,
+    /// Token could not be validated
     #[error("Token not verified")]
     TokenNotVerifed,
+    /// Bolt11 invoice does not have amount
     #[error("Invoice Amount undefined")]
     InvoiceAmountUndefined,
+    /// Proof is missing a required field
     #[error("Proof missing required field")]
     MissingProofField,
+    /// No valid point on curve
     #[error("No valid point found")]
     NoValidPoint,
-    #[error("Kind not found")]
-    KindNotFound,
-    #[error("Unknown Tag")]
-    UnknownTag,
-    #[error("Incorrect Secret Kind")]
-    IncorrectSecretKind,
-    #[error("Spending conditions not met")]
-    SpendConditionsNotMet,
-    #[error("Could not convert key")]
-    Key,
-    #[error("Invalid signature")]
-    InvalidSignature,
-    #[error("Locktime in past")]
-    LocktimeInPast,
-    #[error(transparent)]
-    Secret(#[from] super::secret::Error),
+    /// Secp256k1 error
     #[error(transparent)]
-    NUT01(#[from] crate::nuts::nut01::Error),
+    Secp256k1(#[from] bitcoin::secp256k1::Error),
+    /// Secret error
     #[error(transparent)]
-    NUT02(#[from] crate::nuts::nut02::Error),
+    Secret(#[from] super::secret::Error),
+    /// Bip32 error
     #[cfg(feature = "nut13")]
     #[error(transparent)]
     Bip32(#[from] bitcoin::bip32::Error),
+    /// Parse int error
     #[error(transparent)]
     ParseInt(#[from] std::num::ParseIntError),
+    /// Parse Url Error
+    #[error(transparent)]
+    UrlParseError(#[from] url::ParseError),
+    /// Utf8 parse error
+    #[error(transparent)]
+    Utf8ParseError(#[from] FromUtf8Error),
+    /// Serde Json error
+    #[error(transparent)]
+    SerdeJsonError(#[from] serde_json::Error),
+    /// Base64 error
+    #[error(transparent)]
+    Base64Error(#[from] base64::DecodeError),
+    /// From hex error
+    #[error(transparent)]
+    HexError(#[from] hex::Error),
+    /// Nut01 error
+    #[error(transparent)]
+    NUT01(#[from] crate::nuts::nut01::Error),
+    /// NUT02 error
+    #[error(transparent)]
+    NUT02(#[from] crate::nuts::nut02::Error),
+    /// NUT11 Error
+    #[error(transparent)]
+    NUT11(#[from] crate::nuts::nut11::Error),
     /// Custom error
     #[error("`{0}`")]
     CustomError(String),

+ 0 - 49
crates/cdk/src/error/wallet.rs

@@ -1,49 +0,0 @@
-use std::string::FromUtf8Error;
-
-use thiserror::Error;
-
-use crate::nuts::nut01;
-
-#[derive(Debug, Error)]
-pub enum Error {
-    /// Serde Json error
-    #[error(transparent)]
-    SerdeJsonError(#[from] serde_json::Error),
-    /// Secp256k1 error
-    #[error(transparent)]
-    Secp256k1(#[from] bitcoin::secp256k1::Error),
-    /// NUT01 error
-    #[error(transparent)]
-    NUT01(#[from] nut01::Error),
-    /// Insufficient Funds
-    #[error("Insufficient funds")]
-    InsufficientFunds,
-    /// Utf8 parse error
-    #[error(transparent)]
-    Utf8ParseError(#[from] FromUtf8Error),
-    /// Base64 error
-    #[error(transparent)]
-    Base64Error(#[from] base64::DecodeError),
-    /// Unsupported Token
-    #[error("Token unsupported")]
-    UnsupportedToken,
-    /// Token Requires proofs
-    #[error("Proofs Required")]
-    ProofsRequired,
-    /// Url Parse error
-    #[error("Url Parse")]
-    UrlParse,
-    #[error(transparent)]
-    Secret(#[from] crate::secret::Error),
-    #[error(transparent)]
-    Cashu(#[from] super::Error),
-    /// Custom Error message
-    #[error("`{0}`")]
-    CustomError(String),
-}
-
-impl From<crate::url::Error> for Error {
-    fn from(_err: crate::url::Error) -> Error {
-        Error::UrlParse
-    }
-}

+ 2 - 0
crates/cdk/src/mint/localstore/mod.rs

@@ -46,6 +46,8 @@ pub enum Error {
     #[error(transparent)]
     Cashu(#[from] crate::error::Error),
     #[error(transparent)]
+    NUT00(#[from] crate::nuts::nut00::Error),
+    #[error(transparent)]
     CashuNut02(#[from] crate::nuts::nut02::Error),
     #[error(transparent)]
     Secret(#[from] crate::secret::Error),

+ 6 - 8
crates/cdk/src/mint/mod.rs

@@ -9,15 +9,11 @@ use tracing::{debug, error, info};
 
 use crate::dhke::{hash_to_curve, sign_message, verify_message};
 use crate::error::ErrorResponse;
-use crate::nuts::nut07::{ProofState, State};
-use crate::nuts::{
-    BlindSignature, BlindedMessage, CheckStateRequest, CheckStateResponse, MeltBolt11Request,
-    MeltBolt11Response, Proof, RestoreRequest, RestoreResponse, SwapRequest, SwapResponse, *,
-};
+use crate::nuts::*;
 use crate::types::{MeltQuote, MintQuote};
 use crate::Amount;
 
-mod localstore;
+pub mod localstore;
 #[cfg(all(not(target_arch = "wasm32"), feature = "redb"))]
 pub use localstore::RedbLocalStore;
 pub use localstore::{LocalStore, MemoryLocalStore};
@@ -45,14 +41,16 @@ pub enum Error {
     #[error("`{0}`")]
     Custom(String),
     #[error(transparent)]
-    CashuMint(#[from] crate::error::mint::Error),
-    #[error(transparent)]
     Cashu(#[from] crate::error::Error),
     #[error(transparent)]
     Localstore(#[from] localstore::Error),
     #[error(transparent)]
     Secret(#[from] crate::secret::Error),
     #[error(transparent)]
+    NUT00(#[from] crate::nuts::nut00::Error),
+    #[error(transparent)]
+    NUT11(#[from] crate::nuts::nut11::Error),
+    #[error(transparent)]
     Nut12(#[from] crate::nuts::nut12::Error),
     #[error("Unknown quote")]
     UnknownQuote,

+ 41 - 10
crates/cdk/src/nuts/nut00.rs

@@ -4,16 +4,48 @@
 use std::fmt;
 use std::hash::{self, Hasher};
 use std::str::FromStr;
+use std::string::FromUtf8Error;
 
 use serde::{Deserialize, Serialize};
+use thiserror::Error;
 
 use super::{BlindSignatureDleq, Id, ProofDleq, Proofs, PublicKey, Signatures};
-use crate::error::Error;
 use crate::nuts::nut11::{witness_deserialize, witness_serialize};
 use crate::secret::Secret;
 use crate::url::UncheckedUrl;
 use crate::Amount;
 
+#[derive(Debug, Error)]
+pub enum Error {
+    /// Proofs required
+    #[error("Proofs required in token")]
+    ProofsRequired,
+    /// Unsupported token
+    #[error("Unsupported token")]
+    UnsupportedToken,
+    /// Invalid Url
+    #[error("Invalid Url")]
+    InvalidUrl,
+    /// Serde Json error
+    #[error(transparent)]
+    SerdeJsonError(#[from] serde_json::Error),
+    /// Utf8 parse error
+    #[error(transparent)]
+    Utf8ParseError(#[from] FromUtf8Error),
+    /// Base64 error
+    #[error(transparent)]
+    Base64Error(#[from] base64::DecodeError),
+    /// Parse Url Error
+    #[error(transparent)]
+    UrlParseError(#[from] url::ParseError),
+    /// CDK error
+    #[error(transparent)]
+    Cdk(#[from] crate::error::Error),
+    /// NUT11 error
+    #[error(transparent)]
+    NUT11(#[from] crate::nuts::nut11::Error),
+}
+
 /// Blinded Message [NUT-00]
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub struct BlindedMessage {
@@ -114,13 +146,12 @@ pub mod wallet {
     use serde::{Deserialize, Serialize};
     use url::Url;
 
-    use super::{CurrencyUnit, MintProofs};
+    use super::{CurrencyUnit, MintProofs, *};
     use crate::dhke::blind_message;
-    use crate::error::wallet;
     use crate::nuts::{BlindedMessage, Id, P2PKConditions, Proofs, SecretKey};
     use crate::secret::Secret;
     use crate::url::UncheckedUrl;
-    use crate::{error, Amount};
+    use crate::Amount;
 
     #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
     pub struct PreMint {
@@ -153,7 +184,7 @@ pub mod wallet {
 
     impl PreMintSecrets {
         /// Outputs for speceifed amount with random secret
-        pub fn random(keyset_id: Id, amount: Amount) -> Result<Self, wallet::Error> {
+        pub fn random(keyset_id: Id, amount: Amount) -> Result<Self, Error> {
             let amount_split = amount.split();
 
             let mut output = Vec::with_capacity(amount_split.len());
@@ -330,13 +361,13 @@ pub mod wallet {
             proofs: Proofs,
             memo: Option<String>,
             unit: Option<CurrencyUnit>,
-        ) -> Result<Self, wallet::Error> {
+        ) -> Result<Self, Error> {
             if proofs.is_empty() {
-                return Err(wallet::Error::ProofsRequired);
+                return Err(Error::ProofsRequired);
             }
 
             // Check Url is valid
-            let _: Url = (&mint_url).try_into()?;
+            let _: Url = (&mint_url).try_into().map_err(|_| Error::InvalidUrl)?;
 
             Ok(Self {
                 token: vec![MintProofs::new(mint_url, proofs)],
@@ -359,13 +390,13 @@ pub mod wallet {
     }
 
     impl FromStr for Token {
-        type Err = error::wallet::Error;
+        type Err = Error;
 
         fn from_str(s: &str) -> Result<Self, Self::Err> {
             let s = if s.starts_with("cashuA") {
                 s.replace("cashuA", "")
             } else {
-                return Err(wallet::Error::UnsupportedToken);
+                return Err(Error::UnsupportedToken);
             };
 
             let decode_config = general_purpose::GeneralPurposeConfig::new()

+ 52 - 9
crates/cdk/src/nuts/nut11.rs

@@ -16,15 +16,60 @@ use bitcoin::secp256k1::{
 use serde::de::Error as DeserializerError;
 use serde::ser::SerializeSeq;
 use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
+use thiserror::Error;
 
 use super::nut01::PublicKey;
 use super::nut10::{Secret, SecretData};
 use super::{Proof, SecretKey};
-use crate::error::Error;
 use crate::nuts::nut00::BlindedMessage;
 use crate::util::{hex, unix_time};
 use crate::SECP256K1;
 
+#[derive(Debug, Error)]
+pub enum Error {
+    /// Incorrect secret kind
+    #[error("Secret is not a p2pk secret")]
+    IncorrectSecretKind,
+    /// P2PK locktime has already passed
+    #[error("Locktime in past")]
+    LocktimeInPast,
+    /// Witness signature is not valid
+    #[error("Invalid signature")]
+    InvalidSignature,
+    /// Unknown tag in P2PK secret
+    #[error("Unknown Tag P2PK secret")]
+    UnknownTag,
+    /// P2PK Spend conditions not meet
+    #[error("P2PK Spend conditions are not met")]
+    SpendConditionsNotMet,
+    /// Pubkey must be in data field of P2PK
+    #[error("P2PK Required in secret data")]
+    P2PKPubkeyRequired,
+    #[error("Kind not found")]
+    KindNotFound,
+    /// Parse Url Error
+    #[error(transparent)]
+    UrlParseError(#[from] url::ParseError),
+    /// Parse int error
+    #[error(transparent)]
+    ParseInt(#[from] std::num::ParseIntError),
+    /// From hex error
+    #[error(transparent)]
+    HexError(#[from] hex::Error),
+    /// Serde Json error
+    #[error(transparent)]
+    SerdeJsonError(#[from] serde_json::Error),
+    /// Secp256k1 error
+    #[error(transparent)]
+    Secp256k1(#[from] bitcoin::secp256k1::Error),
+    /// NUT01 Error
+    #[error(transparent)]
+    NUT01(#[from] crate::nuts::nut01::Error),
+    /// Secret error
+    #[error(transparent)]
+    Secret(#[from] crate::secret::Error),
+}
+
 #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub struct Signatures {
     #[serde(default)]
@@ -219,12 +264,10 @@ impl TryFrom<P2PKConditions> for Secret {
             sig_flag,
         } = conditions;
 
-        // Check there is at least one pubkey
-        if pubkeys.len().lt(&1) {
-            return Err(Error::Amount);
-        }
-
-        let data: PublicKey = pubkeys[0].clone().to_normalized_public_key();
+        let data = match pubkeys.first() {
+            Some(data) => data.to_string(),
+            None => return Err(Error::P2PKPubkeyRequired),
+        };
 
         let data = data.to_string();
 
@@ -263,7 +306,7 @@ impl TryFrom<P2PKConditions> for crate::secret::Secret {
     fn try_from(conditions: P2PKConditions) -> Result<crate::secret::Secret, Self::Error> {
         let secret: Secret = conditions.try_into()?;
 
-        secret.try_into()
+        secret.try_into().map_err(|_| Error::IncorrectSecretKind)
     }
 }
 
@@ -597,7 +640,7 @@ impl TryFrom<&PublicKey> for VerifyingKey {
             bytes.to_vec()
         };
 
-        VerifyingKey::from_bytes(&bytes).map_err(|_| Error::Key)
+        VerifyingKey::from_bytes(&bytes)
     }
 }
 

+ 3 - 3
crates/cdk/src/nuts/nut13.rs

@@ -63,7 +63,7 @@ mod wallet {
     use bip39::Mnemonic;
 
     use crate::dhke::blind_message;
-    use crate::error::wallet;
+    use crate::error::Error;
     use crate::nuts::{BlindedMessage, Id, PreMint, PreMintSecrets, SecretKey};
     use crate::secret::Secret;
     use crate::Amount;
@@ -77,7 +77,7 @@ mod wallet {
             mnemonic: &Mnemonic,
             amount: Amount,
             zero_amount: bool,
-        ) -> Result<Self, wallet::Error> {
+        ) -> Result<Self, Error> {
             let mut pre_mint_secrets = PreMintSecrets::default();
 
             let mut counter = counter;
@@ -113,7 +113,7 @@ mod wallet {
             mnemonic: &Mnemonic,
             start_count: u64,
             end_count: u64,
-        ) -> Result<Self, wallet::Error> {
+        ) -> Result<Self, Error> {
             let mut pre_mint_secrets = PreMintSecrets::default();
 
             for i in start_count..=end_count {

+ 14 - 10
crates/cdk/src/wallet/mod.rs

@@ -28,22 +28,15 @@ pub enum Error {
     /// Insufficient Funds
     #[error("Insufficient Funds")]
     InsufficientFunds,
-    #[error("`{0}`")]
-    CashuWallet(#[from] crate::error::wallet::Error),
-    #[error("`{0}`")]
-    Client(#[from] crate::client::Error),
-    /// Cashu Url Error
-    #[error("`{0}`")]
-    CashuUrl(#[from] crate::url::Error),
     #[error("Quote Expired")]
     QuoteExpired,
     #[error("Quote Unknown")]
     QuoteUnknown,
     #[error("No active keyset")]
     NoActiveKeyset,
-    #[error("`{0}`")]
+    #[error(transparent)]
     LocalStore(#[from] localstore::Error),
-    #[error("`{0}`")]
+    #[error(transparent)]
     Cashu(#[from] crate::error::Error),
     #[error("Could not verify Dleq")]
     CouldNotVerifyDleq,
@@ -53,8 +46,19 @@ pub enum Error {
     InvalidSpendConditions(String),
     #[error("Unknown Key")]
     UnknownKey,
-    #[error("`{0}`")]
+    #[error(transparent)]
     ParseInt(#[from] ParseIntError),
+    #[error(transparent)]
+    Client(#[from] crate::client::Error),
+    /// Cashu Url Error
+    #[error(transparent)]
+    CashuUrl(#[from] crate::url::Error),
+    /// NUT00 Error
+    #[error(transparent)]
+    NUT00(#[from] crate::nuts::nut00::Error),
+    /// NUT11 Error
+    #[error(transparent)]
+    NUT11(#[from] crate::nuts::nut11::Error),
     #[error("`{0}`")]
     Custom(String),
 }