From 7e7072258df79ccb07098d7d9c490b6ad3b9e075 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Mon, 5 Sep 2022 12:06:35 +0100 Subject: [PATCH] Add `nym-cli` tool (#1577) Co-authored-by: tommy --- CHANGELOG.md | 3 +- Cargo.lock | 153 +- Cargo.toml | 2 + Makefile | 3 + .../src/nymd/cosmwasm_client/types.rs | 10 +- .../validator-client/src/nymd/mod.rs | 44 +- .../validator-client/src/nymd/wallet/mod.rs | 13 +- common/commands/Cargo.toml | 32 + common/commands/README.md | 13 + common/commands/src/coconut/mod.rs | 4 + common/commands/src/context/errors.rs | 18 + common/commands/src/context/mod.rs | 138 + common/commands/src/lib.rs | 7 + common/commands/src/utils.rs | 44 + .../commands/src/validator/account/balance.rs | 72 + .../commands/src/validator/account/create.rs | 24 + common/commands/src/validator/account/mod.rs | 28 + .../commands/src/validator/account/pubkey.rs | 89 + common/commands/src/validator/account/send.rs | 66 + .../src/validator/block/block_time.rs | 23 + .../src/validator/block/current_height.rs | 19 + common/commands/src/validator/block/get.rs | 24 + common/commands/src/validator/block/mod.rs | 25 + .../validator/cosmwasm/execute_contract.rs | 60 + .../src/validator/cosmwasm/init_contract.rs | 78 + .../validator/cosmwasm/migrate_contract.rs | 51 + common/commands/src/validator/cosmwasm/mod.rs | 28 + .../src/validator/cosmwasm/upload_contract.rs | 37 + .../mixnet/delegators/delegate_to_mixnode.rs | 31 + .../src/validator/mixnet/delegators/mod.rs | 35 + .../delegators/query_for_delegations.rs | 129 + .../rewards/claim_delegator_reward.rs | 23 + .../mixnet/delegators/rewards/mod.rs | 22 + .../rewards/vesting_claim_delegator_reward.rs | 23 + .../delegators/undelegate_from_mixnode.rs | 23 + .../delegators/vesting_delegate_to_mixnode.rs | 34 + .../vesting_undelegate_from_mixnode.rs | 26 + common/commands/src/validator/mixnet/mod.rs | 25 + .../mixnet/operators/gateway/bond_gateway.rs | 77 + .../validator/mixnet/operators/gateway/mod.rs | 28 + .../operators/gateway/unbond_gateway.rs | 20 + .../operators/gateway/vesting_bond_gateway.rs | 76 + .../gateway/vesting_unbond_gateway.rs | 20 + .../mixnet/operators/mixnode/bond_mixnode.rs | 85 + .../mixnode/keys/decode_mixnode_key.rs | 17 + .../mixnet/operators/mixnode/keys/mod.rs | 19 + .../validator/mixnet/operators/mixnode/mod.rs | 37 + .../mixnode/rewards/claim_operator_reward.rs | 20 + .../mixnet/operators/mixnode/rewards/mod.rs | 22 + .../rewards/vesting_claim_operator_reward.rs | 23 + .../mixnet/operators/mixnode/settings/mod.rs | 22 + .../mixnode/settings/update_profit_percent.rs | 24 + .../settings/vesting_update_profit_percent.rs | 28 + .../operators/mixnode/unbond_mixnode.rs | 21 + .../operators/mixnode/vesting_bond_mixnode.rs | 86 + .../mixnode/vesting_unbond_mixnode.rs | 24 + .../src/validator/mixnet/operators/mod.rs | 22 + .../src/validator/mixnet/query/mod.rs | 22 + .../mixnet/query/query_all_gateways.rs | 52 + .../mixnet/query/query_all_mixnodes.rs | 60 + common/commands/src/validator/mod.rs | 10 + .../src/validator/signature/errors.rs | 13 + .../src/validator/signature/helpers.rs | 90 + .../commands/src/validator/signature/mod.rs | 24 + .../commands/src/validator/signature/sign.rs | 68 + .../src/validator/signature/verify.rs | 89 + .../validator/transactions/get_transaction.rs | 28 + .../src/validator/transactions/mod.rs | 22 + .../transactions/query_transactions.rs | 30 + .../commands/src/validator/vesting/balance.rs | 55 + .../vesting/create_vesting_schedule.rs | 83 + common/commands/src/validator/vesting/mod.rs | 28 + .../vesting/query_vesting_schedule.rs | 149 + .../src/validator/vesting/withdraw_vested.rs | 112 + common/network-defaults/envs/mainnet.env | 20 + common/network-defaults/envs/qa.env | 20 + examples/README.md | 9 + .../cli/commands/verify-signature}/Cargo.lock | 776 +-- .../cli/commands/verify-signature/Cargo.toml | 9 + .../cli/commands/verify-signature/README.md | 38 + .../cli/commands/verify-signature/src/main.rs | 43 + nym-connect/Cargo.lock | 1 + tools/nym-cli/Cargo.toml | 24 + tools/nym-cli/Makefile | 3 + tools/nym-cli/README.md | 139 + tools/nym-cli/src/completion.rs | 10 + tools/nym-cli/src/main.rs | 168 + tools/nym-cli/src/validator/account.rs | 79 + tools/nym-cli/src/validator/block.rs | 35 + tools/nym-cli/src/validator/cosmwasm.rs | 45 + .../src/validator/mixnet/delegators/mod.rs | 32 + .../mixnet/delegators/rewards/mod.rs | 19 + tools/nym-cli/src/validator/mixnet/mod.rs | 25 + .../mixnet/operators/gateways/mod.rs | 22 + .../mixnet/operators/mixnodes/keys/mod.rs | 13 + .../mixnet/operators/mixnodes/mod.rs | 35 + .../mixnet/operators/mixnodes/rewards/mod.rs | 19 + .../mixnet/operators/mixnodes/settings/mod.rs | 19 + .../src/validator/mixnet/operators/mod.rs | 24 + .../nym-cli/src/validator/mixnet/query/mod.rs | 28 + tools/nym-cli/src/validator/mod.rs | 10 + tools/nym-cli/src/validator/signature.rs | 30 + tools/nym-cli/src/validator/transactions.rs | 29 + tools/nym-cli/src/validator/vesting.rs | 49 + tools/nym-cli/user-docs/fig-spec.ts | 5048 +++++++++++++++++ tools/nym-cli/user-docs/tsconfig.json | 5 + 106 files changed, 9512 insertions(+), 399 deletions(-) create mode 100644 common/commands/Cargo.toml create mode 100644 common/commands/README.md create mode 100644 common/commands/src/coconut/mod.rs create mode 100644 common/commands/src/context/errors.rs create mode 100644 common/commands/src/context/mod.rs create mode 100644 common/commands/src/lib.rs create mode 100644 common/commands/src/utils.rs create mode 100644 common/commands/src/validator/account/balance.rs create mode 100644 common/commands/src/validator/account/create.rs create mode 100644 common/commands/src/validator/account/mod.rs create mode 100644 common/commands/src/validator/account/pubkey.rs create mode 100644 common/commands/src/validator/account/send.rs create mode 100644 common/commands/src/validator/block/block_time.rs create mode 100644 common/commands/src/validator/block/current_height.rs create mode 100644 common/commands/src/validator/block/get.rs create mode 100644 common/commands/src/validator/block/mod.rs create mode 100644 common/commands/src/validator/cosmwasm/execute_contract.rs create mode 100644 common/commands/src/validator/cosmwasm/init_contract.rs create mode 100644 common/commands/src/validator/cosmwasm/migrate_contract.rs create mode 100644 common/commands/src/validator/cosmwasm/mod.rs create mode 100644 common/commands/src/validator/cosmwasm/upload_contract.rs create mode 100644 common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/delegators/mod.rs create mode 100644 common/commands/src/validator/mixnet/delegators/query_for_delegations.rs create mode 100644 common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs create mode 100644 common/commands/src/validator/mixnet/delegators/rewards/mod.rs create mode 100644 common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs create mode 100644 common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs create mode 100644 common/commands/src/validator/mixnet/operators/gateway/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs create mode 100644 common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs create mode 100644 common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/keys/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/rewards/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/settings/mod.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/settings/update_profit_percent.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_profit_percent.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs create mode 100644 common/commands/src/validator/mixnet/operators/mod.rs create mode 100644 common/commands/src/validator/mixnet/query/mod.rs create mode 100644 common/commands/src/validator/mixnet/query/query_all_gateways.rs create mode 100644 common/commands/src/validator/mixnet/query/query_all_mixnodes.rs create mode 100644 common/commands/src/validator/mod.rs create mode 100644 common/commands/src/validator/signature/errors.rs create mode 100644 common/commands/src/validator/signature/helpers.rs create mode 100644 common/commands/src/validator/signature/mod.rs create mode 100644 common/commands/src/validator/signature/sign.rs create mode 100644 common/commands/src/validator/signature/verify.rs create mode 100644 common/commands/src/validator/transactions/get_transaction.rs create mode 100644 common/commands/src/validator/transactions/mod.rs create mode 100644 common/commands/src/validator/transactions/query_transactions.rs create mode 100644 common/commands/src/validator/vesting/balance.rs create mode 100644 common/commands/src/validator/vesting/create_vesting_schedule.rs create mode 100644 common/commands/src/validator/vesting/mod.rs create mode 100644 common/commands/src/validator/vesting/query_vesting_schedule.rs create mode 100644 common/commands/src/validator/vesting/withdraw_vested.rs create mode 100644 common/network-defaults/envs/mainnet.env create mode 100644 common/network-defaults/envs/qa.env create mode 100644 examples/README.md rename {tools => examples/cli/commands/verify-signature}/Cargo.lock (82%) create mode 100644 examples/cli/commands/verify-signature/Cargo.toml create mode 100644 examples/cli/commands/verify-signature/README.md create mode 100644 examples/cli/commands/verify-signature/src/main.rs create mode 100644 tools/nym-cli/Cargo.toml create mode 100644 tools/nym-cli/Makefile create mode 100644 tools/nym-cli/README.md create mode 100644 tools/nym-cli/src/completion.rs create mode 100644 tools/nym-cli/src/main.rs create mode 100644 tools/nym-cli/src/validator/account.rs create mode 100644 tools/nym-cli/src/validator/block.rs create mode 100644 tools/nym-cli/src/validator/cosmwasm.rs create mode 100644 tools/nym-cli/src/validator/mixnet/delegators/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/delegators/rewards/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/gateways/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/mixnodes/keys/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/mixnodes/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/mixnodes/rewards/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/mixnodes/settings/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/operators/mod.rs create mode 100644 tools/nym-cli/src/validator/mixnet/query/mod.rs create mode 100644 tools/nym-cli/src/validator/mod.rs create mode 100644 tools/nym-cli/src/validator/signature.rs create mode 100644 tools/nym-cli/src/validator/transactions.rs create mode 100644 tools/nym-cli/src/validator/vesting.rs create mode 100644 tools/nym-cli/user-docs/fig-spec.ts create mode 100644 tools/nym-cli/user-docs/tsconfig.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 709ae4b36d..0b9a93a151 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,16 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ### Added +- nym-cli: added CLI tool for interacting with the Nyx blockchain and Nym mixnet smart contracts ([#1577]) - validator-client: added `query_contract_smart` and `query_contract_raw` on `NymdClient` ([#1558]) - ### Changed - validator-client: made `fee` argument optional for `execute` and `execute_multiple` ([#1541]) [#1541]: https://github.com/nymtech/nym/pull/1541 [#1558]: https://github.com/nymtech/nym/pull/1558 +[#1577]: https://github.com/nymtech/nym/pull/1577 ## [nym-binaries-1.0.2](https://github.com/nymtech/nym/tree/nym-binaries-1.0.2) diff --git a/Cargo.lock b/Cargo.lock index 36796c5ed8..363c907a18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,6 +583,25 @@ dependencies = [ "textwrap 0.15.0", ] +[[package]] +name = "clap_complete" +version = "3.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4179da71abd56c26b54dd0c248cc081c1f43b0a1a7e8448e28e57a29baa993d" +dependencies = [ + "clap 3.2.8", +] + +[[package]] +name = "clap_complete_fig" +version = "3.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9" +dependencies = [ + "clap 3.2.8", + "clap_complete", +] + [[package]] name = "clap_derive" version = "3.2.7" @@ -671,6 +690,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "comfy-table" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121d8a5b0346092c18a4b2fd6f620d7a06f0eb7ac0a45860939a0884bc579c56" +dependencies = [ + "crossterm", + "strum 0.24.1", + "strum_macros 0.24.3", + "unicode-width", +] + [[package]] name = "config" version = "0.1.0" @@ -1027,6 +1058,31 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crossterm" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.0", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -3064,6 +3120,57 @@ dependencies = [ "libc", ] +[[package]] +name = "nym-cli" +version = "1.0.0" +dependencies = [ + "anyhow", + "base64", + "bip39", + "bs58", + "clap 3.2.8", + "clap_complete", + "clap_complete_fig", + "dotenv", + "log", + "network-defaults", + "nym-cli-commands", + "pretty_env_logger", + "serde", + "serde_json", + "tokio", + "validator-client", +] + +[[package]] +name = "nym-cli-commands" +version = "1.0.0" +dependencies = [ + "base64", + "bip39", + "bs58", + "cfg-if 1.0.0", + "clap 3.2.8", + "comfy-table", + "cosmrs", + "cosmwasm-std", + "handlebars", + "humantime-serde", + "k256", + "log", + "mixnet-contract-common", + "network-defaults", + "rand 0.6.5", + "serde", + "serde_json", + "thiserror", + "time 0.3.9", + "toml", + "url", + "validator-client", + "vesting-contract-common", +] + [[package]] name = "nym-client" version = "1.0.2" @@ -3281,7 +3388,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "strum", + "strum 0.23.0", "tempfile", "thiserror", "ts-rs", @@ -3362,7 +3469,7 @@ dependencies = [ "nym-types", "serde", "serde_json", - "strum", + "strum 0.23.0", "ts-rs", "validator-client", "vesting-contract", @@ -5118,6 +5225,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -5439,9 +5567,15 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" dependencies = [ - "strum_macros", + "strum_macros 0.23.1", ] +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + [[package]] name = "strum_macros" version = "0.23.1" @@ -5455,6 +5589,19 @@ dependencies = [ "syn", ] +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.0", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "subtle" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 6e3dc19265..a294283126 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "common/client-libs/mixnet-client", "common/client-libs/validator-client", "common/coconut-interface", + "common/commands", "common/config", "common/cosmwasm-smart-contracts/coconut-bandwidth-contract", "common/cosmwasm-smart-contracts/contracts-common", @@ -69,6 +70,7 @@ members = [ "service-providers/network-statistics", "validator-api", "validator-api/validator-api-requests", + "tools/nym-cli", "tools/ts-rs-cli" ] diff --git a/Makefile b/Makefile index fb1393d11a..97f2d02abd 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,9 @@ build-wallet: build-connect: cargo build --manifest-path nym-connect/Cargo.toml --workspace +build-nym-cli: + cargo build --release --manifest-path tools/nym-cli/Cargo.toml + fmt-main: cargo fmt --all diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs index 3c28d8991f..b680a1a8f4 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs @@ -489,7 +489,7 @@ impl TryFrom for ContractCodeHistoryEntry { } } -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize)] pub struct GasInfo { /// GasWanted is the maximum units of work we allow this tx to perform. pub gas_wanted: Gas, @@ -645,7 +645,7 @@ impl InstantiateOptions { } } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct InstantiateResult { /// The address of the newly instantiated contract pub contract_address: AccountId, @@ -658,7 +658,7 @@ pub struct InstantiateResult { pub gas_info: GasInfo, } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct ChangeAdminResult { pub logs: Vec, @@ -668,7 +668,7 @@ pub struct ChangeAdminResult { pub gas_info: GasInfo, } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct MigrateResult { pub logs: Vec, @@ -678,7 +678,7 @@ pub struct MigrateResult { pub gas_info: GasInfo, } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct ExecuteResult { pub logs: Vec, diff --git a/common/client-libs/validator-client/src/nymd/mod.rs b/common/client-libs/validator-client/src/nymd/mod.rs index 1daf333456..d6c1d40c7f 100644 --- a/common/client-libs/validator-client/src/nymd/mod.rs +++ b/common/client-libs/validator-client/src/nymd/mod.rs @@ -10,6 +10,8 @@ use crate::nymd::error::NymdError; use crate::nymd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; use crate::nymd::wallet::DirectSecp256k1HdWallet; use cosmrs::cosmwasm; +use cosmrs::rpc::endpoint::block::Response as BlockResponse; +use cosmrs::rpc::query::Query; use cosmrs::rpc::Error as TendermintRpcError; use cosmrs::rpc::HttpClientUrl; use cosmrs::tx::Msg; @@ -212,6 +214,10 @@ impl NymdClient { &self.config } + pub fn current_chain_details(&self) -> &ChainDetails { + &self.config.chain_details + } + pub fn set_mixnet_contract_address(&mut self, address: AccountId) { self.config.mixnet_contract_address = Some(address); } @@ -355,11 +361,26 @@ impl NymdClient { address: &AccountId, ) -> Result, NymdError> where - C: SigningCosmWasmClient + Sync, + C: CosmWasmClient + Sync, { self.client.get_account(address).await } + pub async fn get_account_public_key( + &self, + address: &AccountId, + ) -> Result, NymdError> + where + C: CosmWasmClient + Sync, + { + if let Some(account) = self.client.get_account(address).await? { + let base_account = account.try_get_base_account()?; + return Ok(base_account.pubkey); + } + + Ok(None) + } + pub async fn get_current_block_timestamp(&self) -> Result where C: CosmWasmClient + Sync, @@ -377,6 +398,13 @@ impl NymdClient { Ok(self.client.get_block(height).await?.block.header.time) } + pub async fn get_block(&self, height: Option) -> Result + where + C: CosmWasmClient + Sync, + { + self.client.get_block(height).await + } + pub async fn get_current_block_height(&self) -> Result where C: CosmWasmClient + Sync, @@ -421,6 +449,13 @@ impl NymdClient { self.client.get_balance(address, denom).await } + pub async fn get_all_balances(&self, address: &AccountId) -> Result, NymdError> + where + C: CosmWasmClient + Sync, + { + self.client.get_all_balances(address).await + } + pub async fn get_tx(&self, id: tx::Hash) -> Result where C: CosmWasmClient + Sync, @@ -428,6 +463,13 @@ impl NymdClient { self.client.get_tx(id).await } + pub async fn search_tx(&self, query: Query) -> Result, NymdError> + where + C: CosmWasmClient + Sync, + { + self.client.search_tx(query).await + } + pub async fn get_total_supply(&self) -> Result, NymdError> where C: CosmWasmClient + Sync, diff --git a/common/client-libs/validator-client/src/nymd/wallet/mod.rs b/common/client-libs/validator-client/src/nymd/wallet/mod.rs index 247ffcd743..e071d48853 100644 --- a/common/client-libs/validator-client/src/nymd/wallet/mod.rs +++ b/common/client-libs/validator-client/src/nymd/wallet/mod.rs @@ -4,7 +4,7 @@ use crate::nymd::error::NymdError; use config::defaults; use cosmrs::bip32::{DerivationPath, XPrv}; -use cosmrs::crypto::secp256k1::SigningKey; +use cosmrs::crypto::secp256k1::{Signature, SigningKey}; use cosmrs::crypto::PublicKey; use cosmrs::tx::SignDoc; use cosmrs::{tx, AccountId}; @@ -105,6 +105,17 @@ impl DirectSecp256k1HdWallet { self.secret.to_string() } + pub fn sign_raw_with_account( + &self, + signer: &AccountData, + message: &[u8], + ) -> Result { + signer + .private_key + .sign(message) + .map_err(|_| NymdError::SigningFailure) + } + pub fn sign_direct_with_account( &self, signer: &AccountData, diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml new file mode 100644 index 0000000000..35b38512fa --- /dev/null +++ b/common/commands/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "nym-cli-commands" +version = "1.0.0" +authors = ["Nym Technologies SA"] +edition = "2021" + +[dependencies] +base64 = "0.13.0" +bip39 = "1.0.1" +bs58 = "0.4" +comfy-table = "6.0.0" +cfg-if = "1.0.0" +clap = { version = "3.2", features = ["derive"] } +handlebars = "3.0.1" +humantime-serde = "1.0" +k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +log = "0.4" +rand = {version = "0.6", features = ["std"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1" +thiserror = "1" +time = { version = "0.3.6", features = ["parsing", "formatting"] } +toml = "0.5.6" +url = "2.2" + +cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmwasm-std = { version = "1.0.0" } + +validator-client = { path = "../client-libs/validator-client", features = ["nymd-client"] } +network-defaults = { path = "../network-defaults" } +mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } +vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" } diff --git a/common/commands/README.md b/common/commands/README.md new file mode 100644 index 0000000000..c545e13b1d --- /dev/null +++ b/common/commands/README.md @@ -0,0 +1,13 @@ +# Common `clap` Command Crate + +This crate contains `clap` commands for common operations: + +- account creation and queries +- block queries +- cosmwasm uploads, instantiate, execution, query, etc +- mixnet actions and queries +- sign and verify messages +- query for transactions +- create vesting schedules and query for them + +For how to use this crate, please see the [Nym CLI](../../tools/nym-cli). \ No newline at end of file diff --git a/common/commands/src/coconut/mod.rs b/common/commands/src/coconut/mod.rs new file mode 100644 index 0000000000..6cfc921228 --- /dev/null +++ b/common/commands/src/coconut/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +// TODO: add coconut commands here diff --git a/common/commands/src/context/errors.rs b/common/commands/src/context/errors.rs new file mode 100644 index 0000000000..5c3d24a2bb --- /dev/null +++ b/common/commands/src/context/errors.rs @@ -0,0 +1,18 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContextError { + #[error("mnemonic was not provided, pass as an argument or an env var called MNEMONIC")] + MnemonicNotProvided, + + #[error("failed to parse mnemonic - {0}")] + Bip39Error(#[from] bip39::Error), + + // there are lots of error that can occur in the nymd client, so just pass through their display details + // TODO: improve this to return known errors + #[error("failed to create client - {0}")] + NymdError(String), +} diff --git a/common/commands/src/context/mod.rs b/common/commands/src/context/mod.rs new file mode 100644 index 0000000000..856a03e62a --- /dev/null +++ b/common/commands/src/context/mod.rs @@ -0,0 +1,138 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::{ + setup_env, + var_names::{API_VALIDATOR, MIXNET_CONTRACT_ADDRESS, NYMD_VALIDATOR, VESTING_CONTRACT_ADDRESS}, + NymNetworkDetails, +}; +use validator_client::nymd::{self, AccountId, NymdClient, QueryNymdClient, SigningNymdClient}; +pub use validator_client::validator_api::Client as ValidatorApiClient; + +use crate::context::errors::ContextError; + +pub mod errors; + +pub type SigningClient = validator_client::nymd::NymdClient; +pub type QueryClient = validator_client::nymd::NymdClient; +pub type SigningClientWithValidatorAPI = validator_client::Client; +pub type QueryClientWithValidatorAPI = validator_client::Client; + +#[derive(Debug)] +pub struct ClientArgs { + pub config_env_file: Option, + pub nymd_url: Option, + pub validator_api_url: Option, + pub mnemonic: Option, + pub mixnet_contract_address: Option, + pub vesting_contract_address: Option, +} + +pub fn get_network_details(args: &ClientArgs) -> Result { + // let the network defaults crate handle setting up the env vars if the file arg is set, otherwise + // it will default to what is already in env vars, falling back to mainnet + setup_env(args.config_env_file.clone()); + + // override the env vars with user supplied arguments, if set + if let Some(nymd_url) = args.nymd_url.as_ref() { + std::env::set_var(NYMD_VALIDATOR, nymd_url); + } + if let Some(validator_api_url) = args.validator_api_url.as_ref() { + std::env::set_var(API_VALIDATOR, validator_api_url); + } + if let Some(mixnet_contract_address) = args.mixnet_contract_address.as_ref() { + std::env::set_var(MIXNET_CONTRACT_ADDRESS, mixnet_contract_address.to_string()); + } + if let Some(vesting_contract_address) = args.vesting_contract_address.as_ref() { + std::env::set_var( + VESTING_CONTRACT_ADDRESS, + vesting_contract_address.to_string(), + ); + } + + Ok(NymNetworkDetails::new_from_env()) +} + +pub fn create_signing_client( + args: ClientArgs, + network_details: &NymNetworkDetails, +) -> Result { + let client_config = nymd::Config::try_from_nym_network_details(network_details) + .expect("failed to construct valid validator client config with the provided network"); + + // get mnemonic + let mnemonic = match std::env::var("MNEMONIC") { + Ok(value) => bip39::Mnemonic::parse(value)?, + // env var MNEMONIC is not present, so try to fall back to arg --mnemonic ... + Err(_) => match args.mnemonic { + Some(value) => value, + None => return Err(ContextError::MnemonicNotProvided), // no env var or arg provided + }, + }; + + let nymd_url = network_details + .endpoints + .first() + .expect("network details are not defined") + .nymd_url + .as_str(); + + match NymdClient::connect_with_mnemonic(client_config, nymd_url, mnemonic, None) { + Ok(client) => Ok(client), + Err(e) => Err(ContextError::NymdError(format!("{:?}", e))), + } +} + +pub fn create_query_client( + network_details: &NymNetworkDetails, +) -> Result { + let client_config = nymd::Config::try_from_nym_network_details(network_details) + .expect("failed to construct valid validator client config with the provided network"); + + let nymd_url = network_details + .endpoints + .first() + .expect("network details are not defined") + .nymd_url + .as_str(); + + match NymdClient::connect(client_config, nymd_url) { + Ok(client) => Ok(client), + Err(e) => Err(ContextError::NymdError(format!("{:?}", e))), + } +} + +pub fn create_signing_client_with_validator_api( + args: ClientArgs, + network_details: &NymNetworkDetails, +) -> Result { + let client_config = validator_client::Config::try_from_nym_network_details(network_details) + .expect("failed to construct valid validator client config with the provided network"); + + // get mnemonic + let mnemonic = match std::env::var("MNEMONIC") { + Ok(value) => bip39::Mnemonic::parse(value)?, + // env var MNEMONIC is not present, so try to fall back to arg --mnemonic ... + Err(_) => match args.mnemonic { + Some(value) => value, + None => return Err(ContextError::MnemonicNotProvided), // no env var or arg provided + }, + }; + + match validator_client::client::Client::new_signing(client_config, mnemonic) { + Ok(client) => Ok(client), + Err(e) => Err(ContextError::NymdError(format!("{:?}", e))), + } +} + +pub fn create_query_client_with_validator_api( + network_details: &NymNetworkDetails, +) -> Result { + let client_config = validator_client::Config::try_from_nym_network_details(network_details) + .expect("failed to construct valid validator client config with the provided network"); + + match validator_client::client::Client::new_query(client_config) { + Ok(client) => Ok(client), + Err(e) => Err(ContextError::NymdError(format!("{:?}", e))), + } +} diff --git a/common/commands/src/lib.rs b/common/commands/src/lib.rs new file mode 100644 index 0000000000..afca2be0f7 --- /dev/null +++ b/common/commands/src/lib.rs @@ -0,0 +1,7 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod coconut; +pub mod context; +pub mod utils; +pub mod validator; diff --git a/common/commands/src/utils.rs b/common/commands/src/utils.rs new file mode 100644 index 0000000000..d6419fa20b --- /dev/null +++ b/common/commands/src/utils.rs @@ -0,0 +1,44 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::error::Error; +use std::fmt::Display; + +use cosmwasm_std::{Coin as CosmWasmCoin, Decimal}; +use log::error; +use validator_client::nymd::Coin; + +pub fn pretty_coin(coin: &Coin) -> String { + let amount = Decimal::from_ratio(coin.amount, 1_000_000u128); + let denom = if coin.denom.starts_with('u') { + &coin.denom[1..] + } else { + &coin.denom + }; + format!("{} {}", amount, denom) +} + +pub fn pretty_cosmwasm_coin(coin: &CosmWasmCoin) -> String { + let amount = Decimal::from_ratio(coin.amount, 1_000_000u128); + let denom = if coin.denom.starts_with('u') { + &coin.denom[1..] + } else { + &coin.denom + }; + format!("{} {}", amount, denom) +} + +pub fn show_error(e: E) +where + E: Display, +{ + error!("{}", e); +} + +pub fn show_error_passthrough(e: E) -> E +where + E: Error + Display, +{ + error!("{}", e); + e +} diff --git a/common/commands/src/validator/account/balance.rs b/common/commands/src/validator/account/balance.rs new file mode 100644 index 0000000000..8ac24b273f --- /dev/null +++ b/common/commands/src/validator/account/balance.rs @@ -0,0 +1,72 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::{error, info}; + +use validator_client::nymd::AccountId; + +use crate::context::QueryClient; +use crate::utils::{pretty_coin, show_error}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The account address to get the balance for")] + pub address: Option, + + #[clap(long)] + #[clap(help = "Optional currency to show balance for")] + pub denom: Option, + + #[clap(long, requires = "denom")] + #[clap(help = "Optionally hide the denom")] + pub hide_denom: bool, + + #[clap(long)] + #[clap(help = "Show as a raw value")] + pub raw: bool, +} + +pub async fn query_balance( + args: Args, + client: &QueryClient, + address_from_mnemonic: Option, +) { + if args.address.is_none() && address_from_mnemonic.is_none() { + error!("Please specify an account address or a mnemonic to get the balance for"); + return; + } + + let address = args + .address + .unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic")); + + info!("Getting balance for {}...", address); + + match client.get_all_balances(&address).await { + Ok(coins) => { + if coins.is_empty() { + println!("No balance"); + return; + } + + let denom = args.denom.unwrap_or_else(|| "".to_string()); + + for coin in coins { + if denom.is_empty() || denom.eq_ignore_ascii_case(&coin.denom) { + if args.raw { + if !args.hide_denom { + println!("{}", coin); + } else { + println!("{}", coin.amount); + } + } else { + println!("{}", pretty_coin(&coin)); + } + } + } + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/account/create.rs b/common/commands/src/validator/account/create.rs new file mode 100644 index 0000000000..3003b9a9d5 --- /dev/null +++ b/common/commands/src/validator/account/create.rs @@ -0,0 +1,24 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use validator_client::nymd::wallet::DirectSecp256k1HdWallet; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + // allowed values are 12, 18 or 24 + pub word_count: Option, +} + +pub fn create_account(args: Args, prefix: &str) { + let word_count = args.word_count.unwrap_or(24); + let mnemonic = bip39::Mnemonic::generate(word_count).expect("failed to generate mnemonic!"); + + let wallet = + DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic).expect("failed to build wallet!"); + + // Output address and mnemonics into separate lines for easier parsing + println!("{}", wallet.mnemonic()); + println!("{}", wallet.try_derive_accounts().unwrap()[0].address()); +} diff --git a/common/commands/src/validator/account/mod.rs b/common/commands/src/validator/account/mod.rs new file mode 100644 index 0000000000..b3cecc7c9a --- /dev/null +++ b/common/commands/src/validator/account/mod.rs @@ -0,0 +1,28 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod balance; +pub mod create; +pub mod pubkey; +pub mod send; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Account { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum AccountCommands { + /// Create a new mnemonic - note, this account does not appear on the chain until the account id is used in a transaction + Create(crate::validator::account::create::Args), + /// Gets the balance of an account + Balance(crate::validator::account::balance::Args), + /// Gets the public key of an account + PubKey(crate::validator::account::pubkey::Args), + /// Sends tokens to another account + Send(crate::validator::account::send::Args), +} diff --git a/common/commands/src/validator/account/pubkey.rs b/common/commands/src/validator/account/pubkey.rs new file mode 100644 index 0000000000..83d15f25e3 --- /dev/null +++ b/common/commands/src/validator/account/pubkey.rs @@ -0,0 +1,89 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::{error, info}; + +use validator_client::nymd::wallet::DirectSecp256k1HdWallet; +use validator_client::nymd::AccountId; + +use crate::context::QueryClient; +use crate::utils::show_error; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap( + help = "Optionally, show the public key for this account address, otherwise generate the account address from the mnemonic" + )] + pub address: Option, + + #[clap(long)] + #[clap(help = "If set, get the public key from the mnemonic, rather than querying for it")] + pub from_mnemonic: bool, +} + +pub async fn get_pubkey( + args: Args, + client: &QueryClient, + mnemonic: Option, + address_from_mnemonic: Option, +) { + if args.address.is_none() && address_from_mnemonic.is_none() { + error!("Please specify an account address or a mnemonic to get the balance for"); + return; + } + + let address = args + .address + .unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic")); + + if args.from_mnemonic { + let prefix = client + .current_chain_details() + .bech32_account_prefix + .as_str(); + get_pubkey_from_mnemonic(address, prefix, mnemonic.expect("mnemonic not set")); + return; + } + + get_pubkey_from_chain(address, client).await; +} + +pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip39::Mnemonic) { + match DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic) { + Ok(wallet) => match wallet.try_derive_accounts() { + Ok(accounts) => match accounts.iter().find(|a| *a.address() == address) { + Some(account) => { + println!("{}", account.public_key().to_string()); + } + None => { + error!("Could not derive key that matches {}", address) + } + }, + Err(e) => { + error!("Failed to derive accounts. {}", e); + } + }, + Err(e) => show_error(e), + } +} + +pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) { + info!("Getting public key for address {} from chain...", address); + match client.get_account_details(&address).await { + Ok(Some(account)) => { + if let Ok(base_account) = account.try_get_base_account() { + if let Some(pubkey) = base_account.pubkey { + println!("{}", pubkey.to_string()); + } else { + println!("No account associated with address {}", address); + } + } + } + Ok(None) => { + println!("No account associated with address {}", address); + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/account/send.rs b/common/commands/src/validator/account/send.rs new file mode 100644 index 0000000000..90816258bd --- /dev/null +++ b/common/commands/src/validator/account/send.rs @@ -0,0 +1,66 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; +use serde_json::json; + +use validator_client::nymd::{AccountId, Coin}; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser, help = "The recipient account address")] + pub recipient: AccountId, + + #[clap( + value_parser, + help = "Amount to transfer in micro denomination (e.g. unym or unyx)" + )] + pub amount: u128, + + #[clap(long, help = "Override the denomination")] + pub denom: Option, + + #[clap(long)] + pub memo: Option, +} + +pub async fn send(args: Args, client: &SigningClient) { + let memo = args + .memo + .unwrap_or_else(|| "Sending tokens with nym-cli".to_owned()); + let denom = args + .denom + .unwrap_or_else(|| client.current_chain_details().mix_denom.base.clone()); + + let coin = Coin { + denom, + amount: args.amount, + }; + + info!( + "Sending {} {} from {} to {}...", + coin.amount, + coin.denom, + client.address(), + args.recipient + ); + + let res = client + .send(&args.recipient, vec![coin], memo, None) + .await + .expect("failed to send tokens!"); + + info!("Sending result: {}", json!(res)); + + println!(); + println!( + "Nodesguru: https://nym.explorers.guru/transaction/{}", + &res.hash + ); + println!("Mintscan: https://www.mintscan.io/nyx/txs/{}", &res.hash); + println!("Transaction result code: {}", &res.tx_result.code.value()); + println!("Transaction hash: {}", &res.hash); +} diff --git a/common/commands/src/validator/block/block_time.rs b/common/commands/src/validator/block/block_time.rs new file mode 100644 index 0000000000..a35e7ca597 --- /dev/null +++ b/common/commands/src/validator/block/block_time.rs @@ -0,0 +1,23 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; + +use crate::context::QueryClient; +use crate::utils::show_error; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The block height")] + pub height: u32, +} + +pub async fn query_for_block_time(args: Args, client: &QueryClient) { + match client.get_block_timestamp(Some(args.height)).await { + Ok(res) => { + println!("{}", res.to_rfc3339()) + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/block/current_height.rs b/common/commands/src/validator/block/current_height.rs new file mode 100644 index 0000000000..a7aa7fb743 --- /dev/null +++ b/common/commands/src/validator/block/current_height.rs @@ -0,0 +1,19 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; + +use crate::context::QueryClient; +use crate::utils::show_error; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn query_current_block_height(client: &QueryClient) { + match client.get_current_block_height().await { + Ok(res) => { + println!("Current block height:\n{}", res.value()) + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/block/get.rs b/common/commands/src/validator/block/get.rs new file mode 100644 index 0000000000..12a612b0c8 --- /dev/null +++ b/common/commands/src/validator/block/get.rs @@ -0,0 +1,24 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; + +use crate::context::QueryClient; +use crate::utils::show_error; +use serde_json::json; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The block height")] + pub height: u32, +} + +pub async fn query_for_block(args: Args, client: &QueryClient) { + match client.get_block(Some(args.height)).await { + Ok(res) => { + println!("{}", json!(res)) + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/block/mod.rs b/common/commands/src/validator/block/mod.rs new file mode 100644 index 0000000000..07798ced63 --- /dev/null +++ b/common/commands/src/validator/block/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod block_time; +pub mod current_height; +pub mod get; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Block { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum BlockCommands { + /// Gets a block's details and prints as JSON + Get(crate::validator::block::get::Args), + /// Gets the block time at a height + Time(crate::validator::block::block_time::Args), + /// Gets the current block height + CurrentHeight(crate::validator::block::current_height::Args), +} diff --git a/common/commands/src/validator/cosmwasm/execute_contract.rs b/common/commands/src/validator/cosmwasm/execute_contract.rs new file mode 100644 index 0000000000..f387b83903 --- /dev/null +++ b/common/commands/src/validator/cosmwasm/execute_contract.rs @@ -0,0 +1,60 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use cosmrs::AccountId; +use log::{error, info}; +use serde_json::{json, Value}; +use validator_client::nymd::Coin; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The address of contract to execute")] + pub contract_address: AccountId, + + #[clap(value_parser)] + #[clap(help = "JSON encoded method arguments")] + pub json_args: String, + + #[clap(long)] + pub memo: Option, + + #[clap( + value_parser, + requires = "fundsDenom", + help = "Amount to supply as funds in micro denomination (e.g. unym or unyx)" + )] + pub funds: Option, + + #[clap(long, requires = "funds", help = "Set the denomination for the funds")] + pub funds_denom: Option, +} + +pub async fn execute(args: Args, client: SigningClient) { + info!("Starting contract method execution!"); + + let json_args: Value = + serde_json::from_str(&args.json_args).expect("Unable to parse JSON args"); + + let memo = args + .memo + .unwrap_or_else(|| "nym-cli execute contract method".to_owned()); + + let funds = match args.funds { + Some(funds) => vec![Coin::new( + funds, + args.funds_denom.expect("denom for funds not set"), + )], + None => vec![], + }; + + match client + .execute(&args.contract_address, &json_args, None, memo, funds) + .await + { + Ok(res) => info!("SUCCESS ✅\n{}", json!(res)), + Err(e) => error!("FAILURE ❌\n{}", e), + } +} diff --git a/common/commands/src/validator/cosmwasm/init_contract.rs b/common/commands/src/validator/cosmwasm/init_contract.rs new file mode 100644 index 0000000000..c624a81a94 --- /dev/null +++ b/common/commands/src/validator/cosmwasm/init_contract.rs @@ -0,0 +1,78 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use cosmrs::{AccountId, Coin as CosmosCoin}; +use log::info; +use network_defaults::NymNetworkDetails; +use validator_client::nymd::cosmwasm_client::types::{ContractCodeId, InstantiateOptions}; +use validator_client::nymd::Coin; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + pub code_id: ContractCodeId, + + #[clap(long)] + pub memo: Option, + + #[clap(long)] + pub label: Option, + + #[clap(long)] + pub init_message: String, + + #[clap(long)] + pub admin: Option, + + #[clap( + long, + requires = "fundsDenom", + help = "Amount to supply as funds in micro denomination (e.g. unym or unyx)" + )] + pub funds: Option, + + #[clap(long, requires = "funds", help = "Set the denomination for the funds")] + pub funds_denom: Option, +} + +pub async fn init(args: Args, client: SigningClient, network_details: &NymNetworkDetails) { + info!("Starting contract instantiation!"); + + let memo = args + .memo + .unwrap_or_else(|| "contract instantiation".to_owned()); + let label = args + .label + .unwrap_or_else(|| "Nym mixnet smart contract".to_owned()); + + let funds: Vec = match args.funds { + Some(funds) => vec![Coin::new( + funds, + args.funds_denom + .unwrap_or_else(|| network_details.chain_details.mix_denom.base.to_string()), + ) + .into()], + None => vec![], + }; + + // by default we make ourselves an admin, let me know if you don't like that behaviour + let opts = Some(InstantiateOptions { + funds, + admin: Some(args.admin.unwrap_or_else(|| client.address().clone())), + }); + + let msg: serde_json::Value = + serde_json::from_str(&args.init_message).expect("failed to parse init message"); + + // the EmptyMsg{} argument is equivalent to `--init-message='{}'` + let res = client + .instantiate(args.code_id, &msg, label, memo, opts, None) + .await + .expect("failed to instantiate the contract!"); + + info!("Init result: {:?}", res); + + println!("{}", res.contract_address) +} diff --git a/common/commands/src/validator/cosmwasm/migrate_contract.rs b/common/commands/src/validator/cosmwasm/migrate_contract.rs new file mode 100644 index 0000000000..fa21062ee7 --- /dev/null +++ b/common/commands/src/validator/cosmwasm/migrate_contract.rs @@ -0,0 +1,51 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use crate::utils::show_error_passthrough; +use clap::Parser; +use cosmrs::AccountId; +use log::info; +use validator_client::nymd::cosmwasm_client::types::{ContractCodeId, EmptyMsg}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + pub contract_address: AccountId, + + #[clap(long)] + pub code_id: ContractCodeId, + + #[clap(long)] + pub memo: Option, + + #[clap(long)] + pub init_message: Option, +} + +pub async fn migrate(args: Args, client: SigningClient) { + println!("Starting contract migration!"); + + let memo = args.memo.unwrap_or_else(|| "contract migration".to_owned()); + let contract_address = args.contract_address; + + // the EmptyMsg{} argument is equivalent to `--init-message='{}'` + let res = if let Some(raw_msg) = args.init_message { + let msg: serde_json::Value = + serde_json::from_str(&raw_msg).expect("failed to parse init message"); + + client + .migrate(&contract_address, args.code_id, &msg, memo, None) + .await + .map_err(show_error_passthrough) + .expect("failed to migrate the contract!") + } else { + client + .migrate(&contract_address, args.code_id, &EmptyMsg {}, memo, None) + .await + .map_err(show_error_passthrough) + .expect("failed to migrate the contract!") + }; + + info!("Migrate result: {:?}", res); +} diff --git a/common/commands/src/validator/cosmwasm/mod.rs b/common/commands/src/validator/cosmwasm/mod.rs new file mode 100644 index 0000000000..9ee1fa182f --- /dev/null +++ b/common/commands/src/validator/cosmwasm/mod.rs @@ -0,0 +1,28 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod execute_contract; +pub mod init_contract; +pub mod migrate_contract; +pub mod upload_contract; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Cosmwasm { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum CosmwasmCommands { + /// Upload a smart contract WASM blob + Upload(crate::validator::cosmwasm::upload_contract::Args), + /// Init a WASM smart contract + Init(crate::validator::cosmwasm::init_contract::Args), + /// Migrate a WASM smart contract + Migrate(crate::validator::cosmwasm::migrate_contract::Args), + /// Execute a WASM smart contract method + Execute(crate::validator::cosmwasm::execute_contract::Args), +} diff --git a/common/commands/src/validator/cosmwasm/upload_contract.rs b/common/commands/src/validator/cosmwasm/upload_contract.rs new file mode 100644 index 0000000000..96d01741ee --- /dev/null +++ b/common/commands/src/validator/cosmwasm/upload_contract.rs @@ -0,0 +1,37 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; +use std::io::Read; +use std::path::PathBuf; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub wasm_path: PathBuf, + + #[clap(long)] + pub memo: Option, +} + +pub async fn upload(args: Args, client: SigningClient) { + info!("Starting contract upload!"); + + let mut file = std::fs::File::open(args.wasm_path).expect("failed to open the wasm blob"); + let mut data = Vec::new(); + + file.read_to_end(&mut data).unwrap(); + + let memo = args.memo.unwrap_or_else(|| "contract upload".to_owned()); + + let res = client + .upload(data, memo, None) + .await + .expect("failed to upload the contract!"); + + info!("Upload result: {:?}", res); + + println!("{}", res.code_id) +} diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs new file mode 100644 index 0000000000..d69d5e0028 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs @@ -0,0 +1,31 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; +use mixnet_contract_common::Coin; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub amount: u128, +} + +pub async fn delegate_to_mixnode(args: Args, client: SigningClient) { + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!("Starting delegation to mixnode"); + + let coin = Coin::new(args.amount, denom); + + let res = client + .delegate_to_mixnode(&*args.identity_key, coin.into(), None) + .await + .expect("failed to delegate to mixnode!"); + + info!("delegating to mixnode: {:?}", res); +} diff --git a/common/commands/src/validator/mixnet/delegators/mod.rs b/common/commands/src/validator/mixnet/delegators/mod.rs new file mode 100644 index 0000000000..61e87f119d --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/mod.rs @@ -0,0 +1,35 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod rewards; + +pub mod delegate_to_mixnode; +pub mod query_for_delegations; +pub mod undelegate_from_mixnode; +pub mod vesting_delegate_to_mixnode; +pub mod vesting_undelegate_from_mixnode; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetDelegators { + #[clap(subcommand)] + pub command: MixnetDelegatorsCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetDelegatorsCommands { + /// Lists current delegations + List(query_for_delegations::Args), + /// Manage rewards from delegations + Rewards(rewards::MixnetDelegatorsReward), + /// Delegate to a mixnode + Delegate(delegate_to_mixnode::Args), + /// Undelegate from a mixnode + Undelegate(undelegate_from_mixnode::Args), + /// Delegate to a mixnode with locked tokens + DelegateVesting(vesting_delegate_to_mixnode::Args), + /// Undelegate from a mixnode (when originally using locked tokens) + UndelegateVesting(vesting_undelegate_from_mixnode::Args), +} diff --git a/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs b/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs new file mode 100644 index 0000000000..efb685e085 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs @@ -0,0 +1,129 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; + +use crate::context::SigningClientWithValidatorAPI; +use crate::utils::{pretty_cosmwasm_coin, show_error_passthrough}; + +use comfy_table::Table; +use mixnet_contract_common::mixnode::DelegationEvent; +use mixnet_contract_common::Delegation; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn execute(_args: Args, client: SigningClientWithValidatorAPI) { + info!( + "Getting delegations for account {}...", + client.nymd.address() + ); + + let delegations = client + .get_all_delegator_delegations(client.nymd.address()) + .await + .map_err(show_error_passthrough); + + let mixnet_contract_events = client + .nymd + .get_pending_delegation_events(client.nymd.address().to_string(), None) + .await + .map_err(show_error_passthrough); + + let vesting_contract = client.nymd.vesting_contract_address(); + + let vesting_contract_events = client + .nymd + .get_pending_delegation_events( + client.nymd.address().to_string(), + Some(vesting_contract.to_string()), + ) + .await + .map_err(show_error_passthrough); + + if let Ok(res) = delegations { + println!(); + if res.is_empty() { + println!("This account has not delegated any tokens to mixnodes"); + } else { + println!("Delegations:"); + print_delegations(res, &client).await; + } + } + if let Ok(res) = mixnet_contract_events { + if !res.is_empty() { + println!(); + println!("Pending delegations (liquid tokens):"); + print_delegation_events(res, &client).await; + } + } + if let Ok(res) = vesting_contract_events { + if !res.is_empty() { + println!(); + println!("Pending delegations (locked tokens):"); + print_delegation_events(res, &client).await; + } + } +} + +async fn to_iso_timestamp(block_height: u32, client: &SigningClientWithValidatorAPI) -> String { + match client.nymd.get_block_timestamp(Some(block_height)).await { + Ok(res) => res.to_rfc3339(), + Err(_e) => "-".to_string(), + } +} + +async fn print_delegations(delegations: Vec, client: &SigningClientWithValidatorAPI) { + let mut table = Table::new(); + + table.set_header(vec!["Timestamp", "Identity Key", "Delegation", "Proxy"]); + + for delegation in delegations { + table.add_row(vec![ + to_iso_timestamp(delegation.block_height as u32, client).await, + delegation.node_identity.to_string(), + pretty_cosmwasm_coin(&delegation.amount), + format!("{:?}", delegation.proxy), + ]); + } + + println!("{table}"); +} + +async fn print_delegation_events( + events: Vec, + client: &SigningClientWithValidatorAPI, +) { + let mut table = Table::new(); + + table.set_header(vec![ + "Timestamp", + "Identity Key", + "Delegation", + "Event Type", + ]); + + for event in events { + match event { + DelegationEvent::Delegate(delegation) => { + table.add_row(vec![ + to_iso_timestamp(delegation.block_height as u32, client).await, + delegation.node_identity.to_string(), + pretty_cosmwasm_coin(&delegation.amount), + "Delegate".to_string(), + ]); + } + DelegationEvent::Undelegate(undelegate) => { + table.add_row(vec![ + to_iso_timestamp(undelegate.block_height() as u32, client).await, + undelegate.mix_identity().to_string(), + "-".to_string(), + "Undelegate".to_string(), + ]); + } + } + } + + println!("{table}"); +} diff --git a/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs new file mode 100644 index 0000000000..850ac076d6 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs @@ -0,0 +1,23 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity_key: String, +} + +pub async fn claim_delegator_reward(args: Args, client: SigningClient) { + info!("Claim delegator reward"); + + let res = client + .execute_claim_delegator_reward(args.identity_key, None) + .await + .expect("failed to claim delegator-reward"); + + info!("Claiming delegator reward: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/delegators/rewards/mod.rs b/common/commands/src/validator/mixnet/delegators/rewards/mod.rs new file mode 100644 index 0000000000..05fe7e98b5 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/rewards/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod claim_delegator_reward; +pub mod vesting_claim_delegator_reward; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetDelegatorsReward { + #[clap(subcommand)] + pub command: MixnetDelegatorsRewardCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetDelegatorsRewardCommands { + /// Claim rewards accumulated during the delegation of unlocked tokens + Claim(claim_delegator_reward::Args), + /// Claim rewards accumulated during the delegation of locked tokens + VestingClaim(vesting_claim_delegator_reward::Args), +} diff --git a/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs new file mode 100644 index 0000000000..7e0e4d23ee --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs @@ -0,0 +1,23 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity: String, +} + +pub async fn vesting_claim_delegator_reward(args: Args, client: SigningClient) { + info!("Claim vesting delegator reward"); + + let res = client + .execute_vesting_claim_delegator_reward(args.identity, None) + .await + .expect("failed to claim vesting delegator-reward"); + + info!("Claiming vesting delegator reward: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs new file mode 100644 index 0000000000..8cd28d0629 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs @@ -0,0 +1,23 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity_key: String, +} + +pub async fn undelegate_from_mixnode(args: Args, client: SigningClient) { + info!("removing stake from mix-node"); + + let res = client + .remove_mixnode_delegation(&*args.identity_key, None) + .await + .expect("failed to remove stake from mixnode!"); + + info!("removing stake from mixnode: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs new file mode 100644 index 0000000000..d87c334fa8 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs @@ -0,0 +1,34 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; + +use mixnet_contract_common::Coin; +use validator_client::nymd::VestingSigningClient; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub amount: u128, +} + +pub async fn vesting_delegate_to_mixnode(args: Args, client: SigningClient) { + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!("Starting vesting delegation to mixnode"); + + let coin = Coin::new(args.amount, denom); + + let res = client + .vesting_delegate_to_mixnode(&*args.identity_key, coin.into(), None) + .await + .expect("failed to delegate to mixnode!"); + + info!("vesting delegating to mixnode: {:?}", res); +} diff --git a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs new file mode 100644 index 0000000000..9dd802f1e0 --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs @@ -0,0 +1,26 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; + +use validator_client::nymd::VestingSigningClient; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub identity_key: String, +} + +pub async fn vesting_undelegate_from_mixnode(args: Args, client: SigningClient) { + info!("removing stake from vesting mix-node"); + + let res = client + .vesting_undelegate_from_mixnode(&*args.identity_key, None) + .await + .expect("failed to remove stake from vesting account on mixnode!"); + + info!("removing stake from vesting mixnode: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/mod.rs b/common/commands/src/validator/mixnet/mod.rs new file mode 100644 index 0000000000..9429ea6118 --- /dev/null +++ b/common/commands/src/validator/mixnet/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod delegators; +pub mod operators; +pub mod query; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Mixnet { + #[clap(subcommand)] + pub command: MixnetCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetCommands { + /// Query the mixnet directory + Query(query::MixnetQuery), + /// Manage your delegations + Delegators(delegators::MixnetDelegators), + /// Manage a mixnode or gateway you operate + Operators(operators::MixnetOperators), +} diff --git a/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs new file mode 100644 index 0000000000..254ae650da --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs @@ -0,0 +1,77 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::{info, warn}; +use mixnet_contract_common::Coin; +use network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub host: String, + + #[clap(long)] + pub signature: String, + + #[clap(long)] + pub mix_port: Option, + + #[clap(long)] + pub clients_port: Option, + + #[clap(long)] + pub location: Option, + + #[clap(long)] + pub sphinx_key: String, + + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub version: String, + + #[clap( + long, + help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')" + )] + pub amount: u128, + + #[clap(short, long)] + pub force: bool, +} + +pub async fn bond_gateway(args: Args, client: SigningClient) { + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!("Starting gateway bonding!"); + + // if we're trying to bond less than 1 token + if args.amount < 1_000_000 && !args.force { + warn!("You're trying to bond only {}{} which is less than 1 full token. Are you sure that's what you want? If so, run with `--force` or `-f` flag", args.amount, denom); + return; + } + + let gateway = mixnet_contract_common::Gateway { + host: args.host, + mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT), + clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT), + location: args + .location + .unwrap_or_else(|| "secret gateway location".to_owned()), + sphinx_key: args.sphinx_key, + identity_key: args.identity_key, + version: args.version, + }; + + let coin = Coin::new(args.amount, denom); + + let res = client + .bond_gateway(gateway, args.signature, coin.into(), None) + .await + .expect("failed to bond gateway!"); + + info!("Bonding result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/gateway/mod.rs b/common/commands/src/validator/mixnet/operators/gateway/mod.rs new file mode 100644 index 0000000000..af658a7876 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/gateway/mod.rs @@ -0,0 +1,28 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod bond_gateway; +pub mod unbond_gateway; +pub mod vesting_bond_gateway; +pub mod vesting_unbond_gateway; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperatorsGateway { + #[clap(subcommand)] + pub command: MixnetOperatorsGatewayCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsGatewayCommands { + /// Bond to a gateway + Bond(bond_gateway::Args), + /// Unbound from a gateway + Unbound(unbond_gateway::Args), + /// Bond to a gateway with locked tokens + VestingBond(vesting_bond_gateway::Args), + /// Unbound from a gateway (when originally using locked tokens) + VestingUnbound(vesting_unbond_gateway::Args), +} diff --git a/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs new file mode 100644 index 0000000000..75a695dfa1 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs @@ -0,0 +1,20 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn unbond_gateway(client: SigningClient) { + info!("Starting gateway unbonding!"); + + let res = client + .unbond_gateway(None) + .await + .expect("failed to unbond gateway!"); + + info!("Unbonding result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs new file mode 100644 index 0000000000..d82a01c0c5 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs @@ -0,0 +1,76 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::{info, warn}; +use mixnet_contract_common::{Coin, Gateway}; +use network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; +use validator_client::nymd::VestingSigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub host: String, + + #[clap(long)] + pub signature: String, + + #[clap(long)] + pub mix_port: Option, + + #[clap(long)] + pub clients_port: Option, + + #[clap(long)] + pub location: Option, + + #[clap(long)] + pub sphinx_key: String, + + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub version: String, + + #[clap( + long, + help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')" + )] + pub amount: u128, + + #[clap(short, long)] + pub force: bool, +} + +pub async fn vesting_bond_gateway(client: SigningClient, args: Args, denom: &str) { + info!("Starting vesting gateway bonding!"); + + // if we're trying to bond less than 1 token + if args.amount < 1_000_000 && !args.force { + warn!("You're trying to bond only {}{} which is less than 1 full token. Are you sure that's what you want? If so, run with `--force` or `-f` flag", args.amount, denom); + return; + } + + let gateway = Gateway { + host: args.host, + mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT), + clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT), + location: args + .location + .unwrap_or_else(|| "secret gateway location".to_owned()), + sphinx_key: args.sphinx_key, + identity_key: args.identity_key, + version: args.version, + }; + + let coin = Coin::new(args.amount, denom); + + let res = client + .vesting_bond_gateway(gateway, &*args.signature, coin.into(), None) + .await + .expect("failed to bond gateway!"); + + info!("Vesting bonding gateway result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs new file mode 100644 index 0000000000..563c4bdff6 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs @@ -0,0 +1,20 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn vesting_unbond_gateway(client: SigningClient) { + info!("Starting vesting gateway unbonding!"); + + let res = client + .unbond_gateway(None) + .await + .expect("failed to unbond vesting gateway!"); + + info!("Unbonding vesting result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs new file mode 100644 index 0000000000..26d95fe93f --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs @@ -0,0 +1,85 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::{info, warn}; + +use mixnet_contract_common::Coin; +use network_defaults::{ + DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, +}; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub host: String, + + #[clap(long)] + pub signature: String, + + #[clap(long)] + pub mix_port: Option, + + #[clap(long)] + pub verloc_port: Option, + + #[clap(long)] + pub http_api_port: Option, + + #[clap(long)] + pub sphinx_key: String, + + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub version: String, + + #[clap(long)] + pub profit_margin_percent: Option, + + #[clap( + long, + help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')" + )] + pub amount: u128, + + #[clap(short, long)] + pub force: bool, +} + +pub async fn bond_mixnode(args: Args, client: SigningClient) { + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!("Starting mixnode bonding!"); + + // if we're trying to bond less than 1 token + if args.amount < 1_000_000 && !args.force { + warn!("You're trying to bond only {}{} which is less than 1 full token. Are you sure that's what you want? If so, run with `--force` or `-f` flag", args.amount, denom); + return; + } + + let mixnode = mixnet_contract_common::MixNode { + host: args.host, + mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT), + verloc_port: args.verloc_port.unwrap_or(DEFAULT_VERLOC_LISTENING_PORT), + http_api_port: args + .http_api_port + .unwrap_or(DEFAULT_HTTP_API_LISTENING_PORT), + sphinx_key: args.sphinx_key, + identity_key: args.identity_key, + version: args.version, + profit_margin_percent: args.profit_margin_percent.unwrap_or(10), + }; + + let coin = Coin::new(args.amount, denom); + + let res = client + .bond_mixnode(mixnode, args.signature, coin.into(), None) + .await + .expect("failed to bond mixnode!"); + + info!("Bonding result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs b/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs new file mode 100644 index 0000000000..5938a672c4 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/keys/decode_mixnode_key.rs @@ -0,0 +1,17 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(short, long)] + pub key: String, +} + +pub fn decode_mixnode_key(args: Args) { + let b64_decoded = base64::decode(args.key).expect("failed to decode base64 string"); + let b58_encoded = bs58::encode(&b64_decoded).into_string(); + + println!("{}", b58_encoded) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/keys/mod.rs b/common/commands/src/validator/mixnet/operators/mixnode/keys/mod.rs new file mode 100644 index 0000000000..3f2b566a12 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/keys/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod decode_mixnode_key; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperatorsMixnodeKeys { + #[clap(subcommand)] + pub command: MixnetOperatorsMixnodeKeysCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsMixnodeKeysCommands { + /// Decode a mixnode key + DecodeMixnodeKey(decode_mixnode_key::Args), +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/mod.rs b/common/commands/src/validator/mixnet/operators/mixnode/mod.rs new file mode 100644 index 0000000000..e608c4c36f --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod bond_mixnode; +pub mod keys; +pub mod rewards; +pub mod settings; +pub mod unbond_mixnode; +pub mod vesting_bond_mixnode; +pub mod vesting_unbond_mixnode; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperatorsMixnode { + #[clap(subcommand)] + pub command: MixnetOperatorsMixnodeCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsMixnodeCommands { + /// Operations for mixnode keys + Keys(keys::MixnetOperatorsMixnodeKeys), + /// Manage your mixnode operator rewards + Rewards(rewards::MixnetOperatorsMixnodeRewards), + /// Manage your mixnode settings stored in the directory + Settings(settings::MixnetOperatorsMixnodeSettings), + /// Bond to a mixnode + Bond(bond_mixnode::Args), + /// Unbound from a mixnode + Unbound(unbond_mixnode::Args), + /// Bond to a mixnode with locked tokens + BondVesting(vesting_bond_mixnode::Args), + /// Unbound from a mixnode (when originally using locked tokens) + UnboundVesting(vesting_unbond_mixnode::Args), +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs b/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs new file mode 100644 index 0000000000..2f3f8dd3c4 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs @@ -0,0 +1,20 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn claim_operator_reward(_args: Args, client: SigningClient) { + info!("Claim operator reward"); + + let res = client + .execute_claim_operator_reward(None) + .await + .expect("failed to claim operator reward"); + + info!("Claiming operator reward: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/rewards/mod.rs b/common/commands/src/validator/mixnet/operators/mixnode/rewards/mod.rs new file mode 100644 index 0000000000..d3e4fc988c --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/rewards/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod claim_operator_reward; +pub mod vesting_claim_operator_reward; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperatorsMixnodeRewards { + #[clap(subcommand)] + pub command: MixnetOperatorsMixnodeRewardsCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsMixnodeRewardsCommands { + /// Claim rewards + Claim(claim_operator_reward::Args), + /// Claim rewards for a mixnode bonded with locked tokens + VestingClaim(vesting_claim_operator_reward::Args), +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs b/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs new file mode 100644 index 0000000000..ffcd4670e1 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs @@ -0,0 +1,23 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub gas: Option, +} + +pub async fn vesting_claim_operator_reward(client: SigningClient) { + info!("Claim vesting operator reward"); + + let res = client + .execute_vesting_claim_operator_reward(None) + .await + .expect("failed to claim vesting operator reward"); + + info!("Claiming vesting operator reward: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/mod.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/mod.rs new file mode 100644 index 0000000000..10bbd6ba8b --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod update_profit_percent; +pub mod vesting_update_profit_percent; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperatorsMixnodeSettings { + #[clap(subcommand)] + pub command: MixnetOperatorsMixnodeSettingsCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsMixnodeSettingsCommands { + /// Update profit percentage + UpdateProfitPercentage(update_profit_percent::Args), + /// Update profit percentage for a mixnode bonded with locked tokens + VestingUpdateProfitPercentage(vesting_update_profit_percent::Args), +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/update_profit_percent.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_profit_percent.rs new file mode 100644 index 0000000000..3c874c007c --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_profit_percent.rs @@ -0,0 +1,24 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub profit_percent: u8, +} + +pub async fn update_profit_percent(args: Args, client: SigningClient) { + info!("Update mix node profit percent - get those rewards!"); + + //profit percent between 1-100 + let res = client + .update_mixnode_config(args.profit_percent, None) + .await + .expect("updating mix-node profit percent"); + + info!("profit percentage updated: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_profit_percent.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_profit_percent.rs new file mode 100644 index 0000000000..cc47d99c1e --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_profit_percent.rs @@ -0,0 +1,28 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; +use validator_client::nymd::VestingSigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub profit_percent: u8, + + #[clap(long)] + pub gas: Option, +} + +pub async fn vesting_update_profit_percent(client: SigningClient, args: Args) { + info!("Update vesting mix node profit percent - get those rewards!"); + + //profit percent between 1-100 + let res = client + .vesting_update_mixnode_config(args.profit_percent, None) + .await + .expect("updating vesting mix-node profit percent"); + + info!("profit percentage updated: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs new file mode 100644 index 0000000000..d4f2bb478c --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs @@ -0,0 +1,21 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args {} + +pub async fn unbond_mixnode(_args: Args, client: SigningClient) { + info!("Starting mixnode unbonding!"); + + let res = client + .unbond_mixnode(None) + .await + .expect("failed to unbond mixnode!"); + + info!("Unbonding result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs new file mode 100644 index 0000000000..2e90a83f7e --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs @@ -0,0 +1,86 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::{info, warn}; +use mixnet_contract_common::Coin; +use mixnet_contract_common::MixNode; +use network_defaults::{ + DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, +}; +use validator_client::nymd::VestingSigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub host: String, + + #[clap(long)] + pub signature: String, + + #[clap(long)] + pub mix_port: Option, + + #[clap(long)] + pub verloc_port: Option, + + #[clap(long)] + pub http_api_port: Option, + + #[clap(long)] + pub sphinx_key: String, + + #[clap(long)] + pub identity_key: String, + + #[clap(long)] + pub version: String, + + #[clap(long)] + pub profit_margin_percent: Option, + + #[clap( + long, + help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')" + )] + pub amount: u128, + + #[clap(long)] + pub gas: Option, + + #[clap(short, long)] + pub force: bool, +} + +pub async fn vesting_bond_mixnode(client: SigningClient, args: Args, denom: &str) { + info!("Starting vesting mixnode bonding!"); + + // if we're trying to bond less than 1 token + if args.amount < 1_000_000 && !args.force { + warn!("You're trying to bond only {}{} which is less than 1 full token. Are you sure that's what you want? If so, run with `--force` or `-f` flag", args.amount, denom); + return; + } + + let mixnode = MixNode { + host: args.host, + mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT), + verloc_port: args.verloc_port.unwrap_or(DEFAULT_VERLOC_LISTENING_PORT), + http_api_port: args + .http_api_port + .unwrap_or(DEFAULT_HTTP_API_LISTENING_PORT), + sphinx_key: args.sphinx_key, + identity_key: args.identity_key, + version: args.version, + profit_margin_percent: args.profit_margin_percent.unwrap_or(10), + }; + + let coin = Coin::new(args.amount, denom); + + let res = client + .vesting_bond_mixnode(mixnode, &*args.signature, coin.into(), None) + .await + .expect("failed to bond vesting mixnode!"); + + info!("Bonding vesting result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs new file mode 100644 index 0000000000..0824cc9342 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs @@ -0,0 +1,24 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use clap::Parser; +use log::info; +use validator_client::nymd::VestingSigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub gas: Option, +} + +pub async fn vesting_unbond_mixnode(client: SigningClient) { + info!("Starting vesting mixnode unbonding!"); + + let res = client + .vesting_unbond_mixnode(None) + .await + .expect("failed to unbond vesting mixnode!"); + + info!("Unbonding vesting result: {:?}", res) +} diff --git a/common/commands/src/validator/mixnet/operators/mod.rs b/common/commands/src/validator/mixnet/operators/mod.rs new file mode 100644 index 0000000000..a38479ba65 --- /dev/null +++ b/common/commands/src/validator/mixnet/operators/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod gateway; +pub mod mixnode; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetOperators { + #[clap(subcommand)] + pub command: MixnetOperatorsCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetOperatorsCommands { + /// Manage your mixnode + Mixnode(mixnode::MixnetOperatorsMixnode), + /// Manage your gateway + Gateway(gateway::MixnetOperatorsGateway), +} diff --git a/common/commands/src/validator/mixnet/query/mod.rs b/common/commands/src/validator/mixnet/query/mod.rs new file mode 100644 index 0000000000..6d86e6c7b9 --- /dev/null +++ b/common/commands/src/validator/mixnet/query/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod query_all_gateways; +pub mod query_all_mixnodes; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct MixnetQuery { + #[clap(subcommand)] + pub command: MixnetQueryCommands, +} + +#[derive(Debug, Subcommand)] +pub enum MixnetQueryCommands { + /// Query mixnodes + Mixnodes(query_all_mixnodes::Args), + /// Query gateways + Gateways(query_all_gateways::Args), +} diff --git a/common/commands/src/validator/mixnet/query/query_all_gateways.rs b/common/commands/src/validator/mixnet/query/query_all_gateways.rs new file mode 100644 index 0000000000..679ac08bcd --- /dev/null +++ b/common/commands/src/validator/mixnet/query/query_all_gateways.rs @@ -0,0 +1,52 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use comfy_table::Table; + +use crate::context::QueryClientWithValidatorAPI; +use crate::utils::{pretty_cosmwasm_coin, show_error}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "Optionally, the gateway to display")] + pub identity_key: Option, +} + +pub async fn query(args: Args, client: &QueryClientWithValidatorAPI) { + match client.validator_api.get_gateways().await { + Ok(res) => match args.identity_key { + Some(identity_key) => { + let node = res.iter().find(|node| { + node.gateway + .identity_key + .to_string() + .eq_ignore_ascii_case(&identity_key) + }); + println!( + "{}", + ::serde_json::to_string_pretty(&node).expect("json formatting error") + ); + } + None => { + let mut table = Table::new(); + + table.set_header(vec!["Identity Key", "Owner", "Host", "Bond", "Version"]); + for node in res { + table.add_row(vec![ + node.gateway.identity_key.to_string(), + node.owner.to_string(), + node.gateway.host.to_string(), + pretty_cosmwasm_coin(&node.pledge_amount), + node.gateway.version, + ]); + } + + println!("The gateways in the directory are:"); + println!("{table}"); + } + }, + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/mixnet/query/query_all_mixnodes.rs b/common/commands/src/validator/mixnet/query/query_all_mixnodes.rs new file mode 100644 index 0000000000..91cc344806 --- /dev/null +++ b/common/commands/src/validator/mixnet/query/query_all_mixnodes.rs @@ -0,0 +1,60 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use comfy_table::Table; + +use crate::context::QueryClientWithValidatorAPI; +use crate::utils::{pretty_cosmwasm_coin, show_error}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "Optionally, the mixnode to display")] + pub identity_key: Option, +} + +pub async fn query(args: Args, client: &QueryClientWithValidatorAPI) { + match client.validator_api.get_mixnodes().await { + Ok(res) => match args.identity_key { + Some(identity_key) => { + let node = res.iter().find(|node| { + node.mix_node + .identity_key + .to_string() + .eq_ignore_ascii_case(&identity_key) + }); + println!( + "{}", + ::serde_json::to_string_pretty(&node).expect("json formatting error") + ); + } + None => { + let mut table = Table::new(); + + table.set_header(vec![ + "Identity Key", + "Owner", + "Host", + "Bond", + "Total Delegations", + "Version", + ]); + for node in res { + table.add_row(vec![ + node.mix_node.identity_key.to_string(), + node.owner.to_string(), + node.mix_node.host.to_string(), + pretty_cosmwasm_coin(&node.pledge_amount), + pretty_cosmwasm_coin(&node.total_delegation()), + node.mix_node.version, + ]); + } + + println!("The mixnodes in the directory are:"); + println!("{table}"); + } + }, + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/mod.rs b/common/commands/src/validator/mod.rs new file mode 100644 index 0000000000..ebc295569f --- /dev/null +++ b/common/commands/src/validator/mod.rs @@ -0,0 +1,10 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod account; +pub mod block; +pub mod cosmwasm; +pub mod mixnet; +pub mod signature; +pub mod transactions; +pub mod vesting; diff --git a/common/commands/src/validator/signature/errors.rs b/common/commands/src/validator/signature/errors.rs new file mode 100644 index 0000000000..82aae7e08c --- /dev/null +++ b/common/commands/src/validator/signature/errors.rs @@ -0,0 +1,13 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Errors { + #[error("signature error - {0}")] + SignatureError(#[from] k256::ecdsa::signature::Error), + + #[error("{0}")] + CosmrsError(#[from] cosmrs::ErrorReport), +} diff --git a/common/commands/src/validator/signature/helpers.rs b/common/commands/src/validator/signature/helpers.rs new file mode 100644 index 0000000000..817a880b64 --- /dev/null +++ b/common/commands/src/validator/signature/helpers.rs @@ -0,0 +1,90 @@ +use std::str::FromStr; + +use cosmrs::crypto::secp256k1::{Signature, VerifyingKey}; +use cosmrs::crypto::PublicKey; +use k256::ecdsa::signature::Verifier; + +use crate::validator::signature::errors::Errors; + +pub fn secp256k1_verify_with_public_key( + public_key_as_bytes: &[u8], + signature_as_hex: String, + message: String, +) -> Result<(), k256::ecdsa::signature::Error> { + let verifying_key = VerifyingKey::from_sec1_bytes(public_key_as_bytes)?; + let signature = Signature::from_str(&signature_as_hex)?; + let message_as_bytes = message.into_bytes(); + verifying_key.verify(&message_as_bytes, &signature) +} + +pub fn secp256k1_verify_with_public_key_json( + public_key_as_json: String, + signature_as_hex: String, + message: String, +) -> Result<(), Errors> { + let public_key = PublicKey::from_json(&public_key_as_json)?; + let verifying_key = VerifyingKey::from_sec1_bytes(&public_key.to_bytes())?; + let signature = Signature::from_str(&signature_as_hex)?; + let message_as_bytes = message.into_bytes(); + Ok(verifying_key.verify(&message_as_bytes, &signature)?) +} + +#[cfg(test)] +mod test_secp256k1 { + use crate::validator::signature::helpers::{ + secp256k1_verify_with_public_key, secp256k1_verify_with_public_key_json, + }; + use cosmrs::crypto::PublicKey; + + #[test] + fn test_verify_with_json_public_key_with_valid_signature() { + let json_public_key = r#"{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4FdhUMasPmNhRZjtpKlmjNbq7EEUgPxfdI+E3vSajvc"}"#; + let signature_as_hex = "E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28".to_string(); + let message = "test 1234".to_string(); + + let public_key = PublicKey::from_json(json_public_key).unwrap(); + let public_key_bytes = public_key.to_bytes(); + + let result = secp256k1_verify_with_public_key(&public_key_bytes, signature_as_hex, message); + + assert!(result.is_ok()); + } + + #[test] + fn test_verify_with_json_public_key_with_invalid_signature() { + let json_public_key = r#"{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4FdhUMasPmNhRZjtpKlmjNbq7EEUgPxfdI+E3vSajvc"}"#; + let signature_as_hex = "E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28".to_string(); + let message = "abcdef".to_string(); + + let public_key = PublicKey::from_json(json_public_key).unwrap(); + let public_key_bytes = public_key.to_bytes(); + + let result = secp256k1_verify_with_public_key(&public_key_bytes, signature_as_hex, message); + + assert!(result.is_err()); + } + + #[test] + fn test_valid_json_public_key_succeeds() { + let json_public_key = r#"{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4FdhUMasPmNhRZjtpKlmjNbq7EEUgPxfdI+E3vSajvc"}"#.to_string(); + let signature_as_hex = "E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28".to_string(); + let message = "test 1234".to_string(); + + let result = + secp256k1_verify_with_public_key_json(json_public_key, signature_as_hex, message); + + assert!(result.is_ok()); + } + + #[test] + fn test_json_public_key_fails_with_error() { + let bad_json_public_key = r#"This is not JSON ☠️"#.to_string(); + let signature_as_hex = "E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28".to_string(); + let message = "abcdef".to_string(); + + let result = + secp256k1_verify_with_public_key_json(bad_json_public_key, signature_as_hex, message); + + assert!(result.is_err()); + } +} diff --git a/common/commands/src/validator/signature/mod.rs b/common/commands/src/validator/signature/mod.rs new file mode 100644 index 0000000000..3782e977f4 --- /dev/null +++ b/common/commands/src/validator/signature/mod.rs @@ -0,0 +1,24 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod errors; +pub mod helpers; +pub mod sign; +pub mod verify; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Signature { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum SignatureCommands { + /// Sign a message + Sign(crate::validator::signature::sign::Args), + /// Verify a message + Verify(crate::validator::signature::verify::Args), +} diff --git a/common/commands/src/validator/signature/sign.rs b/common/commands/src/validator/signature/sign.rs new file mode 100644 index 0000000000..d26302aeba --- /dev/null +++ b/common/commands/src/validator/signature/sign.rs @@ -0,0 +1,68 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils::show_error; +use clap::Parser; +use cosmrs::crypto::PublicKey; +use log::error; +use serde::Serialize; +use serde_json::json; +use validator_client::nymd::wallet::DirectSecp256k1HdWallet; + +#[derive(Debug, Serialize)] +pub struct SignatureOutputJson { + pub account_id: String, + pub public_key: PublicKey, + pub signature: String, +} + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The message to sign")] + pub message: String, +} + +pub fn sign(args: Args, prefix: &str, mnemonic: Option) { + if args.message.trim().is_empty() { + error!("Message is empty or contains only whitespace"); + return; + } + + if mnemonic.is_none() { + error!( + "Please provide the mnemonic as an argument or using the MNEMONIC environment variable" + ); + return; + } + + match DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.expect("mnemonic not set")) { + Ok(wallet) => match wallet.try_derive_accounts() { + Ok(accounts) => match accounts.first() { + Some(account) => { + let msg = args.message.into_bytes(); + match wallet.sign_raw_with_account(account, &msg) { + Ok(signature) => { + let output = SignatureOutputJson { + account_id: account.address().to_string(), + public_key: account.public_key(), + signature: signature.to_string(), + }; + println!("{}", json!(output)); + } + Err(e) => { + error!("Failed to sign message. {}", e); + } + } + } + None => { + error!("Could not derive an account key from the mnemonic",) + } + }, + Err(e) => { + error!("Failed to derive accounts. {}", e); + } + }, + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/signature/verify.rs b/common/commands/src/validator/signature/verify.rs new file mode 100644 index 0000000000..b29f93ca9a --- /dev/null +++ b/common/commands/src/validator/signature/verify.rs @@ -0,0 +1,89 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::str::FromStr; + +use clap::Parser; +use cosmrs::crypto::PublicKey; +use log::{error, info}; +use serde_json::json; + +use validator_client::nymd::AccountId; + +use crate::context::QueryClient; +use crate::validator::signature::helpers::secp256k1_verify_with_public_key; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap( + help = "The public key of the account, or the account id to query for a public key (NOTE: the account must have signed a message stored on the chain for the public key record to exist)" + )] + pub public_key_or_address: String, + + #[clap(value_parser)] + #[clap(help = "The signature to verify as hex")] + pub signature_as_hex: String, + + #[clap(value_parser)] + #[clap(help = "The message to verify as a string")] + pub message: String, +} + +pub async fn verify(args: Args, client: &QueryClient) { + if args.public_key_or_address.trim().is_empty() { + error!("Please ensure the public key or address is not empty or whitespace"); + return; + } + + let public_key = match AccountId::from_str(&args.public_key_or_address) { + Ok(address) => { + info!("Found account address instead of public key, so looking up public key for {} from chain", address); + match client.get_account_public_key(&address).await.ok() { + Some(public_key) => { + if let Some(k) = public_key { + info!("Found public key {}", json!(k)); + } + public_key + } + None => { + error!( + "Address {} does not have a public key recorded on the chain. This is probably because the account has never signed a transaction.", + address + ); + None + } + } + } + Err(_) => match PublicKey::from_json(&args.public_key_or_address) { + Ok(parsed) => Some(parsed), + Err(e) => { + error!("Public key should be JSON. Unable to parse: {}", e); + None + } + }, + }; + + match public_key { + Some(public_key) => { + if public_key.type_url() != PublicKey::SECP256K1_TYPE_URL { + error!("Sorry, we only support secp256k1 public keys at the moment"); + return; + } + + match secp256k1_verify_with_public_key( + &public_key.to_bytes(), + args.signature_as_hex, + args.message, + ) { + Ok(()) => println!("SUCCESS ✅ signature verified"), + Err(e) => { + error!("FAILURE ❌ Signature verification failed: {}", e); + } + } + } + None => { + error!("Unable to verify, as unable to get the public key"); + } + } +} diff --git a/common/commands/src/validator/transactions/get_transaction.rs b/common/commands/src/validator/transactions/get_transaction.rs new file mode 100644 index 0000000000..3d1b53e7b2 --- /dev/null +++ b/common/commands/src/validator/transactions/get_transaction.rs @@ -0,0 +1,28 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use std::str::FromStr; + +use crate::context::QueryClient; +use crate::utils::show_error; +use cosmrs::tx::Hash; +use serde_json::json; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The transaction hash")] + pub tx_hash: String, +} + +pub async fn get(args: Args, client: &QueryClient) { + let hash = Hash::from_str(&args.tx_hash).expect("could not parse transaction hash"); + + match client.get_tx(hash).await { + Ok(res) => { + println!("{}", json!(res)) + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/transactions/mod.rs b/common/commands/src/validator/transactions/mod.rs new file mode 100644 index 0000000000..d78cdf07b0 --- /dev/null +++ b/common/commands/src/validator/transactions/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod get_transaction; +pub mod query_transactions; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct Transactions { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum TransactionsCommands { + /// Get a transaction by hash or block height + Get(crate::validator::transactions::get_transaction::Args), + /// Query for transactions + Query(crate::validator::transactions::query_transactions::Args), +} diff --git a/common/commands/src/validator/transactions/query_transactions.rs b/common/commands/src/validator/transactions/query_transactions.rs new file mode 100644 index 0000000000..b8b341ec57 --- /dev/null +++ b/common/commands/src/validator/transactions/query_transactions.rs @@ -0,0 +1,30 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::str::FromStr; + +use clap::Parser; +use cosmrs::rpc::query::Query; +use serde_json::json; + +use crate::context::QueryClient; +use crate::utils::show_error; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "The query to execute")] + pub query: String, +} + +pub async fn query(args: Args, client: &QueryClient) { + match Query::from_str(&args.query) { + Ok(query) => match client.search_tx(query).await { + Ok(res) => { + println!("{}", json!(res)) + } + Err(e) => show_error(e), + }, + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/vesting/balance.rs b/common/commands/src/validator/vesting/balance.rs new file mode 100644 index 0000000000..45b2f7866d --- /dev/null +++ b/common/commands/src/validator/vesting/balance.rs @@ -0,0 +1,55 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use cosmrs::AccountId; +use log::info; + +use validator_client::nymd::{Coin, VestingQueryClient}; + +use crate::context::SigningClient; +use crate::utils::show_error; +use crate::utils::{pretty_coin, pretty_cosmwasm_coin}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "Optionally, the account address to get the balance for")] + pub address: Option, +} + +pub async fn balance(args: Args, client: SigningClient) { + let account_id = args.address.unwrap_or_else(|| client.address().clone()); + let vesting_address = account_id.to_string(); + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!( + "Getting vesting schedule information for {}...", + &vesting_address + ); + + let original_vesting = client.original_vesting(&vesting_address).await; + + match original_vesting { + Ok(res) => { + let spendable_coins = client + .spendable_coins(&vesting_address, None) + .await + .unwrap_or_else(|_| Coin::new(0u128, denom)); + let liquid_account_balance = client + .get_balance(&account_id, denom.to_string()) + .await + .unwrap_or(None) + .unwrap_or_else(|| Coin::new(0u128, denom)); + + println!( + "Account {} has\n{} vested with\n{} available to be withdrawn to the main account (balance {})", + &account_id, + pretty_cosmwasm_coin(&res.amount), + pretty_coin(&spendable_coins), + pretty_coin(&liquid_account_balance), + ); + } + Err(e) => show_error(e), + } +} diff --git a/common/commands/src/validator/vesting/create_vesting_schedule.rs b/common/commands/src/validator/vesting/create_vesting_schedule.rs new file mode 100644 index 0000000000..60f69e6f2b --- /dev/null +++ b/common/commands/src/validator/vesting/create_vesting_schedule.rs @@ -0,0 +1,83 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::str::FromStr; + +use clap::Parser; +use log::info; + +use mixnet_contract_common::Coin; +use network_defaults::NymNetworkDetails; +use validator_client::nymd::AccountId; +use validator_client::nymd::VestingSigningClient; +use validator_client::nymd::{CosmosCoin, Denom}; +use vesting_contract_common::messages::VestingSpecification; + +use crate::context::SigningClient; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub periods_seconds: Option, + + #[clap(long)] + pub number_of_periods: Option, + + #[clap(long)] + pub start_time: Option, + + #[clap(long)] + pub address: String, + + #[clap(long)] + pub amount: u64, + + #[clap(long)] + pub staking_address: Option, +} + +pub async fn create(args: Args, client: SigningClient, network_details: &NymNetworkDetails) { + info!("Creating vesting schedule!"); + + let vesting = VestingSpecification::new( + args.start_time, + args.periods_seconds, + args.number_of_periods, + ); + + let denom = network_details.chain_details.mix_denom.base.to_string(); + + let coin = Coin::new(args.amount.into(), &denom); + + let res = client + .create_periodic_vesting_account( + &*args.address, + args.staking_address, + Some(vesting), + coin.into(), + None, + ) + .await + .expect("creating vesting schedule for the user!"); + + //send 1 coin + let coin_amount: u64 = 1_000_000; + + let coin = CosmosCoin { + denom: Denom::from_str(&denom).unwrap(), + amount: coin_amount.into(), + }; + + let send_coin_response = client + .send( + &AccountId::from_str(&*args.address).unwrap(), + vec![coin.into()], + "payment made :)", + None, + ) + .await + .unwrap(); + + info!("Vesting result: {:?}", res); + info!("Coin send result: {:?}", send_coin_response); +} diff --git a/common/commands/src/validator/vesting/mod.rs b/common/commands/src/validator/vesting/mod.rs new file mode 100644 index 0000000000..807ba08438 --- /dev/null +++ b/common/commands/src/validator/vesting/mod.rs @@ -0,0 +1,28 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{Args, Subcommand}; + +pub mod balance; +pub mod create_vesting_schedule; +pub mod query_vesting_schedule; +pub mod withdraw_vested; + +#[derive(Debug, Args)] +#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)] +pub struct VestingSchedule { + #[clap(subcommand)] + pub command: Option, +} + +#[derive(Debug, Subcommand)] +pub enum VestingScheduleCommands { + /// Creates a vesting schedule + Create(crate::validator::vesting::create_vesting_schedule::Args), + /// Query for vesting schedule + Query(crate::validator::vesting::query_vesting_schedule::Args), + /// Get the amount that has vested and is free for withdrawal, delegation or bonding + VestedBalance(crate::validator::vesting::balance::Args), + /// Withdraw vested tokens (note: the available amount excludes anything delegated or bonded before or after vesting) + WithdrawVested(crate::validator::vesting::withdraw_vested::Args), +} diff --git a/common/commands/src/validator/vesting/query_vesting_schedule.rs b/common/commands/src/validator/vesting/query_vesting_schedule.rs new file mode 100644 index 0000000000..23118c1bf5 --- /dev/null +++ b/common/commands/src/validator/vesting/query_vesting_schedule.rs @@ -0,0 +1,149 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use cosmrs::AccountId; +use cosmwasm_std::Coin as CosmWasmCoin; +use log::info; + +use validator_client::nymd::{Coin, VestingQueryClient}; + +use crate::context::SigningClient; +use crate::utils::show_error; +use crate::utils::{pretty_coin, pretty_cosmwasm_coin}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "Optionally, the account address to get the balance for")] + pub address: Option, +} + +pub async fn query(args: Args, client: SigningClient) { + let account_id = args.address.unwrap_or_else(|| client.address().clone()); + let vesting_address = account_id.to_string(); + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!( + "Getting vesting schedule information for {}...", + &vesting_address + ); + + let liquid_account_balance = client + .get_balance(&account_id, denom.to_string()) + .await + .unwrap_or(None) + .unwrap_or_else(|| Coin::new(0u128, denom)); + let original_vesting = client.original_vesting(&vesting_address).await; + let start_time = client.vesting_start_time(&vesting_address).await; + let end_time = client.vesting_end_time(&vesting_address).await; + let vested_coins = client.vested_coins(&vesting_address, None).await; + let spendable_coins = client.spendable_coins(&vesting_address, None).await; + let locked_coins = client.locked_coins(&vesting_address, None).await; + + // TODO: get better copy text for what these are + let vesting_coins = client.vesting_coins(&vesting_address, None).await; + let delegated_vesting = client.delegated_vesting(&vesting_address, None).await; + let delegated_free = client.delegated_free(&vesting_address, None).await; + + original_vesting.as_ref().map_or_else(show_error, |res| { + println!( + "Amount: {} ({})", + pretty_cosmwasm_coin(&res.amount), + res.amount + ); + println!("No of periods: {}", res.number_of_periods); + println!( + "Duration each: {}", + time::Duration::seconds(res.period_duration as i64) + ); + }); + + start_time.as_ref().map_or_else(show_error, |res| { + println!( + "Start date: {}", + time::OffsetDateTime::from_unix_timestamp(res.seconds() as i64) + .expect("unable to parse vesting start timestamp") + .date() + ); + }); + + end_time.map_or_else(show_error, |res| { + println!( + "End date: {}", + time::OffsetDateTime::from_unix_timestamp(res.seconds() as i64) + .expect("unable to parse vesting end timestamp") + .date() + ); + }); + + vested_coins.map_or_else(show_error, |res| { + println!("Vested balance: {} ({})", pretty_coin(&res), res); + }); + + if let Ok(res) = original_vesting { + if let Ok(start) = start_time { + let amount_in_each_period = res.amount.amount.u128() / res.number_of_periods as u128; + let coin_in_each_period = CosmWasmCoin::new(amount_in_each_period, denom); + println!(); + println!("Vesting schedule:"); + for period in 1..(res.number_of_periods as u64 + 1) { + let date = time::OffsetDateTime::from_unix_timestamp( + (start.seconds() + period * res.period_duration) as i64, + ) + .expect("unable to parse vesting start timestamp") + .date(); + let amount_in_vested = + period as u128 * res.amount.amount.u128() / res.number_of_periods as u128; + let coin_in_vested = CosmWasmCoin::new(amount_in_vested, denom); + println!( + "{}. {} {} => {}", + period, + date, + pretty_cosmwasm_coin(&coin_in_each_period), + pretty_cosmwasm_coin(&coin_in_vested), + ); + } + } + } + + spendable_coins.map_or_else(show_error, |res| { + println!(); + println!("This account has the following vested tokens available either to be withdrawn to the main account, or to be delegated:"); + println!("Spendable coins: {} ({})", pretty_coin(&res), res); + }); + + locked_coins.map_or_else(show_error, |res| { + println!(); + if res.amount > 0 { + println!("This account has delegated more than the current cap, so the following balance is unavailable for bonding or delegation:"); + println!("Locked balance: {} ({})", pretty_coin(&res), res); + } else { + println!("This account is not capped and can use the spendable balance for bonding or delegations:"); + println!("Locked balance: {} ({})", pretty_coin(&res), res); + } + }); + + println!(); + println!("The following are shown for information (more help text will follow soon):"); + vesting_coins.map_or_else(show_error, |res| { + println!("Vesting coins: {} ({})", pretty_coin(&res), res); + }); + delegated_vesting.map_or_else(show_error, |res| { + println!("Delegated vesting: {} ({})", pretty_coin(&res), res); + }); + delegated_free.map_or_else(show_error, |res| { + println!("Delegation free: {} ({})", pretty_coin(&res), res); + }); + + println!(); + println!( + "The main account {} also has a regular balance of:", + &account_id + ); + println!( + "{} ({})", + pretty_coin(&liquid_account_balance), + &liquid_account_balance + ); +} diff --git a/common/commands/src/validator/vesting/withdraw_vested.rs b/common/commands/src/validator/vesting/withdraw_vested.rs new file mode 100644 index 0000000000..972c5290d9 --- /dev/null +++ b/common/commands/src/validator/vesting/withdraw_vested.rs @@ -0,0 +1,112 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::Parser; +use log::info; + +use validator_client::nymd::{Coin, VestingQueryClient, VestingSigningClient}; + +use crate::context::SigningClient; +use crate::utils::show_error; +use crate::utils::{pretty_coin, pretty_cosmwasm_coin}; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(value_parser)] + #[clap(help = "Amount to transfer in micro denomination (e.g. unym or unyx)")] + pub amount: u128, +} + +pub async fn execute(args: Args, client: SigningClient) { + let account_id = client.address(); + let vesting_address = account_id.to_string(); + let denom = client.current_chain_details().mix_denom.base.as_str(); + + info!( + "Getting vesting schedule information for {}...", + &vesting_address + ); + + let original_vesting = client.original_vesting(&vesting_address).await; + + match original_vesting { + Ok(res) => { + let spendable_coins = client + .spendable_coins(&vesting_address, None) + .await + .unwrap_or_else(|_| Coin::new(0u128, denom)); + let liquid_account_balance = client + .get_balance(account_id, denom.to_string()) + .await + .unwrap_or(None) + .unwrap_or_else(|| Coin::new(0u128, denom)); + + println!( + "Account {} has\n{} vested with {} available to be withdrawn to the main account (balance {})", + &account_id, + pretty_cosmwasm_coin(&res.amount), + pretty_coin(&spendable_coins), + pretty_coin(&liquid_account_balance), + ); + println!(); + + // execute withdraw + + let amount = Coin { + amount: args.amount, + denom: denom.to_string(), + }; + + info!( + "Withdrawing {} ({}) from {}...", + pretty_coin(&amount), + &amount, + &account_id + ); + + match client.withdraw_vested_coins(amount, None).await { + Ok(res) => { + println!(); + println!("SUCCESS ✅"); + println!( + "Nodesguru: https://nym.explorers.guru/transaction/{}", + &res.transaction_hash + ); + println!( + "Mintscan: https://www.mintscan.io/nyx/txs/{}", + &res.transaction_hash + ); + println!("Transaction hash: {}", &res.transaction_hash); + println!("Gas used: {}", &res.gas_info.gas_used); + println!(); + } + Err(e) => show_error(e), + } + + // query for balances again + let res = client + .original_vesting(&vesting_address) + .await + .expect("vesting account does not exist"); + let spendable_coins = client + .spendable_coins(&vesting_address, None) + .await + .unwrap_or_else(|_| Coin::new(0u128, denom)); + + let liquid_account_balance = client + .get_balance(account_id, denom.to_string()) + .await + .unwrap_or(None) + .unwrap_or_else(|| Coin::new(0u128, denom)); + + println!( + "After withdrawal, account {} has\n{} vested with {} available to be withdrawn to the main account (balance {})", + &account_id, + pretty_cosmwasm_coin(&res.amount), + pretty_coin(&spendable_coins), + pretty_coin(&liquid_account_balance), + ); + } + Err(e) => show_error(e), + } +} diff --git a/common/network-defaults/envs/mainnet.env b/common/network-defaults/envs/mainnet.env new file mode 100644 index 0000000000..dce1c3c9c0 --- /dev/null +++ b/common/network-defaults/envs/mainnet.env @@ -0,0 +1,20 @@ +CONFIGURED=true + +RUST_LOG=info +RUST_BACKTRACE=1 + +BECH32_PREFIX=n +MIX_DENOM=unym +MIX_DENOM_DISPLAY=nym +STAKE_DENOM=unyx +STAKE_DENOM_DISPLAY=nyx +DENOMS_EXPONENT=6 +MIXNET_CONTRACT_ADDRESS=n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g +VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw +BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 +COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 +MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 +REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy +STATISTICS_SERVICE_DOMAIN_ADDRESS="http://127.0.0.1:8090" +NYMD_VALIDATOR="https://rpc.nyx.nodes.guru/" +API_VALIDATOR="https://validator.nymtech.net/api/" diff --git a/common/network-defaults/envs/qa.env b/common/network-defaults/envs/qa.env new file mode 100644 index 0000000000..842fb54c4d --- /dev/null +++ b/common/network-defaults/envs/qa.env @@ -0,0 +1,20 @@ +CONFIGURED=true + +RUST_LOG=info +RUST_BACKTRACE=1 + +BECH32_PREFIX=n +MIX_DENOM=unym +MIX_DENOM_DISPLAY=nym +STAKE_DENOM=unyx +STAKE_DENOM_DISPLAY=nyx +DENOMS_EXPONENT=6 +MIXNET_CONTRACT_ADDRESS=n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep +VESTING_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav +BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 +COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1ghd753shjuwexxywmgs4xz7x2q732vcn7ty4yw +MULTISIG_CONTRACT_ADDRESS=n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs +REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq +STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" +NYMD_VALIDATOR="https://qa-validator.nymtech.net" +API_VALIDATOR="https://qa-validator-api.nymtech.net/api" diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..00ba21ad4a --- /dev/null +++ b/examples/README.md @@ -0,0 +1,9 @@ +# Examples + +This directory contains examples of using the libraries in this repo: + +### CLI + +#### CLI Commands + +- [Use an account public key to verify a signature](./cli/commands/verify-signature) \ No newline at end of file diff --git a/tools/Cargo.lock b/examples/cli/commands/verify-signature/Cargo.lock similarity index 82% rename from tools/Cargo.lock rename to examples/cli/commands/verify-signature/Cargo.lock index d32be85ea2..176da87bee 100644 --- a/tools/Cargo.lock +++ b/examples/cli/commands/verify-signature/Cargo.lock @@ -16,15 +16,15 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] name = "async-trait" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" dependencies = [ "proc-macro2", "quote", @@ -59,9 +59,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "az" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f771a5d1f5503f7f4279a30f3643d3421ba149848b89ecaaec0ea2acf04a5ac4" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" [[package]] name = "base16ct" @@ -77,9 +77,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" +checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" [[package]] name = "bip32" @@ -124,26 +124,14 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding 0.1.5", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", - "generic-array 0.14.5", + "block-padding", + "generic-array", ] [[package]] @@ -152,16 +140,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ - "generic-array 0.14.5", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "generic-array", ] [[package]] @@ -195,21 +174,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "byteorder" @@ -219,9 +192,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" @@ -235,6 +208,45 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "3.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -244,9 +256,21 @@ dependencies = [ "bitflags", ] +[[package]] +name = "coconut-bandwidth-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" +dependencies = [ + "cosmwasm-std", + "multisig-contract-common", + "schemars", + "serde", +] + [[package]] name = "coconut-interface" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "bs58", "getset", @@ -269,6 +293,7 @@ dependencies = [ [[package]] name = "config" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "cfg-if", "handlebars", @@ -289,6 +314,7 @@ checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "contracts-common" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "cosmwasm-std", ] @@ -311,8 +337,8 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cosmos-sdk-proto" -version = "0.9.0" -source = "git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation#911fbe1236cfed591783ccef01018f7ccc97c496" +version = "0.12.3" +source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" dependencies = [ "prost", "prost-types", @@ -321,14 +347,14 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.4.1" -source = "git+https://github.com/nymtech/cosmos-rust?branch=bugfix/account-id-length-validation#911fbe1236cfed591783ccef01018f7ccc97c496" +version = "0.7.1" +source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" dependencies = [ "bip32", "cosmos-sdk-proto", "ecdsa", "eyre", - "getrandom 0.2.6", + "getrandom 0.2.7", "k256", "prost", "prost-types", @@ -382,9 +408,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" dependencies = [ "libc", ] @@ -410,7 +436,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ - "generic-array 0.14.5", + "generic-array", "rand_core 0.6.3", "subtle", "zeroize", @@ -418,11 +444,11 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.5", + "generic-array", "typenum", ] @@ -432,7 +458,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.5", + "generic-array", "subtle", ] @@ -447,9 +473,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" dependencies = [ "byteorder", "digest 0.9.0", @@ -460,15 +486,51 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" +checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" dependencies = [ "cosmwasm-std", "schemars", "serde", ] +[[package]] +name = "cw-utils" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +dependencies = [ + "cosmwasm-std", + "cw-utils", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + [[package]] name = "der" version = "0.5.1" @@ -478,22 +540,13 @@ dependencies = [ "const-oid", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.5", + "generic-array", ] [[package]] @@ -507,10 +560,16 @@ dependencies = [ ] [[package]] -name = "dyn-clone" -version = "1.0.5" +name = "dotenv" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dyn-clone" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" [[package]] name = "ecdsa" @@ -562,9 +621,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "elliptic-curve" @@ -576,7 +635,7 @@ dependencies = [ "crypto-bigint", "der", "ff 0.11.1", - "generic-array 0.14.5", + "generic-array", "group 0.11.0", "rand_core 0.6.3", "sec1", @@ -593,6 +652,22 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "example-verify-signature" +version = "0.1.0" +dependencies = [ + "nym-cli-commands", +] + +[[package]] +name = "execute" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "eyre" version = "0.6.8" @@ -603,17 +678,11 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -640,9 +709,9 @@ dependencies = [ [[package]] name = "fixed" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a65312835c1097a0c926ff3702df965285fadc33d948b87397ff8961bad881" +checksum = "ec8c4fbf8cd36f2a96740c31320902abbf0acbd733049b758707d842490c98c4" dependencies = [ "az", "bytemuck", @@ -653,13 +722,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -718,9 +785,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" dependencies = [ "futures-channel", "futures-core", @@ -733,9 +800,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" dependencies = [ "futures-core", "futures-sink", @@ -743,15 +810,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" dependencies = [ "futures-core", "futures-task", @@ -760,15 +827,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" dependencies = [ "proc-macro2", "quote", @@ -777,21 +844,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ "futures-channel", "futures-core", @@ -807,18 +874,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.12.4" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -837,14 +895,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -885,9 +943,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -904,9 +962,12 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +dependencies = [ + "crunchy", +] [[package]] name = "handlebars" @@ -924,9 +985,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "headers" @@ -941,7 +1002,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha-1 0.10.0", + "sha-1", ] [[package]] @@ -955,12 +1016,9 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -995,9 +1053,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -1045,9 +1103,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.18" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -1078,11 +1136,12 @@ dependencies = [ "headers", "http", "hyper", - "hyper-tls", - "native-tls", + "hyper-rustls", + "rustls-native-certs", "tokio", - "tokio-native-tls", + "tokio-rustls", "tower-service", + "webpki", ] [[package]] @@ -1135,9 +1194,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg 1.1.0", "hashbrown", @@ -1170,15 +1229,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -1211,9 +1270,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "log" @@ -1224,12 +1283,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matches" version = "0.1.9" @@ -1256,18 +1309,18 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", @@ -1278,13 +1331,13 @@ dependencies = [ [[package]] name = "mixnet-contract-common" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "az", "contracts-common", "cosmwasm-std", "fixed", "log", - "network-defaults", "schemars", "serde", "serde_repr", @@ -1293,6 +1346,19 @@ dependencies = [ "ts-rs", ] +[[package]] +name = "multisig-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" +dependencies = [ + "cosmwasm-std", + "cw-utils", + "cw3", + "cw4", + "schemars", + "serde", +] + [[package]] name = "native-tls" version = "0.2.10" @@ -1314,8 +1380,10 @@ dependencies = [ [[package]] name = "network-defaults" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "cfg-if", + "dotenv", "hex-literal", "once_cell", "serde", @@ -1363,57 +1431,40 @@ dependencies = [ ] [[package]] -name = "nym-types" +name = "nym-cli-commands" version = "1.0.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ - "coconut-interface", - "config", + "bip39", + "cfg-if", + "clap", "cosmrs", - "cosmwasm-std", - "eyre", - "itertools", + "handlebars", + "humantime-serde", + "k256", "log", "mixnet-contract-common", - "reqwest", - "schemars", + "network-defaults", + "rand 0.6.5", "serde", "serde_json", - "strum", "thiserror", - "ts-rs", + "toml", "url", "validator-client", - "vesting-contract", - "vesting-contract-common", -] - -[[package]] -name = "nym-wallet-types" -version = "1.0.0" -dependencies = [ - "config", - "cosmrs", - "cosmwasm-std", - "mixnet-contract-common", - "nym-types", - "serde", - "serde_json", - "strum", - "ts-rs", - "validator-client", - "vesting-contract", "vesting-contract-common", ] [[package]] name = "nymcoconut" version = "0.5.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "bls12_381", "bs58", "digest 0.9.0", "ff 0.10.1", - "getrandom 0.2.6", + "getrandom 0.2.7", "group 0.10.0", "itertools", "rand 0.8.5", @@ -1425,15 +1476,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" [[package]] name = "opaque-debug" @@ -1443,9 +1488,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.40" +version = "0.10.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" dependencies = [ "bitflags", "cfg-if", @@ -1475,9 +1520,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.73" +version = "0.9.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" +checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" dependencies = [ "autocfg 1.1.0", "cc", @@ -1486,6 +1531,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + [[package]] name = "pairing" version = "0.20.0" @@ -1497,9 +1548,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" +checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" [[package]] name = "pbkdf2" @@ -1545,18 +1596,19 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pest" -version = "2.1.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4" dependencies = [ + "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91" dependencies = [ "pest", "pest_generator", @@ -1564,9 +1616,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.1.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad" dependencies = [ "pest", "pest_meta", @@ -1577,29 +1629,29 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.1.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04" dependencies = [ - "maplit", + "once_cell", "pest", - "sha-1 0.8.2", + "sha-1", ] [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -1667,18 +1719,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" dependencies = [ "bytes", "prost-derive", @@ -1686,9 +1738,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" dependencies = [ "anyhow", "itertools", @@ -1699,9 +1751,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" +checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" dependencies = [ "bytes", "prost", @@ -1715,9 +1767,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -1802,7 +1854,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.6", + "getrandom 0.2.7", ] [[package]] @@ -1878,9 +1930,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -1896,9 +1948,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" +checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" dependencies = [ "base64", "bytes", @@ -1923,6 +1975,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -1964,7 +2017,7 @@ checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" dependencies = [ "block-buffer 0.9.0", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -1992,17 +2045,11 @@ dependencies = [ "security-framework", ] -[[package]] -name = "rustversion" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -2065,7 +2112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", - "generic-array 0.14.5", + "generic-array", "pkcs8", "subtle", "zeroize", @@ -2073,9 +2120,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -2096,9 +2143,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -2114,18 +2161,18 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" +checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -2145,9 +2192,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -2156,9 +2203,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed" +checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" dependencies = [ "proc-macro2", "quote", @@ -2177,18 +2224,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha-1" version = "0.10.0" @@ -2210,7 +2245,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2222,7 +2257,7 @@ dependencies = [ "block-buffer 0.9.0", "digest 0.9.0", "keccak", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -2237,9 +2272,12 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "smallvec" @@ -2283,26 +2321,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "strum" -version = "0.23.0" +name = "strsim" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" @@ -2321,9 +2343,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.95" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -2358,9 +2380,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.3" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ef686b8ecd36550d0581f0989c9d8607090b23005df479d8e6ba348b5800b9" +checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" dependencies = [ "async-trait", "bytes", @@ -2389,9 +2411,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.3" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc127f82e7a8c7337c1f293d65a821380d3407c4c44bc979ef4da0ebc3b31ed" +checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" dependencies = [ "flex-error", "serde", @@ -2403,9 +2425,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.3" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e0a0251fd81bed7420bea0f4d91c2a58f6c9fa34d5b2f70bed0ba8890de5aa" +checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" dependencies = [ "bytes", "flex-error", @@ -2421,15 +2443,15 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.3" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626c493e9ced3a9de37583bbd929f4b6dbd49aa513ab9b4776aa44a9332ce9b5" +checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" dependencies = [ "async-trait", "bytes", "flex-error", "futures", - "getrandom 0.2.6", + "getrandom 0.2.7", "http", "hyper", "hyper-proxy", @@ -2462,19 +2484,25 @@ dependencies = [ ] [[package]] -name = "thiserror" -version = "1.0.31" +name = "textwrap" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + +[[package]] +name = "thiserror" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -2483,9 +2511,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" dependencies = [ "itoa", "libc", @@ -2501,10 +2529,11 @@ checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" [[package]] name = "tokio" -version = "1.18.2" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" dependencies = [ + "autocfg 1.1.0", "bytes", "libc", "memchr", @@ -2519,9 +2548,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", @@ -2551,9 +2580,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ "bytes", "futures-core", @@ -2574,40 +2603,28 @@ dependencies = [ [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -2618,34 +2635,19 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "ts-rs" -version = "6.1.2" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d26cba30c9b3a2f537f765cf754126f11c983b7426d280ae0b4cef2374cab98" +checksum = "dc59f479df54269b400dd95bc3b7e81623b3e4b9c70c8ca7125ab8341eafa64e" dependencies = [ "thiserror", "ts-rs-macros", ] -[[package]] -name = "ts-rs-cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "mixnet-contract-common", - "nym-types", - "nym-wallet-types", - "ts-rs", - "validator-api-requests", - "validator-client", - "vesting-contract-common", - "walkdir", -] - [[package]] name = "ts-rs-macros" -version = "6.1.2" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8e302fbcf5b60dfa1df443535967511442c5ce4eac8b4c9fa811f2274280a4" +checksum = "9f807fdb3151fee75df7485b901a89624358cd07a67a8fb1a5831bf5a07681ff" dependencies = [ "Inflector", "proc-macro2", @@ -2662,9 +2664,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" [[package]] name = "uint" @@ -2686,9 +2688,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-normalization" @@ -2699,12 +2701,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - [[package]] name = "unicode-xid" version = "0.2.3" @@ -2739,7 +2735,12 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "validator-api-requests" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ + "bs58", + "coconut-interface", + "cosmrs", + "getset", "mixnet-contract-common", "schemars", "serde", @@ -2749,20 +2750,25 @@ dependencies = [ [[package]] name = "validator-client" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "async-trait", "base64", "bip39", + "coconut-bandwidth-contract-common", "coconut-interface", "colored", "config", "cosmrs", "cosmwasm-std", + "cw3", + "execute", "flate2", "futures", "itertools", "log", "mixnet-contract-common", + "multisig-contract-common", "network-defaults", "prost", "reqwest", @@ -2771,7 +2777,6 @@ dependencies = [ "sha2", "thiserror", "tokio", - "ts-rs", "url", "validator-api-requests", "vesting-contract", @@ -2792,9 +2797,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vesting-contract" -version = "1.0.0" +version = "1.0.1" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ - "config", "cosmwasm-std", "cw-storage-plus", "mixnet-contract-common", @@ -2807,6 +2812,7 @@ dependencies = [ [[package]] name = "vesting-contract-common" version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=feature/nym-cli#4045541e461898c37872a9b75822d3ba84b9f98c" dependencies = [ "config", "cosmwasm-std", @@ -2844,12 +2850,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2858,9 +2858,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2868,13 +2868,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -2883,9 +2883,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if", "js-sys", @@ -2895,9 +2895,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2905,9 +2905,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -2918,15 +2918,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -3036,9 +3036,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.5" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" dependencies = [ "zeroize_derive", ] diff --git a/examples/cli/commands/verify-signature/Cargo.toml b/examples/cli/commands/verify-signature/Cargo.toml new file mode 100644 index 0000000000..5ad0673115 --- /dev/null +++ b/examples/cli/commands/verify-signature/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "example-verify-signature" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +nym-cli-commands = { git = "https://github.com/nymtech/nym", branch = "develop" } \ No newline at end of file diff --git a/examples/cli/commands/verify-signature/README.md b/examples/cli/commands/verify-signature/README.md new file mode 100644 index 0000000000..e32c0b558c --- /dev/null +++ b/examples/cli/commands/verify-signature/README.md @@ -0,0 +1,38 @@ +# Example code to verify a signature + +This is an example app that shows how to verify a signature signed by an account key. + +Inputs to the app are: + +- **signature** - bytes represented as a hex string +- **public key** - in JSON format (you can query any Cosmos chain for account's public key as JSON, however it will need to have sent a signed transaction to the chain for this to be present) +- **message** - the string message to verify + +## Running locally + +Run the example by changning to this directory and running: + +``` +cargo run +``` + +And you should see the output: + +``` +Nym signature verification example + + +public key: {"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4FdhUMasPmNhRZjtpKlmjNbq7EEUgPxfdI+E3vSajvc"} +signature: E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28 +message: test 1234 + + +Verify the correct message: + +SUCCESS ✅ signature is valid + + +Verify another message: + +FAILURE ❌ signature is not valid: signature error +``` \ No newline at end of file diff --git a/examples/cli/commands/verify-signature/src/main.rs b/examples/cli/commands/verify-signature/src/main.rs new file mode 100644 index 0000000000..28f47ca4a4 --- /dev/null +++ b/examples/cli/commands/verify-signature/src/main.rs @@ -0,0 +1,43 @@ +use nym_cli_commands::validator::signature::helpers::secp256k1_verify_with_public_key_json; + +fn main() { + println!("\nNym signature verification example\n\n"); + + // the public key in JSON format (because Cosmos supports secp256k1 and ed25519 - NB: the helper only supports secp256k1) + let public_key_as_json = r#"{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A4FdhUMasPmNhRZjtpKlmjNbq7EEUgPxfdI+E3vSajvc"}"#; + + // the signature as a string of hex characters to represent the bytes in the signature + let signature_as_hex = "E3AA5AC0DA1B7DEBB7808000F719D8ACB9A0BE10AFA2756A788516268EB246A1257EC1097C5E364EF916145B01641DEDFE955994CB340BDAFA99A65BCA3F6F28"; + + // the original message as a string to verify + let message = "test 1234".to_string(); + + println!("public key: {}", &public_key_as_json); + println!("signature: {}", &signature_as_hex); + println!("message: {}", &message); + + println!(); + + // this will pass, because the signature was signed for this message + println!("\nVerify the correct message:\n"); + do_verify( + public_key_as_json.to_string(), + signature_as_hex.to_string(), + message, + ); + + // this will fail, because the signature is for another message + println!("\n\nVerify another message:\n"); + do_verify( + public_key_as_json.to_string(), + signature_as_hex.to_string(), + "another message that will fail".to_string(), + ); +} + +fn do_verify(public_key_as_json: String, signature_as_hex: String, message: String) { + match secp256k1_verify_with_public_key_json(public_key_as_json, signature_as_hex, message) { + Ok(()) => println!("SUCCESS ✅ signature is valid"), + Err(e) => println!("FAILURE ❌ signature is not valid: {}", e), + } +} diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 1e808758c8..d6bf186f83 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -5227,6 +5227,7 @@ version = "0.1.0" dependencies = [ "nymsphinx-addressing", "ordered-buffer", + "thiserror", ] [[package]] diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml new file mode 100644 index 0000000000..fe7a243f85 --- /dev/null +++ b/tools/nym-cli/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "nym-cli" +version = "1.0.0" +authors = ["Nym Technologies SA"] +edition = "2021" + +[dependencies] +base64 = "0.13.0" +bs58 = "0.4" +clap = { version = "3.2.8", features = ["derive"] } +clap_complete = "3.2.4" +clap_complete_fig = "3.2.4" +dotenv = "0.15.0" +log = "0.4" +pretty_env_logger = "0.4" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +tokio = { version = "1.11", features = [ "net", "rt-multi-thread", "macros", "signal"] } +bip39 = "1.0.1" +anyhow = "1" + +nym-cli-commands = { path = "../../common/commands" } +validator-client = { path = "../../common/client-libs/validator-client", features = ["nymd-client"] } +network-defaults = { path = "../../common/network-defaults" } diff --git a/tools/nym-cli/Makefile b/tools/nym-cli/Makefile new file mode 100644 index 0000000000..1d79365de9 --- /dev/null +++ b/tools/nym-cli/Makefile @@ -0,0 +1,3 @@ +generate-user-docs: + cargo build --release + ../../target/release/nym-cli generate-fig > user-docs/fig-spec.ts diff --git a/tools/nym-cli/README.md b/tools/nym-cli/README.md new file mode 100644 index 0000000000..415e500564 --- /dev/null +++ b/tools/nym-cli/README.md @@ -0,0 +1,139 @@ +# Nym CLI + +This is a CLI tool for interacting with: + +- the Nyx blockchain +- the smart contracts for the Mixnet + +It provides a convenient wrapper around the [`nymd client`](../../common/client-libs) with similar functionality to the`nyxd` binary for querying the chain or executing smart contract methods. + +And in the future it will provide an easy way to interact with Coconut, to issue and verify Coconut credenitals. + +### It DOES NOT do these things: + +The infrastructure components that run a [`gateway`](../../gateway), [`mixnode`](../../mixnode) or Service Provider have their own binaries. + +The [`socks5`](../../common/socks5) client also has its own binary, or use [NymConnect](../../nym-connect). + +# Installing + +Download the CLI binary for your platform from https://nymtech.net/downloads or get a specific version from [GitHub releases](https://github.com/nymtech/nym/releases?q=nym-cli&expanded=true). + +# Configuration + +The Nym CLI runs against mainnet by default. + +If you want to use another environment, you can do this by: +- providing a `.env` file +- setting environment variables ([see here for options](../../common/network-defaults/envs/mainnet.env)) +- passing named arguments + +### `.env` File + +There are two ways to provide this: + +1. A file called `.env` in the same directory as the binary +2. Pass the `--config-env-file` along with a command + +### Passing named arguments + +You will need to pass the following with every command as an argument: + +``` +--mnemonic +--nymd-url +--mixnet-contract +--vesting-contract +``` + +# How do I use it? + +The simplest way to find out how to use the CLI is to explore the built-in help: + +``` +nym-cli --help +``` + +# Features + +### 🏦 Account + +- create a new account with a random mnemonic +- query the account balance +- query the account public key (needed to verify signatures) +- query for transactions originating from the account +- send tokens to another account + +### ⛓ Block + +- query for the current block height +- query for a block at a height +- query for a block at a timestamp + +### 🪐 `cosmwasm` + +- upload a smart contract +- instantiate a smart contract +- upgrade a smart contract +- execute a smart contract method + +### 𐄳 Mixnet + +#### 📒 Directory + +- query for mixnodes +- query for gateways + +#### 🧑‍🔧 Operators + +- bond/unbond a mixnode or gateway +- query for waiting rewards +- withdraw rewards +- manage mixnode settings + +#### 🥩 Delegators + +- delegate/undelegate to a mixnode +- query for waiting rewards +- withdraw rewards + +### ✍ Sign + +- create a signature for string data (UTF-8) +- verify a signature for an account + +### 🕓 Vesting +- create a vesting schedule +- query for a vesting schedule + +### 🥥 Coconut + +Coming soon, including: + +- issue credential +- verify credential + +# Building + +Build the tool locally by running the following in this directory: + +``` +cargo build --release +``` + +# Generating user docs + +There is a [Makefile](./Makefile) with a target to build the user docs: + +``` +make generate-user-docs +``` + +Build the tool and run the `generate` command: + +``` +cargo build --release +../../target/release/nym-cli generate-fig > user-docs/fig-spec.ts +``` + +See https://github.com/withfig/autocomplete-tools/tree/main/types. \ No newline at end of file diff --git a/tools/nym-cli/src/completion.rs b/tools/nym-cli/src/completion.rs new file mode 100644 index 0000000000..27dedb0318 --- /dev/null +++ b/tools/nym-cli/src/completion.rs @@ -0,0 +1,10 @@ +use clap::Command; +use clap_complete::generate; +use clap_complete_fig::Fig; + +use std::io; + +/// Generates a file with a Typescript export of type Fig.Spec (use https://www.npmjs.com/package/@withfig/autocomplete-tools for typings) +pub(crate) fn print_fig(cmd: &mut Command) { + generate(Fig, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} diff --git a/tools/nym-cli/src/main.rs b/tools/nym-cli/src/main.rs new file mode 100644 index 0000000000..842229b15e --- /dev/null +++ b/tools/nym-cli/src/main.rs @@ -0,0 +1,168 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use clap::{CommandFactory, Parser, Subcommand}; +use log::{error, warn}; + +use nym_cli_commands::context::{get_network_details, ClientArgs}; +use validator_client::nymd::AccountId; + +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, + + #[clap(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, + + #[clap(long, global = true)] + #[clap( + help = "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file" + )] + pub(crate) nymd_url: Option, + + #[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) validator_api_url: Option, + + #[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, + + #[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, + + #[clap(subcommand)] + command: Commands, +} + +#[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), + /// 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 { + nymd_url: cli.nymd_url, + validator_api_url: cli.validator_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::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(()) +} + +fn setup_logging() { + let mut log_builder = pretty_env_logger::formatted_timed_builder(); + if let Ok(s) = ::std::env::var("RUST_LOG") { + log_builder.parse_filters(&s); + } else { + // default to 'Info' + log_builder.filter(None, log::LevelFilter::Info); + } + + log_builder + .filter_module("hyper", log::LevelFilter::Warn) + .filter_module("tokio_reactor", log::LevelFilter::Warn) + .filter_module("reqwest", log::LevelFilter::Warn) + .filter_module("mio", log::LevelFilter::Warn) + .filter_module("want", log::LevelFilter::Warn) + .filter_module("sled", log::LevelFilter::Warn) + .filter_module("tungstenite", log::LevelFilter::Warn) + .filter_module("tokio_tungstenite", log::LevelFilter::Warn) + .init(); +} + +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() { + setup_logging(); + + let cli = Cli::parse(); + + tokio::select! { + _ = wait_for_interrupt() => warn!("Received interrupt - the specified command might have not completed!"), + _ = execute(cli) => (), + } +} diff --git a/tools/nym-cli/src/validator/account.rs b/tools/nym-cli/src/validator/account.rs new file mode 100644 index 0000000000..36fc3460ba --- /dev/null +++ b/tools/nym-cli/src/validator/account.rs @@ -0,0 +1,79 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_query_client, create_signing_client, ClientArgs}; +use validator_client::nymd::AccountId; + +pub(crate) async fn execute( + global_args: ClientArgs, + account: nym_cli_commands::validator::account::Account, + network_details: &NymNetworkDetails, + mnemonic: Option, +) -> anyhow::Result<()> { + match account.command { + Some(nym_cli_commands::validator::account::AccountCommands::Create(args)) => { + nym_cli_commands::validator::account::create::create_account( + args, + &network_details.chain_details.bech32_account_prefix, + ) + } + Some(nym_cli_commands::validator::account::AccountCommands::Balance(args)) => { + let address_from_args = args.address.clone(); + nym_cli_commands::validator::account::balance::query_balance( + args, + &create_query_client(network_details)?, + get_account_from_mnemonic_as_option( + global_args, + network_details, + address_from_args, + ), + ) + .await + } + Some(nym_cli_commands::validator::account::AccountCommands::PubKey(args)) => { + let address_from_args = args.address.clone(); + nym_cli_commands::validator::account::pubkey::get_pubkey( + args, + &create_query_client(network_details)?, + mnemonic, + get_account_from_mnemonic_as_option( + global_args, + network_details, + address_from_args, + ), + ) + .await; + } + Some(nym_cli_commands::validator::account::AccountCommands::Send(args)) => { + nym_cli_commands::validator::account::send::send( + args, + &create_signing_client(global_args, network_details)?, + ) + .await; + } + _ => unreachable!(), + } + + Ok(()) +} + +fn get_account_from_mnemonic( + global_args: ClientArgs, + network_details: &NymNetworkDetails, + address: Option, +) -> anyhow::Result> { + Ok(address.or(Some( + create_signing_client(global_args, network_details)? + .address() + .clone(), + ))) +} + +fn get_account_from_mnemonic_as_option( + global_args: ClientArgs, + network_details: &NymNetworkDetails, + address: Option, +) -> Option { + get_account_from_mnemonic(global_args, network_details, address).unwrap_or(None) +} diff --git a/tools/nym-cli/src/validator/block.rs b/tools/nym-cli/src/validator/block.rs new file mode 100644 index 0000000000..104680a1d1 --- /dev/null +++ b/tools/nym-cli/src/validator/block.rs @@ -0,0 +1,35 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::create_query_client; + +pub(crate) async fn execute( + block: nym_cli_commands::validator::block::Block, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match block.command { + Some(nym_cli_commands::validator::block::BlockCommands::Get(args)) => { + nym_cli_commands::validator::block::get::query_for_block( + args, + &create_query_client(network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::block::BlockCommands::Time(args)) => { + nym_cli_commands::validator::block::block_time::query_for_block_time( + args, + &create_query_client(network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::block::BlockCommands::CurrentHeight(_args)) => { + nym_cli_commands::validator::block::current_height::query_current_block_height( + &create_query_client(network_details)?, + ) + .await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/cosmwasm.rs b/tools/nym-cli/src/validator/cosmwasm.rs new file mode 100644 index 0000000000..4a77b3896f --- /dev/null +++ b/tools/nym-cli/src/validator/cosmwasm.rs @@ -0,0 +1,45 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + cosmwasm: nym_cli_commands::validator::cosmwasm::Cosmwasm, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match cosmwasm.command { + Some(nym_cli_commands::validator::cosmwasm::CosmwasmCommands::Upload(args)) => { + nym_cli_commands::validator::cosmwasm::upload_contract::upload( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::cosmwasm::CosmwasmCommands::Init(args)) => { + nym_cli_commands::validator::cosmwasm::init_contract::init( + args, + create_signing_client(global_args, network_details)?, + network_details, + ) + .await + } + Some(nym_cli_commands::validator::cosmwasm::CosmwasmCommands::Migrate(args)) => { + nym_cli_commands::validator::cosmwasm::migrate_contract::migrate( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::cosmwasm::CosmwasmCommands::Execute(args)) => { + nym_cli_commands::validator::cosmwasm::execute_contract::execute( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/delegators/mod.rs b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs new file mode 100644 index 0000000000..ed1ac2f211 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs @@ -0,0 +1,32 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{ + create_signing_client, create_signing_client_with_validator_api, ClientArgs, +}; + +pub(crate) mod rewards; + +pub(crate) async fn execute( + global_args: ClientArgs, + delegators: nym_cli_commands::validator::mixnet::delegators::MixnetDelegators, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match delegators.command { + nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::Rewards(rewards) => { + rewards::execute(global_args, rewards, network_details).await? + } + nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::Delegate(args) => { + nym_cli_commands::validator::mixnet::delegators::delegate_to_mixnode::delegate_to_mixnode(args, create_signing_client(global_args, network_details)?).await + } + nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::Undelegate(args) => { + nym_cli_commands::validator::mixnet::delegators::undelegate_from_mixnode::undelegate_from_mixnode(args, create_signing_client(global_args, network_details)?).await + } + nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::List(args) => { + nym_cli_commands::validator::mixnet::delegators::query_for_delegations::execute(args, create_signing_client_with_validator_api(global_args, network_details)?).await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/delegators/rewards/mod.rs b/tools/nym-cli/src/validator/mixnet/delegators/rewards/mod.rs new file mode 100644 index 0000000000..39ca3f673c --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/delegators/rewards/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + rewards: nym_cli_commands::validator::mixnet::delegators::rewards::MixnetDelegatorsReward, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match rewards.command { + nym_cli_commands::validator::mixnet::delegators::rewards::MixnetDelegatorsRewardCommands::Claim(args) => { + nym_cli_commands::validator::mixnet::delegators::rewards::claim_delegator_reward::claim_delegator_reward(args, create_signing_client(global_args, network_details)?).await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/mod.rs b/tools/nym-cli/src/validator/mixnet/mod.rs new file mode 100644 index 0000000000..366b922b16 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/mod.rs @@ -0,0 +1,25 @@ +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::ClientArgs; + +pub(crate) mod delegators; +pub(crate) mod operators; +pub(crate) mod query; + +pub(crate) async fn execute( + global_args: ClientArgs, + mixnet: nym_cli_commands::validator::mixnet::Mixnet, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match mixnet.command { + nym_cli_commands::validator::mixnet::MixnetCommands::Delegators(delegators) => { + delegators::execute(global_args, delegators, network_details).await? + } + nym_cli_commands::validator::mixnet::MixnetCommands::Operators(operators) => { + operators::execute(global_args, operators, network_details).await? + } + nym_cli_commands::validator::mixnet::MixnetCommands::Query(query) => { + query::execute(query, network_details).await? + } + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/gateways/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/gateways/mod.rs new file mode 100644 index 0000000000..f54ac43bca --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/gateways/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + gateway: nym_cli_commands::validator::mixnet::operators::gateway::MixnetOperatorsGateway, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match gateway.command { + nym_cli_commands::validator::mixnet::operators::gateway::MixnetOperatorsGatewayCommands::Bond(args) => { + nym_cli_commands::validator::mixnet::operators::gateway::bond_gateway::bond_gateway(args, create_signing_client(global_args, network_details)?).await + }, + nym_cli_commands::validator::mixnet::operators::gateway::MixnetOperatorsGatewayCommands::Unbound(_args) => { + nym_cli_commands::validator::mixnet::operators::gateway::unbond_gateway::unbond_gateway(create_signing_client(global_args, network_details)?).await + }, + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/mixnodes/keys/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/keys/mod.rs new file mode 100644 index 0000000000..3923093dbb --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/keys/mod.rs @@ -0,0 +1,13 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub(crate) async fn execute( + keys: nym_cli_commands::validator::mixnet::operators::mixnode::keys::MixnetOperatorsMixnodeKeys, +) -> anyhow::Result<()> { + match keys.command { + nym_cli_commands::validator::mixnet::operators::mixnode::keys::MixnetOperatorsMixnodeKeysCommands::DecodeMixnodeKey(args) => { + nym_cli_commands::validator::mixnet::operators::mixnode::keys::decode_mixnode_key::decode_mixnode_key(args) + } + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/mixnodes/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/mod.rs new file mode 100644 index 0000000000..2a6a3d0477 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/mod.rs @@ -0,0 +1,35 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) mod keys; +pub(crate) mod rewards; +pub(crate) mod settings; + +pub(crate) async fn execute( + global_args: ClientArgs, + mixnode: nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnode, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match mixnode.command { + nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnodeCommands::Keys(keys) => { + keys::execute(keys).await? + } + nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnodeCommands::Rewards(rewards) => { + rewards::execute(global_args, rewards, network_details).await? + } + nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnodeCommands::Settings(settings) => { + settings::execute(global_args, settings, network_details).await? + } + nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnodeCommands::Bond(args) => { + nym_cli_commands::validator::mixnet::operators::mixnode::bond_mixnode::bond_mixnode(args, create_signing_client(global_args, network_details)?).await + } + nym_cli_commands::validator::mixnet::operators::mixnode::MixnetOperatorsMixnodeCommands::Unbound(args) => { + nym_cli_commands::validator::mixnet::operators::mixnode::unbond_mixnode::unbond_mixnode(args, create_signing_client(global_args, network_details)?).await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/mixnodes/rewards/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/rewards/mod.rs new file mode 100644 index 0000000000..fb2d241b74 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/rewards/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + rewards: nym_cli_commands::validator::mixnet::operators::mixnode::rewards::MixnetOperatorsMixnodeRewards, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match rewards.command { + nym_cli_commands::validator::mixnet::operators::mixnode::rewards::MixnetOperatorsMixnodeRewardsCommands::Claim(args) => { + nym_cli_commands::validator::mixnet::operators::mixnode::rewards::claim_operator_reward::claim_operator_reward(args, create_signing_client(global_args, network_details)?).await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/mixnodes/settings/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/settings/mod.rs new file mode 100644 index 0000000000..43a579b17b --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/mixnodes/settings/mod.rs @@ -0,0 +1,19 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + settings: nym_cli_commands::validator::mixnet::operators::mixnode::settings::MixnetOperatorsMixnodeSettings, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match settings.command { + nym_cli_commands::validator::mixnet::operators::mixnode::settings::MixnetOperatorsMixnodeSettingsCommands::UpdateProfitPercentage(args) => { + nym_cli_commands::validator::mixnet::operators::mixnode::settings::update_profit_percent::update_profit_percent(args, create_signing_client(global_args, network_details)?).await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/operators/mod.rs b/tools/nym-cli/src/validator/mixnet/operators/mod.rs new file mode 100644 index 0000000000..b1706fb6c8 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/operators/mod.rs @@ -0,0 +1,24 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::ClientArgs; + +pub(crate) mod gateways; +pub(crate) mod mixnodes; + +pub(crate) async fn execute( + global_args: ClientArgs, + operators: nym_cli_commands::validator::mixnet::operators::MixnetOperators, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match operators.command { + nym_cli_commands::validator::mixnet::operators::MixnetOperatorsCommands::Gateway( + gateway, + ) => gateways::execute(global_args, gateway, network_details).await?, + nym_cli_commands::validator::mixnet::operators::MixnetOperatorsCommands::Mixnode( + mixnode, + ) => mixnodes::execute(global_args, mixnode, network_details).await?, + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mixnet/query/mod.rs b/tools/nym-cli/src/validator/mixnet/query/mod.rs new file mode 100644 index 0000000000..21afb8c833 --- /dev/null +++ b/tools/nym-cli/src/validator/mixnet/query/mod.rs @@ -0,0 +1,28 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::create_query_client_with_validator_api; + +pub(crate) async fn execute( + query: nym_cli_commands::validator::mixnet::query::MixnetQuery, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match query.command { + nym_cli_commands::validator::mixnet::query::MixnetQueryCommands::Mixnodes(args) => { + nym_cli_commands::validator::mixnet::query::query_all_mixnodes::query( + args, + &create_query_client_with_validator_api(network_details)?, + ) + .await + } + nym_cli_commands::validator::mixnet::query::MixnetQueryCommands::Gateways(args) => { + nym_cli_commands::validator::mixnet::query::query_all_gateways::query( + args, + &create_query_client_with_validator_api(network_details)?, + ) + .await + } + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/mod.rs b/tools/nym-cli/src/validator/mod.rs new file mode 100644 index 0000000000..0f1ddb6122 --- /dev/null +++ b/tools/nym-cli/src/validator/mod.rs @@ -0,0 +1,10 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub(crate) mod account; +pub(crate) mod block; +pub(crate) mod cosmwasm; +pub(crate) mod mixnet; +pub(crate) mod signature; +pub(crate) mod transactions; +pub(crate) mod vesting; diff --git a/tools/nym-cli/src/validator/signature.rs b/tools/nym-cli/src/validator/signature.rs new file mode 100644 index 0000000000..edc237753f --- /dev/null +++ b/tools/nym-cli/src/validator/signature.rs @@ -0,0 +1,30 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::create_query_client; + +pub(crate) async fn execute( + signature: nym_cli_commands::validator::signature::Signature, + network_details: &NymNetworkDetails, + mnemonic: Option, +) -> anyhow::Result<()> { + match signature.command { + Some(nym_cli_commands::validator::signature::SignatureCommands::Sign(args)) => { + nym_cli_commands::validator::signature::sign::sign( + args, + &network_details.chain_details.bech32_account_prefix, + mnemonic, + ) + } + Some(nym_cli_commands::validator::signature::SignatureCommands::Verify(args)) => { + nym_cli_commands::validator::signature::verify::verify( + args, + &create_query_client(network_details)?, + ) + .await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/transactions.rs b/tools/nym-cli/src/validator/transactions.rs new file mode 100644 index 0000000000..05455a3502 --- /dev/null +++ b/tools/nym-cli/src/validator/transactions.rs @@ -0,0 +1,29 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::create_query_client; + +pub(crate) async fn execute( + transactions: nym_cli_commands::validator::transactions::Transactions, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match transactions.command { + Some(nym_cli_commands::validator::transactions::TransactionsCommands::Get(args)) => { + nym_cli_commands::validator::transactions::get_transaction::get( + args, + &create_query_client(network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::transactions::TransactionsCommands::Query(args)) => { + nym_cli_commands::validator::transactions::query_transactions::query( + args, + &create_query_client(network_details)?, + ) + .await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/src/validator/vesting.rs b/tools/nym-cli/src/validator/vesting.rs new file mode 100644 index 0000000000..d87ca2c9ff --- /dev/null +++ b/tools/nym-cli/src/validator/vesting.rs @@ -0,0 +1,49 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use network_defaults::NymNetworkDetails; +use nym_cli_commands::context::{create_signing_client, ClientArgs}; + +pub(crate) async fn execute( + global_args: ClientArgs, + vesting: nym_cli_commands::validator::vesting::VestingSchedule, + network_details: &NymNetworkDetails, +) -> anyhow::Result<()> { + match vesting.command { + Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::Create(args)) => { + nym_cli_commands::validator::vesting::create_vesting_schedule::create( + args, + create_signing_client(global_args, network_details)?, + network_details, + ) + .await + } + Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::Query(args)) => { + nym_cli_commands::validator::vesting::query_vesting_schedule::query( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::VestedBalance( + args, + )) => { + nym_cli_commands::validator::vesting::balance::balance( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::WithdrawVested( + args, + )) => { + nym_cli_commands::validator::vesting::withdraw_vested::execute( + args, + create_signing_client(global_args, network_details)?, + ) + .await + } + _ => unreachable!(), + } + Ok(()) +} diff --git a/tools/nym-cli/user-docs/fig-spec.ts b/tools/nym-cli/user-docs/fig-spec.ts new file mode 100644 index 0000000000..95825de55d --- /dev/null +++ b/tools/nym-cli/user-docs/fig-spec.ts @@ -0,0 +1,5048 @@ +const completion: Fig.Spec = { + name: "nym-cli", + description: "A client for interacting with Nym smart contracts and the Nyx blockchain", + subcommands: [ + { + name: "account", + description: "Query and manage Nyx blockchain accounts", + subcommands: [ + { + name: "create", + description: "Create a new mnemonic - note, this account does not appear on the chain until the account id is used in a transaction", + options: [ + { + name: "--word-count", + args: { + name: "word-count", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "balance", + description: "Gets the balance of an account", + options: [ + { + name: "--denom", + description: "Optional currency to show balance for", + args: { + name: "denom", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: "--hide-denom", + description: "Optionally hide the denom", + }, + { + name: "--raw", + description: "Show as a raw value", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "address", + isOptional: true, + }, + }, + { + name: "pub-key", + description: "Gets the public key of an account", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: "--from-mnemonic", + description: "If set, get the public key from the mnemonic, rather than querying for it", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "address", + isOptional: true, + }, + }, + { + name: "send", + description: "Sends tokens to another account", + options: [ + { + name: "--denom", + description: "Override the denomination", + args: { + name: "denom", + isOptional: true, + }, + }, + { + name: "--memo", + args: { + name: "memo", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: [ + { + name: "recipient", + }, + { + name: "amount", + }, + ] + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "signature", + description: "Sign and verify messages", + subcommands: [ + { + name: "sign", + description: "Sign a message", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "message", + }, + }, + { + name: "verify", + description: "Verify a message", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: [ + { + name: "public-key-or-address", + }, + { + name: "signature-as-hex", + }, + { + name: "message", + }, + ] + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "block", + description: "Query chain blocks", + subcommands: [ + { + name: "get", + description: "Gets a block's details and prints as JSON", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "height", + }, + }, + { + name: "time", + description: "Gets the block time at a height", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "height", + }, + }, + { + name: "current-height", + description: "Gets the current block height", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "cosmwasm", + description: "Manage and execute WASM smart contracts", + subcommands: [ + { + name: "upload", + description: "Upload a smart contract WASM blob", + options: [ + { + name: "--wasm-path", + args: { + name: "wasm-path", + }, + }, + { + name: "--memo", + args: { + name: "memo", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "init", + description: "Init a WASM smart contract", + options: [ + { + name: "--memo", + args: { + name: "memo", + isOptional: true, + }, + }, + { + name: "--label", + args: { + name: "label", + isOptional: true, + }, + }, + { + name: "--init-message", + args: { + name: "init-message", + }, + }, + { + name: "--admin", + args: { + name: "admin", + isOptional: true, + }, + }, + { + name: "--funds", + description: "Amount to supply as funds in micro denomination (e.g. unym or unyx)", + args: { + name: "funds", + isOptional: true, + }, + }, + { + name: "--funds-denom", + description: "Set the denomination for the funds", + args: { + name: "funds-denom", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "code-id", + }, + }, + { + name: "migrate", + description: "Migrate a WASM smart contract", + options: [ + { + name: "--code-id", + args: { + name: "code-id", + }, + }, + { + name: "--memo", + args: { + name: "memo", + isOptional: true, + }, + }, + { + name: "--init-message", + args: { + name: "init-message", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "contract-address", + }, + }, + { + name: "execute", + description: "Execute a WASM smart contract method", + options: [ + { + name: "--memo", + args: { + name: "memo", + isOptional: true, + }, + }, + { + name: "--funds-denom", + description: "Set the denomination for the funds", + args: { + name: "funds-denom", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: [ + { + name: "contract-address", + }, + { + name: "json-args", + }, + { + name: "funds", + isOptional: true, + }, + ] + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "tx", + description: "Query for transactions", + subcommands: [ + { + name: "get", + description: "Get a transaction by hash or block height", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "tx-hash", + }, + }, + { + name: "query", + description: "Query for transactions", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "query", + }, + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-schedule", + description: "Create and query for a vesting schedule", + subcommands: [ + { + name: "create", + description: "Creates a vesting schedule", + options: [ + { + name: "--periods-seconds", + args: { + name: "periods-seconds", + isOptional: true, + }, + }, + { + name: "--number-of-periods", + args: { + name: "number-of-periods", + isOptional: true, + }, + }, + { + name: "--start-time", + args: { + name: "start-time", + isOptional: true, + }, + }, + { + name: "--address", + args: { + name: "address", + }, + }, + { + name: "--amount", + args: { + name: "amount", + }, + }, + { + name: "--staking-address", + args: { + name: "staking-address", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "query", + description: "Query for vesting schedule", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "address", + isOptional: true, + }, + }, + { + name: "vested-balance", + description: "Get the amount that has vested and is free for withdrawal, delegation or bonding", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "address", + isOptional: true, + }, + }, + { + name: "withdraw-vested", + description: "Withdraw vested tokens (note: the available amount excludes anything delegated or bonded before or after vesting)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "amount", + }, + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "mixnet", + description: "Manage your mixnet infrastructure, delegate stake or query the directory", + subcommands: [ + { + name: "query", + description: "Query the mixnet directory", + subcommands: [ + { + name: "mixnodes", + description: "Query mixnodes", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "identity-key", + isOptional: true, + }, + }, + { + name: "gateways", + description: "Query gateways", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + args: { + name: "identity-key", + isOptional: true, + }, + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "delegators", + description: "Manage your delegations", + subcommands: [ + { + name: "list", + description: "Lists current delegations", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "rewards", + description: "Manage rewards from delegations", + subcommands: [ + { + name: "claim", + description: "Claim rewards accumulated during the delegation of unlocked tokens", + options: [ + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-claim", + description: "Claim rewards accumulated during the delegation of locked tokens", + options: [ + { + name: "--identity", + args: { + name: "identity", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "delegate", + description: "Delegate to a mixnode", + options: [ + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--amount", + args: { + name: "amount", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "undelegate", + description: "Undelegate from a mixnode", + options: [ + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "delegate-vesting", + description: "Delegate to a mixnode with locked tokens", + options: [ + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--amount", + args: { + name: "amount", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "undelegate-vesting", + description: "Undelegate from a mixnode (when originally using locked tokens)", + options: [ + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "operators", + description: "Manage a mixnode or gateway you operate", + subcommands: [ + { + name: "mixnode", + description: "Manage your mixnode", + subcommands: [ + { + name: "keys", + description: "Operations for mixnode keys", + subcommands: [ + { + name: "decode-mixnode-key", + description: "Decode a mixnode key", + options: [ + { + name: ["-k", "--key"], + args: { + name: "key", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "rewards", + description: "Manage your mixnode operator rewards", + subcommands: [ + { + name: "claim", + description: "Claim rewards", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-claim", + description: "Claim rewards for a mixnode bonded with locked tokens", + options: [ + { + name: "--gas", + args: { + name: "gas", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "settings", + description: "Manage your mixnode settings stored in the directory", + subcommands: [ + { + name: "update-profit-percentage", + description: "Update profit percentage", + options: [ + { + name: "--profit-percent", + args: { + name: "profit-percent", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-update-profit-percentage", + description: "Update profit percentage for a mixnode bonded with locked tokens", + options: [ + { + name: "--profit-percent", + args: { + name: "profit-percent", + }, + }, + { + name: "--gas", + args: { + name: "gas", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "bond", + description: "Bond to a mixnode", + options: [ + { + name: "--host", + args: { + name: "host", + }, + }, + { + name: "--signature", + args: { + name: "signature", + }, + }, + { + name: "--mix-port", + args: { + name: "mix-port", + isOptional: true, + }, + }, + { + name: "--verloc-port", + args: { + name: "verloc-port", + isOptional: true, + }, + }, + { + name: "--http-api-port", + args: { + name: "http-api-port", + isOptional: true, + }, + }, + { + name: "--sphinx-key", + args: { + name: "sphinx-key", + }, + }, + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--version", + args: { + name: "version", + }, + }, + { + name: "--profit-margin-percent", + args: { + name: "profit-margin-percent", + isOptional: true, + }, + }, + { + name: "--amount", + description: "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')", + args: { + name: "amount", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-f", "--force"], + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "unbound", + description: "Unbound from a mixnode", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "bond-vesting", + description: "Bond to a mixnode with locked tokens", + options: [ + { + name: "--host", + args: { + name: "host", + }, + }, + { + name: "--signature", + args: { + name: "signature", + }, + }, + { + name: "--mix-port", + args: { + name: "mix-port", + isOptional: true, + }, + }, + { + name: "--verloc-port", + args: { + name: "verloc-port", + isOptional: true, + }, + }, + { + name: "--http-api-port", + args: { + name: "http-api-port", + isOptional: true, + }, + }, + { + name: "--sphinx-key", + args: { + name: "sphinx-key", + }, + }, + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--version", + args: { + name: "version", + }, + }, + { + name: "--profit-margin-percent", + args: { + name: "profit-margin-percent", + isOptional: true, + }, + }, + { + name: "--amount", + description: "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')", + args: { + name: "amount", + }, + }, + { + name: "--gas", + args: { + name: "gas", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-f", "--force"], + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "unbound-vesting", + description: "Unbound from a mixnode (when originally using locked tokens)", + options: [ + { + name: "--gas", + args: { + name: "gas", + isOptional: true, + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "gateway", + description: "Manage your gateway", + subcommands: [ + { + name: "bond", + description: "Bond to a gateway", + options: [ + { + name: "--host", + args: { + name: "host", + }, + }, + { + name: "--signature", + args: { + name: "signature", + }, + }, + { + name: "--mix-port", + args: { + name: "mix-port", + isOptional: true, + }, + }, + { + name: "--clients-port", + args: { + name: "clients-port", + isOptional: true, + }, + }, + { + name: "--location", + args: { + name: "location", + isOptional: true, + }, + }, + { + name: "--sphinx-key", + args: { + name: "sphinx-key", + }, + }, + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--version", + args: { + name: "version", + }, + }, + { + name: "--amount", + description: "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')", + args: { + name: "amount", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-f", "--force"], + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "unbound", + description: "Unbound from a gateway", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-bond", + description: "Bond to a gateway with locked tokens", + options: [ + { + name: "--host", + args: { + name: "host", + }, + }, + { + name: "--signature", + args: { + name: "signature", + }, + }, + { + name: "--mix-port", + args: { + name: "mix-port", + isOptional: true, + }, + }, + { + name: "--clients-port", + args: { + name: "clients-port", + isOptional: true, + }, + }, + { + name: "--location", + args: { + name: "location", + isOptional: true, + }, + }, + { + name: "--sphinx-key", + args: { + name: "sphinx-key", + }, + }, + { + name: "--identity-key", + args: { + name: "identity-key", + }, + }, + { + name: "--version", + args: { + name: "version", + }, + }, + { + name: "--amount", + description: "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')", + args: { + name: "amount", + }, + }, + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-f", "--force"], + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "vesting-unbound", + description: "Unbound from a gateway (when originally using locked tokens)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "generate-fig", + description: "Generates shell completion", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + ], + args: { + name: "subcommand", + isOptional: true, + }, + }, + ], + options: [ + { + name: "--mnemonic", + description: "Provide the mnemonic for your account. You can also provide this is an env var called MNEMONIC.", + args: { + name: "mnemonic", + isOptional: true, + }, + }, + { + name: "--config-env-file", + description: "Overrides configuration as a file of environment variables. Note: individual env vars take precedence over this file.", + args: { + name: "config-env-file", + isOptional: true, + }, + }, + { + name: "--nymd-url", + description: "Overrides the nymd URL provided either as an environment variable NYMD_VALIDATOR or in a config file", + args: { + name: "nymd-url", + isOptional: true, + }, + }, + { + name: "--validator-api-url", + description: "Overrides the validator API URL provided either as an environment variable API_VALIDATOR or in a config file", + args: { + name: "validator-api-url", + isOptional: true, + }, + }, + { + name: "--mixnet-contract-address", + description: "Overrides the mixnet contract address provided either as an environment variable or in a config file", + args: { + name: "mixnet-contract-address", + isOptional: true, + }, + }, + { + name: "--vesting-contract-address", + description: "Overrides the vesting contract address provided either as an environment variable or in a config file", + args: { + name: "vesting-contract-address", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], +}; + +export default completion; diff --git a/tools/nym-cli/user-docs/tsconfig.json b/tools/nym-cli/user-docs/tsconfig.json new file mode 100644 index 0000000000..b810c4f5c9 --- /dev/null +++ b/tools/nym-cli/user-docs/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "types": ["@withfig/autocomplete-types"] + }, +} \ No newline at end of file