Struct OffersMessageFlow

Source
pub struct OffersMessageFlow<MR: Deref, L: Deref>{ /* private fields */ }
Expand description

A BOLT12 offers code and flow utility provider, which facilitates BOLT12 builder generation and onion message handling.

OffersMessageFlow is parameterized by a MessageRouter, which is responsible for finding message paths when initiating and retrying onion messages.

Implementations§

Source§

impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>

Source

pub fn new( chain_hash: ChainHash, best_block: BestBlock, our_network_pubkey: PublicKey, current_timestamp: u32, inbound_payment_key: ExpandedKey, receive_auth_key: ReceiveAuthKey, secp_ctx: Secp256k1<All>, message_router: MR, logger: L, ) -> Self

Creates a new OffersMessageFlow

Source

pub fn with_async_payments_offers_cache( self, async_receive_offer_cache: AsyncReceiveOfferCache, ) -> Self

If we are an async recipient, on startup we’ll interactively build offers and static invoices with an always-online node that will serve static invoices on our behalf. Once the offer is built and the static invoice is confirmed as persisted by the server, the underlying AsyncReceiveOfferCache should be persisted using Self::writeable_async_receive_offer_cache so we remember the offers we’ve built.

Source

pub fn set_paths_to_static_invoice_server( &self, paths_to_static_invoice_server: Vec<BlindedMessagePath>, peers: Vec<MessageForwardNode>, ) -> Result<(), ()>

Sets the BlindedMessagePaths that we will use as an async recipient to interactively build Offers with a static invoice server, so the server can serve StaticInvoices to payers on our behalf when we’re offline.

This method will also send out messages initiating async offer creation to the static invoice server, if any peers are connected.

This method only needs to be called once when the server first takes on the recipient as a client, or when the paths change, e.g. if the paths are set to expire at a particular time.

Source

pub fn best_block_updated(&self, header: &Header, _height: u32)

Notifies the OffersMessageFlow that a new block has been observed.

This allows the flow to keep in sync with the latest block timestamp, which may be used for time-sensitive operations.

Must be called whenever a new chain tip becomes available. May be skipped for intermediary blocks.

Source§

impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>

Source

pub fn blinded_paths_for_async_recipient( &self, recipient_id: Vec<u8>, relative_expiry: Option<Duration>, peers: Vec<MessageForwardNode>, ) -> Result<Vec<BlindedMessagePath>, ()>

BlindedMessagePaths for an async recipient to communicate with this node and interactively build Offers and StaticInvoices for receiving async payments.

If relative_expiry is unset, the BlindedMessagePaths will never expire.

Returns the paths that the recipient should be configured with via Self::set_paths_to_static_invoice_server.

Errors if blinded path creation fails or the provided recipient_id is larger than 1KiB.

Source§

impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>

Source

pub fn verify_invoice_request( &self, invoice_request: InvoiceRequest, context: Option<OffersContext>, ) -> Result<InvreqResponseInstructions, ()>

Verifies an InvoiceRequest using the provided OffersContext or the InvoiceRequest::metadata.

  • If an OffersContext::InvoiceRequest with a nonce is provided, verification is performed using recipient context data.
  • If no context is provided but the InvoiceRequest contains Offer metadata, verification is performed using that metadata.
  • If neither is available, verification fails.
§Errors

Returns an error if:

  • Both OffersContext and InvoiceRequest metadata are absent or invalid.
  • The verification process (via recipient context data or metadata) fails.
Source

pub fn verify_bolt12_invoice( &self, invoice: &Bolt12Invoice, context: Option<&OffersContext>, ) -> Result<PaymentId, ()>

Verifies a Bolt12Invoice using the provided OffersContext or the invoice’s payer metadata, returning the corresponding PaymentId if successful.

  • If an OffersContext::OutboundPayment with a nonce is provided, verification is performed using this to form the payer metadata.
  • If no context is provided and the invoice corresponds to a Refund without blinded paths, verification is performed using the Bolt12Invoice::payer_metadata.
  • If neither condition is met, verification fails.
Source

pub fn verify_inbound_async_payment_context( &self, context: AsyncPaymentsContext, ) -> Result<(), ()>

Verifies the provided AsyncPaymentsContext for an inbound HeldHtlcAvailable message.

Because blinded path contexts are verified as a part of onion message processing, this only validates that the context is not yet expired based on path_absolute_expiry.

§Errors

Returns Err(()) if:

  • The inbound payment context has expired.
Source

pub fn create_offer_builder<ES: Deref>( &self, entropy_source: ES, peers: Vec<MessageForwardNode>, ) -> Result<OfferBuilder<'_, DerivedMetadata, All>, Bolt12SemanticError>
where ES::Target: EntropySource,

Creates an OfferBuilder such that the Offer it builds is recognized by the OffersMessageFlow, and any corresponding InvoiceRequest can be verified using Self::verify_invoice_request. The offer will expire at absolute_expiry if Some, or will not expire if None.

§Privacy

Uses MessageRouter provided at construction to construct a BlindedMessagePath for the offer. See the documentation of the selected MessageRouter for details on how it selects blinded paths including privacy implications and reliability tradeoffs.

Also uses a derived signing pubkey in the offer for recipient privacy.

§Limitations

If DefaultMessageRouter is used to parameterize the OffersMessageFlow, a direct connection to the introduction node in the responding InvoiceRequest’s reply path is required. See the DefaultMessageRouter documentation for more details.

§Errors

Returns an error if the parameterized Router is unable to create a blinded path for the offer.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>( &self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>, ) -> Result<OfferBuilder<'_, DerivedMetadata, All>, Bolt12SemanticError>

Same as Self::create_offer_builder, but allows specifying a custom MessageRouter instead of using the one provided via the OffersMessageFlow parameterization.

This gives users full control over how the BlindedMessagePath is constructed, including the option to omit it entirely.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

See Self::create_offer_builder for more details on usage.

Source

pub fn create_async_receive_offer_builder<ES: Deref>( &self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>, ) -> Result<(OfferBuilder<'_, DerivedMetadata, All>, Nonce), Bolt12SemanticError>
where ES::Target: EntropySource,

Create an offer for receiving async payments as an often-offline recipient.

Because we may be offline when the payer attempts to request an invoice, you MUST:

  1. Provide at least 1 BlindedMessagePath terminating at an always-online node that will serve the StaticInvoice created from this offer on our behalf.
  2. Use Self::create_static_invoice_builder to create a StaticInvoice from this Offer plus the returned Nonce, and provide the static invoice to the aforementioned always-online node.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_refund_builder<ES: Deref>( &self, entropy_source: ES, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId, peers: Vec<MessageForwardNode>, ) -> Result<RefundBuilder<'_, All>, Bolt12SemanticError>
where ES::Target: EntropySource,

Creates a RefundBuilder such that the Refund it builds is recognized by the OffersMessageFlow, and any corresponding Bolt12Invoice received for the refund can be verified using Self::verify_bolt12_invoice.

§Privacy

Uses MessageRouter provided at construction to construct a BlindedMessagePath for the refund. See the documentation of the selected MessageRouter for details on how it selects blinded paths including privacy implications and reliability tradeoffs.

The builder will have the provided expiration set. Any changes to the expiration on the returned builder will not be honored by OffersMessageFlow. For non-std, the highest seen block time minus two hours is used for the current time when determining if the refund has expired.

The refund can be revoked by the user prior to receiving the invoice. If abandoned, or if an invoice is not received before expiration, the payment will fail with an Event::PaymentFailed.

If max_total_routing_fee_msat is not specified, the default from RouteParameters::from_payment_params_and_value is applied.

Also uses a derived payer id in the refund for payer privacy.

§Errors

Returns an error if:

  • A duplicate payment_id is provided, given the caveats in the aforementioned link.
  • amount_msats is invalid, or
  • The parameterized Router is unable to create a blinded path for the refund.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_refund_builder_using_router<ES: Deref, ME: Deref>( &self, router: ME, entropy_source: ES, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId, peers: Vec<MessageForwardNode>, ) -> Result<RefundBuilder<'_, All>, Bolt12SemanticError>

Same as Self::create_refund_builder but allows specifying a custom MessageRouter instead of using the one provided via the OffersMessageFlow parameterization.

This gives users full control over how the BlindedMessagePath is constructed, including the option to omit it entirely.

See Self::create_refund_builder for more details on usage.

§Errors

In addition to the errors documented in Self::create_refund_builder, this method will return an error if the provided MessageRouter fails to construct a valid BlindedMessagePath for the refund.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_invoice_request_builder<'a>( &'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId, ) -> Result<InvoiceRequestBuilder<'a, 'a, All>, Bolt12SemanticError>

Creates an InvoiceRequestBuilder such that the InvoiceRequest it builds is recognized by the OffersMessageFlow, and any corresponding Bolt12Invoice received in response can be verified using Self::verify_bolt12_invoice.

§Nonce

The nonce is used to create a unique InvoiceRequest::payer_metadata for the invoice request. These will be used to verify the corresponding Bolt12Invoice when it is received.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>( &self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce, payment_secret: PaymentSecret, relative_expiry_secs: u32, usable_channels: Vec<ChannelDetails>, peers: Vec<MessageForwardNode>, ) -> Result<StaticInvoiceBuilder<'a>, Bolt12SemanticError>

Creates a StaticInvoiceBuilder from the corresponding Offer and Nonce that were created via Self::create_async_receive_offer_builder.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref>( &'a self, router: &R, entropy_source: ES, refund: &'a Refund, payment_hash: PaymentHash, payment_secret: PaymentSecret, usable_channels: Vec<ChannelDetails>, ) -> Result<InvoiceBuilder<'a, DerivedSigningPubkey>, Bolt12SemanticError>

Creates an InvoiceBuilder using the provided Refund.

This method is used when a node wishes to construct an InvoiceBuilder in response to a Refund request as part of a BOLT 12 flow.

Returns an InvoiceBuilder configured with:

  • Blinded payment paths created using the parameterized Router, with the provided payment_secret included in the path payloads.
  • The given payment_hash and payment_secret, enabling secure claim verification.

Returns an error if the refund targets a different chain or if no valid blinded path can be constructed.

This is not exported to bindings users as builder patterns don’t map outside of move semantics.

Source

pub fn create_response_for_invoice_request<ES: Deref, NS: Deref, R: Deref>( &self, signer: &NS, router: &R, entropy_source: ES, invoice_request: VerifiedInvoiceRequest, amount_msats: u64, payment_hash: PaymentHash, payment_secret: PaymentSecret, usable_channels: Vec<ChannelDetails>, ) -> (OffersMessage, Option<MessageContext>)

Creates a response for the provided VerifiedInvoiceRequest.

A response can be either an OffersMessage::Invoice with additional MessageContext, or an OffersMessage::InvoiceError, depending on the InvoiceRequest.

An OffersMessage::InvoiceError will be generated if:

Source

pub fn enqueue_invoice_request( &self, invoice_request: InvoiceRequest, payment_id: PaymentId, nonce: Nonce, peers: Vec<MessageForwardNode>, ) -> Result<(), Bolt12SemanticError>

Enqueues the created InvoiceRequest to be sent to the counterparty.

§Payment

The provided payment_id is used to create a unique MessageContext for the blinded paths sent to the counterparty. This allows them to respond with an invoice, over those blinded paths, which can be verified against the intended outbound payment, ensuring the invoice corresponds to a payment we actually want to make.

§Nonce

The nonce is used to create a unique MessageContext for the reply paths. These will be used to verify the corresponding Bolt12Invoice when it is received.

Note: The provided Nonce MUST be the same as the Nonce used for creating the InvoiceRequest to ensure correct verification of the corresponding Bolt12Invoice.

See OffersMessageFlow::create_invoice_request_builder for more details.

§Peers

The user must provide a list of MessageForwardNode that will be used to generate valid reply paths for the counterparty to send back the corresponding Bolt12Invoice or InvoiceError.

Source

pub fn enqueue_invoice( &self, invoice: Bolt12Invoice, refund: &Refund, peers: Vec<MessageForwardNode>, ) -> Result<(), Bolt12SemanticError>

Enqueues the created Bolt12Invoice corresponding to a Refund to be sent to the counterparty.

§Peers

The user must provide a list of MessageForwardNode that will be used to generate valid reply paths for the counterparty to send back the corresponding InvoiceError if we fail to create blinded reply paths

Source

pub fn enqueue_static_invoice( &self, invoice: StaticInvoice, responder: Responder, ) -> Result<(), Bolt12SemanticError>

Forwards a StaticInvoice over the provided Responder in response to an InvoiceRequest that we as a static invoice server received on behalf of an often-offline recipient.

Source

pub fn enqueue_invoice_request_to_forward( &self, invoice_request: InvoiceRequest, destination: BlindedMessagePath, reply_path: Responder, )

Forwards an InvoiceRequest to the specified BlindedMessagePath. If we receive an invoice request as a static invoice server on behalf of an often-offline recipient this can be used to forward the request to give the recipient a chance to provide an invoice if the recipient is online. The reply_path Responder provided is the path to the sender where the recipient can send the invoice.

Source

pub fn enqueue_held_htlc_available( &self, invoice: &StaticInvoice, reply_path_params: HeldHtlcReplyPath, ) -> Result<(), Bolt12SemanticError>

Enqueues held_htlc_available onion messages to be sent to the payee via the reply paths contained within the provided StaticInvoice.

Source

pub fn path_for_release_held_htlc<ES: Deref>( &self, intercept_id: InterceptId, prev_outbound_scid_alias: u64, htlc_id: u64, entropy: ES, ) -> BlindedMessagePath
where ES::Target: EntropySource,

If we are holding an HTLC on behalf of an often-offline sender, this method allows us to create a path for the sender to use as the reply path when they send the recipient a HeldHtlcAvailable onion message, so the recipient’s ReleaseHeldHtlc response will be received to our node.

Source

pub fn release_pending_offers_messages( &self, ) -> Vec<(OffersMessage, MessageSendInstructions)>

Gets the enqueued OffersMessage with their corresponding MessageSendInstructions.

Source

pub fn release_pending_async_messages( &self, ) -> Vec<(AsyncPaymentsMessage, MessageSendInstructions)>

Gets the enqueued AsyncPaymentsMessage with their corresponding MessageSendInstructions.

Source

pub fn get_async_receive_offer(&self) -> Result<(Offer, bool), ()>

Retrieve an Offer for receiving async payments as an often-offline recipient. Will only return an offer if Self::set_paths_to_static_invoice_server was called and we succeeded in interactively building a StaticInvoice with the static invoice server.

Returns the requested offer as well as a bool indicating whether the cache needs to be persisted using Self::writeable_async_receive_offer_cache.

Source

pub fn check_refresh_async_receive_offer_cache<ES: Deref, R: Deref>( &self, peers: Vec<MessageForwardNode>, usable_channels: Vec<ChannelDetails>, entropy: ES, router: R, timer_tick_occurred: bool, ) -> Result<(), ()>

Sends out OfferPathsRequest and ServeStaticInvoice onion messages if we are an often-offline recipient and are configured to interactively build offers and static invoices with a static invoice server.

§Usage

This method should be called on peer connection and once per minute or so, to keep the offers cache updated. When calling this method once per minute, SHOULD set timer_tick_occurred so the cache can self-regulate the number of messages sent out.

Errors if we failed to create blinded reply paths when sending an OfferPathsRequest message.

Source

pub fn handle_offer_paths_request( &self, request: &OfferPathsRequest, context: AsyncPaymentsContext, peers: Vec<MessageForwardNode>, ) -> Option<(OfferPaths, MessageContext)>

Handles an incoming OfferPathsRequest onion message from an often-offline recipient who wants us (the static invoice server) to serve StaticInvoices to payers on their behalf. Sends out OfferPaths onion messages in response.

Source

pub fn handle_offer_paths<ES: Deref, R: Deref>( &self, message: OfferPaths, context: AsyncPaymentsContext, responder: Responder, peers: Vec<MessageForwardNode>, usable_channels: Vec<ChannelDetails>, entropy: ES, router: R, ) -> Option<(ServeStaticInvoice, MessageContext)>

Handles an incoming OfferPaths message from the static invoice server, sending out ServeStaticInvoice onion messages in response if we’ve built a new async receive offer and need the corresponding StaticInvoice to be persisted by the static invoice server.

Returns None if we have enough offers cached already, verification of message fails, or we fail to create blinded paths.

Source

pub fn verify_serve_static_invoice_message( &self, message: &ServeStaticInvoice, context: AsyncPaymentsContext, ) -> Result<(Vec<u8>, u16), ()>

Verifies an incoming ServeStaticInvoice onion message from an often-offline recipient who wants us as a static invoice server to serve the ServeStaticInvoice::invoice to payers on their behalf.

On success, returns (recipient_id, invoice_slot) for use in persisting and later retrieving the static invoice from the database.

Errors if the ServeStaticInvoice::invoice is expired or larger than MAX_STATIC_INVOICE_SIZE_BYTES.

Source

pub fn static_invoice_persisted(&self, responder: Responder)

Indicates that a ServeStaticInvoice::invoice has been persisted and is ready to be served to payers on behalf of an often-offline recipient. This method must be called after persisting a StaticInvoice to confirm to the recipient that their corresponding Offer is ready to receive async payments.

Source

pub fn handle_static_invoice_persisted( &self, context: AsyncPaymentsContext, ) -> bool

Handles an incoming StaticInvoicePersisted onion message from the static invoice server. Returns a bool indicating whether the async receive offer cache needs to be re-persisted using Self::writeable_async_receive_offer_cache.

Source

pub fn writeable_async_receive_offer_cache(&self) -> Vec<u8>

Get the encoded AsyncReceiveOfferCache for persistence.

Auto Trait Implementations§

§

impl<MR, L> !Freeze for OffersMessageFlow<MR, L>

§

impl<MR, L> RefUnwindSafe for OffersMessageFlow<MR, L>

§

impl<MR, L> Send for OffersMessageFlow<MR, L>
where MR: Send, L: Send,

§

impl<MR, L> Sync for OffersMessageFlow<MR, L>
where MR: Sync, L: Sync,

§

impl<MR, L> Unpin for OffersMessageFlow<MR, L>
where MR: Unpin, L: Unpin,

§

impl<MR, L> UnwindSafe for OffersMessageFlow<MR, L>
where MR: UnwindSafe, L: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V