leo_lang/cli/commands/query/
mod.rsuse super::*;
use snarkvm::prelude::{CanaryV0, MainnetV0, TestnetV0};
pub mod block;
pub use block::LeoBlock;
pub mod program;
pub use program::LeoProgram;
pub mod state_root;
pub use state_root::StateRoot;
pub mod committee;
pub use committee::LeoCommittee;
pub mod mempool;
pub use mempool::LeoMempool;
pub mod peers;
pub use peers::LeoPeers;
pub mod transaction;
pub use transaction::LeoTransaction;
mod utils;
use utils::*;
use leo_errors::UtilError;
use leo_retriever::{NetworkName, fetch_from_network, verify_valid_program};
#[derive(Parser, Debug)]
pub struct LeoQuery {
#[clap(short, long, global = true, help = "Endpoint to retrieve network state from. Defaults to entry in `.env`.")]
pub endpoint: Option<String>,
#[clap(short, long, global = true, help = "Network to use. Defaults to entry in `.env`.")]
pub(crate) network: Option<String>,
#[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::try_from(context.get_network(&self.network)?)?;
let endpoint = context.get_endpoint(&self.endpoint)?;
match network {
NetworkName::MainnetV0 => handle_query::<MainnetV0>(self, context, &network.to_string(), &endpoint),
NetworkName::TestnetV0 => handle_query::<TestnetV0>(self, context, &network.to_string(), &endpoint),
NetworkName::CanaryV0 => handle_query::<CanaryV0>(self, context, &network.to_string(), &endpoint),
}
}
}
fn handle_query<N: Network>(
query: LeoQuery,
context: Context,
network: &str,
endpoint: &str,
) -> Result<<LeoQuery as Command>::Output> {
let recursive = context.recursive;
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!("{}/{}/{output}", endpoint, network);
let result = fetch_from_network(&url)?;
if !recursive {
tracing::info!("✅ Successfully retrieved data from '{url}'.\n");
println!("{}\n", result);
}
if let Some(name) = program {
verify_valid_program::<N>(&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,
},
}