From 23bb067001aa728ab30283e8d37e97587d121d12 Mon Sep 17 00:00:00 2001 From: Amidamaru Date: Tue, 29 Aug 2023 03:36:57 +0700 Subject: [PATCH] feat: order networks selection based on the selected account id (bubble up more relevant networks) (#225) Co-authored-by: Vlad Frolov --- .../print_keypair_to_terminal/mod.rs | 32 +++++---- .../save_keypair_to_keychain/mod.rs | 41 ++++++----- .../save_keypair_to_macos_keychain/mod.rs | 32 +++++---- .../account/add_key/use_ledger/mod.rs | 32 +++++---- .../use_manually_provided_seed_phrase/mod.rs | 32 +++++---- .../account/add_key/use_public_key/mod.rs | 32 +++++---- .../fund_myself_create_account/mod.rs | 6 +- .../fund_myself_create_account/sign_as/mod.rs | 16 +++-- .../sponsor_by_faucet_service/network/mod.rs | 2 +- src/commands/account/delete_account/mod.rs | 26 ++++--- src/commands/account/delete_key/mod.rs | 35 ++++++---- .../import_account/using_private_key/mod.rs | 7 +- .../import_account/using_seed_phrase/mod.rs | 13 ++-- .../import_account/using_web_wallet/mod.rs | 5 +- src/commands/account/list_keys/mod.rs | 6 +- .../storage_management/storage_deposit.rs | 68 ++++++++++-------- .../storage_management/storage_withdraw.rs | 63 +++++++++-------- .../view_storage_balance.rs | 1 + .../account/view_account_summary/mod.rs | 7 +- src/commands/config/delete_connection/mod.rs | 2 +- .../call_function/as_read_only/mod.rs | 12 ++-- .../call_function/as_transaction/mod.rs | 33 +++++---- .../initialize_mode/call_function_type/mod.rs | 50 +++++++------ .../contract/deploy/initialize_mode/mod.rs | 30 +++++--- src/commands/contract/download_wasm/mod.rs | 9 +-- src/commands/mod.rs | 1 + src/commands/tokens/send_ft/mod.rs | 63 ++++++++++------- src/commands/tokens/send_near/mod.rs | 27 ++++--- src/commands/tokens/send_nft/mod.rs | 70 +++++++++++-------- src/commands/tokens/view_ft_balance/mod.rs | 12 ++-- src/commands/tokens/view_near_balance/mod.rs | 23 +++--- src/commands/tokens/view_nft_assets/mod.rs | 12 ++-- .../construct_transaction/skip_action/mod.rs | 22 ++++-- .../send_meta_transaction/sign_as/mod.rs | 30 ++++---- .../send_signed_transaction/network/mod.rs | 10 ++- .../transaction/sign_transaction/mod.rs | 24 ++++--- src/commands/transaction/view_status/mod.rs | 7 +- src/common.rs | 34 ++++++++- src/network/mod.rs | 4 +- src/network_for_transaction/mod.rs | 9 ++- src/network_view_at_block/mod.rs | 3 +- 41 files changed, 569 insertions(+), 374 deletions(-) diff --git a/src/commands/account/add_key/autogenerate_new_keypair/print_keypair_to_terminal/mod.rs b/src/commands/account/add_key/autogenerate_new_keypair/print_keypair_to_terminal/mod.rs index 45dd5cd21..c89e2451a 100644 --- a/src/commands/account/add_key/autogenerate_new_keypair/print_keypair_to_terminal/mod.rs +++ b/src/commands/account/add_key/autogenerate_new_keypair/print_keypair_to_terminal/mod.rs @@ -34,23 +34,29 @@ impl PrintKeypairToTerminalContext { impl From for crate::commands::ActionContext { fn from(item: PrintKeypairToTerminalContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.public_key.clone(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.public_key.clone(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs index 3ac03619c..b57ce68de 100644 --- a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs +++ b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_keychain/mod.rs @@ -35,27 +35,31 @@ impl SaveKeypairToKeychainContext { impl From for crate::commands::ActionContext { fn from(item: SaveKeypairToKeychainContext) -> Self { - let credentials_home_dir = item.global_context.config.credentials_home_dir.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.public_key.clone(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.public_key.clone(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); let on_before_sending_transaction_callback: crate::transaction_signature_options::OnBeforeSendingTransactionCallback = - std::sync::Arc::new( + std::sync::Arc::new({ + let credentials_home_dir = item.global_context.config.credentials_home_dir.clone(); + move |signed_transaction, network_config, storage_message| { let key_pair_properties_buf = serde_json::to_string(&item.key_pair_properties)?; *storage_message = crate::common::save_access_key_to_keychain( @@ -72,11 +76,12 @@ impl From for crate::commands::ActionContext { ) })?; Ok(()) - }, - ); + } + }); Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_macos_keychain/mod.rs b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_macos_keychain/mod.rs index 58c8573c2..86a89db84 100644 --- a/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_macos_keychain/mod.rs +++ b/src/commands/account/add_key/autogenerate_new_keypair/save_keypair_to_macos_keychain/mod.rs @@ -22,20 +22,24 @@ impl SaveKeypairToMacosKeychainContext { impl From for crate::commands::ActionContext { fn from(item: SaveKeypairToMacosKeychainContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.0.signer_account_id.clone(), - receiver_id: item.0.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.0.public_key.clone(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.0.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.0.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.0.public_key.clone(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.0.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); let on_before_sending_transaction_callback: crate::transaction_signature_options::OnBeforeSendingTransactionCallback = std::sync::Arc::new( @@ -49,8 +53,10 @@ impl From for crate::commands::ActionContext Ok(()) }, ); + Self { global_context: item.0.global_context, + interacting_with_account_ids: vec![item.0.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/add_key/use_ledger/mod.rs b/src/commands/account/add_key/use_ledger/mod.rs index 164be4c98..d0e9eef53 100644 --- a/src/commands/account/add_key/use_ledger/mod.rs +++ b/src/commands/account/add_key/use_ledger/mod.rs @@ -49,23 +49,29 @@ impl AddLedgerKeyActionContext { impl From for crate::commands::ActionContext { fn from(item: AddLedgerKeyActionContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.public_key.clone().into(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.public_key.clone().into(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/add_key/use_manually_provided_seed_phrase/mod.rs b/src/commands/account/add_key/use_manually_provided_seed_phrase/mod.rs index a47e6a783..0d75bf04a 100644 --- a/src/commands/account/add_key/use_manually_provided_seed_phrase/mod.rs +++ b/src/commands/account/add_key/use_manually_provided_seed_phrase/mod.rs @@ -41,23 +41,29 @@ impl AddAccessWithSeedPhraseActionContext { impl From for crate::commands::ActionContext { fn from(item: AddAccessWithSeedPhraseActionContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.public_key.clone(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.public_key.clone(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/add_key/use_public_key/mod.rs b/src/commands/account/add_key/use_public_key/mod.rs index c5a4f7815..d8668404e 100644 --- a/src/commands/account/add_key/use_public_key/mod.rs +++ b/src/commands/account/add_key/use_public_key/mod.rs @@ -34,23 +34,29 @@ impl AddAccessKeyActionContext { impl From for crate::commands::ActionContext { fn from(item: AddAccessKeyActionContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.signer_account_id.clone(), - actions: vec![near_primitives::transaction::Action::AddKey( - near_primitives::transaction::AddKeyAction { - public_key: item.public_key.clone().into(), - access_key: near_primitives::account::AccessKey { - nonce: 0, - permission: item.permission.clone(), + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: signer_account_id.clone(), + actions: vec![near_primitives::transaction::Action::AddKey( + near_primitives::transaction::AddKeyAction { + public_key: item.public_key.clone().into(), + access_key: near_primitives::account::AccessKey { + nonce: 0, + permission: item.permission.clone(), + }, }, - }, - )], - }) + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/create_account/fund_myself_create_account/mod.rs b/src/commands/account/create_account/fund_myself_create_account/mod.rs index 06b10641d..0059ce930 100644 --- a/src/commands/account/create_account/fund_myself_create_account/mod.rs +++ b/src/commands/account/create_account/fund_myself_create_account/mod.rs @@ -24,7 +24,7 @@ pub struct NewAccount { #[derive(Debug, Clone)] pub struct NewAccountContext { global_context: crate::GlobalContext, - new_account_id: crate::types::account_id::AccountId, + new_account_id: near_primitives::types::AccountId, initial_balance: crate::common::NearBalance, } @@ -35,7 +35,7 @@ impl NewAccountContext { ) -> color_eyre::eyre::Result { Ok(Self { global_context: previous_context, - new_account_id: scope.new_account_id.clone(), + new_account_id: scope.new_account_id.clone().into(), initial_balance: scope.initial_balance.clone(), }) } @@ -154,7 +154,7 @@ pub struct AccountPropertiesContext { #[derive(Debug, Clone)] pub struct AccountProperties { - pub new_account_id: crate::types::account_id::AccountId, + pub new_account_id: near_primitives::types::AccountId, pub public_key: near_crypto::PublicKey, pub initial_balance: crate::common::NearBalance, } diff --git a/src/commands/account/create_account/fund_myself_create_account/sign_as/mod.rs b/src/commands/account/create_account/fund_myself_create_account/sign_as/mod.rs index 44055eaa5..30c070982 100644 --- a/src/commands/account/create_account/fund_myself_create_account/sign_as/mod.rs +++ b/src/commands/account/create_account/fund_myself_create_account/sign_as/mod.rs @@ -44,8 +44,7 @@ impl From for crate::commands::ActionContext { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = std::sync::Arc::new({ - let new_account_id: near_primitives::types::AccountId = - item.account_properties.new_account_id.clone().into(); + let new_account_id = item.account_properties.new_account_id.clone(); let signer_id = item.signer_account_id.clone(); move |network_config| { @@ -150,6 +149,10 @@ impl From for crate::commands::ActionContext { Self { global_context, + interacting_with_account_ids: vec![ + item.signer_account_id, + item.account_properties.new_account_id, + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), @@ -164,11 +167,10 @@ impl SignerAccountId { fn input_signer_account_id( context: &super::AccountPropertiesContext, ) -> color_eyre::eyre::Result> { - let parent_account_id = context - .account_properties - .new_account_id - .clone() - .get_parent_account_id_from_sub_account(); + let parent_account_id = + crate::types::account_id::AccountId::get_parent_account_id_from_sub_account( + context.account_properties.new_account_id.clone().into(), + ); if !parent_account_id.0.is_top_level() { Ok(Some(parent_account_id)) } else { diff --git a/src/commands/account/create_account/sponsor_by_faucet_service/network/mod.rs b/src/commands/account/create_account/sponsor_by_faucet_service/network/mod.rs index d20209c30..bce0b1dd8 100644 --- a/src/commands/account/create_account/sponsor_by_faucet_service/network/mod.rs +++ b/src/commands/account/create_account/sponsor_by_faucet_service/network/mod.rs @@ -61,7 +61,7 @@ impl Network { fn input_network_name( context: &super::SponsorServiceContext, ) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.config) + crate::common::input_network_name(&context.config, &[context.new_account_id.clone().into()]) } } diff --git a/src/commands/account/delete_account/mod.rs b/src/commands/account/delete_account/mod.rs index 26ef67b65..6f1e19ee3 100644 --- a/src/commands/account/delete_account/mod.rs +++ b/src/commands/account/delete_account/mod.rs @@ -76,19 +76,25 @@ impl BeneficiaryAccountContext { impl From for crate::commands::ActionContext { fn from(item: BeneficiaryAccountContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.account_id.clone(), - receiver_id: item.account_id.clone(), - actions: vec![near_primitives::transaction::Action::DeleteAccount( - near_primitives::transaction::DeleteAccountAction { - beneficiary_id: item.beneficiary_account_id.clone(), - }, - )], - }) + std::sync::Arc::new({ + let account_id = item.account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: account_id.clone(), + receiver_id: account_id.clone(), + actions: vec![near_primitives::transaction::Action::DeleteAccount( + near_primitives::transaction::DeleteAccountAction { + beneficiary_id: item.beneficiary_account_id.clone(), + }, + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/delete_key/mod.rs b/src/commands/account/delete_key/mod.rs index 21bb665f3..ba2b6547a 100644 --- a/src/commands/account/delete_key/mod.rs +++ b/src/commands/account/delete_key/mod.rs @@ -35,25 +35,30 @@ impl DeleteKeyCommandContext { impl From for crate::commands::ActionContext { fn from(item: DeleteKeyCommandContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.owner_account_id.clone(), - receiver_id: item.owner_account_id.clone(), - actions: item - .public_keys - .clone() - .into_iter() - .map(|public_key| { - near_primitives::transaction::Action::DeleteKey( - near_primitives::transaction::DeleteKeyAction { public_key }, - ) - }) - .collect(), - }) + std::sync::Arc::new({ + let owner_account_id = item.owner_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: owner_account_id.clone(), + receiver_id: owner_account_id.clone(), + actions: item + .public_keys + .clone() + .into_iter() + .map(|public_key| { + near_primitives::transaction::Action::DeleteKey( + near_primitives::transaction::DeleteKeyAction { public_key }, + ) + }) + .collect(), + }) + } }); Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.owner_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/import_account/using_private_key/mod.rs b/src/commands/account/import_account/using_private_key/mod.rs index d3fefdeb4..df490f3e1 100644 --- a/src/commands/account/import_account/using_private_key/mod.rs +++ b/src/commands/account/import_account/using_private_key/mod.rs @@ -17,7 +17,6 @@ impl LoginFromPrivateKeyContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let config = previous_context.config.clone(); let private_key: near_crypto::SecretKey = scope.private_key.clone().into(); let public_key = private_key.public_key(); let key_pair_properties = KeyPairProperties { @@ -25,23 +24,25 @@ impl LoginFromPrivateKeyContext { private_key, }; let key_pair_properties_buf = serde_json::to_string(&key_pair_properties).unwrap(); - let error_message = "\nIt is currently not possible to verify the account access key.\nYou may have entered an incorrect account_id.\nYou have the option to reconfirm your account or save your access key information.\n"; let on_after_getting_network_callback: crate::network::OnAfterGettingNetworkCallback = std::sync::Arc::new({ + let config = previous_context.config.clone(); + move |network_config| { super::login( network_config.clone(), config.credentials_home_dir.clone(), &key_pair_properties_buf, &public_key.to_string(), - error_message, + "\nIt is currently not possible to verify the account access key.\nYou may have entered an incorrect account_id.\nYou have the option to reconfirm your account or save your access key information.\n", ) } }); Ok(Self(crate::network::NetworkContext { config: previous_context.config, + interacting_with_account_ids: Vec::new(), on_after_getting_network_callback, })) } diff --git a/src/commands/account/import_account/using_seed_phrase/mod.rs b/src/commands/account/import_account/using_seed_phrase/mod.rs index 64f36a0d1..b26891e74 100644 --- a/src/commands/account/import_account/using_seed_phrase/mod.rs +++ b/src/commands/account/import_account/using_seed_phrase/mod.rs @@ -23,31 +23,30 @@ impl LoginFromSeedPhraseContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let config = previous_context.config.clone(); - let seed_phrase_hd_path = scope.seed_phrase_hd_path.clone(); - let master_seed_phrase = scope.master_seed_phrase.clone(); let key_pair_properties = crate::common::get_key_pair_properties_from_seed_phrase( - seed_phrase_hd_path, - master_seed_phrase, + scope.seed_phrase_hd_path.clone(), + scope.master_seed_phrase.clone(), )?; let key_pair_properties_buf = serde_json::to_string(&key_pair_properties).unwrap(); - let error_message = "\nIt is currently not possible to verify the account access key.\nYou may have entered an incorrect account_id.\nYou have the option to reconfirm your account or save your access key information.\n"; let on_after_getting_network_callback: crate::network::OnAfterGettingNetworkCallback = std::sync::Arc::new({ + let config = previous_context.config.clone(); + move |network_config| { super::login( network_config.clone(), config.credentials_home_dir.clone(), &key_pair_properties_buf, &key_pair_properties.public_key_str, - error_message, + "\nIt is currently not possible to verify the account access key.\nYou may have entered an incorrect account_id.\nYou have the option to reconfirm your account or save your access key information.\n", ) } }); Ok(Self(crate::network::NetworkContext { config: previous_context.config, + interacting_with_account_ids: Vec::new(), on_after_getting_network_callback, })) } diff --git a/src/commands/account/import_account/using_web_wallet/mod.rs b/src/commands/account/import_account/using_web_wallet/mod.rs index fe43dc753..38e549878 100644 --- a/src/commands/account/import_account/using_web_wallet/mod.rs +++ b/src/commands/account/import_account/using_web_wallet/mod.rs @@ -15,10 +15,10 @@ impl LoginFromWebWalletContext { previous_context: crate::GlobalContext, _scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let config = previous_context.config.clone(); - let on_after_getting_network_callback: crate::network::OnAfterGettingNetworkCallback = std::sync::Arc::new({ + let config = previous_context.config.clone(); + move |network_config| { let key_pair_properties: crate::common::KeyPairProperties = crate::common::generate_keypair()?; @@ -49,6 +49,7 @@ impl LoginFromWebWalletContext { Ok(Self(crate::network::NetworkContext { config: previous_context.config, + interacting_with_account_ids: Vec::new(), on_after_getting_network_callback, })) } diff --git a/src/commands/account/list_keys/mod.rs b/src/commands/account/list_keys/mod.rs index d860ecf93..77441ac93 100644 --- a/src/commands/account/list_keys/mod.rs +++ b/src/commands/account/list_keys/mod.rs @@ -23,9 +23,9 @@ impl ViewListKeysContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); + move |network_config, block_reference| { let access_key_list = network_config .json_rpc_client() @@ -45,8 +45,10 @@ impl ViewListKeysContext { Ok(()) } }); + Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.config, + interacting_with_account_ids: vec![scope.account_id.clone().into()], on_after_getting_block_reference_callback, })) } diff --git a/src/commands/account/storage_management/storage_deposit.rs b/src/commands/account/storage_management/storage_deposit.rs index fdebe89f9..28fb41c0e 100644 --- a/src/commands/account/storage_management/storage_deposit.rs +++ b/src/commands/account/storage_management/storage_deposit.rs @@ -104,49 +104,57 @@ impl SignerAccountIdContext { previous_context: DepositArgsContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let signer = scope.signer_account_id.clone(); - let signer_id: near_primitives::types::AccountId = scope.signer_account_id.clone().into(); - let deposit = previous_context.deposit.clone(); - let receiver_account_id = previous_context.receiver_account_id.clone(); - let get_contract_account_id = previous_context.get_contract_account_id.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: signer_id.clone(), - receiver_id: get_contract_account_id(network_config)?, - actions: vec![near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: "storage_deposit".to_string(), - args: serde_json::json!({ - "account_id": &previous_context.receiver_account_id.clone() - }) - .to_string() - .into_bytes(), - gas: crate::common::NearGas::from_str("50 TeraGas") - .unwrap() - .inner, - deposit: previous_context.deposit.to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id: near_primitives::types::AccountId = + scope.signer_account_id.clone().into(); + let receiver_account_id = previous_context.receiver_account_id.clone(); + let get_contract_account_id = previous_context.get_contract_account_id.clone(); + let deposit = previous_context.deposit.clone(); + + move |network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: get_contract_account_id(network_config)?, + actions: vec![near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: "storage_deposit".to_string(), + args: serde_json::json!({ "account_id": &receiver_account_id }) + .to_string() + .into_bytes(), + gas: crate::common::NearGas::from_str("50 TeraGas") + .unwrap() + .inner, + deposit: deposit.to_yoctonear(), + }, + )], + }) + } }); - let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new( + let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new({ + let signer_account_id: near_primitives::types::AccountId = scope.signer_account_id.clone().into(); + let receiver_account_id = previous_context.receiver_account_id.clone(); + move |outcome_view, network_config| { - let contract_account_id = (previous_context.get_contract_account_id)(network_config)?; + let contract_account_id = (previous_context.get_contract_account_id)(network_config)?; if let near_primitives::views::FinalExecutionStatus::SuccessValue(_) = outcome_view.status { eprintln!( - "<{signer}> has successfully added a deposit of {deposit} to <{receiver_account_id}> on contract <{contract_account_id}>.", + "<{signer_account_id}> has successfully added a deposit of {deposit} to <{receiver_account_id}> on contract <{contract_account_id}>.", + deposit = previous_context.deposit, ); } Ok(()) - }, - ); + } + }); Ok(Self(crate::commands::ActionContext { global_context: previous_context.global_context, + interacting_with_account_ids: vec![ + scope.signer_account_id.clone().into(), + previous_context.receiver_account_id, + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/storage_management/storage_withdraw.rs b/src/commands/account/storage_management/storage_withdraw.rs index a0a26d832..0e3fbb74e 100644 --- a/src/commands/account/storage_management/storage_withdraw.rs +++ b/src/commands/account/storage_management/storage_withdraw.rs @@ -51,47 +51,54 @@ impl SignerAccountIdContext { previous_context: WithdrawArgsContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let signer = scope.signer_account_id.clone(); - let signer_id: near_primitives::types::AccountId = scope.signer_account_id.clone().into(); - let amount = previous_context.amount.clone(); - let get_contract_account_id = previous_context.get_contract_account_id.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: signer_id.clone(), - receiver_id: get_contract_account_id(network_config)?, - actions: vec![near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: "storage_withdraw".to_string(), - args: serde_json::json!({ - "amount": previous_context.amount.clone().to_yoctonear().to_string() - }) - .to_string() - .into_bytes(), - gas: crate::common::NearGas::from_str("50 TeraGas") - .unwrap() - .inner, - deposit: crate::common::NearBalance::from_yoctonear(1).to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id: near_primitives::types::AccountId = + scope.signer_account_id.clone().into(); + let get_contract_account_id = previous_context.get_contract_account_id.clone(); + let amount = previous_context.amount.clone(); + + move |network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: get_contract_account_id(network_config)?, + actions: vec![near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: "storage_withdraw".to_string(), + args: serde_json::json!({ + "amount": amount.clone().to_yoctonear().to_string() + }) + .to_string() + .into_bytes(), + gas: crate::common::NearGas::from_str("50 TeraGas") + .unwrap() + .inner, + deposit: crate::common::NearBalance::from_yoctonear(1) + .to_yoctonear(), + }, + )], + }) + } }); - let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new( + let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new({ + let signer_account_id: near_primitives::types::AccountId = scope.signer_account_id.clone().into(); + move |outcome_view, network_config| { let contract_account_id = (previous_context.get_contract_account_id)(network_config)?; if let near_primitives::views::FinalExecutionStatus::SuccessValue(_) = outcome_view.status { eprintln!( - "<{signer}> has successfully withdraw {amount} from <{contract_account_id}>.", + "<{signer_account_id}> has successfully withdraw {amount} from <{contract_account_id}>.", + amount = previous_context.amount, ); } Ok(()) - }, - ); + } + }); Ok(Self(crate::commands::ActionContext { global_context: previous_context.global_context, + interacting_with_account_ids: vec![scope.signer_account_id.clone().into()], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/account/storage_management/view_storage_balance.rs b/src/commands/account/storage_management/view_storage_balance.rs index b441595d2..ada659985 100644 --- a/src/commands/account/storage_management/view_storage_balance.rs +++ b/src/commands/account/storage_management/view_storage_balance.rs @@ -69,6 +69,7 @@ impl AccountContext { Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.global_context.config, + interacting_with_account_ids: vec![scope.account_id.clone().into()], on_after_getting_block_reference_callback, })) } diff --git a/src/commands/account/view_account_summary/mod.rs b/src/commands/account/view_account_summary/mod.rs index c6b8b054e..ef986c6bb 100644 --- a/src/commands/account/view_account_summary/mod.rs +++ b/src/commands/account/view_account_summary/mod.rs @@ -23,13 +23,13 @@ impl ViewAccountSummaryContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); + move |network_config, block_reference| { let rpc_query_response = network_config .json_rpc_client() - .blocking_call_view_account(&account_id.clone(), block_reference.clone()) + .blocking_call_view_account(&account_id, block_reference.clone()) .wrap_err_with(|| { format!( "Failed to fetch query ViewAccount for <{}>", @@ -64,6 +64,7 @@ impl ViewAccountSummaryContext { }); Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.config, + interacting_with_account_ids: vec![scope.account_id.clone().into()], on_after_getting_block_reference_callback, })) } diff --git a/src/commands/config/delete_connection/mod.rs b/src/commands/config/delete_connection/mod.rs index 0016f0831..d01238e1e 100644 --- a/src/commands/config/delete_connection/mod.rs +++ b/src/commands/config/delete_connection/mod.rs @@ -31,6 +31,6 @@ impl DeleteNetworkConnection { fn input_connection_name( context: &crate::GlobalContext, ) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.config) + crate::common::input_network_name(&context.config, &[]) } } diff --git a/src/commands/contract/call_function/as_read_only/mod.rs b/src/commands/contract/call_function/as_read_only/mod.rs index 330db3cc6..796a35dbb 100644 --- a/src/commands/contract/call_function/as_read_only/mod.rs +++ b/src/commands/contract/call_function/as_read_only/mod.rs @@ -29,12 +29,12 @@ impl CallFunctionViewContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let function_args = scope.function_args.clone(); - let function_args_type = scope.function_args_type.clone(); - let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); - let function_name = scope.function_name.clone(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let function_args = scope.function_args.clone(); + let function_args_type = scope.function_args_type.clone(); + let account_id: near_primitives::types::AccountId = scope.account_id.clone().into(); + let function_name = scope.function_name.clone(); + move |network_config, block_reference| { let args = super::call_function_args_type::function_args( function_args.clone(), @@ -64,8 +64,10 @@ impl CallFunctionViewContext { Ok(()) } }); + Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.config, + interacting_with_account_ids: vec![scope.account_id.clone().into()], on_after_getting_block_reference_callback, })) } diff --git a/src/commands/contract/call_function/as_transaction/mod.rs b/src/commands/contract/call_function/as_transaction/mod.rs index aa6ee2747..a12d9cd90 100644 --- a/src/commands/contract/call_function/as_transaction/mod.rs +++ b/src/commands/contract/call_function/as_transaction/mod.rs @@ -227,22 +227,29 @@ impl SignerAccountIdContext { impl From for crate::commands::ActionContext { fn from(item: SignerAccountIdContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.receiver_account_id.clone(), - actions: vec![near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: item.function_name.clone(), - args: item.function_args.clone(), - gas: item.gas.inner, - deposit: item.deposit.to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: receiver_account_id.clone(), + actions: vec![near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: item.function_name.clone(), + args: item.function_args.clone(), + gas: item.gas.inner, + deposit: item.deposit.to_yoctonear(), + }, + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id, item.receiver_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/contract/deploy/initialize_mode/call_function_type/mod.rs b/src/commands/contract/deploy/initialize_mode/call_function_type/mod.rs index c34571e38..02d3ba9fc 100644 --- a/src/commands/contract/deploy/initialize_mode/call_function_type/mod.rs +++ b/src/commands/contract/deploy/initialize_mode/call_function_type/mod.rs @@ -151,29 +151,39 @@ impl DepositContext { let deposit = scope.deposit.clone(); let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: previous_context.signer_account_id.clone(), - receiver_id: previous_context.receiver_account_id.clone(), - actions: vec![ - near_primitives::transaction::Action::DeployContract( - near_primitives::transaction::DeployContractAction { - code: previous_context.code.clone(), - }, - ), - near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: previous_context.function_name.clone(), - args: previous_context.function_args.clone(), - gas: previous_context.gas.inner, - deposit: deposit.to_yoctonear(), - }, - ), - ], - }) + std::sync::Arc::new({ + let signer_account_id = previous_context.signer_account_id.clone(); + let receiver_account_id = previous_context.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: receiver_account_id.clone(), + actions: vec![ + near_primitives::transaction::Action::DeployContract( + near_primitives::transaction::DeployContractAction { + code: previous_context.code.clone(), + }, + ), + near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: previous_context.function_name.clone(), + args: previous_context.function_args.clone(), + gas: previous_context.gas.inner, + deposit: deposit.to_yoctonear(), + }, + ), + ], + }) + } }); + Ok(Self(crate::commands::ActionContext { global_context: previous_context.global_context, + interacting_with_account_ids: vec![ + previous_context.signer_account_id.clone(), + previous_context.receiver_account_id.clone(), + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/contract/deploy/initialize_mode/mod.rs b/src/commands/contract/deploy/initialize_mode/mod.rs index c402d8894..ad5cb0ce5 100644 --- a/src/commands/contract/deploy/initialize_mode/mod.rs +++ b/src/commands/contract/deploy/initialize_mode/mod.rs @@ -44,19 +44,29 @@ impl NoInitializeContext { impl From for crate::commands::ActionContext { fn from(item: NoInitializeContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.0.signer_account_id.clone(), - receiver_id: item.0.receiver_account_id.clone(), - actions: vec![near_primitives::transaction::Action::DeployContract( - near_primitives::transaction::DeployContractAction { - code: item.0.code.clone(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id = item.0.signer_account_id.clone(); + let receiver_account_id = item.0.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: receiver_account_id.clone(), + actions: vec![near_primitives::transaction::Action::DeployContract( + near_primitives::transaction::DeployContractAction { + code: item.0.code.clone(), + }, + )], + }) + } }); + Self { global_context: item.0.global_context, + interacting_with_account_ids: vec![ + item.0.signer_account_id, + item.0.receiver_account_id, + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/contract/download_wasm/mod.rs b/src/commands/contract/download_wasm/mod.rs index 55055a2b6..c3aff3c0b 100644 --- a/src/commands/contract/download_wasm/mod.rs +++ b/src/commands/contract/download_wasm/mod.rs @@ -66,17 +66,17 @@ impl DownloadContractContext { previous_context: ContractAccountContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let account_id = previous_context.account_id; - let folder_path: std::path::PathBuf = scope.folder_path.clone().into(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let account_id = previous_context.account_id.clone(); + let folder_path: std::path::PathBuf = scope.folder_path.clone().into(); + move |network_config, block_reference| { let query_view_method_response = network_config .json_rpc_client() .blocking_call(near_jsonrpc_client::methods::query::RpcQueryRequest { block_reference: block_reference.clone(), request: near_primitives::views::QueryRequest::ViewCode { - account_id: account_id.clone(), + account_id: account_id.clone().into(), }, }) .wrap_err_with(|| format!("Failed to fetch query ViewCode for <{}>", &account_id))?; @@ -105,6 +105,7 @@ impl DownloadContractContext { Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.global_context.config, on_after_getting_block_reference_callback, + interacting_with_account_ids: vec![previous_context.account_id], })) } } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 982f2b677..2ebb484b2 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -65,6 +65,7 @@ pub struct PrepopulatedTransaction { #[derive(Clone)] pub struct ActionContext { pub global_context: crate::GlobalContext, + pub interacting_with_account_ids: Vec, pub on_after_getting_network_callback: OnAfterGettingNetworkCallback, pub on_before_signing_callback: OnBeforeSigningCallback, pub on_before_sending_transaction_callback: diff --git a/src/commands/tokens/send_ft/mod.rs b/src/commands/tokens/send_ft/mod.rs index 469b201c3..17efee964 100644 --- a/src/commands/tokens/send_ft/mod.rs +++ b/src/commands/tokens/send_ft/mod.rs @@ -58,33 +58,39 @@ impl SendFtCommandContext { impl From for crate::commands::ActionContext { fn from(item: SendFtCommandContext) -> Self { - let signer_account_id = item.signer_account_id.clone(); - let amount = item.amount; - let ft_contract_account_id = item.ft_contract_account_id.clone(); - let receiver_account_id = item.receiver_account_id.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.ft_contract_account_id.clone(), - actions: vec![near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: "ft_transfer".to_string(), - args: json!({ - "receiver_id": item.receiver_account_id.to_string(), - "amount": item.amount.to_string() - }) - .to_string() - .into_bytes(), - gas: item.gas.inner, - deposit: item.deposit.to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let ft_contract_account_id = item.ft_contract_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone().into(), + receiver_id: ft_contract_account_id.clone().into(), + actions: vec![near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: "ft_transfer".to_string(), + args: json!({ + "receiver_id": receiver_account_id.to_string(), + "amount": item.amount.to_string() + }) + .to_string() + .into_bytes(), + gas: item.gas.inner, + deposit: item.deposit.to_yoctonear(), + }, + )], + }) + } }); - let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new( + let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let amount = item.amount; + let ft_contract_account_id = item.ft_contract_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + move |outcome_view, _network_config| { if let near_primitives::views::FinalExecutionStatus::SuccessValue(_) = outcome_view.status { eprintln!( @@ -92,11 +98,16 @@ impl From for crate::commands::ActionContext { ); } Ok(()) - }, - ); + } + }); Self { global_context: item.global_context, + interacting_with_account_ids: vec![ + item.ft_contract_account_id, + item.signer_account_id, + item.receiver_account_id, + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/tokens/send_near/mod.rs b/src/commands/tokens/send_near/mod.rs index 3bf2568ff..96568142b 100644 --- a/src/commands/tokens/send_near/mod.rs +++ b/src/commands/tokens/send_near/mod.rs @@ -40,19 +40,26 @@ impl SendNearCommandContext { impl From for crate::commands::ActionContext { fn from(item: SendNearCommandContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.signer_account_id.clone(), - receiver_id: item.receiver_account_id.clone(), - actions: vec![near_primitives::transaction::Action::Transfer( - near_primitives::transaction::TransferAction { - deposit: item.amount_in_near.to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: receiver_account_id.clone(), + actions: vec![near_primitives::transaction::Action::Transfer( + near_primitives::transaction::TransferAction { + deposit: item.amount_in_near.to_yoctonear(), + }, + )], + }) + } }); + Self { global_context: item.global_context, + interacting_with_account_ids: vec![item.signer_account_id, item.receiver_account_id], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/tokens/send_nft/mod.rs b/src/commands/tokens/send_nft/mod.rs index 53115fe6e..eaac90f71 100644 --- a/src/commands/tokens/send_nft/mod.rs +++ b/src/commands/tokens/send_nft/mod.rs @@ -58,49 +58,57 @@ impl SendNftCommandContext { impl From for crate::commands::ActionContext { fn from(item: SendNftCommandContext) -> Self { - let signer_account_id = item.signer_account_id.clone(); - let nft_contract_account_id = item.nft_contract_account_id.clone(); - let receiver_account_id = item.receiver_account_id.clone(); - let token_id = item.token_id.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: signer_account_id.clone(), - receiver_id: nft_contract_account_id.clone(), - actions: vec![near_primitives::transaction::Action::FunctionCall( - near_primitives::transaction::FunctionCallAction { - method_name: "nft_transfer".to_string(), - args: json!({ - "receiver_id": receiver_account_id.to_string(), - "token_id": token_id - }) - .to_string() - .into_bytes(), - gas: item.gas.inner, - deposit: item.deposit.to_yoctonear(), - }, - )], - }) + std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let nft_contract_account_id = item.nft_contract_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + let token_id = item.token_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: nft_contract_account_id.clone(), + actions: vec![near_primitives::transaction::Action::FunctionCall( + near_primitives::transaction::FunctionCallAction { + method_name: "nft_transfer".to_string(), + args: json!({ + "receiver_id": receiver_account_id.to_string(), + "token_id": token_id + }) + .to_string() + .into_bytes(), + gas: item.gas.inner, + deposit: item.deposit.to_yoctonear(), + }, + )], + }) + } }); - let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new( + let on_after_sending_transaction_callback: crate::transaction_signature_options::OnAfterSendingTransactionCallback = std::sync::Arc::new({ + let signer_account_id = item.signer_account_id.clone(); + let nft_contract_account_id = item.nft_contract_account_id.clone(); + let receiver_account_id = item.receiver_account_id.clone(); + let token_id = item.token_id.clone(); + move |outcome_view, _network_config| { if let near_primitives::views::FinalExecutionStatus::SuccessValue(_) = outcome_view.status { eprintln!( - "<{}> has successfully transferred NFT token_id=\"{}\" to <{}> on contract <{}>.", - item.signer_account_id, - item.token_id, - item.receiver_account_id, - item.nft_contract_account_id, + "<{signer_account_id}> has successfully transferred NFT token_id=\"{token_id}\" to <{receiver_account_id}> on contract <{nft_contract_account_id}>.", ); } Ok(()) - }, - ); + } + }); Self { global_context: item.global_context, + interacting_with_account_ids: vec![ + item.nft_contract_account_id.clone(), + item.signer_account_id.clone(), + item.receiver_account_id.clone(), + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/tokens/view_ft_balance/mod.rs b/src/commands/tokens/view_ft_balance/mod.rs index 6cf2ebaec..a02555e53 100644 --- a/src/commands/tokens/view_ft_balance/mod.rs +++ b/src/commands/tokens/view_ft_balance/mod.rs @@ -23,11 +23,11 @@ impl ViewFtBalanceContext { previous_context: super::TokensCommandsContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let owner_account_id = previous_context.owner_account_id; - let ft_contract_account_id: near_primitives::types::AccountId = - scope.ft_contract_account_id.clone().into(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let owner_account_id = previous_context.owner_account_id.clone(); + let ft_contract_account_id: near_primitives::types::AccountId = + scope.ft_contract_account_id.clone().into(); + move |network_config, block_reference| { let super::FtMetadata { decimals, symbol } = super::params_ft_metadata( ft_contract_account_id.clone(), @@ -75,6 +75,10 @@ impl ViewFtBalanceContext { Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.global_context.config, on_after_getting_block_reference_callback, + interacting_with_account_ids: vec![ + scope.ft_contract_account_id.clone().into(), + previous_context.owner_account_id, + ], })) } } diff --git a/src/commands/tokens/view_near_balance/mod.rs b/src/commands/tokens/view_near_balance/mod.rs index ff48a75cd..67ed2152c 100644 --- a/src/commands/tokens/view_near_balance/mod.rs +++ b/src/commands/tokens/view_near_balance/mod.rs @@ -15,20 +15,23 @@ impl ViewNearBalanceContext { previous_context: super::TokensCommandsContext, _scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let owner_account_id = previous_context.owner_account_id; - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let owner_account_id = previous_context.owner_account_id.clone(); + move |network_config, block_reference| { - let account_transfer_allowance = crate::common::get_account_transfer_allowance( - network_config.clone(), - owner_account_id.clone(), - block_reference.clone(), - )?; - eprintln! {"{}", &account_transfer_allowance}; - Ok(()) - }}); + let account_transfer_allowance = crate::common::get_account_transfer_allowance( + network_config.clone(), + owner_account_id.clone(), + block_reference.clone(), + )?; + eprintln! {"{}", &account_transfer_allowance}; + Ok(()) + } + }); + Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.global_context.config, + interacting_with_account_ids: vec![previous_context.owner_account_id], on_after_getting_block_reference_callback, })) } diff --git a/src/commands/tokens/view_nft_assets/mod.rs b/src/commands/tokens/view_nft_assets/mod.rs index 49d0f53e0..d73341211 100644 --- a/src/commands/tokens/view_nft_assets/mod.rs +++ b/src/commands/tokens/view_nft_assets/mod.rs @@ -23,11 +23,11 @@ impl ViewNftAssetsContext { previous_context: super::TokensCommandsContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let owner_account_id = previous_context.owner_account_id; - let nft_contract_account_id: near_primitives::types::AccountId = - scope.nft_contract_account_id.clone().into(); - let on_after_getting_block_reference_callback: crate::network_view_at_block::OnAfterGettingBlockReferenceCallback = std::sync::Arc::new({ + let owner_account_id = previous_context.owner_account_id.clone(); + let nft_contract_account_id: near_primitives::types::AccountId = + scope.nft_contract_account_id.clone().into(); + move |network_config, block_reference| { let args = json!({ "account_id": owner_account_id.to_string(), @@ -53,6 +53,10 @@ impl ViewNftAssetsContext { Ok(Self(crate::network_view_at_block::ArgsForViewContext { config: previous_context.global_context.config, on_after_getting_block_reference_callback, + interacting_with_account_ids: vec![ + scope.nft_contract_account_id.clone().into(), + previous_context.owner_account_id, + ], })) } } diff --git a/src/commands/transaction/construct_transaction/skip_action/mod.rs b/src/commands/transaction/construct_transaction/skip_action/mod.rs index 9a54a9a35..f9935d249 100644 --- a/src/commands/transaction/construct_transaction/skip_action/mod.rs +++ b/src/commands/transaction/construct_transaction/skip_action/mod.rs @@ -22,15 +22,25 @@ impl SkipActionContext { impl From for crate::commands::ActionContext { fn from(item: SkipActionContext) -> Self { let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: item.0.signer_account_id.clone(), - receiver_id: item.0.receiver_account_id.clone(), - actions: item.0.actions.clone(), - }) + std::sync::Arc::new({ + let signer_account_id = item.0.signer_account_id.clone(); + let receiver_account_id = item.0.receiver_account_id.clone(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_account_id.clone(), + receiver_id: receiver_account_id.clone(), + actions: item.0.actions.clone(), + }) + } }); + Self { global_context: item.0.global_context, + interacting_with_account_ids: vec![ + item.0.signer_account_id, + item.0.receiver_account_id, + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/transaction/send_meta_transaction/sign_as/mod.rs b/src/commands/transaction/send_meta_transaction/sign_as/mod.rs index 27f13222a..26f640163 100644 --- a/src/commands/transaction/send_meta_transaction/sign_as/mod.rs +++ b/src/commands/transaction/send_meta_transaction/sign_as/mod.rs @@ -20,22 +20,21 @@ impl RelayerAccountIdContext { previous_context: super::SendMetaTransactionContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let signer_id: near_primitives::types::AccountId = scope.relayer_account_id.clone().into(); - let signed_delegate_action = previous_context.signed_delegate_action.clone(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - let actions = vec![previous_context.signed_delegate_action.clone().into()]; + std::sync::Arc::new({ + let signer_id: near_primitives::types::AccountId = + scope.relayer_account_id.clone().into(); + let signed_delegate_action = previous_context.signed_delegate_action.clone(); - Ok(crate::commands::PrepopulatedTransaction { - signer_id: signer_id.clone(), - receiver_id: previous_context - .signed_delegate_action - .delegate_action - .sender_id - .clone(), - actions, - }) + move |_network_config| { + let actions = vec![signed_delegate_action.clone().into()]; + + Ok(crate::commands::PrepopulatedTransaction { + signer_id: signer_id.clone(), + receiver_id: signed_delegate_action.delegate_action.sender_id.clone(), + actions, + }) + } }); let on_before_signing_callback: crate::commands::OnBeforeSigningCallback = @@ -43,7 +42,7 @@ impl RelayerAccountIdContext { move |prepopulated_unsigned_transaction, _network_config| { prepopulated_unsigned_transaction.actions = vec![near_primitives::transaction::Action::Delegate( - signed_delegate_action.clone(), + previous_context.signed_delegate_action.clone(), )]; Ok(()) } @@ -51,6 +50,7 @@ impl RelayerAccountIdContext { Ok(Self(crate::commands::ActionContext { global_context: previous_context.global_context, + interacting_with_account_ids: vec![scope.relayer_account_id.clone().into()], on_after_getting_network_callback, on_before_signing_callback, on_before_sending_transaction_callback: std::sync::Arc::new( diff --git a/src/commands/transaction/send_signed_transaction/network/mod.rs b/src/commands/transaction/send_signed_transaction/network/mod.rs index 0f79b4025..06d524296 100644 --- a/src/commands/transaction/send_signed_transaction/network/mod.rs +++ b/src/commands/transaction/send_signed_transaction/network/mod.rs @@ -23,8 +23,9 @@ impl NetworkContext { previous_context: super::SignedTransactionContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let networks = previous_context.config.network_connection.clone(); - let network_config = networks + let network_config = previous_context + .config + .network_connection .get(&scope.network_name) .expect("Failed to get network config!") .clone(); @@ -40,7 +41,10 @@ impl Network { fn input_network_name( context: &super::SignedTransactionContext, ) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.config) + crate::common::input_network_name( + &context.config, + &[context.signed_transaction.transaction.receiver_id.clone()], + ) } } diff --git a/src/commands/transaction/sign_transaction/mod.rs b/src/commands/transaction/sign_transaction/mod.rs index 249feb806..01575d0ff 100644 --- a/src/commands/transaction/sign_transaction/mod.rs +++ b/src/commands/transaction/sign_transaction/mod.rs @@ -17,20 +17,26 @@ impl SignTransactionContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let unsigned_transaction: near_primitives::transaction::Transaction = - scope.unsigned_transaction.clone().into(); - let on_after_getting_network_callback: crate::commands::OnAfterGettingNetworkCallback = - std::sync::Arc::new(move |_network_config| { - Ok(crate::commands::PrepopulatedTransaction { - signer_id: unsigned_transaction.signer_id.clone(), - receiver_id: unsigned_transaction.receiver_id.clone(), - actions: unsigned_transaction.actions.clone(), - }) + std::sync::Arc::new({ + let unsigned_transaction: near_primitives::transaction::Transaction = + scope.unsigned_transaction.clone().into(); + + move |_network_config| { + Ok(crate::commands::PrepopulatedTransaction { + signer_id: unsigned_transaction.signer_id.clone(), + receiver_id: unsigned_transaction.receiver_id.clone(), + actions: unsigned_transaction.actions.clone(), + }) + } }); Ok(Self(crate::commands::ActionContext { global_context: previous_context, + interacting_with_account_ids: vec![ + scope.unsigned_transaction.inner.signer_id.clone().into(), + scope.unsigned_transaction.inner.receiver_id.clone().into(), + ], on_after_getting_network_callback, on_before_signing_callback: std::sync::Arc::new( |_prepolulated_unsinged_transaction, _network_config| Ok(()), diff --git a/src/commands/transaction/view_status/mod.rs b/src/commands/transaction/view_status/mod.rs index fcfc382f2..a9f90be88 100644 --- a/src/commands/transaction/view_status/mod.rs +++ b/src/commands/transaction/view_status/mod.rs @@ -24,11 +24,11 @@ impl TransactionInfoContext { previous_context: crate::GlobalContext, scope: &::InteractiveClapContextScope, ) -> color_eyre::eyre::Result { - let transaction_hash = scope.transaction_hash; - let signer_account_id = scope.signer_account_id.clone(); - let on_after_getting_network_callback: crate::network::OnAfterGettingNetworkCallback = std::sync::Arc::new({ + let signer_account_id = scope.signer_account_id.clone(); + let transaction_hash = scope.transaction_hash.clone(); + move |network_config| { let query_view_transaction_status = network_config .json_rpc_client() @@ -46,6 +46,7 @@ impl TransactionInfoContext { Ok(Self(crate::network::NetworkContext { config: previous_context.config, + interacting_with_account_ids: vec![scope.signer_account_id.clone().into()], on_after_getting_network_callback, })) } diff --git a/src/common.rs b/src/common.rs index e4cc80f4e..748150f6c 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1572,10 +1572,42 @@ pub fn display_access_key_list(access_keys: &[near_primitives::views::AccessKeyI table.printstd(); } +/// Interactive prompt for network name. +/// +/// If account_ids is provided, show the network connections that are more +/// relevant at the top of the list. pub fn input_network_name( config: &crate::config::Config, + account_ids: &[near_primitives::types::AccountId], ) -> color_eyre::eyre::Result> { - let variants = config.network_connection.keys().collect::>(); + let variants = if !account_ids.is_empty() { + let (mut matches, non_matches): (Vec<_>, Vec<_>) = config + .network_connection + .iter() + .partition(|(_, network_config)| { + // We use `linkdrop_account_id` as a heuristic to determine if + // the accounts are on the same network. In the future, we + // might consider to have a better way to do this. + network_config + .linkdrop_account_id + .as_ref() + .map_or(false, |linkdrop_account_id| { + account_ids.iter().any(|account_id| { + account_id.as_str().ends_with(linkdrop_account_id.as_str()) + }) + }) + }); + let variants = if matches.is_empty() { + non_matches + } else { + matches.extend(non_matches); + matches + }; + variants.into_iter().map(|(k, _)| k).collect() + } else { + config.network_connection.keys().collect() + }; + let select_submit = Select::new("What is the name of the network?", variants).prompt(); match select_submit { Ok(value) => Ok(Some(value.clone())), diff --git a/src/network/mod.rs b/src/network/mod.rs index 456198b9e..69ebe18cd 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -16,12 +16,14 @@ pub type OnAfterGettingNetworkCallback = #[derive(Clone)] pub struct NetworkContext { pub config: crate::config::Config, + pub interacting_with_account_ids: Vec, pub on_after_getting_network_callback: OnAfterGettingNetworkCallback, } impl interactive_clap::FromCli for Network { type FromCliContext = NetworkContext; type FromCliError = color_eyre::eyre::Error; + fn from_cli( optional_clap_variant: Option<::CliVariant>, context: Self::FromCliContext, @@ -68,7 +70,7 @@ impl interactive_clap::FromCli for Network { impl Network { fn input_network_name(context: &NetworkContext) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.config) + crate::common::input_network_name(&context.config, &context.interacting_with_account_ids) } fn input_wallet_url( diff --git a/src/network_for_transaction/mod.rs b/src/network_for_transaction/mod.rs index a090e1290..e4ea670ce 100644 --- a/src/network_for_transaction/mod.rs +++ b/src/network_for_transaction/mod.rs @@ -138,15 +138,18 @@ impl NetworkForTransactionArgs { fn input_network_name( context: &crate::commands::ActionContext, ) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.global_context.config) + crate::common::input_network_name( + &context.global_context.config, + &context.interacting_with_account_ids, + ) } pub fn get_network_config( &self, config: crate::config::Config, ) -> crate::config::NetworkConfig { - let network_config = config.network_connection; - network_config + config + .network_connection .get(self.network_name.as_str()) .expect("Impossible to get network name!") .clone() diff --git a/src/network_view_at_block/mod.rs b/src/network_view_at_block/mod.rs index 347d6e8cb..78a3bc9f9 100644 --- a/src/network_view_at_block/mod.rs +++ b/src/network_view_at_block/mod.rs @@ -8,6 +8,7 @@ pub type OnAfterGettingBlockReferenceCallback = #[derive(Clone)] pub struct ArgsForViewContext { pub config: crate::config::Config, + pub interacting_with_account_ids: Vec, pub on_after_getting_block_reference_callback: OnAfterGettingBlockReferenceCallback, } @@ -50,7 +51,7 @@ impl NetworkViewAtBlockArgs { fn input_network_name( context: &ArgsForViewContext, ) -> color_eyre::eyre::Result> { - crate::common::input_network_name(&context.config) + crate::common::input_network_name(&context.config, &context.interacting_with_account_ids) } }