From 324e63a1f2ba2f1a0e65b82c13c5f0ffe8776028 Mon Sep 17 00:00:00 2001 From: FroVolod Date: Sat, 26 Jun 2021 09:48:25 +0300 Subject: [PATCH 1/4] recent block hash: created --- src/commands/mod.rs | 4 +- src/commands/view_command/mod.rs | 10 +++ .../view_recent_block_hash/mod.rs | 1 + .../operation_mode/mod.rs | 69 ++++++++++++++ .../operation_mode/online_mode/mod.rs | 36 ++++++++ .../online_mode/select_server/mod.rs | 89 +++++++++++++++++++ .../online_mode/select_server/server/mod.rs | 67 ++++++++++++++ 7 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 src/commands/view_command/view_recent_block_hash/mod.rs create mode 100644 src/commands/view_command/view_recent_block_hash/operation_mode/mod.rs create mode 100644 src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/mod.rs create mode 100644 src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/mod.rs create mode 100644 src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/server/mod.rs diff --git a/src/commands/mod.rs b/src/commands/mod.rs index edc6f0d84..78b652471 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -29,7 +29,7 @@ pub enum CliTopLevelCommand { Transfer(self::transfer_command::CliCurrency), /// Helpers Utils(self::utils_command::CliUtils), - /// View account, contract code, contract state, transaction + /// View account, contract code, contract state, transaction, nonce, recent block hash View(self::view_command::CliViewQueryRequest), } @@ -39,7 +39,7 @@ pub enum TopLevelCommand { #[strum_discriminants(strum(message = "Login with wallet authorization"))] Login(self::login::operation_mode::OperationMode), #[strum_discriminants(strum( - message = "View account, contract code, contract state, transaction, nonce" + message = "View account, contract code, contract state, transaction, nonce, recent block hash" ))] View(self::view_command::ViewQueryRequest), #[strum_discriminants(strum(message = "Transfer tokens"))] diff --git a/src/commands/view_command/mod.rs b/src/commands/view_command/mod.rs index 29ae71518..0ea552bab 100644 --- a/src/commands/view_command/mod.rs +++ b/src/commands/view_command/mod.rs @@ -5,6 +5,7 @@ mod view_account; mod view_contract_code; mod view_contract_state; mod view_nonce; +mod view_recent_block_hash; mod view_transaction_status; /// инструмент выбора to view @@ -52,6 +53,8 @@ pub enum CliQueryRequest { Transaction(self::view_transaction_status::operation_mode::CliOperationMode), /// View a nonce for a public key Nonce(self::view_nonce::operation_mode::CliOperationMode), + /// View recent block hash for this network + RecentBlockHash(self::view_recent_block_hash::operation_mode::CliOperationMode) } #[derive(Debug, EnumDiscriminants)] @@ -67,6 +70,8 @@ pub enum QueryRequest { Transaction(self::view_transaction_status::operation_mode::OperationMode), #[strum_discriminants(strum(message = "View a nonce for a public key"))] Nonce(self::view_nonce::operation_mode::OperationMode), + #[strum_discriminants(strum(message = "View recent block hash for this network"))] + RecentBlockHash(self::view_recent_block_hash::operation_mode::OperationMode), } impl From for QueryRequest { @@ -87,6 +92,9 @@ impl From for QueryRequest { CliQueryRequest::Nonce(cli_operation_mode) => { QueryRequest::Nonce(cli_operation_mode.into()) } + CliQueryRequest::RecentBlockHash(cli_operation_mode) => { + QueryRequest::RecentBlockHash(cli_operation_mode.into()) + } } } } @@ -119,6 +127,7 @@ impl QueryRequest { CliQueryRequest::Transaction(Default::default()) } QueryRequestDiscriminants::Nonce => CliQueryRequest::Nonce(Default::default()), + QueryRequestDiscriminants::RecentBlockHash => CliQueryRequest::RecentBlockHash(Default::default()), }; Self::from(cli_request) } @@ -130,6 +139,7 @@ impl QueryRequest { QueryRequest::ContractState(operation_mode) => operation_mode.process().await, QueryRequest::Transaction(operation_mode) => operation_mode.process().await, QueryRequest::Nonce(operation_mode) => operation_mode.process().await, + QueryRequest::RecentBlockHash(operation_mode) => operation_mode.process().await, } } } diff --git a/src/commands/view_command/view_recent_block_hash/mod.rs b/src/commands/view_command/view_recent_block_hash/mod.rs new file mode 100644 index 000000000..6777ebcf1 --- /dev/null +++ b/src/commands/view_command/view_recent_block_hash/mod.rs @@ -0,0 +1 @@ +pub mod operation_mode; diff --git a/src/commands/view_command/view_recent_block_hash/operation_mode/mod.rs b/src/commands/view_command/view_recent_block_hash/operation_mode/mod.rs new file mode 100644 index 000000000..8f2b45c85 --- /dev/null +++ b/src/commands/view_command/view_recent_block_hash/operation_mode/mod.rs @@ -0,0 +1,69 @@ +use strum::{EnumDiscriminants, EnumIter, EnumMessage}; + +pub mod online_mode; + +/// инструмент выбора режима online/offline +#[derive(Debug, Default, clap::Clap)] +#[clap( + setting(clap::AppSettings::ColoredHelp), + setting(clap::AppSettings::DisableHelpSubcommand), + setting(clap::AppSettings::VersionlessSubcommands) +)] +pub struct CliOperationMode { + #[clap(subcommand)] + mode: Option, +} + +#[derive(Debug)] +pub struct OperationMode { + pub mode: Mode, +} + +impl From for OperationMode { + fn from(item: CliOperationMode) -> Self { + let mode = match item.mode { + Some(cli_mode) => Mode::from(cli_mode), + None => Mode::choose_mode(), + }; + Self { mode } + } +} + +impl OperationMode { + pub async fn process(self) -> crate::CliResult { + self.mode.process().await + } +} + +#[derive(Debug, clap::Clap)] +pub enum CliMode { + /// Execute a change method with online mode + Network(self::online_mode::CliNetworkArgs), +} + +#[derive(Debug, EnumDiscriminants)] +#[strum_discriminants(derive(EnumMessage, EnumIter))] +pub enum Mode { + #[strum_discriminants(strum(message = "Yes, I keep it simple"))] + Network(self::online_mode::NetworkArgs), +} + +impl From for Mode { + fn from(item: CliMode) -> Self { + match item { + CliMode::Network(cli_network_args) => Self::Network(cli_network_args.into()), + } + } +} + +impl Mode { + pub fn choose_mode() -> Self { + Self::from(CliMode::Network(Default::default())) + } + + pub async fn process(self) -> crate::CliResult { + match self { + Self::Network(network_args) => network_args.process().await, + } + } +} diff --git a/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/mod.rs b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/mod.rs new file mode 100644 index 000000000..a10f12ab9 --- /dev/null +++ b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/mod.rs @@ -0,0 +1,36 @@ +pub mod select_server; + +/// аргументы, необходимые для создания транзакции в online mode +#[derive(Debug, Default, clap::Clap)] +#[clap( + setting(clap::AppSettings::ColoredHelp), + setting(clap::AppSettings::DisableHelpSubcommand), + setting(clap::AppSettings::VersionlessSubcommands) +)] +pub struct CliNetworkArgs { + #[clap(subcommand)] + selected_server: Option, +} + +#[derive(Debug)] +pub struct NetworkArgs { + selected_server: self::select_server::SelectServer, +} + +impl From for NetworkArgs { + fn from(item: CliNetworkArgs) -> Self { + let selected_server = match item.selected_server { + Some(cli_selected_server) => { + self::select_server::SelectServer::from(cli_selected_server) + } + None => self::select_server::SelectServer::choose_server(), + }; + Self { selected_server } + } +} + +impl NetworkArgs { + pub async fn process(self) -> crate::CliResult { + self.selected_server.process().await + } +} diff --git a/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/mod.rs b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/mod.rs new file mode 100644 index 000000000..1ffe72c3f --- /dev/null +++ b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/mod.rs @@ -0,0 +1,89 @@ +use dialoguer::{theme::ColorfulTheme, Select}; +use strum::{EnumDiscriminants, EnumIter, EnumMessage, IntoEnumIterator}; + +pub mod server; + +#[derive(Debug, clap::Clap)] +pub enum CliSelectServer { + /// предоставление данных для сервера https://rpc.testnet.near.org + Testnet(self::server::CliServer), + /// предоставление данных для сервера https://rpc.mainnet.near.org + Mainnet(self::server::CliServer), + /// предоставление данных для сервера https://rpc.betanet.near.org + Betanet(self::server::CliServer), + /// предоставление данных для сервера, указанного вручную + Custom(self::server::CliCustomServer), +} + +#[derive(Debug, EnumDiscriminants)] +#[strum_discriminants(derive(EnumMessage, EnumIter))] +pub enum SelectServer { + #[strum_discriminants(strum(message = "Testnet"))] + Testnet(self::server::Server), + #[strum_discriminants(strum(message = "Mainnet"))] + Mainnet(self::server::Server), + #[strum_discriminants(strum(message = "Betanet"))] + Betanet(self::server::Server), + #[strum_discriminants(strum(message = "Custom"))] + Custom(self::server::Server), +} + +impl From for SelectServer { + fn from(item: CliSelectServer) -> Self { + match item { + CliSelectServer::Testnet(cli_server) => { + Self::Testnet(cli_server.into_server(crate::common::ConnectionConfig::Testnet)) + } + CliSelectServer::Mainnet(cli_server) => { + Self::Mainnet(cli_server.into_server(crate::common::ConnectionConfig::Mainnet)) + } + CliSelectServer::Betanet(cli_server) => { + Self::Betanet(cli_server.into_server(crate::common::ConnectionConfig::Betanet)) + } + CliSelectServer::Custom(cli_custom_server) => { + Self::Custom(cli_custom_server.into_server()) + } + } + } +} + +impl SelectServer { + pub fn choose_server() -> Self { + println!(); + let variants = SelectServerDiscriminants::iter().collect::>(); + let servers = variants + .iter() + .map(|p| p.get_message().unwrap().to_owned()) + .collect::>(); + let selected_server = Select::with_theme(&ColorfulTheme::default()) + .with_prompt("Select NEAR protocol RPC server:") + .items(&servers) + .default(0) + .interact() + .unwrap(); + let cli_select_server = match variants[selected_server] { + SelectServerDiscriminants::Testnet => CliSelectServer::Testnet(Default::default()), + SelectServerDiscriminants::Mainnet => CliSelectServer::Mainnet(Default::default()), + SelectServerDiscriminants::Betanet => CliSelectServer::Betanet(Default::default()), + SelectServerDiscriminants::Custom => CliSelectServer::Custom(Default::default()), + }; + Self::from(cli_select_server) + } + + pub async fn process(self) -> crate::CliResult { + Ok(match self { + SelectServer::Testnet(server) => { + server.process().await?; + } + SelectServer::Mainnet(server) => { + server.process().await?; + } + SelectServer::Betanet(server) => { + server.process().await?; + } + SelectServer::Custom(server) => { + server.process().await?; + } + }) + } +} diff --git a/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/server/mod.rs b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/server/mod.rs new file mode 100644 index 000000000..4d672a050 --- /dev/null +++ b/src/commands/view_command/view_recent_block_hash/operation_mode/online_mode/select_server/server/mod.rs @@ -0,0 +1,67 @@ +use dialoguer::Input; + +/// предустановленный RPC-сервер +#[derive(Debug, Default, clap::Clap)] +#[clap( + setting(clap::AppSettings::ColoredHelp), + setting(clap::AppSettings::DisableHelpSubcommand), + setting(clap::AppSettings::VersionlessSubcommands) +)] +pub struct CliServer { +} + +/// данные для custom server +#[derive(Debug, Default, clap::Clap)] +#[clap( + setting(clap::AppSettings::ColoredHelp), + setting(clap::AppSettings::DisableHelpSubcommand), + setting(clap::AppSettings::VersionlessSubcommands) +)] +pub struct CliCustomServer { + #[clap(long)] + pub url: Option, +} + +#[derive(Debug)] +pub struct Server { + pub connection_config: crate::common::ConnectionConfig, +} + +impl CliServer { + pub fn into_server(self, connection_config: crate::common::ConnectionConfig) -> Server { + Server { + connection_config, + } + } +} + +impl CliCustomServer { + pub fn into_server(self) -> Server { + let url: crate::common::AvailableRpcServerUrl = match self.url { + Some(url) => url, + None => Input::new() + .with_prompt("What is the RPC endpoint?") + .interact_text() + .unwrap(), + }; + Server { + connection_config: crate::common::ConnectionConfig::Custom { url: url.inner }, + } + } +} + +impl Server { + pub async fn process(self) -> crate::CliResult { + let status = near_jsonrpc_client::new_client(self.connection_config.rpc_url().as_str()) + .status() + .await + .map_err(|err| { + color_eyre::Report::msg(format!( + "Failed to fetch public key information for nonce: {:?}", + err + )) + })?; + println!("recent block hash: {:?}", status.sync_info.latest_block_hash); + Ok(()) + } +} From 51420d65494a666d322484445dbcbb7adb1cf980 Mon Sep 17 00:00:00 2001 From: FroVolod <36816899+FroVolod@users.noreply.github.com> Date: Sat, 26 Jun 2021 10:54:48 +0300 Subject: [PATCH 2/4] Update GUIDE.ru.md --- docs/GUIDE.ru.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/GUIDE.ru.md b/docs/GUIDE.ru.md index 96a1d8906..b207f2b70 100644 --- a/docs/GUIDE.ru.md +++ b/docs/GUIDE.ru.md @@ -19,7 +19,7 @@ * _recent block hash_ - Информацию для этого параметра нужно искать [здесь](https://explorer.testnet.near.org/blocks). + Информацию для этого параметра нужно искать [здесь](https://explorer.testnet.near.org/blocks) либо получить при помощи [View recent block hash](#view-recent-block-hash)
recent block hash @@ -367,6 +367,27 @@ current nonce: 168 for a public key: ed25519:7FmDRADa1v4BcLiiR9MPPdmWQp3Um1iPdA
+#### View recent block hash + +Для просмотра _recent block hash_ выбранной сети необходимо ввести в командной строке терминала: +```txt +./near-cli view recent-block-hash \ + network testnet +``` + +
Результат выполнения команды + +```txt +recent block hash: `CDgRvkv2qv2c8e5m2WDKFUFqAtXrq2fiUteM6XHpy58t` +``` +
+ +
Демонстрация работы команды в интерактивном режиме + + + +
+ ### Transfer tokens From aac24800f2673d7b6b3757f025b95882d6550ec7 Mon Sep 17 00:00:00 2001 From: FroVolod <36816899+FroVolod@users.noreply.github.com> Date: Sat, 26 Jun 2021 11:04:09 +0300 Subject: [PATCH 3/4] Update GUIDE.en.md --- docs/GUIDE.en.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/GUIDE.en.md b/docs/GUIDE.en.md index 72a6a187b..47feccc3b 100644 --- a/docs/GUIDE.en.md +++ b/docs/GUIDE.en.md @@ -20,7 +20,7 @@ Before proceeding to the description of specific commands, it is necessary to co * _recent block hash_ - Information for this parameter should be found [here](https://explorer.testnet.near.org/blocks). + Information for this parameter should be found [here](https://explorer.testnet.near.org/blocks) or will need to be obtained using [View recent block hash](#view-recent-block-hash).
recent block hash @@ -368,6 +368,27 @@ current nonce: 168 for a public key: ed25519:7FmDRADa1v4BcLiiR9MPPdmWQp3Um1iPdA
+#### View recent block hash + +To view the _recent block hash_ for network, type the following in the terminal command line: +```txt +./near-cli view recent-block-hash \ + network testnet +``` + +
The result of this command will be as follows: + +```txt +recent block hash: `CDgRvkv2qv2c8e5m2WDKFUFqAtXrq2fiUteM6XHpy58t` +``` +
+ +
Demonstration of the command in interactive mode + + + +
+ ### Transfer tokens From 6cd4bbedbd00b0c82e879a1a37f00b2ef2b69d19 Mon Sep 17 00:00:00 2001 From: FroVolod Date: Sat, 26 Jun 2021 11:08:49 +0300 Subject: [PATCH 4/4] recent block hash: release --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2f9f987d..6b137ef7f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Get the release version from the tag # if: env.NEAR_CLI_VERSION == '' run: | - echo "NEAR_CLI_VERSION=0.1.5" >> $GITHUB_ENV + echo "NEAR_CLI_VERSION=0.1.6" >> $GITHUB_ENV echo "version is: ${{ env.NEAR_CLI_VERSION }}" - name: Create GitHub release