diff --git a/Cargo.lock b/Cargo.lock index def6fc1..a451999 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,6 +252,7 @@ dependencies = [ "shadow-rs", "thiserror", "tokio", + "toml 0.8.10", ] [[package]] @@ -2414,7 +2415,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -2424,7 +2425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -2921,6 +2922,15 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3373,11 +3383,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.4", +] + [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -3390,6 +3415,19 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tonic" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index 1136d31..3057f04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "aurora-cli-rs" version = "0.1.0" authors = ["Aurora Labs "] edition = "2021" -rust-version = "1.70.0" +rust-version = "1.75.0" homepage = "https://github.com/aurora-is-near/aurora-cli-rs" repository = "https://github.com/aurora-is-near/aurora-cli-rs" description = "Aurora CLI is a command line interface to bootstrap Aurora engine" @@ -41,6 +41,7 @@ rand = "0.8" rlp = "0.5.0" serde = { version = "1", features = ["derive"] } serde_json = "1" +toml = "0.8.10" shadow-rs = "0.24" thiserror = "1" tokio = { version = "1", features = ["full"] } diff --git a/rust-toolchain b/rust-toolchain index cad9254..76958ae 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "1.70.0" +channel = "1.75.0" components = [ "clippy", "rustfmt" ] diff --git a/scripts/different-outputs.sh b/scripts/different-outputs.sh new file mode 100755 index 0000000..c0a8077 --- /dev/null +++ b/scripts/different-outputs.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash + +export NEARCORE_HOME="/tmp/localnet" + +AURORA_PREV_VERSION="2.10.2" +AURORA_LAST_VERSION="3.1.0" +EVM_CODE=$(cat docs/res/HelloWorld.hex) +ABI_PATH="docs/res/HelloWorld.abi" +ENGINE_PREV_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_PREV_VERSION/aurora-mainnet.wasm" +ENGINE_LAST_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_LAST_VERSION/aurora-mainnet.wasm" +XCC_ROUTER_LAST_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_LAST_VERSION/aurora-factory-mainnet.wasm" +ENGINE_WASM_PATH="/tmp/aurora-mainnet.wasm" +XCC_ROUTER_WASM_PATH="/tmp/aurora-factory-mainnet.wasm" +USER_BASE_BIN=$(python3 -m site --user-base)/bin +NODE_KEY_PATH=$NEARCORE_HOME/node0/validator_key.json +AURORA_KEY_PATH=$NEARCORE_HOME/node0/aurora_key.json +MANAGER_KEY_PATH=$NEARCORE_HOME/node0/manager_key.json +RELAYER_KEY_PATH=$NEARCORE_HOME/node0/relayer_key.json +AURORA_SECRET_KEY=27cb3ddbd18037b38d7fb9ae3433a9d6f5cd554a4ba5768c8a15053f688ee167 +ENGINE_ACCOUNT=aurora.node0 +MANAGER_ACCOUNT=key-manager.aurora.node0 + +export PATH="$PATH:$USER_BASE_BIN:$HOME/.cargo/bin" +export PATH="$HOME/NearProtocol/aurora/aurora-cli-rs/target/debug/:$PATH:$USER_BASE_BIN" + + +# Install `nearup` utility if not installed before. +pip3 list | grep nearup > /dev/null || pip3 install --user nearup + +start_node() { + cmd="nearup run localnet --home $NEARCORE_HOME" + + if [[ $(uname -m) == "arm64" ]]; then # Check for local execution + cmd="$cmd --binary-path $HOME/.nearup/near/localnet --num-nodes 1" + fi + + $cmd > /dev/null 2>&1 +} + +stop_node() { + nearup stop > /dev/null 2>&1 +} + +finish() { + # Stop NEAR node. + stop_node + # Cleanup + rm -rf $NEARCORE_HOME + + if [[ -z "$1" ]]; then + exit 0 + else + exit "$1" + fi +} + +error_exit() { + finish 1 +} + +assert_eq() { + if [[ $1 != $2 ]]; then + echo "Unexpected result, should be $1 but actual is $2" + finish 1 + fi +} + +# Start NEAR node. +start_node +sleep 1 + +# Download Aurora EVM. +curl -sL $ENGINE_PREV_WASM_URL -o $ENGINE_WASM_PATH || error_exit + +export NEAR_KEY_PATH=$NODE_KEY_PATH +# Create an account for Aurora EVM. +aurora-cli create-account --account $ENGINE_ACCOUNT --balance 100 > $AURORA_KEY_PATH || error_exit +sleep 1 + +# View info of created account. +aurora-cli view-account $ENGINE_ACCOUNT || error_exit +sleep 1 + +# Deploy Aurora EVM. +export NEAR_KEY_PATH=$AURORA_KEY_PATH +aurora-cli deploy-aurora $ENGINE_WASM_PATH || error_exit +sleep 4 +# Init Aurora EVM. +aurora-cli --engine $ENGINE_ACCOUNT init \ + --chain-id 1313161556 \ + --owner-id $ENGINE_ACCOUNT \ + --bridge-prover-id "prover" \ + --upgrade-delay-blocks 1 \ + --custodian-address 0x1B16948F011686AE64BB2Ba0477aeFA2Ea97084D \ + --ft-metadata-path docs/res/ft_metadata.json || error_exit +sleep 2 + +# Upgrading Aurora EVM to 2.10.0. +version=$(aurora-cli --engine $ENGINE_ACCOUNT get-version || error_exit) +assert_eq "$version" $AURORA_PREV_VERSION +echo "$version" +curl -sL $ENGINE_LAST_WASM_URL -o $ENGINE_WASM_PATH || error_exit +aurora-cli --engine $ENGINE_ACCOUNT stage-upgrade $ENGINE_WASM_PATH || error_exit +sleep 2 +aurora-cli --engine $ENGINE_ACCOUNT deploy-upgrade || error_exit +sleep 1 +version=$(aurora-cli --engine $ENGINE_ACCOUNT get-version || error_exit) +assert_eq "$version" $AURORA_LAST_VERSION +echo "$version" + +# Create account id for key manager +aurora-cli create-account --account $MANAGER_ACCOUNT --balance 10 > $MANAGER_KEY_PATH || error_exit +sleep 1 + +# Set key manager +aurora-cli --engine $ENGINE_ACCOUNT set-key-manager $MANAGER_ACCOUNT || error_exit +sleep 1 + +# Create new keys for relayer +aurora-cli generate-near-key $ENGINE_ACCOUNT ed25519 > $RELAYER_KEY_PATH || error_exit +relayer_public_key="$(jq -r .public_key < $RELAYER_KEY_PATH)" + +# Add relayer key by key manager +export NEAR_KEY_PATH=$MANAGER_KEY_PATH +aurora-cli --engine $ENGINE_ACCOUNT add-relayer-key --public-key "$relayer_public_key" --allowance "0.5" || error_exit +sleep 1 + +# Deploy Hello World EVM code with relayer key. +export NEAR_KEY_PATH=$RELAYER_KEY_PATH +aurora-cli --engine $ENGINE_ACCOUNT deploy --code "$EVM_CODE" --aurora-secret-key $AURORA_SECRET_KEY || error_exit +sleep 1 +result=$(aurora-cli --engine $ENGINE_ACCOUNT view-call -a 0xa3078bf607d2e859dca0b1a13878ec2e607f30de -f greet \ + --abi-path $ABI_PATH || error_exit) +assert_eq "$result" "Hello, World!" +sleep 1 + +# Remove relayer key +export NEAR_KEY_PATH=$MANAGER_KEY_PATH +aurora-cli --engine $ENGINE_ACCOUNT remove-relayer-key "$relayer_public_key" || error_exit +sleep 1 + +# Deploy Counter EVM code. +export NEAR_KEY_PATH=$AURORA_KEY_PATH +EVM_CODE=$(cat docs/res/Counter.hex) +ABI_PATH=docs/res/Counter.abi +aurora-cli --engine $ENGINE_ACCOUNT deploy --code $EVM_CODE --abi-path $ABI_PATH --args '{"init_value":"5"}' \ + --aurora-secret-key $AURORA_SECRET_KEY || error_exit +sleep 1 +result=$(aurora-cli --engine $ENGINE_ACCOUNT view-call -a 0x4cf003049d1a9c4918c73e9bf62464d904184555 -f value \ + --abi-path $ABI_PATH || error_exit) +assert_eq "$result" "5" +sleep 1 +aurora-cli --engine $ENGINE_ACCOUNT call -a 0x4cf003049d1a9c4918c73e9bf62464d904184555 -f increment \ + --abi-path $ABI_PATH \ + --aurora-secret-key 611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c || error_exit +sleep 1 +result=$(aurora-cli --engine $ENGINE_ACCOUNT view-call -a 0x4cf003049d1a9c4918c73e9bf62464d904184555 -f value \ + --abi-path $ABI_PATH || error_exit) +assert_eq "$result" "6" +sleep 1 +aurora-cli --engine $ENGINE_ACCOUNT call -a 0x4cf003049d1a9c4918c73e9bf62464d904184555 -f decrement \ + --abi-path $ABI_PATH \ + --aurora-secret-key 611830d3641a68f94a690dcc25d1f4b0dac948325ac18f6dd32564371735f32c || error_exit +sleep 1 +result=$(aurora-cli --engine $ENGINE_ACCOUNT view-call -a 0x4cf003049d1a9c4918c73e9bf62464d904184555 -f value \ + --abi-path $ABI_PATH || error_exit) +assert_eq "$result" "5" +sleep 1 + +# Check read operations. +aurora-cli --engine $ENGINE_ACCOUNT get-chain-id || error_exit +aurora-cli --engine $ENGINE_ACCOUNT get-owner || error_exit +aurora-cli --engine $ENGINE_ACCOUNT get-bridge-prover || error_exit +aurora-cli --engine $ENGINE_ACCOUNT get-balance 0x04b678962787ccd195a8e324d4c6bc4d5727f82b || error_exit +aurora-cli --engine $ENGINE_ACCOUNT get-code 0xa3078bf607d2e859dca0b1a13878ec2e607f30de || error_exit +aurora-cli key-pair --seed 1 || error_exit +block_hash=$(aurora-cli --network mainnet get-block-hash 88300374 || error_exit) +assert_eq "$block_hash" "0xd31857e9ce14083a7a74092b71f9ac48b8c0d4988ad40074182c1f0ffa296ec5" + +# Register a new relayer address +aurora-cli --engine $ENGINE_ACCOUNT register-relayer 0xf644ad75e048eaeb28844dd75bd384984e8cd508 || error_exit +sleep 1 + +# Set a new owner. The functionality has not been released yet. +aurora-cli --engine $ENGINE_ACCOUNT set-owner node0 || error_exit +sleep 1 +owner=$(aurora-cli --engine $ENGINE_ACCOUNT get-owner || error_exit) +assert_eq "$owner" node0 +export NEAR_KEY_PATH=$NODE_KEY_PATH +aurora-cli --engine $ENGINE_ACCOUNT set-owner aurora.node0 || error_exit +sleep 1 +owner=$(aurora-cli --engine $ENGINE_ACCOUNT get-owner || error_exit) +assert_eq "$owner" $ENGINE_ACCOUNT + +# XCC router operations. +# Download XCC router contract. +curl -sL $XCC_ROUTER_LAST_WASM_URL -o $XCC_ROUTER_WASM_PATH || error_exit +aurora-cli --engine $ENGINE_ACCOUNT factory-update $XCC_ROUTER_WASM_PATH || error_exit +sleep 1 +aurora-cli --engine $ENGINE_ACCOUNT factory-set-wnear-address 0x80c6a002756e29b8bf2a587f7d975a726d5de8b9 || error_exit +sleep 1 +# aurora-cli --engine $ENGINE_ACCOUNT fund-xcc-sub-account 0x43a4969cc2c22d0000c591ff4bd71983ea8a8be9 some_account.near 25.5 || error_exit + +# Change upgrade delay blocks. +blocks=$(aurora-cli --engine $ENGINE_ACCOUNT get-upgrade-delay-blocks || error_exit) +assert_eq "$blocks" 1 # 1 is set on init stage +aurora-cli --engine $ENGINE_ACCOUNT set-upgrade-delay-blocks 5 || error_exit +sleep 1 +blocks=$(aurora-cli --engine $ENGINE_ACCOUNT get-upgrade-delay-blocks || error_exit) +assert_eq "$blocks" 5 + +# Stop NEAR node and clean up. +finish diff --git a/scripts/simple.sh b/scripts/simple.sh index be9a4aa..eed2fad 100755 --- a/scripts/simple.sh +++ b/scripts/simple.sh @@ -21,6 +21,8 @@ ENGINE_ACCOUNT=aurora.node0 MANAGER_ACCOUNT=key-manager.aurora.node0 export PATH="$PATH:$USER_BASE_BIN:$HOME/.cargo/bin" +export PATH="$HOME/NearProtocol/aurora/aurora-cli-rs/target/debug/:$PATH:$USER_BASE_BIN" + # Install `nearup` utility if not installed before. pip3 list | grep nearup > /dev/null || pip3 install --user nearup diff --git a/src/cli/mod.rs b/src/cli/mod.rs index b55084c..8ffc6e0 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -4,10 +4,10 @@ mod advanced; pub mod simple; #[cfg(feature = "advanced")] -pub use advanced::{aurora, near, process_tx_data, run, Cli, Command}; +pub use advanced::{run, Cli}; #[cfg(feature = "simple")] -pub use simple::{command, run, Cli, Command}; +pub use simple::{command, run, Cli}; /// NEAR Endpoints. const NEAR_MAINNET_ENDPOINT: &str = "https://archival-rpc.mainnet.near.org/"; diff --git a/src/cli/simple/command/mod.rs b/src/cli/simple/command/mod.rs index a8203a6..41f15b6 100644 --- a/src/cli/simple/command/mod.rs +++ b/src/cli/simple/command/mod.rs @@ -18,11 +18,12 @@ use aurora_engine_types::public_key::{KeyType, PublicKey}; use aurora_engine_types::types::Address; use aurora_engine_types::{types::Wei, H256, U256}; use near_primitives::views::{CallResult, FinalExecutionStatus}; -use serde_json::Value; +use serde_json::{to_string_pretty, Value}; +use crate::cli::simple::OutputFormat; use crate::cli::simple::WithdrawSerialization; use crate::{ - client::Client, + client::Context, utils::{self, hex_to_address, hex_to_arr, hex_to_vec, near_to_yocto, secret_key_from_hex}, }; @@ -40,63 +41,63 @@ macro_rules! contract_call { } /// Return `chain_id` of the current network. -pub async fn get_chain_id(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_chain_id", None).await +pub async fn get_chain_id(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_chain_id", None).await } /// Return version of the Aurora EVM. -pub async fn get_version(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_version", None).await +pub async fn get_version(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_version", None).await } /// Return owner of the Aurora EVM. -pub async fn get_owner(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_owner", None).await +pub async fn get_owner(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_owner", None).await } /// Return bridge prover of the Aurora EVM. -pub async fn get_bridge_prover(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_bridge_prover", None).await +pub async fn get_bridge_prover(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_bridge_prover", None).await } /// Return nonce for the address. -pub async fn get_nonce(client: Client, address: String) -> anyhow::Result<()> { +pub async fn get_nonce(context: Context, address: String) -> anyhow::Result<()> { let address = hex_to_vec(&address)?; - get_value::(client, "get_nonce", Some(address)).await + get_value::(context, "get_nonce", Some(address)).await } /// Return a height, after which an upgrade could be done. -pub async fn get_upgrade_index(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_upgrade_index", None).await +pub async fn get_upgrade_index(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_upgrade_index", None).await } /// Return a delay in block for an upgrade. -pub async fn get_upgrade_delay_blocks(client: Client) -> anyhow::Result<()> { - get_value::(client, "get_upgrade_delay_blocks", None).await +pub async fn get_upgrade_delay_blocks(context: Context) -> anyhow::Result<()> { + get_value::(context, "get_upgrade_delay_blocks", None).await } /// Return ETH balance of the address. -pub async fn get_balance(client: Client, address: String) -> anyhow::Result<()> { +pub async fn get_balance(context: Context, address: String) -> anyhow::Result<()> { let address = hex_to_vec(&address)?; - get_value::(client, "get_balance", Some(address)).await + get_value::(context, "get_balance", Some(address)).await } /// Return a hex code of the smart contract. -pub async fn get_code(client: Client, address: String) -> anyhow::Result<()> { +pub async fn get_code(context: Context, address: String) -> anyhow::Result<()> { let address = hex_to_vec(&address)?; - get_value::(client, "get_code", Some(address)).await + get_value::(context, "get_code", Some(address)).await } /// Return a block hash of the specified height. -pub async fn get_block_hash(client: Client, height: u64) -> anyhow::Result<()> { +pub async fn get_block_hash(context: Context, height: u64) -> anyhow::Result<()> { let height = height.to_le_bytes().to_vec(); - get_value::(client, "get_block_hash", Some(height)).await + get_value::(context, "get_block_hash", Some(height)).await } /// Deploy Aurora EVM smart contract. -pub async fn deploy_aurora + Send>(client: Client, path: P) -> anyhow::Result<()> { +pub async fn deploy_aurora + Send>(context: Context, path: P) -> anyhow::Result<()> { let code = std::fs::read(path)?; - let result = match client.near().deploy_contract(code).await { + let result = match context.client.near().deploy_contract(code).await { Ok(outcome) => match outcome.status { FinalExecutionStatus::SuccessValue(_) => { "Aurora EVM has been deployed successfully".to_string() @@ -113,7 +114,7 @@ pub async fn deploy_aurora + Send>(client: Client, path: P) -> an /// Initialize Aurora EVM smart contract. pub async fn init( - client: Client, + context: Context, chain_id: u64, owner_id: Option, bridge_prover: Option, @@ -121,8 +122,8 @@ pub async fn init( custodian_address: Option, ft_metadata_path: Option, ) -> anyhow::Result<()> { - let owner_id = to_account_id(owner_id, &client)?; - let prover_id = to_account_id(bridge_prover, &client)?; + let owner_id = to_account_id(owner_id, &context)?; + let prover_id = to_account_id(bridge_prover, &context)?; let aurora_init_args = NewCallArgs::V2(NewCallArgsV2 { chain_id: H256::from_low_u64_be(chain_id).into(), @@ -148,7 +149,13 @@ pub async fn init( ("new_eth_connector".to_string(), eth_connector_init_args), ]; - match client.near().contract_call_batch(batch).await?.status { + match context + .client + .near() + .contract_call_batch(batch) + .await? + .status + { FinalExecutionStatus::Failure(e) => { anyhow::bail!("Error while initializing Aurora EVM: {e}") } @@ -165,7 +172,7 @@ pub async fn init( /// Deploy EVM byte code. pub async fn deploy_evm_code( - client: Client, + context: Context, code: String, abi_path: Option, args: Option, @@ -188,7 +195,8 @@ pub async fn deploy_evm_code( hex::decode(code)? }; - let result = client + let result = context + .client .near() .send_aurora_transaction(&sk, None, Wei::zero(), input) .await?; @@ -220,11 +228,16 @@ pub async fn deploy_evm_code( /// Creates new NEAR account. pub async fn create_account( - client: Client, + context: Context, account: &str, initial_balance: f64, ) -> anyhow::Result<()> { - match client.near().create_account(account, initial_balance).await { + match context + .client + .near() + .create_account(account, initial_balance) + .await + { Ok(result) => println!("{result}"), Err(e) => eprintln!("{e:?}"), } @@ -233,8 +246,8 @@ pub async fn create_account( } /// View new NEAR account. -pub async fn view_account(client: Client, account: &str) -> anyhow::Result<()> { - match client.near().view_account(account).await { +pub async fn view_account(context: Context, account: &str) -> anyhow::Result<()> { + match context.client.near().view_account(account).await { Ok(result) => println!("{result}"), Err(e) => eprintln!("{e:?}"), } @@ -244,7 +257,7 @@ pub async fn view_account(client: Client, account: &str) -> anyhow::Result<()> { /// Read-only call of the EVM smart contract. pub async fn view_call( - client: Client, + context: Context, address: String, function: String, args: Option, @@ -256,7 +269,8 @@ pub async fn view_call( let args: Value = args.map_or(Ok(Value::Null), |args| serde_json::from_str(&args))?; let tokens = utils::abi::parse_args(&func.inputs, &args)?; let input = func.encode_input(&tokens)?; - let result = client + let result = context + .client .near() .view_contract_call(Address::default(), target, Wei::zero(), input) .await?; @@ -278,7 +292,7 @@ pub async fn view_call( /// Modifying call of the EVM smart contract. pub async fn call( - client: Client, + context: Context, address: String, function: String, args: Option, @@ -299,7 +313,8 @@ pub async fn call( .and_then(|a| U256::from_dec_str(&a).ok()) .map_or_else(Wei::zero, Wei::new); - let result = client + let result = context + .client .near() .send_aurora_transaction(&sk, Some(target), amount, input) .await?; @@ -331,7 +346,7 @@ pub async fn call( } /// Upgrade Aurora Contract with provided code. -pub async fn upgrade + Send>(client: Client, path: P) -> anyhow::Result<()> { +pub async fn upgrade + Send>(context: Context, path: P) -> anyhow::Result<()> { let code = std::fs::read(path)?; contract_call!( @@ -339,12 +354,12 @@ pub async fn upgrade + Send>(client: Client, path: P) -> anyhow:: "The aurora contract has been upgraded successfully", "Error while upgrading the aurora smart contract" ) - .proceed(client, code) + .proceed(context, code) .await } /// Stage code for delayed upgrade. -pub async fn stage_upgrade + Send>(client: Client, path: P) -> anyhow::Result<()> { +pub async fn stage_upgrade + Send>(context: Context, path: P) -> anyhow::Result<()> { let code = std::fs::read(path)?; contract_call!( @@ -352,23 +367,23 @@ pub async fn stage_upgrade + Send>(client: Client, path: P) -> an "The code has been saved for staged upgrade successfully", "Error while staging code for upgrade" ) - .proceed(client, code) + .proceed(context, code) .await } /// Deploy staged upgrade. -pub async fn deploy_upgrade(client: Client) -> anyhow::Result<()> { +pub async fn deploy_upgrade(context: Context) -> anyhow::Result<()> { contract_call!( "deploy_upgrade", "The upgrade has been applied successfully", "Error while deploying upgrade" ) - .proceed(client, vec![]) + .proceed(context, vec![]) .await } /// Updates the bytecode for user's router contracts. -pub async fn factory_update(client: Client, path: String) -> anyhow::Result<()> { +pub async fn factory_update(context: Context, path: String) -> anyhow::Result<()> { let code = std::fs::read(path)?; contract_call!( @@ -376,17 +391,17 @@ pub async fn factory_update(client: Client, path: String) -> anyhow::Result<()> "The bytecode of user's router contract has been updated successfully", "Error while updating the bytecode of user's router contract" ) - .proceed(client, code) + .proceed(context, code) .await } /// Returns the address of the `wNEAR` ERC-20 contract -pub async fn factory_get_wnear_address(client: Client) -> anyhow::Result<()> { - get_value::(client, "factory_get_wnear_address", None).await +pub async fn factory_get_wnear_address(context: Context) -> anyhow::Result<()> { + get_value::(context, "factory_get_wnear_address", None).await } /// Sets the address for the `wNEAR` ERC-20 contract -pub async fn factory_set_wnear_address(client: Client, address: String) -> anyhow::Result<()> { +pub async fn factory_set_wnear_address(context: Context, address: String) -> anyhow::Result<()> { let args: [u8; 20] = hex_to_arr(&address)?; contract_call!( @@ -394,13 +409,13 @@ pub async fn factory_set_wnear_address(client: Client, address: String) -> anyho "The wnear address has been set successfully", "Error while upgrading wnear address" ) - .proceed(client, args.to_vec()) + .proceed(context, args.to_vec()) .await } /// Create and/or fund an XCC sub-account directly pub async fn fund_xcc_sub_account( - client: Client, + context: Context, target: String, account_id: Option, deposit: f64, @@ -418,12 +433,12 @@ pub async fn fund_xcc_sub_account( "The XCC sub-account has been funded successfully", "Error while funding XCC sub-account" ) - .proceed_with_deposit(client, args, deposit) + .proceed_with_deposit(context, args, deposit) .await } /// Set a new owner of the Aurora EVM. -pub async fn set_owner(client: Client, account_id: String) -> anyhow::Result<()> { +pub async fn set_owner(context: Context, account_id: String) -> anyhow::Result<()> { let args = SetOwnerArgs { new_owner: account_id.parse().map_err(|e| anyhow::anyhow!("{e}"))?, } @@ -434,12 +449,12 @@ pub async fn set_owner(client: Client, account_id: String) -> anyhow::Result<()> "The owner has been changed successfully", "Error while setting a new owner" ) - .proceed(client, args) + .proceed(context, args) .await } /// Register relayer address. -pub async fn register_relayer(client: Client, address: String) -> anyhow::Result<()> { +pub async fn register_relayer(context: Context, address: String) -> anyhow::Result<()> { let args = hex_to_vec(&address)?; contract_call!( @@ -447,12 +462,12 @@ pub async fn register_relayer(client: Client, address: String) -> anyhow::Result "The new relayer has been registered successfully", "Error while registering a new relayer" ) - .proceed(client, args) + .proceed(context, args) .await } /// Return value in storage for key at address. -pub async fn get_storage_at(client: Client, address: String, key: String) -> anyhow::Result<()> { +pub async fn get_storage_at(context: Context, address: String, key: String) -> anyhow::Result<()> { let address = hex_to_address(&address)?; let key = H256::from_str(&key)?; let input = GetStorageAtArgs { @@ -461,7 +476,7 @@ pub async fn get_storage_at(client: Client, address: String, key: String) -> any } .try_to_vec()?; - get_value::(client, "get_storage_at", Some(input)).await + get_value::(context, "get_storage_at", Some(input)).await } /// Return EVM address from NEAR account. @@ -503,7 +518,7 @@ pub fn gen_near_key(account_id: &str, key_type: KeyType) -> anyhow::Result<()> { } /// Pause precompiles with mask. -pub async fn pause_precompiles(client: Client, mask: u32) -> anyhow::Result<()> { +pub async fn pause_precompiles(context: Context, mask: u32) -> anyhow::Result<()> { let args = PausePrecompilesCallArgs { paused_mask: mask }.try_to_vec()?; contract_call!( @@ -511,12 +526,12 @@ pub async fn pause_precompiles(client: Client, mask: u32) -> anyhow::Result<()> "The precompiles have been paused successfully", "Error while pausing precompiles" ) - .proceed(client, args) + .proceed(context, args) .await } /// Resume precompiles with mask. -pub async fn resume_precompiles(client: Client, mask: u32) -> anyhow::Result<()> { +pub async fn resume_precompiles(context: Context, mask: u32) -> anyhow::Result<()> { let args = PausePrecompilesCallArgs { paused_mask: mask }.try_to_vec()?; contract_call!( @@ -524,17 +539,20 @@ pub async fn resume_precompiles(client: Client, mask: u32) -> anyhow::Result<()> "The precompiles have been resumed successfully", "Error while resuming precompiles" ) - .proceed(client, args) + .proceed(context, args) .await } /// Return paused precompiles. -pub async fn paused_precompiles(client: Client) -> anyhow::Result<()> { - get_value::(client, "paused_precompiles", None).await +pub async fn paused_precompiles(context: Context) -> anyhow::Result<()> { + get_value::(context, "paused_precompiles", None).await } /// Set relayer key manager. -pub async fn set_key_manager(client: Client, key_manager: Option) -> anyhow::Result<()> { +pub async fn set_key_manager( + context: Context, + key_manager: Option, +) -> anyhow::Result<()> { let message = key_manager.as_ref().map_or_else( || "has been removed".to_string(), |account_id| format!("{account_id} has been set"), @@ -546,13 +564,13 @@ pub async fn set_key_manager(client: Client, key_manager: Option) -> "The key manager {message} successfully", "Error while setting key manager" ) - .proceed(client, args) + .proceed(context, args) .await } /// Add relayer public key. pub async fn add_relayer_key( - client: Client, + context: Context, public_key: PublicKey, allowance: f64, ) -> anyhow::Result<()> { @@ -563,12 +581,12 @@ pub async fn add_relayer_key( "The public key: {public_key} has been added successfully", "Error while adding public key" ) - .proceed_with_deposit(client, args, allowance) + .proceed_with_deposit(context, args, allowance) .await } /// Remove relayer public key. -pub async fn remove_relayer_key(client: Client, public_key: PublicKey) -> anyhow::Result<()> { +pub async fn remove_relayer_key(context: Context, public_key: PublicKey) -> anyhow::Result<()> { let args = serde_json::to_vec(&RelayerKeyArgs { public_key })?; contract_call!( @@ -576,12 +594,12 @@ pub async fn remove_relayer_key(client: Client, public_key: PublicKey) -> anyhow "The public key: {public_key} has been removed successfully", "Error while removing public key" ) - .proceed(client, args) + .proceed(context, args) .await } /// Set a delay in blocks for an upgrade. -pub async fn set_upgrade_delay_blocks(client: Client, blocks: u64) -> anyhow::Result<()> { +pub async fn set_upgrade_delay_blocks(context: Context, blocks: u64) -> anyhow::Result<()> { let args = SetUpgradeDelayBlocksArgs { upgrade_delay_blocks: blocks, } @@ -592,27 +610,31 @@ pub async fn set_upgrade_delay_blocks(client: Client, blocks: u64) -> anyhow::Re "Upgrade delay blocks: {blocks} has been set successfully", "Error while setting upgrade delay blocks" ) - .proceed(client, args) + .proceed(context, args) .await } /// Get ERC-20 address from account id of NEP-141. -pub async fn get_erc20_from_nep141(client: Client, account_id: String) -> anyhow::Result<()> { +pub async fn get_erc20_from_nep141(context: Context, account_id: String) -> anyhow::Result<()> { let args = account_id.try_to_vec()?; - get_value::(client, "get_erc20_from_nep141", Some(args)).await + get_value::(context, "get_erc20_from_nep141", Some(args)).await } /// Get NEP-141 account id from address of ERC-20. -pub async fn get_nep141_from_erc20(client: Client, address: String) -> anyhow::Result<()> { +pub async fn get_nep141_from_erc20(context: Context, address: String) -> anyhow::Result<()> { let args = hex_to_address(&address)?.as_bytes().to_vec(); - get_value::(client, "get_nep141_from_erc20", Some(args)).await + get_value::(context, "get_nep141_from_erc20", Some(args)).await } /// Get a metadata of ERC-20 contract. -pub async fn get_erc20_metadata(client: Client, identifier: String) -> anyhow::Result<()> { +pub async fn get_erc20_metadata(context: Context, identifier: String) -> anyhow::Result<()> { let args = str_to_identifier(&identifier) .and_then(|id| serde_json::to_vec(&id).map_err(Into::into))?; - let result = client.near().view_call("get_erc20_metadata", args).await?; + let result = context + .client + .near() + .view_call("get_erc20_metadata", args) + .await?; let output = serde_json::from_slice::(&result.result) .and_then(|metadata| serde_json::to_string_pretty(&metadata))?; @@ -623,7 +645,7 @@ pub async fn get_erc20_metadata(client: Client, identifier: String) -> anyhow::R /// Set a metadata of ERC-20 contract. pub async fn set_erc20_metadata( - client: Client, + context: Context, identifier: String, name: String, symbol: String, @@ -644,13 +666,13 @@ pub async fn set_erc20_metadata( "ERC-20 metadata has been set successfully", "Error while setting ERC-20 metadata" ) - .proceed(client, args) + .proceed(context, args) .await } /// Mirror ERC-20 contract. pub async fn mirror_erc20_token( - client: Client, + context: Context, contract_id: String, nep141: String, ) -> anyhow::Result<()> { @@ -665,13 +687,13 @@ pub async fn mirror_erc20_token( "ERC-20 token has been mirrored successfully", "Error while mirroring ERC-20 token" ) - .proceed(client, args) + .proceed(context, args) .await } /// Set ETH connector account id pub async fn set_eth_connector_account_id( - client: Client, + context: Context, account_id: String, withdraw_ser: Option, ) -> anyhow::Result<()> { @@ -689,16 +711,17 @@ pub async fn set_eth_connector_account_id( "ETH connector account has been set successfully", "Error while setting ETH connector account" ) - .proceed(client, args) + .proceed(context, args) .await } async fn get_value( - client: Client, + context: Context, method_name: &str, args: Option>, ) -> anyhow::Result<()> { - let result = client + let result = context + .client .near() .view_call(method_name, args.unwrap_or_default()) .await?; @@ -708,10 +731,11 @@ async fn get_value( Ok(()) } -fn to_account_id(id: Option, client: &Client) -> anyhow::Result { +fn to_account_id(id: Option, context: &Context) -> anyhow::Result { id.map_or_else( || { - client + context + .client .near() .engine_account_id .to_string() @@ -798,18 +822,19 @@ struct ContractCall<'a> { } impl ContractCall<'_> { - async fn proceed(&self, client: Client, args: Vec) -> anyhow::Result<()> { - self.proceed_with_deposit(client, args, 0.0).await + async fn proceed(&self, context: Context, args: Vec) -> anyhow::Result<()> { + self.proceed_with_deposit(context, args, 0.0).await } async fn proceed_with_deposit( &self, - client: Client, + context: Context, args: Vec, deposit: f64, ) -> anyhow::Result<()> { let yocto = near_to_yocto(deposit); - let result = client + let result = context + .client .near() .contract_call_with_deposit(self.method, args, yocto) .await?; @@ -821,9 +846,17 @@ impl ContractCall<'_> { FinalExecutionStatus::Failure(e) => { anyhow::bail!("{}: {e}", self.error_message) } - FinalExecutionStatus::SuccessValue(_) => { - println!("{}", self.success_message); - } + FinalExecutionStatus::SuccessValue(_) => match context.output_format { + OutputFormat::Plain => println!("{}", self.success_message), + OutputFormat::Json => { + let formatted = to_string_pretty(&result.transaction_outcome)?; + println!("{formatted}"); + } + OutputFormat::Toml => { + let formatted = toml::to_string_pretty(&result.transaction_outcome)?; + println!("{formatted}"); + } + }, } Ok(()) diff --git a/src/cli/simple/command/silo.rs b/src/cli/simple/command/silo.rs index 1a6040b..c087d86 100644 --- a/src/cli/simple/command/silo.rs +++ b/src/cli/simple/command/silo.rs @@ -9,17 +9,17 @@ use std::fmt::{Display, Formatter}; use super::{get_value, ContractCall}; use crate::cli::command::FromCallResult; -use crate::client::Client; +use crate::client::Context; use crate::contract_call; use crate::utils::hex_to_address; /// Return fixed gas cost. -pub async fn get_fixed_gas_cost(client: Client) -> anyhow::Result<()> { +pub async fn get_fixed_gas_cost(client: Context) -> anyhow::Result<()> { get_value::(client, "get_fixed_gas", None).await } /// Set fixed gas cost. -pub async fn set_fixed_gas(client: Client, cost: u64) -> anyhow::Result<()> { +pub async fn set_fixed_gas(client: Context, cost: u64) -> anyhow::Result<()> { let args = FixedGasArgs { fixed_gas: Some(EthGas::new(cost)), } @@ -35,7 +35,7 @@ pub async fn set_fixed_gas(client: Client, cost: u64) -> anyhow::Result<()> { } pub async fn set_silo_params( - client: Client, + client: Context, gas: u64, fallback_address: String, ) -> anyhow::Result<()> { @@ -55,7 +55,7 @@ pub async fn set_silo_params( } /// Get a status of the whitelist. -pub async fn get_whitelist_status(client: Client, kind: String) -> anyhow::Result<()> { +pub async fn get_whitelist_status(client: Context, kind: String) -> anyhow::Result<()> { let args = WhitelistKindArgs { kind: get_kind(&kind)?, } @@ -65,7 +65,7 @@ pub async fn get_whitelist_status(client: Client, kind: String) -> anyhow::Resul } /// Set a status of the whitelist. -pub async fn set_whitelist_status(client: Client, kind: String, status: u8) -> anyhow::Result<()> { +pub async fn set_whitelist_status(client: Context, kind: String, status: u8) -> anyhow::Result<()> { let args = WhitelistStatusArgs { kind: get_kind(&kind)?, active: status > 0, @@ -84,7 +84,7 @@ pub async fn set_whitelist_status(client: Client, kind: String, status: u8) -> a /// Add an entry to the whitelist. pub async fn add_entry_to_whitelist( - client: Client, + client: Context, kind: String, entry: String, ) -> anyhow::Result<()> { @@ -100,7 +100,7 @@ pub async fn add_entry_to_whitelist( } /// Add a batch of entries to the whitelist. -pub async fn add_entry_to_whitelist_batch(client: Client, path: String) -> anyhow::Result<()> { +pub async fn add_entry_to_whitelist_batch(client: Context, path: String) -> anyhow::Result<()> { let args = std::fs::read_to_string(path) .and_then(|string| serde_json::from_str::>(&string).map_err(Into::into)) .and_then(|entries| entries.try_to_vec())?; @@ -116,7 +116,7 @@ pub async fn add_entry_to_whitelist_batch(client: Client, path: String) -> anyho /// Remove an entry from the whitelist. pub async fn remove_entry_from_whitelist( - client: Client, + client: Context, kind: String, entry: String, ) -> anyhow::Result<()> { diff --git a/src/cli/simple/mod.rs b/src/cli/simple/mod.rs index a3ae690..e76911e 100644 --- a/src/cli/simple/mod.rs +++ b/src/cli/simple/mod.rs @@ -30,6 +30,9 @@ pub struct Cli { /// Aurora EVM account #[arg(long, value_name = "ACCOUNT_ID", default_value = "aurora")] pub engine: String, + /// The way output of a command would be formatted + #[arg(long, default_value = "plain")] + pub output_format: OutputFormat, /// Path to file with NEAR account id and secret key in JSON format #[arg(long)] pub near_key_path: Option, @@ -354,6 +357,27 @@ impl FromStr for Network { } } +#[derive(Default, Clone)] +pub enum OutputFormat { + #[default] + Plain, + Json, + Toml, +} + +impl FromStr for OutputFormat { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "plain" => Ok(Self::Plain), + "json" => Ok(Self::Json), + "toml" => Ok(Self::Toml), + _ => anyhow::bail!("unknown output format: {s}"), + } + } +} + #[derive(Clone)] pub enum WithdrawSerialization { Borsh, @@ -379,18 +403,19 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { Network::Localnet => super::NEAR_LOCAL_ENDPOINT, }; let client = crate::client::Client::new(near_rpc, &args.engine, args.near_key_path); + let context = crate::client::Context::new(client, args.output_format); match args.command { - Command::GetChainId => command::get_chain_id(client).await?, - Command::GetVersion => command::get_version(client).await?, - Command::GetOwner => command::get_owner(client).await?, - Command::SetOwner { account_id } => command::set_owner(client, account_id).await?, - Command::RegisterRelayer { address } => command::register_relayer(client, address).await?, - Command::GetBridgeProver => command::get_bridge_prover(client).await?, - Command::GetNonce { address } => command::get_nonce(client, address).await?, - Command::GetCode { address } => command::get_code(client, address).await?, - Command::GetBalance { address } => command::get_balance(client, address).await?, - Command::GetBlockHash { height } => command::get_block_hash(client, height).await?, + Command::GetChainId => command::get_chain_id(context).await?, + Command::GetVersion => command::get_version(context).await?, + Command::GetOwner => command::get_owner(context).await?, + Command::SetOwner { account_id } => command::set_owner(context, account_id).await?, + Command::RegisterRelayer { address } => command::register_relayer(context, address).await?, + Command::GetBridgeProver => command::get_bridge_prover(context).await?, + Command::GetNonce { address } => command::get_nonce(context, address).await?, + Command::GetCode { address } => command::get_code(context, address).await?, + Command::GetBalance { address } => command::get_balance(context, address).await?, + Command::GetBlockHash { height } => command::get_block_hash(context, height).await?, Command::Call { address, function, @@ -400,7 +425,7 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { aurora_secret_key, } => { command::call( - client, + context, address, function, args, @@ -415,28 +440,28 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { function, args, abi_path, - } => command::view_call(client, address, function, args, abi_path).await?, - Command::PausePrecompiles { mask } => command::pause_precompiles(client, mask).await?, - Command::ResumePrecompiles { mask } => command::resume_precompiles(client, mask).await?, - Command::PausedPrecompiles => command::paused_precompiles(client).await?, - Command::GetUpgradeIndex => command::get_upgrade_index(client).await?, - Command::FactoryUpdate { path } => command::factory_update(client, path).await?, - Command::FactoryGetWnearAddress => command::factory_get_wnear_address(client).await?, + } => command::view_call(context, address, function, args, abi_path).await?, + Command::PausePrecompiles { mask } => command::pause_precompiles(context, mask).await?, + Command::ResumePrecompiles { mask } => command::resume_precompiles(context, mask).await?, + Command::PausedPrecompiles => command::paused_precompiles(context).await?, + Command::GetUpgradeIndex => command::get_upgrade_index(context).await?, + Command::FactoryUpdate { path } => command::factory_update(context, path).await?, + Command::FactoryGetWnearAddress => command::factory_get_wnear_address(context).await?, Command::FactorySetWnearAddress { address } => { - command::factory_set_wnear_address(client, address).await?; + command::factory_set_wnear_address(context, address).await?; } Command::FundXccSubAccount { target, wnear_account_id, deposit, } => { - command::fund_xcc_sub_account(client, target, wnear_account_id, deposit).await?; + command::fund_xcc_sub_account(context, target, wnear_account_id, deposit).await?; } - Command::Upgrade { path } => command::upgrade(client, path).await?, - Command::StageUpgrade { path } => command::stage_upgrade(client, path).await?, - Command::DeployUpgrade => command::deploy_upgrade(client).await?, + Command::Upgrade { path } => command::upgrade(context, path).await?, + Command::StageUpgrade { path } => command::stage_upgrade(context, path).await?, + Command::DeployUpgrade => command::deploy_upgrade(context).await?, Command::GetStorageAt { address, key } => { - command::get_storage_at(client, address, key).await?; + command::get_storage_at(context, address, key).await?; } Command::Deploy { code, @@ -444,14 +469,14 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { args, aurora_secret_key, } => { - command::deploy_evm_code(client, code, abi_path, args, aurora_secret_key.as_deref()) + command::deploy_evm_code(context, code, abi_path, args, aurora_secret_key.as_deref()) .await?; } - Command::DeployAurora { path } => command::deploy_aurora(client, path).await?, + Command::DeployAurora { path } => command::deploy_aurora(context, path).await?, Command::CreateAccount { account, balance } => { - command::create_account(client, &account, balance).await?; + command::create_account(context, &account, balance).await?; } - Command::ViewAccount { account } => command::view_account(client, &account).await?, + Command::ViewAccount { account } => command::view_account(context, &account).await?, Command::Init { chain_id, owner_id, @@ -461,7 +486,7 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { ft_metadata_path, } => { command::init( - client, + context, chain_id, owner_id, bridge_prover_id, @@ -478,57 +503,57 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { key_type, } => command::gen_near_key(&account_id, key_type)?, // Silo Specific Methods - Command::GetFixedGas => command::silo::get_fixed_gas_cost(client).await?, + Command::GetFixedGas => command::silo::get_fixed_gas_cost(context).await?, Command::SetFixedGas { cost } => { - command::silo::set_fixed_gas(client, cost).await?; + command::silo::set_fixed_gas(context, cost).await?; } Command::SetSiloParams { gas, fallback_address, } => { - command::silo::set_silo_params(client, gas, fallback_address).await?; + command::silo::set_silo_params(context, gas, fallback_address).await?; } Command::GetWhitelistStatus { kind } => { - command::silo::get_whitelist_status(client, kind).await?; + command::silo::get_whitelist_status(context, kind).await?; } Command::SetWhitelistStatus { kind, status } => { - command::silo::set_whitelist_status(client, kind, status).await?; + command::silo::set_whitelist_status(context, kind, status).await?; } Command::AddEntryToWhitelist { kind, entry } => { - command::silo::add_entry_to_whitelist(client, kind, entry).await?; + command::silo::add_entry_to_whitelist(context, kind, entry).await?; } Command::AddEntryToWhitelistBatch { path } => { - command::silo::add_entry_to_whitelist_batch(client, path).await?; + command::silo::add_entry_to_whitelist_batch(context, path).await?; } Command::RemoveEntryFromWhitelist { kind, entry } => { - command::silo::remove_entry_from_whitelist(client, kind, entry).await?; + command::silo::remove_entry_from_whitelist(context, kind, entry).await?; } Command::SetKeyManager { account_id } => { - command::set_key_manager(client, account_id).await?; + command::set_key_manager(context, account_id).await?; } Command::AddRelayerKey { public_key, allowance, } => { - command::add_relayer_key(client, public_key, allowance).await?; + command::add_relayer_key(context, public_key, allowance).await?; } Command::RemoveRelayerKey { public_key } => { - command::remove_relayer_key(client, public_key).await?; + command::remove_relayer_key(context, public_key).await?; } Command::GetUpgradeDelayBlocks => { - command::get_upgrade_delay_blocks(client).await?; + command::get_upgrade_delay_blocks(context).await?; } Command::SetUpgradeDelayBlocks { blocks } => { - command::set_upgrade_delay_blocks(client, blocks).await?; + command::set_upgrade_delay_blocks(context, blocks).await?; } Command::GetErc20FromNep141 { account_id } => { - command::get_erc20_from_nep141(client, account_id).await?; + command::get_erc20_from_nep141(context, account_id).await?; } Command::GetNep141FromErc20 { address } => { - command::get_nep141_from_erc20(client, address).await?; + command::get_nep141_from_erc20(context, address).await?; } Command::GetErc20Metadata { erc20_id } => { - command::get_erc20_metadata(client, erc20_id).await?; + command::get_erc20_metadata(context, erc20_id).await?; } Command::SetErc20Metadata { erc20_id, @@ -536,19 +561,19 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { symbol, decimals, } => { - command::set_erc20_metadata(client, erc20_id, name, symbol, decimals).await?; + command::set_erc20_metadata(context, erc20_id, name, symbol, decimals).await?; } Command::MirrorErc20Token { contract_id, nep141, } => { - command::mirror_erc20_token(client, contract_id, nep141).await?; + command::mirror_erc20_token(context, contract_id, nep141).await?; } Command::SetEthConnectorAccountId { account_id, withdraw_ser, } => { - command::set_eth_connector_account_id(client, account_id, withdraw_ser).await?; + command::set_eth_connector_account_id(context, account_id, withdraw_ser).await?; } } diff --git a/src/client/mod.rs b/src/client/mod.rs index 5524e79..1812ff9 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -11,6 +11,9 @@ use thiserror::Error; pub use aurora::AuroraClient; pub use near::NearClient; +#[cfg(feature = "simple")] +use crate::cli::simple::OutputFormat; + #[cfg(feature = "advanced")] mod aurora; mod near; @@ -23,6 +26,22 @@ type NearCallError = near_jsonrpc_client::errors::JsonRpcError< near_jsonrpc_client::methods::broadcast_tx_commit::RpcTransactionError, >; +#[cfg(feature = "simple")] +pub struct Context { + pub client: Client, + pub output_format: OutputFormat, +} + +#[cfg(feature = "simple")] +impl Context { + pub const fn new(client: Client, output_format: OutputFormat) -> Self { + Self { + client, + output_format, + } + } +} + #[cfg(feature = "simple")] pub struct Client { near_rpc: String, diff --git a/src/main.rs b/src/main.rs index d4966a5..e7ad127 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,9 @@ #![deny(clippy::pedantic, clippy::nursery)] -#![allow(clippy::too_many_lines, clippy::module_name_repetitions)] +#![allow( + clippy::too_many_lines, + clippy::module_name_repetitions, + clippy::needless_raw_string_hashes +)] use clap::Parser; diff --git a/src/transaction_reader/filter.rs b/src/transaction_reader/filter.rs index 8f3b1c1..629a400 100644 --- a/src/transaction_reader/filter.rs +++ b/src/transaction_reader/filter.rs @@ -81,7 +81,9 @@ pub struct GeneralGasFilter { impl Filter for GeneralGasFilter { fn pass(&self, data: &TxData) -> bool { - let Some(near_gas_used) = data.gas_profile.get("TOTAL") else { return false }; + let Some(near_gas_used) = data.gas_profile.get("TOTAL") else { + return false; + }; let evm_gas_used = match &data.status { TxStatus::Executed(submit_result) => &submit_result.gas_used, _ => return false, diff --git a/src/transaction_reader/mod.rs b/src/transaction_reader/mod.rs index 5442ddc..03855c7 100644 --- a/src/transaction_reader/mod.rs +++ b/src/transaction_reader/mod.rs @@ -105,7 +105,7 @@ fn get_gas_profile(value: &Value) -> Option> { } })?; let profile = get_recursive(outcome.get("metadata")?, &["gas_profile"])?.as_array()?; - for entry in profile.iter() { + for entry in profile { let entry = entry.as_object()?; let name = entry.get("cost")?.as_str()?; let amount = entry.get("gas_used")?.as_str()?; diff --git a/src/utils/abi.rs b/src/utils/abi.rs index 3c8c8ff..22bfc0a 100644 --- a/src/utils/abi.rs +++ b/src/utils/abi.rs @@ -85,7 +85,9 @@ pub fn parse_arg(arg: &str, kind: ðabi::ParamType) -> anyhow::Result { } ethabi::ParamType::Tuple(tuple_kinds) => { let value: Value = serde_json::from_str(arg)?; - let Value::Array(values) = value else { anyhow::bail!("Expected Array"); }; + let Value::Array(values) = value else { + anyhow::bail!("Expected Array"); + }; if values.len() != tuple_kinds.len() { anyhow::bail!("Incorrect number of args for tuple size"); } diff --git a/src/utils/ft_metadata.rs b/src/utils/ft_metadata.rs index 00cfe51..73de824 100644 --- a/src/utils/ft_metadata.rs +++ b/src/utils/ft_metadata.rs @@ -2,7 +2,9 @@ use aurora_engine_types::borsh::BorshDeserialize; use aurora_engine_types::parameters::connector::{FungibleReferenceHash, FungibleTokenMetadata}; pub fn parse_ft_metadata(input: Option) -> anyhow::Result { - let Some(input) = input else { return Ok(default_ft_metadata()); }; + let Some(input) = input else { + return Ok(default_ft_metadata()); + }; let json: serde_json::Map = serde_json::from_str(&input)?; Ok(FungibleTokenMetadata { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 2254f1d..5236f53 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -83,7 +83,7 @@ pub fn hex_to_arr(hex: &str) -> anyhow::Result<[u8; SIZE]> { let mut output = [0u8; SIZE]; hex::decode_to_slice(hex.trim_start_matches("0x"), &mut output) - .map(|_| output) + .map(|()| output) .map_err(|e| anyhow::anyhow!("Couldn't create array from the hex: {hex}, {e}")) }