Skip to content

Commit ebb776d

Browse files
committed
allow route_parameters in BOLT11 & BOLT12 send API
1 parent aaf587d commit ebb776d

File tree

5 files changed

+154
-10
lines changed

5 files changed

+154
-10
lines changed

ldk-server-cli/src/main.rs

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,19 @@ use ldk_server_client::ldk_server_protos::api::{
1010
ListChannelsRequest, ListPaymentsRequest, OnchainReceiveRequest, OnchainSendRequest,
1111
OpenChannelRequest,
1212
};
13+
use ldk_server_client::ldk_server_protos::types::RouteParametersConfig;
1314
use ldk_server_client::ldk_server_protos::types::{
1415
bolt11_invoice_description, Bolt11InvoiceDescription, PageToken, Payment,
1516
};
1617
use std::fmt::Debug;
1718

19+
// Having these default values as constants in the Proto file and
20+
// importing/reusing them here might be better, but Proto3 removed
21+
// the ability to set default values.
22+
const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008;
23+
const DEFAULT_MAX_PATH_COUNT: u32 = 10;
24+
const DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF: u32 = 2;
25+
1826
#[derive(Parser, Debug)]
1927
#[command(version, about, long_about = None)]
2028
struct Cli {
@@ -55,6 +63,14 @@ enum Commands {
5563
invoice: String,
5664
#[arg(long)]
5765
amount_msat: Option<u64>,
66+
#[arg(long)]
67+
max_total_routing_fee_msat: Option<u64>,
68+
#[arg(long)]
69+
max_total_cltv_expiry_delta: Option<u32>,
70+
#[arg(long)]
71+
max_path_count: Option<u32>,
72+
#[arg(long)]
73+
max_channel_saturation_power_of_half: Option<u32>,
5874
},
5975
Bolt12Receive {
6076
#[arg(short, long)]
@@ -75,6 +91,14 @@ enum Commands {
7591
quantity: Option<u64>,
7692
#[arg(short, long)]
7793
payer_note: Option<String>,
94+
#[arg(long)]
95+
max_total_routing_fee_msat: Option<u64>,
96+
#[arg(long)]
97+
max_total_cltv_expiry_delta: Option<u32>,
98+
#[arg(long)]
99+
max_path_count: Option<u32>,
100+
#[arg(long)]
101+
max_channel_saturation_power_of_half: Option<u32>,
78102
},
79103
CloseChannel {
80104
#[arg(short, long)]
@@ -161,9 +185,30 @@ async fn main() {
161185

162186
handle_response_result(client.bolt11_receive(request).await);
163187
},
164-
Commands::Bolt11Send { invoice, amount_msat } => {
188+
Commands::Bolt11Send {
189+
invoice,
190+
amount_msat,
191+
max_total_routing_fee_msat,
192+
max_total_cltv_expiry_delta,
193+
max_path_count,
194+
max_channel_saturation_power_of_half,
195+
} => {
196+
let route_parameters = RouteParametersConfig {
197+
max_total_routing_fee_msat,
198+
max_total_cltv_expiry_delta: max_total_cltv_expiry_delta
199+
.unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA),
200+
max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT),
201+
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
202+
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
203+
};
165204
handle_response_result(
166-
client.bolt11_send(Bolt11SendRequest { invoice, amount_msat }).await,
205+
client
206+
.bolt11_send(Bolt11SendRequest {
207+
invoice,
208+
amount_msat,
209+
route_parameters: Some(route_parameters),
210+
})
211+
.await,
167212
);
168213
},
169214
Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => {
@@ -178,10 +223,34 @@ async fn main() {
178223
.await,
179224
);
180225
},
181-
Commands::Bolt12Send { offer, amount_msat, quantity, payer_note } => {
226+
Commands::Bolt12Send {
227+
offer,
228+
amount_msat,
229+
quantity,
230+
payer_note,
231+
max_total_routing_fee_msat,
232+
max_total_cltv_expiry_delta,
233+
max_path_count,
234+
max_channel_saturation_power_of_half,
235+
} => {
236+
let route_parameters = RouteParametersConfig {
237+
max_total_routing_fee_msat,
238+
max_total_cltv_expiry_delta: max_total_cltv_expiry_delta
239+
.unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA),
240+
max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT),
241+
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
242+
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
243+
};
244+
182245
handle_response_result(
183246
client
184-
.bolt12_send(Bolt12SendRequest { offer, amount_msat, quantity, payer_note })
247+
.bolt12_send(Bolt12SendRequest {
248+
offer,
249+
amount_msat,
250+
quantity,
251+
payer_note,
252+
route_parameters: Some(route_parameters),
253+
})
185254
.await,
186255
);
187256
},

ldk-server-protos/src/api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ pub struct Bolt11SendRequest {
141141
/// This operation will fail if the amount specified is less than the value required by the given invoice.
142142
#[prost(uint64, optional, tag = "2")]
143143
pub amount_msat: ::core::option::Option<u64>,
144+
/// Configuration options for payment routing and pathfinding.
145+
#[prost(message, optional, tag = "3")]
146+
pub route_parameters: ::core::option::Option<super::types::RouteParametersConfig>,
144147
}
145148
/// The response `content` for the `Bolt11Send` API, when HttpStatusCode is OK (200).
146149
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.
@@ -205,6 +208,9 @@ pub struct Bolt12SendRequest {
205208
/// If set, it will be seen by the recipient and reflected back in the invoice.
206209
#[prost(string, optional, tag = "4")]
207210
pub payer_note: ::core::option::Option<::prost::alloc::string::String>,
211+
/// Configuration options for payment routing and pathfinding.
212+
#[prost(message, optional, tag = "5")]
213+
pub route_parameters: ::core::option::Option<super::types::RouteParametersConfig>,
208214
}
209215
/// The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200).
210216
/// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`.

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ message Bolt11SendRequest {
138138
// amount paid to be determined by the user.
139139
// This operation will fail if the amount specified is less than the value required by the given invoice.
140140
optional uint64 amount_msat = 2;
141+
142+
// Configuration options for payment routing and pathfinding.
143+
optional types.RouteParametersConfig route_parameters = 3;
141144

142145
}
143146

@@ -199,6 +202,9 @@ message Bolt12SendRequest {
199202

200203
// If set, it will be seen by the recipient and reflected back in the invoice.
201204
optional string payer_note = 4;
205+
206+
// Configuration options for payment routing and pathfinding.
207+
optional types.RouteParametersConfig route_parameters = 5;
202208
}
203209

204210
// The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200).

ldk-server/src/api/bolt11_send.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::api::error::LdkServerError;
2+
use crate::api::error::LdkServerErrorCode::InvalidRequestError;
23
use crate::service::Context;
4+
use ldk_node::lightning::routing::router::RouteParametersConfig;
35
use ldk_node::lightning_invoice::Bolt11Invoice;
46
use ldk_server_protos::api::{Bolt11SendRequest, Bolt11SendResponse};
57
use std::str::FromStr;
@@ -12,10 +14,38 @@ pub(crate) fn handle_bolt11_send_request(
1214
let invoice = Bolt11Invoice::from_str(&request.invoice.as_str())
1315
.map_err(|_| ldk_node::NodeError::InvalidInvoice)?;
1416

17+
let route_parameters = match request.route_parameters {
18+
Some(params) => {
19+
let max_path_count: u8 = params.max_path_count.try_into().map_err(|_| {
20+
LdkServerError::new(
21+
InvalidRequestError,
22+
format!("Invalid max_path_count, must be between 0 and {}", u8::MAX),
23+
)
24+
})?;
25+
let max_channel_saturation_power_of_half: u8 =
26+
params.max_channel_saturation_power_of_half.try_into().map_err(|_| {
27+
LdkServerError::new(
28+
InvalidRequestError,
29+
format!(
30+
"Invalid max_channel_saturation_power_of_half, must be between 0 and {}",
31+
u8::MAX
32+
),
33+
)
34+
})?;
35+
Some(RouteParametersConfig {
36+
max_total_routing_fee_msat: params.max_total_routing_fee_msat,
37+
max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta,
38+
max_path_count,
39+
max_channel_saturation_power_of_half,
40+
})
41+
},
42+
None => None,
43+
};
44+
1545
let payment_id = match request.amount_msat {
16-
None => context.node.bolt11_payment().send(&invoice, None),
46+
None => context.node.bolt11_payment().send(&invoice, route_parameters),
1747
Some(amount_msat) => {
18-
context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, None)
48+
context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, route_parameters)
1949
},
2050
}?;
2151

ldk-server/src/api/bolt12_send.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::api::error::LdkServerError;
2+
use crate::api::error::LdkServerErrorCode::InvalidRequestError;
23
use crate::service::Context;
34
use ldk_node::lightning::offers::offer::Offer;
5+
use ldk_node::lightning::routing::router::RouteParametersConfig;
46
use ldk_server_protos::api::{Bolt12SendRequest, Bolt12SendResponse};
57
use std::str::FromStr;
68

@@ -12,16 +14,47 @@ pub(crate) fn handle_bolt12_send_request(
1214
let offer =
1315
Offer::from_str(&request.offer.as_str()).map_err(|_| ldk_node::NodeError::InvalidOffer)?;
1416

15-
let payment_id = match request.amount_msat {
16-
None => {
17-
context.node.bolt12_payment().send(&offer, request.quantity, request.payer_note, None)
17+
let route_parameters = match request.route_parameters {
18+
Some(params) => {
19+
let max_path_count = params.max_path_count.try_into().map_err(|_| {
20+
LdkServerError::new(
21+
InvalidRequestError,
22+
format!("Invalid max_path_count, must be between 0 and {}", u8::MAX),
23+
)
24+
})?;
25+
let max_channel_saturation_power_of_half =
26+
params.max_channel_saturation_power_of_half.try_into().map_err(|_| {
27+
LdkServerError::new(
28+
InvalidRequestError,
29+
format!(
30+
"Invalid max_channel_saturation_power_of_half, must be between 0 and {}",
31+
u8::MAX
32+
),
33+
)
34+
})?;
35+
Some(RouteParametersConfig {
36+
max_total_routing_fee_msat: params.max_total_routing_fee_msat,
37+
max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta,
38+
max_path_count,
39+
max_channel_saturation_power_of_half,
40+
})
1841
},
42+
None => None,
43+
};
44+
45+
let payment_id = match request.amount_msat {
46+
None => context.node.bolt12_payment().send(
47+
&offer,
48+
request.quantity,
49+
request.payer_note,
50+
route_parameters,
51+
),
1952
Some(amount_msat) => context.node.bolt12_payment().send_using_amount(
2053
&offer,
2154
amount_msat,
2255
request.quantity,
2356
request.payer_note,
24-
None,
57+
route_parameters,
2558
),
2659
}?;
2760

0 commit comments

Comments
 (0)