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