Skip to content

Commit 6b1a799

Browse files
authored
Merge pull request #143 from tnull/2026-03-lsps2-client-support
2 parents 733ffeb + 47c2c95 commit 6b1a799

11 files changed

Lines changed: 412 additions & 19 deletions

File tree

ldk-server-cli/src/main.rs

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ use ldk_server_client::error::LdkServerErrorCode::{
2424
use ldk_server_client::ldk_server_protos::api::{
2525
Bolt11ClaimForHashRequest, Bolt11ClaimForHashResponse, Bolt11FailForHashRequest,
2626
Bolt11FailForHashResponse, Bolt11ReceiveForHashRequest, Bolt11ReceiveForHashResponse,
27-
Bolt11ReceiveRequest, Bolt11ReceiveResponse, Bolt11SendRequest, Bolt11SendResponse,
27+
Bolt11ReceiveRequest, Bolt11ReceiveResponse, Bolt11ReceiveVariableAmountViaJitChannelRequest,
28+
Bolt11ReceiveVariableAmountViaJitChannelResponse, Bolt11ReceiveViaJitChannelRequest,
29+
Bolt11ReceiveViaJitChannelResponse, Bolt11SendRequest, Bolt11SendResponse,
2830
Bolt12ReceiveRequest, Bolt12ReceiveResponse, Bolt12SendRequest, Bolt12SendResponse,
2931
CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest, ConnectPeerResponse,
3032
DisconnectPeerRequest, DisconnectPeerResponse, ExportPathfindingScoresRequest,
@@ -178,6 +180,41 @@ enum Commands {
178180
#[arg(help = "The hex-encoded 32-byte payment hash")]
179181
payment_hash: String,
180182
},
183+
#[command(about = "Create a fixed-amount BOLT11 invoice to receive via an LSPS2 JIT channel")]
184+
Bolt11ReceiveViaJitChannel {
185+
#[arg(help = "Amount to request, e.g. 50sat or 50000msat")]
186+
amount: Amount,
187+
#[arg(short, long, help = "Description to attach along with the invoice")]
188+
description: Option<String>,
189+
#[arg(
190+
long,
191+
help = "SHA-256 hash of the description (hex). Use instead of description for longer text"
192+
)]
193+
description_hash: Option<String>,
194+
#[arg(short, long, help = "Invoice expiry time in seconds (default: 86400)")]
195+
expiry_secs: Option<u32>,
196+
#[arg(
197+
long,
198+
help = "Maximum total fee an LSP may deduct for opening the JIT channel, e.g. 50sat or 50000msat"
199+
)]
200+
max_total_lsp_fee_limit: Option<Amount>,
201+
},
202+
#[command(
203+
about = "Create a variable-amount BOLT11 invoice to receive via an LSPS2 JIT channel"
204+
)]
205+
Bolt11ReceiveVariableAmountViaJitChannel {
206+
#[arg(short, long, help = "Description to attach along with the invoice")]
207+
description: Option<String>,
208+
#[arg(
209+
long,
210+
help = "SHA-256 hash of the description (hex). Use instead of description for longer text"
211+
)]
212+
description_hash: Option<String>,
213+
#[arg(short, long, help = "Invoice expiry time in seconds (default: 86400)")]
214+
expiry_secs: Option<u32>,
215+
#[arg(long, help = "Maximum proportional fee the LSP may deduct in ppm-msat")]
216+
max_proportional_lsp_fee_limit_ppm_msat: Option<u64>,
217+
},
181218
#[command(about = "Pay a BOLT11 invoice")]
182219
Bolt11Send {
183220
#[arg(help = "A BOLT11 invoice for a payment within the Lightning Network")]
@@ -571,21 +608,8 @@ async fn main() {
571608
},
572609
Commands::Bolt11Receive { description, description_hash, expiry_secs, amount } => {
573610
let amount_msat = amount.map(|a| a.to_msat());
574-
let invoice_description = match (description, description_hash) {
575-
(Some(desc), None) => Some(Bolt11InvoiceDescription {
576-
kind: Some(bolt11_invoice_description::Kind::Direct(desc)),
577-
}),
578-
(None, Some(hash)) => Some(Bolt11InvoiceDescription {
579-
kind: Some(bolt11_invoice_description::Kind::Hash(hash)),
580-
}),
581-
(Some(_), Some(_)) => {
582-
handle_error(LdkServerError::new(
583-
InternalError,
584-
"Only one of description or description_hash can be set.".to_string(),
585-
));
586-
},
587-
(None, None) => None,
588-
};
611+
let invoice_description =
612+
parse_bolt11_invoice_description(description, description_hash);
589613

590614
let expiry_secs = expiry_secs.unwrap_or(DEFAULT_EXPIRY_SECS);
591615
let request =
@@ -647,6 +671,40 @@ async fn main() {
647671
client.bolt11_fail_for_hash(Bolt11FailForHashRequest { payment_hash }).await,
648672
);
649673
},
674+
Commands::Bolt11ReceiveViaJitChannel {
675+
amount,
676+
description,
677+
description_hash,
678+
expiry_secs,
679+
max_total_lsp_fee_limit,
680+
} => {
681+
let request = Bolt11ReceiveViaJitChannelRequest {
682+
amount_msat: amount.to_msat(),
683+
description: parse_bolt11_invoice_description(description, description_hash),
684+
expiry_secs: expiry_secs.unwrap_or(DEFAULT_EXPIRY_SECS),
685+
max_total_lsp_fee_limit_msat: max_total_lsp_fee_limit.map(|a| a.to_msat()),
686+
};
687+
688+
handle_response_result::<_, Bolt11ReceiveViaJitChannelResponse>(
689+
client.bolt11_receive_via_jit_channel(request).await,
690+
);
691+
},
692+
Commands::Bolt11ReceiveVariableAmountViaJitChannel {
693+
description,
694+
description_hash,
695+
expiry_secs,
696+
max_proportional_lsp_fee_limit_ppm_msat,
697+
} => {
698+
let request = Bolt11ReceiveVariableAmountViaJitChannelRequest {
699+
description: parse_bolt11_invoice_description(description, description_hash),
700+
expiry_secs: expiry_secs.unwrap_or(DEFAULT_EXPIRY_SECS),
701+
max_proportional_lsp_fee_limit_ppm_msat,
702+
};
703+
704+
handle_response_result::<_, Bolt11ReceiveVariableAmountViaJitChannelResponse>(
705+
client.bolt11_receive_variable_amount_via_jit_channel(request).await,
706+
);
707+
},
650708
Commands::Bolt11Send {
651709
invoice,
652710
amount,
@@ -1054,6 +1112,26 @@ where
10541112
}
10551113
}
10561114

1115+
fn parse_bolt11_invoice_description(
1116+
description: Option<String>, description_hash: Option<String>,
1117+
) -> Option<Bolt11InvoiceDescription> {
1118+
match (description, description_hash) {
1119+
(Some(desc), None) => Some(Bolt11InvoiceDescription {
1120+
kind: Some(bolt11_invoice_description::Kind::Direct(desc)),
1121+
}),
1122+
(None, Some(hash)) => Some(Bolt11InvoiceDescription {
1123+
kind: Some(bolt11_invoice_description::Kind::Hash(hash)),
1124+
}),
1125+
(Some(_), Some(_)) => {
1126+
handle_error(LdkServerError::new(
1127+
InternalError,
1128+
"Only one of description or description_hash can be set.".to_string(),
1129+
));
1130+
},
1131+
(None, None) => None,
1132+
}
1133+
}
1134+
10571135
fn parse_page_token(token_str: &str) -> Result<PageToken, LdkServerError> {
10581136
let parts: Vec<&str> = token_str.split(':').collect();
10591137
if parts.len() != 2 {

ldk-server-client/src/client.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ use bitcoin_hashes::{sha256, Hash, HashEngine};
1414
use ldk_server_protos::api::{
1515
Bolt11ClaimForHashRequest, Bolt11ClaimForHashResponse, Bolt11FailForHashRequest,
1616
Bolt11FailForHashResponse, Bolt11ReceiveForHashRequest, Bolt11ReceiveForHashResponse,
17-
Bolt11ReceiveRequest, Bolt11ReceiveResponse, Bolt11SendRequest, Bolt11SendResponse,
17+
Bolt11ReceiveRequest, Bolt11ReceiveResponse, Bolt11ReceiveVariableAmountViaJitChannelRequest,
18+
Bolt11ReceiveVariableAmountViaJitChannelResponse, Bolt11ReceiveViaJitChannelRequest,
19+
Bolt11ReceiveViaJitChannelResponse, Bolt11SendRequest, Bolt11SendResponse,
1820
Bolt12ReceiveRequest, Bolt12ReceiveResponse, Bolt12SendRequest, Bolt12SendResponse,
1921
CloseChannelRequest, CloseChannelResponse, ConnectPeerRequest, ConnectPeerResponse,
2022
DisconnectPeerRequest, DisconnectPeerResponse, ExportPathfindingScoresRequest,
@@ -33,7 +35,8 @@ use ldk_server_protos::api::{
3335
};
3436
use ldk_server_protos::endpoints::{
3537
BOLT11_CLAIM_FOR_HASH_PATH, BOLT11_FAIL_FOR_HASH_PATH, BOLT11_RECEIVE_FOR_HASH_PATH,
36-
BOLT11_RECEIVE_PATH, BOLT11_SEND_PATH, BOLT12_RECEIVE_PATH, BOLT12_SEND_PATH,
38+
BOLT11_RECEIVE_PATH, BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH,
39+
BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH, BOLT11_SEND_PATH, BOLT12_RECEIVE_PATH, BOLT12_SEND_PATH,
3740
CLOSE_CHANNEL_PATH, CONNECT_PEER_PATH, DISCONNECT_PEER_PATH, EXPORT_PATHFINDING_SCORES_PATH,
3841
FORCE_CLOSE_CHANNEL_PATH, GET_BALANCES_PATH, GET_NODE_INFO_PATH, GET_PAYMENT_DETAILS_PATH,
3942
GRAPH_GET_CHANNEL_PATH, GRAPH_GET_NODE_PATH, GRAPH_LIST_CHANNELS_PATH, GRAPH_LIST_NODES_PATH,
@@ -174,6 +177,30 @@ impl LdkServerClient {
174177
self.post_request(&request, &url).await
175178
}
176179

180+
/// Retrieve a new fixed-amount BOLT11 invoice for receiving via an LSPS2 JIT channel.
181+
/// For API contract/usage, refer to docs for [`Bolt11ReceiveViaJitChannelRequest`] and
182+
/// [`Bolt11ReceiveViaJitChannelResponse`].
183+
pub async fn bolt11_receive_via_jit_channel(
184+
&self, request: Bolt11ReceiveViaJitChannelRequest,
185+
) -> Result<Bolt11ReceiveViaJitChannelResponse, LdkServerError> {
186+
let url = format!("https://{}/{BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH}", self.base_url);
187+
self.post_request(&request, &url).await
188+
}
189+
190+
/// Retrieve a new variable-amount BOLT11 invoice for receiving via an LSPS2 JIT channel.
191+
/// For API contract/usage, refer to docs for
192+
/// [`Bolt11ReceiveVariableAmountViaJitChannelRequest`] and
193+
/// [`Bolt11ReceiveVariableAmountViaJitChannelResponse`].
194+
pub async fn bolt11_receive_variable_amount_via_jit_channel(
195+
&self, request: Bolt11ReceiveVariableAmountViaJitChannelRequest,
196+
) -> Result<Bolt11ReceiveVariableAmountViaJitChannelResponse, LdkServerError> {
197+
let url = format!(
198+
"https://{}/{BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH}",
199+
self.base_url,
200+
);
201+
self.post_request(&request, &url).await
202+
}
203+
177204
/// Send a payment for a BOLT11 invoice.
178205
/// For API contract/usage, refer to docs for [`Bolt11SendRequest`] and [`Bolt11SendResponse`].
179206
pub async fn bolt11_send(

ldk-server-protos/src/api.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,70 @@ pub struct Bolt11FailForHashRequest {
259259
#[allow(clippy::derive_partial_eq_without_eq)]
260260
#[derive(Clone, PartialEq, ::prost::Message)]
261261
pub struct Bolt11FailForHashResponse {}
262+
/// Return a BOLT11 payable invoice that can be used to request and receive a payment via an
263+
/// LSPS2 just-in-time channel.
264+
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_via_jit_channel>
265+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
266+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
267+
#[allow(clippy::derive_partial_eq_without_eq)]
268+
#[derive(Clone, PartialEq, ::prost::Message)]
269+
pub struct Bolt11ReceiveViaJitChannelRequest {
270+
/// The amount in millisatoshi to request.
271+
#[prost(uint64, tag = "1")]
272+
pub amount_msat: u64,
273+
/// An optional description to attach along with the invoice.
274+
/// Will be set in the description field of the encoded payment request.
275+
#[prost(message, optional, tag = "2")]
276+
pub description: ::core::option::Option<super::types::Bolt11InvoiceDescription>,
277+
/// Invoice expiry time in seconds.
278+
#[prost(uint32, tag = "3")]
279+
pub expiry_secs: u32,
280+
/// Optional upper bound for the total fee an LSP may deduct when opening the JIT channel.
281+
#[prost(uint64, optional, tag = "4")]
282+
pub max_total_lsp_fee_limit_msat: ::core::option::Option<u64>,
283+
}
284+
/// The response `content` for the `Bolt11ReceiveViaJitChannel` API, when HttpStatusCode is OK (200).
285+
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
286+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
287+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
288+
#[allow(clippy::derive_partial_eq_without_eq)]
289+
#[derive(Clone, PartialEq, ::prost::Message)]
290+
pub struct Bolt11ReceiveViaJitChannelResponse {
291+
/// An invoice for a payment within the Lightning Network.
292+
#[prost(string, tag = "1")]
293+
pub invoice: ::prost::alloc::string::String,
294+
}
295+
/// Return a variable-amount BOLT11 invoice that can be used to receive a payment via an LSPS2
296+
/// just-in-time channel.
297+
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_variable_amount_via_jit_channel>
298+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
299+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
300+
#[allow(clippy::derive_partial_eq_without_eq)]
301+
#[derive(Clone, PartialEq, ::prost::Message)]
302+
pub struct Bolt11ReceiveVariableAmountViaJitChannelRequest {
303+
/// An optional description to attach along with the invoice.
304+
/// Will be set in the description field of the encoded payment request.
305+
#[prost(message, optional, tag = "1")]
306+
pub description: ::core::option::Option<super::types::Bolt11InvoiceDescription>,
307+
/// Invoice expiry time in seconds.
308+
#[prost(uint32, tag = "2")]
309+
pub expiry_secs: u32,
310+
/// Optional upper bound for the proportional fee, in parts-per-million millisatoshis, that an
311+
/// LSP may deduct when opening the JIT channel.
312+
#[prost(uint64, optional, tag = "3")]
313+
pub max_proportional_lsp_fee_limit_ppm_msat: ::core::option::Option<u64>,
314+
}
315+
/// The response `content` for the `Bolt11ReceiveVariableAmountViaJitChannel` API, when HttpStatusCode is OK (200).
316+
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
317+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
318+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
319+
#[allow(clippy::derive_partial_eq_without_eq)]
320+
#[derive(Clone, PartialEq, ::prost::Message)]
321+
pub struct Bolt11ReceiveVariableAmountViaJitChannelResponse {
322+
/// An invoice for a payment within the Lightning Network.
323+
#[prost(string, tag = "1")]
324+
pub invoice: ::prost::alloc::string::String,
325+
}
262326
/// Send a payment for a BOLT11 invoice.
263327
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.send>
264328
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

ldk-server-protos/src/endpoints.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub const BOLT11_RECEIVE_PATH: &str = "Bolt11Receive";
1515
pub const BOLT11_RECEIVE_FOR_HASH_PATH: &str = "Bolt11ReceiveForHash";
1616
pub const BOLT11_CLAIM_FOR_HASH_PATH: &str = "Bolt11ClaimForHash";
1717
pub const BOLT11_FAIL_FOR_HASH_PATH: &str = "Bolt11FailForHash";
18+
pub const BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH: &str = "Bolt11ReceiveViaJitChannel";
19+
pub const BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH: &str =
20+
"Bolt11ReceiveVariableAmountViaJitChannel";
1821
pub const BOLT11_SEND_PATH: &str = "Bolt11Send";
1922
pub const BOLT12_RECEIVE_PATH: &str = "Bolt12Receive";
2023
pub const BOLT12_SEND_PATH: &str = "Bolt12Send";

ldk-server-protos/src/proto/api.proto

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,59 @@ message Bolt11FailForHashRequest {
215215
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
216216
message Bolt11FailForHashResponse {}
217217

218+
// Return a BOLT11 payable invoice that can be used to request and receive a payment via an
219+
// LSPS2 just-in-time channel.
220+
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_via_jit_channel
221+
message Bolt11ReceiveViaJitChannelRequest {
222+
223+
// The amount in millisatoshi to request.
224+
uint64 amount_msat = 1;
225+
226+
// An optional description to attach along with the invoice.
227+
// Will be set in the description field of the encoded payment request.
228+
types.Bolt11InvoiceDescription description = 2;
229+
230+
// Invoice expiry time in seconds.
231+
uint32 expiry_secs = 3;
232+
233+
// Optional upper bound for the total fee an LSP may deduct when opening the JIT channel.
234+
optional uint64 max_total_lsp_fee_limit_msat = 4;
235+
}
236+
237+
// The response `content` for the `Bolt11ReceiveViaJitChannel` API, when HttpStatusCode is OK (200).
238+
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
239+
message Bolt11ReceiveViaJitChannelResponse {
240+
241+
// An invoice for a payment within the Lightning Network.
242+
string invoice = 1;
243+
}
244+
245+
// Return a variable-amount BOLT11 invoice that can be used to receive a payment via an LSPS2
246+
// just-in-time channel.
247+
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_variable_amount_via_jit_channel
248+
message Bolt11ReceiveVariableAmountViaJitChannelRequest {
249+
250+
// An optional description to attach along with the invoice.
251+
// Will be set in the description field of the encoded payment request.
252+
types.Bolt11InvoiceDescription description = 1;
253+
254+
// Invoice expiry time in seconds.
255+
uint32 expiry_secs = 2;
256+
257+
// Optional upper bound for the proportional fee, in parts-per-million millisatoshis, that an
258+
// LSP may deduct when opening the JIT channel.
259+
optional uint64 max_proportional_lsp_fee_limit_ppm_msat = 3;
260+
}
261+
262+
// The response `content` for the `Bolt11ReceiveVariableAmountViaJitChannel` API, when HttpStatusCode is OK (200).
263+
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
264+
message Bolt11ReceiveVariableAmountViaJitChannelResponse {
265+
266+
// An invoice for a payment within the Lightning Network.
267+
string invoice = 1;
268+
}
269+
270+
218271
// Send a payment for a BOLT11 invoice.
219272
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.send
220273
message Bolt11SendRequest {

ldk-server/ldk-server-config.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ server_url = "https://mempool.space/api" # Esplora endpoint
4343
connection_string = "" # RabbitMQ connection string
4444
exchange_name = ""
4545

46+
# LSPS2 Client Support
47+
[liquidity.lsps2_client]
48+
# The public key of the LSPS2 LSP we source just-in-time liquidity from.
49+
node_pubkey = "<lsp node pubkey>"
50+
# Address to connect to the LSPS2 LSP (IPv4:port, IPv6:port, OnionV3:port, or hostname:port).
51+
address = "<lsp ip address>:9735"
52+
# Optional token for authenticating to the LSP.
53+
# token = ""
54+
4655
# Experimental LSPS2 Service Support
4756
# CAUTION: LSPS2 support is highly experimental and for testing purposes only.
4857
[liquidity.lsps2_service]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
10+
use ldk_server_protos::api::{
11+
Bolt11ReceiveVariableAmountViaJitChannelRequest,
12+
Bolt11ReceiveVariableAmountViaJitChannelResponse, Bolt11ReceiveViaJitChannelRequest,
13+
Bolt11ReceiveViaJitChannelResponse,
14+
};
15+
16+
use crate::api::error::LdkServerError;
17+
use crate::service::Context;
18+
use crate::util::proto_adapter::proto_to_bolt11_description;
19+
20+
pub(crate) fn handle_bolt11_receive_via_jit_channel_request(
21+
context: Context, request: Bolt11ReceiveViaJitChannelRequest,
22+
) -> Result<Bolt11ReceiveViaJitChannelResponse, LdkServerError> {
23+
let description = proto_to_bolt11_description(request.description)?;
24+
let invoice = context.node.bolt11_payment().receive_via_jit_channel(
25+
request.amount_msat,
26+
&description,
27+
request.expiry_secs,
28+
request.max_total_lsp_fee_limit_msat,
29+
)?;
30+
31+
Ok(Bolt11ReceiveViaJitChannelResponse { invoice: invoice.to_string() })
32+
}
33+
34+
pub(crate) fn handle_bolt11_receive_variable_amount_via_jit_channel_request(
35+
context: Context, request: Bolt11ReceiveVariableAmountViaJitChannelRequest,
36+
) -> Result<Bolt11ReceiveVariableAmountViaJitChannelResponse, LdkServerError> {
37+
let description = proto_to_bolt11_description(request.description)?;
38+
let invoice = context.node.bolt11_payment().receive_variable_amount_via_jit_channel(
39+
&description,
40+
request.expiry_secs,
41+
request.max_proportional_lsp_fee_limit_ppm_msat,
42+
)?;
43+
44+
Ok(Bolt11ReceiveVariableAmountViaJitChannelResponse { invoice: invoice.to_string() })
45+
}

0 commit comments

Comments
 (0)