-
-
Save johncantrell97/dc682d2d75a0331fa83cb10a54f62b74 to your computer and use it in GitHub Desktop.
lightning-liquidity LSP Server Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ************************************** | |
| // STEP 1: Initialize liquidity manager * | |
| // ************************************** | |
| // Create a service config for LSPS2 | |
| let liquidity_service_config = LiquidityServiceConfig { | |
| lsps2_service_config: Some(LSPS2ServiceConfig { | |
| // Used to verify the fee parameters you give out | |
| promise_secret: [0; 32], | |
| min_payment_size_msat: 10_000_000, | |
| max_payment_size_msat: 1_000_000_000, | |
| }) | |
| }; | |
| // Create a liquidity manager which acts as a custom message handler | |
| let liquidity_manager = new LiquidityManager( | |
| keys_manager, | |
| channel_manager, | |
| None, | |
| None, | |
| Some(liquidity_service_config), | |
| None | |
| ); | |
| // Provide the liquidity manager as the custom message handler | |
| let lightning_msg_handler = MessageHandler { | |
| chan_handler, | |
| route_handler, | |
| onion_message_handler, | |
| custom_message_handler: liquidity_manager, | |
| }; | |
| // Use the message handler when creating your peer manager | |
| let peer_manager = PeerManager::new( | |
| lightning_msg_handler, | |
| ... | |
| ); | |
| // ******************************************* | |
| // STEP 2: Handle lightning-liquidity events * | |
| // ******************************************* | |
| // `lightning-liquidity` event handling | |
| tokio::spawn(async move { | |
| let mut interval = tokio::time::interval(Duration::from_secs(1)); | |
| loop { | |
| interval.tick().await; | |
| for event in liquidity_manager.get_and_clear_pending_events() { | |
| match event { | |
| LSPSEvent::LSPS2Service(event) => match event { | |
| // A client is asking for our fee information | |
| LSPS2ServiceEvent::GetInfo { request_id, counterparty_node_id, token } => { | |
| // (optional) Check if token is valid and requires custom fees or parameters | |
| // determine fee rate you want to charge | |
| let opening_fee_params_menu = vec![ | |
| RawOpeningFeeParams { | |
| min_fee_msat: 5000_000, | |
| proportional_fee: 10_000, | |
| // The parameters are valid for the next 10 minutes | |
| valid_until: Utc::now() + Duration::minutes(10), | |
| // How many blocks we guarantee the channel will remain open for | |
| min_lifetime: 4320, | |
| // The maximum number of blocks we will allow the client to lock our funds up for | |
| // if we need to force close the channel | |
| max_client_to_self_delay: 432 | |
| } | |
| ]; | |
| // Provide the information to lightning-liquidity so it can handle the response | |
| let lsps2_service_handler = liquidity_manager.lsps2_service_handler().unwrap(); | |
| lsps2_service_handler.opening_fee_params_generated(&counterparty_node_id, request_id, opening_fee_params_menu).unwrap(); | |
| } | |
| // A client is asking to purchase a channel given one of the fee options we provided during a previous GetInfo request | |
| LSPS2ServiceEvent::BuyRequest { request_id, counterparty_node_id, opening_fee_params, payment_size_msat } => { | |
| // (optional) Create an identifier to track this channel request | |
| let user_channel_id = 0; | |
| // Have LDK provide an scid we can use to intercept the payment's HTLC(s) | |
| let intercept_scid = channel_manager.get_intercept_scid(); | |
| let cltv_expiry_delta = 72; | |
| let client_trusts_lsp = true; | |
| // Provide the invoice parameters to lightning-liquidity so it can handle the response | |
| let lsps2_service_handler = liquidity_manager.lsps2_service_handler().unwrap(); | |
| lsps2_service_handler.invoice_parameters_generated( | |
| &counterparty_node_id, | |
| request_id, | |
| intercept_scid, | |
| client_trusts_lsp, | |
| user_channel_id, | |
| ).unwrap(); | |
| } | |
| // The payment has been intercepted, it's time to open the channel | |
| LSPS2ServiceEvent::OpenChannel { user_channel_id, their_network_key, amt_to_forward_msat, opening_fee_msat, .. } => { | |
| // Decide on a channel size based on the amount to forward | |
| let channel_value_sats = amt_to_forward_msat * 2; | |
| let push_msats = 0; | |
| // Create the channel with the user | |
| channel_manager.create_channel( | |
| their_network_key, | |
| channel_value_sats, | |
| push_msats, | |
| user_channel_id, | |
| None, | |
| ).unwrap(); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }) | |
| /// *********************************** | |
| /// STEP3: Augment LDK event handling * | |
| /// *********************************** | |
| let event_handler = move | event: Event | { | |
| match event { | |
| // LDK has intercepted an HTLC with the scid we provided to a user. | |
| Event::HTLCIntercepted { | |
| intercept_id, | |
| request_next_hop_scid, | |
| expected_outbound_amount_msat, | |
| .. | |
| } => { | |
| // Inform lightning-liquidity of this htlc so it can determine if we should open a channel or not. | |
| let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler().unwrap(); | |
| lsps2_service_handler.htlc_intercepted( | |
| requested_next_hop_scid, | |
| intercept_id, | |
| expected_outbound_amount_msat, | |
| ).unwrap(); | |
| } | |
| // A channel is ready to be used | |
| Event::ChannelReady { | |
| ref channel_id, | |
| user_channel_id, | |
| ref counterparty_node_id, | |
| .. | |
| } => { | |
| // Inform lightning-liquidity a channel is ready so it can determine if it should forward the payment | |
| let lsps2_service_handler = self.liquidity_manager.lsps2_service_handler().unwrap(); | |
| lsps2_service_handler.channel_ready(user_channel_id, channel_id, counterparty_node_id).unwrap(); | |
| } | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment