Skip to content

Commit 6dd6e64

Browse files
committed
fix: handle max amount calculations in calculate_total_fee
When users try to calculate fees for amounts close to their total balance, calculate_total_fee` would previously throw `InsufficientFunds`. This fix detects when the requested amount is within the spendable balance and automatically calculates the fee as if sending all available funds, while retaining the anchor channel reserve. - Detect near-full-balance send attempts and apply max-spend logic - Avoids InsufficientFunds error in calculate_total_fee when near the total spendable balance - Retains anchor channel reserve to ensure safety and correctness - Updates bindings - Bumps version to 0.6.1-rc.5
1 parent 75c4f18 commit 6dd6e64

File tree

8 files changed

+44
-12
lines changed

8 files changed

+44
-12
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ldk-node"
3-
version = "0.6.1-rc.4"
3+
version = "0.6.1-rc.5"
44
authors = ["Elias Rohrer <[email protected]>"]
55
homepage = "https://lightningdevkit.org/"
66
license = "MIT OR Apache-2.0"

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
import PackageDescription
55

6-
let tag = "v0.6.1-rc.4"
7-
let checksum = "827824d292db54baf9c9ac5b2de2ed84f6c93e22a8fe64b838ca85bb0753d495"
6+
let tag = "v0.6.1-rc.5"
7+
let checksum = "8834dd706cc3393202f27f4ac9eb0144c00a7804dbf9004cf179ff9f997e6de3"
88
let url = "https://github.com/synonymdev/ldk-node/releases/download/\(tag)/LDKNodeFFI.xcframework.zip"
99

1010
let package = Package(

bindings/kotlin/ldk-node-android/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Publishing new version guide.
3131
- add dependency in `libs.versions.toml`:
3232
```toml
3333
# by tag
34-
ldk-node-android = { module = "com.github.synonymdev:ldk-node", version = "v0.6.1-rc.4"
34+
ldk-node-android = { module = "com.github.synonymdev:ldk-node", version = "v0.6.1-rc.5"
3535

3636
# or by branch
3737
ldk-node-android = { module = "com.github.synonymdev:ldk-node", version = "main-SNAPSHOT"

bindings/kotlin/ldk-node-android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
22
android.useAndroidX=true
33
android.enableJetifier=true
44
kotlin.code.style=official
5-
libraryVersion=v0.6.1-rc.4
5+
libraryVersion=v0.6.1-rc.5
Binary file not shown.
Binary file not shown.
Binary file not shown.

src/payment/onchain.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,16 @@ impl OnchainPayment {
157157
/// The calculation respects any on-chain reserve requirements and validates that sufficient
158158
/// funds are available, just like [`send_to_address`].
159159
///
160+
/// **Special handling for maximum amounts:** If the specified amount would result in
161+
/// insufficient funds due to fees, but is within the spendable balance, this method will
162+
/// automatically calculate the fee for sending all available funds while retaining the
163+
/// anchor channel reserve. This allows users to calculate fees when trying to send
164+
/// their maximum spendable balance.
165+
///
160166
/// # Arguments
161167
///
162168
/// * `address` - The Bitcoin address to send to
163-
/// * `amount_sats` - The amount to send in satoshis
169+
/// * `amount_sats` - The amount to send in satoshis (or total balance for max send)
164170
/// * `fee_rate` - Optional fee rate to use (if None, will estimate based on current network conditions)
165171
/// * `utxos_to_spend` - Optional list of specific UTXOs to use for the transaction
166172
///
@@ -176,6 +182,7 @@ impl OnchainPayment {
176182
/// * [`Error::WalletOperationFailed`] - If fee calculation fails
177183
///
178184
/// [`send_to_address`]: Self::send_to_address
185+
/// [`BalanceDetails::total_onchain_balance_sats`]: crate::balance::BalanceDetails::total_onchain_balance_sats
179186
pub fn calculate_total_fee(
180187
&self, address: &bitcoin::Address, amount_sats: u64, fee_rate: Option<FeeRate>,
181188
utxos_to_spend: Option<Vec<SpendableUtxo>>,
@@ -187,18 +194,43 @@ impl OnchainPayment {
187194

188195
let cur_anchor_reserve_sats =
189196
crate::total_anchor_channels_reserve_sats(&self.channel_manager, &self.config);
190-
let send_amount =
191-
OnchainSendAmount::ExactRetainingReserve { amount_sats, cur_anchor_reserve_sats };
197+
198+
// Get current balances
199+
let (_total_balance, spendable_balance) = self.wallet.get_balances(cur_anchor_reserve_sats)
200+
.unwrap_or((0, 0));
201+
202+
// First try with the exact amount
192203
let outpoints = utxos_to_spend.map(|utxos| utxos.into_iter().map(|u| u.outpoint).collect());
193204
let fee_rate_opt = maybe_map_fee_rate_opt!(fee_rate);
194-
195-
self.wallet.calculate_transaction_fee(
205+
206+
// Try calculating with exact amount first
207+
let send_amount = OnchainSendAmount::ExactRetainingReserve { amount_sats, cur_anchor_reserve_sats };
208+
let result = self.wallet.calculate_transaction_fee(
196209
address,
197210
send_amount,
198211
fee_rate_opt,
199-
outpoints,
212+
outpoints.clone(),
200213
&self.channel_manager,
201-
)
214+
);
215+
216+
// If we get InsufficientFunds and the amount is within the spendable balance,
217+
// try calculating as if sending all available funds
218+
if matches!(result, Err(Error::InsufficientFunds)) && amount_sats <= spendable_balance {
219+
// Try with AllRetainingReserve to calculate the fee for sending all
220+
let all_retaining = OnchainSendAmount::AllRetainingReserve { cur_anchor_reserve_sats };
221+
if let Ok(fee) = self.wallet.calculate_transaction_fee(
222+
address,
223+
all_retaining,
224+
fee_rate_opt,
225+
outpoints.clone(),
226+
&self.channel_manager,
227+
) {
228+
// Return the fee for sending all available funds
229+
return Ok(fee);
230+
}
231+
}
232+
233+
result
202234
}
203235

204236
/// Send an on-chain payment to the given address.

0 commit comments

Comments
 (0)