@@ -106,7 +106,7 @@ use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
106106
107107pub use balance:: { BalanceDetails , LightningBalance , PendingSweepBalance } ;
108108use bitcoin:: secp256k1:: PublicKey ;
109- use bitcoin:: Amount ;
109+ use bitcoin:: { Address , Amount } ;
110110#[ cfg( feature = "uniffi" ) ]
111111pub use builder:: ArcedNodeBuilder as Builder ;
112112pub use builder:: BuildError ;
@@ -1292,6 +1292,59 @@ impl Node {
12921292 }
12931293 }
12941294
1295+ /// Remove funds from an existing channel, sending them to an on-chain address.
1296+ ///
1297+ /// This provides for decreasing a channel's outbound liquidity without re-balancing or closing
1298+ /// it. Once negotiation with the counterparty is complete, the channel remains operational
1299+ /// while waiting for a new funding transaction to confirm.
1300+ pub fn splice_out (
1301+ & self , user_channel_id : & UserChannelId , counterparty_node_id : PublicKey , address : Address ,
1302+ splice_amount_sats : u64 ,
1303+ ) -> Result < ( ) , Error > {
1304+ let open_channels =
1305+ self . channel_manager . list_channels_with_counterparty ( & counterparty_node_id) ;
1306+ if let Some ( channel_details) =
1307+ open_channels. iter ( ) . find ( |c| c. user_channel_id == user_channel_id. 0 )
1308+ {
1309+ if splice_amount_sats > channel_details. outbound_capacity_msat {
1310+ return Err ( Error :: ChannelSplicingFailed ) ;
1311+ }
1312+
1313+ self . wallet . parse_and_validate_address ( & address) ?;
1314+
1315+ let contribution = SpliceContribution :: SpliceOut {
1316+ outputs : vec ! [ bitcoin:: TxOut {
1317+ value: Amount :: from_sat( splice_amount_sats) ,
1318+ script_pubkey: address. script_pubkey( ) ,
1319+ } ] ,
1320+ } ;
1321+
1322+ let fee_rate = self . wallet . estimate_channel_funding_fee_rate ( ) ;
1323+ let funding_feerate_per_kw = fee_rate. to_sat_per_kwu ( ) . try_into ( ) . unwrap_or ( u32:: MAX ) ;
1324+
1325+ self . channel_manager
1326+ . splice_channel (
1327+ & channel_details. channel_id ,
1328+ & counterparty_node_id,
1329+ contribution,
1330+ funding_feerate_per_kw,
1331+ None ,
1332+ )
1333+ . map_err ( |e| {
1334+ log_error ! ( self . logger, "Failed to splice channel: {:?}" , e) ;
1335+ Error :: ChannelSplicingFailed
1336+ } )
1337+ } else {
1338+ log_error ! (
1339+ self . logger,
1340+ "Channel not found for user_channel_id: {:?} and counterparty: {}" ,
1341+ user_channel_id,
1342+ counterparty_node_id
1343+ ) ;
1344+ Err ( Error :: ChannelSplicingFailed )
1345+ }
1346+ }
1347+
12951348 /// Manually sync the LDK and BDK wallets with the current chain state and update the fee rate
12961349 /// cache.
12971350 ///
0 commit comments