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 } ;
@@ -20,7 +20,6 @@ use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
20
20
use lightning:: routing:: router:: { Route , RouteHint , RouteHintHop , RouteParameters , find_route} ;
21
21
use lightning:: util:: logger:: Logger ;
22
22
use secp256k1:: PublicKey ;
23
- use core:: convert:: TryInto ;
24
23
use core:: ops:: Deref ;
25
24
use core:: time:: Duration ;
26
25
use sync:: Mutex ;
@@ -162,7 +161,8 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
162
161
. current_timestamp ( )
163
162
. payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
164
163
. payment_secret ( payment_secret)
165
- . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) ) ;
164
+ . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) )
165
+ . expiry_time ( Duration :: from_secs ( invoice_expiry_delta_secs. into ( ) ) ) ;
166
166
if let Some ( amt) = amt_msat {
167
167
invoice = invoice. amount_milli_satoshis ( amt) ;
168
168
}
@@ -212,9 +212,12 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
212
212
/// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user
213
213
/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
214
214
/// that the payment secret is valid when the invoice is paid.
215
+ ///
216
+ /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
217
+ /// in excess of the current time.
215
218
pub fn create_invoice_from_channelmanager < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
216
219
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
217
- amt_msat : Option < u64 > , description : String
220
+ amt_msat : Option < u64 > , description : String , invoice_expiry_delta_secs : u32
218
221
) -> Result < Invoice , SignOrCreationError < ( ) > >
219
222
where
220
223
M :: Target : chain:: Watch < Signer > ,
@@ -227,7 +230,8 @@ where
227
230
let duration = SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH )
228
231
. expect ( "for the foreseeable future this shouldn't happen" ) ;
229
232
create_invoice_from_channelmanager_and_duration_since_epoch (
230
- channelmanager, keys_manager, network, amt_msat, description, duration
233
+ channelmanager, keys_manager, network, amt_msat,
234
+ description, duration, invoice_expiry_delta_secs
231
235
)
232
236
}
233
237
@@ -238,9 +242,12 @@ where
238
242
/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
239
243
/// that the payment secret is valid when the invoice is paid.
240
244
/// Use this variant if you want to pass the `description_hash` to the invoice.
245
+ ///
246
+ /// `invoice_expiry_delta_secs` describes the number of seconds that the invoice is valid for
247
+ /// in excess of the current time.
241
248
pub fn create_invoice_from_channelmanager_with_description_hash < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
242
249
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
243
- amt_msat : Option < u64 > , description_hash : Sha256 ,
250
+ amt_msat : Option < u64 > , description_hash : Sha256 , invoice_expiry_delta_secs : u32
244
251
) -> Result < Invoice , SignOrCreationError < ( ) > >
245
252
where
246
253
M :: Target : chain:: Watch < Signer > ,
@@ -256,7 +263,8 @@ where
256
263
. expect ( "for the foreseeable future this shouldn't happen" ) ;
257
264
258
265
create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch (
259
- channelmanager, keys_manager, network, amt_msat, description_hash, duration,
266
+ channelmanager, keys_manager, network, amt_msat,
267
+ description_hash, duration, invoice_expiry_delta_secs
260
268
)
261
269
}
262
270
@@ -266,6 +274,7 @@ where
266
274
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
275
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
268
276
amt_msat : Option < u64 > , description_hash : Sha256 , duration_since_epoch : Duration ,
277
+ invoice_expiry_delta_secs : u32
269
278
) -> Result < Invoice , SignOrCreationError < ( ) > >
270
279
where
271
280
M :: Target : chain:: Watch < Signer > ,
@@ -277,7 +286,7 @@ where
277
286
_create_invoice_from_channelmanager_and_duration_since_epoch (
278
287
channelmanager, keys_manager, network, amt_msat,
279
288
InvoiceDescription :: Hash ( & description_hash) ,
280
- duration_since_epoch,
289
+ duration_since_epoch, invoice_expiry_delta_secs
281
290
)
282
291
}
283
292
@@ -287,6 +296,7 @@ where
287
296
pub fn create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
288
297
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
289
298
amt_msat : Option < u64 > , description : String , duration_since_epoch : Duration ,
299
+ invoice_expiry_delta_secs : u32
290
300
) -> Result < Invoice , SignOrCreationError < ( ) > >
291
301
where
292
302
M :: Target : chain:: Watch < Signer > ,
@@ -300,13 +310,14 @@ where
300
310
InvoiceDescription :: Direct (
301
311
& Description :: new ( description) . map_err ( SignOrCreationError :: CreationError ) ?,
302
312
) ,
303
- duration_since_epoch,
313
+ duration_since_epoch, invoice_expiry_delta_secs
304
314
)
305
315
}
306
316
307
317
fn _create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
308
318
channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
309
319
amt_msat : Option < u64 > , description : InvoiceDescription , duration_since_epoch : Duration ,
320
+ invoice_expiry_delta_secs : u32
310
321
) -> Result < Invoice , SignOrCreationError < ( ) > >
311
322
where
312
323
M :: Target : chain:: Watch < Signer > ,
@@ -320,7 +331,7 @@ where
320
331
// `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
321
332
// supply.
322
333
let ( payment_hash, payment_secret) = channelmanager
323
- . create_inbound_payment ( amt_msat, DEFAULT_EXPIRY_TIME . try_into ( ) . unwrap ( ) )
334
+ . create_inbound_payment ( amt_msat, invoice_expiry_delta_secs )
324
335
. map_err ( |( ) | SignOrCreationError :: CreationError ( CreationError :: InvalidAmount ) ) ?;
325
336
let our_node_pubkey = channelmanager. get_our_node_id ( ) ;
326
337
@@ -337,7 +348,8 @@ where
337
348
. payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
338
349
. payment_secret ( payment_secret)
339
350
. basic_mpp ( )
340
- . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) ) ;
351
+ . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) )
352
+ . expiry_time ( Duration :: from_secs ( invoice_expiry_delta_secs. into ( ) ) ) ;
341
353
if let Some ( amt) = amt_msat {
342
354
invoice = invoice. amount_milli_satoshis ( amt) ;
343
355
}
@@ -526,12 +538,14 @@ mod test {
526
538
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
527
539
let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
528
540
create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100000 , 10001 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
541
+ let non_default_invoice_expiry_secs = 4200 ;
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 ) , non_default_invoice_expiry_secs ) . 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( non_default_invoice_expiry_secs. into( ) ) ) ;
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 {
@@ -799,8 +813,14 @@ mod test {
799
813
} else {
800
814
None
801
815
} ;
816
+ let non_default_invoice_expiry_secs = 4200 ;
802
817
803
- let invoice = :: utils:: create_phantom_invoice :: < EnforcingSigner , & test_utils:: TestKeysInterface > ( Some ( payment_amt) , payment_hash, "test" . to_string ( ) , 3600 , route_hints, & nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet ) . unwrap ( ) ;
818
+ let invoice = :: utils:: create_phantom_invoice :: <
819
+ EnforcingSigner , & test_utils:: TestKeysInterface
820
+ > (
821
+ Some ( payment_amt) , payment_hash, "test" . to_string ( ) , non_default_invoice_expiry_secs,
822
+ route_hints, & nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet
823
+ ) . unwrap ( ) ;
804
824
let ( payment_hash, payment_secret) = ( PaymentHash ( invoice. payment_hash ( ) . into_inner ( ) ) , * invoice. payment_secret ( ) ) ;
805
825
let payment_preimage = if user_generated_pmt_hash {
806
826
user_payment_preimage
@@ -811,6 +831,7 @@ mod test {
811
831
assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
812
832
assert_eq ! ( invoice. description( ) , InvoiceDescription :: Direct ( & Description ( "test" . to_string( ) ) ) ) ;
813
833
assert_eq ! ( invoice. route_hints( ) . len( ) , 2 ) ;
834
+ assert_eq ! ( invoice. expiry_time( ) , Duration :: from_secs( non_default_invoice_expiry_secs. into( ) ) ) ;
814
835
assert ! ( !invoice. features( ) . unwrap( ) . supports_basic_mpp( ) ) ;
815
836
816
837
let payment_params = PaymentParameters :: from_node_id ( invoice. recover_payee_pub_key ( ) )
@@ -931,10 +952,17 @@ mod test {
931
952
] ;
932
953
933
954
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
-
955
+ let non_default_invoice_expiry_secs = 4200 ;
956
+ let invoice = :: utils:: create_phantom_invoice_with_description_hash :: <
957
+ EnforcingSigner , & test_utils:: TestKeysInterface ,
958
+ > (
959
+ Some ( payment_amt) , None , non_default_invoice_expiry_secs, description_hash,
960
+ route_hints, & nodes[ 1 ] . keys_manager , 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