@@ -36,16 +36,19 @@ pub use event::LdkLiteEvent;
36
36
use event:: LdkLiteEventHandler ;
37
37
38
38
#[ allow( unused_imports) ]
39
- use logger:: { Logger , FilesystemLogger , log_info, log_error, log_warn, log_trace, log_given_level, log_internal} ;
39
+ use logger:: {
40
+ log_error, log_given_level, log_info, log_internal, log_trace, log_warn, FilesystemLogger ,
41
+ Logger ,
42
+ } ;
40
43
41
44
use lightning:: chain:: keysinterface:: { InMemorySigner , KeysInterface , KeysManager , Recipient } ;
42
45
use lightning:: chain:: { chainmonitor, Access , BestBlock , Confirm , Filter , Watch } ;
43
46
use lightning:: ln:: channelmanager;
44
47
use lightning:: ln:: channelmanager:: {
45
- ChainParameters , ChannelManagerReadArgs , PaymentId , SimpleArcChannelManager ,
48
+ ChainParameters , ChannelManagerReadArgs , SimpleArcChannelManager ,
46
49
} ;
47
50
use lightning:: ln:: peer_handler:: { IgnoringMessageHandler , MessageHandler , SimpleArcPeerManager } ;
48
- use lightning:: ln:: { PaymentHash , PaymentPreimage } ;
51
+ use lightning:: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
49
52
use lightning:: routing:: gossip;
50
53
use lightning:: routing:: gossip:: P2PGossipSync ;
51
54
use lightning:: routing:: scoring:: ProbabilisticScorer ;
@@ -66,6 +69,8 @@ use bdk::blockchain::esplora::EsploraBlockchain;
66
69
use bdk:: blockchain:: { GetBlockHash , GetHeight } ;
67
70
use bdk:: database:: MemoryDatabase ;
68
71
72
+ use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
73
+ use bitcoin:: hashes:: Hash ;
69
74
use bitcoin:: secp256k1:: PublicKey ;
70
75
use bitcoin:: BlockHash ;
71
76
@@ -306,8 +311,8 @@ impl LdkLiteBuilder {
306
311
307
312
// Step 13: Init payment info storage
308
313
// TODO: persist payment info to disk
309
- let _inbound_payments = Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
310
- let _outbound_payments = Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
314
+ let inbound_payments = Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
315
+ let outbound_payments = Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ;
311
316
312
317
// Step 14: Handle LDK Events
313
318
let event_queue = mpsc:: sync_channel ( CHANNEL_BUF_SIZE ) ;
@@ -317,8 +322,8 @@ impl LdkLiteBuilder {
317
322
Arc :: clone ( & channel_manager) ,
318
323
Arc :: clone ( & network_graph) ,
319
324
Arc :: clone ( & keys_manager) ,
320
- Arc :: clone ( & _inbound_payments ) ,
321
- Arc :: clone ( & _outbound_payments ) ,
325
+ Arc :: clone ( & inbound_payments ) ,
326
+ Arc :: clone ( & outbound_payments ) ,
322
327
event_sender,
323
328
Arc :: clone ( & logger) ,
324
329
Arc :: clone ( & config) ,
@@ -356,8 +361,8 @@ impl LdkLiteBuilder {
356
361
network_graph,
357
362
scorer,
358
363
invoice_payer,
359
- _inbound_payments ,
360
- _outbound_payments ,
364
+ inbound_payments ,
365
+ outbound_payments ,
361
366
event_queue,
362
367
} )
363
368
}
@@ -389,8 +394,8 @@ pub struct LdkLite {
389
394
scorer : Arc < Mutex < Scorer > > ,
390
395
network_graph : Arc < NetworkGraph > ,
391
396
invoice_payer : Arc < InvoicePayer < LdkLiteEventHandler > > ,
392
- _inbound_payments : Arc < PaymentInfoStorage > ,
393
- _outbound_payments : Arc < PaymentInfoStorage > ,
397
+ inbound_payments : Arc < PaymentInfoStorage > ,
398
+ outbound_payments : Arc < PaymentInfoStorage > ,
394
399
event_queue : ( EventSender , EventReceiver ) ,
395
400
}
396
401
@@ -575,12 +580,13 @@ impl LdkLite {
575
580
576
581
/// Retrieve a new on-chain/funding address.
577
582
pub fn new_funding_address ( & mut self ) -> Result < bitcoin:: Address , Error > {
578
- // TODO: log
579
583
if self . running . read ( ) . unwrap ( ) . is_none ( ) {
580
584
return Err ( Error :: NotRunning ) ;
581
585
}
582
586
583
- self . chain_access . get_new_address ( )
587
+ let funding_address = self . chain_access . get_new_address ( ) ?;
588
+ log_info ! ( self . logger, "generated new funding address: {}" , funding_address) ;
589
+ Ok ( funding_address)
584
590
}
585
591
586
592
// Connect to a node and open a new channel. Disconnects and re-connects should be handled automatically
@@ -590,40 +596,120 @@ impl LdkLite {
590
596
// pub close_channel(&mut self, channel_id: u64) -> Result<()>;
591
597
//
592
598
/// Send a payement given an invoice.
593
- pub fn send_payment ( & self , invoice : Invoice ) -> Result < PaymentId , Error > {
599
+ pub fn send_payment ( & self , invoice : Invoice ) -> Result < PaymentHash , Error > {
594
600
if self . running . read ( ) . unwrap ( ) . is_none ( ) {
595
601
return Err ( Error :: NotRunning ) ;
596
602
}
603
+
597
604
// TODO: ensure we never tried paying the given payment hash before
598
- // TODO: log
599
- Ok ( self . invoice_payer . pay_invoice ( & invoice) ?)
605
+ let status = match self . invoice_payer . pay_invoice ( & invoice) {
606
+ Ok ( _payment_id) => {
607
+ let payee_pubkey = invoice. recover_payee_pub_key ( ) ;
608
+ // TODO: is this unwrap safe? Would a payment to an invoice with None amount ever
609
+ // succeed?
610
+ let amt_msat = invoice. amount_milli_satoshis ( ) . unwrap ( ) ;
611
+ log_info ! ( self . logger, "initiated sending {} msats to {}" , amt_msat, payee_pubkey) ;
612
+ PaymentStatus :: Pending
613
+ }
614
+ Err ( payment:: PaymentError :: Invoice ( e) ) => {
615
+ log_error ! ( self . logger, "invalid invoice: {}" , e) ;
616
+ return Err ( Error :: Payment ( payment:: PaymentError :: Invoice ( e) ) ) ;
617
+ }
618
+ Err ( payment:: PaymentError :: Routing ( e) ) => {
619
+ log_error ! ( self . logger, "failed to find route: {}" , e. err) ;
620
+ return Err ( Error :: Payment ( payment:: PaymentError :: Routing ( e) ) ) ;
621
+ }
622
+ Err ( payment:: PaymentError :: Sending ( e) ) => {
623
+ log_error ! ( self . logger, "failed to send payment: {:?}" , e) ;
624
+ PaymentStatus :: Failed
625
+ }
626
+ } ;
627
+
628
+ let payment_hash = PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ;
629
+ let payment_secret = Some ( invoice. payment_secret ( ) . clone ( ) ) ;
630
+
631
+ let mut outbound_payments_lock = self . outbound_payments . lock ( ) . unwrap ( ) ;
632
+ outbound_payments_lock. insert (
633
+ payment_hash,
634
+ PaymentInfo {
635
+ preimage : None ,
636
+ secret : payment_secret,
637
+ status,
638
+ amount_msat : invoice. amount_milli_satoshis ( ) ,
639
+ } ,
640
+ ) ;
641
+
642
+ Ok ( payment_hash)
600
643
}
601
644
602
645
/// Send a spontaneous, aka. "keysend", payment
603
646
pub fn send_spontaneous_payment (
604
647
& self , amount_msat : u64 , node_id : PublicKey ,
605
- ) -> Result < PaymentId , Error > {
648
+ ) -> Result < PaymentHash , Error > {
606
649
if self . running . read ( ) . unwrap ( ) . is_none ( ) {
607
650
return Err ( Error :: NotRunning ) ;
608
651
}
609
- // TODO: log
652
+
610
653
let payment_preimage = PaymentPreimage ( self . keys_manager . get_secure_random_bytes ( ) ) ;
611
- Ok ( self . invoice_payer . pay_pubkey (
654
+ let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
655
+
656
+ let status = match self . invoice_payer . pay_pubkey (
612
657
node_id,
613
658
payment_preimage,
614
659
amount_msat,
615
660
self . config . default_cltv_expiry_delta ,
616
- ) ?)
661
+ ) {
662
+ Ok ( _payment_id) => {
663
+ log_info ! ( self . logger, "initiated sending {} msats to {}" , amount_msat, node_id) ;
664
+ PaymentStatus :: Pending
665
+ }
666
+ Err ( payment:: PaymentError :: Invoice ( e) ) => {
667
+ log_error ! ( self . logger, "invalid invoice: {}" , e) ;
668
+ return Err ( Error :: Payment ( payment:: PaymentError :: Invoice ( e) ) ) ;
669
+ }
670
+ Err ( payment:: PaymentError :: Routing ( e) ) => {
671
+ log_error ! ( self . logger, "failed to find route: {}" , e. err) ;
672
+ return Err ( Error :: Payment ( payment:: PaymentError :: Routing ( e) ) ) ;
673
+ }
674
+ Err ( payment:: PaymentError :: Sending ( e) ) => {
675
+ log_error ! ( self . logger, "failed to send payment: {:?}" , e) ;
676
+ PaymentStatus :: Failed
677
+ }
678
+ } ;
679
+
680
+ let mut outbound_payments_lock = self . outbound_payments . lock ( ) . unwrap ( ) ;
681
+ outbound_payments_lock. insert (
682
+ payment_hash,
683
+ PaymentInfo { preimage : None , secret : None , status, amount_msat : Some ( amount_msat) } ,
684
+ ) ;
685
+
686
+ Ok ( payment_hash)
617
687
}
618
688
//
619
689
// // Create an invoice to receive a payment
620
690
// pub receive_payment(&mut self, amount: Option<u64>) -> Invoice;
621
691
//
622
- // // Get a new on-chain/funding address.
623
- // pub new_funding_address(&mut self) -> Address;
624
- //
625
- // // Query for information about payment status.
626
- // pub payment_info(&mut self) -> PaymentInfo;
692
+ /// Query for information about the status of a specific payment.
693
+ pub fn payment_info ( & mut self , payment_hash : & [ u8 ; 32 ] ) -> Option < PaymentInfo > {
694
+ let payment_hash = PaymentHash ( * payment_hash) ;
695
+
696
+ {
697
+ let outbound_payments_lock = self . outbound_payments . lock ( ) . unwrap ( ) ;
698
+ if let Some ( payment_info) = outbound_payments_lock. get ( & payment_hash) {
699
+ return Some ( ( * payment_info) . clone ( ) ) ;
700
+ }
701
+ }
702
+
703
+ {
704
+ let inbound_payments_lock = self . inbound_payments . lock ( ) . unwrap ( ) ;
705
+ if let Some ( payment_info) = inbound_payments_lock. get ( & payment_hash) {
706
+ return Some ( ( * payment_info) . clone ( ) ) ;
707
+ }
708
+ }
709
+
710
+ None
711
+ }
712
+
627
713
//
628
714
// // Query for information about our channels
629
715
// pub channel_info(&mut self) -> ChannelInfo;
@@ -680,7 +766,30 @@ async fn do_connect_peer(
680
766
// Structs wrapping the particular information which should easily be
681
767
// understandable, parseable, and transformable, i.e., we'll try to avoid
682
768
// exposing too many technical detail here.
683
- struct PaymentInfo ;
769
+ /// Represents a payment.
770
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
771
+ pub struct PaymentInfo {
772
+ /// The pre-image used by the payment.
773
+ pub preimage : Option < PaymentPreimage > ,
774
+ /// The secret used by the payment.
775
+ pub secret : Option < PaymentSecret > ,
776
+ /// The status of the payment.
777
+ pub status : PaymentStatus ,
778
+ /// The amount transferred.
779
+ pub amount_msat : Option < u64 > ,
780
+ }
781
+
782
+ /// Represents the current status of a payment.
783
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
784
+ pub enum PaymentStatus {
785
+ /// The payment is still pending.
786
+ Pending ,
787
+ /// The payment suceeded.
788
+ Succeeded ,
789
+ /// The payment failed.
790
+ Failed ,
791
+ }
792
+
684
793
//struct ChannelInfo;
685
794
//struct FundingInfo;
686
795
0 commit comments