@@ -69,6 +69,8 @@ use crate::offers::offer::{Offer, OfferBuilder};
69
69
use crate::offers::parse::Bolt12SemanticError;
70
70
use crate::offers::refund::{Refund, RefundBuilder};
71
71
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
72
+ #[cfg(async_payments)]
73
+ use crate::offers::static_invoice::StaticInvoice;
72
74
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
73
75
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
74
76
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
@@ -4251,6 +4253,33 @@ where
4251
4253
)
4252
4254
}
4253
4255
4256
+ #[cfg(async_payments)]
4257
+ fn initiate_async_payment(
4258
+ &self, invoice: &StaticInvoice, payment_id: PaymentId
4259
+ ) -> Result<(), Bolt12PaymentError> {
4260
+ let reply_path = self.create_blinded_path(
4261
+ MessageContext::AsyncPayments(AsyncPaymentsContext::OutboundPayment { payment_id })
4262
+ ).map_err(|_| Bolt12PaymentError::BlindedPathNotFound)?;
4263
+
4264
+ let payment_release_secret = self.pending_outbound_payments.static_invoice_received(
4265
+ invoice, payment_id, &*self.entropy_source
4266
+ )?;
4267
+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4268
+
4269
+ let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4270
+ const HTLC_AVAILABLE_LIMIT: usize = 10;
4271
+ for path in invoice.message_paths().into_iter().take(HTLC_AVAILABLE_LIMIT) {
4272
+ let message = new_pending_onion_message(
4273
+ AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable { payment_release_secret }),
4274
+ Destination::BlindedPath(path.clone()),
4275
+ Some(reply_path.clone()),
4276
+ );
4277
+ pending_async_payments_messages.push(message);
4278
+ }
4279
+
4280
+ Ok(())
4281
+ }
4282
+
4254
4283
/// Signals that no further attempts for the given payment should occur. Useful if you have a
4255
4284
/// pending outbound payment with retries remaining, but wish to stop retrying the payment before
4256
4285
/// retries are exhausted.
@@ -10878,15 +10907,17 @@ where
10878
10907
}
10879
10908
},
10880
10909
#[cfg(async_payments)]
10881
- OffersMessage::StaticInvoice(_invoice) => {
10882
- match responder {
10883
- Some(responder) => {
10884
- responder.respond(OffersMessage::InvoiceError(
10885
- InvoiceError::from_string("Static invoices not yet supported".to_string())
10886
- ))
10887
- },
10888
- None => return ResponseInstruction::NoResponse,
10910
+ OffersMessage::StaticInvoice(invoice) => {
10911
+ let payment_id = match context {
10912
+ OffersContext::OutboundPayment { payment_id } => payment_id,
10913
+ _ => {
10914
+ return ResponseInstruction::NoResponse
10915
+ }
10916
+ };
10917
+ if let Err(e) = self.initiate_async_payment(&invoice, payment_id) {
10918
+ log_trace!(self.logger, "Failed to initiate async payment to static invoice: {:?}", e);
10889
10919
}
10920
+ ResponseInstruction::NoResponse
10890
10921
},
10891
10922
OffersMessage::InvoiceError(invoice_error) => {
10892
10923
abandon_if_payment(context);
@@ -10922,7 +10953,7 @@ where
10922
10953
fn release_held_htlc(&self, _message: ReleaseHeldHtlc, _context: AsyncPaymentsContext) {}
10923
10954
10924
10955
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<AsyncPaymentsMessage>> {
10925
- Vec::new( )
10956
+ core::mem::take(&mut self.pending_async_payments_messages.lock().unwrap() )
10926
10957
}
10927
10958
}
10928
10959
0 commit comments