feat(cdk): add payment request and proof to transaction records (#1155)

Add payment_request and payment_proof fields to Transaction model to store Lightning invoice details and payment preimages. Update database migrations and all transaction creation points across wallet operations (mint, melt, send, receive) to populate these fields.
This commit is contained in:
tsk
2025-10-06 14:40:21 +02:00
committed by GitHub
parent c15a79f313
commit c5e5d71701
11 changed files with 54 additions and 9 deletions

View File

@@ -204,6 +204,10 @@ pub struct Transaction {
pub metadata: HashMap<String, String>,
/// Quote ID if this is a mint or melt transaction
pub quote_id: Option<String>,
/// Payment request (e.g., BOLT11 invoice, BOLT12 offer)
pub payment_request: Option<String>,
/// Payment proof (e.g., preimage for Lightning melt transactions)
pub payment_proof: Option<String>,
}
impl Transaction {

View File

@@ -35,6 +35,10 @@ pub struct Transaction {
pub metadata: HashMap<String, String>,
/// Quote ID if this is a mint or melt transaction
pub quote_id: Option<String>,
/// Payment request (e.g., BOLT11 invoice, BOLT12 offer)
pub payment_request: Option<String>,
/// Payment proof (e.g., preimage for Lightning melt transactions)
pub payment_proof: Option<String>,
}
impl From<cdk::wallet::types::Transaction> for Transaction {
@@ -51,6 +55,8 @@ impl From<cdk::wallet::types::Transaction> 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<Transaction> 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,
})
}
}

View File

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

View File

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

View File

@@ -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<Column>) -> Result<Transaction, Error> {
timestamp,
memo,
metadata,
quote_id
quote_id,
payment_request,
payment_proof
) = row
);
@@ -1321,5 +1331,7 @@ fn sql_row_to_transaction(row: Vec<Column>) -> Result<Transaction, Error> {
})
.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),
})
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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