From 7aef8ee30f0e1f175b862c2a382edaf7fd4baff3 Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Tue, 9 Dec 2025 13:10:57 +0100 Subject: [PATCH 1/6] add `RouteParametersConfig` struct to proto types --- ldk-server-protos/src/proto/types.proto | 21 +++++++++++++++++++++ ldk-server-protos/src/types.rs | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/ldk-server-protos/src/proto/types.proto b/ldk-server-protos/src/proto/types.proto index 5f41441..7d65540 100644 --- a/ldk-server-protos/src/proto/types.proto +++ b/ldk-server-protos/src/proto/types.proto @@ -683,3 +683,24 @@ message Bolt11InvoiceDescription { string hash = 2; } } + +// Configuration options for payment routing and pathfinding. +// See https://docs.rs/lightning/0.2.0/lightning/routing/router/struct.RouteParametersConfig.html for more details on each field. +message RouteParametersConfig { + // The maximum total fees, in millisatoshi, that may accrue during route finding. + // Defaults to 1% of the payment amount + 50 sats + optional uint64 max_total_routing_fee_msat = 1; + + // The maximum total CLTV delta we accept for the route. + // Defaults to [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`]. + uint32 max_total_cltv_expiry_delta = 2; + + // The maximum number of paths that may be used by (MPP) payments. + // Defaults to [`DEFAULT_MAX_PATH_COUNT`]. + uint32 max_path_count = 3; + + // Selects the maximum share of a channel's total capacity which will be + // sent over a channel, as a power of 1/2. + // Default value: 2 + uint32 max_channel_saturation_power_of_half = 4; +} diff --git a/ldk-server-protos/src/types.rs b/ldk-server-protos/src/types.rs index 2e5dc8c..e44762a 100644 --- a/ldk-server-protos/src/types.rs +++ b/ldk-server-protos/src/types.rs @@ -779,6 +779,29 @@ pub mod bolt11_invoice_description { Hash(::prost::alloc::string::String), } } +/// Configuration options for payment routing and pathfinding. +/// See for more details on each field. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RouteParametersConfig { + /// The maximum total fees, in millisatoshi, that may accrue during route finding. + /// Defaults to 1% of the payment amount + 50 sats + #[prost(uint64, optional, tag = "1")] + pub max_total_routing_fee_msat: ::core::option::Option, + /// The maximum total CLTV delta we accept for the route. + /// Defaults to \[`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`\]. + #[prost(uint32, tag = "2")] + pub max_total_cltv_expiry_delta: u32, + /// The maximum number of paths that may be used by (MPP) payments. + /// Defaults to \[`DEFAULT_MAX_PATH_COUNT`\]. + #[prost(uint32, tag = "3")] + pub max_path_count: u32, + /// Selects the maximum share of a channel's total capacity which will be + /// sent over a channel, as a power of 1/2. + /// Default value: 2 + #[prost(uint32, tag = "4")] + pub max_channel_saturation_power_of_half: u32, +} /// Represents the direction of a payment. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] From 46760c82ec0651796f3ed736ad5970ace9f8abfc Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Tue, 9 Dec 2025 13:24:59 +0100 Subject: [PATCH 2/6] allow `route_parameters` in BOLT11 send API --- ldk-server-cli/src/main.rs | 33 +++++++++++++++++++++++++-- ldk-server-protos/src/api.rs | 19 ++++++++------- ldk-server-protos/src/proto/api.proto | 3 +++ ldk-server/src/api/bolt11_send.rs | 12 ++++++++-- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/ldk-server-cli/src/main.rs b/ldk-server-cli/src/main.rs index a45ec6e..c0e8ea2 100644 --- a/ldk-server-cli/src/main.rs +++ b/ldk-server-cli/src/main.rs @@ -10,6 +10,7 @@ use ldk_server_client::ldk_server_protos::api::{ ListChannelsRequest, ListPaymentsRequest, OnchainReceiveRequest, OnchainSendRequest, OpenChannelRequest, }; +use ldk_server_client::ldk_server_protos::types::RouteParametersConfig; use ldk_server_client::ldk_server_protos::types::{ bolt11_invoice_description, Bolt11InvoiceDescription, PageToken, Payment, }; @@ -55,6 +56,14 @@ enum Commands { invoice: String, #[arg(long)] amount_msat: Option, + #[arg(long)] + max_total_routing_fee_msat: Option, + #[arg(long)] + max_total_cltv_expiry_delta: Option, + #[arg(long)] + max_path_count: Option, + #[arg(long)] + max_channel_saturation_power_of_half: Option, }, Bolt12Receive { #[arg(short, long)] @@ -161,9 +170,29 @@ async fn main() { handle_response_result(client.bolt11_receive(request).await); }, - Commands::Bolt11Send { invoice, amount_msat } => { + Commands::Bolt11Send { + invoice, + amount_msat, + max_total_routing_fee_msat, + max_total_cltv_expiry_delta, + max_path_count, + max_channel_saturation_power_of_half, + } => { + let route_parameters = RouteParametersConfig { + max_total_routing_fee_msat, + max_total_cltv_expiry_delta: max_total_cltv_expiry_delta.unwrap_or_default(), + max_path_count: max_path_count.unwrap_or_default(), + max_channel_saturation_power_of_half: max_channel_saturation_power_of_half + .unwrap_or_default(), + }; handle_response_result( - client.bolt11_send(Bolt11SendRequest { invoice, amount_msat }).await, + client + .bolt11_send(Bolt11SendRequest { + invoice, + amount_msat, + route_parameters: Some(route_parameters), + }) + .await, ); }, Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => { diff --git a/ldk-server-protos/src/api.rs b/ldk-server-protos/src/api.rs index d89283b..415462c 100644 --- a/ldk-server-protos/src/api.rs +++ b/ldk-server-protos/src/api.rs @@ -133,14 +133,17 @@ pub struct Bolt11ReceiveResponse { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Bolt11SendRequest { - /// An invoice for a payment within the Lightning Network. - #[prost(string, tag = "1")] - pub invoice: ::prost::alloc::string::String, - /// Set this field when paying a so-called "zero-amount" invoice, i.e., an invoice that leaves the - /// amount paid to be determined by the user. - /// This operation will fail if the amount specified is less than the value required by the given invoice. - #[prost(uint64, optional, tag = "2")] - pub amount_msat: ::core::option::Option, + /// An invoice for a payment within the Lightning Network. + #[prost(string, tag = "1")] + pub invoice: ::prost::alloc::string::String, + /// Set this field when paying a so-called "zero-amount" invoice, i.e., an invoice that leaves the + /// amount paid to be determined by the user. + /// This operation will fail if the amount specified is less than the value required by the given invoice. + #[prost(uint64, optional, tag = "2")] + pub amount_msat: ::core::option::Option, + /// Configuration options for payment routing and pathfinding. + #[prost(message, optional, tag = "3")] + pub route_parameters: ::core::option::Option, } /// The response `content` for the `Bolt11Send` API, when HttpStatusCode is OK (200). /// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`. diff --git a/ldk-server-protos/src/proto/api.proto b/ldk-server-protos/src/proto/api.proto index 32be3c3..060b155 100644 --- a/ldk-server-protos/src/proto/api.proto +++ b/ldk-server-protos/src/proto/api.proto @@ -138,6 +138,9 @@ message Bolt11SendRequest { // amount paid to be determined by the user. // This operation will fail if the amount specified is less than the value required by the given invoice. optional uint64 amount_msat = 2; + + // Configuration options for payment routing and pathfinding. + optional types.RouteParametersConfig route_parameters = 3; } diff --git a/ldk-server/src/api/bolt11_send.rs b/ldk-server/src/api/bolt11_send.rs index 6a13143..aa4ad3d 100644 --- a/ldk-server/src/api/bolt11_send.rs +++ b/ldk-server/src/api/bolt11_send.rs @@ -1,5 +1,6 @@ use crate::api::error::LdkServerError; use crate::service::Context; +use ldk_node::lightning::routing::router::RouteParametersConfig; use ldk_node::lightning_invoice::Bolt11Invoice; use ldk_server_protos::api::{Bolt11SendRequest, Bolt11SendResponse}; use std::str::FromStr; @@ -12,10 +13,17 @@ pub(crate) fn handle_bolt11_send_request( let invoice = Bolt11Invoice::from_str(&request.invoice.as_str()) .map_err(|_| ldk_node::NodeError::InvalidInvoice)?; + let route_parameters = request.route_parameters.map(|params| RouteParametersConfig { + max_total_routing_fee_msat: params.max_total_routing_fee_msat, + max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, + max_path_count: params.max_path_count as u8, + max_channel_saturation_power_of_half: params.max_channel_saturation_power_of_half as u8, + }); + let payment_id = match request.amount_msat { - None => context.node.bolt11_payment().send(&invoice, None), + None => context.node.bolt11_payment().send(&invoice, route_parameters), Some(amount_msat) => { - context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, None) + context.node.bolt11_payment().send_using_amount(&invoice, amount_msat, route_parameters) }, }?; From 96842d24615d14e2aca08461c7f744fd45e2b43d Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Tue, 9 Dec 2025 13:50:12 +0100 Subject: [PATCH 3/6] allow `route_parameters` in BOLT12 send API --- ldk-server-cli/src/main.rs | 35 +++++++++++++++++++++++++-- ldk-server-protos/src/api.rs | 25 ++++++++++--------- ldk-server-protos/src/proto/api.proto | 3 +++ ldk-server-protos/src/types.rs | 34 +++++++++++++------------- ldk-server/src/api/bolt12_send.rs | 19 ++++++++++++--- 5 files changed, 82 insertions(+), 34 deletions(-) diff --git a/ldk-server-cli/src/main.rs b/ldk-server-cli/src/main.rs index c0e8ea2..a7e6dce 100644 --- a/ldk-server-cli/src/main.rs +++ b/ldk-server-cli/src/main.rs @@ -84,6 +84,14 @@ enum Commands { quantity: Option, #[arg(short, long)] payer_note: Option, + #[arg(long)] + max_total_routing_fee_msat: Option, + #[arg(long)] + max_total_cltv_expiry_delta: Option, + #[arg(long)] + max_path_count: Option, + #[arg(long)] + max_channel_saturation_power_of_half: Option, }, CloseChannel { #[arg(short, long)] @@ -207,10 +215,33 @@ async fn main() { .await, ); }, - Commands::Bolt12Send { offer, amount_msat, quantity, payer_note } => { + Commands::Bolt12Send { + offer, + amount_msat, + quantity, + payer_note, + max_total_routing_fee_msat, + max_total_cltv_expiry_delta, + max_path_count, + max_channel_saturation_power_of_half, + } => { + let route_parameters = RouteParametersConfig { + max_total_routing_fee_msat, + max_total_cltv_expiry_delta: max_total_cltv_expiry_delta.unwrap_or_default(), + max_path_count: max_path_count.unwrap_or_default(), + max_channel_saturation_power_of_half: max_channel_saturation_power_of_half + .unwrap_or_default(), + }; + handle_response_result( client - .bolt12_send(Bolt12SendRequest { offer, amount_msat, quantity, payer_note }) + .bolt12_send(Bolt12SendRequest { + offer, + amount_msat, + quantity, + payer_note, + route_parameters: Some(route_parameters), + }) .await, ); }, diff --git a/ldk-server-protos/src/api.rs b/ldk-server-protos/src/api.rs index 415462c..631ef83 100644 --- a/ldk-server-protos/src/api.rs +++ b/ldk-server-protos/src/api.rs @@ -133,17 +133,17 @@ pub struct Bolt11ReceiveResponse { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Bolt11SendRequest { - /// An invoice for a payment within the Lightning Network. - #[prost(string, tag = "1")] - pub invoice: ::prost::alloc::string::String, - /// Set this field when paying a so-called "zero-amount" invoice, i.e., an invoice that leaves the - /// amount paid to be determined by the user. - /// This operation will fail if the amount specified is less than the value required by the given invoice. - #[prost(uint64, optional, tag = "2")] - pub amount_msat: ::core::option::Option, - /// Configuration options for payment routing and pathfinding. - #[prost(message, optional, tag = "3")] - pub route_parameters: ::core::option::Option, + /// An invoice for a payment within the Lightning Network. + #[prost(string, tag = "1")] + pub invoice: ::prost::alloc::string::String, + /// Set this field when paying a so-called "zero-amount" invoice, i.e., an invoice that leaves the + /// amount paid to be determined by the user. + /// This operation will fail if the amount specified is less than the value required by the given invoice. + #[prost(uint64, optional, tag = "2")] + pub amount_msat: ::core::option::Option, + /// Configuration options for payment routing and pathfinding. + #[prost(message, optional, tag = "3")] + pub route_parameters: ::core::option::Option, } /// The response `content` for the `Bolt11Send` API, when HttpStatusCode is OK (200). /// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`. @@ -208,6 +208,9 @@ pub struct Bolt12SendRequest { /// If set, it will be seen by the recipient and reflected back in the invoice. #[prost(string, optional, tag = "4")] pub payer_note: ::core::option::Option<::prost::alloc::string::String>, + /// Configuration options for payment routing and pathfinding. + #[prost(message, optional, tag = "5")] + pub route_parameters: ::core::option::Option, } /// The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200). /// When HttpStatusCode is not OK (non-200), the response `content` contains a serialized `ErrorResponse`. diff --git a/ldk-server-protos/src/proto/api.proto b/ldk-server-protos/src/proto/api.proto index 060b155..49d4ff7 100644 --- a/ldk-server-protos/src/proto/api.proto +++ b/ldk-server-protos/src/proto/api.proto @@ -202,6 +202,9 @@ message Bolt12SendRequest { // If set, it will be seen by the recipient and reflected back in the invoice. optional string payer_note = 4; + + // Configuration options for payment routing and pathfinding. + optional types.RouteParametersConfig route_parameters = 5; } // The response `content` for the `Bolt12Send` API, when HttpStatusCode is OK (200). diff --git a/ldk-server-protos/src/types.rs b/ldk-server-protos/src/types.rs index e44762a..7d7b987 100644 --- a/ldk-server-protos/src/types.rs +++ b/ldk-server-protos/src/types.rs @@ -784,23 +784,23 @@ pub mod bolt11_invoice_description { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RouteParametersConfig { - /// The maximum total fees, in millisatoshi, that may accrue during route finding. - /// Defaults to 1% of the payment amount + 50 sats - #[prost(uint64, optional, tag = "1")] - pub max_total_routing_fee_msat: ::core::option::Option, - /// The maximum total CLTV delta we accept for the route. - /// Defaults to \[`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`\]. - #[prost(uint32, tag = "2")] - pub max_total_cltv_expiry_delta: u32, - /// The maximum number of paths that may be used by (MPP) payments. - /// Defaults to \[`DEFAULT_MAX_PATH_COUNT`\]. - #[prost(uint32, tag = "3")] - pub max_path_count: u32, - /// Selects the maximum share of a channel's total capacity which will be - /// sent over a channel, as a power of 1/2. - /// Default value: 2 - #[prost(uint32, tag = "4")] - pub max_channel_saturation_power_of_half: u32, + /// The maximum total fees, in millisatoshi, that may accrue during route finding. + /// Defaults to 1% of the payment amount + 50 sats + #[prost(uint64, optional, tag = "1")] + pub max_total_routing_fee_msat: ::core::option::Option, + /// The maximum total CLTV delta we accept for the route. + /// Defaults to \[`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`\]. + #[prost(uint32, tag = "2")] + pub max_total_cltv_expiry_delta: u32, + /// The maximum number of paths that may be used by (MPP) payments. + /// Defaults to \[`DEFAULT_MAX_PATH_COUNT`\]. + #[prost(uint32, tag = "3")] + pub max_path_count: u32, + /// Selects the maximum share of a channel's total capacity which will be + /// sent over a channel, as a power of 1/2. + /// Default value: 2 + #[prost(uint32, tag = "4")] + pub max_channel_saturation_power_of_half: u32, } /// Represents the direction of a payment. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] diff --git a/ldk-server/src/api/bolt12_send.rs b/ldk-server/src/api/bolt12_send.rs index bbf392a..0154bab 100644 --- a/ldk-server/src/api/bolt12_send.rs +++ b/ldk-server/src/api/bolt12_send.rs @@ -1,6 +1,7 @@ use crate::api::error::LdkServerError; use crate::service::Context; use ldk_node::lightning::offers::offer::Offer; +use ldk_node::lightning::routing::router::RouteParametersConfig; use ldk_server_protos::api::{Bolt12SendRequest, Bolt12SendResponse}; use std::str::FromStr; @@ -12,16 +13,26 @@ pub(crate) fn handle_bolt12_send_request( let offer = Offer::from_str(&request.offer.as_str()).map_err(|_| ldk_node::NodeError::InvalidOffer)?; + let route_parameters = request.route_parameters.map(|params| RouteParametersConfig { + max_total_routing_fee_msat: params.max_total_routing_fee_msat, + max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, + max_path_count: params.max_path_count as u8, + max_channel_saturation_power_of_half: params.max_channel_saturation_power_of_half as u8, + }); + let payment_id = match request.amount_msat { - None => { - context.node.bolt12_payment().send(&offer, request.quantity, request.payer_note, None) - }, + None => context.node.bolt12_payment().send( + &offer, + request.quantity, + request.payer_note, + route_parameters, + ), Some(amount_msat) => context.node.bolt12_payment().send_using_amount( &offer, amount_msat, request.quantity, request.payer_note, - None, + route_parameters, ), }?; From 61df07d19eae5c418de7d866e949683e515895e7 Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Wed, 10 Dec 2025 08:36:25 +0100 Subject: [PATCH 4/6] removed `unwrap_or_default()` and using actual default values --- ldk-server-cli/src/main.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/ldk-server-cli/src/main.rs b/ldk-server-cli/src/main.rs index a7e6dce..b948681 100644 --- a/ldk-server-cli/src/main.rs +++ b/ldk-server-cli/src/main.rs @@ -16,6 +16,13 @@ use ldk_server_client::ldk_server_protos::types::{ }; use std::fmt::Debug; +// Having these default values as constants in the Proto file and +// importing/reusing them here might be better, but Proto3 removed +// the ability to set default values. +const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA: u32 = 1008; +const DEFAULT_MAX_PATH_COUNT: u32 = 10; +const DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF: u32 = 2; + #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Cli { @@ -188,10 +195,11 @@ async fn main() { } => { let route_parameters = RouteParametersConfig { max_total_routing_fee_msat, - max_total_cltv_expiry_delta: max_total_cltv_expiry_delta.unwrap_or_default(), - max_path_count: max_path_count.unwrap_or_default(), + max_total_cltv_expiry_delta: max_total_cltv_expiry_delta + .unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA), + max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT), max_channel_saturation_power_of_half: max_channel_saturation_power_of_half - .unwrap_or_default(), + .unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF), }; handle_response_result( client @@ -227,10 +235,11 @@ async fn main() { } => { let route_parameters = RouteParametersConfig { max_total_routing_fee_msat, - max_total_cltv_expiry_delta: max_total_cltv_expiry_delta.unwrap_or_default(), - max_path_count: max_path_count.unwrap_or_default(), + max_total_cltv_expiry_delta: max_total_cltv_expiry_delta + .unwrap_or(DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA), + max_path_count: max_path_count.unwrap_or(DEFAULT_MAX_PATH_COUNT), max_channel_saturation_power_of_half: max_channel_saturation_power_of_half - .unwrap_or_default(), + .unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF), }; handle_response_result( From 262acbe444d5396bfc486345fd6eb7ea4e1346eb Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Wed, 10 Dec 2025 08:50:15 +0100 Subject: [PATCH 5/6] use actual values in `RouteParametersConfig` proto field definition --- ldk-server-protos/src/proto/types.proto | 4 ++-- ldk-server-protos/src/types.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ldk-server-protos/src/proto/types.proto b/ldk-server-protos/src/proto/types.proto index 7d65540..7306169 100644 --- a/ldk-server-protos/src/proto/types.proto +++ b/ldk-server-protos/src/proto/types.proto @@ -692,11 +692,11 @@ message RouteParametersConfig { optional uint64 max_total_routing_fee_msat = 1; // The maximum total CLTV delta we accept for the route. - // Defaults to [`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`]. + // Defaults to 1008. uint32 max_total_cltv_expiry_delta = 2; // The maximum number of paths that may be used by (MPP) payments. - // Defaults to [`DEFAULT_MAX_PATH_COUNT`]. + // Defaults to 10. uint32 max_path_count = 3; // Selects the maximum share of a channel's total capacity which will be diff --git a/ldk-server-protos/src/types.rs b/ldk-server-protos/src/types.rs index 7d7b987..3251bc4 100644 --- a/ldk-server-protos/src/types.rs +++ b/ldk-server-protos/src/types.rs @@ -789,11 +789,11 @@ pub struct RouteParametersConfig { #[prost(uint64, optional, tag = "1")] pub max_total_routing_fee_msat: ::core::option::Option, /// The maximum total CLTV delta we accept for the route. - /// Defaults to \[`DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA`\]. + /// Defaults to 1008. #[prost(uint32, tag = "2")] pub max_total_cltv_expiry_delta: u32, /// The maximum number of paths that may be used by (MPP) payments. - /// Defaults to \[`DEFAULT_MAX_PATH_COUNT`\]. + /// Defaults to 10. #[prost(uint32, tag = "3")] pub max_path_count: u32, /// Selects the maximum share of a channel's total capacity which will be From a8de0d1f05243c009218df28cc603539fe67734c Mon Sep 17 00:00:00 2001 From: Anyitechs Date: Wed, 10 Dec 2025 09:59:02 +0100 Subject: [PATCH 6/6] remove type casting & use `try_into()` for conversion --- ldk-server/src/api/bolt11_send.rs | 34 +++++++++++++++++++++++++------ ldk-server/src/api/bolt12_send.rs | 34 +++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/ldk-server/src/api/bolt11_send.rs b/ldk-server/src/api/bolt11_send.rs index aa4ad3d..fd22b41 100644 --- a/ldk-server/src/api/bolt11_send.rs +++ b/ldk-server/src/api/bolt11_send.rs @@ -1,4 +1,5 @@ use crate::api::error::LdkServerError; +use crate::api::error::LdkServerErrorCode::InvalidRequestError; use crate::service::Context; use ldk_node::lightning::routing::router::RouteParametersConfig; use ldk_node::lightning_invoice::Bolt11Invoice; @@ -13,12 +14,33 @@ pub(crate) fn handle_bolt11_send_request( let invoice = Bolt11Invoice::from_str(&request.invoice.as_str()) .map_err(|_| ldk_node::NodeError::InvalidInvoice)?; - let route_parameters = request.route_parameters.map(|params| RouteParametersConfig { - max_total_routing_fee_msat: params.max_total_routing_fee_msat, - max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, - max_path_count: params.max_path_count as u8, - max_channel_saturation_power_of_half: params.max_channel_saturation_power_of_half as u8, - }); + let route_parameters = match request.route_parameters { + Some(params) => { + let max_path_count: u8 = params.max_path_count.try_into().map_err(|_| { + LdkServerError::new( + InvalidRequestError, + format!("Invalid max_path_count, must be between 0 and {}", u8::MAX), + ) + })?; + let max_channel_saturation_power_of_half: u8 = + params.max_channel_saturation_power_of_half.try_into().map_err(|_| { + LdkServerError::new( + InvalidRequestError, + format!( + "Invalid max_channel_saturation_power_of_half, must be between 0 and {}", + u8::MAX + ), + ) + })?; + Some(RouteParametersConfig { + max_total_routing_fee_msat: params.max_total_routing_fee_msat, + max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, + max_path_count, + max_channel_saturation_power_of_half, + }) + }, + None => None, + }; let payment_id = match request.amount_msat { None => context.node.bolt11_payment().send(&invoice, route_parameters), diff --git a/ldk-server/src/api/bolt12_send.rs b/ldk-server/src/api/bolt12_send.rs index 0154bab..439fe13 100644 --- a/ldk-server/src/api/bolt12_send.rs +++ b/ldk-server/src/api/bolt12_send.rs @@ -1,4 +1,5 @@ use crate::api::error::LdkServerError; +use crate::api::error::LdkServerErrorCode::InvalidRequestError; use crate::service::Context; use ldk_node::lightning::offers::offer::Offer; use ldk_node::lightning::routing::router::RouteParametersConfig; @@ -13,12 +14,33 @@ pub(crate) fn handle_bolt12_send_request( let offer = Offer::from_str(&request.offer.as_str()).map_err(|_| ldk_node::NodeError::InvalidOffer)?; - let route_parameters = request.route_parameters.map(|params| RouteParametersConfig { - max_total_routing_fee_msat: params.max_total_routing_fee_msat, - max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, - max_path_count: params.max_path_count as u8, - max_channel_saturation_power_of_half: params.max_channel_saturation_power_of_half as u8, - }); + let route_parameters = match request.route_parameters { + Some(params) => { + let max_path_count = params.max_path_count.try_into().map_err(|_| { + LdkServerError::new( + InvalidRequestError, + format!("Invalid max_path_count, must be between 0 and {}", u8::MAX), + ) + })?; + let max_channel_saturation_power_of_half = + params.max_channel_saturation_power_of_half.try_into().map_err(|_| { + LdkServerError::new( + InvalidRequestError, + format!( + "Invalid max_channel_saturation_power_of_half, must be between 0 and {}", + u8::MAX + ), + ) + })?; + Some(RouteParametersConfig { + max_total_routing_fee_msat: params.max_total_routing_fee_msat, + max_total_cltv_expiry_delta: params.max_total_cltv_expiry_delta, + max_path_count, + max_channel_saturation_power_of_half, + }) + }, + None => None, + }; let payment_id = match request.amount_msat { None => context.node.bolt12_payment().send(