1use crate::config::{Config, LDK_PAYMENT_RETRY_TIMEOUT};
11use crate::error::Error;
12use crate::logger::{log_error, log_info, LdkLogger, Logger};
13use crate::payment::store::{PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus};
14use crate::payment::SendingParameters;
15use crate::types::{ChannelManager, CustomTlvRecord, KeysManager, PaymentStore};
16
17use lightning::ln::channelmanager::{PaymentId, RecipientOnionFields, Retry, RetryableSendFailure};
18use lightning::routing::router::{PaymentParameters, RouteParameters};
19use lightning::sign::EntropySource;
20
21use lightning_types::payment::{PaymentHash, PaymentPreimage};
22
23use bitcoin::secp256k1::PublicKey;
24
25use std::sync::{Arc, RwLock};
26
27const LDK_DEFAULT_FINAL_CLTV_EXPIRY_DELTA: u32 = 144;
29
30pub struct SpontaneousPayment {
36 runtime: Arc<RwLock<Option<Arc<tokio::runtime::Runtime>>>>,
37 channel_manager: Arc<ChannelManager>,
38 keys_manager: Arc<KeysManager>,
39 payment_store: Arc<PaymentStore>,
40 config: Arc<Config>,
41 logger: Arc<Logger>,
42}
43
44impl SpontaneousPayment {
45 pub(crate) fn new(
46 runtime: Arc<RwLock<Option<Arc<tokio::runtime::Runtime>>>>,
47 channel_manager: Arc<ChannelManager>, keys_manager: Arc<KeysManager>,
48 payment_store: Arc<PaymentStore>, config: Arc<Config>, logger: Arc<Logger>,
49 ) -> Self {
50 Self { runtime, channel_manager, keys_manager, payment_store, config, logger }
51 }
52
53 pub fn send(
58 &self, amount_msat: u64, node_id: PublicKey, sending_parameters: Option<SendingParameters>,
59 ) -> Result<PaymentId, Error> {
60 self.send_inner(amount_msat, node_id, sending_parameters, None)
61 }
62
63 pub fn send_with_custom_tlvs(
65 &self, amount_msat: u64, node_id: PublicKey, sending_parameters: Option<SendingParameters>,
66 custom_tlvs: Vec<CustomTlvRecord>,
67 ) -> Result<PaymentId, Error> {
68 self.send_inner(amount_msat, node_id, sending_parameters, Some(custom_tlvs))
69 }
70
71 fn send_inner(
72 &self, amount_msat: u64, node_id: PublicKey, sending_parameters: Option<SendingParameters>,
73 custom_tlvs: Option<Vec<CustomTlvRecord>>,
74 ) -> Result<PaymentId, Error> {
75 let rt_lock = self.runtime.read().unwrap();
76 if rt_lock.is_none() {
77 return Err(Error::NotRunning);
78 }
79
80 let payment_preimage = PaymentPreimage(self.keys_manager.get_secure_random_bytes());
81 let payment_hash = PaymentHash::from(payment_preimage);
82 let payment_id = PaymentId(payment_hash.0);
83
84 if let Some(payment) = self.payment_store.get(&payment_id) {
85 if payment.status == PaymentStatus::Pending
86 || payment.status == PaymentStatus::Succeeded
87 {
88 log_error!(self.logger, "Payment error: must not send duplicate payments.");
89 return Err(Error::DuplicatePayment);
90 }
91 }
92
93 let mut route_params = RouteParameters::from_payment_params_and_value(
94 PaymentParameters::from_node_id(node_id, LDK_DEFAULT_FINAL_CLTV_EXPIRY_DELTA),
95 amount_msat,
96 );
97
98 let override_params =
99 sending_parameters.as_ref().or(self.config.sending_parameters.as_ref());
100 if let Some(override_params) = override_params {
101 override_params
102 .max_total_routing_fee_msat
103 .map(|f| route_params.max_total_routing_fee_msat = f.into());
104 override_params
105 .max_total_cltv_expiry_delta
106 .map(|d| route_params.payment_params.max_total_cltv_expiry_delta = d);
107 override_params.max_path_count.map(|p| route_params.payment_params.max_path_count = p);
108 override_params
109 .max_channel_saturation_power_of_half
110 .map(|s| route_params.payment_params.max_channel_saturation_power_of_half = s);
111 };
112
113 let recipient_fields = match custom_tlvs {
114 Some(tlvs) => RecipientOnionFields::spontaneous_empty()
115 .with_custom_tlvs(tlvs.into_iter().map(|tlv| (tlv.type_num, tlv.value)).collect())
116 .map_err(|e| {
117 log_error!(self.logger, "Failed to send payment with custom TLVs: {:?}", e);
118 Error::InvalidCustomTlvs
119 })?,
120 None => RecipientOnionFields::spontaneous_empty(),
121 };
122
123 match self.channel_manager.send_spontaneous_payment(
124 Some(payment_preimage),
125 recipient_fields,
126 PaymentId(payment_hash.0),
127 route_params,
128 Retry::Timeout(LDK_PAYMENT_RETRY_TIMEOUT),
129 ) {
130 Ok(_hash) => {
131 log_info!(self.logger, "Initiated sending {}msat to {}.", amount_msat, node_id);
132
133 let kind = PaymentKind::Spontaneous {
134 hash: payment_hash,
135 preimage: Some(payment_preimage),
136 };
137 let payment = PaymentDetails::new(
138 payment_id,
139 kind,
140 Some(amount_msat),
141 None,
142 PaymentDirection::Outbound,
143 PaymentStatus::Pending,
144 );
145 self.payment_store.insert(payment)?;
146
147 Ok(payment_id)
148 },
149 Err(e) => {
150 log_error!(self.logger, "Failed to send payment: {:?}", e);
151
152 match e {
153 RetryableSendFailure::DuplicatePayment => Err(Error::DuplicatePayment),
154 _ => {
155 let kind = PaymentKind::Spontaneous {
156 hash: payment_hash,
157 preimage: Some(payment_preimage),
158 };
159 let payment = PaymentDetails::new(
160 payment_id,
161 kind,
162 Some(amount_msat),
163 None,
164 PaymentDirection::Outbound,
165 PaymentStatus::Failed,
166 );
167
168 self.payment_store.insert(payment)?;
169 Err(Error::PaymentSendingFailed)
170 },
171 }
172 },
173 }
174 }
175
176 pub fn send_probes(&self, amount_msat: u64, node_id: PublicKey) -> Result<(), Error> {
183 let rt_lock = self.runtime.read().unwrap();
184 if rt_lock.is_none() {
185 return Err(Error::NotRunning);
186 }
187
188 let liquidity_limit_multiplier = Some(self.config.probing_liquidity_limit_multiplier);
189
190 self.channel_manager
191 .send_spontaneous_preflight_probes(
192 node_id,
193 amount_msat,
194 LDK_DEFAULT_FINAL_CLTV_EXPIRY_DELTA,
195 liquidity_limit_multiplier,
196 )
197 .map_err(|e| {
198 log_error!(self.logger, "Failed to send payment probes: {:?}", e);
199 Error::ProbeSendingFailed
200 })?;
201
202 Ok(())
203 }
204}