11//! Convenient utilities to create an invoice.
22
3- use { CreationError , Currency , DEFAULT_EXPIRY_TIME , Invoice , InvoiceBuilder , SignOrCreationError } ;
3+ use { CreationError , Currency , Invoice , InvoiceBuilder , SignOrCreationError } ;
44use payment:: { Payer , Router } ;
55
66use crate :: { prelude:: * , Description , InvoiceDescription , Sha256 } ;
@@ -20,7 +20,6 @@ use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
2020use lightning:: routing:: router:: { Route , RouteHint , RouteHintHop , RouteParameters , find_route} ;
2121use lightning:: util:: logger:: Logger ;
2222use secp256k1:: PublicKey ;
23- use core:: convert:: TryInto ;
2423use core:: ops:: Deref ;
2524use core:: time:: Duration ;
2625use sync:: Mutex ;
@@ -213,9 +212,12 @@ fn _create_phantom_invoice<Signer: Sign, K: Deref>(
213212/// method stores the invoice's payment secret and preimage in `ChannelManager`, so (a) the user
214213/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
215214/// 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.
216218pub fn create_invoice_from_channelmanager < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
217219 channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
218- amt_msat : Option < u64 > , description : String
220+ amt_msat : Option < u64 > , description : String , invoice_expiry_delta_secs : u32
219221) -> Result < Invoice , SignOrCreationError < ( ) > >
220222where
221223 M :: Target : chain:: Watch < Signer > ,
@@ -228,7 +230,8 @@ where
228230 let duration = SystemTime :: now ( ) . duration_since ( SystemTime :: UNIX_EPOCH )
229231 . expect ( "for the foreseeable future this shouldn't happen" ) ;
230232 create_invoice_from_channelmanager_and_duration_since_epoch (
231- channelmanager, keys_manager, network, amt_msat, description, duration
233+ channelmanager, keys_manager, network, amt_msat,
234+ description, duration, invoice_expiry_delta_secs
232235 )
233236}
234237
@@ -239,9 +242,12 @@ where
239242/// doesn't have to store preimage/payment secret information and (b) `ChannelManager` can verify
240243/// that the payment secret is valid when the invoice is paid.
241244/// 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.
242248pub fn create_invoice_from_channelmanager_with_description_hash < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
243249 channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
244- amt_msat : Option < u64 > , description_hash : Sha256 ,
250+ amt_msat : Option < u64 > , description_hash : Sha256 , invoice_expiry_delta_secs : u32
245251) -> Result < Invoice , SignOrCreationError < ( ) > >
246252where
247253 M :: Target : chain:: Watch < Signer > ,
@@ -257,7 +263,8 @@ where
257263 . expect ( "for the foreseeable future this shouldn't happen" ) ;
258264
259265 create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch (
260- channelmanager, keys_manager, network, amt_msat, description_hash, duration,
266+ channelmanager, keys_manager, network, amt_msat,
267+ description_hash, duration, invoice_expiry_delta_secs
261268 )
262269}
263270
@@ -267,6 +274,7 @@ where
267274pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
268275 channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
269276 amt_msat : Option < u64 > , description_hash : Sha256 , duration_since_epoch : Duration ,
277+ invoice_expiry_delta_secs : u32
270278) -> Result < Invoice , SignOrCreationError < ( ) > >
271279where
272280 M :: Target : chain:: Watch < Signer > ,
@@ -278,7 +286,7 @@ where
278286 _create_invoice_from_channelmanager_and_duration_since_epoch (
279287 channelmanager, keys_manager, network, amt_msat,
280288 InvoiceDescription :: Hash ( & description_hash) ,
281- duration_since_epoch,
289+ duration_since_epoch, invoice_expiry_delta_secs
282290 )
283291}
284292
@@ -288,6 +296,7 @@ where
288296pub fn create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
289297 channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
290298 amt_msat : Option < u64 > , description : String , duration_since_epoch : Duration ,
299+ invoice_expiry_delta_secs : u32
291300) -> Result < Invoice , SignOrCreationError < ( ) > >
292301where
293302 M :: Target : chain:: Watch < Signer > ,
@@ -301,13 +310,14 @@ where
301310 InvoiceDescription :: Direct (
302311 & Description :: new ( description) . map_err ( SignOrCreationError :: CreationError ) ?,
303312 ) ,
304- duration_since_epoch,
313+ duration_since_epoch, invoice_expiry_delta_secs
305314 )
306315}
307316
308317fn _create_invoice_from_channelmanager_and_duration_since_epoch < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
309318 channelmanager : & ChannelManager < Signer , M , T , K , F , L > , keys_manager : K , network : Currency ,
310319 amt_msat : Option < u64 > , description : InvoiceDescription , duration_since_epoch : Duration ,
320+ invoice_expiry_delta_secs : u32
311321) -> Result < Invoice , SignOrCreationError < ( ) > >
312322where
313323 M :: Target : chain:: Watch < Signer > ,
@@ -321,7 +331,7 @@ where
321331 // `create_inbound_payment` only returns an error if the amount is greater than the total bitcoin
322332 // supply.
323333 let ( payment_hash, payment_secret) = channelmanager
324- . create_inbound_payment ( amt_msat, DEFAULT_EXPIRY_TIME . try_into ( ) . unwrap ( ) )
334+ . create_inbound_payment ( amt_msat, invoice_expiry_delta_secs )
325335 . map_err ( |( ) | SignOrCreationError :: CreationError ( CreationError :: InvalidAmount ) ) ?;
326336 let our_node_pubkey = channelmanager. get_our_node_id ( ) ;
327337
@@ -338,7 +348,8 @@ where
338348 . payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
339349 . payment_secret ( payment_secret)
340350 . basic_mpp ( )
341- . 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 ( ) ) ) ;
342353 if let Some ( amt) = amt_msat {
343354 invoice = invoice. amount_milli_satoshis ( amt) ;
344355 }
@@ -527,12 +538,14 @@ mod test {
527538 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
528539 let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
529540 create_unannounced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 100000 , 10001 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
541+ let non_default_invoice_expiry_secs = 4200 ;
530542 let invoice = create_invoice_from_channelmanager_and_duration_since_epoch (
531543 & nodes[ 1 ] . node , nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet , Some ( 10_000 ) , "test" . to_string ( ) ,
532- Duration :: from_secs ( 1234567 ) ) . unwrap ( ) ;
544+ Duration :: from_secs ( 1234567 ) , non_default_invoice_expiry_secs ) . unwrap ( ) ;
533545 assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 100_000 ) ) ;
534546 assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
535547 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( ) ) ) ;
536549
537550 // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
538551 // available.
@@ -593,7 +606,7 @@ mod test {
593606 let description_hash = crate :: Sha256 ( Hash :: hash ( "Testing description_hash" . as_bytes ( ) ) ) ;
594607 let invoice = :: utils:: create_invoice_from_channelmanager_with_description_hash_and_duration_since_epoch (
595608 & nodes[ 1 ] . node , nodes[ 1 ] . keys_manager , Currency :: BitcoinTestnet , Some ( 10_000 ) ,
596- description_hash, Duration :: from_secs ( 1234567 ) ,
609+ description_hash, Duration :: from_secs ( 1234567 ) , 3600
597610 ) . unwrap ( ) ;
598611 assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 100_000 ) ) ;
599612 assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
@@ -753,7 +766,7 @@ mod test {
753766 ) {
754767 let invoice = create_invoice_from_channelmanager_and_duration_since_epoch (
755768 & invoice_node. node , invoice_node. keys_manager , Currency :: BitcoinTestnet , invoice_amt, "test" . to_string ( ) ,
756- Duration :: from_secs ( 1234567 ) ) . unwrap ( ) ;
769+ Duration :: from_secs ( 1234567 ) , 3600 ) . unwrap ( ) ;
757770 let hints = invoice. private_routes ( ) ;
758771
759772 for hint in hints {
0 commit comments