feat: wait invoice is stream of request_lookup_id

This commit is contained in:
thesimplekid
2024-07-05 13:03:15 +01:00
parent 6a315fc3b9
commit 8b775cb7f1
8 changed files with 80 additions and 13 deletions

View File

@@ -56,7 +56,7 @@ impl MintLightning for Cln {
async fn wait_any_invoice(
&self,
) -> Result<Pin<Box<dyn Stream<Item = Bolt11Invoice> + Send>>, Self::Err> {
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
let last_pay_index = self.get_last_pay_index().await?;
let cln_client = cln_rpc::ClnRpc::new(&self.rpc_socket).await?;
@@ -86,11 +86,7 @@ impl MintLightning for Cln {
last_pay_idx = invoice.pay_index;
if let Some(bolt11) = invoice.bolt11 {
if let Ok(invoice) = Bolt11Invoice::from_str(&bolt11) {
break Some((invoice, (cln_client, last_pay_idx)));
}
}
break Some((invoice.label, (cln_client, last_pay_idx)));
}
},
)

View File

@@ -177,9 +177,9 @@ async fn main() -> anyhow::Result<()> {
loop {
match ln.wait_any_invoice().await {
Ok(mut stream) => {
while let Some(invoice) = stream.next().await {
while let Some(request_lookup_id) = stream.next().await {
if let Err(err) =
handle_paid_invoice(Arc::clone(&mint), &invoice.to_string()).await
handle_paid_invoice(Arc::clone(&mint), &request_lookup_id).await
{
tracing::warn!("{:?}", err);
}
@@ -201,8 +201,12 @@ async fn main() -> anyhow::Result<()> {
}
/// Update mint quote when called for a paid invoice
async fn handle_paid_invoice(mint: Arc<Mint>, request: &str) -> Result<()> {
if let Ok(Some(mint_quote)) = mint.localstore.get_mint_quote_by_request(request).await {
async fn handle_paid_invoice(mint: Arc<Mint>, request_lookup_id: &str) -> Result<()> {
if let Ok(Some(mint_quote)) = mint
.localstore
.get_mint_quote_by_request_lookup_id(request_lookup_id)
.await
{
mint.localstore
.update_mint_quote_state(&mint_quote.id, cdk::nuts::MintQuoteState::Paid)
.await?;

View File

@@ -331,6 +331,22 @@ impl MintDatabase for MintRedbDatabase {
Ok(quote)
}
async fn get_mint_quote_by_request_lookup_id(
&self,
request_lookup_id: &str,
) -> Result<Option<MintQuote>, Self::Err> {
let quotes = self.get_mint_quotes().await?;
let quote = quotes
.into_iter()
.filter(|q| q.request_lookup_id.eq(request_lookup_id))
.collect::<Vec<MintQuote>>()
.first()
.cloned();
Ok(quote)
}
async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
let db = self.db.lock().await;
let read_txn = db.begin_read().map_err(Error::from)?;

View File

@@ -1,2 +1,5 @@
ALTER TABLE mint_quote ADD request_lookup_id TEXT;
ALTER TABLE melt_quote ADD request_lookup_id TEXT;
ALTER TABLE mint_quote ADD request_lookup_id TEXT UNIQUE;
ALTER TABLE melt_quote ADD request_lookup_id TEXT UNIQUE;
CREATE INDEX IF NOT EXISTS mint_quote_request_lookup_id_index ON mint_quote(request_lookup_id);
CREATE INDEX IF NOT EXISTS melt_quote_request_lookup_id_index ON melt_quote(request_lookup_id);

View File

@@ -198,6 +198,32 @@ WHERE request=?;
Ok(Some(sqlite_row_to_mint_quote(rec)?))
}
async fn get_mint_quote_by_request_lookup_id(
&self,
request_lookup_id: &str,
) -> Result<Option<MintQuote>, Self::Err> {
let rec = sqlx::query(
r#"
SELECT *
FROM mint_quote
WHERE request_lookup_id=?;
"#,
)
.bind(request_lookup_id)
.fetch_one(&self.pool)
.await;
let rec = match rec {
Ok(rec) => rec,
Err(err) => match err {
sqlx::Error::RowNotFound => return Ok(None),
_ => return Err(Error::SQLX(err).into()),
},
};
Ok(Some(sqlite_row_to_mint_quote(rec)?))
}
async fn update_mint_quote_state(
&self,
quote_id: &str,

View File

@@ -128,6 +128,22 @@ impl MintDatabase for MintMemoryDatabase {
Ok(current_state)
}
async fn get_mint_quote_by_request_lookup_id(
&self,
request: &str,
) -> Result<Option<MintQuote>, Self::Err> {
let quotes = self.get_mint_quotes().await?;
let quote = quotes
.into_iter()
.filter(|q| q.request_lookup_id.eq(request))
.collect::<Vec<MintQuote>>()
.first()
.cloned();
Ok(quote)
}
async fn get_mint_quote_by_request(
&self,
request: &str,

View File

@@ -185,6 +185,11 @@ pub trait MintDatabase {
&self,
request: &str,
) -> Result<Option<MintMintQuote>, Self::Err>;
/// Get all [`MintMintQuote`]s
async fn get_mint_quote_by_request_lookup_id(
&self,
request_lookup_id: &str,
) -> Result<Option<MintMintQuote>, Self::Err>;
/// Get Mint Quotes
async fn get_mint_quotes(&self) -> Result<Vec<MintMintQuote>, Self::Err>;
/// Remove [`MintMintQuote`]

View File

@@ -64,9 +64,10 @@ pub trait MintLightning {
) -> Result<PayInvoiceResponse, Self::Err>;
/// Listen for invoices to be paid to the mint
/// Returns a stream of request_lookup_id once invoices are paid
async fn wait_any_invoice(
&self,
) -> Result<Pin<Box<dyn Stream<Item = Bolt11Invoice> + Send>>, Self::Err>;
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err>;
/// Check the status of an incoming payment
async fn check_invoice_status(