mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-24 08:05:02 +01:00
Wallet: Check Pending Melt Quotes (#895)
* Add transaction for pending melt * Check pending melt quotes * Fix imports
This commit is contained in:
@@ -69,6 +69,8 @@ pub trait Database: Debug {
|
||||
async fn add_melt_quote(&self, quote: wallet::MeltQuote) -> Result<(), Self::Err>;
|
||||
/// Get melt quote from storage
|
||||
async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<wallet::MeltQuote>, Self::Err>;
|
||||
/// Get melt quotes from storage
|
||||
async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Self::Err>;
|
||||
/// Remove melt quote from storage
|
||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err>;
|
||||
|
||||
|
||||
@@ -477,6 +477,21 @@ impl WalletDatabase for WalletRedbDatabase {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Self::Err> {
|
||||
let read_txn = self.db.begin_read().map_err(Error::from)?;
|
||||
let table = read_txn
|
||||
.open_table(MELT_QUOTES_TABLE)
|
||||
.map_err(Error::from)?;
|
||||
|
||||
Ok(table
|
||||
.iter()
|
||||
.map_err(Error::from)?
|
||||
.flatten()
|
||||
.flat_map(|(_id, quote)| serde_json::from_str(quote.value()))
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
||||
let write_txn = self.db.begin_write().map_err(Error::from)?;
|
||||
|
||||
@@ -530,6 +530,30 @@ ON CONFLICT(id) DO UPDATE SET
|
||||
.transpose()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
async fn get_melt_quotes(&self) -> Result<Vec<wallet::MeltQuote>, Self::Err> {
|
||||
Ok(Statement::new(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
unit,
|
||||
amount,
|
||||
request,
|
||||
fee_reserve,
|
||||
state,
|
||||
expiry,
|
||||
payment_preimage
|
||||
FROM
|
||||
melt_quote
|
||||
"#,
|
||||
)
|
||||
.fetch_all(&self.pool.get().map_err(Error::Pool)?)
|
||||
.map_err(Error::Sqlite)?
|
||||
.into_iter()
|
||||
.map(sqlite_row_to_melt_quote)
|
||||
.collect::<Result<_, _>>()?)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
||||
Statement::new(r#"DELETE FROM melt_quote WHERE id=:id"#)
|
||||
|
||||
@@ -104,6 +104,13 @@ impl Wallet {
|
||||
Some(quote) => {
|
||||
let mut quote = quote;
|
||||
|
||||
if let Err(e) = self
|
||||
.add_transaction_for_pending_melt("e, &response)
|
||||
.await
|
||||
{
|
||||
tracing::error!("Failed to add transaction for pending melt: {}", e);
|
||||
}
|
||||
|
||||
quote.state = response.state;
|
||||
self.localstore.add_melt_quote(quote).await?;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,13 @@ impl Wallet {
|
||||
Some(quote) => {
|
||||
let mut quote = quote;
|
||||
|
||||
if let Err(e) = self
|
||||
.add_transaction_for_pending_melt("e, &response)
|
||||
.await
|
||||
{
|
||||
tracing::error!("Failed to add transaction for pending melt: {}", e);
|
||||
}
|
||||
|
||||
quote.state = response.state;
|
||||
self.localstore.add_melt_quote(quote).await?;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,81 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cdk_common::util::unix_time;
|
||||
use cdk_common::wallet::{MeltQuote, Transaction, TransactionDirection};
|
||||
use cdk_common::{Error, MeltQuoteBolt11Response, MeltQuoteState, ProofsMethods};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::Wallet;
|
||||
|
||||
mod melt_bolt11;
|
||||
mod melt_bolt12;
|
||||
|
||||
impl Wallet {
|
||||
/// Check pending melt quotes
|
||||
#[instrument(skip_all)]
|
||||
pub async fn check_pending_melt_quotes(&self) -> Result<(), Error> {
|
||||
let quotes = self.get_pending_melt_quotes().await?;
|
||||
for quote in quotes {
|
||||
self.melt_quote_status("e.id).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get all active melt quotes from the wallet
|
||||
pub async fn get_active_melt_quotes(&self) -> Result<Vec<MeltQuote>, Error> {
|
||||
let quotes = self.localstore.get_melt_quotes().await?;
|
||||
Ok(quotes
|
||||
.into_iter()
|
||||
.filter(|q| {
|
||||
q.state == MeltQuoteState::Pending
|
||||
|| (q.state == MeltQuoteState::Unpaid && q.expiry > unix_time())
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Get pending melt quotes
|
||||
pub async fn get_pending_melt_quotes(&self) -> Result<Vec<MeltQuote>, Error> {
|
||||
let quotes = self.localstore.get_melt_quotes().await?;
|
||||
Ok(quotes
|
||||
.into_iter()
|
||||
.filter(|q| q.state == MeltQuoteState::Pending)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub(crate) async fn add_transaction_for_pending_melt(
|
||||
&self,
|
||||
quote: &MeltQuote,
|
||||
response: &MeltQuoteBolt11Response<String>,
|
||||
) -> Result<(), Error> {
|
||||
if quote.state != response.state {
|
||||
tracing::info!(
|
||||
"Quote melt {} state changed from {} to {}",
|
||||
quote.id,
|
||||
quote.state,
|
||||
response.state
|
||||
);
|
||||
if response.state == MeltQuoteState::Paid {
|
||||
let pending_proofs = self.get_pending_proofs().await?;
|
||||
let proofs_total = pending_proofs.total_amount().unwrap_or_default();
|
||||
let change_total = response.change_amount().unwrap_or_default();
|
||||
self.localstore
|
||||
.add_transaction(Transaction {
|
||||
mint_url: self.mint_url.clone(),
|
||||
direction: TransactionDirection::Outgoing,
|
||||
amount: response.amount,
|
||||
fee: proofs_total
|
||||
.checked_sub(response.amount)
|
||||
.and_then(|amt| amt.checked_sub(change_total))
|
||||
.unwrap_or_default(),
|
||||
unit: quote.unit.clone(),
|
||||
ys: pending_proofs.ys()?,
|
||||
timestamp: unix_time(),
|
||||
memo: None,
|
||||
metadata: HashMap::new(),
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user