add shadow-rs for build metadata git commit hash, build time, branch etc, in version
159 lines
6.0 KiB
Rust
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:?}"),
|
|
}
|
|
}
|