frequency_cli/
export_metadata_cmd.rs1use clap::Parser;
2use sc_cli::{CliConfiguration, Error, GenericNumber, SharedParams};
3use sc_client_api::HeaderBackend;
4use serde_json::{json, to_writer};
5use sp_api::{Metadata, ProvideRuntimeApi};
6use sp_core::Bytes;
7use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
8use std::{fmt::Debug, fs, io, path::PathBuf, str::FromStr, sync::Arc};
9
10#[derive(Debug, Clone, Parser)]
13pub struct ExportMetadataCmd {
14 #[clap(value_parser)]
16 pub output: Option<PathBuf>,
17
18 #[clap(long, value_name = "BLOCK")]
22 pub from: Option<GenericNumber>,
23
24 #[allow(missing_docs)]
25 #[clap(flatten)]
26 pub shared_params: SharedParams,
27
28 #[arg(long, conflicts_with = "base_path")]
36 pub tmp: bool,
37}
38
39#[allow(clippy::unwrap_used)]
40impl ExportMetadataCmd {
41 pub async fn run<B, C>(&self, client: Arc<C>) -> Result<(), Error>
43 where
44 B: BlockT,
45 C: ProvideRuntimeApi<B> + HeaderBackend<B>,
46 C::Api: Metadata<B> + 'static,
47 <<B::Header as HeaderT>::Number as FromStr>::Err: Debug,
48 {
49 let api = client.runtime_api();
50
51 let block_number = self.from.as_ref().and_then(|f| f.parse().ok()).unwrap_or(0u32);
52 let maybe_hash = client.hash(block_number.into())?;
53 let block_hash = maybe_hash.ok_or_else(|| Error::from("Block not found"))?;
54
55 let metadata: Bytes = api.metadata_at_version(block_hash, 15u32).unwrap().unwrap().into();
56 let result = json!({ "result": metadata });
57
58 let file: Box<dyn io::Write> = match &self.output {
59 Some(filename) => Box::new(fs::File::create(filename)?),
60 None => Box::new(io::stdout()),
61 };
62 to_writer(file, &result).map_err(|_| Error::from("Failed Encoding"))
63 }
64}
65
66impl CliConfiguration for ExportMetadataCmd {
67 fn shared_params(&self) -> &SharedParams {
68 &self.shared_params
69 }
70
71 fn base_path(&self) -> Result<Option<sc_service::BasePath>, sc_cli::Error> {
73 match &self.tmp {
74 true => Ok(Some(sc_service::BasePath::new_temp_dir()?)),
75 false => self.shared_params.base_path(),
76 }
77 }
78}