Skip to content

Commit 9deda08

Browse files
benthecarmanclaude
andcommitted
Splice and open channels with all on-chain funds
Use ldk-node's new splice_in_with_all and open_channel_with_all APIs, which compute the maximum drain amount net of fees and anchor reserves. This replaces the hand-rolled fee subtraction on splice and the hardcoded fee constant on channel open. Drop the amt parameter from the LightningWallet trait's open_channel_with_lsp and splice_to_lsp_channel methods. Every implementation discarded it; the signature now matches the contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4cf5efb commit 9deda08

2 files changed

Lines changed: 17 additions & 48 deletions

File tree

graduated-rebalancer/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,21 @@ pub trait LightningWallet: Send + Sync {
110110
/// Check if we already have a channel with the LSP
111111
fn has_channel_with_lsp(&self) -> bool;
112112

113-
/// Open a channel with the LSP using on-chain funds
113+
/// Open a channel with the LSP using all available on-chain funds
114+
/// (minus fees and anchor reserves).
114115
fn open_channel_with_lsp(
115-
&self, amt: Amount,
116+
&self,
116117
) -> Pin<Box<dyn Future<Output = Result<u128, Self::Error>> + Send + '_>>;
117118

118119
/// Wait for a channel pending notification, returns the new channel's outpoint
119120
fn await_channel_pending(
120121
&self, channel_id: u128,
121122
) -> Pin<Box<dyn Future<Output = OutPoint> + Send + '_>>;
122123

123-
/// Splice funds from on-chain to an existing channel with the LSP
124+
/// Splice all available on-chain funds (minus fees and anchor reserves) into
125+
/// an existing channel with the LSP.
124126
fn splice_to_lsp_channel(
125-
&self, amt: Amount,
127+
&self,
126128
) -> Pin<Box<dyn Future<Output = Result<u128, Self::Error>> + Send + '_>>;
127129

128130
/// Wait for a splice pending notification, returns the splice outpoint
@@ -344,7 +346,7 @@ where
344346
let (channel_outpoint, user_channel_id) = if self.ln_wallet.has_channel_with_lsp() {
345347
log_info!(self.logger, "Splicing into channel with LSP with on-chain funds");
346348

347-
let user_chan_id = match self.ln_wallet.splice_to_lsp_channel(params.amount).await {
349+
let user_chan_id = match self.ln_wallet.splice_to_lsp_channel().await {
348350
Ok(chan_id) => chan_id,
349351
Err(e) => {
350352
log_error!(self.logger, "Failed to open channel with LSP: {e:?}");
@@ -362,7 +364,7 @@ where
362364
} else {
363365
log_info!(self.logger, "Opening channel with LSP with on-chain funds");
364366

365-
let user_chan_id = match self.ln_wallet.open_channel_with_lsp(params.amount).await {
367+
let user_chan_id = match self.ln_wallet.open_channel_with_lsp().await {
366368
Ok(chan_id) => chan_id,
367369
Err(e) => {
368370
log_error!(self.logger, "Failed to open channel with LSP: {e:?}");

orange-sdk/src/lightning_wallet.rs

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -403,20 +403,16 @@ impl LightningWallet {
403403
}
404404
}
405405

406-
pub(crate) async fn splice_balance_into_channel(
407-
&self, amount: Amount,
408-
) -> Result<UserChannelId, NodeError> {
406+
pub(crate) async fn splice_all_into_channel(&self) -> Result<UserChannelId, NodeError> {
409407
// find existing channel to splice into
410408
let channels = self.inner.ldk_node.list_channels();
411409
let channel = channels.iter().find(|c| c.counterparty_node_id == self.inner.lsp_node_id);
412410

413411
match channel {
414412
Some(chan) => {
415-
self.inner.ldk_node.splice_in(
416-
&chan.user_channel_id,
417-
chan.counterparty_node_id,
418-
amount.sats_rounding_up(),
419-
)?;
413+
self.inner
414+
.ldk_node
415+
.splice_in_with_all(&chan.user_channel_id, chan.counterparty_node_id)?;
420416
Ok(chan.user_channel_id)
421417
},
422418
None => {
@@ -427,23 +423,9 @@ impl LightningWallet {
427423
}
428424

429425
pub(crate) async fn open_channel_with_lsp(&self) -> Result<UserChannelId, NodeError> {
430-
let bal = self.inner.ldk_node.list_balances().spendable_onchain_balance_sats;
431-
432-
// need a dummy p2wsh address to estimate the fee, p2wsh is used for LN channels
433-
// let fake_addr = Address::p2wsh(Script::new(), self.inner.ldk_node.config().network);
434-
//
435-
// let fee = self
436-
// .inner
437-
// .ldk_node
438-
// .onchain_payment()
439-
// .estimate_send_all_to_address(&fake_addr, true, None)?;
440-
// todo get real fee
441-
let fee = 1000;
442-
443-
let id = self.inner.ldk_node.open_channel(
426+
let id = self.inner.ldk_node.open_channel_with_all(
444427
self.inner.lsp_node_id,
445428
self.inner.lsp_socket_addr.clone(),
446-
bal - fee,
447429
None,
448430
None,
449431
)?;
@@ -544,12 +526,9 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
544526
}
545527

546528
fn open_channel_with_lsp(
547-
&self, _amt: Amount,
529+
&self,
548530
) -> Pin<Box<dyn Future<Output = Result<u128, Self::Error>> + Send + '_>> {
549-
Box::pin(async move {
550-
// we don't use the amount and just use our full spendable balance in open_channel_with_lsp
551-
self.open_channel_with_lsp().await.map(|c| c.0)
552-
})
531+
Box::pin(async move { self.open_channel_with_lsp().await.map(|c| c.0) })
553532
}
554533

555534
fn await_channel_pending(
@@ -573,21 +552,9 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
573552
}
574553

575554
fn splice_to_lsp_channel(
576-
&self, amt: Amount,
555+
&self,
577556
) -> Pin<Box<dyn Future<Output = Result<u128, Self::Error>> + Send + '_>> {
578-
let bal = self.inner.ldk_node.list_balances();
579-
// if we don't have enough onchain balance, return error
580-
// if we are within 1,000 sats of the amount, reduce the amount to account for fees
581-
if bal.spendable_onchain_balance_sats < amt.sats_rounding_up() {
582-
return Box::pin(async move { Err(NodeError::InsufficientFunds) });
583-
} else if bal.spendable_onchain_balance_sats < amt.sats_rounding_up() + 1_000 {
584-
let reduced_amt = amt.saturating_sub(Amount::from_sats(1_000).expect("valid amount"));
585-
return Box::pin(async move {
586-
self.splice_balance_into_channel(reduced_amt).await.map(|c| c.0)
587-
});
588-
}
589-
590-
Box::pin(async move { self.splice_balance_into_channel(amt).await.map(|c| c.0) })
557+
Box::pin(async move { self.splice_all_into_channel().await.map(|c| c.0) })
591558
}
592559

593560
fn await_splice_pending(

0 commit comments

Comments
 (0)