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>;
|
async fn add_melt_quote(&self, quote: wallet::MeltQuote) -> Result<(), Self::Err>;
|
||||||
/// Get melt quote from storage
|
/// Get melt quote from storage
|
||||||
async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<wallet::MeltQuote>, Self::Err>;
|
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
|
/// Remove melt quote from storage
|
||||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err>;
|
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err>;
|
||||||
|
|
||||||
|
|||||||
@@ -477,6 +477,21 @@ impl WalletDatabase for WalletRedbDatabase {
|
|||||||
Ok(None)
|
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)]
|
#[instrument(skip_all)]
|
||||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
||||||
let write_txn = self.db.begin_write().map_err(Error::from)?;
|
let write_txn = self.db.begin_write().map_err(Error::from)?;
|
||||||
|
|||||||
@@ -530,6 +530,30 @@ ON CONFLICT(id) DO UPDATE SET
|
|||||||
.transpose()?)
|
.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))]
|
#[instrument(skip(self))]
|
||||||
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
|
||||||
Statement::new(r#"DELETE FROM melt_quote WHERE id=:id"#)
|
Statement::new(r#"DELETE FROM melt_quote WHERE id=:id"#)
|
||||||
|
|||||||
@@ -104,6 +104,13 @@ impl Wallet {
|
|||||||
Some(quote) => {
|
Some(quote) => {
|
||||||
let mut quote = 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;
|
quote.state = response.state;
|
||||||
self.localstore.add_melt_quote(quote).await?;
|
self.localstore.add_melt_quote(quote).await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,13 @@ impl Wallet {
|
|||||||
Some(quote) => {
|
Some(quote) => {
|
||||||
let mut quote = 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;
|
quote.state = response.state;
|
||||||
self.localstore.add_melt_quote(quote).await?;
|
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_bolt11;
|
||||||
mod melt_bolt12;
|
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