diff --git a/openapi.yaml b/openapi.yaml index 81a6cf52..725a14b6 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -2346,6 +2346,9 @@ components: payee_pubkey: type: string example: 03b79a4bc1ec365524b4fab9a39eb133753646babb5a1da5c4bc94c53110b7795d + preimage: + type: string + example: 89d28bd306aa9bb906fd0ac31092d04c37c919a171b343083167e2a3cdc60578 Peer: type: object required: diff --git a/src/routes.rs b/src/routes.rs index 0e6d6a3d..e405325d 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -863,6 +863,7 @@ pub(crate) struct Payment { pub(crate) created_at: u64, pub(crate) updated_at: u64, pub(crate) payee_pubkey: String, + pub(crate) preimage: Option, } #[derive(Clone, Deserialize, Serialize)] @@ -1774,6 +1775,7 @@ pub(crate) async fn get_payment( created_at: payment_info.created_at, updated_at: payment_info.updated_at, payee_pubkey: payment_info.payee_pubkey.to_string(), + preimage: payment_info.preimage.map(|p| hex_str(&p.0)), }, })); } @@ -1803,6 +1805,7 @@ pub(crate) async fn get_payment( created_at: payment_info.created_at, updated_at: payment_info.updated_at, payee_pubkey: payment_info.payee_pubkey.to_string(), + preimage: payment_info.preimage.map(|p| hex_str(&p.0)), }, })); } @@ -2316,6 +2319,7 @@ pub(crate) async fn list_payments( created_at: payment_info.created_at, updated_at: payment_info.updated_at, payee_pubkey: payment_info.payee_pubkey.to_string(), + preimage: payment_info.preimage.map(|p| hex_str(&p.0)), }); } @@ -2342,6 +2346,7 @@ pub(crate) async fn list_payments( created_at: payment_info.created_at, updated_at: payment_info.updated_at, payee_pubkey: payment_info.payee_pubkey.to_string(), + preimage: payment_info.preimage.map(|p| hex_str(&p.0)), }); } diff --git a/src/test/mod.rs b/src/test/mod.rs index 268b0294..7b29c35a 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1,5 +1,7 @@ use amplify::s; use biscuit_auth::{builder::date, macros::*, KeyPair}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::Hash; use chrono::{DateTime, Local, Utc}; use electrum_client::ElectrumApi; use lazy_static::lazy_static; @@ -41,7 +43,7 @@ use crate::routes::{ SendPaymentResponse, SendRgbRequest, SendRgbResponse, Swap, SwapStatus, TakerRequest, Transaction, Transfer, UnlockRequest, Unspent, WitnessData, }; -use crate::utils::{hex_str_to_vec, ELECTRUM_URL_REGTEST, PROXY_ENDPOINT_LOCAL}; +use crate::utils::{hex_str, hex_str_to_vec, ELECTRUM_URL_REGTEST, PROXY_ENDPOINT_LOCAL}; use super::*; @@ -83,6 +85,13 @@ fn _bitcoin_cli() -> [String; 7] { ] } +fn check_preimage_matches_hash(payment: &Payment, expected_payment_hash: &str) { + let payment_preimage = payment.preimage.as_ref().unwrap(); + let payment_preimage_hash = + hex_str(&Sha256::hash(&hex_str_to_vec(payment_preimage).unwrap()).to_byte_array()); + assert_eq!(payment_preimage_hash, expected_payment_hash); +} + async fn _check_response_is_ok(res: Response) -> Response { if res.status() != reqwest::StatusCode::OK { panic!("reqwest response is not OK: {:?}", res.text().await); diff --git a/src/test/payment.rs b/src/test/payment.rs index fed915d0..c09ef0d7 100644 --- a/src/test/payment.rs +++ b/src/test/payment.rs @@ -64,10 +64,24 @@ async fn success() { assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let payment = get_payment(node2_addr, &decoded.payment_hash).await; assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); + let payment = list_payments(node1_addr) + .await + .into_iter() + .find(|payment| payment.payment_hash == decoded.payment_hash) + .unwrap(); + check_preimage_matches_hash(&payment, &decoded.payment_hash); + let payment = list_payments(node2_addr) + .await + .into_iter() + .find(|payment| payment.payment_hash == decoded.payment_hash) + .unwrap(); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let asset_amount = Some(50); let LNInvoiceResponse { invoice } = @@ -86,10 +100,12 @@ async fn success() { assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let payment = get_payment(node2_addr, &decoded.payment_hash).await; assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let LNInvoiceResponse { invoice } = ln_invoice(node2_addr, None, Some(&asset_id), asset_amount, 900).await; @@ -100,10 +116,12 @@ async fn success() { assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let payment = get_payment(node2_addr, &decoded.payment_hash).await; assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let LNInvoiceResponse { invoice } = ln_invoice(node1_addr, None, Some(&asset_id), asset_amount, 900).await; @@ -114,10 +132,12 @@ async fn success() { assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let payment = get_payment(node2_addr, &decoded.payment_hash).await; assert_eq!(payment.asset_id, Some(asset_id.clone())); assert_eq!(payment.asset_amount, asset_amount); assert_eq!(payment.status, HTLCStatus::Succeeded); + check_preimage_matches_hash(&payment, &decoded.payment_hash); let channels_1 = list_channels(node1_addr).await; let channels_2 = list_channels(node2_addr).await;