@@ -67,6 +67,8 @@ use crate::offers::offer::{Offer, OfferBuilder};
67
67
use crate::offers::parse::Bolt12SemanticError;
68
68
use crate::offers::refund::{Refund, RefundBuilder};
69
69
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
70
+ #[cfg(async_payments)]
71
+ use crate::offers::static_invoice::StaticInvoice;
70
72
use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction};
71
73
use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
72
74
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
@@ -4046,6 +4048,34 @@ where
4046
4048
)
4047
4049
}
4048
4050
4051
+ #[cfg(async_payments)]
4052
+ fn initiate_async_payment(
4053
+ &self, invoice: &StaticInvoice, payment_id: PaymentId
4054
+ ) -> Result<(), InvoiceError> {
4055
+ if invoice.message_paths().is_empty() { return Err(Bolt12SemanticError::MissingPaths.into()) }
4056
+
4057
+ let reply_path = self.create_blinded_path(Some(payment_id))
4058
+ .map_err(|_| Bolt12SemanticError::MissingPaths)?;
4059
+
4060
+ let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4061
+ let payment_release_secret = self.pending_outbound_payments.static_invoice_received(
4062
+ invoice, payment_id, &*self.entropy_source
4063
+ ).map_err(|e| InvoiceError::from_string(format!("{:?}", e)))?;
4064
+
4065
+ let mut pending_async_payments_messages = self.pending_async_payments_messages.lock().unwrap();
4066
+ const HTLC_AVAILABLE_LIMIT: usize = 10;
4067
+ for path in invoice.message_paths().into_iter().take(HTLC_AVAILABLE_LIMIT) {
4068
+ let message = new_pending_onion_message(
4069
+ AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable { payment_release_secret }),
4070
+ Destination::BlindedPath(path.clone()),
4071
+ Some(reply_path.clone()),
4072
+ );
4073
+ pending_async_payments_messages.push(message);
4074
+ }
4075
+
4076
+ Ok(())
4077
+ }
4078
+
4049
4079
/// Signals that no further attempts for the given payment should occur. Useful if you have a
4050
4080
/// pending outbound payment with retries remaining, but wish to stop retrying the payment before
4051
4081
/// retries are exhausted.
@@ -10389,14 +10419,22 @@ where
10389
10419
}
10390
10420
},
10391
10421
#[cfg(async_payments)]
10392
- OffersMessage::StaticInvoice(_invoice) => {
10393
- match responder {
10394
- Some(responder) => {
10395
- responder.respond(OffersMessage::InvoiceError(
10396
- InvoiceError::from_string("Static invoices not yet supported".to_string())
10397
- ))
10398
- },
10422
+ OffersMessage::StaticInvoice(invoice) => {
10423
+ let responder = match responder {
10424
+ Some(responder) => responder,
10399
10425
None => return ResponseInstruction::NoResponse,
10426
+ };
10427
+ let payment_id = match _payment_id {
10428
+ Some(id) => id,
10429
+ None => {
10430
+ return responder.respond(OffersMessage::InvoiceError(
10431
+ InvoiceError::from_string("Unrecognized invoice".to_string())
10432
+ ))
10433
+ }
10434
+ };
10435
+ match self.initiate_async_payment(&invoice, payment_id) {
10436
+ Ok(()) => return ResponseInstruction::NoResponse,
10437
+ Err(e) => responder.respond(OffersMessage::InvoiceError(e)),
10400
10438
}
10401
10439
},
10402
10440
OffersMessage::InvoiceError(invoice_error) => {
@@ -10432,7 +10470,7 @@ where
10432
10470
fn release_held_htlc(&self, _message: ReleaseHeldHtlc, _payment_id: Option<PaymentId>) {}
10433
10471
10434
10472
fn release_pending_messages(&self) -> Vec<PendingOnionMessage<AsyncPaymentsMessage>> {
10435
- Vec::new( )
10473
+ core::mem::take(&mut self.pending_async_payments_messages.lock().unwrap() )
10436
10474
}
10437
10475
}
10438
10476
0 commit comments