From e9abc14b4ce2b03935695b177d87ac3667b32444 Mon Sep 17 00:00:00 2001 From: Enigbe Date: Tue, 24 Feb 2026 13:03:33 +0100 Subject: [PATCH] Add LdkServer to manage comms with an instance of ldk-server (daemon) Explores the addition of a client to manage communication with an instance of an ldk-server. We realize early the disparity between the local node information APIs exposed by LDK, relative to LND and CLN, and need to add feature support on ldk-node/server to permit the retrieval of the running node's network and features. These are necessary for sim-ln's validation logic as: - network ensures all nodes run on the same network, and also do not run on the mainnet - features ensure that keysend support is enabled --- simln-lib/Cargo.toml | 1 + simln-lib/src/ldk.rs | 90 ++++++++++++++++++++++++++++++ simln-lib/src/lib.rs | 1 + simln-lib/tests/ldk_integration.rs | 14 +++++ 4 files changed, 106 insertions(+) create mode 100644 simln-lib/src/ldk.rs create mode 100644 simln-lib/tests/ldk_integration.rs diff --git a/simln-lib/Cargo.toml b/simln-lib/Cargo.toml index 39d2f5ca..2c9faafe 100755 --- a/simln-lib/Cargo.toml +++ b/simln-lib/Cargo.toml @@ -33,6 +33,7 @@ rand_distr = "0.4.3" rand_chacha = "0.3.1" reqwest = { version = "0.12", features = ["json", "multipart"] } tokio-util = { version = "0.7.13", features = ["rt"] } +ldk-server-client = { git = "https://github.com/enigbe/ldk-server", rev = "refs/pull/1/head", package = "ldk-server-client"} [dev-dependencies] ntest = "0.9.0" diff --git a/simln-lib/src/ldk.rs b/simln-lib/src/ldk.rs new file mode 100644 index 00000000..36ca16b8 --- /dev/null +++ b/simln-lib/src/ldk.rs @@ -0,0 +1,90 @@ +use std::str::FromStr; + +use async_trait::async_trait; +use bitcoin::Network; +use ldk_server_client::client::LdkServerClient; +use lightning::ln::features::NodeFeatures; + +use crate::{LightningError, LightningNode, NodeInfo}; + +pub struct LdkServerConnection { + pub base_url: String, + pub api_key: String, + pub server_cert_pem: Vec, +} + +pub struct LdkServer { + client: LdkServerClient, + info: NodeInfo, + network: Network, +} + +impl LdkServer { + /// Creates a new instance that connects to a running `ldk-server` node (daemon). + pub async fn new(connection: LdkServerConnection) -> Result { + let client = LdkServerClient::new(base_url, api_key, server_cert_pem) + .map_err(|e| LightningError::ConnectionError(e))?; + + let node_info_res = client + .get_node_info(node_info_req) + .await + .map_err(|e| LightningError::GetNodeInfoError(e.to_string()))?; + + let network = Network::from_str(node_info_res.network.as_str()) + .map_err(|e| LightningError::GetNodeInfoError(e.to_string()))?; + + let info = NodeInfo { + pubkey: node_info_res.node_id.into(), + alias: node_info_res.node_alias().to_string(), + features: match node_info_res.features { + Some(features) => NodeFeatures::from_be_bytes(features.node.to_vec()), + None => NodeFeatures::empty(), + }, + }; + + Ok(Self { + client, + info, + network, + }) + } +} + +#[async_trait] +impl LightningNode for LdkServer { + fn get_info(&self) -> &NodeInfo { + todo!() + } + + fn get_network(&self) -> Network { + todo!() + } + + async fn send_payment( + &self, + dest: PublicKey, + amount_msat: u64, + ) -> Result { + todo!() + } + + async fn track_payment( + &self, + hash: &PaymentHash, + shutdown: Listener, + ) -> Result { + todo!() + } + + async fn get_node_info(&self, node_id: &PublicKey) -> Result { + todo!() + } + + async fn channel_capacities(&self) -> Result { + todo!() + } + + async fn get_graph(&self) -> Result { + todo!() + } +} diff --git a/simln-lib/src/lib.rs b/simln-lib/src/lib.rs index a1b5fe0e..23988abb 100755 --- a/simln-lib/src/lib.rs +++ b/simln-lib/src/lib.rs @@ -36,6 +36,7 @@ pub mod clock; mod defined_activity; pub mod eclair; pub mod latency_interceptor; +pub mod ldk; pub mod lnd; mod random_activity; pub mod serializers; diff --git a/simln-lib/tests/ldk_integration.rs b/simln-lib/tests/ldk_integration.rs new file mode 100644 index 00000000..f8a3f60c --- /dev/null +++ b/simln-lib/tests/ldk_integration.rs @@ -0,0 +1,14 @@ +use simln_lib::ldk::{LdkServer, LdkServerConnection}; + +#[test] +async fn connect_successfully_to_ldkserver() { + let conn = LdkServerConnection { + base_url: "127.0.0.1:3002".to_string(), + api_key: todo!(), + server_cert_pem: todo!(), + }; + let client = LdkServer::new(conn) + .await + .expect("Failed to connect to LDK server."); + todo!() +}