فهرست منبع

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
thesimplekid 1 ماه پیش
والد
کامیت
5518ad2654

+ 2 - 0
CHANGELOG.md

@@ -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]).

+ 2 - 0
crates/cdk-common/src/wallet.rs

@@ -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 {

+ 2 - 2
crates/cdk-sql-common/src/mint/auth/migrations.rs

@@ -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"#)),
 ];

+ 3 - 3
crates/cdk-sql-common/src/mint/migrations.rs

@@ -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"#)),
 ];

+ 4 - 2
crates/cdk-sql-common/src/wallet/migrations.rs

@@ -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"#)),
 ];

+ 1 - 0
crates/cdk-sql-common/src/wallet/migrations/postgres/20250906200000_add_transaction_quote_id.sql

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

+ 1 - 0
crates/cdk-sql-common/src/wallet/migrations/sqlite/20250906200000_add_transaction_quote_id.sql

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

+ 12 - 6
crates/cdk-sql-common/src/wallet/mod.rs

@@ -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),
     })
 }

+ 1 - 0
crates/cdk/src/wallet/issue/issue_bolt11.rs

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

+ 1 - 0
crates/cdk/src/wallet/issue/issue_bolt12.rs

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

+ 1 - 0
crates/cdk/src/wallet/melt/melt_bolt11.rs

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

+ 1 - 0
crates/cdk/src/wallet/melt/mod.rs

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

+ 1 - 0
crates/cdk/src/wallet/receive.rs

@@ -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?;
 

+ 1 - 0
crates/cdk/src/wallet/send.rs

@@ -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?;