leo_lang/cli/commands/query/
mod.rs1use leo_ast::NetworkName;
18use leo_errors::UtilError;
19use leo_package::{fetch_from_network, verify_valid_program};
20
21use super::*;
22
23mod block;
24pub use block::LeoBlock;
25
26mod program;
27pub use program::LeoProgram;
28
29mod state_root;
30pub use state_root::StateRoot;
31
32mod committee;
33pub use committee::LeoCommittee;
34
35mod mempool;
36pub use mempool::LeoMempool;
37
38mod peers;
39pub use peers::LeoPeers;
40
41mod transaction;
42pub use transaction::LeoTransaction;
43
44mod utils;
45use utils::*;
46
47#[derive(Parser, Debug)]
49pub struct LeoQuery {
50 #[clap(flatten)]
51 pub(crate) env_override: EnvOptions,
52 #[clap(subcommand)]
53 pub command: QueryCommands,
54}
55
56impl Command for LeoQuery {
57 type Input = ();
58 type Output = String;
59
60 fn log_span(&self) -> Span {
61 tracing::span!(tracing::Level::INFO, "Leo")
62 }
63
64 fn prelude(&self, _context: Context) -> Result<Self::Input> {
65 Ok(())
66 }
67
68 fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
69 let network: NetworkName = get_network(&self.env_override.network)?;
71 let endpoint = get_endpoint(&self.env_override.endpoint)?;
72 handle_query(self, context, network, &endpoint)
73 }
74}
75
76fn handle_query(
78 query: LeoQuery,
79 context: Context,
80 network: NetworkName,
81 endpoint: &str,
82) -> Result<<LeoQuery as Command>::Output> {
83 let recursive = context.recursive;
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)?;
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}