pub struct LightningClientModule {
pub(crate) federation_id: FederationId,
pub(crate) cfg: LightningClientConfig,
pub(crate) notifier: ModuleNotifier<LightningClientStateMachines>,
pub(crate) client_ctx: ClientContext<Self>,
pub(crate) module_api: DynModuleApi,
pub(crate) keypair: Keypair,
pub(crate) lnurl_keypair: Keypair,
pub(crate) gateway_conn: Arc<dyn GatewayConnection + Send + Sync>,
pub(crate) admin_auth: Option<ApiAuth>,
}Fields§
§federation_id: FederationId§cfg: LightningClientConfig§notifier: ModuleNotifier<LightningClientStateMachines>§client_ctx: ClientContext<Self>§module_api: DynModuleApi§keypair: Keypair§lnurl_keypair: Keypair§gateway_conn: Arc<dyn GatewayConnection + Send + Sync>§admin_auth: Option<ApiAuth>Implementations§
Source§impl LightningClientModule
impl LightningClientModule
Sourcepub async fn create_htlc(
&self,
amount: Amount,
payment_image: PaymentImage,
claim_pk: PublicKey,
expiration_delta: u64,
custom_meta: Value,
) -> Result<(OperationId, OutPoint, OutgoingContract), HtlcError>
pub async fn create_htlc( &self, amount: Amount, payment_image: PaymentImage, claim_pk: PublicKey, expiration_delta: u64, custom_meta: Value, ) -> Result<(OperationId, OutPoint, OutgoingContract), HtlcError>
Fund a direct HTLC: an outgoing contract of amount locked to the
counterparty’s claim_pk, without any gateway involvement. The
counterparty can claim the contract with the preimage of
payment_image via Self::claim_htlc until expiration_delta
blocks from now; afterwards we can reclaim it via
Self::refund_htlc, or earlier via Self::cancel_htlc if the
counterparty provides a forfeit signature.
Returns the contract and the outpoint it is funded at; share both with
the counterparty so they can verify the funding via
Self::await_htlc_funded and claim the contract. Await the
acceptance of the funding transaction via
Self::await_htlc_operation_settled and the counterparty’s claim
via Self::await_htlc_resolution, which yields the preimage.
The contract’s refund key is derived from our static module key via the ephemeral key committed in the contract, so refunding and cancelling only require the contract itself, not this operation’s local state.
Sourcepub async fn claim_htlc(
&self,
outpoint: OutPoint,
contract: OutgoingContract,
claim_keypair: Keypair,
preimage: [u8; 32],
custom_meta: Value,
) -> Result<OperationId, HtlcError>
pub async fn claim_htlc( &self, outpoint: OutPoint, contract: OutgoingContract, claim_keypair: Keypair, preimage: [u8; 32], custom_meta: Value, ) -> Result<OperationId, HtlcError>
Claim a direct HTLC funded at outpoint with the preimage of its
payment image; the ecash is issued to our wallet. The claiming
transaction has to be signed by the contract’s claim key, hence the
claim_keypair.
Since the preimage becomes public with the claiming transaction the
caller has to ensure sufficient time until the contract’s expiration
remains; this method only rejects contracts that have already expired.
Await the issuance of the ecash via
Self::await_htlc_operation_settled.
Retrying a claim, refund or cancellation that has already been recorded returns the recorded operation, whether or not its transaction has been accepted yet.
Sourcepub async fn refund_htlc(
&self,
outpoint: OutPoint,
contract: OutgoingContract,
custom_meta: Value,
) -> Result<OperationId, HtlcError>
pub async fn refund_htlc( &self, outpoint: OutPoint, contract: OutgoingContract, custom_meta: Value, ) -> Result<OperationId, HtlcError>
Refund a direct HTLC we created via Self::create_htlc after its
expiration; the ecash is issued back to our wallet. Await the issuance
via Self::await_htlc_operation_settled.
Sourcepub async fn cancel_htlc(
&self,
outpoint: OutPoint,
contract: OutgoingContract,
forfeit_signature: Signature,
custom_meta: Value,
) -> Result<OperationId, HtlcError>
pub async fn cancel_htlc( &self, outpoint: OutPoint, contract: OutgoingContract, forfeit_signature: Signature, custom_meta: Value, ) -> Result<OperationId, HtlcError>
Cancel a direct HTLC we created via Self::create_htlc before its
expiration using the counterparty’s forfeit_signature, created via
Self::create_htlc_forfeit_signature; the ecash is issued back to
our wallet. Await the issuance via
Self::await_htlc_operation_settled.
Sourcepub async fn consensus_block_count(&self) -> Result<u64, HtlcError>
pub async fn consensus_block_count(&self) -> Result<u64, HtlcError>
The federation’s current consensus block count, against which direct HTLC expirations are measured.
Returns HtlcError::NoBlockCountConsensus while the federation has
not yet committed its first block count votes, during which the
reported count would be zero while the actual chain tip may already
be at a positive height; an expiration computed against the zero
count would be overtaken the moment the first votes are committed.
For the same reason Self::create_htlc, Self::claim_htlc and
Self::await_htlc_funded refuse to operate until this method
succeeds.
Sourcepub fn create_htlc_forfeit_signature(
contract: &OutgoingContract,
claim_keypair: &Keypair,
) -> Result<Signature, HtlcError>
pub fn create_htlc_forfeit_signature( contract: &OutgoingContract, claim_keypair: &Keypair, ) -> Result<Signature, HtlcError>
Create a forfeit signature for a direct HTLC locked to our
claim_keypair, which allows its funder to reclaim the contract
before its expiration via Self::cancel_htlc. This is how the
claiming side fails an HTLC cooperatively; it is a pure offline
operation.
Sourcepub async fn await_htlc_funded(
&self,
outpoint: OutPoint,
contract: &OutgoingContract,
) -> Result<u64, HtlcError>
pub async fn await_htlc_funded( &self, outpoint: OutPoint, contract: &OutgoingContract, ) -> Result<u64, HtlcError>
Wait until the given contract is funded at outpoint and return the
number of blocks remaining until its expiration. This is how the
claiming side verifies the funder’s claim that the HTLC exists before
taking any action of its own, e.g. sending funds on another chain.
This method polls the federation indefinitely, retrying connection failures, so callers should enforce their own timeout; note that it will also never resolve if the contract has already been claimed, refunded or cancelled again. Any other federation error, e.g. one of a federation that does not support direct HTLCs, is returned.
Returns HtlcError::NoBlockCountConsensus while the federation has
not yet reached consensus on a block count, as the remaining blocks
would be measured against a count of zero and overstate the contract’s
lifetime; see Self::consensus_block_count.
Sourcepub async fn await_htlc_resolution(
&self,
outpoint: OutPoint,
contract: &OutgoingContract,
) -> Result<Option<[u8; 32]>, HtlcError>
pub async fn await_htlc_resolution( &self, outpoint: OutPoint, contract: &OutgoingContract, ) -> Result<Option<[u8; 32]>, HtlcError>
Wait until the direct HTLC funded at outpoint is either claimed, in
which case the preimage is returned, or expired unclaimed, in which
case None is returned and the funder can safely refund the contract
via Self::refund_htlc.
Sourcepub async fn await_htlc_operation_settled(
&self,
operation_id: OperationId,
) -> Result<(), HtlcError>
pub async fn await_htlc_operation_settled( &self, operation_id: OperationId, ) -> Result<(), HtlcError>
Wait until the transaction of a direct HTLC operation is accepted by the federation and any ecash it issues has been minted.
Sourceasync fn existing_htlc_spend(
&self,
spend: &HtlcSpend,
) -> Result<Option<OperationId>, HtlcError>
async fn existing_htlc_spend( &self, spend: &HtlcSpend, ) -> Result<Option<OperationId>, HtlcError>
Return the operation id of spend if it has already been recorded,
such that retrying a spend, e.g. after its caller was interrupted
while the transaction is in flight, yields the original operation.
Callers have to check this before they verify the contract against
the federation, since that check fails once the recorded spend has
resolved the contract. The retry’s custom meta is ignored.
Concurrent calls for the same spend may both miss the recorded operation, in which case recording the second one fails.
Sourceasync fn spend_htlc(&self, spend: HtlcSpend) -> Result<OperationId, HtlcError>
async fn spend_htlc(&self, spend: HtlcSpend) -> Result<OperationId, HtlcError>
Submit a transaction spending a direct HTLC and record it under a new
operation. Callers have to check for an existing operation via
Self::existing_htlc_spend and verify the contract against the
federation via Self::funded_contract_expiration first.
Sourceasync fn funded_contract_expiration(
&self,
outpoint: OutPoint,
contract: &OutgoingContract,
) -> Result<u64, HtlcError>
async fn funded_contract_expiration( &self, outpoint: OutPoint, contract: &OutgoingContract, ) -> Result<u64, HtlcError>
Verify that contract is the unresolved contract funded at outpoint
and return the number of blocks remaining until its expiration, which
is zero once it has expired.
Every spend of a contract has to pass this check before it is recorded, since spends are recorded under operation ids derived from the outpoint alone: a spend recorded with a mismatched contract would be rejected by the federation while making every later attempt with the correct contract fail against the recorded operation.
Sourcefn recover_htlc_refund_keypair(
&self,
contract: &OutgoingContract,
) -> Option<Keypair>
fn recover_htlc_refund_keypair( &self, contract: &OutgoingContract, ) -> Option<Keypair>
Recover the refund keypair of a direct HTLC created by this client from the contract’s ephemeral key and our static module key.
Source§impl LightningClientModule
impl LightningClientModule
pub(crate) fn new( federation_id: FederationId, cfg: LightningClientConfig, notifier: ModuleNotifier<LightningClientStateMachines>, client_ctx: ClientContext<Self>, module_api: DynModuleApi, module_root_secret: &DerivableSecret, gateway_conn: Arc<dyn GatewayConnection + Send + Sync>, custom_meta_fn: Arc<dyn Fn() -> Value + Send + Sync>, admin_auth: Option<ApiAuth>, task_group: &TaskGroup, client_span: &Span, ) -> Self
pub(crate) fn spawn_gateway_map_update_task( &self, task_group: &TaskGroup, client_span: &Span, )
pub(crate) async fn update_gateway_map(&self)
Sourcepub async fn select_gateway(
&self,
invoice: Option<Bolt11Invoice>,
) -> Result<(SafeUrl, RoutingInfo), SelectGatewayError>
pub async fn select_gateway( &self, invoice: Option<Bolt11Invoice>, ) -> Result<(SafeUrl, RoutingInfo), SelectGatewayError>
Selects an available gateway by querying the federation’s registered
gateways, checking if one of them match the invoice’s payee public
key, then queries the gateway for RoutingInfo to determine if it is
online.
Sourcepub async fn list_gateways(
&self,
peer: Option<PeerId>,
) -> Result<Vec<SafeUrl>, ListGatewaysError>
pub async fn list_gateways( &self, peer: Option<PeerId>, ) -> Result<Vec<SafeUrl>, ListGatewaysError>
Sends a request to each peer for their registered gateway list and
returns a Vec<SafeUrl of all registered gateways to the client.
Sourcepub async fn routing_info(
&self,
gateway: &SafeUrl,
) -> Result<Option<RoutingInfo>, RoutingInfoError>
pub async fn routing_info( &self, gateway: &SafeUrl, ) -> Result<Option<RoutingInfo>, RoutingInfoError>
Requests the RoutingInfo, including fee information, from the gateway
available at the SafeUrl.
Sourcepub async fn send(
&self,
invoice: Bolt11Invoice,
gateway: Option<SafeUrl>,
custom_meta: Value,
) -> Result<OperationId, SendPaymentError>
pub async fn send( &self, invoice: Bolt11Invoice, gateway: Option<SafeUrl>, custom_meta: Value, ) -> Result<OperationId, SendPaymentError>
Pay an invoice. For testing you can optionally specify a gateway to route with, otherwise a gateway will be selected automatically. If the invoice was created by a gateway connected to our federation, the same gateway will be selected to allow for a direct ecash swap. Otherwise we select a random online gateway.
The fee for this payment may depend on the selected gateway but will be limited to one and a half percent plus one hundred satoshis. This fee accounts for the fee charged by the gateway as well as the additional fee required to reliably route this payment over lightning if necessary. Since the gateway has been vetted by at least one guardian we trust it to set a reasonable fee and only enforce a rather high limit.
The absolute fee for a payment can be calculated from the operation meta to be shown to the user in the transaction history.
Sourcepub async fn send_with_terms(
&self,
invoice: Bolt11Invoice,
gateway: SafeUrl,
send_fee: PaymentFee,
expiration_delta: u64,
custom_meta: Value,
) -> Result<OperationId, SendWithTermsError>
pub async fn send_with_terms( &self, invoice: Bolt11Invoice, gateway: SafeUrl, send_fee: PaymentFee, expiration_delta: u64, custom_meta: Value, ) -> Result<OperationId, SendWithTermsError>
Pays invoice through gateway at the terms the caller already
checked.
Self::send reads the gateway’s terms itself, so a caller that showed
the user a fee and asked for approval has no guarantee the funded
contract carries that fee: the gateway may change its schedule between
the two reads. This variant takes the send_fee and expiration_delta
the caller obtained from RoutingInfo::send_parameters and refuses
with SendWithTermsError::TermsChanged, before funding anything, if
the gateway currently reports different terms. A cheaper fee counts
as changed too, so the funded contract always matches what was
approved. This binds the funded contract to the approved terms, not
the gateway’s acceptance: a gateway that raises its schedule after the
check can still refuse the contract, in which case the payment is
refunded. The error carries the current terms for re-quoting.
Sourcepub(crate) async fn validate_send_invoice(
&self,
invoice: &Bolt11Invoice,
) -> Result<(u64, OperationId), SendPaymentError>
pub(crate) async fn validate_send_invoice( &self, invoice: &Bolt11Invoice, ) -> Result<(u64, OperationId), SendPaymentError>
Checks that invoice is payable by this client and has not been
attempted before, returning its amount in millisatoshis and the
operation id a payment of it uses.
Sourcepub(crate) async fn resolve_send_gateway(
&self,
invoice: &Bolt11Invoice,
gateway: Option<SafeUrl>,
) -> Result<(SafeUrl, RoutingInfo), SendPaymentError>
pub(crate) async fn resolve_send_gateway( &self, invoice: &Bolt11Invoice, gateway: Option<SafeUrl>, ) -> Result<(SafeUrl, RoutingInfo), SendPaymentError>
Resolves the gateway to pay invoice through and its current routing
info: the given one, or an automatically selected one when None.
Sourcepub(crate) async fn fund_outgoing_contract(
&self,
invoice: Bolt11Invoice,
amount: u64,
operation_id: OperationId,
gateway_api: SafeUrl,
routing_info: RoutingInfo,
custom_meta: Value,
) -> Result<OperationId, SendPaymentError>
pub(crate) async fn fund_outgoing_contract( &self, invoice: Bolt11Invoice, amount: u64, operation_id: OperationId, gateway_api: SafeUrl, routing_info: RoutingInfo, custom_meta: Value, ) -> Result<OperationId, SendPaymentError>
Funds an outgoing contract for invoice at the terms in routing_info
and starts the state machine that hands it to gateway_api.
Sourcepub async fn get_invoice_send_status(
&self,
invoice: &Bolt11Invoice,
) -> Result<InvoiceSendStatus, OperationLookupError>
pub async fn get_invoice_send_status( &self, invoice: &Bolt11Invoice, ) -> Result<InvoiceSendStatus, OperationLookupError>
The status of a previous Self::send for this invoice.
Callers deciding whether an invoice is safe to pay through another
mechanism must treat anything but InvoiceSendStatus::NotAttempted
as a potential double payment.
Sourcepub async fn subscribe_send_operation_state_updates(
&self,
operation_id: OperationId,
) -> Result<UpdateStreamOrOutcome<SendOperationState>, OperationLookupError>
pub async fn subscribe_send_operation_state_updates( &self, operation_id: OperationId, ) -> Result<UpdateStreamOrOutcome<SendOperationState>, OperationLookupError>
Subscribe to all state updates of the send operation.
Sourcepub async fn await_final_send_operation_state(
&self,
operation_id: OperationId,
) -> Result<FinalSendOperationState, OperationLookupError>
pub async fn await_final_send_operation_state( &self, operation_id: OperationId, ) -> Result<FinalSendOperationState, OperationLookupError>
Await the final state of the send operation.
Sourcepub async fn receive(
&self,
amount: Amount,
expiry_secs: u32,
description: Bolt11InvoiceDescription,
gateway: Option<SafeUrl>,
custom_meta: Value,
) -> Result<(Bolt11Invoice, OperationId), ReceiveError>
pub async fn receive( &self, amount: Amount, expiry_secs: u32, description: Bolt11InvoiceDescription, gateway: Option<SafeUrl>, custom_meta: Value, ) -> Result<(Bolt11Invoice, OperationId), ReceiveError>
Request an invoice. For testing you can optionally specify a gateway to generate the invoice, otherwise a random online gateway will be selected automatically.
The total fee for this payment may depend on the chosen gateway but will be limited to half of one percent plus fifty satoshis. Since the selected gateway has been vetted by at least one guardian we trust it to set a reasonable fee and only enforce a rather high limit.
The absolute fee for a payment can be calculated from the operation meta to be shown to the user in the transaction history.
Sourcepub async fn receive_with_terms(
&self,
amount: Amount,
expiry_secs: u32,
description: Bolt11InvoiceDescription,
gateway: SafeUrl,
receive_fee: PaymentFee,
custom_meta: Value,
) -> Result<(Bolt11Invoice, OperationId), ReceiveWithTermsError>
pub async fn receive_with_terms( &self, amount: Amount, expiry_secs: u32, description: Bolt11InvoiceDescription, gateway: SafeUrl, receive_fee: PaymentFee, custom_meta: Value, ) -> Result<(Bolt11Invoice, OperationId), ReceiveWithTermsError>
Requests an invoice from gateway at the receive fee the caller
already checked.
Self::receive reads the gateway’s fee itself, so a caller that
showed the user a fee has no guarantee the incoming contract is
created at that fee: the gateway may change its schedule between the
two reads. This variant takes the receive_fee the caller obtained
from RoutingInfo::receive_fee and refuses with
ReceiveWithTermsError::TermsChanged, before creating anything, if
the gateway currently reports a different fee. A cheaper fee counts as
changed too, so the contract always matches what was approved; the
error carries the current fee for re-quoting.
Sourcepub(crate) async fn resolve_receive_gateway(
&self,
gateway: Option<SafeUrl>,
) -> Result<(SafeUrl, RoutingInfo), ReceiveError>
pub(crate) async fn resolve_receive_gateway( &self, gateway: Option<SafeUrl>, ) -> Result<(SafeUrl, RoutingInfo), ReceiveError>
Resolves the gateway to request an invoice from and its current
routing info: the given one, or an automatically selected one when
None.
Sourcepub(crate) async fn select_receive_gateway(
&self,
) -> Result<(SafeUrl, RoutingInfo), SelectGatewayError>
pub(crate) async fn select_receive_gateway( &self, ) -> Result<(SafeUrl, RoutingInfo), SelectGatewayError>
Selects the first registered gateway that is online and currently accepts incoming payments for this federation. A gateway that answers but has turned receives off is skipped rather than handed an invoice request it would refuse.
Sourcepub(crate) async fn receive_with_routing_info(
&self,
amount: Amount,
expiry_secs: u32,
description: Bolt11InvoiceDescription,
gateway: SafeUrl,
routing_info: RoutingInfo,
custom_meta: Value,
) -> Result<(Bolt11Invoice, OperationId), ReceiveError>
pub(crate) async fn receive_with_routing_info( &self, amount: Amount, expiry_secs: u32, description: Bolt11InvoiceDescription, gateway: SafeUrl, routing_info: RoutingInfo, custom_meta: Value, ) -> Result<(Bolt11Invoice, OperationId), ReceiveError>
Creates the incoming contract locked to a public key derived from our
static module public key, fetches its invoice from gateway at the
terms in routing_info, then starts the receive operation.
Sourcepub async fn receive_fee_quote(
&self,
amount: Amount,
) -> Result<FeeQuote, TransactionSubmitError>
pub async fn receive_fee_quote( &self, amount: Amount, ) -> Result<FeeQuote, TransactionSubmitError>
Computes the federation fee a receive of amount would incur, without
submitting anything.
When the incoming contract is claimed, the client submits a transaction with a single Lightning input worth the contract amount; the primary module balances it by minting the change credited to the wallet. This quotes the fee of that transaction — the Lightning input fee, the mint output fees, and any sub-denomination dust — via the shared, module-agnostic fee quote.
The gateway’s off-chain Lightning fee is deliberately excluded: this is
only the fee of the on-federation transaction. For that reason the quote
is taken on amount directly (rather than the gateway-reduced contract
amount), and no gateway round-trip is needed.
Sourcepub(crate) async fn is_worth_claiming(&self, amount: Amount) -> bool
pub(crate) async fn is_worth_claiming(&self, amount: Amount) -> bool
Whether an incoming contract worth amount is worth claiming, i.e.
whether claiming it would leave the wallet better off than leaving it.
This is the computed counterpart of a fixed dust limit: it prices the actual claim - the lightning input fee at this federation’s fee consensus, the change the primary module has to mint, and the sub-denomination remainder that cannot be minted at all - rather than assuming a floor. A quote that fails outright is the same verdict: the claim spends the contract as the transaction’s only input, so a fee larger than the contract leaves a transaction that cannot be balanced.
Sourcepub async fn send_fee_quote(
&self,
amount: Amount,
) -> Result<FeeQuote, TransactionSubmitError>
pub async fn send_fee_quote( &self, amount: Amount, ) -> Result<FeeQuote, TransactionSubmitError>
Computes the federation fee a send funding an outgoing contract worth
amount would incur, without submitting anything.
When a payment is sent, the client submits a transaction with a single
Lightning output (the outgoing contract) worth amount; the primary
module balances it by spending ecash to fund the contract and minting
any change. This quotes the fee of that transaction — the Lightning
output fee, the mint input fees on the funding notes, any mint change
output fees, and sub-denomination dust — via the shared, module-agnostic
fee quote.
The gateway’s off-chain Lightning fee is deliberately excluded: it is
part of the contract amount the gateway claims, not the on-federation
transaction fee. So amount is the full outgoing contract value
(send_fee.add_to(invoice_amount)).
Sourcepub async fn spendable_amount(
&self,
balance: Amount,
gateway: Option<SafeUrl>,
) -> Result<Amount, SpendableAmountError>
pub async fn spendable_amount( &self, balance: Amount, gateway: Option<SafeUrl>, ) -> Result<Amount, SpendableAmountError>
Computes the largest invoice amount the client can pay in full out of
balance, i.e. the amount to request an invoice for in order to spend
(close to) the entire balance.
Paying an invoice deducts two kinds of fee from the balance:
- the gateway fee, which is added on top of the invoice amount to form
the outgoing contract (
send_fee.add_to(invoice_amount)), and - the federation fee of funding that contract — the Lightning output
fee, the mint input fees on the funding notes, the mint output fees on
any change, and sub-denomination dust — as quoted by
Self::send_fee_quote.
balance is the client’s current Bitcoin balance (e.g. from
Client::get_balance_for_btc). gateway optionally pins the gateway
whose fee schedule to use; if None one is selected automatically, the
same way Self::send does when no gateway is given. The gateway’s
default send fee is used — the higher of its two send fees, applied to
a Lightning swap rather than a direct fedimint-to-fedimint swap — so the
returned amount stays payable even when the eventual invoice is routed
over Lightning.
The maximum payable amount is found by binary search over the real fee
quote (see max_affordable_send_amount) rather than a closed form,
because the federation fee is stepwise in the amount. The quote is
point-in-time and moves with the balance, exactly like
Self::send_fee_quote; the eventual Self::send remains the source
of truth and may still fail if balance or gateway state changes in
between.
Returns SpendableAmountError::BalanceTooLow if the balance cannot
cover even the smallest payable amount plus fees, and
SpendableAmountError::Quote if the fee probe itself failed; only
the first of the two says the wallet is short. Any LNURL
minSendable/maxSendable bounds are the caller’s responsibility to
apply. The remaining variants of SpendableAmountError are
gateway-side, and none of them means the wallet is short.
pub(crate) async fn receive_incoming_contract( &self, sk: SecretKey, contract: IncomingContract, operation_meta: LightningOperationMeta, ) -> Option<OperationId>
Sourcepub async fn subscribe_receive_operation_state_updates(
&self,
operation_id: OperationId,
) -> Result<UpdateStreamOrOutcome<ReceiveOperationState>, OperationLookupError>
pub async fn subscribe_receive_operation_state_updates( &self, operation_id: OperationId, ) -> Result<UpdateStreamOrOutcome<ReceiveOperationState>, OperationLookupError>
Subscribe to all state updates of the receive operation.
Sourcepub async fn await_final_receive_operation_state(
&self,
operation_id: OperationId,
) -> Result<FinalReceiveOperationState, OperationLookupError>
pub async fn await_final_receive_operation_state( &self, operation_id: OperationId, ) -> Result<FinalReceiveOperationState, OperationLookupError>
Await the final state of the receive operation.
Sourcepub async fn generate_lnurl(
&self,
recurringd: SafeUrl,
gateway: Option<SafeUrl>,
) -> Result<String, GenerateLnurlError>
pub async fn generate_lnurl( &self, recurringd: SafeUrl, gateway: Option<SafeUrl>, ) -> Result<String, GenerateLnurlError>
Generate an lnurl for the client. You can optionally specify a gateway to use for testing purposes.
pub(crate) fn spawn_receive_lnurl_task( &self, custom_meta_fn: Arc<dyn Fn() -> Value + Send + Sync>, task_group: &TaskGroup, client_span: &Span, )
pub(crate) async fn receive_lnurl(&self, custom_meta: Value)
Trait Implementations§
Source§impl ClientModule for LightningClientModule
impl ClientModule for LightningClientModule
type Init = LightningClientInit
Source§type Common = LightningModuleTypes
type Common = LightningModuleTypes
Source§type Backup = NoModuleBackup
type Backup = NoModuleBackup
Source§type ModuleStateMachineContext = LightningClientContext
type ModuleStateMachineContext = LightningClientContext
Source§type States = LightningClientStateMachines
type States = LightningClientStateMachines
fn context(&self) -> Self::ModuleStateMachineContext
Source§fn input_fee(
&self,
amounts: &Amounts,
_input: &<Self::Common as ModuleCommon>::Input,
) -> Option<Amounts>
fn input_fee( &self, amounts: &Amounts, _input: &<Self::Common as ModuleCommon>::Input, ) -> Option<Amounts>
Source§fn output_fee(
&self,
amounts: &Amounts,
_output: &<Self::Common as ModuleCommon>::Output,
) -> Option<Amounts>
fn output_fee( &self, amounts: &Amounts, _output: &<Self::Common as ModuleCommon>::Output, ) -> Option<Amounts>
Source§fn handle_cli_command<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [OsString],
) -> Pin<Box<dyn Future<Output = Result<Value, ClientModuleError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn handle_cli_command<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [OsString],
) -> Pin<Box<dyn Future<Output = Result<Value, ClientModuleError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fedimint-cli module command, given as its arguments. Read morefn decoder() -> Decoder
fn kind() -> ModuleKind
Source§fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
Source§fn handle_rpc<'life0, 'async_trait>(
&'life0 self,
_method: String,
_request: Value,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = Result<Value, ClientModuleError>> + Send + 'life0>>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fn handle_rpc<'life0, 'async_trait>(
&'life0 self,
_method: String,
_request: Value,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = Result<Value, ClientModuleError>> + Send + 'life0>>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fedimint-client-rpc forwards. Read morefn supports_backup(&self) -> bool
Source§fn backup<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Self::Backup, ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fn backup<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Self::Backup, ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
Source§fn supports_being_primary(&self) -> PrimaryModuleSupport
fn supports_being_primary(&self) -> PrimaryModuleSupport
Source§fn create_final_inputs_and_outputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
_operation_id: OperationId,
_unit: AmountUnit,
_input_amount: Amount,
_output_amount: Amount,
) -> Pin<Box<dyn Future<Output = Result<(ClientInputBundle<<Self::Common as ModuleCommon>::Input, Self::States>, ClientOutputBundle<<Self::Common as ModuleCommon>::Output, Self::States>), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
fn create_final_inputs_and_outputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
_operation_id: OperationId,
_unit: AmountUnit,
_input_amount: Amount,
_output_amount: Amount,
) -> Pin<Box<dyn Future<Output = Result<(ClientInputBundle<<Self::Common as ModuleCommon>::Input, Self::States>, ClientOutputBundle<<Self::Common as ModuleCommon>::Output, Self::States>), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
Source§fn await_primary_module_output<'life0, 'async_trait>(
&'life0 self,
_operation_id: OperationId,
_out_point: OutPoint,
) -> Pin<Box<dyn Future<Output = Result<(), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fn await_primary_module_output<'life0, 'async_trait>(
&'life0 self,
_operation_id: OperationId,
_out_point: OutPoint,
) -> Pin<Box<dyn Future<Output = Result<(), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
Self::create_final_inputs_and_outputs to become available. This
function returning typically implies a change in the output of
Self::get_balance. Read moreSource§fn get_balance<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
_unit: AmountUnit,
) -> Pin<Box<dyn Future<Output = Amount> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
fn get_balance<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
_unit: AmountUnit,
) -> Pin<Box<dyn Future<Output = Amount> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
Source§fn get_balances<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
) -> Pin<Box<dyn Future<Output = Amounts> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
fn get_balances<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
) -> Pin<Box<dyn Future<Output = Amounts> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
Source§fn subscribe_balance_changes<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = ()> + Send>>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
fn subscribe_balance_changes<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = ()> + Send>>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: Sync + 'async_trait,
Source§fn leave<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
fn leave<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_dbtx: &'life1 mut DatabaseTransaction<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Sync + 'async_trait,
Source§impl Clone for LightningClientModule
impl Clone for LightningClientModule
Source§fn clone(&self) -> LightningClientModule
fn clone(&self) -> LightningClientModule
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for LightningClientModule
impl !RefUnwindSafe for LightningClientModule
impl Send for LightningClientModule
impl Sync for LightningClientModule
impl Unpin for LightningClientModule
impl !UnwindSafe for LightningClientModule
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> IClientModule for Twhere
T: ClientModule,
impl<T> IClientModule for Twhere
T: ClientModule,
fn as_any(&self) -> &(dyn Any + Send + Sync + 'static)
fn decoder(&self) -> Decoder
fn context(&self, instance: u16) -> DynContext
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
'life0: 'async_trait,
T: 'async_trait,
fn handle_cli_command<'life0, 'life1, 'async_trait>(
&'life0 self,
args: &'life1 [OsString],
) -> Pin<Box<dyn Future<Output = Result<Value, ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
T: 'async_trait,
fn handle_rpc<'life0, 'async_trait>(
&'life0 self,
method: String,
request: Value,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = Result<Value, ClientModuleError>> + Send + 'life0>>> + Send + 'async_trait>>where
'life0: 'async_trait,
T: 'async_trait,
fn input_fee(&self, amount: &Amounts, input: &DynInput) -> Option<Amounts>
fn output_fee(&self, amount: &Amounts, output: &DynOutput) -> Option<Amounts>
fn supports_backup(&self) -> bool
fn backup<'life0, 'async_trait>(
&'life0 self,
module_instance_id: u16,
) -> Pin<Box<dyn Future<Output = Result<DynModuleBackup, ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
T: 'async_trait,
fn supports_being_primary(&self) -> PrimaryModuleSupport
fn create_final_inputs_and_outputs<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
module_instance: u16,
dbtx: &'life1 mut DatabaseTransaction<'life2>,
operation_id: OperationId,
unit: AmountUnit,
input_amount: Amount,
output_amount: Amount,
) -> Pin<Box<dyn Future<Output = Result<(ClientInputBundle, ClientOutputBundle), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
T: 'async_trait,
fn await_primary_module_output<'life0, 'async_trait>(
&'life0 self,
operation_id: OperationId,
out_point: OutPoint,
) -> Pin<Box<dyn Future<Output = Result<(), ClientModuleError>> + Send + 'async_trait>>where
'life0: 'async_trait,
T: 'async_trait,
fn get_balance<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
module_instance: u16,
dbtx: &'life1 mut DatabaseTransaction<'life2>,
unit: AmountUnit,
) -> Pin<Box<dyn Future<Output = Amount> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
T: 'async_trait,
fn subscribe_balance_changes<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Pin<Box<dyn Stream<Item = ()> + Send>>> + Send + 'async_trait>>where
'life0: 'async_trait,
T: 'async_trait,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> PossiblyOption<T> for T
impl<T> PossiblyOption<T> for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.