@@ -44,7 +44,7 @@ use crate::offers::invoice_request::{
44
44
InvoiceRequest , InvoiceRequestAmountSource , InvoiceRequestBuilder , VerifiedInvoiceRequest ,
45
45
} ;
46
46
use crate :: offers:: nonce:: Nonce ;
47
- use crate :: offers:: offer:: { DerivedMetadata , Offer , OfferBuilder } ;
47
+ use crate :: offers:: offer:: { Amount , DerivedMetadata , Offer , OfferBuilder } ;
48
48
use crate :: offers:: parse:: Bolt12SemanticError ;
49
49
use crate :: offers:: refund:: { Refund , RefundBuilder } ;
50
50
use crate :: onion_message:: async_payments:: AsyncPaymentsMessage ;
@@ -60,7 +60,6 @@ use crate::types::payment::{PaymentHash, PaymentSecret};
60
60
use {
61
61
crate :: blinded_path:: message:: AsyncPaymentsContext ,
62
62
crate :: blinded_path:: payment:: AsyncBolt12OfferContext ,
63
- crate :: offers:: offer:: Amount ,
64
63
crate :: offers:: signer,
65
64
crate :: offers:: static_invoice:: { StaticInvoice , StaticInvoiceBuilder } ,
66
65
crate :: onion_message:: async_payments:: HeldHtlcAvailable ,
@@ -181,6 +180,121 @@ pub enum OfferEvents {
181
180
} ,
182
181
}
183
182
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
+
184
298
/// A BOLT12 offers code and flow utility provider, which facilitates
185
299
/// BOLT12 builder generation and onion message handling.
186
300
///
@@ -213,6 +327,8 @@ where
213
327
pub ( crate ) hrn_resolver : OMNameResolver ,
214
328
#[ cfg( feature = "dnssec" ) ]
215
329
pending_dns_onion_messages : Mutex < Vec < ( DNSResolverMessage , MessageSendInstructions ) > > ,
330
+
331
+ user_configs : FlowConfigs ,
216
332
}
217
333
218
334
impl < MR : Deref > OffersMessageFlow < MR >
@@ -223,7 +339,7 @@ where
223
339
pub fn new (
224
340
chain_hash : ChainHash , best_block : BestBlock , our_network_pubkey : PublicKey ,
225
341
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 ,
227
343
) -> Self {
228
344
Self {
229
345
chain_hash,
@@ -244,6 +360,8 @@ where
244
360
hrn_resolver : OMNameResolver :: new ( current_timestamp, best_block. height ) ,
245
361
#[ cfg( feature = "dnssec" ) ]
246
362
pending_dns_onion_messages : Mutex :: new ( Vec :: new ( ) ) ,
363
+
364
+ user_configs : configs,
247
365
}
248
366
}
249
367
0 commit comments