Skip to content

Commit e65a0fb

Browse files
committed
Make cli output json
Previously we would output the debug format of each of our return times which worked, but was not very usable. You could not easily pipe results with cli tools or anything like that. This changes the results to be output to json to make it easier to use and more similiar to what people expect.
1 parent dc62253 commit e65a0fb

File tree

10 files changed

+249
-32
lines changed

10 files changed

+249
-32
lines changed

Cargo.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ldk-server-cli/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
ldk-server-client = { path = "../ldk-server-client" }
7+
ldk-server-client = { path = "../ldk-server-client", features = ["serde"] }
88
clap = { version = "4.0.5", default-features = false, features = ["derive", "std", "error-context", "suggestions", "help"] }
99
tokio = { version = "1.38.0", default-features = false, features = ["rt-multi-thread", "macros"] }
10-
prost = { version = "0.11.6", default-features = false}
10+
serde = "1.0"
11+
serde_json = "1.0"

ldk-server-cli/src/main.rs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ use ldk_server_client::error::LdkServerErrorCode::{
55
AuthError, InternalError, InternalServerError, InvalidRequestError, LightningError,
66
};
77
use ldk_server_client::ldk_server_protos::api::{
8-
Bolt11ReceiveRequest, Bolt11SendRequest, Bolt12ReceiveRequest, Bolt12SendRequest,
9-
CloseChannelRequest, ForceCloseChannelRequest, GetBalancesRequest, GetNodeInfoRequest,
10-
ListChannelsRequest, ListPaymentsRequest, OnchainReceiveRequest, OnchainSendRequest,
11-
OpenChannelRequest, SpliceInRequest, SpliceOutRequest, UpdateChannelConfigRequest,
8+
Bolt11ReceiveRequest, Bolt11ReceiveResponse, Bolt11SendRequest, Bolt11SendResponse,
9+
Bolt12ReceiveRequest, Bolt12ReceiveResponse, Bolt12SendRequest, Bolt12SendResponse,
10+
CloseChannelRequest, CloseChannelResponse, ForceCloseChannelRequest, ForceCloseChannelResponse,
11+
GetBalancesRequest, GetBalancesResponse, GetNodeInfoRequest, GetNodeInfoResponse,
12+
ListChannelsRequest, ListChannelsResponse, ListPaymentsRequest, ListPaymentsResponse,
13+
OnchainReceiveRequest, OnchainReceiveResponse, OnchainSendRequest, OnchainSendResponse,
14+
OpenChannelRequest, OpenChannelResponse, SpliceInRequest, SpliceInResponse, SpliceOutRequest,
15+
SpliceOutResponse, UpdateChannelConfigRequest, UpdateChannelConfigResponse,
1216
};
13-
use ldk_server_client::ldk_server_protos::types::RouteParametersConfig;
1417
use ldk_server_client::ldk_server_protos::types::{
15-
bolt11_invoice_description, channel_config, Bolt11InvoiceDescription, ChannelConfig, PageToken,
16-
Payment,
18+
bolt11_invoice_description, Bolt11InvoiceDescription, ChannelConfig, PageToken, Payment,
19+
RouteParametersConfig,
1720
};
18-
use std::fmt::Debug;
21+
use serde::Serialize;
1922

2023
// Having these default values as constants in the Proto file and
2124
// importing/reusing them here might be better, but Proto3 removed
@@ -199,16 +202,22 @@ async fn main() {
199202

200203
match cli.command {
201204
Commands::GetNodeInfo => {
202-
handle_response_result(client.get_node_info(GetNodeInfoRequest {}).await);
205+
handle_response_result::<_, GetNodeInfoResponse>(
206+
client.get_node_info(GetNodeInfoRequest {}).await,
207+
);
203208
},
204209
Commands::GetBalances => {
205-
handle_response_result(client.get_balances(GetBalancesRequest {}).await);
210+
handle_response_result::<_, GetBalancesResponse>(
211+
client.get_balances(GetBalancesRequest {}).await,
212+
);
206213
},
207214
Commands::OnchainReceive => {
208-
handle_response_result(client.onchain_receive(OnchainReceiveRequest {}).await);
215+
handle_response_result::<_, OnchainReceiveResponse>(
216+
client.onchain_receive(OnchainReceiveRequest {}).await,
217+
);
209218
},
210219
Commands::OnchainSend { address, amount_sats, send_all, fee_rate_sat_per_vb } => {
211-
handle_response_result(
220+
handle_response_result::<_, OnchainSendResponse>(
212221
client
213222
.onchain_send(OnchainSendRequest {
214223
address,
@@ -239,7 +248,9 @@ async fn main() {
239248
let request =
240249
Bolt11ReceiveRequest { description: invoice_description, expiry_secs, amount_msat };
241250

242-
handle_response_result(client.bolt11_receive(request).await);
251+
handle_response_result::<_, Bolt11ReceiveResponse>(
252+
client.bolt11_receive(request).await,
253+
);
243254
},
244255
Commands::Bolt11Send {
245256
invoice,
@@ -257,7 +268,7 @@ async fn main() {
257268
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
258269
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
259270
};
260-
handle_response_result(
271+
handle_response_result::<_, Bolt11SendResponse>(
261272
client
262273
.bolt11_send(Bolt11SendRequest {
263274
invoice,
@@ -268,7 +279,7 @@ async fn main() {
268279
);
269280
},
270281
Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => {
271-
handle_response_result(
282+
handle_response_result::<_, Bolt12ReceiveResponse>(
272283
client
273284
.bolt12_receive(Bolt12ReceiveRequest {
274285
description,
@@ -298,7 +309,7 @@ async fn main() {
298309
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
299310
};
300311

301-
handle_response_result(
312+
handle_response_result::<_, Bolt12SendResponse>(
302313
client
303314
.bolt12_send(Bolt12SendRequest {
304315
offer,
@@ -311,7 +322,7 @@ async fn main() {
311322
);
312323
},
313324
Commands::CloseChannel { user_channel_id, counterparty_node_id } => {
314-
handle_response_result(
325+
handle_response_result::<_, CloseChannelResponse>(
315326
client
316327
.close_channel(CloseChannelRequest { user_channel_id, counterparty_node_id })
317328
.await,
@@ -322,7 +333,7 @@ async fn main() {
322333
counterparty_node_id,
323334
force_close_reason,
324335
} => {
325-
handle_response_result(
336+
handle_response_result::<_, ForceCloseChannelResponse>(
326337
client
327338
.force_close_channel(ForceCloseChannelRequest {
328339
user_channel_id,
@@ -348,7 +359,7 @@ async fn main() {
348359
cltv_expiry_delta,
349360
);
350361

351-
handle_response_result(
362+
handle_response_result::<_, OpenChannelResponse>(
352363
client
353364
.open_channel(OpenChannelRequest {
354365
node_pubkey,
@@ -362,7 +373,7 @@ async fn main() {
362373
);
363374
},
364375
Commands::SpliceIn { user_channel_id, counterparty_node_id, splice_amount_sats } => {
365-
handle_response_result(
376+
handle_response_result::<_, SpliceInResponse>(
366377
client
367378
.splice_in(SpliceInRequest {
368379
user_channel_id,
@@ -378,7 +389,7 @@ async fn main() {
378389
address,
379390
splice_amount_sats,
380391
} => {
381-
handle_response_result(
392+
handle_response_result::<_, SpliceOutResponse>(
382393
client
383394
.splice_out(SpliceOutRequest {
384395
user_channel_id,
@@ -390,10 +401,17 @@ async fn main() {
390401
);
391402
},
392403
Commands::ListChannels => {
393-
handle_response_result(client.list_channels(ListChannelsRequest {}).await);
404+
handle_response_result::<_, ListChannelsResponse>(
405+
client.list_channels(ListChannelsRequest {}).await,
406+
);
394407
},
395408
Commands::ListPayments { number_of_payments } => {
396-
handle_response_result(list_n_payments(client, number_of_payments).await);
409+
handle_response_result::<_, ListPaymentsResponse>(
410+
list_n_payments(client, number_of_payments)
411+
.await
412+
// todo: handle pagination properly
413+
.map(|payments| ListPaymentsResponse { payments, next_page_token: None }),
414+
);
397415
},
398416
Commands::UpdateChannelConfig {
399417
user_channel_id,
@@ -411,7 +429,7 @@ async fn main() {
411429
max_dust_htlc_exposure: None,
412430
};
413431

414-
handle_response_result(
432+
handle_response_result::<_, UpdateChannelConfigResponse>(
415433
client
416434
.update_channel_config(UpdateChannelConfigRequest {
417435
user_channel_id,
@@ -466,10 +484,21 @@ async fn list_n_payments(
466484
Ok(payments)
467485
}
468486

469-
fn handle_response_result<Rs: Debug>(response: Result<Rs, LdkServerError>) {
487+
fn handle_response_result<Rs, Js>(response: Result<Rs, LdkServerError>)
488+
where
489+
Rs: Into<Js>,
490+
Js: Serialize + std::fmt::Debug,
491+
{
470492
match response {
471493
Ok(response) => {
472-
println!("Success: {:?}", response);
494+
let json_response: Js = response.into();
495+
match serde_json::to_string_pretty(&json_response) {
496+
Ok(json) => println!("{json}"),
497+
Err(e) => {
498+
eprintln!("Error serializing response ({json_response:?}) to JSON: {e}");
499+
std::process::exit(1);
500+
},
501+
}
473502
},
474503
Err(e) => {
475504
handle_error(e);

ldk-server-client/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name = "ldk-server-client"
33
version = "0.1.0"
44
edition = "2021"
55

6+
[features]
7+
default = []
8+
serde = ["ldk-server-protos/serde"]
9+
610
[dependencies]
711
ldk-server-protos = { path = "../ldk-server-protos" }
812
reqwest = { version = "0.11.13", default-features = false, features = ["rustls-tls"] }

ldk-server-protos/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ edition = "2021"
55

66
build = "build.rs"
77

8+
[features]
9+
default = []
10+
serde = ["dep:serde", "dep:bytes"]
11+
812
[dependencies]
913
prost = { version = "0.11.6", default-features = false, features = ["std", "prost-derive"] }
14+
serde = { version = "1.0", features = ["derive"], optional = true }
15+
bytes = { version = "1", features = ["serde"], optional = true }
1016

1117
[target.'cfg(genproto)'.build-dependencies]
12-
prost-build = { version = "0.11.6" , default-features = false}
18+
prost-build = { version = "0.11.6", default-features = false }

ldk-server-protos/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ fn main() {
1414
fn generate_protos() {
1515
prost_build::Config::new()
1616
.bytes(&["."])
17+
.type_attribute(
18+
".",
19+
"#[cfg_attr(feature = \"serde\", derive(serde::Serialize, serde::Deserialize))]",
20+
)
21+
.type_attribute(".", "#[cfg_attr(feature = \"serde\", serde(rename_all = \"snake_case\"))]")
1722
.compile_protos(
1823
&[
1924
"src/proto/api.proto",

0 commit comments

Comments
 (0)