@@ -260,6 +260,15 @@ pub struct ReceiveTlvs {
260260 pub payment_constraints : PaymentConstraints ,
261261 /// Context for the receiver of this payment.
262262 pub payment_context : PaymentContext ,
263+ /// Custom data set by the user. And is returned back when the blinded path is used.
264+ ///
265+ /// ## Note on Forward Compatibility:
266+ /// Users can encode any kind of data into the `Vec<u8>` bytes here. However, they should ensure
267+ /// that the data is structured in a forward-compatible manner. This is especially important as
268+ /// `ReceiveTlvs` created in one version of the software may still appear in payments received
269+ /// shortly after a software upgrade. Proper forward compatibility helps prevent data loss or
270+ /// misinterpretation in future versions.
271+ pub custom_data : Vec < u8 > ,
263272}
264273
265274/// Data to construct a [`BlindedHop`] for sending a payment over.
@@ -404,7 +413,8 @@ impl Writeable for ReceiveTlvs {
404413 encode_tlv_stream ! ( w, {
405414 ( 12 , self . payment_constraints, required) ,
406415 ( 65536 , self . payment_secret, required) ,
407- ( 65537 , self . payment_context, required)
416+ ( 65537 , self . payment_context, required) ,
417+ ( 65539 , self . custom_data, ( default_value, Vec :: new( ) ) ) ,
408418 } ) ;
409419 Ok ( ( ) )
410420 }
@@ -432,6 +442,7 @@ impl Readable for BlindedPaymentTlvs {
432442 ( 14 , features, ( option, encoding: ( BlindedHopFeatures , WithoutLength ) ) ) ,
433443 ( 65536 , payment_secret, option) ,
434444 ( 65537 , payment_context, ( default_value, PaymentContext :: unknown( ) ) ) ,
445+ ( 65539 , custom_data, ( default_value, Vec :: new( ) ) )
435446 } ) ;
436447 let _padding: Option < utils:: Padding > = _padding;
437448
@@ -452,6 +463,7 @@ impl Readable for BlindedPaymentTlvs {
452463 payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
453464 payment_constraints : payment_constraints. 0 . unwrap ( ) ,
454465 payment_context : payment_context. 0 . unwrap ( ) ,
466+ custom_data : custom_data. 0 . unwrap ( ) ,
455467 } ) )
456468 }
457469 }
@@ -683,6 +695,7 @@ mod tests {
683695 htlc_minimum_msat : 1 ,
684696 } ,
685697 payment_context : PaymentContext :: unknown ( ) ,
698+ custom_data : Vec :: new ( ) ,
686699 } ;
687700 let htlc_maximum_msat = 100_000 ;
688701 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, 12 ) . unwrap ( ) ;
@@ -702,6 +715,7 @@ mod tests {
702715 htlc_minimum_msat : 1 ,
703716 } ,
704717 payment_context : PaymentContext :: unknown ( ) ,
718+ custom_data : Vec :: new ( ) ,
705719 } ;
706720 let blinded_payinfo = super :: compute_payinfo ( & [ ] , & recv_tlvs, 4242 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
707721 assert_eq ! ( blinded_payinfo. fee_base_msat, 0 ) ;
@@ -758,6 +772,7 @@ mod tests {
758772 htlc_minimum_msat : 3 ,
759773 } ,
760774 payment_context : PaymentContext :: unknown ( ) ,
775+ custom_data : Vec :: new ( ) ,
761776 } ;
762777 let htlc_maximum_msat = 100_000 ;
763778 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
@@ -811,6 +826,7 @@ mod tests {
811826 htlc_minimum_msat : 1 ,
812827 } ,
813828 payment_context : PaymentContext :: unknown ( ) ,
829+ custom_data : Vec :: new ( ) ,
814830 } ;
815831 let htlc_minimum_msat = 3798 ;
816832 assert ! ( super :: compute_payinfo( & intermediate_nodes[ ..] , & recv_tlvs, htlc_minimum_msat - 1 , TEST_FINAL_CLTV as u16 ) . is_err( ) ) ;
@@ -868,6 +884,7 @@ mod tests {
868884 htlc_minimum_msat : 1 ,
869885 } ,
870886 payment_context : PaymentContext :: unknown ( ) ,
887+ custom_data : Vec :: new ( )
871888 } ;
872889
873890 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, 10_000 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
0 commit comments