Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit

Permalink
Estimates fedimint fee
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyRonning committed Jan 31, 2024
1 parent 848c3f3 commit 977f699
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
60 changes: 60 additions & 0 deletions mutiny-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,66 @@ impl<S: MutinyStorage> MutinyWallet<S> {
}
}

/// Estimates the lightning fee for a transaction. Amount is either from the invoice
/// if one is available or a passed in amount (priority). It will try to predict either
/// sending the payment through a federation or through lightning, depending on balances.
/// The amount and fee is in satoshis.
/// Returns None if it has no good way to calculate fee.
pub async fn estimate_ln_fee(
&self,
inv: Option<&Bolt11Invoice>,
amt_sats: Option<u64>,
) -> Result<Option<u64>, MutinyError> {
let amt = if let Some(a) = amt_sats {
a
} else if let Some(i) = inv {
if let Some(a) = i.amount_milli_satoshis() {
a
} else {
return Err(MutinyError::BadAmountError);
}
} else {
return Err(MutinyError::BadAmountError);
};

// check balances first
let total_balances = self.get_balance().await?;
if total_balances.federation > amt {
let federation_ids = self.list_federation_ids().await?;
for federation_id in federation_ids {
// Check if the federation has enough balance
if let Some(fedimint_client) = self.federations.read().await.get(&federation_id) {
let current_balance = fedimint_client.get_balance().await?;
log_info!(
self.logger,
"current fedimint client balance: {}",
current_balance
);

let fees = fedimint_client.gateway_fee().await?;
let max_spendable = max_spendable_amount(current_balance, fees.clone())
.map_or(Err(MutinyError::InsufficientBalance), Ok)?;

if max_spendable >= amt {
let prop_fee_msat =
(amt as f64 * 1_000.0 * fees.proportional_millionths as f64)
/ 1_000_000.0;

let total_fee = fees.base_msat as f64 + prop_fee_msat;
return Ok(Some((total_fee / 1_000.0).floor() as u64));
}
}
}
}

if total_balances.lightning > amt {
// TODO try something to try to get lightning fee
return Ok(None);
}

Err(MutinyError::InsufficientBalance)
}

/// Creates a BIP 21 invoice. This creates a new address and a lightning invoice.
/// The lightning invoice may return errors related to the LSP. Check the error and
/// fallback to `get_new_address` and warn the user that Lightning is not available.
Expand Down
20 changes: 20 additions & 0 deletions mutiny-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,26 @@ impl MutinyWallet {
.estimate_sweep_channel_open_fee(fee_rate)?)
}

/// Estimates the lightning fee for a transaction. Amount is either from the invoice
/// if one is available or a passed in amount (priority). It will try to predict either
/// sending the payment through a federation or through lightning, depending on balances.
/// The amount and fee is in satoshis.
/// Returns None if it has no good way to calculate fee.
pub async fn estimate_ln_fee(
&self,
invoice_str: Option<String>,
amt_sats: Option<u64>,
) -> Result<Option<u64>, MutinyJsError> {
let invoice = match invoice_str {
Some(i) => Some(Bolt11Invoice::from_str(&i)?),
None => None,
};
Ok(self
.inner
.estimate_ln_fee(invoice.as_ref(), amt_sats)
.await?)
}

/// Bumps the given transaction by replacing the given tx with a transaction at
/// the new given fee rate in sats/vbyte
pub async fn bump_fee(&self, txid: String, fee_rate: f32) -> Result<String, MutinyJsError> {
Expand Down

0 comments on commit 977f699

Please sign in to comment.