Skip to content

Commit 39ad7cb

Browse files
authored
Merge pull request lightningdevkit#13 from G8XSU/s2-apis
Implement ListChannels and GetNodeInfo Api.
2 parents 78f482a + 729e672 commit 39ad7cb

10 files changed

Lines changed: 252 additions & 40 deletions

File tree

ldk-server/protos/src/lib.rs

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,50 @@
1+
/// Retrieve the latest node info like `node_id`, `current_best_block` etc.
2+
/// See more:
3+
/// - <https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.node_id>
4+
/// - <https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.status>
5+
#[allow(clippy::derive_partial_eq_without_eq)]
6+
#[derive(Clone, PartialEq, ::prost::Message)]
7+
pub struct GetNodeInfoRequest {}
8+
#[allow(clippy::derive_partial_eq_without_eq)]
9+
#[derive(Clone, PartialEq, ::prost::Message)]
10+
pub struct GetNodeInfoResponse {
11+
/// The hex-encoded `node-id` or public key for our own lightning node.
12+
#[prost(string, tag = "1")]
13+
pub node_id: ::prost::alloc::string::String,
14+
/// The best block to which our Lightning wallet is currently synced.
15+
///
16+
/// Should be always set, will never be `None`.
17+
#[prost(message, optional, tag = "3")]
18+
pub current_best_block: ::core::option::Option<BestBlock>,
19+
/// The timestamp, in seconds since start of the UNIX epoch, when we last successfully synced our Lightning wallet
20+
/// to the chain tip.
21+
///
22+
/// Will be `None` if the wallet hasn’t been synced since the node was initialized.
23+
#[prost(uint64, optional, tag = "4")]
24+
pub latest_wallet_sync_timestamp: ::core::option::Option<u64>,
25+
/// The timestamp, in seconds since start of the UNIX epoch, when we last successfully synced our on-chain
26+
/// wallet to the chain tip.
27+
///
28+
/// Will be `None` if the wallet hasn’t been synced since the node was initialized.
29+
#[prost(uint64, optional, tag = "5")]
30+
pub latest_onchain_wallet_sync_timestamp: ::core::option::Option<u64>,
31+
/// The timestamp, in seconds since start of the UNIX epoch, when we last successfully update our fee rate cache.
32+
///
33+
/// Will be `None` if the cache hasn’t been updated since the node was initialized.
34+
#[prost(uint64, optional, tag = "6")]
35+
pub latest_fee_rate_cache_update_timestamp: ::core::option::Option<u64>,
36+
/// The timestamp, in seconds since start of the UNIX epoch, when the last rapid gossip sync (RGS) snapshot we
37+
/// successfully applied was generated.
38+
///
39+
/// Will be `None` if RGS isn’t configured or the snapshot hasn’t been updated since the node was initialized.
40+
#[prost(uint64, optional, tag = "7")]
41+
pub latest_rgs_snapshot_timestamp: ::core::option::Option<u64>,
42+
/// The timestamp, in seconds since start of the UNIX epoch, when we last broadcasted a node announcement.
43+
///
44+
/// Will be `None` if we have no public channels or we haven’t broadcasted since the node was initialized.
45+
#[prost(uint64, optional, tag = "8")]
46+
pub latest_node_announcement_broadcast_timestamp: ::core::option::Option<u64>,
47+
}
148
/// Retrieve a new on-chain funding address.
249
/// See more: <https://docs.rs/ldk-node/latest/ldk_node/payment/struct.OnchainPayment.html#method.new_address>
350
#[allow(clippy::derive_partial_eq_without_eq)]
@@ -184,28 +231,28 @@ pub struct ChannelConfig {
184231
/// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
185232
/// over the channel.
186233
/// See more: <https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.forwarding_fee_proportional_millionths>
187-
#[prost(uint32, tag = "1")]
188-
pub forwarding_fee_proportional_millionths: u32,
234+
#[prost(uint32, optional, tag = "1")]
235+
pub forwarding_fee_proportional_millionths: ::core::option::Option<u32>,
189236
/// Amount (in milli-satoshi) charged for payments forwarded outbound over the channel,
190237
/// in excess of forwarding_fee_proportional_millionths.
191238
/// See more: <https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.forwarding_fee_base_msat>
192-
#[prost(uint32, tag = "2")]
193-
pub forwarding_fee_base_msat: u32,
239+
#[prost(uint32, optional, tag = "2")]
240+
pub forwarding_fee_base_msat: ::core::option::Option<u32>,
194241
/// The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded
195242
/// over the channel this config applies to.
196243
/// See more: <https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.cltv_expiry_delta>
197-
#[prost(uint32, tag = "3")]
198-
pub cltv_expiry_delta: u32,
244+
#[prost(uint32, optional, tag = "3")]
245+
pub cltv_expiry_delta: ::core::option::Option<u32>,
199246
/// The maximum additional fee we’re willing to pay to avoid waiting for the counterparty’s
200247
/// to_self_delay to reclaim funds.
201248
/// See more: <https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.force_close_avoidance_max_fee_satoshis>
202-
#[prost(uint64, tag = "4")]
203-
pub force_close_avoidance_max_fee_satoshis: u64,
249+
#[prost(uint64, optional, tag = "4")]
250+
pub force_close_avoidance_max_fee_satoshis: ::core::option::Option<u64>,
204251
/// If set, allows this channel’s counterparty to skim an additional fee off this node’s
205252
/// inbound HTLCs. Useful for liquidity providers to offload on-chain channel costs to end users.
206253
/// See more: <https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.accept_underpaying_htlcs>
207-
#[prost(bool, tag = "5")]
208-
pub accept_underpaying_htlcs: bool,
254+
#[prost(bool, optional, tag = "5")]
255+
pub accept_underpaying_htlcs: ::core::option::Option<bool>,
209256
/// Limit our total exposure to potential loss to on-chain fees on close, including
210257
/// in-flight HTLCs which are burned to fees as they are too small to claim on-chain
211258
/// and fees on commitment transaction(s) broadcasted by our counterparty in excess of
@@ -284,9 +331,9 @@ pub struct Channel {
284331
/// our counterparty already.
285332
#[prost(message, optional, tag = "3")]
286333
pub funding_txo: ::core::option::Option<OutPoint>,
287-
/// The local `user_channel_id` of this channel.
288-
#[prost(bytes = "bytes", tag = "4")]
289-
pub user_channel_id: ::prost::bytes::Bytes,
334+
/// The hex-encoded local `user_channel_id` of this channel.
335+
#[prost(string, tag = "4")]
336+
pub user_channel_id: ::prost::alloc::string::String,
290337
/// The value, in satoshis, that must always be held as a reserve in the channel for us. This
291338
/// value ensures that if we broadcast a revoked state, our counterparty can punish us by
292339
/// claiming at least this value on chain.
@@ -383,8 +430,8 @@ pub struct Channel {
383430
/// claiming at least this value on chain.
384431
///
385432
/// This value is not included in `inbound_capacity_msat` as it can never be spent.
386-
#[prost(uint64, optional, tag = "22")]
387-
pub counterparty_unspendable_punishment_reserve: ::core::option::Option<u64>,
433+
#[prost(uint64, tag = "22")]
434+
pub counterparty_unspendable_punishment_reserve: u64,
388435
/// Base routing fee in millisatoshis.
389436
#[prost(uint32, optional, tag = "23")]
390437
pub counterparty_forwarding_info_fee_base_msat: ::core::option::Option<u32>,
@@ -407,3 +454,13 @@ pub struct OutPoint {
407454
#[prost(uint32, tag = "2")]
408455
pub vout: u32,
409456
}
457+
#[allow(clippy::derive_partial_eq_without_eq)]
458+
#[derive(Clone, PartialEq, ::prost::Message)]
459+
pub struct BestBlock {
460+
/// The block’s hash
461+
#[prost(string, tag = "1")]
462+
pub block_hash: ::prost::alloc::string::String,
463+
/// The height at which the block was confirmed.
464+
#[prost(uint32, tag = "2")]
465+
pub height: u32,
466+
}

ldk-server/protos/src/proto/ldk_node_server.proto

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,52 @@
11
syntax = "proto3";
22
package ldk_node_server;
33

4+
// Retrieve the latest node info like `node_id`, `current_best_block` etc.
5+
// See more:
6+
// - https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.node_id
7+
// - https://docs.rs/ldk-node/latest/ldk_node/struct.Node.html#method.status
8+
message GetNodeInfoRequest {
9+
}
10+
11+
message GetNodeInfoResponse {
12+
13+
// The hex-encoded `node-id` or public key for our own lightning node.
14+
string node_id = 1;
15+
16+
// The best block to which our Lightning wallet is currently synced.
17+
//
18+
// Should be always set, will never be `None`.
19+
BestBlock current_best_block = 3;
20+
21+
// The timestamp, in seconds since start of the UNIX epoch, when we last successfully synced our Lightning wallet
22+
// to the chain tip.
23+
//
24+
// Will be `None` if the wallet hasn’t been synced since the node was initialized.
25+
optional uint64 latest_wallet_sync_timestamp = 4;
26+
27+
// The timestamp, in seconds since start of the UNIX epoch, when we last successfully synced our on-chain
28+
// wallet to the chain tip.
29+
//
30+
// Will be `None` if the wallet hasn’t been synced since the node was initialized.
31+
optional uint64 latest_onchain_wallet_sync_timestamp = 5;
32+
33+
// The timestamp, in seconds since start of the UNIX epoch, when we last successfully update our fee rate cache.
34+
//
35+
// Will be `None` if the cache hasn’t been updated since the node was initialized.
36+
optional uint64 latest_fee_rate_cache_update_timestamp = 6;
37+
38+
// The timestamp, in seconds since start of the UNIX epoch, when the last rapid gossip sync (RGS) snapshot we
39+
// successfully applied was generated.
40+
//
41+
// Will be `None` if RGS isn’t configured or the snapshot hasn’t been updated since the node was initialized.
42+
optional uint64 latest_rgs_snapshot_timestamp = 7;
43+
44+
// The timestamp, in seconds since start of the UNIX epoch, when we last broadcasted a node announcement.
45+
//
46+
// Will be `None` if we have no public channels or we haven’t broadcasted since the node was initialized.
47+
optional uint64 latest_node_announcement_broadcast_timestamp = 8;
48+
}
49+
450
// Retrieve a new on-chain funding address.
551
// See more: https://docs.rs/ldk-node/latest/ldk_node/payment/struct.OnchainPayment.html#method.new_address
652
message OnchainReceiveRequest {
@@ -174,27 +220,27 @@ message ChannelConfig {
174220
// Amount (in millionths of a satoshi) charged per satoshi for payments forwarded outbound
175221
// over the channel.
176222
// See more: https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.forwarding_fee_proportional_millionths
177-
uint32 forwarding_fee_proportional_millionths = 1;
223+
optional uint32 forwarding_fee_proportional_millionths = 1;
178224

179225
// Amount (in milli-satoshi) charged for payments forwarded outbound over the channel,
180226
// in excess of forwarding_fee_proportional_millionths.
181227
// See more: https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.forwarding_fee_base_msat
182-
uint32 forwarding_fee_base_msat = 2;
228+
optional uint32 forwarding_fee_base_msat = 2;
183229

184230
// The difference in the CLTV value between incoming HTLCs and an outbound HTLC forwarded
185231
// over the channel this config applies to.
186232
// See more: https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.cltv_expiry_delta
187-
uint32 cltv_expiry_delta = 3;
233+
optional uint32 cltv_expiry_delta = 3;
188234

189235
// The maximum additional fee we’re willing to pay to avoid waiting for the counterparty’s
190236
// to_self_delay to reclaim funds.
191237
// See more: https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.force_close_avoidance_max_fee_satoshis
192-
uint64 force_close_avoidance_max_fee_satoshis = 4;
238+
optional uint64 force_close_avoidance_max_fee_satoshis = 4;
193239

194240
// If set, allows this channel’s counterparty to skim an additional fee off this node’s
195241
// inbound HTLCs. Useful for liquidity providers to offload on-chain channel costs to end users.
196242
// See more: https://docs.rs/lightning/latest/lightning/util/config/struct.ChannelConfig.html#structfield.accept_underpaying_htlcs
197-
bool accept_underpaying_htlcs = 5;
243+
optional bool accept_underpaying_htlcs = 5;
198244

199245
// Limit our total exposure to potential loss to on-chain fees on close, including
200246
// in-flight HTLCs which are burned to fees as they are too small to claim on-chain
@@ -259,8 +305,8 @@ message Channel {
259305
// our counterparty already.
260306
optional OutPoint funding_txo = 3;
261307

262-
// The local `user_channel_id` of this channel.
263-
bytes user_channel_id = 4;
308+
// The hex-encoded local `user_channel_id` of this channel.
309+
string user_channel_id = 4;
264310

265311
// The value, in satoshis, that must always be held as a reserve in the channel for us. This
266312
// value ensures that if we broadcast a revoked state, our counterparty can punish us by
@@ -358,7 +404,7 @@ message Channel {
358404
// claiming at least this value on chain.
359405
//
360406
// This value is not included in `inbound_capacity_msat` as it can never be spent.
361-
optional uint64 counterparty_unspendable_punishment_reserve = 22;
407+
uint64 counterparty_unspendable_punishment_reserve = 22;
362408

363409
// Base routing fee in millisatoshis.
364410
optional uint32 counterparty_forwarding_info_fee_base_msat = 23;
@@ -378,4 +424,14 @@ message OutPoint {
378424

379425
// The index of the referenced output in its transaction's vout.
380426
uint32 vout = 2;
381-
}
427+
}
428+
429+
message BestBlock {
430+
431+
// The block’s hash
432+
string block_hash = 1;
433+
434+
// The height at which the block was confirmed.
435+
uint32 height = 2;
436+
437+
}

ldk-server/server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ tokio = { version = "1.38.0", default-features = false, features = ["time", "sig
1414
prost = { version = "0.11.6", default-features = false, features = ["std"] }
1515
protos = { path = "../protos" }
1616
bytes = "1.4.0"
17+
hex = { package = "hex-conservative", version = "0.2.1", default-features = false }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use ldk_node::Node;
2+
use protos::{BestBlock, GetNodeInfoRequest, GetNodeInfoResponse};
3+
use std::sync::Arc;
4+
5+
pub(crate) const GET_NODE_INFO: &str = "GetNodeInfo";
6+
7+
pub(crate) fn handle_get_node_info_request(
8+
node: Arc<Node>, _request: GetNodeInfoRequest,
9+
) -> Result<GetNodeInfoResponse, ldk_node::NodeError> {
10+
let node_status = node.status();
11+
12+
let best_block = BestBlock {
13+
block_hash: node_status.current_best_block.block_hash.to_string(),
14+
height: node_status.current_best_block.height,
15+
};
16+
17+
let response = GetNodeInfoResponse {
18+
node_id: node.node_id().to_string(),
19+
current_best_block: Some(best_block),
20+
latest_wallet_sync_timestamp: node_status.latest_wallet_sync_timestamp,
21+
latest_onchain_wallet_sync_timestamp: node_status.latest_onchain_wallet_sync_timestamp,
22+
latest_fee_rate_cache_update_timestamp: node_status.latest_fee_rate_cache_update_timestamp,
23+
latest_rgs_snapshot_timestamp: node_status.latest_rgs_snapshot_timestamp,
24+
latest_node_announcement_broadcast_timestamp: node_status
25+
.latest_node_announcement_broadcast_timestamp,
26+
};
27+
Ok(response)
28+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use crate::util::proto_adapter::channel_to_proto;
2+
use ldk_node::Node;
3+
use protos::{ListChannelsRequest, ListChannelsResponse};
4+
use std::sync::Arc;
5+
6+
pub(crate) const LIST_CHANNELS_PATH: &str = "ListChannels";
7+
8+
pub(crate) fn handle_list_channels_request(
9+
node: Arc<Node>, _request: ListChannelsRequest,
10+
) -> Result<ListChannelsResponse, ldk_node::NodeError> {
11+
let channels = node.list_channels().into_iter().map(|c| channel_to_proto(c)).collect();
12+
13+
let response = ListChannelsResponse { channels };
14+
Ok(response)
15+
}

ldk-server/server/src/api/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pub(crate) mod bolt11_send;
33
pub(crate) mod bolt12_receive;
44
pub(crate) mod bolt12_send;
55
pub(crate) mod close_channel;
6+
pub(crate) mod get_node_info;
7+
pub(crate) mod list_channels;
68
pub(crate) mod onchain_receive;
79
pub(crate) mod onchain_send;
810
pub(crate) mod open_channel;

ldk-server/server/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod api;
22
mod service;
3+
mod util;
34

45
use crate::service::NodeService;
56

ldk-server/server/src/service.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,16 @@ use std::future::Future;
1111
use std::pin::Pin;
1212
use std::sync::Arc;
1313

14-
use crate::api::bolt11_receive::handle_bolt11_receive_request;
15-
use crate::api::bolt11_receive::BOLT11_RECEIVE_PATH;
16-
use crate::api::bolt11_send::handle_bolt11_send_request;
17-
use crate::api::bolt11_send::BOLT11_SEND_PATH;
18-
use crate::api::bolt12_receive::handle_bolt12_receive_request;
19-
use crate::api::bolt12_receive::BOLT12_RECEIVE_PATH;
20-
use crate::api::bolt12_send::handle_bolt12_send_request;
21-
use crate::api::bolt12_send::BOLT12_SEND_PATH;
22-
use crate::api::close_channel::handle_close_channel_request;
23-
use crate::api::close_channel::CLOSE_CHANNEL_PATH;
24-
use crate::api::onchain_receive::handle_onchain_receive_request;
25-
use crate::api::onchain_receive::ONCHAIN_RECEIVE_PATH;
26-
use crate::api::onchain_send::handle_onchain_send_request;
27-
use crate::api::onchain_send::ONCHAIN_SEND_PATH;
28-
use crate::api::open_channel::handle_open_channel;
29-
use crate::api::open_channel::OPEN_CHANNEL_PATH;
14+
use crate::api::bolt11_receive::{handle_bolt11_receive_request, BOLT11_RECEIVE_PATH};
15+
use crate::api::bolt11_send::{handle_bolt11_send_request, BOLT11_SEND_PATH};
16+
use crate::api::bolt12_receive::{handle_bolt12_receive_request, BOLT12_RECEIVE_PATH};
17+
use crate::api::bolt12_send::{handle_bolt12_send_request, BOLT12_SEND_PATH};
18+
use crate::api::close_channel::{handle_close_channel_request, CLOSE_CHANNEL_PATH};
19+
use crate::api::get_node_info::{handle_get_node_info_request, GET_NODE_INFO};
20+
use crate::api::list_channels::{handle_list_channels_request, LIST_CHANNELS_PATH};
21+
use crate::api::onchain_receive::{handle_onchain_receive_request, ONCHAIN_RECEIVE_PATH};
22+
use crate::api::onchain_send::{handle_onchain_send_request, ONCHAIN_SEND_PATH};
23+
use crate::api::open_channel::{handle_open_channel, OPEN_CHANNEL_PATH};
3024

3125
#[derive(Clone)]
3226
pub struct NodeService {
@@ -48,6 +42,7 @@ impl Service<Request<Incoming>> for NodeService {
4842
let node = Arc::clone(&self.node);
4943
// Exclude '/' from path pattern matching.
5044
match &req.uri().path()[1..] {
45+
GET_NODE_INFO => Box::pin(handle_request(node, req, handle_get_node_info_request)),
5146
ONCHAIN_RECEIVE_PATH => {
5247
Box::pin(handle_request(node, req, handle_onchain_receive_request))
5348
},
@@ -62,6 +57,7 @@ impl Service<Request<Incoming>> for NodeService {
6257
BOLT12_SEND_PATH => Box::pin(handle_request(node, req, handle_bolt12_send_request)),
6358
OPEN_CHANNEL_PATH => Box::pin(handle_request(node, req, handle_open_channel)),
6459
CLOSE_CHANNEL_PATH => Box::pin(handle_request(node, req, handle_close_channel_request)),
60+
LIST_CHANNELS_PATH => Box::pin(handle_request(node, req, handle_list_channels_request)),
6561
path => {
6662
let error = format!("Unknown request: {}", path).into_bytes();
6763
Box::pin(async {

ldk-server/server/src/util/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub(crate) mod proto_adapter;

0 commit comments

Comments
 (0)