Browse Source

Merge pull request #629 from ok300/ok300-ensure-cdk

Add `ensure_cdk` macro for validation checks
thesimplekid 1 month ago
parent
commit
a394145fba

+ 10 - 0
crates/cashu/src/lib.rs

@@ -15,3 +15,13 @@ pub use lightning_invoice::{self, Bolt11Invoice};
 pub use self::amount::Amount;
 pub use self::nuts::*;
 pub use self::util::SECP256K1;
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! ensure_cdk {
+    ($cond:expr, $err:expr) => {
+        if !$cond {
+            return Err($err);
+        }
+    };
+}

+ 4 - 3
crates/cashu/src/mint_url.rs

@@ -10,6 +10,8 @@ use serde::{Deserialize, Serialize};
 use thiserror::Error;
 use url::{ParseError, Url};
 
+use crate::ensure_cdk;
+
 /// Url Error
 #[derive(Debug, Error, PartialEq, Eq)]
 pub enum Error {
@@ -27,9 +29,8 @@ pub struct MintUrl(String);
 
 impl MintUrl {
     fn format_url(url: &str) -> Result<String, Error> {
-        if url.is_empty() {
-            return Err(Error::InvalidUrl);
-        }
+        ensure_cdk!(!url.is_empty(), Error::InvalidUrl);
+
         let url = url.trim_end_matches('/');
         // https://URL.com/path/TO/resource -> https://url.com/path/TO/resource
         let protocol = url

+ 10 - 24
crates/cashu/src/nuts/nut00/token.rs

@@ -14,7 +14,7 @@ use super::{Error, Proof, ProofV4, Proofs};
 use crate::mint_url::MintUrl;
 use crate::nuts::nut00::ProofsMethods;
 use crate::nuts::{CurrencyUnit, Id};
-use crate::Amount;
+use crate::{ensure_cdk, Amount};
 
 /// Token Enum
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@@ -103,11 +103,9 @@ impl Token {
             Self::TokenV3(token) => {
                 let mint_urls = token.mint_urls();
 
-                if mint_urls.len() != 1 {
-                    return Err(Error::UnsupportedToken);
-                }
+                ensure_cdk!(mint_urls.len() == 1, Error::UnsupportedToken);
 
-                Ok(mint_urls.first().expect("Length is checked above").clone())
+                mint_urls.first().ok_or(Error::UnsupportedToken).cloned()
             }
             Self::TokenV4(token) => Ok(token.mint_url.clone()),
         }
@@ -164,9 +162,7 @@ impl TryFrom<&Vec<u8>> for Token {
     type Error = Error;
 
     fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
-        if bytes.len() < 5 {
-            return Err(Error::UnsupportedToken);
-        }
+        ensure_cdk!(bytes.len() >= 5, Error::UnsupportedToken);
 
         let prefix = String::from_utf8(bytes[..5].to_vec())?;
 
@@ -220,9 +216,7 @@ impl TokenV3 {
         memo: Option<String>,
         unit: Option<CurrencyUnit>,
     ) -> Result<Self, Error> {
-        if proofs.is_empty() {
-            return Err(Error::ProofsRequired);
-        }
+        ensure_cdk!(!proofs.is_empty(), Error::ProofsRequired);
 
         Ok(Self {
             token: vec![TokenV3Token::new(mint_url, proofs)],
@@ -400,18 +394,12 @@ impl TryFrom<&Vec<u8>> for TokenV4 {
     type Error = Error;
 
     fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
-        if bytes.len() < 5 {
-            return Err(Error::UnsupportedToken);
-        }
+        ensure_cdk!(bytes.len() >= 5, Error::UnsupportedToken);
 
         let prefix = String::from_utf8(bytes[..5].to_vec())?;
+        ensure_cdk!(prefix.as_str() == "crawB", Error::UnsupportedToken);
 
-        if prefix.as_str() == "crawB" {
-            let token: TokenV4 = ciborium::from_reader(&bytes[5..])?;
-            Ok(token)
-        } else {
-            Err(Error::UnsupportedToken)
-        }
+        Ok(ciborium::from_reader(&bytes[5..])?)
     }
 }
 
@@ -421,11 +409,9 @@ impl TryFrom<TokenV3> for TokenV4 {
         let proofs = token.proofs();
         let mint_urls = token.mint_urls();
 
-        if mint_urls.len() != 1 {
-            return Err(Error::UnsupportedToken);
-        }
+        ensure_cdk!(mint_urls.len() == 1, Error::UnsupportedToken);
 
-        let mint_url = mint_urls.first().expect("Len is checked");
+        let mint_url = mint_urls.first().ok_or(Error::UnsupportedToken)?;
 
         let proofs = proofs
             .iter()

+ 3 - 7
crates/cashu/src/nuts/nut02.rs

@@ -25,7 +25,7 @@ use super::nut01::Keys;
 use super::nut01::{MintKeyPair, MintKeys};
 use crate::nuts::nut00::CurrencyUnit;
 use crate::util::hex;
-use crate::Amount;
+use crate::{ensure_cdk, Amount};
 
 /// NUT02 Error
 #[derive(Debug, Error)]
@@ -144,9 +144,7 @@ impl TryFrom<String> for Id {
     type Error = Error;
 
     fn try_from(s: String) -> Result<Self, Self::Error> {
-        if s.len() != 16 {
-            return Err(Error::Length);
-        }
+        ensure_cdk!(s.len() == 16, Error::Length);
 
         Ok(Self {
             version: KeySetVersion::from_byte(&hex::decode(&s[..2])?[0])?,
@@ -230,9 +228,7 @@ impl KeySet {
     pub fn verify_id(&self) -> Result<(), Error> {
         let keys_id: Id = (&self.keys).into();
 
-        if keys_id != self.id {
-            return Err(Error::IncorrectKeysetId);
-        }
+        ensure_cdk!(keys_id == self.id, Error::IncorrectKeysetId);
 
         Ok(())
     }

+ 3 - 7
crates/cashu/src/nuts/nut11/mod.rs

@@ -17,6 +17,7 @@ use thiserror::Error;
 use super::nut00::Witness;
 use super::nut01::PublicKey;
 use super::{Kind, Nut10Secret, Proof, Proofs, SecretKey};
+use crate::ensure_cdk;
 use crate::nuts::nut00::BlindedMessage;
 use crate::secret::Secret;
 use crate::util::{hex, unix_time};
@@ -422,9 +423,7 @@ impl Conditions {
         sig_flag: Option<SigFlag>,
     ) -> Result<Self, Error> {
         if let Some(locktime) = locktime {
-            if locktime.lt(&unix_time()) {
-                return Err(Error::LocktimeInPast);
-            }
+            ensure_cdk!(locktime.ge(&unix_time()), Error::LocktimeInPast);
         }
 
         Ok(Self {
@@ -704,10 +703,7 @@ where
     type Error = Error;
 
     fn try_from(tag: Vec<S>) -> Result<Self, Self::Error> {
-        let tag_kind: TagKind = match tag.first() {
-            Some(kind) => TagKind::from(kind),
-            None => return Err(Error::KindNotFound),
-        };
+        let tag_kind = tag.first().map(TagKind::from).ok_or(Error::KindNotFound)?;
 
         match tag_kind {
             TagKind::SigFlag => Ok(Tag::SigFlag(SigFlag::from_str(tag[1].as_ref())?)),

+ 3 - 3
crates/cashu/src/nuts/nut14/mod.rs

@@ -14,6 +14,7 @@ use super::nut00::Witness;
 use super::nut10::Secret;
 use super::nut11::valid_signatures;
 use super::{Conditions, Proof};
+use crate::ensure_cdk;
 use crate::util::unix_time;
 
 pub mod serde_htlc_witness;
@@ -112,9 +113,8 @@ impl Proof {
                     .map(|s| Signature::from_str(s))
                     .collect::<Result<Vec<Signature>, _>>()?;
 
-                if valid_signatures(self.secret.as_bytes(), &pubkey, &signatures).lt(&req_sigs) {
-                    return Err(Error::IncorrectSecretKind);
-                }
+                let valid_sigs = valid_signatures(self.secret.as_bytes(), &pubkey, &signatures);
+                ensure_cdk!(valid_sigs >= req_sigs, Error::IncorrectSecretKind);
             }
         }
 

+ 3 - 3
crates/cashu/src/util/hex.rs

@@ -5,6 +5,8 @@
 
 use core::fmt;
 
+use crate::ensure_cdk;
+
 /// Hex error
 #[derive(Debug, PartialEq, Eq)]
 pub enum Error {
@@ -76,9 +78,7 @@ where
     let hex = hex.as_ref();
     let len = hex.len();
 
-    if len % 2 != 0 {
-        return Err(Error::OddLength);
-    }
+    ensure_cdk!(len % 2 == 0, Error::OddLength);
 
     let mut bytes: Vec<u8> = Vec::with_capacity(len / 2);
 

+ 1 - 1
crates/cdk-common/src/lib.rs

@@ -24,4 +24,4 @@ pub use cashu::mint;
 pub use cashu::nuts::{self, *};
 #[cfg(feature = "wallet")]
 pub use cashu::wallet;
-pub use cashu::{dhke, mint_url, secret, util, SECP256K1};
+pub use cashu::{dhke, ensure_cdk, mint_url, secret, util, SECP256K1};

+ 2 - 4
crates/cdk-fake-wallet/src/lib.rs

@@ -19,10 +19,10 @@ use cdk::amount::{Amount, MSAT_IN_SAT};
 use cdk::cdk_lightning::{
     self, CreateInvoiceResponse, MintLightning, PayInvoiceResponse, PaymentQuoteResponse, Settings,
 };
-use cdk::mint;
 use cdk::mint::FeeReserve;
 use cdk::nuts::{CurrencyUnit, MeltQuoteBolt11Request, MeltQuoteState, MintQuoteState};
 use cdk::util::unix_time;
+use cdk::{ensure_cdk, mint};
 use error::Error;
 use futures::stream::StreamExt;
 use futures::Stream;
@@ -182,9 +182,7 @@ impl MintLightning for FakeWallet {
                 fail.insert(payment_hash.clone());
             }
 
-            if description.pay_err {
-                return Err(Error::UnknownInvoice.into());
-            }
+            ensure_cdk!(!description.pay_err, Error::UnknownInvoice.into());
         }
 
         Ok(PayInvoiceResponse {

+ 1 - 1
crates/cdk/src/lib.rs

@@ -22,7 +22,7 @@ pub mod pub_sub;
 /// Re-export amount type
 #[doc(hidden)]
 pub use cdk_common::{
-    amount, common as types, dhke,
+    amount, common as types, dhke, ensure_cdk,
     error::{self, Error},
     lightning_invoice, mint_url, nuts, secret, util, ws, Amount, Bolt11Invoice,
 };

+ 4 - 10
crates/cdk/src/mint/melt.rs

@@ -19,7 +19,7 @@ use crate::nuts::nut11::{enforce_sig_flag, EnforceSigFlag};
 use crate::nuts::MeltQuoteState;
 use crate::types::LnKey;
 use crate::util::unix_time;
-use crate::{cdk_lightning, Amount, Error};
+use crate::{cdk_lightning, ensure_cdk, Amount, Error};
 
 impl Mint {
     #[instrument(skip_all)]
@@ -35,9 +35,7 @@ impl Mint {
         let nut05 = mint_info.nuts.nut05;
         let nut15 = mint_info.nuts.nut15;
 
-        if nut05.disabled {
-            return Err(Error::MeltingDisabled);
-        }
+        ensure_cdk!(!nut05.disabled, Error::MeltingDisabled);
 
         let settings = nut05
             .get_settings(&unit, &method)
@@ -330,9 +328,7 @@ impl Mint {
 
         let EnforceSigFlag { sig_flag, .. } = enforce_sig_flag(melt_request.inputs.clone());
 
-        if sig_flag.eq(&SigFlag::SigAll) {
-            return Err(Error::SigAllUsedInMelt);
-        }
+        ensure_cdk!(sig_flag.ne(&SigFlag::SigAll), Error::SigAllUsedInMelt);
 
         if let Some(outputs) = &melt_request.outputs {
             let Verification {
@@ -340,9 +336,7 @@ impl Mint {
                 unit: output_unit,
             } = self.verify_outputs(outputs).await?;
 
-            if input_unit != output_unit {
-                return Err(Error::UnsupportedUnit);
-            }
+            ensure_cdk!(input_unit == output_unit, Error::UnsupportedUnit);
         }
 
         tracing::debug!("Verified melt quote: {}", melt_request.quote);

+ 29 - 42
crates/cdk/src/mint/mint_nut04.rs

@@ -9,7 +9,7 @@ use super::{
 use crate::nuts::MintQuoteState;
 use crate::types::LnKey;
 use crate::util::unix_time;
-use crate::{Amount, Error};
+use crate::{ensure_cdk, Amount, Error};
 
 impl Mint {
     /// Checks that minting is enabled, request is supported unit and within range
@@ -21,38 +21,28 @@ impl Mint {
         let mint_info = self.localstore.get_mint_info().await?;
         let nut04 = &mint_info.nuts.nut04;
 
-        if nut04.disabled {
-            return Err(Error::MintingDisabled);
-        }
-
-        match nut04.get_settings(unit, &PaymentMethod::Bolt11) {
-            Some(settings) => {
-                if settings
-                    .max_amount
-                    .map_or(false, |max_amount| amount > max_amount)
-                {
-                    return Err(Error::AmountOutofLimitRange(
-                        settings.min_amount.unwrap_or_default(),
-                        settings.max_amount.unwrap_or_default(),
-                        amount,
-                    ));
-                }
-
-                if settings
-                    .min_amount
-                    .map_or(false, |min_amount| amount < min_amount)
-                {
-                    return Err(Error::AmountOutofLimitRange(
-                        settings.min_amount.unwrap_or_default(),
-                        settings.max_amount.unwrap_or_default(),
-                        amount,
-                    ));
-                }
-            }
-            None => {
-                return Err(Error::UnsupportedUnit);
-            }
-        }
+        ensure_cdk!(!nut04.disabled, Error::MintingDisabled);
+
+        let settings = nut04
+            .get_settings(unit, &PaymentMethod::Bolt11)
+            .ok_or(Error::UnsupportedUnit)?;
+
+        let is_above_max = settings
+            .max_amount
+            .map_or(false, |max_amount| amount > max_amount);
+        let is_below_min = settings
+            .min_amount
+            .map_or(false, |min_amount| amount < min_amount);
+        let is_out_of_range = is_above_max || is_below_min;
+
+        ensure_cdk!(
+            !is_out_of_range,
+            Error::AmountOutofLimitRange(
+                settings.min_amount.unwrap_or_default(),
+                settings.max_amount.unwrap_or_default(),
+                amount,
+            )
+        );
 
         Ok(())
     }
@@ -263,12 +253,11 @@ impl Mint {
         &self,
         mint_request: nut04::MintBolt11Request<Uuid>,
     ) -> Result<nut04::MintBolt11Response, Error> {
-        let mint_quote =
-            if let Some(mint_quote) = self.localstore.get_mint_quote(&mint_request.quote).await? {
-                mint_quote
-            } else {
-                return Err(Error::UnknownQuote);
-            };
+        let mint_quote = self
+            .localstore
+            .get_mint_quote(&mint_request.quote)
+            .await?
+            .ok_or(Error::UnknownQuote)?;
 
         let state = self
             .localstore
@@ -329,9 +318,7 @@ impl Mint {
             ));
         }
 
-        if unit != mint_quote.unit {
-            return Err(Error::UnsupportedUnit);
-        }
+        ensure_cdk!(unit == mint_quote.unit, Error::UnsupportedUnit);
 
         let mut blind_signatures = Vec::with_capacity(mint_request.outputs.len());
 

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

@@ -22,7 +22,7 @@ use crate::error::Error;
 use crate::fees::calculate_fee;
 use crate::nuts::*;
 use crate::util::unix_time;
-use crate::Amount;
+use crate::{ensure_cdk, Amount};
 
 mod builder;
 mod check_spendable;
@@ -240,24 +240,17 @@ impl Mint {
             .await?
             .ok_or(Error::UnknownKeySet)?;
 
-        let active = self
+        // Check that the keyset is active and should be used to sign
+        let active_id = self
             .localstore
             .get_active_keyset_id(&keyset_info.unit)
             .await?
             .ok_or(Error::InactiveKeyset)?;
-
-        // Check that the keyset is active and should be used to sign
-        if keyset_info.id.ne(&active) {
-            return Err(Error::InactiveKeyset);
-        }
+        ensure_cdk!(keyset_info.id.eq(&active_id), Error::InactiveKeyset);
 
         let keysets = self.keysets.read().await;
         let keyset = keysets.get(keyset_id).ok_or(Error::UnknownKeySet)?;
-
-        let key_pair = match keyset.keys.get(amount) {
-            Some(key_pair) => key_pair,
-            None => return Err(Error::AmountKey),
-        };
+        let key_pair = keyset.keys.get(amount).ok_or(Error::AmountKey)?;
 
         let c = sign_message(&key_pair.secret_key, blinded_secret)?;
 
@@ -298,11 +291,7 @@ impl Mint {
         self.ensure_keyset_loaded(&proof.keyset_id).await?;
         let keysets = self.keysets.read().await;
         let keyset = keysets.get(&proof.keyset_id).ok_or(Error::UnknownKeySet)?;
-
-        let keypair = match keyset.keys.get(&proof.amount) {
-            Some(key_pair) => key_pair,
-            None => return Err(Error::AmountKey),
-        };
+        let keypair = keyset.keys.get(&proof.amount).ok_or(Error::AmountKey)?;
 
         verify_message(&keypair.secret_key, proof.c, proof.secret.as_bytes())?;
 

+ 19 - 20
crates/cdk/src/wallet/melt.rs

@@ -12,7 +12,7 @@ use crate::nuts::{
 };
 use crate::types::{Melted, ProofInfo};
 use crate::util::unix_time;
-use crate::{Error, Wallet};
+use crate::{ensure_cdk, Error, Wallet};
 
 impl Wallet {
     /// Melt Quote
@@ -113,16 +113,16 @@ impl Wallet {
     /// Melt specific proofs
     #[instrument(skip(self, proofs))]
     pub async fn melt_proofs(&self, quote_id: &str, proofs: Proofs) -> Result<Melted, Error> {
-        let quote_info = self.localstore.get_melt_quote(quote_id).await?;
-        let quote_info = if let Some(quote) = quote_info {
-            if quote.expiry.le(&unix_time()) {
-                return Err(Error::ExpiredQuote(quote.expiry, unix_time()));
-            }
+        let quote_info = self
+            .localstore
+            .get_melt_quote(quote_id)
+            .await?
+            .ok_or(Error::UnknownQuote)?;
 
-            quote.clone()
-        } else {
-            return Err(Error::UnknownQuote);
-        };
+        ensure_cdk!(
+            quote_info.expiry.gt(&unix_time()),
+            Error::ExpiredQuote(quote_info.expiry, unix_time())
+        );
 
         let proofs_total = proofs.total_amount()?;
         if proofs_total < quote_info.amount + quote_info.fee_reserve {
@@ -272,17 +272,16 @@ impl Wallet {
     /// }
     #[instrument(skip(self))]
     pub async fn melt(&self, quote_id: &str) -> Result<Melted, Error> {
-        let quote_info = self.localstore.get_melt_quote(quote_id).await?;
-
-        let quote_info = if let Some(quote) = quote_info {
-            if quote.expiry.le(&unix_time()) {
-                return Err(Error::ExpiredQuote(quote.expiry, unix_time()));
-            }
+        let quote_info = self
+            .localstore
+            .get_melt_quote(quote_id)
+            .await?
+            .ok_or(Error::UnknownQuote)?;
 
-            quote.clone()
-        } else {
-            return Err(Error::UnknownQuote);
-        };
+        ensure_cdk!(
+            quote_info.expiry.gt(&unix_time()),
+            Error::ExpiredQuote(quote_info.expiry, unix_time())
+        );
 
         let inputs_needed_amount = quote_info.amount + quote_info.fee_reserve;
 

+ 13 - 14
crates/cdk/src/wallet/mint.rs

@@ -1,3 +1,4 @@
+use cdk_common::ensure_cdk;
 use tracing::instrument;
 
 use super::MintQuote;
@@ -50,7 +51,7 @@ impl Wallet {
 
         // If we have a description, we check that the mint supports it.
         if description.is_some() {
-            let mint_method_settings = self
+            let settings = self
                 .localstore
                 .get_mint(mint_url.clone())
                 .await?
@@ -60,9 +61,7 @@ impl Wallet {
                 .get_settings(&unit, &crate::nuts::PaymentMethod::Bolt11)
                 .ok_or(Error::UnsupportedUnit)?;
 
-            if !mint_method_settings.description {
-                return Err(Error::InvoiceDescriptionUnsupported);
-            }
+            ensure_cdk!(settings.description, Error::InvoiceDescriptionUnsupported);
         }
 
         let secret_key = SecretKey::generate();
@@ -186,17 +185,17 @@ impl Wallet {
             self.get_mint_info().await?;
         }
 
-        let quote_info = self.localstore.get_mint_quote(quote_id).await?;
-
-        let quote_info = if let Some(quote) = quote_info {
-            if quote.expiry.le(&unix_time()) && quote.expiry.ne(&0) {
-                return Err(Error::ExpiredQuote(quote.expiry, unix_time()));
-            }
+        let quote_info = self
+            .localstore
+            .get_mint_quote(quote_id)
+            .await?
+            .ok_or(Error::UnknownQuote)?;
 
-            quote.clone()
-        } else {
-            return Err(Error::UnknownQuote);
-        };
+        let unix_time = unix_time();
+        ensure_cdk!(
+            quote_info.expiry > unix_time || quote_info.expiry == 0,
+            Error::ExpiredQuote(quote_info.expiry, unix_time)
+        );
 
         let active_keyset_id = self.get_active_mint_keyset().await?.id;
 

+ 2 - 4
crates/cdk/src/wallet/multi_mint_wallet.rs

@@ -18,7 +18,7 @@ use crate::mint_url::MintUrl;
 use crate::nuts::{CurrencyUnit, MeltOptions, Proof, Proofs, SecretKey, SpendingConditions, Token};
 use crate::types::Melted;
 use crate::wallet::types::MintQuote;
-use crate::{Amount, Wallet};
+use crate::{ensure_cdk, Amount, Wallet};
 
 /// Multi Mint Wallet
 #[derive(Debug, Clone)]
@@ -271,9 +271,7 @@ impl MultiMintWallet {
 
         let quote = wallet.melt_quote(bolt11.to_string(), options).await?;
         if let Some(max_fee) = max_fee {
-            if quote.fee_reserve > max_fee {
-                return Err(Error::MaxFeeExceeded);
-            }
+            ensure_cdk!(quote.fee_reserve <= max_fee, Error::MaxFeeExceeded);
         }
 
         wallet.melt(&quote.id).await

+ 2 - 4
crates/cdk/src/wallet/proofs.rs

@@ -8,7 +8,7 @@ use crate::nuts::{
     CheckStateRequest, Proof, ProofState, Proofs, PublicKey, SpendingConditions, State,
 };
 use crate::types::ProofInfo;
-use crate::{Amount, Error, Wallet};
+use crate::{ensure_cdk, Amount, Error, Wallet};
 
 impl Wallet {
     /// Get unspent proofs for mint
@@ -166,9 +166,7 @@ impl Wallet {
             amount,
             proofs.total_amount()?
         );
-        if proofs.total_amount()? < amount {
-            return Err(Error::InsufficientFunds);
-        }
+        ensure_cdk!(proofs.total_amount()? >= amount, Error::InsufficientFunds);
 
         let (mut proofs_larger, mut proofs_smaller): (Proofs, Proofs) =
             proofs.into_iter().partition(|p| p.amount > amount);

+ 4 - 10
crates/cdk/src/wallet/receive.rs

@@ -13,7 +13,7 @@ use crate::nuts::nut10::Kind;
 use crate::nuts::{Conditions, Proofs, PublicKey, SecretKey, SigFlag, State, Token};
 use crate::types::ProofInfo;
 use crate::util::hex;
-use crate::{Amount, Error, Wallet, SECP256K1};
+use crate::{ensure_cdk, Amount, Error, Wallet, SECP256K1};
 
 impl Wallet {
     /// Receive proofs
@@ -194,21 +194,15 @@ impl Wallet {
 
         let unit = token.unit().unwrap_or_default();
 
-        if unit != self.unit {
-            return Err(Error::UnsupportedUnit);
-        }
+        ensure_cdk!(unit == self.unit, Error::UnsupportedUnit);
 
         let proofs = token.proofs();
 
         if let Token::TokenV3(token) = &token {
-            if token.is_multi_mint() {
-                return Err(Error::MultiMintTokenNotSupported);
-            }
+            ensure_cdk!(!token.is_multi_mint(), Error::MultiMintTokenNotSupported);
         }
 
-        if self.mint_url != token.mint_url()? {
-            return Err(Error::IncorrectMint);
-        }
+        ensure_cdk!(self.mint_url == token.mint_url()?, Error::IncorrectMint);
 
         let amount = self
             .receive_proofs(proofs, amount_split_target, p2pk_signing_keys, preimages)

+ 2 - 4
crates/cdk/src/wallet/swap.rs

@@ -7,7 +7,7 @@ use crate::nuts::{
     nut10, PreMintSecrets, PreSwap, Proofs, PublicKey, SpendingConditions, State, SwapRequest,
 };
 use crate::types::ProofInfo;
-use crate::{Amount, Error, Wallet};
+use crate::{ensure_cdk, Amount, Error, Wallet};
 
 impl Wallet {
     /// Swap
@@ -161,9 +161,7 @@ impl Wallet {
             },
         );
 
-        if proofs_sum < amount {
-            return Err(Error::InsufficientFunds);
-        }
+        ensure_cdk!(proofs_sum >= amount, Error::InsufficientFunds);
 
         let proofs = self.select_proofs_to_swap(amount, available_proofs).await?;