mirror of
https://github.com/aljazceru/cdk.git
synced 2026-01-21 22:06:17 +01:00
refactor(cdk): defer BOLT12 invoice fetching to payment execution (#978)
* refactor(cdk): defer BOLT12 invoice fetching to payment execution Move BOLT12 invoice generation from quote creation to payment time, make request_lookup_id optional for offers, and simplify payment structures by removing unnecessary boxing and intermediate storage of invoices.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
/// Auto-generated by build.rs
|
||||
pub static MIGRATIONS: &[(&str, &str, &str)] = &[
|
||||
("postgres", "1_initial.sql", include_str!(r#"./migrations/postgres/1_initial.sql"#)),
|
||||
("postgres", "2_remove_request_lookup_kind_constraints.sql", include_str!(r#"./migrations/postgres/2_remove_request_lookup_kind_constraints.sql"#)),
|
||||
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
|
||||
("sqlite", "20240612124932_init.sql", include_str!(r#"./migrations/sqlite/20240612124932_init.sql"#)),
|
||||
("sqlite", "20240618195700_quote_state.sql", include_str!(r#"./migrations/sqlite/20240618195700_quote_state.sql"#)),
|
||||
@@ -25,4 +26,5 @@ pub static MIGRATIONS: &[(&str, &str, &str)] = &[
|
||||
("sqlite", "20250626120251_rename_blind_message_y_to_b.sql", include_str!(r#"./migrations/sqlite/20250626120251_rename_blind_message_y_to_b.sql"#)),
|
||||
("sqlite", "20250706101057_bolt12.sql", include_str!(r#"./migrations/sqlite/20250706101057_bolt12.sql"#)),
|
||||
("sqlite", "20250812132015_drop_melt_request.sql", include_str!(r#"./migrations/sqlite/20250812132015_drop_melt_request.sql"#)),
|
||||
("sqlite", "20250819200000_remove_request_lookup_kind_constraints.sql", include_str!(r#"./migrations/sqlite/20250819200000_remove_request_lookup_kind_constraints.sql"#)),
|
||||
];
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Set existing NULL or empty request_lookup_id_kind values to 'payment_hash' in melt_quote
|
||||
UPDATE melt_quote SET request_lookup_id_kind = 'payment_hash' WHERE request_lookup_id_kind IS NULL OR request_lookup_id_kind = '';
|
||||
|
||||
-- Remove NOT NULL constraint and default value from request_lookup_id_kind in melt_quote table
|
||||
ALTER TABLE melt_quote ALTER COLUMN request_lookup_id_kind DROP NOT NULL;
|
||||
ALTER TABLE melt_quote ALTER COLUMN request_lookup_id_kind DROP DEFAULT;
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
-- Set existing NULL or empty request_lookup_id_kind values to 'payment_hash' in melt_quote
|
||||
UPDATE melt_quote SET request_lookup_id_kind = 'payment_hash' WHERE request_lookup_id_kind IS NULL OR request_lookup_id_kind = '';
|
||||
|
||||
-- Remove NOT NULL constraint and default value from request_lookup_id_kind in melt_quote table
|
||||
CREATE TABLE melt_quote_temp (
|
||||
id TEXT PRIMARY KEY,
|
||||
unit TEXT NOT NULL,
|
||||
amount INTEGER NOT NULL,
|
||||
request TEXT NOT NULL,
|
||||
fee_reserve INTEGER NOT NULL,
|
||||
expiry INTEGER NOT NULL,
|
||||
state TEXT CHECK (
|
||||
state IN ('UNPAID', 'PENDING', 'PAID')
|
||||
) NOT NULL DEFAULT 'UNPAID',
|
||||
payment_preimage TEXT,
|
||||
request_lookup_id TEXT,
|
||||
created_time INTEGER NOT NULL DEFAULT 0,
|
||||
paid_time INTEGER,
|
||||
payment_method TEXT NOT NULL DEFAULT 'bolt11',
|
||||
options TEXT,
|
||||
request_lookup_id_kind TEXT
|
||||
);
|
||||
|
||||
INSERT INTO melt_quote_temp (id, unit, amount, request, fee_reserve, expiry, state, payment_preimage, request_lookup_id, created_time, paid_time, payment_method, options, request_lookup_id_kind)
|
||||
SELECT id, unit, amount, request, fee_reserve, expiry, state, payment_preimage, request_lookup_id, created_time, paid_time, payment_method, options, request_lookup_id_kind
|
||||
FROM melt_quote;
|
||||
|
||||
DROP TABLE melt_quote;
|
||||
ALTER TABLE melt_quote_temp RENAME TO melt_quote;
|
||||
|
||||
-- Recreate indexes for melt_quote
|
||||
CREATE INDEX IF NOT EXISTS melt_quote_state_index ON melt_quote(state);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS unique_request_lookup_id_melt ON melt_quote(request_lookup_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_melt_quote_request_lookup_id_and_kind ON melt_quote(request_lookup_id, request_lookup_id_kind);
|
||||
@@ -739,24 +739,6 @@ VALUES (:quote_id, :amount, :timestamp);
|
||||
|
||||
async fn add_melt_quote(&mut self, quote: mint::MeltQuote) -> Result<(), Self::Err> {
|
||||
// First try to find and replace any expired UNPAID quotes with the same request_lookup_id
|
||||
let current_time = unix_time();
|
||||
let row_affected = query(
|
||||
r#"
|
||||
DELETE FROM melt_quote
|
||||
WHERE request_lookup_id = :request_lookup_id
|
||||
AND state = :state
|
||||
AND expiry < :current_time
|
||||
"#,
|
||||
)?
|
||||
.bind("request_lookup_id", quote.request_lookup_id.to_string())
|
||||
.bind("state", MeltQuoteState::Unpaid.to_string())
|
||||
.bind("current_time", current_time as i64)
|
||||
.execute(&self.inner)
|
||||
.await?;
|
||||
|
||||
if row_affected > 0 {
|
||||
tracing::info!("Received new melt quote for existing invoice with expired quote.");
|
||||
}
|
||||
|
||||
// Now insert the new quote
|
||||
query(
|
||||
@@ -783,14 +765,20 @@ VALUES (:quote_id, :amount, :timestamp);
|
||||
.bind("state", quote.state.to_string())
|
||||
.bind("expiry", quote.expiry as i64)
|
||||
.bind("payment_preimage", quote.payment_preimage)
|
||||
.bind("request_lookup_id", quote.request_lookup_id.to_string())
|
||||
.bind(
|
||||
"request_lookup_id",
|
||||
quote.request_lookup_id.as_ref().map(|id| id.to_string()),
|
||||
)
|
||||
.bind("created_time", quote.created_time as i64)
|
||||
.bind("paid_time", quote.paid_time.map(|t| t as i64))
|
||||
.bind(
|
||||
"options",
|
||||
quote.options.map(|o| serde_json::to_string(&o).ok()),
|
||||
)
|
||||
.bind("request_lookup_id_kind", quote.request_lookup_id.kind())
|
||||
.bind(
|
||||
"request_lookup_id_kind",
|
||||
quote.request_lookup_id.map(|id| id.kind()),
|
||||
)
|
||||
.bind("payment_method", quote.payment_method.to_string())
|
||||
.execute(&self.inner)
|
||||
.await?;
|
||||
@@ -1713,19 +1701,24 @@ fn sql_row_to_melt_quote(row: Vec<Column>) -> Result<mint::MeltQuote, Error> {
|
||||
let unit = column_as_string!(unit);
|
||||
let request = column_as_string!(request);
|
||||
|
||||
let mut request_lookup_id_kind = column_as_string!(request_lookup_id_kind);
|
||||
let request_lookup_id_kind = column_as_nullable_string!(request_lookup_id_kind);
|
||||
|
||||
let request_lookup_id = column_as_nullable_string!(&request_lookup_id).unwrap_or_else(|| {
|
||||
let request_lookup_id = column_as_nullable_string!(&request_lookup_id).or_else(|| {
|
||||
Bolt11Invoice::from_str(&request)
|
||||
.ok()
|
||||
.map(|invoice| invoice.payment_hash().to_string())
|
||||
.unwrap_or_else(|_| {
|
||||
request_lookup_id_kind = "custom".to_string();
|
||||
request.clone()
|
||||
})
|
||||
});
|
||||
|
||||
let request_lookup_id = PaymentIdentifier::new(&request_lookup_id_kind, &request_lookup_id)
|
||||
.map_err(|_| ConversionError::MissingParameter("Payment id".to_string()))?;
|
||||
let request_lookup_id = if let (Some(id_kind), Some(request_lookup_id)) =
|
||||
(request_lookup_id_kind, request_lookup_id)
|
||||
{
|
||||
Some(
|
||||
PaymentIdentifier::new(&id_kind, &request_lookup_id)
|
||||
.map_err(|_| ConversionError::MissingParameter("Payment id".to_string()))?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let request = match serde_json::from_str(&request) {
|
||||
Ok(req) => req,
|
||||
|
||||
Reference in New Issue
Block a user