Skip to main content

soroban_cli/commands/network/
info.rs

1use sha2::{Digest, Sha256};
2
3use crate::commands::global;
4use crate::config::network;
5use crate::utils::url::redact_url;
6use crate::{config, print, rpc};
7
8#[derive(thiserror::Error, Debug)]
9pub enum Error {
10    #[error(transparent)]
11    Config(#[from] config::Error),
12    #[error(transparent)]
13    Network(#[from] network::Error),
14    #[error(transparent)]
15    Serde(#[from] serde_json::Error),
16    #[error(transparent)]
17    Rpc(#[from] rpc::Error),
18}
19
20#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
21pub enum OutputFormat {
22    /// Text output of network info
23    #[default]
24    Text,
25    /// JSON result of the RPC request
26    Json,
27    /// Formatted (multiline) JSON output of the RPC request
28    JsonFormatted,
29}
30
31#[derive(Debug, clap::Parser, Clone)]
32#[group(skip)]
33pub struct Cmd {
34    #[command(flatten)]
35    pub config: config::ArgsLocatorAndNetwork,
36    /// Format of the output
37    #[arg(long, default_value = "text")]
38    pub output: OutputFormat,
39}
40
41#[derive(serde::Deserialize, serde::Serialize)]
42struct Info {
43    pub id: String,
44    pub version: String,
45    pub commit_hash: String,
46    pub build_timestamp: String,
47    pub captive_core_version: String,
48    pub protocol_version: u32,
49    pub passphrase: String,
50    pub friendbot_url: Option<String>,
51}
52
53impl Info {
54    fn print_text(&self, print: &print::Print) {
55        print.infoln(format!("Network Id: {}", self.id));
56        print.infoln(format!("Version: {}", self.version));
57        print.infoln(format!("Commit Hash: {}", self.commit_hash));
58        print.infoln(format!("Build Timestamp: {}", self.build_timestamp));
59        print.infoln(format!(
60            "Captive Core Version: {}",
61            self.captive_core_version
62        ));
63        print.infoln(format!("Protocol Version: {}", self.protocol_version));
64        print.infoln(format!("Passphrase: {}", self.passphrase));
65        if let Some(friendbot_url) = &self.friendbot_url {
66            print.infoln(format!("Friendbot Url: {friendbot_url}"));
67        }
68    }
69
70    fn print_json(&self) -> Result<(), serde_json::Error> {
71        let json = serde_json::to_string(&self)?;
72        println!("{json}");
73        Ok(())
74    }
75
76    fn print_json_formatted(&self) -> Result<(), serde_json::Error> {
77        let json = serde_json::to_string_pretty(&self)?;
78        println!("{json}");
79        Ok(())
80    }
81}
82
83impl Cmd {
84    pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
85        let print = print::Print::new(global_args.quiet);
86        let rpc_client = self.config.get_network()?.rpc_client()?;
87        let network_result = rpc_client.get_network().await?;
88        let version_result = rpc_client.get_version_info().await?;
89        let id = hex::encode(Sha256::digest(network_result.passphrase.as_bytes()));
90        let info = Info {
91            id,
92            version: version_result.version,
93            commit_hash: version_result.commmit_hash,
94            build_timestamp: version_result.build_timestamp,
95            captive_core_version: version_result.captive_core_version,
96            protocol_version: network_result.protocol_version,
97            friendbot_url: network_result.friendbot_url.map(|u| redact_url(&u)),
98            passphrase: network_result.passphrase,
99        };
100
101        match self.output {
102            OutputFormat::Text => info.print_text(&print),
103            OutputFormat::Json => info.print_json()?,
104            OutputFormat::JsonFormatted => info.print_json_formatted()?,
105        }
106
107        Ok(())
108    }
109}