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

Commit

Permalink
Merge pull request #964 from MutinyWallet/fee-bump
Browse files Browse the repository at this point in the history
RBF fee bumping utilities
  • Loading branch information
AnthonyRonning authored Jan 15, 2024
2 parents 3802f7a + f71d49a commit 5014401
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
1 change: 1 addition & 0 deletions mutiny-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ impl From<bdk::Error> for MutinyError {
match e {
bdk::Error::Signer(_) => Self::WalletSigningFailed,
bdk::Error::InsufficientFunds { .. } => Self::InsufficientBalance,
bdk::Error::TransactionNotFound => Self::NotFound,
_ => Self::WalletOperationFailed,
}
}
Expand Down
23 changes: 20 additions & 3 deletions mutiny-core/src/nodemanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use payjoin::Uri;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::cmp::max;
use std::io::Cursor;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -936,6 +937,22 @@ impl<S: MutinyStorage> NodeManager<S> {
self.wallet.estimate_sweep_tx_fee(script, fee_rate)
}

/// 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: Txid, new_fee_rate: f32) -> Result<Txid, MutinyError> {
// check that this is not a funding tx for any channels,
// bumping those can cause loss of funds
let channels = self.list_channels().await?;
if channels
.iter()
.any(|c| c.outpoint.is_some_and(|t| t.txid == txid))
{
return Err(MutinyError::ChannelCreationFailed);
}

self.wallet.bump_fee(txid, new_fee_rate).await
}

/// Checks if the given address has any transactions.
/// If it does, it returns the details of the first transaction.
///
Expand Down Expand Up @@ -1313,19 +1330,19 @@ impl<S: MutinyStorage> NodeManager<S> {
/// Gets a fee estimate for a very low priority transaction.
/// Value is in sat/vbyte.
pub fn estimate_fee_low(&self) -> u32 {
self.fee_estimator.get_low_fee_rate() / 250
max(self.fee_estimator.get_low_fee_rate() / 250, 1)
}

/// Gets a fee estimate for an average priority transaction.
/// Value is in sat/vbyte.
pub fn estimate_fee_normal(&self) -> u32 {
self.fee_estimator.get_normal_fee_rate() / 250
max(self.fee_estimator.get_normal_fee_rate() / 250, 1)
}

/// Gets a fee estimate for an high priority transaction.
/// Value is in sat/vbyte.
pub fn estimate_fee_high(&self) -> u32 {
self.fee_estimator.get_high_fee_rate() / 250
max(self.fee_estimator.get_high_fee_rate() / 250, 1)
}

/// Creates a new lightning node and adds it to the manager.
Expand Down
21 changes: 21 additions & 0 deletions mutiny-core/src/onchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,27 @@ impl<S: MutinyStorage> OnChainWallet<S> {

psbt.fee_amount().ok_or(MutinyError::WalletOperationFailed)
}

/// 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: Txid, new_fee_rate: f32) -> Result<Txid, MutinyError> {
let tx = {
let mut wallet = self.wallet.try_write()?;
// build RBF fee bump tx
let mut builder = wallet.build_fee_bump(txid)?;
builder.fee_rate(FeeRate::from_sat_per_vb(new_fee_rate));
let (mut psbt, _) = builder.finish()?;
wallet.sign(&mut psbt, SignOptions::default())?;

psbt.extract_tx()
};

let txid = tx.txid();

self.broadcast_transaction(tx).await?;
log_debug!(self.logger, "Fee bump Transaction broadcast! TXID: {txid}");
Ok(txid)
}
}

fn get_tr_descriptors_for_extended_key(
Expand Down
16 changes: 16 additions & 0 deletions mutiny-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,15 @@ impl MutinyWallet {
.estimate_sweep_channel_open_fee(fee_rate)?)
}

/// 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> {
let txid = Txid::from_str(&txid)?;
let result = self.inner.node_manager.bump_fee(txid, fee_rate).await?;

Ok(result.to_string())
}

/// Checks if the given address has any transactions.
/// If it does, it returns the details of the first transaction.
///
Expand Down Expand Up @@ -622,6 +631,13 @@ impl MutinyWallet {
Ok(JsValue::from_serde(&self.inner.node_manager.list_utxos()?)?)
}

/// Gets a fee estimate for an low priority transaction.
/// Value is in sat/vbyte.
#[wasm_bindgen]
pub fn estimate_fee_low(&self) -> u32 {
self.inner.node_manager.estimate_fee_low()
}

/// Gets a fee estimate for an average priority transaction.
/// Value is in sat/vbyte.
#[wasm_bindgen]
Expand Down

0 comments on commit 5014401

Please sign in to comment.