@@ -332,6 +332,82 @@ where
332332 )
333333}
334334
335+ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash < M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
336+ channelmanager : & ChannelManager < M , T , K , F , L > , keys_manager : K , logger : L ,
337+ network : Currency , amt_msat : Option < u64 > , description : String , duration_since_epoch : Duration ,
338+ invoice_expiry_delta_secs : u32 , payment_hash : PaymentHash , payment_secret : PaymentSecret
339+ ) -> Result < Invoice , SignOrCreationError < ( ) > >
340+ where
341+ M :: Target : chain:: Watch < <K :: Target as KeysInterface >:: Signer > ,
342+ T :: Target : BroadcasterInterface ,
343+ K :: Target : KeysInterface ,
344+ F :: Target : FeeEstimator ,
345+ L :: Target : Logger ,
346+ {
347+ _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash (
348+ channelmanager, keys_manager, logger, network, amt_msat,
349+ InvoiceDescription :: Direct (
350+ & Description :: new ( description) . map_err ( SignOrCreationError :: CreationError ) ?,
351+ ) ,
352+ duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret
353+ )
354+ }
355+
356+ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash < M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
357+ channelmanager : & ChannelManager < M , T , K , F , L > , keys_manager : K , logger : L ,
358+ network : Currency , amt_msat : Option < u64 > , description : InvoiceDescription , duration_since_epoch : Duration ,
359+ invoice_expiry_delta_secs : u32 , payment_hash : PaymentHash , payment_secret : PaymentSecret
360+ ) -> Result < Invoice , SignOrCreationError < ( ) > >
361+ where
362+ M :: Target : chain:: Watch < <K :: Target as KeysInterface >:: Signer > ,
363+ T :: Target : BroadcasterInterface ,
364+ K :: Target : KeysInterface ,
365+ F :: Target : FeeEstimator ,
366+ L :: Target : Logger ,
367+ {
368+ let our_node_pubkey = channelmanager. get_our_node_id ( ) ;
369+ let channels = channelmanager. list_channels ( ) ;
370+
371+ log_trace ! ( logger, "Creating invoice with payment hash {}" , log_bytes!( payment_hash. 0 ) ) ;
372+
373+ let invoice = match description {
374+ InvoiceDescription :: Direct ( description) => {
375+ InvoiceBuilder :: new ( network) . description ( description. 0 . clone ( ) )
376+ }
377+ InvoiceDescription :: Hash ( hash) => InvoiceBuilder :: new ( network) . description_hash ( hash. 0 ) ,
378+ } ;
379+
380+ let mut invoice = invoice
381+ . duration_since_epoch ( duration_since_epoch)
382+ . payee_pub_key ( our_node_pubkey)
383+ . payment_hash ( Hash :: from_slice ( & payment_hash. 0 ) . unwrap ( ) )
384+ . payment_secret ( payment_secret)
385+ . basic_mpp ( )
386+ . min_final_cltv_expiry ( MIN_FINAL_CLTV_EXPIRY . into ( ) )
387+ . expiry_time ( Duration :: from_secs ( invoice_expiry_delta_secs. into ( ) ) ) ;
388+ if let Some ( amt) = amt_msat {
389+ invoice = invoice. amount_milli_satoshis ( amt) ;
390+ }
391+
392+ let route_hints = filter_channels ( channels, amt_msat, & logger) ;
393+ for hint in route_hints {
394+ invoice = invoice. private_route ( hint) ;
395+ }
396+
397+ let raw_invoice = match invoice. build_raw ( ) {
398+ Ok ( inv) => inv,
399+ Err ( e) => return Err ( SignOrCreationError :: CreationError ( e) )
400+ } ;
401+ let hrp_str = raw_invoice. hrp . to_string ( ) ;
402+ let hrp_bytes = hrp_str. as_bytes ( ) ;
403+ let data_without_signature = raw_invoice. data . to_base32 ( ) ;
404+ let signed_raw_invoice = raw_invoice. sign ( |_| keys_manager. sign_invoice ( hrp_bytes, & data_without_signature, Recipient :: Node ) ) ;
405+ match signed_raw_invoice {
406+ Ok ( inv) => Ok ( Invoice :: from_signed ( inv) . unwrap ( ) ) ,
407+ Err ( e) => Err ( SignOrCreationError :: SignError ( e) )
408+ }
409+ }
410+
335411fn _create_invoice_from_channelmanager_and_duration_since_epoch < M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > (
336412 channelmanager : & ChannelManager < M , T , K , F , L > , keys_manager : K , logger : L ,
337413 network : Currency , amt_msat : Option < u64 > , description : InvoiceDescription ,
@@ -567,7 +643,7 @@ where
567643mod test {
568644 use core:: time:: Duration ;
569645 use crate :: { Currency , Description , InvoiceDescription } ;
570- use bitcoin_hashes:: Hash ;
646+ use bitcoin_hashes:: { Hash , sha256 } ;
571647 use bitcoin_hashes:: sha256:: Hash as Sha256 ;
572648 use lightning:: chain:: keysinterface:: PhantomKeysManager ;
573649 use lightning:: ln:: { PaymentPreimage , PaymentHash } ;
@@ -665,6 +741,26 @@ mod test {
665741 assert_eq ! ( invoice. description( ) , InvoiceDescription :: Hash ( & crate :: Sha256 ( Sha256 :: hash( "Testing description_hash" . as_bytes( ) ) ) ) ) ;
666742 }
667743
744+
745+ #[ test]
746+ fn test_create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash ( ) {
747+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
748+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
749+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
750+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
751+ let payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
752+ let payment_secret = & nodes[ 1 ] . node . create_inbound_payment_for_hash ( payment_hash, Some ( 10_000 ) , 3600 ) ;
753+ let invoice = crate :: utils:: create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash (
754+ & nodes[ 1 ] . node , nodes[ 1 ] . keys_manager , nodes[ 1 ] . logger , Currency :: BitcoinTestnet ,
755+ Some ( 10_000 ) , "test" . to_string ( ) , Duration :: from_secs ( 1234567 ) , 3600 ,
756+ payment_hash, payment_secret. unwrap ( )
757+ ) . unwrap ( ) ;
758+ assert_eq ! ( invoice. amount_pico_btc( ) , Some ( 100_000 ) ) ;
759+ assert_eq ! ( invoice. min_final_cltv_expiry( ) , MIN_FINAL_CLTV_EXPIRY as u64 ) ;
760+ assert_eq ! ( invoice. description( ) , InvoiceDescription :: Direct ( & Description ( "test" . to_string( ) ) ) ) ;
761+ assert_eq ! ( invoice. payment_hash( ) , & sha256:: Hash :: from_slice( & payment_hash. 0 [ ..] ) . unwrap( ) ) ;
762+ }
763+
668764 #[ test]
669765 fn test_hints_includes_single_channels_to_nodes ( ) {
670766 let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
0 commit comments