Skip to content

Commit eba4aeb

Browse files
committed
Make address optional in open-channel command
When already connected to a peer, requiring the address to open a channel is unnecessary. The address field is now optional in the OpenChannelRequest proto and the CLI accepts pubkey@address format (like connect-peer) or just the pubkey alone. When no address is provided, the server resolves it from the connected peer list. AI tools were used in preparing this commit.
1 parent b8cebe8 commit eba4aeb

4 files changed

Lines changed: 38 additions & 11 deletions

File tree

ldk-server-cli/src/main.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,15 @@ enum Commands {
356356
},
357357
#[command(about = "Create a new outbound channel to the given remote node")]
358358
OpenChannel {
359-
#[arg(help = "The hex-encoded public key of the node to open a channel with")]
359+
#[arg(
360+
help = "The peer to open a channel with in pubkey@address format, or just the pubkey if already connected or address is provided separately"
361+
)]
360362
node_pubkey: String,
361363
#[arg(
362-
help = "Address to connect to remote peer (IPv4:port, IPv6:port, OnionV3:port, or hostname:port)"
364+
long,
365+
help = "Address to connect to remote peer (IPv4:port, IPv6:port, OnionV3:port, or hostname:port). Optional if address is included in pubkey via @ separator or already connected."
363366
)]
364-
address: String,
367+
address: Option<String>,
365368
#[arg(
366369
help = "The amount to commit to the channel, e.g. 100sat or 100000msat, must be a whole sat amount, cannot send msats on-chain."
367370
)]
@@ -894,6 +897,13 @@ async fn main() {
894897
forwarding_fee_base_msat,
895898
cltv_expiry_delta,
896899
} => {
900+
let (node_pubkey, address) = if let Some(address) = address {
901+
(node_pubkey, Some(address))
902+
} else if let Some((pubkey, addr)) = node_pubkey.split_once('@') {
903+
(pubkey.to_string(), Some(addr.to_string()))
904+
} else {
905+
(node_pubkey, None)
906+
};
897907
let channel_amount_sats =
898908
channel_amount.to_sat().unwrap_or_else(|e| handle_error_msg(&e));
899909
let push_to_counterparty_msat = push_to_counterparty.map(|a| a.to_msat());

ldk-server-protos/src/api.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,10 @@ pub struct OpenChannelRequest {
476476
#[prost(string, tag = "1")]
477477
pub node_pubkey: ::prost::alloc::string::String,
478478
/// An address which can be used to connect to a remote peer.
479-
/// It can be of type IPv4:port, IPv6:port, OnionV3:port or hostname:port
480-
#[prost(string, tag = "2")]
481-
pub address: ::prost::alloc::string::String,
479+
/// It can be of type IPv4:port, IPv6:port, OnionV3:port or hostname:port.
480+
/// Optional if already connected to the peer.
481+
#[prost(string, optional, tag = "2")]
482+
pub address: ::core::option::Option<::prost::alloc::string::String>,
482483
/// The amount of satoshis the caller is willing to commit to the channel.
483484
#[prost(uint64, tag = "3")]
484485
pub channel_amount_sats: u64,

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,9 @@ message OpenChannelRequest {
393393
string node_pubkey = 1;
394394

395395
// An address which can be used to connect to a remote peer.
396-
// It can be of type IPv4:port, IPv6:port, OnionV3:port or hostname:port
397-
string address = 2;
396+
// It can be of type IPv4:port, IPv6:port, OnionV3:port or hostname:port.
397+
// Optional if already connected to the peer.
398+
optional string address = 2;
398399

399400
// The amount of satoshis the caller is willing to commit to the channel.
400401
uint64 channel_amount_sats = 3;

ldk-server/src/api/open_channel.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,31 @@ use ldk_node::lightning::ln::msgs::SocketAddress;
1515
use ldk_server_protos::api::{OpenChannelRequest, OpenChannelResponse};
1616

1717
use crate::api::build_channel_config_from_proto;
18-
use crate::api::error::LdkServerError;
18+
use crate::api::error::{LdkServerError, LdkServerErrorCode};
1919
use crate::service::Context;
2020

2121
pub(crate) fn handle_open_channel(
2222
context: Context, request: OpenChannelRequest,
2323
) -> Result<OpenChannelResponse, LdkServerError> {
2424
let node_id = PublicKey::from_str(&request.node_pubkey)
2525
.map_err(|_| ldk_node::NodeError::InvalidPublicKey)?;
26-
let address = SocketAddress::from_str(&request.address)
27-
.map_err(|_| ldk_node::NodeError::InvalidSocketAddress)?;
26+
let address = match request.address {
27+
Some(addr) => {
28+
SocketAddress::from_str(&addr).map_err(|_| ldk_node::NodeError::InvalidSocketAddress)?
29+
},
30+
None => context
31+
.node
32+
.list_peers()
33+
.into_iter()
34+
.find(|p| p.node_id == node_id && p.is_connected)
35+
.map(|p| p.address)
36+
.ok_or_else(|| {
37+
LdkServerError::new(
38+
LdkServerErrorCode::InvalidRequestError,
39+
"address is required when not already connected to the peer",
40+
)
41+
})?,
42+
};
2843

2944
let channel_config = request
3045
.channel_config

0 commit comments

Comments
 (0)