diff --git a/bindings/ldk_node.udl b/bindings/ldk_node.udl index c144a4656..da850dc11 100644 --- a/bindings/ldk_node.udl +++ b/bindings/ldk_node.udl @@ -135,7 +135,7 @@ interface Bolt12Payment { interface SpontaneousPayment { [Throws=NodeError] - PaymentId send(u64 amount_msat, PublicKey node_id); + PaymentId send(u64 amount_msat, PublicKey node_id, PaymentParameters? payment_parameters); [Throws=NodeError] void send_probes(u64 amount_msat, PublicKey node_id); }; diff --git a/src/payment/spontaneous.rs b/src/payment/spontaneous.rs index 13047eab9..a34f762a0 100644 --- a/src/payment/spontaneous.rs +++ b/src/payment/spontaneous.rs @@ -4,13 +4,13 @@ use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT}; use crate::error::Error; use crate::logger::{log_error, log_info, FilesystemLogger, Logger}; use crate::payment::store::{ - PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus, PaymentStore, + PaymentDetails, PaymentDirection, PaymentKind, PaymentParameters, PaymentStatus, PaymentStore, }; use crate::types::{ChannelManager, KeysManager}; use lightning::ln::channelmanager::{PaymentId, RecipientOnionFields, Retry, RetryableSendFailure}; use lightning::ln::{PaymentHash, PaymentPreimage}; -use lightning::routing::router::{PaymentParameters, RouteParameters}; +use lightning::routing::router::{PaymentParameters as PaymentParams, RouteParameters}; use lightning::sign::EntropySource; use bitcoin::secp256k1::PublicKey; @@ -41,8 +41,12 @@ impl SpontaneousPayment { Self { runtime, channel_manager, keys_manager, payment_store, config, logger } } - /// Send a spontaneous, aka. "keysend", payment - pub fn send(&self, amount_msat: u64, node_id: PublicKey) -> Result { + /// Send a spontaneous, or "keysend", payment given an amount in millisatoshi, node ID, and optional [`PaymentParameters`]. + /// + /// [`PaymentParameters`]: PaymentParameters + pub fn send( + &self, amount_msat: u64, node_id: PublicKey, payment_parameters: Option, + ) -> Result { let rt_lock = self.runtime.read().unwrap(); if rt_lock.is_none() { return Err(Error::NotRunning); @@ -61,10 +65,23 @@ impl SpontaneousPayment { } } - let route_params = RouteParameters::from_payment_params_and_value( - PaymentParameters::from_node_id(node_id, self.config.default_cltv_expiry_delta), + let mut route_params = RouteParameters::from_payment_params_and_value( + PaymentParams::from_node_id(node_id, self.config.default_cltv_expiry_delta), amount_msat, ); + + if let Some(payment_params) = payment_parameters { + payment_params + .expiry_time + .map(|expiry| route_params.payment_params.expiry_time = Some(expiry)); + payment_params + .max_total_routing_fee_msat + .map(|fee| route_params.max_total_routing_fee_msat = Some(fee)); + payment_params + .max_total_cltv_expiry_delta + .map(|delta| route_params.payment_params.max_total_cltv_expiry_delta = delta); + } + let recipient_fields = RecipientOnionFields::spontaneous_empty(); match self.channel_manager.send_spontaneous_payment_with_retry( diff --git a/tests/common/mod.rs b/tests/common/mod.rs index b026a233a..6c4dbc1d1 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -695,7 +695,7 @@ pub(crate) fn do_channel_full_cycle( println!("\nA send_spontaneous_payment"); let keysend_amount_msat = 2500_000; let keysend_payment_id = - node_a.spontaneous_payment().send(keysend_amount_msat, node_b.node_id()).unwrap(); + node_a.spontaneous_payment().send(keysend_amount_msat, node_b.node_id(), None).unwrap(); expect_event!(node_a, PaymentSuccessful); let received_keysend_amount = match node_b.wait_next_event() { ref e @ Event::PaymentReceived { amount_msat, .. } => {