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