Some lightning invoice refactoring
This commit is contained in:
+18
-35
@@ -3,7 +3,8 @@ use sqlx::{Sqlite, SqlitePool, Transaction};
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
use crate::models::{
|
||||
Activity, RELAY_STATUS_ACTIVE, RELAY_STATUS_DELINQUENT, RELAY_STATUS_INACTIVE, Relay, Tenant,
|
||||
Activity, LightningInvoice, RELAY_STATUS_ACTIVE, RELAY_STATUS_DELINQUENT,
|
||||
RELAY_STATUS_INACTIVE, Relay, Tenant,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -298,22 +299,29 @@ impl Command {
|
||||
|
||||
// Invoices
|
||||
|
||||
/// Insert a freshly minted pending bolt11 for an invoice. Returns `false` if
|
||||
/// a row already exists (lost an insert race), in which case the caller
|
||||
/// should read and use the existing row's bolt11.
|
||||
pub async fn insert_pending_lightning_invoice(
|
||||
/// Upsert the pending bolt11 for an invoice, returning the resulting row. On
|
||||
/// conflict the stored bolt11/expiry are replaced — this is how an expired
|
||||
/// invoice is regenerated — except once the invoice is paid, when the
|
||||
/// `status = 'pending'` guard makes the update a no-op and `None` is
|
||||
/// returned so the caller can fall back to reading the settled row.
|
||||
pub async fn insert_lightning_invoice(
|
||||
&self,
|
||||
stripe_invoice_id: &str,
|
||||
tenant_pubkey: &str,
|
||||
bolt11: &str,
|
||||
expires_at: i64,
|
||||
) -> Result<bool> {
|
||||
) -> Result<Option<LightningInvoice>> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
let result = sqlx::query(
|
||||
let row = sqlx::query_as::<_, LightningInvoice>(
|
||||
"INSERT INTO lightning_invoice
|
||||
(stripe_invoice_id, tenant_pubkey, bolt11, status, expires_at, created_at, updated_at)
|
||||
VALUES (?, ?, ?, 'pending', ?, ?, ?)
|
||||
ON CONFLICT(stripe_invoice_id) DO NOTHING",
|
||||
ON CONFLICT(stripe_invoice_id) DO UPDATE SET
|
||||
bolt11 = excluded.bolt11,
|
||||
expires_at = excluded.expires_at,
|
||||
updated_at = excluded.updated_at
|
||||
WHERE status = 'pending'
|
||||
RETURNING *",
|
||||
)
|
||||
.bind(stripe_invoice_id)
|
||||
.bind(tenant_pubkey)
|
||||
@@ -321,35 +329,10 @@ impl Command {
|
||||
.bind(expires_at)
|
||||
.bind(now)
|
||||
.bind(now)
|
||||
.execute(&self.pool)
|
||||
.fetch_optional(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(result.rows_affected() > 0)
|
||||
}
|
||||
|
||||
/// Replace the stored bolt11 for a still-pending invoice whose previous
|
||||
/// invoice expired. No-op once the invoice is paid, so this can never
|
||||
/// overwrite a settled invoice.
|
||||
pub async fn regenerate_lightning_invoice(
|
||||
&self,
|
||||
stripe_invoice_id: &str,
|
||||
bolt11: &str,
|
||||
expires_at: i64,
|
||||
) -> Result<()> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
sqlx::query(
|
||||
"UPDATE lightning_invoice
|
||||
SET bolt11 = ?, expires_at = ?, updated_at = ?
|
||||
WHERE stripe_invoice_id = ? AND status = 'pending'",
|
||||
)
|
||||
.bind(bolt11)
|
||||
.bind(expires_at)
|
||||
.bind(now)
|
||||
.bind(stripe_invoice_id)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
/// Mark a pending invoice paid, recording which method settled it. The
|
||||
|
||||
Reference in New Issue
Block a user