@@ -260,6 +260,15 @@ pub struct ReceiveTlvs {
260
260
pub payment_constraints : PaymentConstraints ,
261
261
/// Context for the receiver of this payment.
262
262
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 > ,
263
272
}
264
273
265
274
/// Data to construct a [`BlindedHop`] for sending a payment over.
@@ -404,7 +413,8 @@ impl Writeable for ReceiveTlvs {
404
413
encode_tlv_stream ! ( w, {
405
414
( 12 , self . payment_constraints, required) ,
406
415
( 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( ) ) ) ,
408
418
} ) ;
409
419
Ok ( ( ) )
410
420
}
@@ -432,6 +442,7 @@ impl Readable for BlindedPaymentTlvs {
432
442
( 14 , features, ( option, encoding: ( BlindedHopFeatures , WithoutLength ) ) ) ,
433
443
( 65536 , payment_secret, option) ,
434
444
( 65537 , payment_context, ( default_value, PaymentContext :: unknown( ) ) ) ,
445
+ ( 65539 , custom_data, ( default_value, Vec :: new( ) ) )
435
446
} ) ;
436
447
let _padding: Option < utils:: Padding > = _padding;
437
448
@@ -452,6 +463,7 @@ impl Readable for BlindedPaymentTlvs {
452
463
payment_secret : payment_secret. ok_or ( DecodeError :: InvalidValue ) ?,
453
464
payment_constraints : payment_constraints. 0 . unwrap ( ) ,
454
465
payment_context : payment_context. 0 . unwrap ( ) ,
466
+ custom_data : custom_data. 0 . unwrap ( ) ,
455
467
} ) )
456
468
}
457
469
}
@@ -683,6 +695,7 @@ mod tests {
683
695
htlc_minimum_msat : 1 ,
684
696
} ,
685
697
payment_context : PaymentContext :: unknown ( ) ,
698
+ custom_data : Vec :: new ( ) ,
686
699
} ;
687
700
let htlc_maximum_msat = 100_000 ;
688
701
let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, htlc_maximum_msat, 12 ) . unwrap ( ) ;
@@ -702,6 +715,7 @@ mod tests {
702
715
htlc_minimum_msat : 1 ,
703
716
} ,
704
717
payment_context : PaymentContext :: unknown ( ) ,
718
+ custom_data : Vec :: new ( ) ,
705
719
} ;
706
720
let blinded_payinfo = super :: compute_payinfo ( & [ ] , & recv_tlvs, 4242 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
707
721
assert_eq ! ( blinded_payinfo. fee_base_msat, 0 ) ;
@@ -758,6 +772,7 @@ mod tests {
758
772
htlc_minimum_msat : 3 ,
759
773
} ,
760
774
payment_context : PaymentContext :: unknown ( ) ,
775
+ custom_data : Vec :: new ( ) ,
761
776
} ;
762
777
let htlc_maximum_msat = 100_000 ;
763
778
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 {
811
826
htlc_minimum_msat : 1 ,
812
827
} ,
813
828
payment_context : PaymentContext :: unknown ( ) ,
829
+ custom_data : Vec :: new ( ) ,
814
830
} ;
815
831
let htlc_minimum_msat = 3798 ;
816
832
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 {
868
884
htlc_minimum_msat : 1 ,
869
885
} ,
870
886
payment_context : PaymentContext :: unknown ( ) ,
887
+ custom_data : Vec :: new ( ) ,
871
888
} ;
872
889
873
890
let blinded_payinfo = super :: compute_payinfo ( & intermediate_nodes[ ..] , & recv_tlvs, 10_000 , TEST_FINAL_CLTV as u16 ) . unwrap ( ) ;
0 commit comments