Skip to content

Commit 94b56f3

Browse files
Inject payer offer into invoice requests for BLIP-42
Implements automatic injection of the payer's offer into invoice requests to support BLIP-42 contact management. This allows recipients to identify which specific offer is being paid, enabling better contact tracking and payment relationship management. Signed-off-by: Vincenzo Palazzo <[email protected]>
1 parent 8f4b944 commit 94b56f3

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13062,6 +13062,11 @@ where
1306213062
Some(c) => c,
1306313063
};
1306413064
let builder = builder.contact_secrets(contacts.clone());
13065+
// Create a minimal offer for BLIP-42 contact exchange (just node_id, no description/paths)
13066+
// TODO: Create a better minimal offer with a single blinded path hop for privacy,
13067+
// while keeping the size small enough to fit in the onion packet.
13068+
let payer_offer = self.create_offer_builder()?.build()?;
13069+
let builder = builder.payer_offer(&payer_offer);
1306513070

1306613071
let invoice_request = builder.build_and_sign()?;
1306713072
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);

lightning/src/ln/offers_tests.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use crate::blinded_path::payment::{Bolt12OfferContext, Bolt12RefundContext, Paym
5151
use crate::blinded_path::message::OffersContext;
5252
use crate::events::{ClosureReason, Event, HTLCHandlingFailureType, PaidBolt12Invoice, PaymentFailureReason, PaymentPurpose};
5353
use crate::ln::channelmanager::{Bolt12PaymentError, PaymentId, RecentPaymentDetails, RecipientOnionFields, Retry, self};
54+
use crate::offers::offer::Offer;
5455
use crate::types::features::Bolt12InvoiceFeatures;
5556
use crate::ln::functional_test_utils::*;
5657
use crate::ln::msgs::{BaseMessageHandler, ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement};
@@ -2571,12 +2572,15 @@ fn pay_offer_and_add_contacts_info_blip42() {
25712572
});
25722573
assert_eq!(invoice_request.amount_msats(), Some(10_000_000));
25732574
assert_ne!(invoice_request.payer_signing_pubkey(), bob_id);
2574-
// Now we check that there are the contact secret and the
2575-
// contact secret is the same that we inject by bob.
25762575
assert!(invoice_request.contact_secret().is_some());
2577-
assert!(invoice_request.payer_offer().is_some());
25782576
// TODO: we should check also if the contact secret is the same that we inject by bob.
25792577

2578+
assert!(invoice_request.payer_offer().is_some());
2579+
// FIXME: this is wrong but make sure that we are following correctly the code path.
2580+
let payer_offer_bytes = invoice_request.payer_offer().unwrap();
2581+
let payer_offer = Offer::try_from(payer_offer_bytes.to_vec()).unwrap();
2582+
assert_eq!(payer_offer, offer);
2583+
25802584
let onion_message = alice.onion_messenger.next_onion_message_for_peer(bob_id).unwrap();
25812585
bob.onion_messenger.handle_onion_message(alice_id, &onion_message);
25822586

lightning/src/offers/invoice_request.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ macro_rules! invoice_request_builder_methods { (
268268
$return_value
269269
}
270270

271+
/// Sets the payer's offer for BLIP-42 contact management.
272+
///
273+
/// This will include the serialized offer bytes in the invoice request,
274+
/// allowing the recipient to identify which offer the payer is responding to.
275+
///
276+
/// Successive calls to this method will override the previous setting.
277+
pub fn payer_offer($($self_mut)* $self: $self_type, offer: &Offer) -> $return_type {
278+
$self.invoice_request.invreq_payer_offer = Some(offer.bytes.clone());
279+
$return_value
280+
}
281+
271282
fn build_with_checks($($self_mut)* $self: $self_type) -> Result<
272283
(UnsignedInvoiceRequest, Option<Keypair>, Option<&'b Secp256k1<$secp_context>>),
273284
Bolt12SemanticError

0 commit comments

Comments
 (0)