@@ -44,6 +44,7 @@ use crate::io::{
4444 EVENT_QUEUE_PERSISTENCE_KEY , EVENT_QUEUE_PERSISTENCE_PRIMARY_NAMESPACE ,
4545 EVENT_QUEUE_PERSISTENCE_SECONDARY_NAMESPACE ,
4646} ;
47+ use crate :: liquidity:: service:: lsps1:: { PendingLSPS1Channel , PendingLSPS1Order } ;
4748use crate :: liquidity:: LiquiditySource ;
4849use crate :: logger:: { log_debug, log_error, log_info, log_trace, LdkLogger , Logger } ;
4950use crate :: payment:: asynchronous:: om_mailbox:: OnionMessageMailbox ;
@@ -724,6 +725,124 @@ where
724725 counterparty_skimmed_fee_msat,
725726 ..
726727 } => {
728+ // We intercept early and check if the payment was an LSPS1
729+ // order payment and handle properly.
730+ if let Ok ( bytes) = self . event_queue . kv_store . read (
731+ "lsps1_pending_orders" ,
732+ "" ,
733+ & payment_hash. 0 . to_string ( ) ,
734+ ) {
735+ if let Ok ( pending_order) = PendingLSPS1Order :: read ( & mut & bytes[ ..] ) {
736+ let ( payment_preimage, payment_method) = match purpose {
737+ PaymentPurpose :: Bolt11InvoicePayment { payment_preimage, .. } => (
738+ payment_preimage,
739+ lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt11 ,
740+ ) ,
741+ PaymentPurpose :: Bolt12OfferPayment { payment_preimage, .. } => (
742+ payment_preimage,
743+ lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt12 ,
744+ ) ,
745+ _ => ( None , lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt11 ) ,
746+ } ;
747+
748+ if let Some ( preimage) = payment_preimage {
749+ let expected_msat =
750+ pending_order. order_total_amount_sat . saturating_mul ( 1000 ) ;
751+
752+ if amount_msat < expected_msat {
753+ log_error ! (
754+ self . logger,
755+ "Refused LSPS1 payment: underpaid. Expected {} msat, received {} msat." ,
756+ expected_msat,
757+ amount_msat
758+ ) ;
759+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
760+ return Ok ( ( ) ) ;
761+ }
762+
763+ self . runtime . block_on ( async {
764+ self . liquidity_source
765+ . lsps1_service ( )
766+ . handle_order_payment_received (
767+ pending_order. counterparty_node_id ,
768+ pending_order. request_id . into ( ) ,
769+ payment_method,
770+ )
771+ . await
772+ } ) ;
773+
774+ self . channel_manager . claim_funds ( preimage) ;
775+
776+ let mut config = self . channel_manager . get_current_config ( ) ;
777+
778+ // We set the forwarding fee to 0 for now as we're getting paid by the channel fee.
779+ config. channel_config . forwarding_fee_base_msat = 0 ;
780+
781+ let channel_size_sat = pending_order. order_params . lsp_balance_sat
782+ + pending_order. order_params . client_balance_sat ;
783+
784+ let push_msat =
785+ pending_order. order_params . client_balance_sat . saturating_mul ( 1000 ) ;
786+
787+ let user_channel_id: u128 = u128:: from_ne_bytes (
788+ self . keys_manager . get_secure_random_bytes ( ) [ ..16 ]
789+ . try_into ( )
790+ . expect ( "slice is exactly 16 bytes" ) ,
791+ ) ;
792+
793+ let pending_channel = PendingLSPS1Channel {
794+ order_id : pending_order. request_id . into ( ) . clone ( ) ,
795+ channel_expiry_blocks : pending_order
796+ . order_params
797+ . channel_expiry_blocks ,
798+ } ;
799+
800+ let _ = self . event_queue . kv_store . write (
801+ "lsps1_pending_channels" ,
802+ "" ,
803+ & user_channel_id. to_string ( ) ,
804+ pending_channel. encode ( ) ,
805+ ) ;
806+
807+ if let Err ( e) = self . channel_manager . create_channel (
808+ pending_order. counterparty_node_id ,
809+ channel_size_sat,
810+ push_msat,
811+ user_channel_id,
812+ None ,
813+ Some ( config) ,
814+ ) {
815+ log_error ! (
816+ self . logger,
817+ "Failed to open LSPS1 channel after claiming funds: {:?}" ,
818+ e
819+ ) ;
820+ self . liquidity_source
821+ . lsps1_service ( )
822+ . handle_order_failed_and_refunded (
823+ pending_order. counterparty_node_id ,
824+ pending_order. request_id . into ( ) ,
825+ )
826+ . await
827+ }
828+
829+ let _ = self . event_queue . kv_store . remove (
830+ "lsps1_pending_orders" ,
831+ "" ,
832+ & payment_hash. 0 . to_string ( ) ,
833+ false ,
834+ ) ;
835+ } else {
836+ log_error ! (
837+ self . logger,
838+ "Failed to claim LSPS1 payment: preimage unknown or unsupported payment purpose."
839+ ) ;
840+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
841+ }
842+ return Ok ( ( ) ) ;
843+ }
844+ }
845+
727846 let payment_id = PaymentId ( payment_hash. 0 ) ;
728847 let payment_info = self . payment_store . get ( & payment_id) ;
729848 if let Some ( info) = payment_info. as_ref ( ) {
@@ -1518,6 +1637,58 @@ where
15181637 counterparty_node_id,
15191638 ) ;
15201639
1640+ // We check if this event was triggered by an LSPS1 order and handle it properly
1641+ if let Ok ( bytes) = self . event_queue . kv_store . read (
1642+ "lsps1_pending_channels" ,
1643+ "" ,
1644+ & user_channel_id. to_string ( ) ,
1645+ ) {
1646+ if let Ok ( pending_channel) = PendingLSPS1Channel :: read ( & mut & bytes[ ..] ) {
1647+ let now_secs = std:: time:: SystemTime :: now ( )
1648+ . duration_since ( std:: time:: UNIX_EPOCH )
1649+ . unwrap_or_default ( )
1650+ . as_secs ( ) ;
1651+
1652+ let funded_at =
1653+ lightning_liquidity:: lsps0:: ser:: LSPSDateTime :: from_unix_timestamp (
1654+ now_secs,
1655+ )
1656+ . expect ( "Valid timestamp" ) ;
1657+
1658+ let expiry_secs =
1659+ now_secs + ( pending_channel. channel_expiry_blocks as u64 * 600 ) ;
1660+ let expires_at =
1661+ lightning_liquidity:: lsps0:: ser:: LSPSDateTime :: from_unix_timestamp (
1662+ expiry_secs,
1663+ )
1664+ . expect ( "Valid timestamp" ) ;
1665+
1666+ let channel_info = LSPS1ChannelInfo {
1667+ funded_at,
1668+ funding_outpoint : funding_txo. into_bitcoin_outpoint ( ) ,
1669+ expires_at,
1670+ } ;
1671+
1672+ self . runtime . block_on ( async {
1673+ self . liquidity_source
1674+ . lsps1_service ( )
1675+ . handle_order_channel_opened (
1676+ counterparty_node_id,
1677+ pending_channel. order_id ,
1678+ channel_info,
1679+ )
1680+ . await
1681+ } ) ;
1682+
1683+ let _ = self . event_queue . kv_store . remove (
1684+ "lsps1_pending_channels" ,
1685+ "" ,
1686+ & user_channel_id. to_string ( ) ,
1687+ false ,
1688+ ) ;
1689+ }
1690+ }
1691+
15211692 let former_temporary_channel_id = former_temporary_channel_id. expect (
15221693 "LDK Node has only ever persisted ChannelPending events from rust-lightning 0.0.115 or later" ,
15231694 ) ;
0 commit comments