@@ -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 ;
@@ -834,6 +835,124 @@ where
834835 counterparty_skimmed_fee_msat,
835836 ..
836837 } => {
838+ // We intercept early and check if the payment was an LSPS1
839+ // order payment and handle properly.
840+ if let Ok ( bytes) = self . event_queue . kv_store . read (
841+ "lsps1_pending_orders" ,
842+ "" ,
843+ & payment_hash. 0 . to_string ( ) ,
844+ ) {
845+ if let Ok ( pending_order) = PendingLSPS1Order :: read ( & mut & bytes[ ..] ) {
846+ let ( payment_preimage, payment_method) = match purpose {
847+ PaymentPurpose :: Bolt11InvoicePayment { payment_preimage, .. } => (
848+ payment_preimage,
849+ lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt11 ,
850+ ) ,
851+ PaymentPurpose :: Bolt12OfferPayment { payment_preimage, .. } => (
852+ payment_preimage,
853+ lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt12 ,
854+ ) ,
855+ _ => ( None , lightning_liquidity:: lsps1:: service:: PaymentMethod :: Bolt11 ) ,
856+ } ;
857+
858+ if let Some ( preimage) = payment_preimage {
859+ let expected_msat =
860+ pending_order. order_total_amount_sat . saturating_mul ( 1000 ) ;
861+
862+ if amount_msat < expected_msat {
863+ log_error ! (
864+ self . logger,
865+ "Refused LSPS1 payment: underpaid. Expected {} msat, received {} msat." ,
866+ expected_msat,
867+ amount_msat
868+ ) ;
869+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
870+ return Ok ( ( ) ) ;
871+ }
872+
873+ self . runtime . block_on ( async {
874+ self . liquidity_source
875+ . lsps1_service ( )
876+ . handle_order_payment_received (
877+ pending_order. counterparty_node_id ,
878+ pending_order. request_id . into ( ) ,
879+ payment_method,
880+ )
881+ . await
882+ } ) ;
883+
884+ self . channel_manager . claim_funds ( preimage) ;
885+
886+ let mut config = self . channel_manager . get_current_config ( ) ;
887+
888+ // We set the forwarding fee to 0 for now as we're getting paid by the channel fee.
889+ config. channel_config . forwarding_fee_base_msat = 0 ;
890+
891+ let channel_size_sat = pending_order. order_params . lsp_balance_sat
892+ + pending_order. order_params . client_balance_sat ;
893+
894+ let push_msat =
895+ pending_order. order_params . client_balance_sat . saturating_mul ( 1000 ) ;
896+
897+ let user_channel_id: u128 = u128:: from_ne_bytes (
898+ self . keys_manager . get_secure_random_bytes ( ) [ ..16 ]
899+ . try_into ( )
900+ . expect ( "slice is exactly 16 bytes" ) ,
901+ ) ;
902+
903+ let pending_channel = PendingLSPS1Channel {
904+ order_id : pending_order. request_id . into ( ) . clone ( ) ,
905+ channel_expiry_blocks : pending_order
906+ . order_params
907+ . channel_expiry_blocks ,
908+ } ;
909+
910+ let _ = self . event_queue . kv_store . write (
911+ "lsps1_pending_channels" ,
912+ "" ,
913+ & user_channel_id. to_string ( ) ,
914+ pending_channel. encode ( ) ,
915+ ) ;
916+
917+ if let Err ( e) = self . channel_manager . create_channel (
918+ pending_order. counterparty_node_id ,
919+ channel_size_sat,
920+ push_msat,
921+ user_channel_id,
922+ None ,
923+ Some ( config) ,
924+ ) {
925+ log_error ! (
926+ self . logger,
927+ "Failed to open LSPS1 channel after claiming funds: {:?}" ,
928+ e
929+ ) ;
930+ self . liquidity_source
931+ . lsps1_service ( )
932+ . handle_order_failed_and_refunded (
933+ pending_order. counterparty_node_id ,
934+ pending_order. request_id . into ( ) ,
935+ )
936+ . await
937+ }
938+
939+ let _ = self . event_queue . kv_store . remove (
940+ "lsps1_pending_orders" ,
941+ "" ,
942+ & payment_hash. 0 . to_string ( ) ,
943+ false ,
944+ ) ;
945+ } else {
946+ log_error ! (
947+ self . logger,
948+ "Failed to claim LSPS1 payment: preimage unknown or unsupported payment purpose."
949+ ) ;
950+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
951+ }
952+ return Ok ( ( ) ) ;
953+ }
954+ }
955+
837956 let ( payment_id, mut payment_info) =
838957 self . resolve_inbound_payment_id ( payment_id, & payment_hash) . await ?;
839958 if let Some ( info) = payment_info. as_ref ( ) {
@@ -1779,6 +1898,58 @@ where
17791898 counterparty_node_id,
17801899 ) ;
17811900
1901+ // We check if this event was triggered by an LSPS1 order and handle it properly
1902+ if let Ok ( bytes) = self . event_queue . kv_store . read (
1903+ "lsps1_pending_channels" ,
1904+ "" ,
1905+ & user_channel_id. to_string ( ) ,
1906+ ) {
1907+ if let Ok ( pending_channel) = PendingLSPS1Channel :: read ( & mut & bytes[ ..] ) {
1908+ let now_secs = std:: time:: SystemTime :: now ( )
1909+ . duration_since ( std:: time:: UNIX_EPOCH )
1910+ . unwrap_or_default ( )
1911+ . as_secs ( ) ;
1912+
1913+ let funded_at =
1914+ lightning_liquidity:: lsps0:: ser:: LSPSDateTime :: from_unix_timestamp (
1915+ now_secs,
1916+ )
1917+ . expect ( "Valid timestamp" ) ;
1918+
1919+ let expiry_secs =
1920+ now_secs + ( pending_channel. channel_expiry_blocks as u64 * 600 ) ;
1921+ let expires_at =
1922+ lightning_liquidity:: lsps0:: ser:: LSPSDateTime :: from_unix_timestamp (
1923+ expiry_secs,
1924+ )
1925+ . expect ( "Valid timestamp" ) ;
1926+
1927+ let channel_info = LSPS1ChannelInfo {
1928+ funded_at,
1929+ funding_outpoint : funding_txo. into_bitcoin_outpoint ( ) ,
1930+ expires_at,
1931+ } ;
1932+
1933+ self . runtime . block_on ( async {
1934+ self . liquidity_source
1935+ . lsps1_service ( )
1936+ . handle_order_channel_opened (
1937+ counterparty_node_id,
1938+ pending_channel. order_id ,
1939+ channel_info,
1940+ )
1941+ . await
1942+ } ) ;
1943+
1944+ let _ = self . event_queue . kv_store . remove (
1945+ "lsps1_pending_channels" ,
1946+ "" ,
1947+ & user_channel_id. to_string ( ) ,
1948+ false ,
1949+ ) ;
1950+ }
1951+ }
1952+
17821953 let former_temporary_channel_id = former_temporary_channel_id. expect (
17831954 "LDK Node has only ever persisted ChannelPending events from rust-lightning 0.0.115 or later" ,
17841955 ) ;
0 commit comments