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