Skip to content

Commit 6f08168

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 50ed4a8 commit 6f08168

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
@@ -400,20 +400,16 @@ impl LightningWallet {
400400
}
401401
}
402402

403-
pub(crate) async fn splice_balance_into_channel(
404-
&self, amount: Amount,
405-
) -> Result<UserChannelId, NodeError> {
403+
pub(crate) async fn splice_all_into_channel(&self) -> Result<UserChannelId, NodeError> {
406404
// find existing channel to splice into
407405
let channels = self.inner.ldk_node.list_channels();
408406
let channel = channels.iter().find(|c| c.counterparty_node_id == self.inner.lsp_node_id);
409407

410408
match channel {
411409
Some(chan) => {
412-
self.inner.ldk_node.splice_in(
413-
&chan.user_channel_id,
414-
chan.counterparty_node_id,
415-
amount.sats_rounding_up(),
416-
)?;
410+
self.inner
411+
.ldk_node
412+
.splice_in_with_all(&chan.user_channel_id, chan.counterparty_node_id)?;
417413
Ok(chan.user_channel_id)
418414
},
419415
None => {
@@ -424,23 +420,9 @@ impl LightningWallet {
424420
}
425421

426422
pub(crate) async fn open_channel_with_lsp(&self) -> Result<UserChannelId, NodeError> {
427-
let bal = self.inner.ldk_node.list_balances().spendable_onchain_balance_sats;
428-
429-
// need a dummy p2wsh address to estimate the fee, p2wsh is used for LN channels
430-
// let fake_addr = Address::p2wsh(Script::new(), self.inner.ldk_node.config().network);
431-
//
432-
// let fee = self
433-
// .inner
434-
// .ldk_node
435-
// .onchain_payment()
436-
// .estimate_send_all_to_address(&fake_addr, true, None)?;
437-
// todo get real fee
438-
let fee = 1000;
439-
440-
let id = self.inner.ldk_node.open_channel(
423+
let id = self.inner.ldk_node.open_channel_with_all(
441424
self.inner.lsp_node_id,
442425
self.inner.lsp_socket_addr.clone(),
443-
bal - fee,
444426
None,
445427
None,
446428
)?;
@@ -541,12 +523,9 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
541523
}
542524

543525
fn open_channel_with_lsp(
544-
&self, _amt: Amount,
526+
&self,
545527
) -> Pin<Box<dyn Future<Output = Result<u128, Self::Error>> + Send + '_>> {
546-
Box::pin(async move {
547-
// we don't use the amount and just use our full spendable balance in open_channel_with_lsp
548-
self.open_channel_with_lsp().await.map(|c| c.0)
549-
})
528+
Box::pin(async move { self.open_channel_with_lsp().await.map(|c| c.0) })
550529
}
551530

552531
fn await_channel_pending(
@@ -570,21 +549,9 @@ impl graduated_rebalancer::LightningWallet for LightningWallet {
570549
}
571550

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

590557
fn await_splice_pending(

0 commit comments

Comments
 (0)