use leo_ast::NetworkName;
use leo_package::{fetch_from_network, verify_valid_program};
use super::*;
mod block;
pub use block::LeoBlock;
mod program;
pub use program::LeoProgram;
mod state_root;
pub use state_root::StateRoot;
mod committee;
pub use committee::LeoCommittee;
mod mempool;
pub use mempool::LeoMempool;
mod peers;
pub use peers::LeoPeers;
mod transaction;
pub use transaction::LeoTransaction;
mod utils;
use utils::*;
#[derive(Parser, Debug)]
pub struct LeoQuery {
#[clap(flatten)]
pub(crate) env_override: EnvOptions,
#[clap(subcommand)]
pub command: QueryCommands,
}
impl Command for LeoQuery {
type Input = ();
type Output = String;
fn log_span(&self) -> Span {
tracing::span!(tracing::Level::INFO, "Leo")
}
fn prelude(&self, _context: Context) -> Result<Self::Input> {
Ok(())
}
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
let network: NetworkName = get_network(&self.env_override.network)?;
let endpoint = get_endpoint(&self.env_override.endpoint)?;
handle_query(self, context, network, &endpoint)
}
}
fn handle_query(
query: LeoQuery,
context: Context,
network: NetworkName,
endpoint: &str,
) -> Result<<LeoQuery as Command>::Output> {
let recursive = context.recursive;
let network_retries = query.env_override.network_retries;
let (program, output) = match query.command {
QueryCommands::Block { command } => (None, command.apply(context, ())?),
QueryCommands::Transaction { command } => (None, command.apply(context, ())?),
QueryCommands::Program { command } => {
let program =
if command.mappings || command.mapping_value.is_some() { None } else { Some(command.name.clone()) };
(program, command.apply(context, ())?)
}
QueryCommands::Stateroot { command } => (None, command.apply(context, ())?),
QueryCommands::Committee { command } => (None, command.apply(context, ())?),
QueryCommands::Mempool { command } => {
if endpoint == "https://api.explorer.provable.com/v1" {
tracing::warn!(
"⚠️ `leo query mempool` is only valid when using a custom endpoint. Specify one using `--endpoint`."
);
}
(None, command.apply(context, ())?)
}
QueryCommands::Peers { command } => {
if endpoint == "https://api.explorer.provable.com/v1" {
tracing::warn!(
"⚠️ `leo query peers` is only valid when using a custom endpoint. Specify one using `--endpoint`."
);
}
(None, command.apply(context, ())?)
}
};
let url = format!("{endpoint}/{network}/{output}");
let result = fetch_from_network(&url, network_retries)?;
if !recursive {
tracing::info!("✅ Successfully retrieved data from '{url}'.\n");
println!("{result}\n");
}
if let Some(name) = program {
verify_valid_program(&name, &result)?;
}
Ok(result)
}
#[derive(Parser, Debug)]
pub enum QueryCommands {
#[clap(about = "Query block information")]
Block {
#[clap(flatten)]
command: LeoBlock,
},
#[clap(about = "Query transaction information")]
Transaction {
#[clap(flatten)]
command: LeoTransaction,
},
#[clap(about = "Query program source code and live mapping values")]
Program {
#[clap(flatten)]
command: LeoProgram,
},
#[clap(about = "Query the latest stateroot")]
Stateroot {
#[clap(flatten)]
command: StateRoot,
},
#[clap(about = "Query the current committee")]
Committee {
#[clap(flatten)]
command: LeoCommittee,
},
#[clap(about = "Query transactions and transmissions from the memory pool")]
Mempool {
#[clap(flatten)]
command: LeoMempool,
},
#[clap(about = "Query peer information")]
Peers {
#[clap(flatten)]
command: LeoPeers,
},
}