Skip to content

Commit aabc42e

Browse files
committed
Introduce FlowConfigs
1 parent abffc78 commit aabc42e

File tree

2 files changed

+124
-6
lines changed

2 files changed

+124
-6
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ use crate::ln::outbound_payment::{
8585
SendAlongPathArgs, StaleExpiration,
8686
};
8787
use crate::ln::types::ChannelId;
88-
use crate::offers::flow::OffersMessageFlow;
88+
use crate::offers::flow::{FlowConfigs, OffersMessageFlow};
8989
use crate::offers::invoice::{
9090
Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, InvoiceBuilderVariant,
9191
UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY,
@@ -3705,7 +3705,7 @@ where
37053705
let flow = OffersMessageFlow::new(
37063706
ChainHash::using_genesis_block(params.network), params.best_block,
37073707
our_network_pubkey, current_timestamp, expanded_inbound_key,
3708-
secp_ctx.clone(), message_router
3708+
secp_ctx.clone(), message_router, FlowConfigs::new()
37093709
);
37103710

37113711
ChannelManager {
@@ -14967,7 +14967,7 @@ where
1496714967
let flow = OffersMessageFlow::new(
1496814968
chain_hash, best_block, our_network_pubkey,
1496914969
highest_seen_timestamp, expanded_inbound_key,
14970-
secp_ctx.clone(), args.message_router
14970+
secp_ctx.clone(), args.message_router, FlowConfigs::new(),
1497114971
);
1497214972

1497314973
let channel_manager = ChannelManager {

lightning/src/offers/flow.rs

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use crate::offers::invoice_request::{
4444
InvoiceRequest, InvoiceRequestAmountSource, InvoiceRequestBuilder, VerifiedInvoiceRequest,
4545
};
4646
use crate::offers::nonce::Nonce;
47-
use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder};
47+
use crate::offers::offer::{Amount, DerivedMetadata, Offer, OfferBuilder};
4848
use crate::offers::parse::Bolt12SemanticError;
4949
use crate::offers::refund::{Refund, RefundBuilder};
5050
use crate::onion_message::async_payments::AsyncPaymentsMessage;
@@ -60,7 +60,6 @@ use crate::types::payment::{PaymentHash, PaymentSecret};
6060
use {
6161
crate::blinded_path::message::AsyncPaymentsContext,
6262
crate::blinded_path::payment::AsyncBolt12OfferContext,
63-
crate::offers::offer::Amount,
6463
crate::offers::signer,
6564
crate::offers::static_invoice::{StaticInvoice, StaticInvoiceBuilder},
6665
crate::onion_message::async_payments::HeldHtlcAvailable,
@@ -181,6 +180,121 @@ pub enum OfferEvents {
181180
},
182181
}
183182

183+
/// Configuration options for determining which [`OfferEvents`] should be generated during BOLT12 offer handling.
184+
///
185+
/// Use this to control whether events such as [`OfferEvents::InvoiceRequestReceived`] and
186+
/// [`OfferEvents::Bolt12InvoiceReceived`] are triggered automatically or suppressed, depending on your use case.
187+
///
188+
/// The default behavior disables all events (`NeverTrigger`) for both cases.
189+
pub struct FlowConfigs {
190+
/// Controls whether [`OfferEvents::InvoiceRequestReceived`] is generated upon receiving an [`InvoiceRequest`].
191+
invoice_request_configs: InvoiceRequestConfigs,
192+
193+
/// Controls whether [`OfferEvents::Bolt12InvoiceReceived`] is generated upon receiving a [`Bolt12Invoice`].
194+
invoice_configs: Bolt12InvoiceConfigs,
195+
}
196+
197+
impl FlowConfigs {
198+
/// Creates a new [`FlowConfigs`] instance with default settings.
199+
///
200+
/// By default, all events are set to `NeverTrigger`, meaning no events will be generated.
201+
pub fn new() -> Self {
202+
Self {
203+
invoice_request_configs: InvoiceRequestConfigs::NeverTrigger,
204+
invoice_configs: Bolt12InvoiceConfigs::NeverTrigger,
205+
}
206+
}
207+
208+
/// Sets the configuration for invoice request events.
209+
pub fn set_invoice_request_configs(self, configs: InvoiceRequestConfigs) -> Self {
210+
Self { invoice_request_configs: configs, ..self }
211+
}
212+
213+
/// Sets the configuration for invoice events.
214+
pub fn set_invoice_configs(self, configs: Bolt12InvoiceConfigs) -> Self {
215+
Self { invoice_configs: configs, ..self }
216+
}
217+
218+
/// Determines whether an [`InvoiceRequest`] should be handled synchronously or dispatched as an event.
219+
pub fn handle_invoice_request_asyncly(
220+
&self, invoice_request: &InvoiceRequest,
221+
) -> Result<bool, ()> {
222+
let amount_source = invoice_request.contents.amount_source().map_err(|_| ())?;
223+
224+
let config = &self.invoice_request_configs;
225+
Ok(match config {
226+
InvoiceRequestConfigs::AlwaysTrigger => true,
227+
InvoiceRequestConfigs::NeverTrigger => false,
228+
InvoiceRequestConfigs::TriggerIfOfferInCurrency => match amount_source {
229+
InvoiceRequestAmountSource::InvoiceRequestAndOfferAmount {
230+
offer_amount, ..
231+
}
232+
| InvoiceRequestAmountSource::OfferOnly { amount: offer_amount } => {
233+
matches!(offer_amount, Amount::Currency { .. })
234+
},
235+
InvoiceRequestAmountSource::InvoiceRequestOnly { .. } => false,
236+
},
237+
})
238+
}
239+
240+
/// Determines whether an [`Bolt12Invoice`] should be handled synchronously or dispatched as an event.
241+
pub fn handle_invoice_asyncly(&self, invoice: &Bolt12Invoice) -> Result<bool, ()> {
242+
let amount_source = invoice.amount_source().map_err(|_| ())?;
243+
let (ir_amount, offer_amount) = match amount_source {
244+
Bolt12InvoiceAmountSource::Offer(amount) => match amount {
245+
InvoiceRequestAmountSource::OfferOnly { amount } => (None, Some(amount)),
246+
InvoiceRequestAmountSource::InvoiceRequestAndOfferAmount {
247+
invoice_request_amount_msats,
248+
offer_amount,
249+
} => (Some(invoice_request_amount_msats), Some(offer_amount)),
250+
InvoiceRequestAmountSource::InvoiceRequestOnly { amount_msats } => {
251+
(Some(amount_msats), None)
252+
},
253+
},
254+
Bolt12InvoiceAmountSource::Refund(_) => (None, None),
255+
};
256+
Ok(match self.invoice_configs {
257+
Bolt12InvoiceConfigs::AlwaysTrigger => true,
258+
Bolt12InvoiceConfigs::TriggerIfOfferInCurrency => {
259+
matches!(offer_amount, Some(Amount::Currency { .. }))
260+
},
261+
Bolt12InvoiceConfigs::TriggerIfOfferInCurrencyAndNoIRAmount => {
262+
matches!(offer_amount, Some(Amount::Currency { .. })) && ir_amount.is_none()
263+
},
264+
Bolt12InvoiceConfigs::NeverTrigger => false,
265+
})
266+
}
267+
}
268+
269+
/// Specifies under what conditions an [`InvoiceRequest`] will generate an [`OfferEvents::InvoiceRequestReceived`] event.
270+
pub enum InvoiceRequestConfigs {
271+
/// Always trigger the event when an [`InvoiceRequest`] is received.
272+
AlwaysTrigger,
273+
274+
/// Trigger the event only if the corresponding [`Offer`] specifies an [`Amount::Currency`] amount.
275+
TriggerIfOfferInCurrency,
276+
277+
/// Never trigger the event, regardless of the incoming [`InvoiceRequest`].
278+
NeverTrigger,
279+
}
280+
281+
/// Specifies under what conditions a [`Bolt12Invoice`] will generate an [`OfferEvents::Bolt12InvoiceReceived`] event.
282+
pub enum Bolt12InvoiceConfigs {
283+
/// Always trigger the event when a [`Bolt12Invoice`] is received.
284+
AlwaysTrigger,
285+
286+
/// Trigger the event only if the invoice corresponds to an [`Offer`] flow with an [`Amount::Currency`] offer.
287+
TriggerIfOfferInCurrency,
288+
289+
/// Trigger the event only if the invoice corresponds to an [`Offer`] flow where:
290+
/// - the underlying [`Offer`] amount is in [`Amount::Currency`], and
291+
/// - the corresponding [`InvoiceRequest`] did **not** specify an amount.
292+
TriggerIfOfferInCurrencyAndNoIRAmount,
293+
294+
/// Never trigger the event, regardless of the incoming [`Bolt12Invoice`].
295+
NeverTrigger,
296+
}
297+
184298
/// A BOLT12 offers code and flow utility provider, which facilitates
185299
/// BOLT12 builder generation and onion message handling.
186300
///
@@ -213,6 +327,8 @@ where
213327
pub(crate) hrn_resolver: OMNameResolver,
214328
#[cfg(feature = "dnssec")]
215329
pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
330+
331+
user_configs: FlowConfigs,
216332
}
217333

218334
impl<MR: Deref> OffersMessageFlow<MR>
@@ -223,7 +339,7 @@ where
223339
pub fn new(
224340
chain_hash: ChainHash, best_block: BestBlock, our_network_pubkey: PublicKey,
225341
current_timestamp: u32, inbound_payment_key: inbound_payment::ExpandedKey,
226-
secp_ctx: Secp256k1<secp256k1::All>, message_router: MR,
342+
secp_ctx: Secp256k1<secp256k1::All>, message_router: MR, configs: FlowConfigs,
227343
) -> Self {
228344
Self {
229345
chain_hash,
@@ -244,6 +360,8 @@ where
244360
hrn_resolver: OMNameResolver::new(current_timestamp, best_block.height),
245361
#[cfg(feature = "dnssec")]
246362
pending_dns_onion_messages: Mutex::new(Vec::new()),
363+
364+
user_configs: configs,
247365
}
248366
}
249367

0 commit comments

Comments
 (0)