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,17 @@ 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, .. } )
584+ => payment_metadata. as_ref ( ) ,
585+ }
586+ }
587+ }
575588
576589// Used when writing PaymentContext in Event::PaymentClaimable to avoid cloning.
577590pub ( crate ) enum PaymentContextRef < ' a > {
@@ -594,6 +607,22 @@ pub struct Bolt12OfferContext {
594607 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
595608 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
596609 pub invoice_request : InvoiceRequestFields ,
610+
611+ /// Additional data about this payment which is not used in LDK and can be used for any
612+ /// purpose.
613+ ///
614+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
615+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
616+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
617+ /// them with the payment.
618+ ///
619+ /// Note that because this is included in the payment onion, its size must be tightly
620+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
621+ /// limited routing options as size increases).
622+ ///
623+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
624+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
625+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
597626}
598627
599628/// The context of a payment made for a static invoice requested from a BOLT 12 [`Offer`].
@@ -606,13 +635,45 @@ pub struct AsyncBolt12OfferContext {
606635 ///
607636 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
608637 pub offer_nonce : Nonce ,
638+
639+ /// Additional data about this payment which is not used in LDK and can be used for any
640+ /// purpose.
641+ ///
642+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
643+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
644+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
645+ /// them with the payment.
646+ ///
647+ /// Note that because this is included in the payment onion, its size must be tightly
648+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
649+ /// limited routing options as size increases).
650+ ///
651+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
652+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
653+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
609654}
610655
611656/// The context of a payment made for an invoice sent for a BOLT 12 [`Refund`].
612657///
613658/// [`Refund`]: crate::offers::refund::Refund
614659#[ derive( Clone , Debug , Eq , PartialEq ) ]
615- pub struct Bolt12RefundContext { }
660+ pub struct Bolt12RefundContext {
661+ /// Additional data about this payment which is not used in LDK and can be used for any
662+ /// purpose.
663+ ///
664+ /// This is analogous to the BOLT 11 [`RecipientOnionFields::payment_metadata`] (which is
665+ /// provided to payers via [`Bolt11Invoice::payment_metadata`]) and can be used any time data
666+ /// needs to be "stored" by a payment recipient for their own internal use, provided back to
667+ /// them with the payment.
668+ ///
669+ /// Note that because this is included in the payment onion, its size must be tightly
670+ /// constrained. More than a few hundred bytes and the payment will be entirely unpayable (with
671+ /// limited routing options as size increases).
672+ ///
673+ /// [`RecipientOnionFields::payment_metadata`]: crate::ln::outbound_payment::RecipientOnionFields::payment_metadata
674+ /// [`Bolt11Invoice::payment_metadata`]: lightning_invoice::Bolt11Invoice::payment_metadata
675+ pub payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
676+ }
616677
617678impl TryFrom < CounterpartyForwardingInfo > for PaymentRelay {
618679 type Error = ( ) ;
@@ -1031,14 +1092,18 @@ impl<'a> Writeable for PaymentContextRef<'a> {
10311092
10321093impl_writeable_tlv_based ! ( Bolt12OfferContext , {
10331094 ( 0 , offer_id, required) ,
1095+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
10341096 ( 2 , invoice_request, required) ,
10351097} ) ;
10361098
10371099impl_writeable_tlv_based ! ( AsyncBolt12OfferContext , {
10381100 ( 0 , offer_nonce, required) ,
1101+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
10391102} ) ;
10401103
1041- impl_writeable_tlv_based ! ( Bolt12RefundContext , { } ) ;
1104+ impl_writeable_tlv_based ! ( Bolt12RefundContext , {
1105+ ( 1 , payment_metadata, ( option, encoding: ( BTreeMap <u64 , Vec <u8 >>, BigSizeKeyedMap ) ) ) ,
1106+ } ) ;
10421107
10431108#[ cfg( test) ]
10441109mod tests {
@@ -1097,7 +1162,7 @@ mod tests {
10971162 let recv_tlvs = ReceiveTlvs {
10981163 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
10991164 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1100- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1165+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { payment_metadata : None } ) ,
11011166 } ;
11021167 let htlc_maximum_msat = 100_000 ;
11031168 let blinded_payinfo =
@@ -1115,7 +1180,7 @@ mod tests {
11151180 let recv_tlvs = ReceiveTlvs {
11161181 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
11171182 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1118- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1183+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { payment_metadata : None } ) ,
11191184 } ;
11201185 let blinded_payinfo = super :: compute_payinfo :: < ForwardTlvs > (
11211186 & [ ] ,
@@ -1178,7 +1243,7 @@ mod tests {
11781243 let recv_tlvs = ReceiveTlvs {
11791244 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
11801245 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 3 } ,
1181- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1246+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { payment_metadata : None } ) ,
11821247 } ;
11831248 let htlc_maximum_msat = 100_000 ;
11841249 let blinded_payinfo = super :: compute_payinfo (
@@ -1238,7 +1303,7 @@ mod tests {
12381303 let recv_tlvs = ReceiveTlvs {
12391304 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
12401305 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1241- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1306+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { payment_metadata : None } ) ,
12421307 } ;
12431308 let htlc_minimum_msat = 3798 ;
12441309 assert ! ( super :: compute_payinfo(
@@ -1309,7 +1374,7 @@ mod tests {
13091374 let recv_tlvs = ReceiveTlvs {
13101375 payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
13111376 payment_constraints : PaymentConstraints { max_cltv_expiry : 0 , htlc_minimum_msat : 1 } ,
1312- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
1377+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { payment_metadata : None } ) ,
13131378 } ;
13141379
13151380 let blinded_payinfo = super :: compute_payinfo (
0 commit comments