feat(cdk): add quote_id field to transactions for quote tracking (#1041)

- Add quote_id field to Transaction struct in cdk-common
- Add database migrations for quote_id column in SQLite and PostgreSQL
- Update wallet operations to populate quote_id for mint/melt transactions
- Set quote_id to None for send/receive operations without associated quotes
This commit is contained in:
thesimplekid
2025-09-06 19:57:23 +01:00
committed by GitHub
parent 9b35158a8a
commit 5518ad2654
14 changed files with 33 additions and 13 deletions

View File

@@ -16,6 +16,8 @@
- cdk-common: Added comprehensive test module for KV store functionality with transaction and isolation testing ([thesimplekid]).
- cdk-sql-common: Database migration to add `kv_store` table for generic key-value storage in SQLite and PostgreSQL ([thesimplekid]).
- cdk-sql-common: Implementation of `MintKVStoreDatabase` trait for SQL-based databases with namespace support ([thesimplekid]).
- cdk-common: Added `quote_id` field to `Transaction` struct for tracking associated mint or melt quote IDs ([thesimplekid]).
- cdk-sql-common: Database migration to add `quote_id` column to transactions table for SQLite and PostgreSQL ([thesimplekid]).
### Changed
- cdk-common: Refactored `MintPayment` trait method `wait_any_incoming_payment` to `wait_payment_event` with event-driven architecture ([thesimplekid]).

View File

@@ -202,6 +202,8 @@ pub struct Transaction {
pub memo: Option<String>,
/// User-defined metadata
pub metadata: HashMap<String, String>,
/// Quote ID if this is a mint or melt transaction
pub quote_id: Option<String>,
}
impl Transaction {

View File

@@ -1,9 +1,9 @@
/// @generated
/// Auto-generated by build.rs
pub static MIGRATIONS: &[(&str, &str, &str)] = &[
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("postgres", "1_init.sql", include_str!(r#"./migrations/postgres/1_init.sql"#)),
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("sqlite", "20250109143347_init.sql", include_str!(r#"./migrations/sqlite/20250109143347_init.sql"#)),
("sqlite", "20250822104351_rename_blind_message_y_to_b.sql", include_str!(r#"./migrations/sqlite/20250822104351_rename_blind_message_y_to_b.sql"#)),
("postgres", "20250822104351_rename_blind_message_y_to_b.sql", include_str!(r#"./migrations/postgres/20250822104351_rename_blind_message_y_to_b.sql"#)),
("sqlite", "20250822104351_rename_blind_message_y_to_b.sql", include_str!(r#"./migrations/sqlite/20250822104351_rename_blind_message_y_to_b.sql"#)),
];

View File

@@ -1,8 +1,8 @@
/// @generated
/// Auto-generated by build.rs
pub static MIGRATIONS: &[(&str, &str, &str)] = &[
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("postgres", "1_initial.sql", include_str!(r#"./migrations/postgres/1_initial.sql"#)),
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("postgres", "2_remove_request_lookup_kind_constraints.sql", include_str!(r#"./migrations/postgres/2_remove_request_lookup_kind_constraints.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"#)),
@@ -27,8 +27,8 @@ pub static MIGRATIONS: &[(&str, &str, &str)] = &[
("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"#)),
("sqlite", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/sqlite/20250901090000_add_kv_store.sql"#)),
("postgres", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/postgres/20250901090000_add_kv_store.sql"#)),
("sqlite", "20250903200000_add_signatory_amounts.sql", include_str!(r#"./migrations/sqlite/20250903200000_add_signatory_amounts.sql"#)),
("sqlite", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/sqlite/20250901090000_add_kv_store.sql"#)),
("postgres", "20250903200000_add_signatory_amounts.sql", include_str!(r#"./migrations/postgres/20250903200000_add_signatory_amounts.sql"#)),
("sqlite", "20250903200000_add_signatory_amounts.sql", include_str!(r#"./migrations/sqlite/20250903200000_add_signatory_amounts.sql"#)),
];

View File

@@ -1,8 +1,8 @@
/// @generated
/// Auto-generated by build.rs
pub static MIGRATIONS: &[(&str, &str, &str)] = &[
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("postgres", "1_initial.sql", include_str!(r#"./migrations/postgres/1_initial.sql"#)),
("sqlite", "1_fix_sqlx_migration.sql", include_str!(r#"./migrations/sqlite/1_fix_sqlx_migration.sql"#)),
("sqlite", "20240612132920_init.sql", include_str!(r#"./migrations/sqlite/20240612132920_init.sql"#)),
("sqlite", "20240618200350_quote_state.sql", include_str!(r#"./migrations/sqlite/20240618200350_quote_state.sql"#)),
("sqlite", "20240626091921_nut04_state.sql", include_str!(r#"./migrations/sqlite/20240626091921_nut04_state.sql"#)),
@@ -22,6 +22,8 @@ pub static MIGRATIONS: &[(&str, &str, &str)] = &[
("sqlite", "20250707093445_bolt12.sql", include_str!(r#"./migrations/sqlite/20250707093445_bolt12.sql"#)),
("sqlite", "20250729111701_keyset_v2_u32.sql", include_str!(r#"./migrations/sqlite/20250729111701_keyset_v2_u32.sql"#)),
("sqlite", "20250812084621_keyset_plus_one.sql", include_str!(r#"./migrations/sqlite/20250812084621_keyset_plus_one.sql"#)),
("sqlite", "20250831215438_melt_quote_method.sql", include_str!(r#"./migrations/sqlite/20250831215438_melt_quote_method.sql"#)),
("postgres", "20250831215438_melt_quote_method.sql", include_str!(r#"./migrations/postgres/20250831215438_melt_quote_method.sql"#)),
("sqlite", "20250831215438_melt_quote_method.sql", include_str!(r#"./migrations/sqlite/20250831215438_melt_quote_method.sql"#)),
("postgres", "20250906200000_add_transaction_quote_id.sql", include_str!(r#"./migrations/postgres/20250906200000_add_transaction_quote_id.sql"#)),
("sqlite", "20250906200000_add_transaction_quote_id.sql", include_str!(r#"./migrations/sqlite/20250906200000_add_transaction_quote_id.sql"#)),
];

View File

@@ -0,0 +1 @@
ALTER TABLE transactions ADD COLUMN quote_id TEXT;

View File

@@ -0,0 +1 @@
ALTER TABLE transactions ADD COLUMN quote_id TEXT;

View File

@@ -903,9 +903,9 @@ ON CONFLICT(id) DO UPDATE SET
query(
r#"
INSERT INTO transactions
(id, mint_url, direction, unit, amount, fee, ys, timestamp, memo, metadata)
(id, mint_url, direction, unit, amount, fee, ys, timestamp, memo, metadata, quote_id)
VALUES
(:id, :mint_url, :direction, :unit, :amount, :fee, :ys, :timestamp, :memo, :metadata)
(:id, :mint_url, :direction, :unit, :amount, :fee, :ys, :timestamp, :memo, :metadata, :quote_id)
ON CONFLICT(id) DO UPDATE SET
mint_url = excluded.mint_url,
direction = excluded.direction,
@@ -915,7 +915,8 @@ ON CONFLICT(id) DO UPDATE SET
ys = excluded.ys,
timestamp = excluded.timestamp,
memo = excluded.memo,
metadata = excluded.metadata
metadata = excluded.metadata,
quote_id = excluded.quote_id
;
"#,
)?
@@ -932,6 +933,7 @@ ON CONFLICT(id) DO UPDATE SET
"metadata",
serde_json::to_string(&transaction.metadata).map_err(Error::from)?,
)
.bind("quote_id", transaction.quote_id)
.execute(&*conn)
.await?;
@@ -955,7 +957,8 @@ ON CONFLICT(id) DO UPDATE SET
ys,
timestamp,
memo,
metadata
metadata,
quote_id
FROM
transactions
WHERE
@@ -989,7 +992,8 @@ ON CONFLICT(id) DO UPDATE SET
ys,
timestamp,
memo,
metadata
metadata,
quote_id
FROM
transactions
"#,
@@ -1226,7 +1230,8 @@ fn sql_row_to_transaction(row: Vec<Column>) -> Result<Transaction, Error> {
ys,
timestamp,
memo,
metadata
metadata,
quote_id
) = row
);
@@ -1249,5 +1254,6 @@ fn sql_row_to_transaction(row: Vec<Column>) -> Result<Transaction, Error> {
serde_json::from_slice(&v).ok()
})
.unwrap_or_default(),
quote_id: column_as_nullable_string!(quote_id),
})
}

View File

@@ -322,6 +322,7 @@ impl Wallet {
timestamp: unix_time,
memo: None,
metadata: HashMap::new(),
quote_id: Some(quote_id.to_string()),
})
.await?;

View File

@@ -226,6 +226,7 @@ impl Wallet {
timestamp: unix_time(),
memo: None,
metadata: HashMap::new(),
quote_id: Some(quote_id.to_string()),
})
.await?;

View File

@@ -285,6 +285,7 @@ impl Wallet {
timestamp: unix_time(),
memo: None,
metadata: HashMap::new(),
quote_id: Some(quote_id.to_string()),
})
.await?;

View File

@@ -74,6 +74,7 @@ impl Wallet {
timestamp: unix_time(),
memo: None,
metadata: HashMap::new(),
quote_id: Some(quote.id.clone()),
})
.await?;
}

View File

@@ -167,6 +167,7 @@ impl Wallet {
timestamp: unix_time(),
memo,
metadata: opts.metadata,
quote_id: None, // Receive transactions don't have a quote_id
})
.await?;

View File

@@ -345,6 +345,7 @@ impl PreparedSend {
timestamp: unix_time(),
memo: memo.clone(),
metadata: self.options.metadata,
quote_id: None, // Send transactions don't have a quote_id
})
.await?;