soroban_cli/commands/contract/info/
env_meta.rs1use std::fmt::Debug;
2use std::fmt::Write;
3
4use clap::{command, Parser};
5
6use soroban_spec_tools::contract;
7use soroban_spec_tools::contract::Spec;
8
9use crate::{
10 commands::{
11 contract::info::{
12 env_meta::Error::{NoEnvMetaPresent, NoSACEnvMeta},
13 shared::{self, fetch, Fetched, MetasInfoOutput},
14 },
15 global,
16 },
17 print::Print,
18 xdr::{ScEnvMetaEntry, ScEnvMetaEntryInterfaceVersion},
19};
20
21#[derive(Parser, Debug, Clone)]
22pub struct Cmd {
23 #[command(flatten)]
24 pub common: shared::Args,
25 #[arg(long, default_value = "text")]
27 pub output: MetasInfoOutput,
28}
29
30#[derive(thiserror::Error, Debug)]
31pub enum Error {
32 #[error(transparent)]
33 Wasm(#[from] shared::Error),
34 #[error(transparent)]
35 Spec(#[from] contract::Error),
36 #[error("Stellar asset contract doesn't contain meta information")]
37 NoSACEnvMeta(),
38 #[error("no meta present in provided WASM file")]
39 NoEnvMetaPresent(),
40 #[error(transparent)]
41 Json(#[from] serde_json::Error),
42}
43
44impl Cmd {
45 pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
46 let print = Print::new(global_args.quiet);
47 let Fetched { contract, .. } = fetch(&self.common, &print).await?;
48
49 let spec = match contract {
50 shared::Contract::Wasm { wasm_bytes } => Spec::new(&wasm_bytes)?,
51 shared::Contract::StellarAssetContract => return Err(NoSACEnvMeta()),
52 };
53
54 let Some(env_meta_base64) = spec.env_meta_base64 else {
55 return Err(NoEnvMetaPresent());
56 };
57
58 let res = match self.output {
59 MetasInfoOutput::XdrBase64 => env_meta_base64,
60 MetasInfoOutput::Json => serde_json::to_string(&spec.env_meta)?,
61 MetasInfoOutput::JsonFormatted => serde_json::to_string_pretty(&spec.env_meta)?,
62 MetasInfoOutput::Text => {
63 let mut meta_str = "Contract env-meta:\n".to_string();
64 for env_meta_entry in &spec.env_meta {
65 match env_meta_entry {
66 ScEnvMetaEntry::ScEnvMetaKindInterfaceVersion(
67 ScEnvMetaEntryInterfaceVersion {
68 protocol,
69 pre_release,
70 },
71 ) => {
72 let _ = writeln!(meta_str, " • Protocol: v{protocol}");
73 if pre_release != &0 {
74 let _ = writeln!(meta_str, " • Pre-release: v{pre_release}");
75 }
76 }
77 }
78 }
79 meta_str
80 }
81 };
82
83 println!("{res}");
84
85 Ok(())
86 }
87}