diff --git a/crates/cdk-common/src/wallet.rs b/crates/cdk-common/src/wallet.rs index a03d48f2..cf2a5a17 100644 --- a/crates/cdk-common/src/wallet.rs +++ b/crates/cdk-common/src/wallet.rs @@ -204,6 +204,10 @@ pub struct Transaction { pub metadata: HashMap, /// Quote ID if this is a mint or melt transaction pub quote_id: Option, + /// Payment request (e.g., BOLT11 invoice, BOLT12 offer) + pub payment_request: Option, + /// Payment proof (e.g., preimage for Lightning melt transactions) + pub payment_proof: Option, } impl Transaction { diff --git a/crates/cdk-ffi/src/types/transaction.rs b/crates/cdk-ffi/src/types/transaction.rs index 9291c778..9c70c35d 100644 --- a/crates/cdk-ffi/src/types/transaction.rs +++ b/crates/cdk-ffi/src/types/transaction.rs @@ -35,6 +35,10 @@ pub struct Transaction { pub metadata: HashMap, /// Quote ID if this is a mint or melt transaction pub quote_id: Option, + /// Payment request (e.g., BOLT11 invoice, BOLT12 offer) + pub payment_request: Option, + /// Payment proof (e.g., preimage for Lightning melt transactions) + pub payment_proof: Option, } impl From for Transaction { @@ -51,6 +55,8 @@ impl From for Transaction { memo: tx.memo, metadata: tx.metadata, quote_id: tx.quote_id, + payment_request: tx.payment_request, + payment_proof: tx.payment_proof, } } } @@ -75,6 +81,8 @@ impl TryFrom for cdk::wallet::types::Transaction { memo: tx.memo, metadata: tx.metadata, quote_id: tx.quote_id, + payment_request: tx.payment_request, + payment_proof: tx.payment_proof, }) } } diff --git a/crates/cdk-sql-common/src/wallet/migrations/postgres/20251005120000_add_payment_info_to_transactions.sql b/crates/cdk-sql-common/src/wallet/migrations/postgres/20251005120000_add_payment_info_to_transactions.sql new file mode 100644 index 00000000..1b3b933d --- /dev/null +++ b/crates/cdk-sql-common/src/wallet/migrations/postgres/20251005120000_add_payment_info_to_transactions.sql @@ -0,0 +1,3 @@ +-- Add payment_request and payment_proof to transactions table +ALTER TABLE transactions ADD COLUMN payment_request TEXT; +ALTER TABLE transactions ADD COLUMN payment_proof TEXT; diff --git a/crates/cdk-sql-common/src/wallet/migrations/sqlite/20251005120000_add_payment_info_to_transactions.sql b/crates/cdk-sql-common/src/wallet/migrations/sqlite/20251005120000_add_payment_info_to_transactions.sql new file mode 100644 index 00000000..1b3b933d --- /dev/null +++ b/crates/cdk-sql-common/src/wallet/migrations/sqlite/20251005120000_add_payment_info_to_transactions.sql @@ -0,0 +1,3 @@ +-- Add payment_request and payment_proof to transactions table +ALTER TABLE transactions ADD COLUMN payment_request TEXT; +ALTER TABLE transactions ADD COLUMN payment_proof TEXT; diff --git a/crates/cdk-sql-common/src/wallet/mod.rs b/crates/cdk-sql-common/src/wallet/mod.rs index 64371613..fd91ea68 100644 --- a/crates/cdk-sql-common/src/wallet/mod.rs +++ b/crates/cdk-sql-common/src/wallet/mod.rs @@ -969,9 +969,9 @@ ON CONFLICT(id) DO UPDATE SET query( r#" INSERT INTO transactions -(id, mint_url, direction, unit, amount, fee, ys, timestamp, memo, metadata, quote_id) +(id, mint_url, direction, unit, amount, fee, ys, timestamp, memo, metadata, quote_id, payment_request, payment_proof) VALUES -(:id, :mint_url, :direction, :unit, :amount, :fee, :ys, :timestamp, :memo, :metadata, :quote_id) +(:id, :mint_url, :direction, :unit, :amount, :fee, :ys, :timestamp, :memo, :metadata, :quote_id, :payment_request, :payment_proof) ON CONFLICT(id) DO UPDATE SET mint_url = excluded.mint_url, direction = excluded.direction, @@ -982,7 +982,9 @@ ON CONFLICT(id) DO UPDATE SET timestamp = excluded.timestamp, memo = excluded.memo, metadata = excluded.metadata, - quote_id = excluded.quote_id + quote_id = excluded.quote_id, + payment_request = excluded.payment_request, + payment_proof = excluded.payment_proof ; "#, )? @@ -1000,6 +1002,8 @@ ON CONFLICT(id) DO UPDATE SET serde_json::to_string(&transaction.metadata).map_err(Error::from)?, ) .bind("quote_id", transaction.quote_id) + .bind("payment_request", transaction.payment_request) + .bind("payment_proof", transaction.payment_proof) .execute(&*conn) .await?; @@ -1024,7 +1028,9 @@ ON CONFLICT(id) DO UPDATE SET timestamp, memo, metadata, - quote_id + quote_id, + payment_request, + payment_proof FROM transactions WHERE @@ -1059,7 +1065,9 @@ ON CONFLICT(id) DO UPDATE SET timestamp, memo, metadata, - quote_id + quote_id, + payment_request, + payment_proof FROM transactions "#, @@ -1297,7 +1305,9 @@ fn sql_row_to_transaction(row: Vec) -> Result { timestamp, memo, metadata, - quote_id + quote_id, + payment_request, + payment_proof ) = row ); @@ -1321,5 +1331,7 @@ fn sql_row_to_transaction(row: Vec) -> Result { }) .unwrap_or_default(), quote_id: column_as_nullable_string!(quote_id), + payment_request: column_as_nullable_string!(payment_request), + payment_proof: column_as_nullable_string!(payment_proof), }) } diff --git a/crates/cdk/src/wallet/issue/issue_bolt11.rs b/crates/cdk/src/wallet/issue/issue_bolt11.rs index 98ac3780..935c7602 100644 --- a/crates/cdk/src/wallet/issue/issue_bolt11.rs +++ b/crates/cdk/src/wallet/issue/issue_bolt11.rs @@ -329,6 +329,8 @@ impl Wallet { memo: None, metadata: HashMap::new(), quote_id: Some(quote_id.to_string()), + payment_request: Some(quote_info.request), + payment_proof: None, }) .await?; diff --git a/crates/cdk/src/wallet/issue/issue_bolt12.rs b/crates/cdk/src/wallet/issue/issue_bolt12.rs index 470f2582..fd8dc10f 100644 --- a/crates/cdk/src/wallet/issue/issue_bolt12.rs +++ b/crates/cdk/src/wallet/issue/issue_bolt12.rs @@ -232,6 +232,8 @@ impl Wallet { memo: None, metadata: HashMap::new(), quote_id: Some(quote_id.to_string()), + payment_request: Some(quote_info.request), + payment_proof: None, }) .await?; diff --git a/crates/cdk/src/wallet/melt/melt_bolt11.rs b/crates/cdk/src/wallet/melt/melt_bolt11.rs index 96a3f12f..58b23353 100644 --- a/crates/cdk/src/wallet/melt/melt_bolt11.rs +++ b/crates/cdk/src/wallet/melt/melt_bolt11.rs @@ -54,7 +54,7 @@ impl Wallet { let invoice = Bolt11Invoice::from_str(&request)?; let quote_request = MeltQuoteBolt11Request { - request: Bolt11Invoice::from_str(&request)?, + request: invoice.clone(), unit: self.unit.clone(), options, }; @@ -248,6 +248,8 @@ impl Wallet { None => None, }; + let payment_preimage = melt_response.payment_preimage.clone(); + let melted = Melted::from_proofs( melt_response.state, melt_response.payment_preimage, @@ -298,6 +300,8 @@ impl Wallet { memo: None, metadata, quote_id: Some(quote_id.to_string()), + payment_request: Some(quote_info.request), + payment_proof: payment_preimage, }) .await?; diff --git a/crates/cdk/src/wallet/melt/mod.rs b/crates/cdk/src/wallet/melt/mod.rs index 24db4629..c56d18eb 100644 --- a/crates/cdk/src/wallet/melt/mod.rs +++ b/crates/cdk/src/wallet/melt/mod.rs @@ -60,6 +60,7 @@ impl Wallet { let pending_proofs = self.get_pending_proofs().await?; let proofs_total = pending_proofs.total_amount().unwrap_or_default(); let change_total = response.change_amount().unwrap_or_default(); + self.localstore .add_transaction(Transaction { mint_url: self.mint_url.clone(), @@ -75,6 +76,8 @@ impl Wallet { memo: None, metadata: HashMap::new(), quote_id: Some(quote.id.clone()), + payment_request: Some(quote.request.clone()), + payment_proof: response.payment_preimage.clone(), }) .await?; } diff --git a/crates/cdk/src/wallet/receive.rs b/crates/cdk/src/wallet/receive.rs index 2d0334b4..b5fc2c8f 100644 --- a/crates/cdk/src/wallet/receive.rs +++ b/crates/cdk/src/wallet/receive.rs @@ -167,7 +167,9 @@ impl Wallet { timestamp: unix_time(), memo, metadata: opts.metadata, - quote_id: None, // Receive transactions don't have a quote_id + quote_id: None, + payment_request: None, + payment_proof: None, }) .await?; diff --git a/crates/cdk/src/wallet/send.rs b/crates/cdk/src/wallet/send.rs index 0f41f8e9..6b4d4123 100644 --- a/crates/cdk/src/wallet/send.rs +++ b/crates/cdk/src/wallet/send.rs @@ -350,7 +350,9 @@ impl PreparedSend { timestamp: unix_time(), memo: memo.clone(), metadata: self.options.metadata, - quote_id: None, // Send transactions don't have a quote_id + quote_id: None, + payment_request: None, + payment_proof: None, }) .await?;