@@ -283,6 +283,15 @@ pub struct UnauthenticatedReceiveTlvs {
283283 pub payment_constraints : PaymentConstraints ,
284284 /// Context for the receiver of this payment.
285285 pub payment_context : PaymentContext ,
286+ /// Custom data set by the user. And is returned back when the blinded path is used.
287+ ///
288+ /// ## Note on Forward Compatibility:
289+ /// Users can encode any kind of data into the `Vec<u8>` bytes here. However, they should ensure
290+ /// that the data is structured in a forward-compatible manner. This is especially important as
291+ /// `ReceiveTlvs` created in one version of the software may still appear in payments received
292+ /// shortly after a software upgrade. Proper forward compatibility helps prevent data loss or
293+ /// misinterpretation in future versions.
294+ pub custom_data : Vec < u8 > ,
286295}
287296
288297impl UnauthenticatedReceiveTlvs {
@@ -444,6 +453,7 @@ impl Writeable for ReceiveTlvs {
444453 ( 65536 , self . tlvs. payment_secret, required) ,
445454 ( 65537 , self . tlvs. payment_context, required) ,
446455 ( 65539 , self . authentication, required) ,
456+ ( 65541 , self . tlvs. custom_data, required)
447457 } ) ;
448458 Ok ( ( ) )
449459 }
@@ -455,6 +465,7 @@ impl Writeable for UnauthenticatedReceiveTlvs {
455465 ( 12 , self . payment_constraints, required) ,
456466 ( 65536 , self . payment_secret, required) ,
457467 ( 65537 , self . payment_context, required) ,
468+ ( 65541 , self . custom_data, ( default_value, Vec :: new( ) ) ) ,
458469 } ) ;
459470 Ok ( ( ) )
460471 }
@@ -483,6 +494,7 @@ impl Readable for BlindedPaymentTlvs {
483494 ( 65536 , payment_secret, option) ,
484495 ( 65537 , payment_context, option) ,
485496 ( 65539 , authentication, option) ,
497+ ( 65541 , custom_data, ( default_value, Vec :: new( ) ) )
486498 } ) ;
487499 let _padding: Option < utils:: Padding > = _padding;
488500
@@ -504,6 +516,7 @@ impl Readable for BlindedPaymentTlvs {
504516 payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
505517 payment_constraints : payment_constraints. 0 . unwrap ( ) ,
506518 payment_context : payment_context. ok_or ( DecodeError :: InvalidValue ) ?,
519+ custom_data : custom_data. 0 . unwrap ( ) ,
507520 } ,
508521 authentication : authentication. ok_or ( DecodeError :: InvalidValue ) ?,
509522 } ) )
@@ -730,6 +743,7 @@ mod tests {
730743 htlc_minimum_msat : 1 ,
731744 } ,
732745 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
746+ custom_data : Vec :: new ( ) ,
733747 } ;
734748 let htlc_maximum_msat = 100_000 ;
735749 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, 12 ) . unwrap ( ) ;
@@ -749,6 +763,7 @@ mod tests {
749763 htlc_minimum_msat : 1 ,
750764 } ,
751765 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
766+ custom_data : Vec :: new ( ) ,
752767 } ;
753768 let blinded_payinfo = super :: compute_payinfo ( & [ ] , & recv_tlvs, 4242 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
754769 assert_eq ! ( blinded_payinfo. fee_base_msat, 0 ) ;
@@ -805,6 +820,7 @@ mod tests {
805820 htlc_minimum_msat : 3 ,
806821 } ,
807822 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
823+ custom_data : Vec :: new ( ) ,
808824 } ;
809825 let htlc_maximum_msat = 100_000 ;
810826 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
@@ -858,6 +874,7 @@ mod tests {
858874 htlc_minimum_msat : 1 ,
859875 } ,
860876 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
877+ custom_data : Vec :: new ( ) ,
861878 } ;
862879 let htlc_minimum_msat = 3798 ;
863880 assert ! ( super :: compute_payinfo( & intermediate_nodes[ ..] , & recv_tlvs, htlc_minimum_msat - 1 , TEST_FINAL_CLTV as u16 ) . is_err( ) ) ;
@@ -915,6 +932,7 @@ mod tests {
915932 htlc_minimum_msat : 1 ,
916933 } ,
917934 payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
935+ custom_data : Vec :: new ( ) ,
918936 } ;
919937
920938 let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, 10_000 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
0 commit comments