1
1
//! Convenient utilities to create an invoice.
2
2
3
- use { CreationError , Currency , DEFAULT_EXPIRY_TIME , Invoice , InvoiceBuilder , SignOrCreationError } ;
3
+ use { CreationError , Currency , Invoice , InvoiceBuilder , SignOrCreationError } ;
4
4
use payment:: { Payer , Router } ;
5
5
6
6
use crate :: { prelude:: * , Description , InvoiceDescription , Sha256 } ;
@@ -162,7 +162,8 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
162
162
. current_timestamp ( )
163
163
. payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
164
164
. payment_secret ( payment_secret)
165
- . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) ) ;
165
+ . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) )
166
+ . expiry_time ( Duration :: from_secs ( invoice_expiry_delta_secs. into ( ) ) ) ;
166
167
if let Some ( amt) = amt_msat {
167
168
invoice = invoice. amount_milli_satoshis ( amt) ;
168
169
}
@@ -212,9 +213,12 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
212
213
/// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user
213
214
/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
214
215
/// that the payment secret is valid when the invoice is paid.
216
+ ///
217
+ /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
218
+ /// in excess of the current time.
215
219
pub fn create_invoice_from_channelmanager < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
216
220
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
217
- amt_msat : Option < u64 > , description : String
221
+ amt_msat : Option < u64 > , description : String , invoice_expiry_delta_secs : u32
218
222
) -> Result < Invoice , SignOrCreationError < ( ) > >
219
223
where
220
224
M :: Target : chain:: Watch < Signer > ,
@@ -227,7 +231,8 @@ where
227
231
let duration = SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH )
228
232
. expect ( "for the foreseeable future this shouldn't happen" ) ;
229
233
create_invoice_from_channelmanager_and_duration_since_epoch (
230
- channelmanager, keys_manager, network, amt_msat, description, duration
234
+ channelmanager, keys_manager, network, amt_msat,
235
+ description, duration, invoice_expiry_delta_secs
231
236
)
232
237
}
233
238
@@ -238,9 +243,12 @@ where
238
243
/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
239
244
/// that the payment secret is valid when the invoice is paid.
240
245
/// Use this variant if you want to pass the `description_hash` to the invoice.
246
+ ///
247
+ /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
248
+ /// in excess of the current time.
241
249
pub fn create_invoice_from_channelmanager_with_description_hash < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
242
250
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
243
- amt_msat : Option < u64 > , description_hash : Sha256 ,
251
+ amt_msat : Option < u64 > , description_hash : Sha256 , invoice_expiry_delta_secs : u32
244
252
) -> Result < Invoice , SignOrCreationError < ( ) > >
245
253
where
246
254
M :: Target : chain:: Watch < Signer > ,
@@ -256,7 +264,8 @@ where
256
264
. expect ( "for the foreseeable future this shouldn't happen" ) ;
257
265
258
266
create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch (
259
- channelmanager, keys_manager, network, amt_msat, description_hash, duration,
267
+ channelmanager, keys_manager, network, amt_msat,
268
+ description_hash, duration, invoice_expiry_delta_secs
260
269
)
261
270
}
262
271
@@ -266,6 +275,7 @@ where
266
275
pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
267
276
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
268
277
amt_msat : Option < u64 > , description_hash : Sha256 , duration_since_epoch : Duration ,
278
+ invoice_expiry_delta_secs : u32
269
279
) -> Result < Invoice , SignOrCreationError < ( ) > >
270
280
where
271
281
M :: Target : chain:: Watch < Signer > ,
@@ -277,7 +287,7 @@ where
277
287
_create_invoice_from_channelmanager_and_duration_since_epoch (
278
288
channelmanager, keys_manager, network, amt_msat,
279
289
InvoiceDescription :: Hash ( & description_hash) ,
280
- duration_since_epoch,
290
+ duration_since_epoch, invoice_expiry_delta_secs
281
291
)
282
292
}
283
293
@@ -287,6 +297,7 @@ where
287
297
pub fn create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
288
298
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
289
299
amt_msat : Option < u64 > , description : String , duration_since_epoch : Duration ,
300
+ invoice_expiry_delta_secs : u32
290
301
) -> Result < Invoice , SignOrCreationError < ( ) > >
291
302
where
292
303
M :: Target : chain:: Watch < Signer > ,
@@ -300,13 +311,14 @@ where
300
311
InvoiceDescription :: Direct (
301
312
& Description :: new ( description) . map_err ( SignOrCreationError :: CreationError ) ?,
302
313
) ,
303
- duration_since_epoch,
314
+ duration_since_epoch, invoice_expiry_delta_secs
304
315
)
305
316
}
306
317
307
318
fn _create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
308
319
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
309
320
amt_msat : Option < u64 > , description : InvoiceDescription , duration_since_epoch : Duration ,
321
+ invoice_expiry_delta_secs : u32
310
322
) -> Result < Invoice , SignOrCreationError < ( ) > >
311
323
where
312
324
M :: Target : chain:: Watch < Signer > ,
@@ -320,7 +332,7 @@ where
320
332
// `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
321
333
// supply.
322
334
let ( payment_hash, payment_secret) = channelmanager
323
- . create_inbound_payment ( amt_msat, DEFAULT_EXPIRY_TIME . try_into ( ) . unwrap ( ) )
335
+ . create_inbound_payment ( amt_msat, invoice_expiry_delta_secs )
324
336
. map_err ( |( ) | SignOrCreationError :: CreationError ( CreationError :: InvalidAmount ) ) ?;
325
337
let our_node_pubkey = channelmanager. get_our_node_id ( ) ;
326
338
@@ -337,7 +349,8 @@ where
337
349
. payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
338
350
. payment_secret ( payment_secret)
339
351
. basic_mpp ( )
340
- . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) ) ;
352
+ . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) )
353
+ . expiry_time ( Duration :: from_secs ( invoice_expiry_delta_secs. into ( ) ) ) ;
341
354
if let Some ( amt) = amt_msat {
342
355
invoice = invoice. amount_milli_satoshis ( amt) ;
343
356
}
@@ -528,10 +541,11 @@ mod test {
528
541
create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100000 , 10001 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
529
542
let invoice = create_invoice_from_channelmanager_and_duration_since_epoch (
530
543
& nodes[ 1 ] . node , nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet , Some ( 10_000 ) , "test" . to_string ( ) ,
531
- Duration :: from_secs ( 1234567 ) ) . unwrap ( ) ;
544
+ Duration :: from_secs ( 1234567 ) , 3600 ) . unwrap ( ) ;
532
545
assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 100_000 ) ) ;
533
546
assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
534
547
assert_eq ! ( invoice. description( ) , InvoiceDescription :: Direct ( & Description ( "test" . to_string( ) ) ) ) ;
548
+ assert_eq ! ( invoice. expiry_time( ) , Duration :: from_secs( 3600 ) ) ;
535
549
536
550
// Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
537
551
// available.
@@ -592,7 +606,7 @@ mod test {
592
606
let description_hash = crate :: Sha256 ( Hash :: hash ( "Testing description_hash" . as_bytes ( ) ) ) ;
593
607
let invoice = :: utils:: create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch (
594
608
& nodes[ 1 ] . node , nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet , Some ( 10_000 ) ,
595
- description_hash, Duration :: from_secs ( 1234567 ) ,
609
+ description_hash, Duration :: from_secs ( 1234567 ) , 3600
596
610
) . unwrap ( ) ;
597
611
assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 100_000 ) ) ;
598
612
assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
@@ -752,7 +766,7 @@ mod test {
752
766
) {
753
767
let invoice = create_invoice_from_channelmanager_and_duration_since_epoch (
754
768
& invoice_node. node , invoice_node. keys_manager , Currency :: BitcoinTestnet , invoice_amt, "test" . to_string ( ) ,
755
- Duration :: from_secs ( 1234567 ) ) . unwrap ( ) ;
769
+ Duration :: from_secs ( 1234567 ) , 3600 ) . unwrap ( ) ;
756
770
let hints = invoice. private_routes ( ) ;
757
771
758
772
for hint in hints {
@@ -811,6 +825,7 @@ mod test {
811
825
assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
812
826
assert_eq ! ( invoice. description( ) , InvoiceDescription :: Direct ( & Description ( "test" . to_string( ) ) ) ) ;
813
827
assert_eq ! ( invoice. route_hints( ) . len( ) , 2 ) ;
828
+ assert_eq ! ( invoice. expiry_time( ) , Duration :: from_secs( 3600 ) ) ;
814
829
assert ! ( !invoice. features( ) . unwrap( ) . supports_basic_mpp( ) ) ;
815
830
816
831
let payment_params = PaymentParameters :: from_node_id ( invoice. recover_payee_pub_key ( ) )
@@ -931,10 +946,23 @@ mod test {
931
946
] ;
932
947
933
948
let description_hash = crate :: Sha256 ( Hash :: hash ( "Description hash phantom invoice" . as_bytes ( ) ) ) ;
934
- let invoice = :: utils:: create_phantom_invoice_with_description_hash :: < EnforcingSigner , & test_utils:: TestKeysInterface > ( Some ( payment_amt) , None , 3600 , description_hash, route_hints, & nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet ) . unwrap ( ) ;
935
-
949
+ let non_default_invoice_expiry_secs = 4200 ;
950
+ let invoice = :: utils:: create_phantom_invoice_with_description_hash :: <
951
+ EnforcingSigner ,
952
+ & test_utils:: TestKeysInterface ,
953
+ > (
954
+ Some ( payment_amt) ,
955
+ None ,
956
+ non_default_invoice_expiry_secs,
957
+ description_hash,
958
+ route_hints,
959
+ & nodes[ 1 ] . keys_manager ,
960
+ Currency :: BitcoinTestnet ,
961
+ )
962
+ . unwrap ( ) ;
936
963
assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 200_000 ) ) ;
937
964
assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
965
+ assert_eq ! ( invoice. expiry_time( ) , Duration :: from_secs( non_default_invoice_expiry_secs. into( ) ) ) ;
938
966
assert_eq ! ( invoice. description( ) , InvoiceDescription :: Hash ( & crate :: Sha256 ( Sha256 :: hash( "Description hash phantom invoice" . as_bytes( ) ) ) ) ) ;
939
967
}
940
968
0 commit comments