leo_lang/cli/commands/query/
mod.rs1use leo_ast::NetworkName;
18use leo_package::{fetch_from_network, verify_valid_program};
19
20use super::*;
21
22mod block;
23pub use block::LeoBlock;
24
25mod program;
26pub use program::LeoProgram;
27
28mod state_root;
29pub use state_root::StateRoot;
30
31mod committee;
32pub use committee::LeoCommittee;
33
34mod mempool;
35pub use mempool::LeoMempool;
36
37mod peers;
38pub use peers::LeoPeers;
39
40mod transaction;
41pub use transaction::LeoTransaction;
42
43mod utils;
44use utils::*;
45
46#[derive(Parser, Debug)]
48pub struct LeoQuery {
49 #[clap(flatten)]
50 pub(crate) env_override: EnvOptions,
51 #[clap(subcommand)]
52 pub command: QueryCommands,
53}
54
55impl Command for LeoQuery {
56 type Input = ();
57 type Output = String;
58
59 fn log_span(&self) -> Span {
60 tracing::span!(tracing::Level::INFO, "Leo")
61 }
62
63 fn prelude(&self, _context: Context) -> Result<Self::Input> {
64 Ok(())
65 }
66
67 fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
68 let network: NetworkName = get_network(&self.env_override.network)?;
70 let endpoint = get_endpoint(&self.env_override.endpoint)?;
71 handle_query(self, context, network, &endpoint)
72 }
73}
74
75fn handle_query(
77 query: LeoQuery,
78 context: Context,
79 network: NetworkName,
80 endpoint: &str,
81) -> Result<<LeoQuery as Command>::Output> {
82 let recursive = context.recursive;
83 let network_retries = query.env_override.network_retries;
84 let (program, output) = match query.command {
85 QueryCommands::Block { command } => (None, command.apply(context, ())?),
86 QueryCommands::Transaction { command } => (None, command.apply(context, ())?),
87 QueryCommands::Program { command } => {
88 let program =
90 if command.mappings || command.mapping_value.is_some() { None } else { Some(command.name.clone()) };
91 (program, command.apply(context, ())?)
92 }
93 QueryCommands::Stateroot { command } => (None, command.apply(context, ())?),
94 QueryCommands::Committee { command } => (None, command.apply(context, ())?),
95 QueryCommands::Mempool { command } => {
96 if endpoint == "https://api.explorer.provable.com/v1" {
97 tracing::warn!(
98 "⚠️ `leo query mempool` is only valid when using a custom endpoint. Specify one using `--endpoint`."
99 );
100 }
101 (None, command.apply(context, ())?)
102 }
103 QueryCommands::Peers { command } => {
104 if endpoint == "https://api.explorer.provable.com/v1" {
105 tracing::warn!(
106 "⚠️ `leo query peers` is only valid when using a custom endpoint. Specify one using `--endpoint`."
107 );
108 }
109 (None, command.apply(context, ())?)
110 }
111 };
112
113 let url = format!("{endpoint}/{network}/{output}");
115 let result = fetch_from_network(&url, network_retries)?;
116 if !recursive {
117 tracing::info!("✅ Successfully retrieved data from '{url}'.\n");
118 println!("{result}\n");
119 }
120
121 if let Some(name) = program {
123 verify_valid_program(&name, &result)?;
124 }
125
126 Ok(result)
127}
128
129#[derive(Parser, Debug)]
130pub enum QueryCommands {
131 #[clap(about = "Query block information")]
132 Block {
133 #[clap(flatten)]
134 command: LeoBlock,
135 },
136 #[clap(about = "Query transaction information")]
137 Transaction {
138 #[clap(flatten)]
139 command: LeoTransaction,
140 },
141 #[clap(about = "Query program source code and live mapping values")]
142 Program {
143 #[clap(flatten)]
144 command: LeoProgram,
145 },
146 #[clap(about = "Query the latest stateroot")]
147 Stateroot {
148 #[clap(flatten)]
149 command: StateRoot,
150 },
151 #[clap(about = "Query the current committee")]
152 Committee {
153 #[clap(flatten)]
154 command: LeoCommittee,
155 },
156 #[clap(about = "Query transactions and transmissions from the memory pool")]
157 Mempool {
158 #[clap(flatten)]
159 command: LeoMempool,
160 },
161 #[clap(about = "Query peer information")]
162 Peers {
163 #[clap(flatten)]
164 command: LeoPeers,
165 },
166}