diff --git a/crates/cdk-cln/src/lib.rs b/crates/cdk-cln/src/lib.rs index b9ed45ee..64c5f27d 100644 --- a/crates/cdk-cln/src/lib.rs +++ b/crates/cdk-cln/src/lib.rs @@ -201,12 +201,20 @@ impl MintLightning for Cln { .amount_milli_satoshis() .ok_or(Error::UnknownInvoiceAmount)?; - let amount = to_unit( + let mut amount = to_unit( invoice_amount_msat, &CurrencyUnit::Msat, &melt_quote_request.unit, )?; + if melt_quote_request.amount { + amount = to_unit( + melt_quote_request.amount, + &CurrencyUnit::Msat, + &melt_quote_request.unit, + )?; + + } let relative_fee_reserve = (self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64; diff --git a/crates/cdk-fake-wallet/src/lib.rs b/crates/cdk-fake-wallet/src/lib.rs index 9e287837..73fa9347 100644 --- a/crates/cdk-fake-wallet/src/lib.rs +++ b/crates/cdk-fake-wallet/src/lib.rs @@ -132,12 +132,19 @@ impl MintLightning for FakeWallet { .amount_milli_satoshis() .ok_or(Error::UnknownInvoiceAmount)?; - let amount = to_unit( + let mut amount = to_unit( invoice_amount_msat, &CurrencyUnit::Msat, &melt_quote_request.unit, )?; + if melt_quote_request.amount { + amount = to_unit( + melt_quote_request.amount, + &CurrencyUnit::Msat, + &melt_quote_request.unit, + )?; + let relative_fee_reserve = (self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64; diff --git a/crates/cdk-lnbits/src/lib.rs b/crates/cdk-lnbits/src/lib.rs index f983847b..8296eb1f 100644 --- a/crates/cdk-lnbits/src/lib.rs +++ b/crates/cdk-lnbits/src/lib.rs @@ -157,12 +157,19 @@ impl MintLightning for LNbits { .amount_milli_satoshis() .ok_or(Error::UnknownInvoiceAmount)?; - let amount = to_unit( + let mut amount = to_unit( invoice_amount_msat, &CurrencyUnit::Msat, &melt_quote_request.unit, )?; + if melt_quote_request.amount { + amount = to_unit( + melt_quote_request.amount, + &CurrencyUnit::Msat, + &melt_quote_request.unit, + )?; + let relative_fee_reserve = (self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64; diff --git a/crates/cdk-lnd/src/lib.rs b/crates/cdk-lnd/src/lib.rs index 96ce2f4e..17add7db 100644 --- a/crates/cdk-lnd/src/lib.rs +++ b/crates/cdk-lnd/src/lib.rs @@ -169,12 +169,19 @@ impl MintLightning for Lnd { .amount_milli_satoshis() .ok_or(Error::UnknownInvoiceAmount)?; - let amount = to_unit( + let mut amount = to_unit( invoice_amount_msat, &CurrencyUnit::Msat, &melt_quote_request.unit, )?; + if melt_quote_request.amount { + amount = to_unit( + melt_quote_request.amount, + &CurrencyUnit::Msat, + &melt_quote_request.unit, + )?; + let relative_fee_reserve = (self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64; diff --git a/crates/cdk-mintd/src/main.rs b/crates/cdk-mintd/src/main.rs index 325ddd93..a55f8174 100644 --- a/crates/cdk-mintd/src/main.rs +++ b/crates/cdk-mintd/src/main.rs @@ -148,6 +148,7 @@ async fn main() -> anyhow::Result<()> { CurrencyUnit::Sat, PaymentMethod::Bolt11, mint_melt_limits, + Some(true), cln.clone(), ); } @@ -167,6 +168,7 @@ async fn main() -> anyhow::Result<()> { unit, PaymentMethod::Bolt11, mint_melt_limits, + Some(true), Arc::new(strike), ); } @@ -181,6 +183,7 @@ async fn main() -> anyhow::Result<()> { CurrencyUnit::Sat, PaymentMethod::Bolt11, mint_melt_limits, + Some(true), Arc::new(lnbits), ); } @@ -194,6 +197,7 @@ async fn main() -> anyhow::Result<()> { CurrencyUnit::Sat, PaymentMethod::Bolt11, mint_melt_limits, + Some(true), Arc::new(phd), ); } @@ -207,6 +211,7 @@ async fn main() -> anyhow::Result<()> { CurrencyUnit::Sat, PaymentMethod::Bolt11, mint_melt_limits, + Some(true), Arc::new(lnd), ); } @@ -224,6 +229,7 @@ async fn main() -> anyhow::Result<()> { unit.clone(), PaymentMethod::Bolt11, mint_melt_limits, + Some(true), fake.clone(), ); } diff --git a/crates/cdk-phoenixd/src/lib.rs b/crates/cdk-phoenixd/src/lib.rs index 48d0912e..ab754d62 100644 --- a/crates/cdk-phoenixd/src/lib.rs +++ b/crates/cdk-phoenixd/src/lib.rs @@ -166,12 +166,19 @@ impl MintLightning for Phoenixd { .amount_milli_satoshis() .ok_or(Error::UnknownInvoiceAmount)?; - let amount = to_unit( + let mut amount = to_unit( invoice_amount_msat, &CurrencyUnit::Msat, &melt_quote_request.unit, )?; + if melt_quote_request.amount { + amount = to_unit( + melt_quote_request.amount, + &CurrencyUnit::Msat, + &melt_quote_request.unit, + )?; + let relative_fee_reserve = (self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64; diff --git a/crates/cdk-strike/src/lib.rs b/crates/cdk-strike/src/lib.rs index ddb103cb..b10afcff 100644 --- a/crates/cdk-strike/src/lib.rs +++ b/crates/cdk-strike/src/lib.rs @@ -167,9 +167,15 @@ impl MintLightning for Strike { let fee = from_strike_amount(quote.lightning_network_fee, &melt_quote_request.unit)?; + let mut amount = from_strike_amount(quote.amount, &melt_quote_request.unit)?.into()?; + + if melt_quote_request.amount { + amount = from_strike_amount(melt_quote_request.amount, &melt_quote_request.unit)?.into() + } + Ok(PaymentQuoteResponse { request_lookup_id: quote.payment_quote_id, - amount: from_strike_amount(quote.amount, &melt_quote_request.unit)?.into(), + amount, fee: fee.into(), state: MeltQuoteState::Unpaid, }) diff --git a/crates/cdk/src/error.rs b/crates/cdk/src/error.rs index dae63c64..be914821 100644 --- a/crates/cdk/src/error.rs +++ b/crates/cdk/src/error.rs @@ -45,6 +45,9 @@ pub enum Error { /// Amount overflow #[error("Amount Overflow")] AmountOverflow, + /// Amountless Invoice Not supported + #[error("Amount Less Invoice is not allowed")] + AmountLessNotAllowed, // Mint Errors /// Minting is disabled diff --git a/crates/cdk/src/mint/builder.rs b/crates/cdk/src/mint/builder.rs index a71c259c..7fd3ccc8 100644 --- a/crates/cdk/src/mint/builder.rs +++ b/crates/cdk/src/mint/builder.rs @@ -108,12 +108,14 @@ impl MintBuilder { unit: CurrencyUnit, method: PaymentMethod, limits: MintMeltLimits, + support_amountless: Option, ln_backend: Arc + Send + Sync>, ) -> Self { let ln_key = LnKey { unit: unit.clone(), method, }; + let support_amountless = support_amountless.unwrap_or(false); let mut ln = self.ln.unwrap_or_default(); @@ -150,6 +152,7 @@ impl MintBuilder { unit, min_amount: Some(limits.melt_min), max_amount: Some(limits.melt_max), + amountless: Some(support_amountless), }; self.mint_info.nuts.nut05.methods.push(melt_method_settings); self.mint_info.nuts.nut05.disabled = false; diff --git a/crates/cdk/src/mint/melt.rs b/crates/cdk/src/mint/melt.rs index 8ac01d69..21dc1f80 100644 --- a/crates/cdk/src/mint/melt.rs +++ b/crates/cdk/src/mint/melt.rs @@ -36,6 +36,9 @@ impl Mint { .get_settings(&unit, &method) .ok_or(Error::UnitUnsupported)?; + if !settings.amountless.unwrap_or_default() { + return Err(Error::AmountLessNotAllowed); + } let is_above_max = matches!(settings.max_amount, Some(max) if amount > max); let is_below_min = matches!(settings.min_amount, Some(min) if amount < min); match is_above_max || is_below_min { @@ -58,6 +61,7 @@ impl Mint { request, unit, options: _, + .. } = melt_request; let amount = match melt_request.options { @@ -93,6 +97,7 @@ impl Mint { Error::UnitUnsupported })?; + let quote = MeltQuote::new( request.to_string(), unit.clone(), diff --git a/crates/cdk/src/nuts/nut05.rs b/crates/cdk/src/nuts/nut05.rs index df9064ef..df9fe4bd 100644 --- a/crates/cdk/src/nuts/nut05.rs +++ b/crates/cdk/src/nuts/nut05.rs @@ -36,6 +36,8 @@ pub struct MeltQuoteBolt11Request { pub request: Bolt11Invoice, /// Unit wallet would like to pay with pub unit: CurrencyUnit, + /// amount for paying amountless bolt11 invoice + pub amount: Option, /// Payment Options pub options: Option, } @@ -264,6 +266,8 @@ pub struct MeltMethodSettings { /// Max Amount #[serde(skip_serializing_if = "Option::is_none")] pub max_amount: Option, + /// Amountless + pub amountless: Option, } impl Settings { @@ -288,6 +292,9 @@ impl Settings { } } +/// meting with an amount_less invoice +// pub amount_less: Option, + /// Melt Settings #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema), schema(as = nut05::Settings))] @@ -305,6 +312,7 @@ impl Default for Settings { unit: CurrencyUnit::Sat, min_amount: Some(Amount::from(1)), max_amount: Some(Amount::from(1000000)), + amountless: Some(false), }; Settings { diff --git a/crates/cdk/src/wallet/melt.rs b/crates/cdk/src/wallet/melt.rs index e8a0a0b5..36fe6e11 100644 --- a/crates/cdk/src/wallet/melt.rs +++ b/crates/cdk/src/wallet/melt.rs @@ -63,6 +63,7 @@ impl Wallet { request: Bolt11Invoice::from_str(&request)?, unit: self.unit.clone(), options, + amount: Some(amount), }; let quote_res = self