Skip to content

Commit 95f3789

Browse files
committed
Expose list_channels in bindings
1 parent 44760ac commit 95f3789

File tree

4 files changed

+123
-5
lines changed

4 files changed

+123
-5
lines changed

bindings/ldk_node.udl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ interface Node {
4848
Invoice receive_variable_amount_payment([ByRef]string description, u32 expiry_secs);
4949
PaymentInfo? payment_info([ByRef]PaymentHash payment_hash);
5050
sequence<PublicKey> list_peers();
51+
sequence<ChannelDetails> list_channels();
5152
};
5253

5354
[Error]
@@ -107,6 +108,29 @@ dictionary PaymentInfo {
107108
PaymentStatus status;
108109
};
109110

111+
dictionary OutPoint {
112+
string txid;
113+
u16 index;
114+
};
115+
116+
dictionary ChannelDetails {
117+
ChannelId channel_id;
118+
PublicKey counterparty;
119+
OutPoint? funding_txo;
120+
u64? short_channel_id;
121+
u64 channel_value_satoshis;
122+
u64 balance_msat;
123+
u64 outbound_capacity_msat;
124+
u64 inbound_capacity_msat;
125+
u32? confirmations_required;
126+
u32? confirmations;
127+
boolean is_outbound;
128+
boolean is_channel_ready;
129+
boolean is_usable;
130+
boolean is_public;
131+
u16? cltv_expiry_delta;
132+
};
133+
110134
[Custom]
111135
typedef string PublicKey;
112136

src/channel.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use crate::ChannelId;
2+
use bitcoin::secp256k1::PublicKey;
3+
use lightning::chain::transaction::OutPoint as LdkOutpoint;
4+
use lightning::ln::channelmanager::ChannelDetails as LdkChannelDetails;
5+
6+
/// Data structure that references and transaction output.
7+
pub struct OutPoint {
8+
/// The referenced transaction's txid.
9+
pub txid: String,
10+
/// The index of the referenced output in its transaction's vout.
11+
pub index: u16,
12+
}
13+
14+
impl From<LdkOutpoint> for OutPoint {
15+
fn from(value: LdkOutpoint) -> Self {
16+
OutPoint { txid: value.txid.to_string(), index: value.index }
17+
}
18+
}
19+
20+
/// Details about the user's channel as returned by [`Node::list_channels`].
21+
///
22+
/// [`Node::list_channels`]: [`crate::Node::list_channels`]
23+
pub struct ChannelDetails {
24+
/// The channel's ID.
25+
pub channel_id: ChannelId,
26+
/// The `node_id` of our channel's counterparty.
27+
pub counterparty: PublicKey,
28+
/// Information about the channel's funding transaction output. `None `unless a funding
29+
/// transaction has been successfully negotiated with the channel's counterparty.
30+
pub funding_txo: Option<OutPoint>,
31+
/// Position of the funding transaction on-chain. `None` unless the funding transaction has been
32+
/// confirmed and fully opened.
33+
pub short_channel_id: Option<u64>,
34+
/// The value, in satoshis, of this channel as appears in the funding output.
35+
pub channel_value_satoshis: u64,
36+
/// Total balance of the channel. It is the amount that will be returned to the user if the
37+
/// channel is closed. The value is not exact, due to potential in-flight and fee-rate changes.
38+
/// Therefore, exactly this amount is likely irrecoverable on close.
39+
pub balance_msat: u64,
40+
/// Available outbound capacity for sending HTLCs to the remote peer. The amount does not
41+
/// include any pending HTLCs which are not yet resolved (and, thus, whose balance is not
42+
/// available for inclusion in new outbound HTLCs). This further does not include any
43+
/// pending outgoing HTLCs which are awaiting some other resolution to be sent.
44+
pub outbound_capacity_msat: u64,
45+
/// Available outbound capacity for sending HTLCs to the remote peer. The amount does not
46+
/// include any pending HTLCs which are not yet resolved (and, thus, whose balance is not
47+
/// available for inclusion in new inbound HTLCs). This further does not include any
48+
/// pending outgoing HTLCs which are awaiting some other resolution to be sent.
49+
pub inbound_capacity_msat: u64,
50+
/// The number of required confirmations on the funding transactions before the funding is
51+
/// considered "locked". The amount is selected by the channel fundee.
52+
///
53+
/// The value will be `None` for outbound channels until the counterparty accepts the channel.
54+
pub confirmations_required: Option<u32>,
55+
/// The current number of confirmations on the funding transaction.
56+
pub confirmations: Option<u32>,
57+
/// Returns `True` if the channel was initiated (and therefore funded) by us.
58+
pub is_outbound: bool,
59+
/// Returns `True` if the channel is confirmed, both parties have exchanged `channel_ready`
60+
/// messages, and the channel is not currently being shut down. Both parties exchange
61+
/// `channel_ready` messages upon independently verifying that the required confirmations count
62+
/// provided by `confirmations_required` has been reached.
63+
pub is_channel_ready: bool,
64+
/// Returns `True` if the channel is (a) confirmed and `channel_ready` has been exchanged,
65+
/// (b) the peer is connected, and (c) the channel is not currently negotiating shutdown.
66+
pub is_usable: bool,
67+
/// Returns `True` if this channel is (or will be) publicly-announced
68+
pub is_public: bool,
69+
/// The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded over
70+
/// the channel.
71+
pub cltv_expiry_delta: Option<u16>,
72+
}
73+
74+
impl From<LdkChannelDetails> for ChannelDetails {
75+
fn from(value: LdkChannelDetails) -> Self {
76+
ChannelDetails {
77+
channel_id: ChannelId(value.channel_id),
78+
counterparty: value.counterparty.node_id,
79+
funding_txo: value.funding_txo.and_then(|o| Some(o.into())),
80+
short_channel_id: value.short_channel_id,
81+
channel_value_satoshis: value.channel_value_satoshis,
82+
balance_msat: value.balance_msat,
83+
outbound_capacity_msat: value.outbound_capacity_msat,
84+
inbound_capacity_msat: value.inbound_capacity_msat,
85+
confirmations_required: value.confirmations_required,
86+
confirmations: value.confirmations,
87+
is_outbound: value.is_outbound,
88+
is_channel_ready: value.is_channel_ready,
89+
is_usable: value.is_usable,
90+
is_public: value.is_public,
91+
cltv_expiry_delta: value.config.and_then(|c| Some(c.cltv_expiry_delta)),
92+
}
93+
}
94+
}

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![allow(ellipsis_inclusive_range_patterns)]
2424
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2525

26+
mod channel;
2627
mod error;
2728
mod event;
2829
mod hex_utils;
@@ -59,9 +60,7 @@ use logger::{log_error, log_info, FilesystemLogger, Logger};
5960
use lightning::chain::keysinterface::EntropySource;
6061
use lightning::chain::{chainmonitor, BestBlock, Confirm, Watch};
6162
use lightning::ln::channelmanager;
62-
use lightning::ln::channelmanager::{
63-
ChainParameters, ChannelDetails, ChannelManagerReadArgs, PaymentId, Retry,
64-
};
63+
use lightning::ln::channelmanager::{ChainParameters, ChannelManagerReadArgs, PaymentId, Retry};
6564
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler};
6665
use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
6766
use lightning::routing::gossip::P2PGossipSync;
@@ -91,6 +90,7 @@ use bitcoin::{Address, BlockHash};
9190

9291
use rand::Rng;
9392

93+
use crate::channel::{ChannelDetails, OutPoint};
9494
use std::convert::{TryFrom, TryInto};
9595
use std::default::Default;
9696
use std::fs;
@@ -754,7 +754,7 @@ impl Node {
754754

755755
/// Retrieve a list of known channels.
756756
pub fn list_channels(&self) -> Vec<ChannelDetails> {
757-
self.channel_manager.list_channels()
757+
self.channel_manager.list_channels().iter().map(|c| c.clone().into()).collect()
758758
}
759759

760760
/// Connect to a node and open a new channel. Disconnects and re-connects are handled automatically

src/tests/functional_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ fn channel_full_cycle() {
186186
assert_eq!(node_a.list_peers(), [node_b.node_id()]);
187187

188188
let funding_txo = loop {
189-
let details = node_a.list_channels();
189+
let details = node_a.channel_manager.list_channels();
190190

191191
if details.is_empty() || details[0].funding_txo.is_none() {
192192
std::thread::sleep(Duration::from_secs(1));

0 commit comments

Comments
 (0)