Skip to content

Commit 0eb5f9d

Browse files
authored
Merge pull request #78 from benthecarman/json-cli
Make cli output json
2 parents a8e25f4 + e65a0fb commit 0eb5f9d

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
@@ -200,16 +203,22 @@ async fn main() {
200203

201204
match cli.command {
202205
Commands::GetNodeInfo => {
203-
handle_response_result(client.get_node_info(GetNodeInfoRequest {}).await);
206+
handle_response_result::<_, GetNodeInfoResponse>(
207+
client.get_node_info(GetNodeInfoRequest {}).await,
208+
);
204209
},
205210
Commands::GetBalances => {
206-
handle_response_result(client.get_balances(GetBalancesRequest {}).await);
211+
handle_response_result::<_, GetBalancesResponse>(
212+
client.get_balances(GetBalancesRequest {}).await,
213+
);
207214
},
208215
Commands::OnchainReceive => {
209-
handle_response_result(client.onchain_receive(OnchainReceiveRequest {}).await);
216+
handle_response_result::<_, OnchainReceiveResponse>(
217+
client.onchain_receive(OnchainReceiveRequest {}).await,
218+
);
210219
},
211220
Commands::OnchainSend { address, amount_sats, send_all, fee_rate_sat_per_vb } => {
212-
handle_response_result(
221+
handle_response_result::<_, OnchainSendResponse>(
213222
client
214223
.onchain_send(OnchainSendRequest {
215224
address,
@@ -241,7 +250,9 @@ async fn main() {
241250
let request =
242251
Bolt11ReceiveRequest { description: invoice_description, expiry_secs, amount_msat };
243252

244-
handle_response_result(client.bolt11_receive(request).await);
253+
handle_response_result::<_, Bolt11ReceiveResponse>(
254+
client.bolt11_receive(request).await,
255+
);
245256
},
246257
Commands::Bolt11Send {
247258
invoice,
@@ -259,7 +270,7 @@ async fn main() {
259270
max_channel_saturation_power_of_half: max_channel_saturation_power_of_half
260271
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
261272
};
262-
handle_response_result(
273+
handle_response_result::<_, Bolt11SendResponse>(
263274
client
264275
.bolt11_send(Bolt11SendRequest {
265276
invoice,
@@ -270,7 +281,7 @@ async fn main() {
270281
);
271282
},
272283
Commands::Bolt12Receive { description, amount_msat, expiry_secs, quantity } => {
273-
handle_response_result(
284+
handle_response_result::<_, Bolt12ReceiveResponse>(
274285
client
275286
.bolt12_receive(Bolt12ReceiveRequest {
276287
description,
@@ -300,7 +311,7 @@ async fn main() {
300311
.unwrap_or(DEFAULT_MAX_CHANNEL_SATURATION_POWER_OF_HALF),
301312
};
302313

303-
handle_response_result(
314+
handle_response_result::<_, Bolt12SendResponse>(
304315
client
305316
.bolt12_send(Bolt12SendRequest {
306317
offer,
@@ -313,7 +324,7 @@ async fn main() {
313324
);
314325
},
315326
Commands::CloseChannel { user_channel_id, counterparty_node_id } => {
316-
handle_response_result(
327+
handle_response_result::<_, CloseChannelResponse>(
317328
client
318329
.close_channel(CloseChannelRequest { user_channel_id, counterparty_node_id })
319330
.await,
@@ -324,7 +335,7 @@ async fn main() {
324335
counterparty_node_id,
325336
force_close_reason,
326337
} => {
327-
handle_response_result(
338+
handle_response_result::<_, ForceCloseChannelResponse>(
328339
client
329340
.force_close_channel(ForceCloseChannelRequest {
330341
user_channel_id,
@@ -350,7 +361,7 @@ async fn main() {
350361
cltv_expiry_delta,
351362
);
352363

353-
handle_response_result(
364+
handle_response_result::<_, OpenChannelResponse>(
354365
client
355366
.open_channel(OpenChannelRequest {
356367
node_pubkey,
@@ -364,7 +375,7 @@ async fn main() {
364375
);
365376
},
366377
Commands::SpliceIn { user_channel_id, counterparty_node_id, splice_amount_sats } => {
367-
handle_response_result(
378+
handle_response_result::<_, SpliceInResponse>(
368379
client
369380
.splice_in(SpliceInRequest {
370381
user_channel_id,
@@ -380,7 +391,7 @@ async fn main() {
380391
address,
381392
splice_amount_sats,
382393
} => {
383-
handle_response_result(
394+
handle_response_result::<_, SpliceOutResponse>(
384395
client
385396
.splice_out(SpliceOutRequest {
386397
user_channel_id,
@@ -392,10 +403,17 @@ async fn main() {
392403
);
393404
},
394405
Commands::ListChannels => {
395-
handle_response_result(client.list_channels(ListChannelsRequest {}).await);
406+
handle_response_result::<_, ListChannelsResponse>(
407+
client.list_channels(ListChannelsRequest {}).await,
408+
);
396409
},
397410
Commands::ListPayments { number_of_payments } => {
398-
handle_response_result(list_n_payments(client, number_of_payments).await);
411+
handle_response_result::<_, ListPaymentsResponse>(
412+
list_n_payments(client, number_of_payments)
413+
.await
414+
// todo: handle pagination properly
415+
.map(|payments| ListPaymentsResponse { payments, next_page_token: None }),
416+
);
399417
},
400418
Commands::UpdateChannelConfig {
401419
user_channel_id,
@@ -413,7 +431,7 @@ async fn main() {
413431
max_dust_htlc_exposure: None,
414432
};
415433

416-
handle_response_result(
434+
handle_response_result::<_, UpdateChannelConfigResponse>(
417435
client
418436
.update_channel_config(UpdateChannelConfigRequest {
419437
user_channel_id,
@@ -468,10 +486,21 @@ async fn list_n_payments(
468486
Ok(payments)
469487
}
470488

471-
fn handle_response_result<Rs: Debug>(response: Result<Rs, LdkServerError>) {
489+
fn handle_response_result<Rs, Js>(response: Result<Rs, LdkServerError>)
490+
where
491+
Rs: Into<Js>,
492+
Js: Serialize + std::fmt::Debug,
493+
{
472494
match response {
473495
Ok(response) => {
474-
println!("Success: {:?}", response);
496+
let json_response: Js = response.into();
497+
match serde_json::to_string_pretty(&json_response) {
498+
Ok(json) => println!("{json}"),
499+
Err(e) => {
500+
eprintln!("Error serializing response ({json_response:?}) to JSON: {e}");
501+
std::process::exit(1);
502+
},
503+
}
475504
},
476505
Err(e) => {
477506
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)