Files
nym/tools/nym-cli/src/main.rs
T
Fran Arbanas 2f6617daac Feature/issue credentials (#3691)
* Move the functionality to issue credentials from the credential binary and connect it with nym-cli

* finished CLI part, trying to fit SDK part

* finished Rust SDK

* fix: cleanup

* linting

* linting

* linting

* remove one layer of coconut in nym-cli

* linting

* Fixes based on PR comments

* formatting

* fixes based on PR comments

* formatting

* fixing clippy errors

* fixed post-rebasing issues and converted the lib into shared dep for other binaries

* removed credentials client in favour of moving the functionality to nym-cli

* removed redundant 'issue_credential' example (it did the same thing as 'bandwdith')

* removed credentials client from build server

* made the coconut cli also accept nym-api configs

* fixed support for socks5 and NR

---------

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2023-08-25 17:13:52 +02:00

156 lines
5.4 KiB
Rust

// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use clap::{CommandFactory, Parser, Subcommand};
use log::{error, warn};
use nym_bin_common::logging::setup_logging;
use nym_cli_commands::context::{get_network_details, ClientArgs};
use nym_validator_client::nyxd::AccountId;
mod coconut;
mod completion;
mod validator;
#[derive(Debug, Parser)]
#[clap(name = "nym-cli")]
#[clap(about = "A client for interacting with Nym smart contracts and the Nyx blockchain", long_about = None)]
pub(crate) struct Cli {
#[clap(long, global = true)]
#[clap(
help = "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC."
)]
pub(crate) mnemonic: Option<bip39::Mnemonic>,
#[clap(short, long, global = true)]
#[clap(
help = "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file."
)]
pub(crate) config_env_file: Option<std::path::PathBuf>,
#[clap(long, global = true)]
#[clap(
help = "Overrides the nyxd URL provided either as an environment variable NYXD_VALIDATOR or in a config file"
)]
pub(crate) nyxd_url: Option<String>,
#[clap(long, global = true)]
#[clap(
help = "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file"
)]
pub(crate) nym_api_url: Option<String>,
#[clap(long, global = true)]
#[clap(
help = "Overrides the mixnet contract address provided either as an environment variable or in a config file"
)]
pub(crate) mixnet_contract_address: Option<AccountId>,
#[clap(long, global = true)]
#[clap(
help = "Overrides the vesting contract address provided either as an environment variable or in a config file"
)]
pub(crate) vesting_contract_address: Option<AccountId>,
#[clap(subcommand)]
command: Commands,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Subcommand)]
pub(crate) enum Commands {
/// Query and manage Nyx blockchain accounts
Account(nym_cli_commands::validator::account::Account),
/// Sign and verify messages
Signature(nym_cli_commands::validator::signature::Signature),
/// Coconut related stuff
Coconut(nym_cli_commands::coconut::Coconut),
/// Query chain blocks
Block(nym_cli_commands::validator::block::Block),
/// Manage and execute WASM smart contracts
Cosmwasm(nym_cli_commands::validator::cosmwasm::Cosmwasm),
/// Query for transactions
Tx(nym_cli_commands::validator::transactions::Transactions),
/// Create and query for a vesting schedule
VestingSchedule(nym_cli_commands::validator::vesting::VestingSchedule),
/// Manage your mixnet infrastructure, delegate stake or query the directory
Mixnet(nym_cli_commands::validator::mixnet::Mixnet),
/// Generates shell completion
GenerateFig,
}
async fn execute(cli: Cli) -> anyhow::Result<()> {
let args = ClientArgs {
nyxd_url: cli.nyxd_url,
nym_api_url: cli.nym_api_url,
mnemonic: cli.mnemonic,
mixnet_contract_address: cli.mixnet_contract_address,
vesting_contract_address: cli.vesting_contract_address,
config_env_file: cli.config_env_file,
};
let network_details = get_network_details(&args)?;
// use the --mnemonic option if set, then try fall back to the MNEMONIC env var
let mnemonic = args.mnemonic.clone().or_else(|| {
std::env::var("MNEMONIC")
.ok()
.and_then(|m| bip39::Mnemonic::parse(m).ok())
});
match cli.command {
Commands::Account(account) => {
validator::account::execute(args, account, &network_details, mnemonic).await?
}
Commands::Signature(signature) => {
validator::signature::execute(signature, &network_details, mnemonic).await?
}
Commands::Coconut(coconut) => coconut::execute(args, coconut, &network_details).await?,
Commands::Block(block) => validator::block::execute(block, &network_details).await?,
Commands::Cosmwasm(cosmwasm) => {
validator::cosmwasm::execute(args, cosmwasm, &network_details).await?
}
Commands::Tx(transactions) => {
validator::transactions::execute(transactions, &network_details).await?
}
Commands::VestingSchedule(vesting) => {
validator::vesting::execute(args, vesting, &network_details).await?
}
Commands::Mixnet(mixnet) => {
validator::mixnet::execute(args, mixnet, &network_details).await?
}
Commands::GenerateFig => {
let mut cmd = Cli::command();
completion::print_fig(&mut cmd);
}
}
Ok(())
}
async fn wait_for_interrupt() {
if let Err(e) = tokio::signal::ctrl_c().await {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
e
);
}
println!(
"Received SIGINT - the process will terminate now (threads are not yet nicely stopped, if you see stack traces that's alright)."
);
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
setup_logging();
let cli = Cli::parse();
tokio::select! {
_ = wait_for_interrupt() => {
warn!("Received interrupt - the specified command might have not completed!");
Ok(())
},
res = execute(cli) => res
}
}