From fb4ff8f5381523d2a1f725349fa61a0d4c886dbb Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Mon, 2 Mar 2026 06:32:36 +0000 Subject: [PATCH] Add `ClaimableAwaitingConfirmations::BalanceSource` --- ldk-server-protos/build.rs | 4 ++ ldk-server-protos/src/proto/types.proto | 19 ++++++++++ ldk-server-protos/src/serde_utils.rs | 1 + ldk-server-protos/src/types.rs | 49 +++++++++++++++++++++++++ ldk-server/src/util/proto_adapter.rs | 15 +++++++- 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/ldk-server-protos/build.rs b/ldk-server-protos/build.rs index 46545695..f110a4e0 100644 --- a/ldk-server-protos/build.rs +++ b/ldk-server-protos/build.rs @@ -65,6 +65,10 @@ fn generate_protos() { "types.Payment.status", "#[cfg_attr(feature = \"serde\", serde(serialize_with = \"crate::serde_utils::serialize_payment_status\"))]", ) + .field_attribute( + "types.ClaimableAwaitingConfirmations.source", + "#[cfg_attr(feature = \"serde\", serde(serialize_with = \"crate::serde_utils::serialize_balance_source\"))]", + ) .compile_protos( &[ "src/proto/api.proto", diff --git a/ldk-server-protos/src/proto/types.proto b/ldk-server-protos/src/proto/types.proto index 73061692..4d7dafa1 100644 --- a/ldk-server-protos/src/proto/types.proto +++ b/ldk-server-protos/src/proto/types.proto @@ -523,6 +523,25 @@ message ClaimableAwaitingConfirmations { // The height at which we start tracking it as `SpendableOutput`. uint32 confirmation_height = 4; + + // Whether this balance is a result of cooperative close, a force-close, or an HTLC. + BalanceSource source = 5; +} + +// Indicates whether the balance is derived from a cooperative close, a force-close (for holder or counterparty), +// or whether it is for an HTLC. +enum BalanceSource { + // The channel was force closed by the holder. + HOLDER_FORCE_CLOSED = 0; + + // The channel was force closed by the counterparty. + COUNTERPARTY_FORCE_CLOSED = 1; + + // The channel was cooperatively closed. + COOP_CLOSE = 2; + + // This balance is the result of an HTLC. + HTLC = 3; } // The channel has been closed, and the given balance should be ours but awaiting spending transaction confirmation. diff --git a/ldk-server-protos/src/serde_utils.rs b/ldk-server-protos/src/serde_utils.rs index 2a32ec7e..5f10d137 100644 --- a/ldk-server-protos/src/serde_utils.rs +++ b/ldk-server-protos/src/serde_utils.rs @@ -36,6 +36,7 @@ macro_rules! stringify_enum_serializer { stringify_enum_serializer!(serialize_payment_direction, crate::types::PaymentDirection); stringify_enum_serializer!(serialize_payment_status, crate::types::PaymentStatus); +stringify_enum_serializer!(serialize_balance_source, crate::types::BalanceSource); /// Serializes `Option` as a hex string (or null). pub fn serialize_opt_bytes_hex( diff --git a/ldk-server-protos/src/types.rs b/ldk-server-protos/src/types.rs index 07098166..8ad60d3a 100644 --- a/ldk-server-protos/src/types.rs +++ b/ldk-server-protos/src/types.rs @@ -661,6 +661,13 @@ pub struct ClaimableAwaitingConfirmations { /// The height at which we start tracking it as `SpendableOutput`. #[prost(uint32, tag = "4")] pub confirmation_height: u32, + /// Whether this balance is a result of cooperative close, a force-close, or an HTLC. + #[prost(enumeration = "BalanceSource", tag = "5")] + #[cfg_attr( + feature = "serde", + serde(serialize_with = "crate::serde_utils::serialize_balance_source") + )] + pub source: i32, } /// The channel has been closed, and the given balance should be ours but awaiting spending transaction confirmation. /// If the spending transaction does not confirm in time, it is possible our counterparty can take the funds by @@ -975,3 +982,45 @@ impl PaymentStatus { } } } + +/// Indicates whether the balance is derived from a cooperative close, a force-close (for holder or counterparty), +/// or whether it is for an HTLC. +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum BalanceSource { + /// The channel was force closed by the holder. + HolderForceClosed = 0, + /// The channel was force closed by the counterparty. + CounterpartyForceClosed = 1, + /// The channel was cooperatively closed. + CoopClose = 2, + /// This balance is the result of an HTLC. + Htlc = 3, +} + +impl BalanceSource { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + BalanceSource::HolderForceClosed => "HOLDER_FORCE_CLOSED", + BalanceSource::CounterpartyForceClosed => "COUNTERPARTY_FORCE_CLOSED", + BalanceSource::CoopClose => "COOP_CLOSE", + BalanceSource::Htlc => "HTLC", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "HOLDER_FORCE_CLOSED" => Some(Self::HolderForceClosed), + "COUNTERPARTY_FORCE_CLOSED" => Some(Self::CounterpartyForceClosed), + "COOP_CLOSE" => Some(Self::CoopClose), + "HTLC" => Some(Self::Htlc), + _ => None, + } + } +} diff --git a/ldk-server/src/util/proto_adapter.rs b/ldk-server/src/util/proto_adapter.rs index 2eece481..690a9002 100644 --- a/ldk-server/src/util/proto_adapter.rs +++ b/ldk-server/src/util/proto_adapter.rs @@ -13,6 +13,7 @@ use hyper::StatusCode; use ldk_node::bitcoin::hashes::sha256; use ldk_node::bitcoin::secp256k1::PublicKey; use ldk_node::config::{ChannelConfig, MaxDustHTLCExposure}; +use ldk_node::lightning::chain::channelmonitor::BalanceSource; use ldk_node::lightning::ln::types::ChannelId; use ldk_node::lightning_invoice::{Bolt11InvoiceDescription, Description, Sha256}; use ldk_node::payment::{ @@ -255,7 +256,7 @@ pub(crate) fn lightning_balance_to_proto( counterparty_node_id, amount_satoshis, confirmation_height, - .. + source, } => ldk_server_protos::types::LightningBalance { balance_type: Some(ClaimableAwaitingConfirmations( ldk_server_protos::types::ClaimableAwaitingConfirmations { @@ -263,6 +264,18 @@ pub(crate) fn lightning_balance_to_proto( counterparty_node_id: counterparty_node_id.to_string(), amount_satoshis, confirmation_height, + source: match source { + BalanceSource::HolderForceClosed => { + ldk_server_protos::types::BalanceSource::HolderForceClosed.into() + }, + BalanceSource::CounterpartyForceClosed => { + ldk_server_protos::types::BalanceSource::CounterpartyForceClosed.into() + }, + BalanceSource::CoopClose => { + ldk_server_protos::types::BalanceSource::CoopClose.into() + }, + BalanceSource::Htlc => ldk_server_protos::types::BalanceSource::Htlc.into(), + }, }, )), },