refactor: remove mint and wallet error mods

This commit is contained in:
thesimplekid
2024-04-12 20:47:07 +01:00
parent 27f718de08
commit ce207953a1
10 changed files with 168 additions and 182 deletions

View File

@@ -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)]

View File

@@ -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),
}

View File

@@ -1,3 +1,5 @@
//! Errors
use std::string::FromUtf8Error;
use serde::{Deserialize, Serialize};
@@ -5,11 +7,42 @@ use thiserror::Error;
use crate::util::hex;
pub mod mint;
pub mod wallet;
#[derive(Debug, Error)]
pub enum Error {
/// 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,
/// Secp256k1 error
#[error(transparent)]
Secp256k1(#[from] bitcoin::secp256k1::Error),
/// Secret error
#[error(transparent)]
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),
@@ -25,48 +58,15 @@ pub enum Error {
/// From hex error
#[error(transparent)]
HexError(#[from] hex::Error),
/// Secp256k1 error
#[error(transparent)]
Secp256k1(#[from] bitcoin::secp256k1::Error),
#[error("No Key for Amoun")]
AmountKey,
#[error("Amount miss match")]
Amount,
#[error("Token already spent")]
TokenSpent,
#[error("Token not verified")]
TokenNotVerifed,
#[error("Invoice Amount undefined")]
InvoiceAmountUndefined,
#[error("Proof missing required field")]
MissingProofField,
#[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),
/// Nut01 error
#[error(transparent)]
NUT01(#[from] crate::nuts::nut01::Error),
/// NUT02 error
#[error(transparent)]
NUT02(#[from] crate::nuts::nut02::Error),
#[cfg(feature = "nut13")]
/// NUT11 Error
#[error(transparent)]
Bip32(#[from] bitcoin::bip32::Error),
#[error(transparent)]
ParseInt(#[from] std::num::ParseIntError),
NUT11(#[from] crate::nuts::nut11::Error),
/// Custom error
#[error("`{0}`")]
CustomError(String),

View File

@@ -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
}
}

View File

@@ -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),

View File

@@ -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,

View File

@@ -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()

View File

@@ -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)
}
}

View File

@@ -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 {

View File

@@ -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),
}