mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-24 08:05:02 +01:00
fix: non sat amounts on melt (#839)
This commit is contained in:
@@ -201,6 +201,7 @@ impl MintPayment for Cln {
|
||||
Ok(PaymentQuoteResponse {
|
||||
request_lookup_id: bolt11.payment_hash().to_string(),
|
||||
amount,
|
||||
unit: unit.clone(),
|
||||
fee: fee.into(),
|
||||
state: MeltQuoteState::Unpaid,
|
||||
})
|
||||
|
||||
@@ -155,6 +155,8 @@ pub struct PaymentQuoteResponse {
|
||||
pub amount: Amount,
|
||||
/// Fee required for melt
|
||||
pub fee: Amount,
|
||||
/// Currency unit of `amount` and `fee`
|
||||
pub unit: CurrencyUnit,
|
||||
/// Status
|
||||
pub state: MeltQuoteState,
|
||||
}
|
||||
|
||||
@@ -23,3 +23,4 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
lightning-invoice.workspace = true
|
||||
tokio-stream.workspace = true
|
||||
reqwest.workspace = true
|
||||
|
||||
@@ -29,6 +29,7 @@ use error::Error;
|
||||
use futures::stream::StreamExt;
|
||||
use futures::Stream;
|
||||
use lightning_invoice::{Bolt11Invoice, Currency, InvoiceBuilder, PaymentSecret};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use tokio::sync::Mutex;
|
||||
@@ -150,7 +151,27 @@ impl MintPayment for FakeWallet {
|
||||
.into(),
|
||||
};
|
||||
|
||||
let amount = to_unit(amount_msat, &CurrencyUnit::Msat, unit)?;
|
||||
let amount = if unit != &CurrencyUnit::Sat && unit != &CurrencyUnit::Msat {
|
||||
let client = Client::new();
|
||||
|
||||
let response: Value = client
|
||||
.get("https://mempool.space/api/v1/prices")
|
||||
.send()
|
||||
.await
|
||||
.map_err(|_| Error::UnknownInvoice)?
|
||||
.json()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let price = response.get(unit.to_string().to_uppercase()).unwrap();
|
||||
|
||||
let bitcoin_amount = u64::from(amount_msat) as f64 / 100_000_000_000.0;
|
||||
let total_price = price.as_f64().unwrap() * bitcoin_amount;
|
||||
|
||||
Amount::from((total_price * 100.0).ceil() as u64)
|
||||
} else {
|
||||
to_unit(amount_msat, &CurrencyUnit::Msat, unit)?
|
||||
};
|
||||
|
||||
let relative_fee_reserve =
|
||||
(self.fee_reserve.percent_fee_reserve * u64::from(amount) as f32) as u64;
|
||||
@@ -163,6 +184,7 @@ impl MintPayment for FakeWallet {
|
||||
request_lookup_id: bolt11.payment_hash().to_string(),
|
||||
amount,
|
||||
fee: fee.into(),
|
||||
unit: unit.clone(),
|
||||
state: MeltQuoteState::Unpaid,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ impl MintPayment for LNbits {
|
||||
Ok(PaymentQuoteResponse {
|
||||
request_lookup_id: bolt11.payment_hash().to_string(),
|
||||
amount,
|
||||
unit: unit.clone(),
|
||||
fee: fee.into(),
|
||||
state: MeltQuoteState::Unpaid,
|
||||
})
|
||||
|
||||
@@ -231,6 +231,7 @@ impl MintPayment for Lnd {
|
||||
Ok(PaymentQuoteResponse {
|
||||
request_lookup_id: bolt11.payment_hash().to_string(),
|
||||
amount,
|
||||
unit: unit.clone(),
|
||||
fee: fee.into(),
|
||||
state: MeltQuoteState::Unpaid,
|
||||
})
|
||||
|
||||
@@ -79,6 +79,7 @@ impl From<cdk_common::payment::PaymentQuoteResponse> for PaymentQuoteResponse {
|
||||
amount: value.amount.into(),
|
||||
fee: value.fee.into(),
|
||||
state: QuoteState::from(value.state).into(),
|
||||
unit: value.unit.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +122,7 @@ impl From<PaymentQuoteResponse> for cdk_common::payment::PaymentQuoteResponse {
|
||||
Self {
|
||||
request_lookup_id: value.request_lookup_id.clone(),
|
||||
amount: value.amount.into(),
|
||||
unit: CurrencyUnit::from_str(&value.unit).unwrap_or_default(),
|
||||
fee: value.fee.into(),
|
||||
state: value.state().into(),
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ message PaymentQuoteResponse {
|
||||
uint64 amount = 2;
|
||||
uint64 fee = 3;
|
||||
QuoteState state = 4;
|
||||
string unit = 5;
|
||||
}
|
||||
|
||||
message MeltQuote {
|
||||
|
||||
@@ -108,19 +108,6 @@ impl Mint {
|
||||
..
|
||||
} = melt_request;
|
||||
|
||||
let amount_msats = melt_request.amount_msat()?;
|
||||
|
||||
let amount_quote_unit = to_unit(amount_msats, &CurrencyUnit::Msat, unit)?;
|
||||
|
||||
self.check_melt_request_acceptable(
|
||||
amount_quote_unit,
|
||||
unit.clone(),
|
||||
PaymentMethod::Bolt11,
|
||||
request.to_string(),
|
||||
*options,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let ln = self
|
||||
.ln
|
||||
.get(&PaymentProcessorKey::new(
|
||||
@@ -150,6 +137,15 @@ impl Mint {
|
||||
Error::UnsupportedUnit
|
||||
})?;
|
||||
|
||||
self.check_melt_request_acceptable(
|
||||
payment_quote.amount,
|
||||
unit.clone(),
|
||||
PaymentMethod::Bolt11,
|
||||
request.to_string(),
|
||||
*options,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// We only want to set the msats_to_pay of the melt quote if the invoice is amountless
|
||||
// or we want to ignore the amount and do an mpp payment
|
||||
let msats_to_pay = options.map(|opt| opt.amount_msat());
|
||||
@@ -169,7 +165,7 @@ impl Mint {
|
||||
tracing::debug!(
|
||||
"New melt quote {} for {} {} with request id {}",
|
||||
quote.id,
|
||||
amount_quote_unit,
|
||||
payment_quote.amount,
|
||||
unit,
|
||||
payment_quote.request_lookup_id
|
||||
);
|
||||
|
||||
@@ -50,20 +50,21 @@ impl Wallet {
|
||||
) -> Result<MeltQuote, Error> {
|
||||
let invoice = Bolt11Invoice::from_str(&request)?;
|
||||
|
||||
let amount_msat = options
|
||||
.map(|opt| opt.amount_msat().into())
|
||||
.or_else(|| invoice.amount_milli_satoshis())
|
||||
.ok_or(Error::InvoiceAmountUndefined)?;
|
||||
|
||||
let amount_quote_unit = to_unit(amount_msat, &CurrencyUnit::Msat, &self.unit).unwrap();
|
||||
|
||||
let quote_request = MeltQuoteBolt11Request {
|
||||
request: Bolt11Invoice::from_str(&request)?,
|
||||
unit: self.unit.clone(),
|
||||
options,
|
||||
};
|
||||
|
||||
let quote_res = self.client.post_melt_quote(quote_request).await.unwrap();
|
||||
let quote_res = self.client.post_melt_quote(quote_request).await?;
|
||||
|
||||
if self.unit == CurrencyUnit::Msat || self.unit == CurrencyUnit::Sat {
|
||||
let amount_msat = options
|
||||
.map(|opt| opt.amount_msat().into())
|
||||
.or_else(|| invoice.amount_milli_satoshis())
|
||||
.ok_or(Error::InvoiceAmountUndefined)?;
|
||||
|
||||
let amount_quote_unit = to_unit(amount_msat, &CurrencyUnit::Msat, &self.unit)?;
|
||||
|
||||
if quote_res.amount != amount_quote_unit {
|
||||
tracing::warn!(
|
||||
@@ -73,10 +74,11 @@ impl Wallet {
|
||||
);
|
||||
return Err(Error::IncorrectQuoteAmount);
|
||||
}
|
||||
}
|
||||
|
||||
let quote = MeltQuote {
|
||||
id: quote_res.quote,
|
||||
amount: amount_quote_unit,
|
||||
amount: quote_res.amount,
|
||||
request,
|
||||
unit: self.unit.clone(),
|
||||
fee_reserve: quote_res.fee_reserve,
|
||||
|
||||
Reference in New Issue
Block a user