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