99
1010//! Data structures and methods for constructing [`BlindedPaymentPath`]s to send a payment over.
1111
12+ use alloc:: collections:: BTreeMap ;
13+
1214use bitcoin:: secp256k1:: ecdh:: SharedSecret ;
1315use bitcoin:: secp256k1:: { self , PublicKey , Secp256k1 , SecretKey } ;
1416
@@ -29,8 +31,8 @@ use crate::types::features::BlindedHopFeatures;
2931use crate :: types:: payment:: PaymentSecret ;
3032use crate :: types:: routing:: RoutingFees ;
3133use crate :: util:: ser:: {
32- FixedLengthReader , HighZeroBytesDroppedBigSize , LengthReadableArgs , Readable , WithoutLength ,
33- Writeable , Writer ,
34+ BigSizeKeyedMap , FixedLengthReader , HighZeroBytesDroppedBigSize , LengthReadableArgs , Readable ,
35+ WithoutLength , Writeable , Writer ,
3436} ;
3537
3638#[ allow( unused_imports) ]
@@ -572,6 +574,16 @@ pub enum PaymentContext {
572574 /// [`Refund`]: crate::offers::refund::Refund
573575 Bolt12Refund ( Bolt12RefundContext ) ,
574576}
577+ impl PaymentContext {
578+ /// Returns the additional payment metadata stored alongside this payment context, if any.
579+ pub fn payment_metadata ( & self ) -> Option < & BTreeMap < u64 , Vec < u8 > > > {
580+ match self {
581+ Self :: Bolt12Offer ( Bolt12OfferContext { payment_metadata, .. } )
582+ | Self :: AsyncBolt12Offer ( AsyncBolt12OfferContext { payment_metadata, .. } )
583+ | Self :: Bolt12Refund ( Bolt12RefundContext { payment_metadata, .. } ) => payment_metadata. as_ref ( ) ,
584+ }
585+ }
586+ }
575587
576588// Used when writing PaymentContext in Event::PaymentClaimable to avoid cloning.
577589pub ( crate ) enum PaymentContextRef < ' a > {
@@ -594,6 +606,22 @@ pub struct Bolt12OfferContext {
594606 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
595607 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
596608 pub invoice_request : InvoiceRequestFields ,
609+
610+ /// Additional data about this payment which is not used in LDK and can be used for any
611+ /// purpose.
612+ ///
613+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
614+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
615+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
616+ /// them with the payment.
617+ ///
618+ /// Note that because this is included in the payment onion, its size must be tightly
619+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
620+ /// limited routing options as size increases).
621+ ///
622+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
623+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
624+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
597625}
598626
599627/// The context of a payment made for a static invoice requested from a BOLT 12 [`Offer`].
@@ -606,13 +634,45 @@ pub struct AsyncBolt12OfferContext {
606634 ///
607635 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
608636 pub offer_nonce : Nonce ,
637+
638+ /// Additional data about this payment which is not used in LDK and can be used for any
639+ /// purpose.
640+ ///
641+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
642+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
643+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
644+ /// them with the payment.
645+ ///
646+ /// Note that because this is included in the payment onion, its size must be tightly
647+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
648+ /// limited routing options as size increases).
649+ ///
650+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
651+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
652+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
609653}
610654
611655/// The context of a payment made for an invoice sent for a BOLT 12 [`Refund`].
612656///
613657/// [`Refund`]: crate::offers::refund::Refund
614658#[ derive( Clone , Debug , Eq , PartialEq ) ]
615- pub struct Bolt12RefundContext { }
659+ pub struct Bolt12RefundContext {
660+ /// Additional data about this payment which is not used in LDK and can be used for any
661+ /// purpose.
662+ ///
663+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
664+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
665+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
666+ /// them with the payment.
667+ ///
668+ /// Note that because this is included in the payment onion, its size must be tightly
669+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
670+ /// limited routing options as size increases).
671+ ///
672+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
673+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
674+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
675+ }
616676
617677impl TryFrom < CounterpartyForwardingInfo > for PaymentRelay {
618678 type Error = ( ) ;
@@ -1031,14 +1091,18 @@ impl<'a> Writeable for PaymentContextRef<'a> {
10311091
10321092impl_writeable_tlv_based ! ( Bolt12OfferContext , {
10331093 ( 0 , offer_id, required) ,
1094+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
10341095 ( 2 , invoice_request, required) ,
10351096} ) ;
10361097
10371098impl_writeable_tlv_based ! ( AsyncBolt12OfferContext , {
10381099 ( 0 , offer_nonce, required) ,
1100+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
10391101} ) ;
10401102
1041- impl_writeable_tlv_based ! ( Bolt12RefundContext , { } ) ;
1103+ impl_writeable_tlv_based ! ( Bolt12RefundContext , {
1104+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
1105+ } ) ;
10421106
10431107#[ cfg( test) ]
10441108mod tests {
@@ -1097,7 +1161,9 @@ mod tests {
10971161 let recv_tlvs = ReceiveTlvs {
10981162 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
10991163 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1100- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1164+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext {
1165+ payment_metadata : None ,
1166+ } ) ,
11011167 } ;
11021168 let htlc_maximum_msat = 100_000 ;
11031169 let blinded_payinfo =
@@ -1115,7 +1181,9 @@ mod tests {
11151181 let recv_tlvs = ReceiveTlvs {
11161182 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
11171183 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1118- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1184+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext {
1185+ payment_metadata : None ,
1186+ } ) ,
11191187 } ;
11201188 let blinded_payinfo = super :: compute_payinfo :: < ForwardTlvs > (
11211189 & [ ] ,
@@ -1178,7 +1246,9 @@ mod tests {
11781246 let recv_tlvs = ReceiveTlvs {
11791247 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
11801248 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 3 } ,
1181- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1249+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext {
1250+ payment_metadata : None ,
1251+ } ) ,
11821252 } ;
11831253 let htlc_maximum_msat = 100_000 ;
11841254 let blinded_payinfo = super :: compute_payinfo (
@@ -1238,7 +1308,9 @@ mod tests {
12381308 let recv_tlvs = ReceiveTlvs {
12391309 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
12401310 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1241- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1311+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext {
1312+ payment_metadata : None ,
1313+ } ) ,
12421314 } ;
12431315 let htlc_minimum_msat = 3798 ;
12441316 assert ! ( super :: compute_payinfo(
@@ -1309,7 +1381,9 @@ mod tests {
13091381 let recv_tlvs = ReceiveTlvs {
13101382 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
13111383 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1312- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1384+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext {
1385+ payment_metadata : None ,
1386+ } ) ,
13131387 } ;
13141388
13151389 let blinded_payinfo = super :: compute_payinfo (
0 commit comments