Skip to content

Commit 0f448d0

Browse files
committed
Add LSPS2 RPCs to ldk-server-protos and ldk-server
Expose dedicated LSPS2 invoice endpoints so callers can request fixed and variable-amount JIT invoices without overloading the existing `Bolt11Receive` API surface. Generated with the assistance of AI. Co-Authored-By: HAL 9000
1 parent 50d1c3f commit 0f448d0

6 files changed

Lines changed: 185 additions & 1 deletion

File tree

ldk-server-protos/src/api.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,70 @@ pub struct Bolt11ReceiveResponse {
174174
#[prost(string, tag = "1")]
175175
pub invoice: ::prost::alloc::string::String,
176176
}
177+
/// Return a BOLT11 payable invoice that can be used to request and receive a payment via an
178+
/// LSPS2 just-in-time channel.
179+
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_via_jit_channel>
180+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
181+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
182+
#[allow(clippy::derive_partial_eq_without_eq)]
183+
#[derive(Clone, PartialEq, ::prost::Message)]
184+
pub struct Bolt11ReceiveViaJitChannelRequest {
185+
/// The amount in millisatoshi to request.
186+
#[prost(uint64, tag = "1")]
187+
pub amount_msat: u64,
188+
/// An optional description to attach along with the invoice.
189+
/// Will be set in the description field of the encoded payment request.
190+
#[prost(message, optional, tag = "2")]
191+
pub description: ::core::option::Option<super::types::Bolt11InvoiceDescription>,
192+
/// Invoice expiry time in seconds.
193+
#[prost(uint32, tag = "3")]
194+
pub expiry_secs: u32,
195+
/// Optional upper bound for the total fee an LSP may deduct when opening the JIT channel.
196+
#[prost(uint64, optional, tag = "4")]
197+
pub max_total_lsp_fee_limit_msat: ::core::option::Option<u64>,
198+
}
199+
/// The response `content` for the `Bolt11ReceiveViaJitChannel` API, when HttpStatusCode is OK (200).
200+
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
201+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
203+
#[allow(clippy::derive_partial_eq_without_eq)]
204+
#[derive(Clone, PartialEq, ::prost::Message)]
205+
pub struct Bolt11ReceiveViaJitChannelResponse {
206+
/// An invoice for a payment within the Lightning Network.
207+
#[prost(string, tag = "1")]
208+
pub invoice: ::prost::alloc::string::String,
209+
}
210+
/// Return a variable-amount BOLT11 invoice that can be used to receive a payment via an LSPS2
211+
/// just-in-time channel.
212+
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_variable_amount_via_jit_channel>
213+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
214+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
215+
#[allow(clippy::derive_partial_eq_without_eq)]
216+
#[derive(Clone, PartialEq, ::prost::Message)]
217+
pub struct Bolt11ReceiveVariableAmountViaJitChannelRequest {
218+
/// An optional description to attach along with the invoice.
219+
/// Will be set in the description field of the encoded payment request.
220+
#[prost(message, optional, tag = "1")]
221+
pub description: ::core::option::Option<super::types::Bolt11InvoiceDescription>,
222+
/// Invoice expiry time in seconds.
223+
#[prost(uint32, tag = "2")]
224+
pub expiry_secs: u32,
225+
/// Optional upper bound for the proportional fee, in parts-per-million millisatoshis, that an
226+
/// LSP may deduct when opening the JIT channel.
227+
#[prost(uint64, optional, tag = "3")]
228+
pub max_proportional_lsp_fee_limit_ppm_msat: ::core::option::Option<u64>,
229+
}
230+
/// The response `content` for the `Bolt11ReceiveVariableAmountViaJitChannel` API, when HttpStatusCode is OK (200).
231+
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
232+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
233+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
234+
#[allow(clippy::derive_partial_eq_without_eq)]
235+
#[derive(Clone, PartialEq, ::prost::Message)]
236+
pub struct Bolt11ReceiveVariableAmountViaJitChannelResponse {
237+
/// An invoice for a payment within the Lightning Network.
238+
#[prost(string, tag = "1")]
239+
pub invoice: ::prost::alloc::string::String,
240+
}
177241
/// Send a payment for a BOLT11 invoice.
178242
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.send>
179243
#[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
@@ -12,6 +12,9 @@ pub const GET_BALANCES_PATH: &str = "GetBalances";
1212
pub const ONCHAIN_RECEIVE_PATH: &str = "OnchainReceive";
1313
pub const ONCHAIN_SEND_PATH: &str = "OnchainSend";
1414
pub const BOLT11_RECEIVE_PATH: &str = "Bolt11Receive";
15+
pub const BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH: &str = "Bolt11ReceiveViaJitChannel";
16+
pub const BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH: &str =
17+
"Bolt11ReceiveVariableAmountViaJitChannel";
1518
pub const BOLT11_SEND_PATH: &str = "Bolt11Send";
1619
pub const BOLT12_RECEIVE_PATH: &str = "Bolt12Receive";
1720
pub const BOLT12_SEND_PATH: &str = "Bolt12Send";

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,58 @@ message Bolt11ReceiveResponse {
148148
string invoice = 1;
149149
}
150150

151+
// Return a BOLT11 payable invoice that can be used to request and receive a payment via an
152+
// LSPS2 just-in-time channel.
153+
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_via_jit_channel
154+
message Bolt11ReceiveViaJitChannelRequest {
155+
156+
// The amount in millisatoshi to request.
157+
uint64 amount_msat = 1;
158+
159+
// An optional description to attach along with the invoice.
160+
// Will be set in the description field of the encoded payment request.
161+
types.Bolt11InvoiceDescription description = 2;
162+
163+
// Invoice expiry time in seconds.
164+
uint32 expiry_secs = 3;
165+
166+
// Optional upper bound for the total fee an LSP may deduct when opening the JIT channel.
167+
optional uint64 max_total_lsp_fee_limit_msat = 4;
168+
}
169+
170+
// The response `content` for the `Bolt11ReceiveViaJitChannel` API, when HttpStatusCode is OK (200).
171+
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
172+
message Bolt11ReceiveViaJitChannelResponse {
173+
174+
// An invoice for a payment within the Lightning Network.
175+
string invoice = 1;
176+
}
177+
178+
// Return a variable-amount BOLT11 invoice that can be used to receive a payment via an LSPS2
179+
// just-in-time channel.
180+
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.receive_variable_amount_via_jit_channel
181+
message Bolt11ReceiveVariableAmountViaJitChannelRequest {
182+
183+
// An optional description to attach along with the invoice.
184+
// Will be set in the description field of the encoded payment request.
185+
types.Bolt11InvoiceDescription description = 1;
186+
187+
// Invoice expiry time in seconds.
188+
uint32 expiry_secs = 2;
189+
190+
// Optional upper bound for the proportional fee, in parts-per-million millisatoshis, that an
191+
// LSP may deduct when opening the JIT channel.
192+
optional uint64 max_proportional_lsp_fee_limit_ppm_msat = 3;
193+
}
194+
195+
// The response `content` for the `Bolt11ReceiveVariableAmountViaJitChannel` API, when HttpStatusCode is OK (200).
196+
// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
197+
message Bolt11ReceiveVariableAmountViaJitChannelResponse {
198+
199+
// An invoice for a payment within the Lightning Network.
200+
string invoice = 1;
201+
}
202+
151203
// Send a payment for a BOLT11 invoice.
152204
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.Bolt11Payment.html#method.send
153205
message Bolt11SendRequest {
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+
}

ldk-server/src/api/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::api::error::LdkServerError;
1515
use crate::api::error::LdkServerErrorCode::InvalidRequestError;
1616

1717
pub(crate) mod bolt11_receive;
18+
pub(crate) mod bolt11_receive_via_jit_channel;
1819
pub(crate) mod bolt11_send;
1920
pub(crate) mod bolt12_receive;
2021
pub(crate) mod bolt12_send;

ldk-server/src/service.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use ldk_node::bitcoin::hashes::hmac::{Hmac, HmacEngine};
1919
use ldk_node::bitcoin::hashes::{sha256, Hash, HashEngine};
2020
use ldk_node::Node;
2121
use ldk_server_protos::endpoints::{
22-
BOLT11_RECEIVE_PATH, BOLT11_SEND_PATH, BOLT12_RECEIVE_PATH, BOLT12_SEND_PATH,
22+
BOLT11_RECEIVE_PATH, BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH,
23+
BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH, BOLT11_SEND_PATH, BOLT12_RECEIVE_PATH, BOLT12_SEND_PATH,
2324
CLOSE_CHANNEL_PATH, CONNECT_PEER_PATH, DISCONNECT_PEER_PATH, EXPORT_PATHFINDING_SCORES_PATH,
2425
FORCE_CLOSE_CHANNEL_PATH, GET_BALANCES_PATH, GET_NODE_INFO_PATH, GET_PAYMENT_DETAILS_PATH,
2526
GRAPH_GET_CHANNEL_PATH, GRAPH_GET_NODE_PATH, GRAPH_LIST_CHANNELS_PATH, GRAPH_LIST_NODES_PATH,
@@ -30,6 +31,10 @@ use ldk_server_protos::endpoints::{
3031
use prost::Message;
3132

3233
use crate::api::bolt11_receive::handle_bolt11_receive_request;
34+
use crate::api::bolt11_receive_via_jit_channel::{
35+
handle_bolt11_receive_variable_amount_via_jit_channel_request,
36+
handle_bolt11_receive_via_jit_channel_request,
37+
};
3338
use crate::api::bolt11_send::handle_bolt11_send_request;
3439
use crate::api::bolt12_receive::handle_bolt12_receive_request;
3540
use crate::api::bolt12_send::handle_bolt12_send_request;
@@ -218,6 +223,20 @@ impl Service<Request<Incoming>> for NodeService {
218223
api_key,
219224
handle_bolt11_receive_request,
220225
)),
226+
BOLT11_RECEIVE_VIA_JIT_CHANNEL_PATH => Box::pin(handle_request(
227+
context,
228+
req,
229+
auth_params,
230+
api_key,
231+
handle_bolt11_receive_via_jit_channel_request,
232+
)),
233+
BOLT11_RECEIVE_VARIABLE_AMOUNT_VIA_JIT_CHANNEL_PATH => Box::pin(handle_request(
234+
context,
235+
req,
236+
auth_params,
237+
api_key,
238+
handle_bolt11_receive_variable_amount_via_jit_channel_request,
239+
)),
221240
BOLT11_SEND_PATH => Box::pin(handle_request(
222241
context,
223242
req,

0 commit comments

Comments
 (0)