detee-cli/src/bin/super-detee-cli.rs
Noor bf7d8707f4
detailed clap version
add shadow-rs for build metadata
git commit hash, build time, branch etc, in version
2025-04-21 17:50:25 +03:00

159 lines
6.0 KiB
Rust

use clap::{Arg, ArgMatches, Command};
use clap_complete::{generate, Shell};
use detee_cli::config::Config;
use detee_cli::*;
use std::io;
use utils::block_on;
const ABOUT: &str = r#"The DeTEE Admin CLI got created for the testnet.
It allows you to:
- airdrop tokens to other accounts
- list all accounts
- list all contracts
The admin pubkeys are hardcoded in the brain."#;
shadow_rs::shadow!(build);
fn main() {
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
let log_level = match std::env::var("LOG_LEVEL") {
Ok(val) => match val.as_str() {
"DEBUG" => log::LevelFilter::Debug,
"INFO" => log::LevelFilter::Info,
_ => log::LevelFilter::Error,
},
_ => log::LevelFilter::Warn,
};
env_logger::builder().filter_level(log_level).format_timestamp(None).init();
let cmd = Command::new("super-detee-cli")
.version(build::CLAP_LONG_VERSION)
.author("https://detee.ltd")
.about(ABOUT)
.subcommand(
Command::new("completion").about("generates shell completion scripts").arg(
Arg::new("shell")
.help("The shell to generate the script for")
.value_parser(["bash", "zsh", "fish"])
.required(true),
),
)
.subcommand(Command::new("contract").about("list all vm contracts"))
.subcommand(
Command::new("airdrop")
.about("give an airdrop to a user")
.arg(Arg::new("wallet").help("pubkey of the wallet").long("wallet").required(true))
.arg(
Arg::new("amount")
.help("the amount of token you want to airdrop")
.long("amount")
.value_parser(clap::value_parser!(u64).range(0..1_000_000))
.required(true),
),
)
.subcommand(
Command::new("slash")
.about("forcefully slash a user")
.arg(
Arg::new("wallet")
.help("pubkey of the wallet you are slashing")
.long("wallet")
.required(true),
)
.arg(
Arg::new("amount")
.help("the amount of tokens you are slashing")
.long("amount")
.value_parser(clap::value_parser!(u64).range(0..1_000_000))
.required(true),
),
)
.subcommand(
Command::new("account")
.about("account and security data for this CLI")
.subcommand(Command::new("list").about("list all accounts that exist in the brain"))
.subcommand(
Command::new("show").about("show account data associated with this CLI"),
)
.subcommand(
Command::new("network")
.about("specify if you connect to testnet or staging")
.arg(
Arg::new("name")
.help("name of the network you are connecting to")
.required(true),
),
),
);
let matches = cmd.clone().get_matches();
match matches.subcommand() {
Some(("completion", subcom_args)) => handle_completion(subcom_args, cmd),
Some(("contract", subcom_args)) => handle_contracts(subcom_args),
Some(("airdrop", subcom_args)) => handle_airdrop(subcom_args),
Some(("slash", subcom_args)) => handle_slash(subcom_args),
Some(("account", subcom_args)) => handle_account(subcom_args),
_ => println!("No valid subcommand provided. Use --help for more information."),
}
}
fn handle_completion(matches: &ArgMatches, mut cmd: Command) {
if let Some(shell) = matches.get_one::<String>("shell") {
let shell: Shell = shell.parse().expect("Invalid shell type");
generate(shell, &mut cmd, "super-detee-cli", &mut io::stdout());
}
}
fn handle_account(matches: &ArgMatches) {
match matches.subcommand() {
Some(("show", _)) => cli_print(Ok(config::Config::get_account_data())),
Some(("list", _)) => match block_on(general::grpc::admin_list_accounts()) {
Ok(accounts) => {
for a in accounts {
println!("{} {} {}", a.pubkey, a.balance, a.tmp_locked);
}
}
Err(e) => println!("Could not get contracts due to error: {e:?}"),
},
Some(("network", path_subcommand)) => {
let name: String = path_subcommand.get_one::<String>("name").unwrap().clone();
Config::set_network(&name);
}
_ => cli_print(Ok(config::Config::get_account_data())),
}
}
fn handle_contracts(_matches: &ArgMatches) {
match block_on(general::grpc::admin_list_contracts()) {
Ok(contracts) => {
for c in contracts {
println!(
"{} {} {} {} {}",
c.admin_pubkey, c.created_at, c.hostname, c.nano_per_minute, c.locked_nano
)
}
}
Err(e) => println!("Could not get contracts due to error: {e:?}"),
}
}
fn handle_airdrop(matches: &ArgMatches) {
let wallet: String = matches.get_one::<String>("wallet").unwrap().clone();
let tokens = *matches.get_one::<u64>("amount").unwrap();
match block_on(general::grpc::admin_airdrop(wallet, tokens)) {
Ok(()) => println!("Success."),
Err(e) => println!("Could not give airdrop due to error: {e:?}"),
}
}
fn handle_slash(matches: &ArgMatches) {
let wallet: String = matches.get_one::<String>("wallet").unwrap().clone();
let tokens = *matches.get_one::<u64>("amount").unwrap();
match block_on(general::grpc::admin_slash(wallet, tokens)) {
Ok(()) => println!("Success."),
Err(e) => println!("Could not slash wallet due to error: {e:?}"),
}
}