From 57dcf6718770375edf4d1e451d57b0b0c9670823 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Wed, 29 Mar 2023 11:01:31 -0700 Subject: [PATCH 01/15] Muli-chain refactoring for tx components All of the tx related components now requires `chain_id` parameter when calling its API. This is to insure we can track txs among multiple chain id for a coin type and also use the correct network url when sending out requests. Since we no longer depends on getting selected chain id from JsonRPCSevice, TxStateManager now doesn't need to depend on it. --- .../brave_wallet_provider_delegate_impl.cc | 15 +- .../brave_wallet/browser/block_tracker.cc | 18 +- .../brave_wallet/browser/block_tracker.h | 14 +- .../browser/brave_wallet_utils.cc | 19 ++ .../brave_wallet/browser/brave_wallet_utils.h | 5 + .../brave_wallet/browser/eth_block_tracker.cc | 52 ++-- .../brave_wallet/browser/eth_block_tracker.h | 21 +- .../brave_wallet/browser/eth_logs_tracker.cc | 6 +- .../brave_wallet/browser/eth_nonce_tracker.cc | 15 +- .../brave_wallet/browser/eth_nonce_tracker.h | 6 +- .../browser/eth_pending_tx_tracker.cc | 64 ++--- .../browser/eth_pending_tx_tracker.h | 16 +- .../brave_wallet/browser/eth_tx_manager.cc | 263 +++++++++++------- .../brave_wallet/browser/eth_tx_manager.h | 56 +++- .../browser/eth_tx_state_manager.cc | 36 ++- .../browser/eth_tx_state_manager.h | 17 +- .../browser/ethereum_provider_impl.cc | 73 +++-- .../browser/ethereum_provider_impl.h | 4 +- .../brave_wallet/browser/fil_block_tracker.cc | 42 ++- .../brave_wallet/browser/fil_block_tracker.h | 17 +- .../brave_wallet/browser/fil_nonce_tracker.cc | 13 +- .../brave_wallet/browser/fil_nonce_tracker.h | 6 +- .../brave_wallet/browser/fil_tx_manager.cc | 105 ++++--- .../brave_wallet/browser/fil_tx_manager.h | 35 ++- .../browser/fil_tx_state_manager.cc | 39 ++- .../browser/fil_tx_state_manager.h | 11 +- .../brave_wallet/browser/json_rpc_service.cc | 106 ++++--- .../brave_wallet/browser/json_rpc_service.h | 63 +++-- .../brave_wallet/browser/keyring_service.cc | 3 +- .../browser/nft_metadata_fetcher.cc | 2 +- .../brave_wallet/browser/nonce_tracker.cc | 10 +- .../brave_wallet/browser/nonce_tracker.h | 6 +- .../browser/solana_block_tracker.cc | 53 ++-- .../browser/solana_block_tracker.h | 26 +- .../brave_wallet/browser/solana_tx_manager.cc | 91 +++--- .../brave_wallet/browser/solana_tx_manager.h | 35 ++- .../browser/solana_tx_state_manager.cc | 43 +-- .../browser/solana_tx_state_manager.h | 11 +- components/brave_wallet/browser/tx_manager.cc | 64 +++-- components/brave_wallet/browser/tx_manager.h | 31 ++- components/brave_wallet/browser/tx_service.cc | 97 ++++--- components/brave_wallet/browser/tx_service.h | 26 +- .../brave_wallet/browser/tx_state_manager.cc | 65 +++-- .../brave_wallet/browser/tx_state_manager.h | 27 +- .../brave_wallet/common/brave_wallet.mojom | 82 ++++-- 45 files changed, 1153 insertions(+), 656 deletions(-) diff --git a/browser/brave_wallet/brave_wallet_provider_delegate_impl.cc b/browser/brave_wallet/brave_wallet_provider_delegate_impl.cc index de4a8b1e9d40..45a21e572444 100644 --- a/browser/brave_wallet/brave_wallet_provider_delegate_impl.cc +++ b/browser/brave_wallet/brave_wallet_provider_delegate_impl.cc @@ -78,19 +78,6 @@ absl::optional CoinTypeToPermissionRequestType( } } -absl::optional CoinTypeToKeyringId(mojom::CoinType coin_type) { - switch (coin_type) { - case mojom::CoinType::ETH: - return mojom::kDefaultKeyringId; - case mojom::CoinType::SOL: - return mojom::kSolanaKeyringId; - case mojom::CoinType::FIL: - return mojom::kFilecoinKeyringId; - default: - return absl::nullopt; - } -} - } // namespace BraveWalletProviderDelegateImpl::BraveWalletProviderDelegateImpl( @@ -128,7 +115,7 @@ void BraveWalletProviderDelegateImpl::ShowWalletOnboarding() { void BraveWalletProviderDelegateImpl::ShowAccountCreation( mojom::CoinType type) { - auto keyring_id = CoinTypeToKeyringId(type); + auto keyring_id = CoinTypeToKeyringId(type, absl::nullopt); if (keyring_id) ::brave_wallet::ShowAccountCreation(web_contents_, *keyring_id); } diff --git a/components/brave_wallet/browser/block_tracker.cc b/components/brave_wallet/browser/block_tracker.cc index c35fc7196b7f..311a1a8ef906 100644 --- a/components/brave_wallet/browser/block_tracker.cc +++ b/components/brave_wallet/browser/block_tracker.cc @@ -5,6 +5,7 @@ #include "brave/components/brave_wallet/browser/block_tracker.h" +#include "base/containers/contains.h" #include "brave/components/brave_wallet/browser/json_rpc_service.h" namespace brave_wallet { @@ -14,12 +15,23 @@ BlockTracker::BlockTracker(JsonRpcService* json_rpc_service) DCHECK(json_rpc_service_); } +BlockTracker::~BlockTracker() = default; + +void BlockTracker::Stop(const std::string& chain_id) { + if (base::Contains(timers_, chain_id)) { + timers_.erase(chain_id); + } +} + void BlockTracker::Stop() { - timer_.Stop(); + timers_.clear(); } -bool BlockTracker::IsRunning() const { - return timer_.IsRunning(); +bool BlockTracker::IsRunning(const std::string& chain_id) const { + if (!base::Contains(timers_, chain_id)) { + return false; + } + return timers_.at(chain_id)->IsRunning(); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/block_tracker.h b/components/brave_wallet/browser/block_tracker.h index 64cb161e6ef1..1f7226153d1f 100644 --- a/components/brave_wallet/browser/block_tracker.h +++ b/components/brave_wallet/browser/block_tracker.h @@ -6,6 +6,10 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_BLOCK_TRACKER_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_BLOCK_TRACKER_H_ +#include +#include +#include + #include "base/memory/raw_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -17,14 +21,16 @@ class JsonRpcService; class BlockTracker { public: explicit BlockTracker(JsonRpcService* json_rpc_service); - virtual ~BlockTracker() = default; + virtual ~BlockTracker(); - virtual void Start(base::TimeDelta interval) = 0; + virtual void Start(const std::string& chain_id, base::TimeDelta interval) = 0; + virtual void Stop(const std::string& chain_id); virtual void Stop(); - bool IsRunning() const; + bool IsRunning(const std::string& chain_id) const; protected: - base::RepeatingTimer timer_; + // + std::map> timers_; raw_ptr json_rpc_service_ = nullptr; }; diff --git a/components/brave_wallet/browser/brave_wallet_utils.cc b/components/brave_wallet/browser/brave_wallet_utils.cc index 5ca0daf647ca..191598f14850 100644 --- a/components/brave_wallet/browser/brave_wallet_utils.cc +++ b/components/brave_wallet/browser/brave_wallet_utils.cc @@ -1507,6 +1507,25 @@ mojom::CoinType GetCoinForKeyring(const std::string& keyring_id) { return mojom::CoinType::ETH; } +absl::optional CoinTypeToKeyringId( + mojom::CoinType coin_type, + const absl::optional& chain_id) { + switch (coin_type) { + case mojom::CoinType::ETH: + return mojom::kDefaultKeyringId; + case mojom::CoinType::SOL: + return mojom::kSolanaKeyringId; + case mojom::CoinType::FIL: + if (!chain_id.has_value()) { + return mojom::kFilecoinKeyringId; + } + return GetFilecoinKeyringId(*chain_id); + default: + NOTREACHED() << "Unsupported coin type"; + return absl::nullopt; + } +} + GURL GetActiveEndpointUrl(const mojom::NetworkInfo& chain) { if (chain.active_rpc_endpoint_index >= 0 && static_cast(chain.active_rpc_endpoint_index) < diff --git a/components/brave_wallet/browser/brave_wallet_utils.h b/components/brave_wallet/browser/brave_wallet_utils.h index ddeda4f89d41..cf0adaff551f 100644 --- a/components/brave_wallet/browser/brave_wallet_utils.h +++ b/components/brave_wallet/browser/brave_wallet_utils.h @@ -188,6 +188,11 @@ std::string GetFilecoinChainId(const std::string& keyring_id); mojom::CoinType GetCoinForKeyring(const std::string& keyring_id); +// optional chain_id only matters to FIL +absl::optional CoinTypeToKeyringId( + mojom::CoinType coin_type, + const absl::optional& chain_id); + GURL GetActiveEndpointUrl(const mojom::NetworkInfo& chain); } // namespace brave_wallet diff --git a/components/brave_wallet/browser/eth_block_tracker.cc b/components/brave_wallet/browser/eth_block_tracker.cc index 3af467ab317c..23f8624b65d6 100644 --- a/components/brave_wallet/browser/eth_block_tracker.cc +++ b/components/brave_wallet/browser/eth_block_tracker.cc @@ -5,8 +5,10 @@ #include "brave/components/brave_wallet/browser/eth_block_tracker.h" +#include #include +#include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/logging.h" #include "brave/components/brave_wallet/browser/json_rpc_service.h" @@ -18,10 +20,15 @@ EthBlockTracker::EthBlockTracker(JsonRpcService* json_rpc_service) EthBlockTracker::~EthBlockTracker() = default; -void EthBlockTracker::Start(base::TimeDelta interval) { - timer_.Start(FROM_HERE, interval, - base::BindRepeating(&EthBlockTracker::GetBlockNumber, - weak_factory_.GetWeakPtr())); +void EthBlockTracker::Start(const std::string& chain_id, + base::TimeDelta interval) { + if (!base::Contains(timers_, chain_id)) { + timers_[chain_id] = std::make_unique(); + } + timers_[chain_id]->Start( + FROM_HERE, interval, + base::BindRepeating(&EthBlockTracker::GetBlockNumber, + weak_factory_.GetWeakPtr(), chain_id)); } void EthBlockTracker::AddObserver(EthBlockTracker::Observer* observer) { @@ -32,36 +39,49 @@ void EthBlockTracker::RemoveObserver(EthBlockTracker::Observer* observer) { observers_.RemoveObserver(observer); } +uint256_t EthBlockTracker::GetCurrentBlock(const std::string& chain_id) const { + if (!base::Contains(current_block_map_, chain_id)) { + return 0; + } + return current_block_map_.at(chain_id); +} + void EthBlockTracker::CheckForLatestBlock( + const std::string& chain_id, base::OnceCallback callback) { - SendGetBlockNumber(std::move(callback)); + SendGetBlockNumber(chain_id, std::move(callback)); } void EthBlockTracker::SendGetBlockNumber( + const std::string& chain_id, base::OnceCallback callback) { - json_rpc_service_->GetBlockNumber(std::move(callback)); + json_rpc_service_->GetBlockNumber(chain_id, std::move(callback)); } -void EthBlockTracker::GetBlockNumber() { - json_rpc_service_->GetBlockNumber(base::BindOnce( - &EthBlockTracker::OnGetBlockNumber, weak_factory_.GetWeakPtr())); +void EthBlockTracker::GetBlockNumber(const std::string& chain_id) { + json_rpc_service_->GetBlockNumber( + chain_id, base::BindOnce(&EthBlockTracker::OnGetBlockNumber, + weak_factory_.GetWeakPtr(), chain_id)); } -void EthBlockTracker::OnGetBlockNumber(uint256_t block_num, +void EthBlockTracker::OnGetBlockNumber(const std::string& chain_id, + uint256_t block_num, mojom::ProviderError error, const std::string& error_message) { if (error == mojom::ProviderError::kSuccess) { - if (current_block_ != block_num) { - current_block_ = block_num; - for (auto& observer : observers_) - observer.OnNewBlock(block_num); + if (GetCurrentBlock(chain_id) != block_num) { + current_block_map_[chain_id] = block_num; + for (auto& observer : observers_) { + observer.OnNewBlock(chain_id, block_num); + } + } + for (auto& observer : observers_) { + observer.OnLatestBlock(chain_id, block_num); } - for (auto& observer : observers_) - observer.OnLatestBlock(block_num); } else { LOG(ERROR) << "GetBlockNumber failed"; diff --git a/components/brave_wallet/browser/eth_block_tracker.h b/components/brave_wallet/browser/eth_block_tracker.h index bb6b5437d299..80d9777dbda0 100644 --- a/components/brave_wallet/browser/eth_block_tracker.h +++ b/components/brave_wallet/browser/eth_block_tracker.h @@ -6,6 +6,7 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ETH_BLOCK_TRACKER_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ETH_BLOCK_TRACKER_H_ +#include #include #include "base/functional/callback.h" @@ -30,35 +31,41 @@ class EthBlockTracker : public BlockTracker { class Observer : public base::CheckedObserver { public: // Fires for each latest block check - virtual void OnLatestBlock(uint256_t block_num) = 0; + virtual void OnLatestBlock(const std::string& chain_id, + uint256_t block_num) = 0; // Only fires when there is a new block - virtual void OnNewBlock(uint256_t block_num) = 0; + virtual void OnNewBlock(const std::string& chain_id, + uint256_t block_num) = 0; }; // If timer is already running, it will be replaced with new interval - void Start(base::TimeDelta interval) override; + void Start(const std::string& chain_id, base::TimeDelta interval) override; void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - uint256_t GetCurrentBlock() const { return current_block_; } + uint256_t GetCurrentBlock(const std::string& chain_id) const; void CheckForLatestBlock( + const std::string& chain_id, base::OnceCallback); private: void SendGetBlockNumber( + const std::string& chain_id, base::OnceCallback); - void GetBlockNumber(); - void OnGetBlockNumber(uint256_t block_num, + void GetBlockNumber(const std::string& chain_id); + void OnGetBlockNumber(const std::string& chain_id, + uint256_t block_num, mojom::ProviderError error, const std::string& error_message); - uint256_t current_block_ = 0; + // + std::map current_block_map_; base::ObserverList observers_; base::WeakPtrFactory weak_factory_; diff --git a/components/brave_wallet/browser/eth_logs_tracker.cc b/components/brave_wallet/browser/eth_logs_tracker.cc index ef7eea287468..244347183454 100644 --- a/components/brave_wallet/browser/eth_logs_tracker.cc +++ b/components/brave_wallet/browser/eth_logs_tracker.cc @@ -50,7 +50,8 @@ void EthLogsTracker::RemoveObserver(EthLogsTracker::Observer* observer) { } void EthLogsTracker::GetLogs() { - const auto chain_id = json_rpc_service_->GetChainId(mojom::CoinType::ETH); + const auto chain_id = + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt); for (auto const& esi : std::as_const(eth_logs_subscription_info_)) { json_rpc_service_->EthGetLogs( @@ -66,8 +67,9 @@ void EthLogsTracker::OnGetLogs(const std::string& subscription, mojom::ProviderError error, const std::string& error_message) { if (error == mojom::ProviderError::kSuccess && rawlogs.is_dict()) { - for (auto& observer : observers_) + for (auto& observer : observers_) { observer.OnLogsReceived(subscription, rawlogs.Clone()); + } } else { LOG(ERROR) << "OnGetLogs failed"; } diff --git a/components/brave_wallet/browser/eth_nonce_tracker.cc b/components/brave_wallet/browser/eth_nonce_tracker.cc index 0d43603d6f34..c6016af7220e 100644 --- a/components/brave_wallet/browser/eth_nonce_tracker.cc +++ b/components/brave_wallet/browser/eth_nonce_tracker.cc @@ -22,12 +22,14 @@ EthNonceTracker::EthNonceTracker(TxStateManager* tx_state_manager, EthNonceTracker::~EthNonceTracker() = default; -void EthNonceTracker::GetNextNonce(const std::string& from, +void EthNonceTracker::GetNextNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback) { json_rpc_service_->GetEthTransactionCount( - from, + chain_id, from, base::BindOnce(&EthNonceTracker::OnGetNetworkNonce, - weak_factory_.GetWeakPtr(), from, std::move(callback))); + weak_factory_.GetWeakPtr(), chain_id, from, + std::move(callback))); } uint256_t EthNonceTracker::GetHighestLocallyConfirmed( @@ -56,7 +58,8 @@ uint256_t EthNonceTracker::GetHighestContinuousFrom( return highest; } -void EthNonceTracker::OnGetNetworkNonce(const std::string& from, +void EthNonceTracker::OnGetNetworkNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback, uint256_t network_nonce, mojom::ProviderError error, @@ -65,8 +68,8 @@ void EthNonceTracker::OnGetNetworkNonce(const std::string& from, std::move(callback).Run(false, network_nonce); return; } - auto nonce = GetFinalNonce(EthAddress::FromHex(from).ToChecksumAddress(), - network_nonce); + auto nonce = GetFinalNonce( + chain_id, EthAddress::FromHex(from).ToChecksumAddress(), network_nonce); std::move(callback).Run(nonce.has_value(), nonce.has_value() ? *nonce : 0); } diff --git a/components/brave_wallet/browser/eth_nonce_tracker.h b/components/brave_wallet/browser/eth_nonce_tracker.h index a95265c84f8e..82e858dd9d98 100644 --- a/components/brave_wallet/browser/eth_nonce_tracker.h +++ b/components/brave_wallet/browser/eth_nonce_tracker.h @@ -30,7 +30,8 @@ class EthNonceTracker : public NonceTracker { EthNonceTracker operator=(const EthNonceTracker&) = delete; // NonceTracker - void GetNextNonce(const std::string& from, + void GetNextNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback) override; uint256_t GetHighestLocallyConfirmed( const std::vector>& metas) override; @@ -39,7 +40,8 @@ class EthNonceTracker : public NonceTracker { uint256_t start) override; private: - void OnGetNetworkNonce(const std::string& from, + void OnGetNetworkNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback, uint256_t network_nonce, mojom::ProviderError error, diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.cc b/components/brave_wallet/browser/eth_pending_tx_tracker.cc index b071df2c7fc0..920fc5cc8fcd 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.cc +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.cc @@ -8,6 +8,7 @@ #include #include +#include "base/containers/contains.h" #include "base/logging.h" #include "base/synchronization/lock.h" #include "brave/components/brave_wallet/browser/eth_nonce_tracker.h" @@ -28,15 +29,16 @@ EthPendingTxTracker::EthPendingTxTracker(EthTxStateManager* tx_state_manager, weak_factory_(this) {} EthPendingTxTracker::~EthPendingTxTracker() = default; -bool EthPendingTxTracker::UpdatePendingTransactions(size_t* num_pending) { +bool EthPendingTxTracker::UpdatePendingTransactions(const std::string& chain_id, + size_t* num_pending) { base::Lock* nonce_lock = nonce_tracker_->GetLock(); if (!nonce_lock->Try()) return false; auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); + chain_id, mojom::TransactionStatus::Submitted, absl::nullopt); auto signed_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Signed, absl::nullopt); + chain_id, mojom::TransactionStatus::Signed, absl::nullopt); pending_transactions.insert( pending_transactions.end(), std::make_move_iterator(signed_transactions.begin()), @@ -48,9 +50,9 @@ bool EthPendingTxTracker::UpdatePendingTransactions(size_t* num_pending) { } std::string id = pending_transaction->id(); json_rpc_service_->GetTransactionReceipt( - pending_transaction->tx_hash(), + chain_id, pending_transaction->tx_hash(), base::BindOnce(&EthPendingTxTracker::OnGetTxReceipt, - weak_factory_.GetWeakPtr(), std::move(id))); + weak_factory_.GetWeakPtr(), chain_id, std::move(id))); } nonce_lock->Release(); @@ -58,29 +60,13 @@ bool EthPendingTxTracker::UpdatePendingTransactions(size_t* num_pending) { return true; } -void EthPendingTxTracker::ResubmitPendingTransactions() { - // TODO(darkdh): limit the rate of tx publishing - auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); - for (const auto& pending_transaction : pending_transactions) { - auto* pending_eth_transaction = - static_cast(pending_transaction.get()); - if (!pending_eth_transaction->tx()->IsSigned()) { - continue; - } - json_rpc_service_->SendRawTransaction( - pending_eth_transaction->tx()->GetSignedTransaction(), - base::BindOnce(&EthPendingTxTracker::OnSendRawTransaction, - weak_factory_.GetWeakPtr())); - } -} - void EthPendingTxTracker::Reset() { network_nonce_map_.clear(); dropped_blocks_counter_.clear(); } -void EthPendingTxTracker::OnGetTxReceipt(std::string id, +void EthPendingTxTracker::OnGetTxReceipt(const std::string& chain_id, + std::string id, TransactionReceipt receipt, mojom::ProviderError error, const std::string& error_message) { @@ -90,7 +76,7 @@ void EthPendingTxTracker::OnGetTxReceipt(std::string id, if (!nonce_lock->Try()) return; - std::unique_ptr meta = tx_state_manager_->GetEthTx(id); + std::unique_ptr meta = tx_state_manager_->GetEthTx(chain_id, id); if (!meta) { nonce_lock->Release(); return; @@ -107,14 +93,15 @@ void EthPendingTxTracker::OnGetTxReceipt(std::string id, nonce_lock->Release(); } -void EthPendingTxTracker::OnGetNetworkNonce(std::string address, +void EthPendingTxTracker::OnGetNetworkNonce(const std::string& chain_id, + const std::string& address, uint256_t result, mojom::ProviderError error, const std::string& error_message) { if (error != mojom::ProviderError::kSuccess) return; - network_nonce_map_[address] = result; + network_nonce_map_[address][chain_id] = result; } void EthPendingTxTracker::OnSendRawTransaction( @@ -124,7 +111,7 @@ void EthPendingTxTracker::OnSendRawTransaction( bool EthPendingTxTracker::IsNonceTaken(const EthTxMeta& meta) { auto confirmed_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Confirmed, absl::nullopt); + meta.chain_id(), mojom::TransactionStatus::Confirmed, absl::nullopt); for (const auto& confirmed_transaction : confirmed_transactions) { auto* eth_confirmed_transaction = static_cast(confirmed_transaction.get()); @@ -136,20 +123,27 @@ bool EthPendingTxTracker::IsNonceTaken(const EthTxMeta& meta) { } bool EthPendingTxTracker::ShouldTxDropped(const EthTxMeta& meta) { - const std::string hex_address = meta.from(); - if (network_nonce_map_.find(hex_address) == network_nonce_map_.end()) { + const std::string& hex_address = meta.from(); + const std::string& chain_id = meta.chain_id(); + auto network_nonce_map_per_chain_id = network_nonce_map_.find(hex_address); + if (network_nonce_map_per_chain_id == network_nonce_map_.end() || + !base::Contains(network_nonce_map_per_chain_id->second, chain_id)) { json_rpc_service_->GetEthTransactionCount( - hex_address, base::BindOnce(&EthPendingTxTracker::OnGetNetworkNonce, - weak_factory_.GetWeakPtr(), hex_address)); + chain_id, hex_address, + base::BindOnce(&EthPendingTxTracker::OnGetNetworkNonce, + weak_factory_.GetWeakPtr(), chain_id, hex_address)); } else { - uint256_t network_nonce = network_nonce_map_[hex_address]; - network_nonce_map_.erase(hex_address); + uint256_t network_nonce = network_nonce_map_[hex_address][chain_id]; + network_nonce_map_per_chain_id->second.erase(chain_id); + if (network_nonce_map_per_chain_id->second.empty()) { + network_nonce_map_.erase(hex_address); + } if (meta.tx()->nonce() < network_nonce) return true; } const std::string tx_hash = meta.tx_hash(); - if (dropped_blocks_counter_.find(tx_hash) == dropped_blocks_counter_.end()) { + if (!base::Contains(dropped_blocks_counter_, tx_hash)) { dropped_blocks_counter_[tx_hash] = 0; } if (dropped_blocks_counter_[tx_hash] >= 3) { @@ -165,7 +159,7 @@ bool EthPendingTxTracker::ShouldTxDropped(const EthTxMeta& meta) { void EthPendingTxTracker::DropTransaction(TxMeta* meta) { if (!meta) return; - tx_state_manager_->DeleteTx(meta->id()); + tx_state_manager_->DeleteTx(meta->chain_id(), meta->id()); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.h b/components/brave_wallet/browser/eth_pending_tx_tracker.h index 090b099dc16d..00c1184bda29 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.h +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.h @@ -6,6 +6,7 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ETH_PENDING_TX_TRACKER_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ETH_PENDING_TX_TRACKER_H_ +#include #include #include "base/containers/flat_map.h" @@ -31,8 +32,8 @@ class EthPendingTxTracker { EthPendingTxTracker(const EthPendingTxTracker&) = delete; EthPendingTxTracker operator=(const EthPendingTxTracker&) = delete; - bool UpdatePendingTransactions(size_t* num_pending); - void ResubmitPendingTransactions(); + bool UpdatePendingTransactions(const std::string& chain_id, + size_t* num_pending); void Reset(); private: @@ -40,11 +41,13 @@ class EthPendingTxTracker { FRIEND_TEST_ALL_PREFIXES(EthPendingTxTrackerUnitTest, ShouldTxDropped); FRIEND_TEST_ALL_PREFIXES(EthPendingTxTrackerUnitTest, DropTransaction); - void OnGetTxReceipt(std::string id, + void OnGetTxReceipt(const std::string& chain_id, + std::string id, TransactionReceipt receipt, mojom::ProviderError error, const std::string& error_message); - void OnGetNetworkNonce(std::string address, + void OnGetNetworkNonce(const std::string& chain_id, + const std::string& address, uint256_t result, mojom::ProviderError error, const std::string& error_message); @@ -57,8 +60,9 @@ class EthPendingTxTracker { void DropTransaction(TxMeta*); - // (address, nonce) - base::flat_map network_nonce_map_; + // (address, (chain_id, nonce)) + base::flat_map> + network_nonce_map_; // (txHash, count) base::flat_map dropped_blocks_counter_; diff --git a/components/brave_wallet/browser/eth_tx_manager.cc b/components/brave_wallet/browser/eth_tx_manager.cc index d5ffc8d495d6..28701ca6d97f 100644 --- a/components/brave_wallet/browser/eth_tx_manager.cc +++ b/components/brave_wallet/browser/eth_tx_manager.cc @@ -77,8 +77,9 @@ bool EthTxManager::ValidateTxData(const mojom::TxDataPtr& tx_data, // static bool EthTxManager::ValidateTxData1559(const mojom::TxData1559Ptr& tx_data, std::string* error) { - if (!ValidateTxData(tx_data->base_data, error)) + if (!ValidateTxData(tx_data->base_data, error)) { return false; + } // Not allowed to have empty gas price and fee per gas if (!tx_data->base_data->gas_price.empty() && !tx_data->max_fee_per_gas.empty()) { @@ -112,7 +113,7 @@ EthTxManager::EthTxManager(TxService* tx_service, JsonRpcService* json_rpc_service, KeyringService* keyring_service, PrefService* prefs) - : TxManager(std::make_unique(prefs, json_rpc_service), + : TxManager(std::make_unique(prefs), std::make_unique(json_rpc_service), tx_service, json_rpc_service, @@ -133,6 +134,7 @@ EthTxManager::~EthTxManager() { } void EthTxManager::AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, @@ -143,17 +145,18 @@ void EthTxManager::AddUnapprovedTransaction( auto origin_val = origin.value_or(url::Origin::Create(GURL("chrome://wallet"))); if (tx_data_union->is_eth_tx_data()) { - AddUnapprovedTransaction(std::move(tx_data_union->get_eth_tx_data()), from, - std::move(origin_val), group_id, - std::move(callback)); + AddUnapprovedTransaction( + chain_id, std::move(tx_data_union->get_eth_tx_data()), from, + std::move(origin_val), group_id, std::move(callback)); } else { AddUnapproved1559Transaction( - std::move(tx_data_union->get_eth_tx_data_1559()), from, + chain_id, std::move(tx_data_union->get_eth_tx_data_1559()), from, std::move(origin_val), group_id, std::move(callback)); } } void EthTxManager::AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataPtr tx_data, const std::string& from, const url::Origin& origin, @@ -186,26 +189,30 @@ void EthTxManager::AddUnapprovedTransaction( const std::string data = tx_data->data.empty() ? "" : ToHex(tx_data->data); if (!tx_ptr->gas_price()) { - json_rpc_service_->GetGasPrice(base::BindOnce( - &EthTxManager::OnGetGasPrice, weak_factory_.GetWeakPtr(), from, origin, - tx_data->to, tx_data->value, data, gas_limit, group_id, - std::move(tx_ptr), std::move(callback), tx_data->sign_only)); + json_rpc_service_->GetGasPrice( + chain_id, + base::BindOnce(&EthTxManager::OnGetGasPrice, weak_factory_.GetWeakPtr(), + chain_id, from, origin, tx_data->to, tx_data->value, + data, gas_limit, group_id, std::move(tx_ptr), + std::move(callback), tx_data->sign_only)); } else if (!tx_ptr->gas_limit()) { json_rpc_service_->GetEstimateGas( - from, tx_data->to, "" /* gas */, "" /* gas_price */, tx_data->value, - data, + chain_id, from, tx_data->to, "" /* gas */, "" /* gas_price */, + tx_data->value, data, base::BindOnce(&EthTxManager::ContinueAddUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, group_id, - std::move(tx_ptr), std::move(callback), + weak_factory_.GetWeakPtr(), chain_id, from, origin, + group_id, std::move(tx_ptr), std::move(callback), tx_data->sign_only)); } else { - ContinueAddUnapprovedTransaction( - from, origin, group_id, std::move(tx_ptr), std::move(callback), - tx_data->sign_only, gas_limit, mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction(chain_id, from, origin, group_id, + std::move(tx_ptr), std::move(callback), + tx_data->sign_only, gas_limit, + mojom::ProviderError::kSuccess, ""); } } -void EthTxManager::OnGetGasPrice(const std::string& from, +void EthTxManager::OnGetGasPrice(const std::string& chain_id, + const std::string& from, const url::Origin& origin, const std::string& to, const std::string& value, @@ -231,18 +238,20 @@ void EthTxManager::OnGetGasPrice(const std::string& from, if (!tx->gas_limit()) { json_rpc_service_->GetEstimateGas( - from, to, "" /* gas */, "" /* gas_price */, value, data, + chain_id, from, to, "" /* gas */, "" /* gas_price */, value, data, base::BindOnce(&EthTxManager::ContinueAddUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, group_id, - std::move(tx), std::move(callback), sign_only)); + weak_factory_.GetWeakPtr(), chain_id, from, origin, + group_id, std::move(tx), std::move(callback), + sign_only)); } else { - ContinueAddUnapprovedTransaction(from, origin, group_id, std::move(tx), - std::move(callback), sign_only, gas_limit, - mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction( + chain_id, from, origin, group_id, std::move(tx), std::move(callback), + sign_only, gas_limit, mojom::ProviderError::kSuccess, ""); } } void EthTxManager::ContinueAddUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -285,12 +294,13 @@ void EthTxManager::ContinueAddUnapprovedTransaction( meta.set_created_time(base::Time::Now()); meta.set_status(mojom::TransactionStatus::Unapproved); meta.set_sign_only(sign_only); - meta.set_chain_id(GetCurrentChainId(prefs_, mojom::CoinType::ETH)); + meta.set_chain_id(chain_id); tx_state_manager_->AddOrUpdateTx(meta); std::move(callback).Run(true, meta.id(), ""); } void EthTxManager::AddUnapproved1559Transaction( + const std::string& chain_id, mojom::TxData1559Ptr tx_data, const std::string& from, const url::Origin& origin, @@ -325,26 +335,31 @@ void EthTxManager::AddUnapproved1559Transaction( bool sign_only = tx_data->base_data->sign_only; if (!tx_ptr->max_priority_fee_per_gas() || !tx_ptr->max_fee_per_gas()) { - GetGasEstimation1559(base::BindOnce( - &EthTxManager::OnGetGasOracleForUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, tx_data->base_data->to, - tx_data->base_data->value, data, gas_limit, group_id, std::move(tx_ptr), - std::move(callback), sign_only)); + GetGasEstimation1559( + chain_id, + base::BindOnce(&EthTxManager::OnGetGasOracleForUnapprovedTransaction, + weak_factory_.GetWeakPtr(), chain_id, from, origin, + tx_data->base_data->to, tx_data->base_data->value, data, + gas_limit, group_id, std::move(tx_ptr), + std::move(callback), sign_only)); } else if (gas_limit.empty()) { json_rpc_service_->GetEstimateGas( - from, tx_data->base_data->to, "" /* gas */, "" /* gas_price */, - tx_data->base_data->value, data, + chain_id, from, tx_data->base_data->to, "" /* gas */, + "" /* gas_price */, tx_data->base_data->value, data, base::BindOnce(&EthTxManager::ContinueAddUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, group_id, - std::move(tx_ptr), std::move(callback), sign_only)); + weak_factory_.GetWeakPtr(), chain_id, from, origin, + group_id, std::move(tx_ptr), std::move(callback), + sign_only)); } else { - ContinueAddUnapprovedTransaction(from, origin, group_id, std::move(tx_ptr), - std::move(callback), sign_only, gas_limit, + ContinueAddUnapprovedTransaction(chain_id, from, origin, group_id, + std::move(tx_ptr), std::move(callback), + sign_only, gas_limit, mojom::ProviderError::kSuccess, ""); } } void EthTxManager::OnGetGasOracleForUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const url::Origin& origin, const std::string& to, @@ -372,22 +387,24 @@ void EthTxManager::OnGetGasOracleForUnapprovedTransaction( if (gas_limit.empty()) { json_rpc_service_->GetEstimateGas( - from, to, "" /* gas */, "" /* gas_price */, value, data, + chain_id, from, to, "" /* gas */, "" /* gas_price */, value, data, base::BindOnce(&EthTxManager::ContinueAddUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, group_id, - std::move(tx), std::move(callback), sign_only)); + weak_factory_.GetWeakPtr(), chain_id, from, origin, + group_id, std::move(tx), std::move(callback), + sign_only)); } else { - ContinueAddUnapprovedTransaction(from, origin, group_id, std::move(tx), - std::move(callback), sign_only, gas_limit, - mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction( + chain_id, from, origin, group_id, std::move(tx), std::move(callback), + sign_only, gas_limit, mojom::ProviderError::kSuccess, ""); } } void EthTxManager::GetNonceForHardwareTransaction( + const std::string& chain_id, const std::string& tx_meta_id, GetNonceForHardwareTransactionCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!meta) { LOG(ERROR) << "No transaction found"; std::move(callback).Run(absl::nullopt); @@ -396,9 +413,10 @@ void EthTxManager::GetNonceForHardwareTransaction( if (!meta->tx()->nonce()) { auto from = meta->from(); nonce_tracker_->GetNextNonce( - from, base::BindOnce(&EthTxManager::OnGetNextNonceForHardware, - weak_factory_.GetWeakPtr(), std::move(meta), - std::move(callback))); + chain_id, from, + base::BindOnce(&EthTxManager::OnGetNextNonceForHardware, + weak_factory_.GetWeakPtr(), std::move(meta), + std::move(callback))); } else { uint256_t nonce = meta->tx()->nonce().value(); OnGetNextNonceForHardware(std::move(meta), std::move(callback), true, @@ -407,18 +425,18 @@ void EthTxManager::GetNonceForHardwareTransaction( } void EthTxManager::GetTransactionMessageToSign( + const std::string& chain_id_str, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id_str, tx_meta_id); if (!meta) { VLOG(1) << __FUNCTION__ << "No transaction found with id:" << tx_meta_id; std::move(callback).Run(nullptr); return; } uint256_t chain_id = 0; - if (!HexValueToUint256(json_rpc_service_->GetChainId(mojom::CoinType::ETH), - &chain_id)) { + if (!HexValueToUint256(meta->chain_id(), &chain_id)) { std::move(callback).Run(nullptr); return; } @@ -427,6 +445,10 @@ void EthTxManager::GetTransactionMessageToSign( std::move(callback).Run(mojom::MessageToSignUnion::NewMessageStr(encoded)); } +mojom::CoinType EthTxManager::GetCoinType() const { + return mojom::CoinType::ETH; +} + void EthTxManager::OnGetNextNonceForHardware( std::unique_ptr meta, GetNonceForHardwareTransactionCallback callback, @@ -446,13 +468,14 @@ void EthTxManager::OnGetNextNonceForHardware( } void EthTxManager::ProcessHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& v, const std::string& r, const std::string& s, ProcessHardwareSignatureCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!meta) { VLOG(1) << __FUNCTION__ << "No transaction found with id" << tx_meta_id; std::move(callback).Run( @@ -480,7 +503,8 @@ void EthTxManager::ProcessHardwareSignature( base::BindOnce(&EthTxManager::ContinueProcessHardwareSignature, weak_factory_.GetWeakPtr(), std::move(callback)); - PublishTransaction(tx_meta_id, data, std::move(internal_callback)); + PublishTransaction(meta->chain_id(), tx_meta_id, data, + std::move(internal_callback)); } void EthTxManager::ContinueProcessHardwareSignature( @@ -493,10 +517,11 @@ void EthTxManager::ContinueProcessHardwareSignature( error_message); } -void EthTxManager::ApproveTransaction(const std::string& tx_meta_id, +void EthTxManager::ApproveTransaction(const std::string& chain_id_str, + const std::string& tx_meta_id, ApproveTransactionCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id_str, tx_meta_id); if (!meta) { LOG(ERROR) << "No transaction found"; std::move(callback).Run( @@ -508,8 +533,7 @@ void EthTxManager::ApproveTransaction(const std::string& tx_meta_id, } uint256_t chain_id = 0; - if (!HexValueToUint256(json_rpc_service_->GetChainId(mojom::CoinType::ETH), - &chain_id)) { + if (!HexValueToUint256(meta->chain_id(), &chain_id)) { LOG(ERROR) << "Could not convert chain ID"; std::move(callback).Run( false, @@ -522,9 +546,10 @@ void EthTxManager::ApproveTransaction(const std::string& tx_meta_id, if (!meta->tx()->nonce()) { auto from = meta->from(); nonce_tracker_->GetNextNonce( - from, base::BindOnce(&EthTxManager::OnGetNextNonce, - weak_factory_.GetWeakPtr(), std::move(meta), - chain_id, std::move(callback))); + chain_id_str, from, + base::BindOnce(&EthTxManager::OnGetNextNonce, + weak_factory_.GetWeakPtr(), std::move(meta), chain_id, + std::move(callback))); } else { uint256_t nonce = meta->tx()->nonce().value(); OnGetNextNonce(std::move(meta), chain_id, std::move(callback), true, nonce); @@ -571,28 +596,31 @@ void EthTxManager::OnGetNextNonce(std::unique_ptr meta, mojom::ProviderErrorUnion::NewProviderError( mojom::ProviderError::kSuccess), ""); - UpdatePendingTransactions(); + UpdatePendingTransactions(meta->chain_id()); } else { - PublishTransaction(meta->id(), meta->tx()->GetSignedTransaction(), - std::move(callback)); + PublishTransaction(meta->chain_id(), meta->id(), + meta->tx()->GetSignedTransaction(), std::move(callback)); } } -void EthTxManager::PublishTransaction(const std::string& tx_meta_id, +void EthTxManager::PublishTransaction(const std::string& chain_id, + const std::string& tx_meta_id, const std::string& signed_transaction, ApproveTransactionCallback callback) { json_rpc_service_->SendRawTransaction( - signed_transaction, base::BindOnce(&EthTxManager::OnPublishTransaction, - weak_factory_.GetWeakPtr(), tx_meta_id, - std::move(callback))); + chain_id, signed_transaction, + base::BindOnce(&EthTxManager::OnPublishTransaction, + weak_factory_.GetWeakPtr(), chain_id, tx_meta_id, + std::move(callback))); } -void EthTxManager::OnPublishTransaction(std::string tx_meta_id, +void EthTxManager::OnPublishTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_hash, mojom::ProviderError error, const std::string& error_message) { - std::unique_ptr meta = tx_state_manager_->GetTx(tx_meta_id); + std::unique_ptr meta = tx_state_manager_->GetTx(chain_id, tx_meta_id); if (!meta) { DCHECK(false) << "Transaction should be found"; std::move(callback).Run( @@ -614,7 +642,7 @@ void EthTxManager::OnPublishTransaction(std::string tx_meta_id, tx_state_manager_->AddOrUpdateTx(*meta); if (error == mojom::ProviderError::kSuccess) { - UpdatePendingTransactions(); + UpdatePendingTransactions(chain_id); } std::move(callback).Run(error_message.empty(), @@ -691,7 +719,7 @@ void EthTxManager::MakeERC721TransferFromData( } const std::string chain_id = - json_rpc_service_->GetChainId(mojom::CoinType::ETH); + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt); // Check if safeTransferFrom is supported first. json_rpc_service_->GetSupportsInterface( contract_address, kERC721InterfaceId, chain_id, @@ -770,10 +798,12 @@ void EthTxManager::NotifyUnapprovedTxUpdated(TxMeta* meta) { } void EthTxManager::GetAllTransactionInfo( + const absl::optional& chain_id, const absl::optional& from, GetAllTransactionInfoCallback callback) { if (!from) { - TxManager::GetAllTransactionInfo(absl::nullopt, std::move(callback)); + TxManager::GetAllTransactionInfo(chain_id, absl::nullopt, + std::move(callback)); return; } auto from_address = EthAddress::FromHex(from.value()); @@ -781,11 +811,12 @@ void EthTxManager::GetAllTransactionInfo( std::move(callback).Run(std::vector()); return; } - TxManager::GetAllTransactionInfo(from_address.ToChecksumAddress(), + TxManager::GetAllTransactionInfo(chain_id, from_address.ToChecksumAddress(), std::move(callback)); } void EthTxManager::SetGasPriceAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& gas_price, const std::string& gas_limit, @@ -795,7 +826,7 @@ void EthTxManager::SetGasPriceAndLimitForUnapprovedTransaction( return; } - auto tx_meta = GetEthTxStateManager()->GetEthTx(tx_meta_id); + auto tx_meta = GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!tx_meta || tx_meta->status() != mojom::TransactionStatus::Unapproved) { std::move(callback).Run(false); return; @@ -820,6 +851,7 @@ void EthTxManager::SetGasPriceAndLimitForUnapprovedTransaction( } void EthTxManager::SetGasFeeAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& max_priority_fee_per_gas, const std::string& max_fee_per_gas, @@ -831,7 +863,7 @@ void EthTxManager::SetGasFeeAndLimitForUnapprovedTransaction( return; } - auto tx_meta = GetEthTxStateManager()->GetEthTx(tx_meta_id); + auto tx_meta = GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!tx_meta || tx_meta->status() != mojom::TransactionStatus::Unapproved || tx_meta->tx()->type() != 2 /* Eip1559 */) { std::move(callback).Run(false); @@ -865,10 +897,11 @@ void EthTxManager::SetGasFeeAndLimitForUnapprovedTransaction( } void EthTxManager::SetDataForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& data, SetDataForUnapprovedTransactionCallback callback) { - auto tx_meta = GetEthTxStateManager()->GetEthTx(tx_meta_id); + auto tx_meta = GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!tx_meta || tx_meta->status() != mojom::TransactionStatus::Unapproved) { std::move(callback).Run(false); return; @@ -881,10 +914,11 @@ void EthTxManager::SetDataForUnapprovedTransaction( } void EthTxManager::SetNonceForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& nonce, SetNonceForUnapprovedTransactionCallback callback) { - auto tx_meta = GetEthTxStateManager()->GetEthTx(tx_meta_id); + auto tx_meta = GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!tx_meta || tx_meta->status() != mojom::TransactionStatus::Unapproved) { std::move(callback).Run(false); return; @@ -906,28 +940,35 @@ void EthTxManager::SetNonceForUnapprovedTransaction( } std::unique_ptr EthTxManager::GetTxForTesting( + const std::string& chain_id, const std::string& tx_meta_id) { - return GetEthTxStateManager()->GetEthTx(tx_meta_id); + return GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); } -void EthTxManager::OnNewBlock(uint256_t block_num) { - UpdatePendingTransactions(); +void EthTxManager::OnNewBlock(const std::string& chain_id, + uint256_t block_num) { + UpdatePendingTransactions(chain_id); } -void EthTxManager::UpdatePendingTransactions() { +void EthTxManager::UpdatePendingTransactions(const std::string& chain_id) { size_t num_pending; - if (pending_tx_tracker_->UpdatePendingTransactions(&num_pending)) { - known_no_pending_tx_ = num_pending == 0; - CheckIfBlockTrackerShouldRun(); + if (pending_tx_tracker_->UpdatePendingTransactions(chain_id, &num_pending)) { + if (num_pending == 0) { + known_no_pending_tx_.emplace(chain_id); + } else { + known_no_pending_tx_.erase(chain_id); + } + CheckIfBlockTrackerShouldRun(chain_id); } } void EthTxManager::SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!meta || meta->status() != mojom::TransactionStatus::Submitted) { std::move(callback).Run( false, "", @@ -944,11 +985,13 @@ void EthTxManager::SpeedupOrCancelTransaction( tx->set_data(std::vector()); } - GetGasEstimation1559(base::BindOnce( - &EthTxManager::ContinueSpeedupOrCancel1559Transaction, - weak_factory_.GetWeakPtr(), meta->from(), meta->origin(), - meta->group_id(), Uint256ValueToHex(meta->tx()->gas_limit()), - std::move(tx), std::move(callback))); + GetGasEstimation1559( + meta->chain_id(), + base::BindOnce(&EthTxManager::ContinueSpeedupOrCancel1559Transaction, + weak_factory_.GetWeakPtr(), meta->chain_id(), + meta->from(), meta->origin(), meta->group_id(), + Uint256ValueToHex(meta->tx()->gas_limit()), + std::move(tx), std::move(callback))); } else { auto tx = std::make_unique(*meta->tx()); if (cancel) { @@ -965,15 +1008,18 @@ void EthTxManager::SpeedupOrCancelTransaction( return; } - json_rpc_service_->GetGasPrice(base::BindOnce( - &EthTxManager::ContinueSpeedupOrCancelTransaction, - weak_factory_.GetWeakPtr(), meta->from(), meta->origin(), - meta->group_id(), Uint256ValueToHex(meta->tx()->gas_limit()), - std::move(tx), std::move(callback))); + json_rpc_service_->GetGasPrice( + meta->chain_id(), + base::BindOnce(&EthTxManager::ContinueSpeedupOrCancelTransaction, + weak_factory_.GetWeakPtr(), meta->chain_id(), + meta->from(), meta->origin(), meta->group_id(), + Uint256ValueToHex(meta->tx()->gas_limit()), + std::move(tx), std::move(callback))); } } void EthTxManager::ContinueSpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -1009,12 +1055,13 @@ void EthTxManager::ContinueSpeedupOrCancelTransaction( static_cast(tx->gas_price()) * 11ULL / 10ULL; tx->set_gas_price(std::max(latest_estimate_gas_price, increased_gas_price)); - ContinueAddUnapprovedTransaction(from, origin, group_id, std::move(tx), - std::move(callback), false, gas_limit, - mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction( + chain_id, from, origin, group_id, std::move(tx), std::move(callback), + false, gas_limit, mojom::ProviderError::kSuccess, ""); } void EthTxManager::ContinueSpeedupOrCancel1559Transaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -1056,15 +1103,16 @@ void EthTxManager::ContinueSpeedupOrCancel1559Transaction( std::max(estimation->avg_max_priority_fee_per_gas, increased_max_priority_fee_per_gas)); - ContinueAddUnapprovedTransaction(from, origin, group_id, std::move(tx), - std::move(callback), false, gas_limit, - mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction( + chain_id, from, origin, group_id, std::move(tx), std::move(callback), + false, gas_limit, mojom::ProviderError::kSuccess, ""); } -void EthTxManager::RetryTransaction(const std::string& tx_meta_id, +void EthTxManager::RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!meta || meta->status() != mojom::TransactionStatus::Error) { std::move(callback).Run( false, "", @@ -1080,14 +1128,17 @@ void EthTxManager::RetryTransaction(const std::string& tx_meta_id, tx = std::make_unique(*meta->tx()); } - ContinueAddUnapprovedTransaction( - meta->from(), meta->origin(), meta->group_id(), std::move(tx), - std::move(callback), false, Uint256ValueToHex(meta->tx()->gas_limit()), - mojom::ProviderError::kSuccess, ""); + ContinueAddUnapprovedTransaction(meta->chain_id(), meta->from(), + meta->origin(), meta->group_id(), + std::move(tx), std::move(callback), false, + Uint256ValueToHex(meta->tx()->gas_limit()), + mojom::ProviderError::kSuccess, ""); } -void EthTxManager::GetGasEstimation1559(GetGasEstimation1559Callback callback) { +void EthTxManager::GetGasEstimation1559(const std::string& chain_id, + GetGasEstimation1559Callback callback) { json_rpc_service_->GetFeeHistory( + chain_id, base::BindOnce(&EthTxManager::OnGetGasEstimation1559, weak_factory_.GetWeakPtr(), std::move(callback))); } diff --git a/components/brave_wallet/browser/eth_tx_manager.h b/components/brave_wallet/browser/eth_tx_manager.h index 91557856509f..00c893cddc03 100644 --- a/components/brave_wallet/browser/eth_tx_manager.h +++ b/components/brave_wallet/browser/eth_tx_manager.h @@ -41,23 +41,29 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { EthTxManager operator=(const EthTxManager&) = delete; // TxManager - void AddUnapprovedTransaction(mojom::TxDataUnionPtr tx_data_union, + void AddUnapprovedTransaction(const std::string& chain_id, + mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, const absl::optional& groupId, AddUnapprovedTransactionCallback) override; - void ApproveTransaction(const std::string& tx_meta_id, + void ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback) override; - void GetAllTransactionInfo(const absl::optional& from, + void GetAllTransactionInfo(const absl::optional& chain_id, + const absl::optional& from, GetAllTransactionInfoCallback) override; void SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) override; - void RetryTransaction(const std::string& tx_meta_id, + void RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) override; void GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) override; @@ -109,41 +115,49 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { MakeERC1155TransferFromDataCallback); void SetGasPriceAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& gas_price, const std::string& gas_limit, SetGasPriceAndLimitForUnapprovedTransactionCallback callback); void SetGasFeeAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& max_priority_fee_per_gas, const std::string& max_fee_per_gas, const std::string& gas_limit, SetGasFeeAndLimitForUnapprovedTransactionCallback callback); void SetDataForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& data, SetDataForUnapprovedTransactionCallback callback); void SetNonceForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& nonce, SetNonceForUnapprovedTransactionCallback); void GetNonceForHardwareTransaction( + const std::string& chain_id, const std::string& tx_meta_id, GetNonceForHardwareTransactionCallback callback); - void ProcessHardwareSignature(const std::string& tx_meta_id, + void ProcessHardwareSignature(const std::string& chain_id, + const std::string& tx_meta_id, const std::string& v, const std::string& r, const std::string& s, ProcessHardwareSignatureCallback callback); // Gas estimation API via eth_feeHistory API - void GetGasEstimation1559(GetGasEstimation1559Callback callback); + void GetGasEstimation1559(const std::string& chain_id, + GetGasEstimation1559Callback callback); static bool ValidateTxData(const mojom::TxDataPtr& tx_data, std::string* error); static bool ValidateTxData1559(const mojom::TxData1559Ptr& tx_data, std::string* error); - std::unique_ptr GetTxForTesting(const std::string& tx_meta_id); + std::unique_ptr GetTxForTesting(const std::string& chain_id, + const std::string& tx_meta_id); private: FRIEND_TEST_ALL_PREFIXES(EthTxManagerUnitTest, TestSubmittedToConfirmed); @@ -151,12 +165,16 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { FRIEND_TEST_ALL_PREFIXES(EthTxManagerUnitTest, Reset); friend class EthTxManagerUnitTest; - void AddUnapprovedTransaction(mojom::TxDataPtr tx_data, + mojom::CoinType GetCoinType() const override; + + void AddUnapprovedTransaction(const std::string& chain_id, + mojom::TxDataPtr tx_data, const std::string& from, const url::Origin& origin, const absl::optional& groupId, AddUnapprovedTransactionCallback); - void AddUnapproved1559Transaction(mojom::TxData1559Ptr tx_data, + void AddUnapproved1559Transaction(const std::string& chain_id, + mojom::TxData1559Ptr tx_data, const std::string& from, const url::Origin& origin, const absl::optional& groupId, @@ -174,15 +192,18 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { GetNonceForHardwareTransactionCallback callback, bool success, uint256_t nonce); - void PublishTransaction(const std::string& tx_meta_id, + void PublishTransaction(const std::string& chain_id, + const std::string& tx_meta_id, const std::string& signed_transaction, ApproveTransactionCallback callback); - void OnPublishTransaction(std::string tx_meta_id, + void OnPublishTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_hash, mojom::ProviderError error, const std::string& error_message); - void OnGetGasPrice(const std::string& from, + void OnGetGasPrice(const std::string& chain_id, + const std::string& from, const url::Origin& origin, const std::string& to, const std::string& value, @@ -196,6 +217,7 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { mojom::ProviderError error, const std::string& error_message); void ContinueAddUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -214,6 +236,7 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { mojom::ProviderError error, const std::string& error_message); void OnGetGasOracleForUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const url::Origin& origin, const std::string& to, @@ -225,9 +248,10 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { AddUnapprovedTransactionCallback callback, bool sign_only, mojom::GasEstimation1559Ptr gas_estimation); - void UpdatePendingTransactions() override; + void UpdatePendingTransactions(const std::string& chain_id) override; void ContinueSpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -238,6 +262,7 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { mojom::ProviderError error, const std::string& error_message); void ContinueSpeedupOrCancel1559Transaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -262,8 +287,9 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { const std::string& error_message); // EthBlockTracker::Observer: - void OnLatestBlock(uint256_t block_num) override {} - void OnNewBlock(uint256_t block_num) override; + void OnLatestBlock(const std::string& chain_id, + uint256_t block_num) override {} + void OnNewBlock(const std::string& chain_id, uint256_t block_num) override; EthTxStateManager* GetEthTxStateManager(); EthBlockTracker* GetEthBlockTracker(); diff --git a/components/brave_wallet/browser/eth_tx_state_manager.cc b/components/brave_wallet/browser/eth_tx_state_manager.cc index 41de8eb6e0d1..13ac7c4d4c95 100644 --- a/components/brave_wallet/browser/eth_tx_state_manager.cc +++ b/components/brave_wallet/browser/eth_tx_state_manager.cc @@ -15,31 +15,32 @@ #include "brave/components/brave_wallet/browser/eip1559_transaction.h" #include "brave/components/brave_wallet/browser/eip2930_transaction.h" #include "brave/components/brave_wallet/browser/eth_tx_meta.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/tx_meta.h" #include "brave/components/brave_wallet/common/eth_address.h" namespace brave_wallet { -EthTxStateManager::EthTxStateManager(PrefService* prefs, - JsonRpcService* json_rpc_service) - : TxStateManager(prefs, json_rpc_service) {} +EthTxStateManager::EthTxStateManager(PrefService* prefs) + : TxStateManager(prefs) {} EthTxStateManager::~EthTxStateManager() = default; std::vector> EthTxStateManager::GetTransactionsByStatus( - absl::optional status, - absl::optional from) { + const absl::optional& chain_id, + const absl::optional& status, + const absl::optional& from) { std::vector> result; absl::optional from_string = from.has_value() ? absl::optional(from->ToChecksumAddress()) : absl::nullopt; - return TxStateManager::GetTransactionsByStatus(status, from_string); + return TxStateManager::GetTransactionsByStatus(chain_id, status, from_string); } -std::unique_ptr EthTxStateManager::GetEthTx(const std::string& id) { +std::unique_ptr EthTxStateManager::GetEthTx( + const std::string& chain_id, + const std::string& id) { return std::unique_ptr{ - static_cast(TxStateManager::GetTx(id).release())}; + static_cast(TxStateManager::GetTx(chain_id, id).release())}; } std::unique_ptr EthTxStateManager::ValueToEthTxMeta( @@ -48,6 +49,10 @@ std::unique_ptr EthTxStateManager::ValueToEthTxMeta( static_cast(ValueToTxMeta(value).release())}; } +mojom::CoinType EthTxStateManager::GetCoinType() const { + return mojom::CoinType::ETH; +} + std::unique_ptr EthTxStateManager::ValueToTxMeta( const base::Value::Dict& value) { std::unique_ptr meta = std::make_unique(); @@ -109,11 +114,14 @@ std::unique_ptr EthTxStateManager::ValueToTxMeta( return meta; } -std::string EthTxStateManager::GetTxPrefPathPrefix() { - return base::StrCat( - {kEthereumPrefKey, ".", - GetNetworkId(prefs_, mojom::CoinType::ETH, - json_rpc_service_->GetChainId(mojom::CoinType::ETH))}); +std::string EthTxStateManager::GetTxPrefPathPrefix( + const absl::optional& chain_id) { + if (chain_id.has_value()) { + return base::StrCat( + {kEthereumPrefKey, ".", + GetNetworkId(prefs_, mojom::CoinType::ETH, *chain_id)}); + } + return kEthereumPrefKey; } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/eth_tx_state_manager.h b/components/brave_wallet/browser/eth_tx_state_manager.h index 690cb1ee8646..2defe1f80f21 100644 --- a/components/brave_wallet/browser/eth_tx_state_manager.h +++ b/components/brave_wallet/browser/eth_tx_state_manager.h @@ -27,29 +27,32 @@ namespace brave_wallet { class TxMeta; class EthTxMeta; -class JsonRpcService; class EthTxStateManager : public TxStateManager { public: - explicit EthTxStateManager(PrefService* prefs, - JsonRpcService* json_rpc_service); + explicit EthTxStateManager(PrefService* prefs); ~EthTxStateManager() override; EthTxStateManager(const EthTxStateManager&) = delete; EthTxStateManager operator=(const EthTxStateManager&) = delete; std::vector> GetTransactionsByStatus( - absl::optional status, - absl::optional from); + const absl::optional& chain_id, + const absl::optional& status, + const absl::optional& from); - std::unique_ptr GetEthTx(const std::string& id); + std::unique_ptr GetEthTx(const std::string& chain_id, + const std::string& id); std::unique_ptr ValueToEthTxMeta(const base::Value::Dict& value); private: FRIEND_TEST_ALL_PREFIXES(EthTxStateManagerUnitTest, GetTxPrefPathPrefix); + mojom::CoinType GetCoinType() const override; + std::unique_ptr ValueToTxMeta( const base::Value::Dict& value) override; - std::string GetTxPrefPathPrefix() override; + std::string GetTxPrefPathPrefix( + const absl::optional& chain_id) override; }; } // namespace brave_wallet diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index 40591ae69a45..75e47e483c11 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -103,8 +103,9 @@ EthereumProviderImpl::EthereumProviderImpl( host_content_settings_map_->AddObserver(this); // Get the current so we can compare for changed events - if (delegate_) + if (delegate_) { UpdateKnownAccounts(); + } eth_block_tracker_.AddObserver(this); eth_logs_tracker_.AddObserver(this); @@ -178,7 +179,8 @@ void EthereumProviderImpl::AddEthereumChain(const std::string& json_payload, // Check if we already have the chain if (GetNetworkURL(prefs_, chain_id_lower, mojom::CoinType::ETH).is_valid()) { if (base::CompareCaseInsensitiveASCII( - json_rpc_service_->GetChainId(mojom::CoinType::ETH), + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin()), chain_id_lower) != 0) { SwitchEthereumChain(chain_id_lower, std::move(callback), std::move(id)); return; @@ -234,8 +236,9 @@ void EthereumProviderImpl::OnAddEthereumChain( DCHECK(delegate_); std::string chain_id_lower = base::ToLowerASCII(chain_id); if (!chain_callbacks_.contains(chain_id_lower) || - !chain_ids_.contains(chain_id_lower)) + !chain_ids_.contains(chain_id_lower)) { return; + } if (error != mojom::ProviderError::kSuccess) { base::Value formed_response = GetProviderErrorDictionary(error, error_message); @@ -255,8 +258,10 @@ void EthereumProviderImpl::SwitchEthereumChain(const std::string& chain_id, base::Value id) { // Only show bubble when there is no immediate error if (json_rpc_service_->AddSwitchEthereumChainRequest( - chain_id, delegate_->GetOrigin(), std::move(callback), std::move(id))) + chain_id, delegate_->GetOrigin(), std::move(callback), + std::move(id))) { delegate_->ShowPanel(); + } } void EthereumProviderImpl::ContinueGetDefaultKeyringInfo( @@ -314,7 +319,7 @@ void EthereumProviderImpl::OnGetNetworkAndDefaultKeyringInfo( // If the chain id is not known yet, then get it and set it first if (tx_data_1559->chain_id == "0x0" || tx_data_1559->chain_id.empty()) { json_rpc_service_->GetChainId( - mojom::CoinType::ETH, + mojom::CoinType::ETH, origin, base::BindOnce( &EthereumProviderImpl::ContinueAddAndApprove1559Transaction, weak_factory_.GetWeakPtr(), std::move(callback), std::move(id), @@ -505,8 +510,9 @@ void EthereumProviderImpl::SignMessage(const std::string& address, } std::string message_str(message_bytes.begin(), message_bytes.end()); - if (!base::IsStringUTF8(message_str)) + if (!base::IsStringUTF8(message_str)) { message_str = ToHex(message_str); + } // Convert to checksum address auto checksum_address = EthAddress::FromHex(address); @@ -591,6 +597,8 @@ void EthereumProviderImpl::EthSubscribe( const auto gen_res = generateHexBytes(eth_subscriptions_); if (std::get<0>(gen_res)) { eth_block_tracker_.Start( + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin()), base::Seconds(kBlockTrackerDefaultTimeInSeconds)); } std::move(callback).Run(std::move(id), base::Value(std::get<1>(gen_res)), @@ -633,7 +641,8 @@ bool EthereumProviderImpl::UnsubscribeBlockObserver( bool found = it != eth_subscriptions_.end(); if (found) { if (eth_subscriptions_.size() == 1) { - eth_block_tracker_.Stop(); + eth_block_tracker_.Stop(json_rpc_service_->GetChainId( + mojom::CoinType::ETH, delegate_->GetOrigin())); } eth_subscriptions_.erase(it); } @@ -827,8 +836,9 @@ void EthereumProviderImpl::SignTypedMessage( const std::string chain_id_hex = Uint256ValueToHex((uint256_t)(uint64_t)*chain_id); if (base::CompareCaseInsensitiveASCII( - chain_id_hex, - json_rpc_service_->GetChainId(mojom::CoinType::ETH)) != 0) { + chain_id_hex, json_rpc_service_->GetChainId( + mojom::CoinType::ETH, delegate_->GetOrigin())) != + 0) { base::Value formed_response = GetProviderErrorDictionary( mojom::ProviderError::kInternalError, l10n_util::GetStringFUTF8( @@ -993,8 +1003,9 @@ void EthereumProviderImpl::OnAddEthereumChainRequestCompleted( const std::string& error) { std::string chain_id_lower = base::ToLowerASCII(chain_id); if (!chain_callbacks_.contains(chain_id_lower) || - !chain_ids_.contains(chain_id_lower)) + !chain_ids_.contains(chain_id_lower)) { return; + } if (error.empty()) { // To match MM for webcompat, after adding a chain we should prompt // again to switch to the chain. And the error result only depends on @@ -1113,14 +1124,14 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( SwitchEthereumChain(chain_id, std::move(callback), std::move(id)); } else if (method == kEthSendTransaction) { json_rpc_service_->GetNetwork( - mojom::CoinType::ETH, + mojom::CoinType::ETH, delegate_->GetOrigin(), base::BindOnce(&EthereumProviderImpl::ContinueGetDefaultKeyringInfo, weak_factory_.GetWeakPtr(), std::move(callback), std::move(id), normalized_json_request, delegate_->GetOrigin(), false)); } else if (method == kEthSignTransaction) { json_rpc_service_->GetNetwork( - mojom::CoinType::ETH, + mojom::CoinType::ETH, delegate_->GetOrigin(), base::BindOnce(&EthereumProviderImpl::ContinueGetDefaultKeyringInfo, weak_factory_.GetWeakPtr(), std::move(callback), std::move(id), normalized_json_request, @@ -1134,6 +1145,8 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( return; } json_rpc_service_->SendRawTransaction( + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin()), signed_transaction, base::BindOnce(&EthereumProviderImpl::OnSendRawTransaction, weak_factory_.GetWeakPtr(), std::move(callback), @@ -1215,12 +1228,14 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( std::move(callback), std::move(id)); } else if (method == kWalletWatchAsset || method == kMetamaskWatchAsset) { mojom::BlockchainTokenPtr token; - const auto chain_id = json_rpc_service_->GetChainId(mojom::CoinType::ETH); + const auto chain_id = json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin()); if (!ParseWalletWatchAssetParams(normalized_json_request, chain_id, mojom::CoinType::ETH, &token, &error_message)) { - if (!error_message.empty()) + if (!error_message.empty()) { error = mojom::ProviderError::kInvalidParams; + } SendErrorOnRequest(error, error_message, std::move(callback), std::move(id)); return; @@ -1270,8 +1285,11 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( } EthUnsubscribe(subscription_id, std::move(callback), std::move(id)); } else { - json_rpc_service_->Request(normalized_json_request, true, std::move(id), - mojom::CoinType::ETH, std::move(callback)); + json_rpc_service_->Request( + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin()), + normalized_json_request, true, std::move(id), mojom::CoinType::ETH, + std::move(callback)); } } @@ -1561,7 +1579,8 @@ void EthereumProviderImpl::Web3ClientVersion(RequestCallback callback, void EthereumProviderImpl::GetChainId(GetChainIdCallback callback) { if (json_rpc_service_) { - json_rpc_service_->GetChainId(mojom::CoinType::ETH, std::move(callback)); + json_rpc_service_->GetChainId(mojom::CoinType::ETH, delegate_->GetOrigin(), + std::move(callback)); } } @@ -1574,8 +1593,9 @@ void EthereumProviderImpl::Init( void EthereumProviderImpl::ChainChangedEvent(const std::string& chain_id, mojom::CoinType coin) { - if (!events_listener_.is_bound() || coin != mojom::CoinType::ETH) + if (!events_listener_.is_bound() || coin != mojom::CoinType::ETH) { return; + } events_listener_->ChainChangedEvent(chain_id); } @@ -1586,13 +1606,15 @@ void EthereumProviderImpl::OnTransactionStatusChanged( if (tx_status != mojom::TransactionStatus::Submitted && tx_status != mojom::TransactionStatus::Signed && tx_status != mojom::TransactionStatus::Rejected && - tx_status != mojom::TransactionStatus::Error) + tx_status != mojom::TransactionStatus::Error) { return; + } std::string tx_meta_id = tx_info->id; if (!add_tx_callbacks_.contains(tx_meta_id) || - !add_tx_ids_.contains(tx_meta_id)) + !add_tx_ids_.contains(tx_meta_id)) { return; + } std::string tx_hash = tx_info->tx_hash; base::Value formed_response; @@ -1634,8 +1656,9 @@ void EthereumProviderImpl::OnTransactionStatusChanged( } void EthereumProviderImpl::SelectedAccountChanged(mojom::CoinType coin) { - if (coin != mojom::CoinType::ETH) + if (coin != mojom::CoinType::ETH) { return; + } UpdateKnownAccounts(); } @@ -1701,9 +1724,10 @@ void EthereumProviderImpl::OnSendRawTransaction( } // EthBlockTracker::Observer: -void EthereumProviderImpl::OnLatestBlock(uint256_t block_num) { +void EthereumProviderImpl::OnLatestBlock(const std::string& chain_id, + uint256_t block_num) { json_rpc_service_->GetBlockByNumber( - kEthereumBlockTagLatest, + chain_id, kEthereumBlockTagLatest, base::BindOnce(&EthereumProviderImpl::OnGetBlockByNumber, weak_factory_.GetWeakPtr())); } @@ -1721,7 +1745,8 @@ void EthereumProviderImpl::OnGetBlockByNumber( } } -void EthereumProviderImpl::OnNewBlock(uint256_t block_num) {} +void EthereumProviderImpl::OnNewBlock(const std::string& chain_id, + uint256_t block_num) {} void EthereumProviderImpl::OnLogsReceived(const std::string& subscription, base::Value rawlogs) { diff --git a/components/brave_wallet/browser/ethereum_provider_impl.h b/components/brave_wallet/browser/ethereum_provider_impl.h index f16dfda989b4..3d6808041b66 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.h +++ b/components/brave_wallet/browser/ethereum_provider_impl.h @@ -385,8 +385,8 @@ class EthereumProviderImpl final const bool update_bind_js_properties); // EthBlockTracker::Observer: - void OnLatestBlock(uint256_t block_num) override; - void OnNewBlock(uint256_t block_num) override; + void OnLatestBlock(const std::string& chain_id, uint256_t block_num) override; + void OnNewBlock(const std::string& chain_id, uint256_t block_num) override; bool UnsubscribeBlockObserver(const std::string& subscription_id); // EthLogsTracker::Observer: diff --git a/components/brave_wallet/browser/fil_block_tracker.cc b/components/brave_wallet/browser/fil_block_tracker.cc index 1551976b30b0..052aedb2fb1a 100644 --- a/components/brave_wallet/browser/fil_block_tracker.cc +++ b/components/brave_wallet/browser/fil_block_tracker.cc @@ -5,8 +5,10 @@ #include "brave/components/brave_wallet/browser/fil_block_tracker.h" +#include #include +#include "base/containers/contains.h" #include "base/functional/bind.h" #include "brave/components/brave_wallet/browser/json_rpc_service.h" @@ -17,20 +19,35 @@ FilBlockTracker::FilBlockTracker(JsonRpcService* json_rpc_service) FilBlockTracker::~FilBlockTracker() = default; -void FilBlockTracker::Start(base::TimeDelta interval) { - timer_.Start(FROM_HERE, interval, - base::BindRepeating(&FilBlockTracker::GetFilBlockHeight, - weak_ptr_factory_.GetWeakPtr(), - base::NullCallback())); +void FilBlockTracker::Start(const std::string& chain_id, + base::TimeDelta interval) { + if (!base::Contains(timers_, chain_id)) { + timers_[chain_id] = std::make_unique(); + } + timers_[chain_id]->Start( + FROM_HERE, interval, + base::BindRepeating(&FilBlockTracker::GetFilBlockHeight, + weak_ptr_factory_.GetWeakPtr(), chain_id, + base::NullCallback())); } -void FilBlockTracker::GetFilBlockHeight(GetFilBlockHeightCallback callback) { +void FilBlockTracker::GetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback) { json_rpc_service_->GetFilBlockHeight( - base::BindOnce(&FilBlockTracker::OnGetFilBlockHeight, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + chain_id, base::BindOnce(&FilBlockTracker::OnGetFilBlockHeight, + weak_ptr_factory_.GetWeakPtr(), chain_id, + std::move(callback))); } -void FilBlockTracker::OnGetFilBlockHeight(GetFilBlockHeightCallback callback, +uint64_t FilBlockTracker::GetLatestHeight(const std::string& chain_id) const { + if (!base::Contains(latest_height_map_, chain_id)) { + return 0; + } + return latest_height_map_.at(chain_id); +} + +void FilBlockTracker::OnGetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback, uint64_t latest_height, mojom::FilecoinProviderError error, const std::string& error_message) { @@ -42,11 +59,12 @@ void FilBlockTracker::OnGetFilBlockHeight(GetFilBlockHeightCallback callback, << static_cast(error) << ", error_message: " << error_message; return; } - if (latest_height_ == latest_height) + if (GetLatestHeight(chain_id) == latest_height) { return; - latest_height_ = latest_height; + } + latest_height_map_[chain_id] = latest_height; for (auto& observer : observers_) - observer.OnLatestHeightUpdated(latest_height); + observer.OnLatestHeightUpdated(chain_id, latest_height); } void FilBlockTracker::AddObserver(FilBlockTracker::Observer* observer) { diff --git a/components/brave_wallet/browser/fil_block_tracker.h b/components/brave_wallet/browser/fil_block_tracker.h index 226f40fb1d58..2ad1a7e9c6ef 100644 --- a/components/brave_wallet/browser/fil_block_tracker.h +++ b/components/brave_wallet/browser/fil_block_tracker.h @@ -6,6 +6,7 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_FIL_BLOCK_TRACKER_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_FIL_BLOCK_TRACKER_H_ +#include #include #include "base/memory/weak_ptr.h" @@ -27,7 +28,8 @@ class FilBlockTracker : public BlockTracker { class Observer : public base::CheckedObserver { public: - virtual void OnLatestHeightUpdated(uint64_t latest_height) = 0; + virtual void OnLatestHeightUpdated(const std::string& chain_id, + uint64_t latest_height) = 0; }; void AddObserver(Observer* observer); @@ -36,18 +38,21 @@ class FilBlockTracker : public BlockTracker { base::OnceCallback; - void GetFilBlockHeight(GetFilBlockHeightCallback callback); - uint64_t latest_height() const { return latest_height_; } + void GetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback); + uint64_t GetLatestHeight(const std::string& chain_id) const; // If timer is already running, it will be replaced with new interval - void Start(base::TimeDelta interval) override; + void Start(const std::string& chain_id, base::TimeDelta interval) override; private: - void OnGetFilBlockHeight(GetFilBlockHeightCallback callback, + void OnGetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback, uint64_t latest_height, mojom::FilecoinProviderError error, const std::string& error_message); - uint64_t latest_height_ = 0; + // + std::map latest_height_map_; base::ObserverList observers_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/components/brave_wallet/browser/fil_nonce_tracker.cc b/components/brave_wallet/browser/fil_nonce_tracker.cc index 065d17734782..bf8cec3f3708 100644 --- a/components/brave_wallet/browser/fil_nonce_tracker.cc +++ b/components/brave_wallet/browser/fil_nonce_tracker.cc @@ -20,12 +20,14 @@ FilNonceTracker::FilNonceTracker(TxStateManager* tx_state_manager, FilNonceTracker::~FilNonceTracker() = default; -void FilNonceTracker::GetNextNonce(const std::string& from, +void FilNonceTracker::GetNextNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback) { json_rpc_service_->GetFilTransactionCount( - from, + chain_id, from, base::BindOnce(&FilNonceTracker::OnGetNetworkNonce, - weak_factory_.GetWeakPtr(), from, std::move(callback))); + weak_factory_.GetWeakPtr(), chain_id, from, + std::move(callback))); } uint256_t FilNonceTracker::GetHighestLocallyConfirmed( @@ -56,7 +58,8 @@ uint256_t FilNonceTracker::GetHighestContinuousFrom( return static_cast(highest); } -void FilNonceTracker::OnGetNetworkNonce(const std::string& from, +void FilNonceTracker::OnGetNetworkNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback, uint256_t network_nonce, mojom::FilecoinProviderError error, @@ -65,7 +68,7 @@ void FilNonceTracker::OnGetNetworkNonce(const std::string& from, std::move(callback).Run(false, network_nonce); return; } - auto nonce = GetFinalNonce(from, network_nonce); + auto nonce = GetFinalNonce(chain_id, from, network_nonce); std::move(callback).Run(nonce.has_value(), nonce.has_value() ? *nonce : 0); } diff --git a/components/brave_wallet/browser/fil_nonce_tracker.h b/components/brave_wallet/browser/fil_nonce_tracker.h index 48fd38bc9de6..84a7dd0c093d 100644 --- a/components/brave_wallet/browser/fil_nonce_tracker.h +++ b/components/brave_wallet/browser/fil_nonce_tracker.h @@ -29,7 +29,8 @@ class FilNonceTracker : public NonceTracker { FilNonceTracker operator=(const FilNonceTracker&) = delete; // NonceTracker - void GetNextNonce(const std::string& from, + void GetNextNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback) override; uint256_t GetHighestLocallyConfirmed( const std::vector>& metas) override; @@ -37,7 +38,8 @@ class FilNonceTracker : public NonceTracker { const std::vector>& metas, uint256_t start) override; - void OnGetNetworkNonce(const std::string& from, + void OnGetNetworkNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback, uint256_t network_nonce, mojom::FilecoinProviderError error, diff --git a/components/brave_wallet/browser/fil_tx_manager.cc b/components/brave_wallet/browser/fil_tx_manager.cc index 940e8672c117..8118da046926 100644 --- a/components/brave_wallet/browser/fil_tx_manager.cc +++ b/components/brave_wallet/browser/fil_tx_manager.cc @@ -31,7 +31,7 @@ FilTxManager::FilTxManager(TxService* tx_service, JsonRpcService* json_rpc_service, KeyringService* keyring_service, PrefService* prefs) - : TxManager(std::make_unique(prefs, json_rpc_service), + : TxManager(std::make_unique(prefs), std::make_unique(json_rpc_service), tx_service, json_rpc_service, @@ -46,7 +46,8 @@ FilTxManager::~FilTxManager() { GetFilBlockTracker()->RemoveObserver(this); } -void FilTxManager::GetEstimatedGas(const std::string& from, +void FilTxManager::GetEstimatedGas(const std::string& chain_id, + const std::string& from, const absl::optional& origin, const absl::optional& group_id, std::unique_ptr tx, @@ -59,13 +60,15 @@ void FilTxManager::GetEstimatedGas(const std::string& from, const std::string max_fee = tx->max_fee(); auto to = tx->to().EncodeAsString(); json_rpc_service_->GetFilEstimateGas( - from, to, gas_premium, gas_fee_cap, gas_limit, nonce, max_fee, value, + chain_id, from, to, gas_premium, gas_fee_cap, gas_limit, nonce, max_fee, + value, base::BindOnce(&FilTxManager::ContinueAddUnapprovedTransaction, - weak_factory_.GetWeakPtr(), from, origin, group_id, - std::move(tx), std::move(callback))); + weak_factory_.GetWeakPtr(), chain_id, from, origin, + group_id, std::move(tx), std::move(callback))); } void FilTxManager::ContinueAddUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -92,13 +95,14 @@ void FilTxManager::ContinueAddUnapprovedTransaction( meta.set_group_id(group_id); meta.set_created_time(base::Time::Now()); meta.set_status(mojom::TransactionStatus::Unapproved); - meta.set_chain_id(GetCurrentChainId(prefs_, mojom::CoinType::FIL)); + meta.set_chain_id(chain_id); tx_state_manager_->AddOrUpdateTx(meta); std::move(callback).Run(true, meta.id(), ""); } void FilTxManager::AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, @@ -131,20 +135,21 @@ void FilTxManager::AddUnapprovedTransaction( const std::string gas_premium = tx->gas_premium(); auto gas_limit = tx->gas_limit(); if (!gas_limit || gas_fee_cap.empty() || gas_premium.empty()) { - GetEstimatedGas(from, origin, group_id, std::move(tx_ptr), + GetEstimatedGas(chain_id, from, origin, group_id, std::move(tx_ptr), std::move(callback)); } else { ContinueAddUnapprovedTransaction( - from, origin, group_id, std::move(tx_ptr), std::move(callback), - gas_premium, gas_fee_cap, gas_limit, + chain_id, from, origin, group_id, std::move(tx_ptr), + std::move(callback), gas_premium, gas_fee_cap, gas_limit, mojom::FilecoinProviderError::kSuccess, ""); } } -void FilTxManager::ApproveTransaction(const std::string& tx_meta_id, +void FilTxManager::ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback) { std::unique_ptr meta = - GetFilTxStateManager()->GetFilTx(tx_meta_id); + GetFilTxStateManager()->GetFilTx(chain_id, tx_meta_id); if (!meta) { DCHECK(false) << "Transaction should be found"; std::move(callback).Run( @@ -157,9 +162,10 @@ void FilTxManager::ApproveTransaction(const std::string& tx_meta_id, if (!meta->tx()->nonce()) { auto from = meta->from(); nonce_tracker_->GetNextNonce( - from, base::BindOnce(&FilTxManager::OnGetNextNonce, - weak_factory_.GetWeakPtr(), std::move(meta), - std::move(callback))); + chain_id, from, + base::BindOnce(&FilTxManager::OnGetNextNonce, + weak_factory_.GetWeakPtr(), std::move(meta), + std::move(callback))); } else { uint64_t nonce = meta->tx()->nonce().value(); OnGetNextNonce(std::move(meta), std::move(callback), true, nonce); @@ -201,19 +207,20 @@ void FilTxManager::OnGetNextNonce(std::unique_ptr meta, return; } json_rpc_service_->SendFilecoinTransaction( - signed_tx.value(), + meta->chain_id(), signed_tx.value(), base::BindOnce(&FilTxManager::OnSendFilecoinTransaction, - weak_factory_.GetWeakPtr(), meta->id(), + weak_factory_.GetWeakPtr(), meta->chain_id(), meta->id(), std::move(callback))); } void FilTxManager::OnSendFilecoinTransaction( + const std::string& chain_id, const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_cid, mojom::FilecoinProviderError error, const std::string& error_message) { - std::unique_ptr meta = tx_state_manager_->GetTx(tx_meta_id); + std::unique_ptr meta = tx_state_manager_->GetTx(chain_id, tx_meta_id); if (!meta) { NOTREACHED() << "Transaction should be found"; std::move(callback).Run( @@ -237,7 +244,7 @@ void FilTxManager::OnSendFilecoinTransaction( tx_state_manager_->AddOrUpdateTx(*meta); if (success) { - UpdatePendingTransactions(); + UpdatePendingTransactions(chain_id); } std::move(callback).Run( error_message.empty(), @@ -246,10 +253,12 @@ void FilTxManager::OnSendFilecoinTransaction( } void FilTxManager::GetAllTransactionInfo( + const absl::optional& chain_id, const absl::optional& from, GetAllTransactionInfoCallback callback) { if (!from) { - TxManager::GetAllTransactionInfo(absl::nullopt, std::move(callback)); + TxManager::GetAllTransactionInfo(chain_id, absl::nullopt, + std::move(callback)); return; } auto from_address = FilAddress::FromAddress(from.value()); @@ -257,27 +266,30 @@ void FilTxManager::GetAllTransactionInfo( std::move(callback).Run(std::vector()); return; } - TxManager::GetAllTransactionInfo(from_address.EncodeAsString(), + TxManager::GetAllTransactionInfo(chain_id, from_address.EncodeAsString(), std::move(callback)); } void FilTxManager::SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) { NOTIMPLEMENTED(); } -void FilTxManager::RetryTransaction(const std::string& tx_meta_id, +void FilTxManager::RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) { NOTIMPLEMENTED(); } void FilTxManager::GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) { std::unique_ptr meta = - GetFilTxStateManager()->GetFilTx(tx_meta_id); + GetFilTxStateManager()->GetFilTx(chain_id, tx_meta_id); if (!meta || !meta->tx()) { VLOG(1) << __FUNCTION__ << "No transaction found with id:" << tx_meta_id; std::move(callback).Run(nullptr); @@ -286,9 +298,10 @@ void FilTxManager::GetTransactionMessageToSign( if (!meta->tx()->nonce()) { auto from = meta->from(); nonce_tracker_->GetNextNonce( - from, base::BindOnce(&FilTxManager::OnGetNextNonceForHardware, - weak_factory_.GetWeakPtr(), std::move(meta), - std::move(callback))); + chain_id, from, + base::BindOnce(&FilTxManager::OnGetNextNonceForHardware, + weak_factory_.GetWeakPtr(), std::move(meta), + std::move(callback))); } else { uint64_t nonce = meta->tx()->nonce().value(); OnGetNextNonceForHardware(std::move(meta), std::move(callback), true, @@ -296,6 +309,10 @@ void FilTxManager::GetTransactionMessageToSign( } } +mojom::CoinType FilTxManager::GetCoinType() const { + return mojom::CoinType::FIL; +} + void FilTxManager::OnGetNextNonceForHardware( std::unique_ptr meta, GetTransactionMessageToSignCallback callback, @@ -328,17 +345,18 @@ void FilTxManager::Reset() { } std::unique_ptr FilTxManager::GetTxForTesting( + const std::string& chain_id, const std::string& tx_meta_id) { - return GetFilTxStateManager()->GetFilTx(tx_meta_id); + return GetFilTxStateManager()->GetFilTx(chain_id, tx_meta_id); } FilTxStateManager* FilTxManager::GetFilTxStateManager() { return static_cast(tx_state_manager_.get()); } -void FilTxManager::UpdatePendingTransactions() { +void FilTxManager::UpdatePendingTransactions(const std::string& chain_id) { auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); + chain_id, mojom::TransactionStatus::Submitted, absl::nullopt); for (const auto& pending_transaction : pending_transactions) { auto cid = pending_transaction->tx_hash(); uint64_t seconds = @@ -350,15 +368,21 @@ void FilTxManager::UpdatePendingTransactions() { // the limit. In case of zero we are looking at last message. uint64_t limit_epochs = seconds == 0 ? 1 : seconds; json_rpc_service_->GetFilStateSearchMsgLimited( - cid, limit_epochs, + chain_id, cid, limit_epochs, base::BindOnce(&FilTxManager::OnGetFilStateSearchMsgLimited, - weak_factory_.GetWeakPtr(), pending_transaction->id())); + weak_factory_.GetWeakPtr(), chain_id, + pending_transaction->id())); + } + if (pending_transactions.empty()) { + known_no_pending_tx_.emplace(chain_id); + } else { + known_no_pending_tx_.erase(chain_id); } - known_no_pending_tx_ = pending_transactions.empty(); - CheckIfBlockTrackerShouldRun(); + CheckIfBlockTrackerShouldRun(chain_id); } void FilTxManager::OnGetFilStateSearchMsgLimited( + const std::string& chain_id, const std::string& tx_meta_id, int64_t exit_code, mojom::FilecoinProviderError error, @@ -367,7 +391,7 @@ void FilTxManager::OnGetFilStateSearchMsgLimited( return; } std::unique_ptr meta = - GetFilTxStateManager()->GetFilTx(tx_meta_id); + GetFilTxStateManager()->GetFilTx(chain_id, tx_meta_id); if (!meta) { return; } @@ -381,8 +405,9 @@ void FilTxManager::OnGetFilStateSearchMsgLimited( tx_state_manager_->AddOrUpdateTx(*meta); } -void FilTxManager::OnLatestHeightUpdated(uint64_t latest_height) { - UpdatePendingTransactions(); +void FilTxManager::OnLatestHeightUpdated(const std::string& chain_id, + uint64_t latest_height) { + UpdatePendingTransactions(chain_id); } FilBlockTracker* FilTxManager::GetFilBlockTracker() { @@ -390,11 +415,12 @@ FilBlockTracker* FilTxManager::GetFilBlockTracker() { } void FilTxManager::ProcessFilHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& signed_tx, ProcessFilHardwareSignatureCallback callback) { std::unique_ptr meta = - GetFilTxStateManager()->GetFilTx(tx_meta_id); + GetFilTxStateManager()->GetFilTx(chain_id, tx_meta_id); if (!meta) { std::move(callback).Run( false, @@ -408,9 +434,10 @@ void FilTxManager::ProcessFilHardwareSignature( tx_state_manager_->AddOrUpdateTx(*meta); json_rpc_service_->SendFilecoinTransaction( - signed_tx, base::BindOnce(&FilTxManager::OnSendFilecoinTransaction, - weak_factory_.GetWeakPtr(), meta->id(), - std::move(callback))); + chain_id, signed_tx, + base::BindOnce(&FilTxManager::OnSendFilecoinTransaction, + weak_factory_.GetWeakPtr(), chain_id, meta->id(), + std::move(callback))); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/fil_tx_manager.h b/components/brave_wallet/browser/fil_tx_manager.h index 4e87170e4135..19153104a65e 100644 --- a/components/brave_wallet/browser/fil_tx_manager.h +++ b/components/brave_wallet/browser/fil_tx_manager.h @@ -39,43 +39,54 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer { using ProcessFilHardwareSignatureCallback = mojom::FilTxManagerProxy::ProcessFilHardwareSignatureCallback; - void AddUnapprovedTransaction(mojom::TxDataUnionPtr tx_data_union, + void AddUnapprovedTransaction(const std::string& chain_id, + mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, const absl::optional& group_id, AddUnapprovedTransactionCallback) override; - void ApproveTransaction(const std::string& tx_meta_id, + void ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback) override; - void GetAllTransactionInfo(const absl::optional& from, + void GetAllTransactionInfo(const absl::optional& chain_id, + const absl::optional& from, GetAllTransactionInfoCallback) override; void GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) override; void SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) override; - void RetryTransaction(const std::string& tx_meta_id, + void RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) override; void Reset() override; void ProcessFilHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& signed_message, ProcessFilHardwareSignatureCallback callback); - void GetEstimatedGas(const std::string& from, + void GetEstimatedGas(const std::string& chain_id, + const std::string& from, const absl::optional& origin, const absl::optional& group_id, std::unique_ptr tx, AddUnapprovedTransactionCallback callback); - std::unique_ptr GetTxForTesting(const std::string& tx_meta_id); + std::unique_ptr GetTxForTesting(const std::string& chain_id, + const std::string& tx_meta_id); private: friend class FilTxManagerUnitTest; + mojom::CoinType GetCoinType() const override; + void OnGetNextNonce(std::unique_ptr meta, ApproveTransactionCallback callback, bool success, @@ -84,12 +95,14 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer { GetTransactionMessageToSignCallback callback, bool success, uint256_t nonce); - void OnSendFilecoinTransaction(const std::string& tx_meta_id, + void OnSendFilecoinTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_hash, mojom::FilecoinProviderError error, const std::string& error_message); void ContinueAddUnapprovedTransaction( + const std::string& chain_id, const std::string& from, const absl::optional& origin, const absl::optional& group_id, @@ -101,7 +114,8 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer { mojom::FilecoinProviderError error, const std::string& error_message); - void OnGetFilStateSearchMsgLimited(const std::string& tx_meta_id, + void OnGetFilStateSearchMsgLimited(const std::string& chain_id, + const std::string& tx_meta_id, int64_t exit_code, mojom::FilecoinProviderError error, const std::string& error_message); @@ -109,10 +123,11 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer { FilBlockTracker* GetFilBlockTracker(); // FilBlockTracker::Observer - void OnLatestHeightUpdated(uint64_t latest_height) override; + void OnLatestHeightUpdated(const std::string& chain_id, + uint64_t latest_height) override; // TxManager - void UpdatePendingTransactions() override; + void UpdatePendingTransactions(const std::string& chain_id) override; std::unique_ptr nonce_tracker_; base::WeakPtrFactory weak_factory_{this}; diff --git a/components/brave_wallet/browser/fil_tx_state_manager.cc b/components/brave_wallet/browser/fil_tx_state_manager.cc index 06baf8b9fcb8..ebef3e97c17d 100644 --- a/components/brave_wallet/browser/fil_tx_state_manager.cc +++ b/components/brave_wallet/browser/fil_tx_state_manager.cc @@ -9,31 +9,39 @@ #include "base/strings/strcat.h" #include "base/values.h" +#include "brave/components/brave_wallet/browser/brave_wallet_constants.h" #include "brave/components/brave_wallet/browser/brave_wallet_utils.h" #include "brave/components/brave_wallet/browser/fil_tx_meta.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/tx_meta.h" #include "brave/components/brave_wallet/common/fil_address.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace brave_wallet { -FilTxStateManager::FilTxStateManager(PrefService* prefs, - JsonRpcService* json_rpc_service) - : TxStateManager(prefs, json_rpc_service) {} +FilTxStateManager::FilTxStateManager(PrefService* prefs) + : TxStateManager(prefs) {} FilTxStateManager::~FilTxStateManager() = default; -std::unique_ptr FilTxStateManager::GetFilTx(const std::string& id) { +std::unique_ptr FilTxStateManager::GetFilTx( + const std::string& chain_id, + const std::string& id) { return std::unique_ptr{ - static_cast(TxStateManager::GetTx(id).release())}; + static_cast(TxStateManager::GetTx(chain_id, id).release())}; } -std::string FilTxStateManager::GetTxPrefPathPrefix() { - return base::StrCat( - {kFilecoinPrefKey, ".", - GetNetworkId(prefs_, mojom::CoinType::FIL, - json_rpc_service_->GetChainId(mojom::CoinType::FIL))}); +std::string FilTxStateManager::GetTxPrefPathPrefix( + const absl::optional& chain_id) { + if (chain_id.has_value()) { + return base::StrCat( + {kFilecoinPrefKey, ".", + GetNetworkId(prefs_, mojom::CoinType::FIL, *chain_id)}); + } + return kFilecoinPrefKey; +} + +mojom::CoinType FilTxStateManager::GetCoinType() const { + return mojom::CoinType::FIL; } std::unique_ptr FilTxStateManager::ValueToFilTxMeta( @@ -46,14 +54,17 @@ std::unique_ptr FilTxStateManager::ValueToTxMeta( const base::Value::Dict& value) { std::unique_ptr meta = std::make_unique(); - if (!TxStateManager::ValueToTxMeta(value, meta.get())) + if (!TxStateManager::ValueToTxMeta(value, meta.get())) { return nullptr; + } const base::Value::Dict* tx = value.FindDict("tx"); - if (!tx) + if (!tx) { return nullptr; + } absl::optional tx_from_value = FilTransaction::FromValue(*tx); - if (!tx_from_value) + if (!tx_from_value) { return nullptr; + } meta->set_tx(std::make_unique(*tx_from_value)); return meta; } diff --git a/components/brave_wallet/browser/fil_tx_state_manager.h b/components/brave_wallet/browser/fil_tx_state_manager.h index d4d340fabe54..58770883cfa2 100644 --- a/components/brave_wallet/browser/fil_tx_state_manager.h +++ b/components/brave_wallet/browser/fil_tx_state_manager.h @@ -23,24 +23,27 @@ namespace brave_wallet { class TxMeta; class FilTxMeta; -class JsonRpcService; class FilTxStateManager : public TxStateManager { public: - FilTxStateManager(PrefService* prefs, JsonRpcService* json_rpc_service); + explicit FilTxStateManager(PrefService* prefs); ~FilTxStateManager() override; FilTxStateManager(const FilTxStateManager&) = delete; FilTxStateManager operator=(const FilTxStateManager&) = delete; - std::unique_ptr GetFilTx(const std::string& id); + std::unique_ptr GetFilTx(const std::string& chain_id, + const std::string& id); std::unique_ptr ValueToFilTxMeta(const base::Value::Dict& value); private: FRIEND_TEST_ALL_PREFIXES(FilTxStateManagerUnitTest, GetTxPrefPathPrefix); + mojom::CoinType GetCoinType() const override; + std::unique_ptr ValueToTxMeta( const base::Value::Dict& value) override; - std::string GetTxPrefPathPrefix() override; + std::string GetTxPrefPathPrefix( + const absl::optional& chain_id) override; }; } // namespace brave_wallet diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index f46dd75caf51..8472fafff119 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -366,13 +366,15 @@ void JsonRpcService::RequestInternal( std::move(conversion_callback)); } -void JsonRpcService::Request(const std::string& json_payload, +void JsonRpcService::Request(const std::string& chain_id, + const std::string& json_payload, bool auto_retry_on_network_change, base::Value id, mojom::CoinType coin, RequestCallback callback) { RequestInternal( - json_payload, auto_retry_on_network_change, network_urls_[coin], + json_payload, auto_retry_on_network_change, + GetNetworkURL(prefs_, chain_id, coin), base::BindOnce(&JsonRpcService::OnRequestResult, base::Unretained(this), std::move(callback), std::move(id))); } @@ -607,7 +609,8 @@ void JsonRpcService::MaybeUpdateIsEip1559(const std::string& chain_id) { return; } - GetIsEip1559(base::BindOnce(&JsonRpcService::UpdateIsEip1559, + GetIsEip1559(chain_id, + base::BindOnce(&JsonRpcService::UpdateIsEip1559, weak_ptr_factory_.GetWeakPtr(), chain_id)); } @@ -731,12 +734,13 @@ void JsonRpcService::SetCustomNetworkForTesting(const std::string& chain_id, FireNetworkChanged(coin); } -void JsonRpcService::GetBlockNumber(GetBlockNumberCallback callback) { +void JsonRpcService::GetBlockNumber(const std::string& chain_id, + GetBlockNumberCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetBlockNumber, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_blockNumber(), true, - network_urls_[mojom::CoinType::ETH], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -806,7 +810,8 @@ void JsonRpcService::OnGetBlockNumber(GetBlockNumberCallback callback, std::move(callback).Run(block_number, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::GetFeeHistory(GetFeeHistoryCallback callback) { +void JsonRpcService::GetFeeHistory(const std::string& chain_id, + GetFeeHistoryCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetFeeHistory, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); @@ -814,7 +819,7 @@ void JsonRpcService::GetFeeHistory(GetFeeHistoryCallback callback) { RequestInternal(eth::eth_feeHistory("0x28", // blockCount = 40 kEthereumBlockTagLatest, std::vector{20, 50, 80}), - true, network_urls_[mojom::CoinType::ETH], + true, GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -921,10 +926,11 @@ void JsonRpcService::OnFilGetBalance(GetBalanceCallback callback, std::move(callback).Run(*balance, mojom::ProviderError::kSuccess, ""); } void JsonRpcService::GetFilStateSearchMsgLimited( + const std::string& chain_id, const std::string& cid, uint64_t period, GetFilStateSearchMsgLimitedCallback callback) { - auto network_url = network_urls_[mojom::CoinType::FIL]; + auto network_url = GetNetworkURL(prefs_, chain_id, mojom::CoinType::FIL); if (!network_url.is_valid()) { std::move(callback).Run( 0, mojom::FilecoinProviderError::kInternalError, @@ -941,8 +947,9 @@ void JsonRpcService::GetFilStateSearchMsgLimited( base::BindOnce(&ConvertInt64ToString, "/result/Receipt/ExitCode")); } -void JsonRpcService::GetFilBlockHeight(GetFilBlockHeightCallback callback) { - auto network_url = network_urls_[mojom::CoinType::FIL]; +void JsonRpcService::GetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback) { + auto network_url = GetNetworkURL(prefs_, chain_id, mojom::CoinType::FIL); if (!network_url.is_valid()) { std::move(callback).Run( 0, mojom::FilecoinProviderError::kInternalError, @@ -979,9 +986,10 @@ void JsonRpcService::OnGetFilBlockHeight(GetFilBlockHeightCallback callback, std::move(callback).Run(height, mojom::FilecoinProviderError::kSuccess, ""); } -void JsonRpcService::GetFilTransactionCount(const std::string& address, +void JsonRpcService::GetFilTransactionCount(const std::string& chain_id, + const std::string& address, GetFilTxCountCallback callback) { - auto network_url = network_urls_[mojom::CoinType::FIL]; + auto network_url = GetNetworkURL(prefs_, chain_id, mojom::CoinType::FIL); if (!network_url.is_valid()) { std::move(callback).Run( 0, mojom::FilecoinProviderError::kInternalError, @@ -997,9 +1005,10 @@ void JsonRpcService::GetFilTransactionCount(const std::string& address, base::BindOnce(&ConvertUint64ToString, "/result")); } -void JsonRpcService::GetEthTransactionCount(const std::string& address, +void JsonRpcService::GetEthTransactionCount(const std::string& chain_id, + const std::string& address, GetTxCountCallback callback) { - auto network_url = network_urls_[mojom::CoinType::ETH]; + auto network_url = GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH); if (!network_url.is_valid()) { std::move(callback).Run( 0, mojom::ProviderError::kInternalError, @@ -1061,13 +1070,14 @@ void JsonRpcService::OnEthGetTransactionCount( std::move(callback).Run(count, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::GetTransactionReceipt(const std::string& tx_hash, +void JsonRpcService::GetTransactionReceipt(const std::string& chain_id, + const std::string& tx_hash, GetTxReceiptCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetTransactionReceipt, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_getTransactionReceipt(tx_hash), true, - network_urls_[mojom::CoinType::ETH], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -1094,13 +1104,14 @@ void JsonRpcService::OnGetTransactionReceipt( std::move(callback).Run(receipt, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::SendRawTransaction(const std::string& signed_tx, +void JsonRpcService::SendRawTransaction(const std::string& chain_id, + const std::string& signed_tx, SendRawTxCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnSendRawTransaction, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_sendRawTransaction(signed_tx), true, - network_urls_[mojom::CoinType::ETH], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -1203,6 +1214,7 @@ void JsonRpcService::GetERC20TokenAllowance( const std::string& contract_address, const std::string& owner_address, const std::string& spender_address, + const std::string& chain_id, JsonRpcService::GetERC20TokenAllowanceCallback callback) { std::string data; if (!erc20::Allowance(owner_address, spender_address, &data)) { @@ -1217,7 +1229,7 @@ void JsonRpcService::GetERC20TokenAllowance( weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_call("", contract_address, "", "", "", data, kEthereumBlockTagLatest), - true, network_urls_[mojom::CoinType::ETH], + true, GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -1969,7 +1981,8 @@ GURL JsonRpcService::GetBlockTrackerUrlFromNetwork( return GURL(); } -void JsonRpcService::GetFilEstimateGas(const std::string& from_address, +void JsonRpcService::GetFilEstimateGas(const std::string& chain_id, + const std::string& from_address, const std::string& to_address, const std::string& gas_premium, const std::string& gas_fee_cap, @@ -1990,7 +2003,8 @@ void JsonRpcService::GetFilEstimateGas(const std::string& from_address, auto request = fil::getEstimateGas(from_address, to_address, gas_premium, gas_fee_cap, gas_limit, nonce, max_fee, value); - RequestInternal(request, true, network_urls_[mojom::CoinType::FIL], + RequestInternal(request, true, + GetNetworkURL(prefs_, chain_id, mojom::CoinType::FIL), std::move(internal_callback), base::BindOnce(&ConvertInt64ToString, "/result/GasLimit")); } @@ -2021,7 +2035,8 @@ void JsonRpcService::OnGetFilEstimateGas(GetFilEstimateGasCallback callback, mojom::FilecoinProviderError::kSuccess, ""); } -void JsonRpcService::GetEstimateGas(const std::string& from_address, +void JsonRpcService::GetEstimateGas(const std::string& chain_id, + const std::string& from_address, const std::string& to_address, const std::string& gas, const std::string& gas_price, @@ -2033,7 +2048,7 @@ void JsonRpcService::GetEstimateGas(const std::string& from_address, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_estimateGas(from_address, to_address, gas, gas_price, value, data), - true, network_urls_[mojom::CoinType::ETH], + true, GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -2059,12 +2074,13 @@ void JsonRpcService::OnGetEstimateGas(GetEstimateGasCallback callback, std::move(callback).Run(*result, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::GetGasPrice(GetGasPriceCallback callback) { +void JsonRpcService::GetGasPrice(const std::string& chain_id, + GetGasPriceCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetGasPrice, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_gasPrice(), true, - network_urls_[mojom::CoinType::ETH], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -2090,12 +2106,13 @@ void JsonRpcService::OnGetGasPrice(GetGasPriceCallback callback, std::move(callback).Run(*result, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::GetIsEip1559(GetIsEip1559Callback callback) { +void JsonRpcService::GetIsEip1559(const std::string& chain_id, + GetIsEip1559Callback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetIsEip1559, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_getBlockByNumber(kEthereumBlockTagLatest, false), - true, network_urls_[mojom::CoinType::ETH], + true, GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -2123,13 +2140,14 @@ void JsonRpcService::OnGetIsEip1559(GetIsEip1559Callback callback, mojom::ProviderError::kSuccess, ""); } -void JsonRpcService::GetBlockByNumber(const std::string& block_number, +void JsonRpcService::GetBlockByNumber(const std::string& chain_id, + const std::string& block_number, GetBlockByNumberCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetBlockByNumber, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(eth::eth_getBlockByNumber(block_number, false), true, - network_urls_[mojom::CoinType::ETH], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::ETH), std::move(internal_callback)); } @@ -2789,6 +2807,7 @@ void JsonRpcService::GetSolTokenMetadata(const std::string& chain_id, } void JsonRpcService::SendFilecoinTransaction( + const std::string& chain_id, const std::string& signed_tx, SendFilecoinTransactionCallback callback) { if (signed_tx.empty()) { @@ -2807,7 +2826,8 @@ void JsonRpcService::SendFilecoinTransaction( auto internal_callback = base::BindOnce(&JsonRpcService::OnSendFilecoinTransaction, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); - RequestInternal(request.value(), true, network_urls_[mojom::CoinType::FIL], + RequestInternal(request.value(), true, + GetNetworkURL(prefs_, chain_id, mojom::CoinType::FIL), std::move(internal_callback)); } @@ -2835,6 +2855,7 @@ void JsonRpcService::OnSendFilecoinTransaction( } void JsonRpcService::SendSolanaTransaction( + const std::string& chain_id, const std::string& signed_tx, absl::optional send_options, SendSolanaTransactionCallback callback) { @@ -2849,7 +2870,7 @@ void JsonRpcService::SendSolanaTransaction( base::BindOnce(&JsonRpcService::OnSendSolanaTransaction, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(solana::sendTransaction(signed_tx, std::move(send_options)), - true, network_urls_[mojom::CoinType::SOL], + true, GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL), std::move(internal_callback)); } @@ -2879,12 +2900,13 @@ void JsonRpcService::OnSendSolanaTransaction( } void JsonRpcService::GetSolanaLatestBlockhash( + const std::string& chain_id, GetSolanaLatestBlockhashCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetSolanaLatestBlockhash, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(solana::getLatestBlockhash(), true, - network_urls_[mojom::CoinType::SOL], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL), std::move(internal_callback), base::BindOnce(&ConvertUint64ToString, "/result/value/lastValidBlockHeight")); @@ -2917,6 +2939,7 @@ void JsonRpcService::OnGetSolanaLatestBlockhash( } void JsonRpcService::GetSolanaSignatureStatuses( + const std::string& chain_id, const std::vector& tx_signatures, GetSolanaSignatureStatusesCallback callback) { auto internal_callback = @@ -2924,7 +2947,8 @@ void JsonRpcService::GetSolanaSignatureStatuses( weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal( solana::getSignatureStatuses(tx_signatures), true, - network_urls_[mojom::CoinType::SOL], std::move(internal_callback), + GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL), + std::move(internal_callback), base::BindOnce(&ConvertMultiUint64InObjectArrayToString, "/result/value", "", std::vector({"slot", "confirmations"}))); } @@ -2957,8 +2981,8 @@ void JsonRpcService::OnGetSolanaSignatureStatuses( } void JsonRpcService::GetSolanaAccountInfo( - const std::string& pubkey, const std::string& chain_id, + const std::string& pubkey, GetSolanaAccountInfoCallback callback) { auto network_url = GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL); if (!network_url.is_valid()) { @@ -2971,18 +2995,12 @@ void JsonRpcService::GetSolanaAccountInfo( auto internal_callback = base::BindOnce(&JsonRpcService::OnGetSolanaAccountInfo, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + RequestInternal(solana::getAccountInfo(pubkey), true, network_url, std::move(internal_callback), solana::ConverterForGetAccountInfo()); } -void JsonRpcService::GetSolanaAccountInfo( - const std::string& pubkey, - GetSolanaAccountInfoCallback callback) { - JsonRpcService::GetSolanaAccountInfo(pubkey, chain_ids_[mojom::CoinType::SOL], - std::move(callback)); -} - void JsonRpcService::OnGetSolanaAccountInfo( GetSolanaAccountInfoCallback callback, APIRequestResult api_request_result) { @@ -3009,6 +3027,7 @@ void JsonRpcService::OnGetSolanaAccountInfo( } void JsonRpcService::GetSolanaFeeForMessage( + const std::string& chain_id, const std::string& message, GetSolanaFeeForMessageCallback callback) { if (message.empty() || !base::Base64Decode(message)) { @@ -3022,7 +3041,7 @@ void JsonRpcService::GetSolanaFeeForMessage( base::BindOnce(&JsonRpcService::OnGetSolanaFeeForMessage, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(solana::getFeeForMessage(message), true, - network_urls_[mojom::CoinType::SOL], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL), std::move(internal_callback), base::BindOnce(&ConvertUint64ToString, "/result/value")); } @@ -3051,12 +3070,13 @@ void JsonRpcService::OnGetSolanaFeeForMessage( } void JsonRpcService::GetSolanaBlockHeight( + const std::string& chain_id, GetSolanaBlockHeightCallback callback) { auto internal_callback = base::BindOnce(&JsonRpcService::OnGetSolanaBlockHeight, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); RequestInternal(solana::getBlockHeight(), true, - network_urls_[mojom::CoinType::SOL], + GetNetworkURL(prefs_, chain_id, mojom::CoinType::SOL), std::move(internal_callback), base::BindOnce(&ConvertUint64ToString, "/result")); } diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 8ede0df79895..397178be6d31 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -95,10 +95,13 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { base::Value rawlogs, mojom::ProviderError error, const std::string& error_message)>; - void GetBlockNumber(GetBlockNumberCallback callback); - void GetFeeHistory(GetFeeHistoryCallback callback); + void GetBlockNumber(const std::string& chain_id, + GetBlockNumberCallback callback); + void GetFeeHistory(const std::string& chain_id, + GetFeeHistoryCallback callback); - void Request(const std::string& json_payload, + void Request(const std::string& chain_id, + const std::string& json_payload, bool auto_retry_on_network_change, base::Value id, mojom::CoinType coin, @@ -120,12 +123,14 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { base::OnceCallback; - void GetFilBlockHeight(GetFilBlockHeightCallback callback); + void GetFilBlockHeight(const std::string& chain_id, + GetFilBlockHeightCallback callback); using GetFilStateSearchMsgLimitedCallback = base::OnceCallback; void GetFilStateSearchMsgLimited( + const std::string& chain_id, const std::string& cid, uint64_t period, GetFilStateSearchMsgLimitedCallback callback); @@ -138,29 +143,34 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { base::OnceCallback; - void GetEthTransactionCount(const std::string& address, + void GetEthTransactionCount(const std::string& chain_id, + const std::string& address, GetTxCountCallback callback); - void GetFilTransactionCount(const std::string& address, + void GetFilTransactionCount(const std::string& chain_id, + const std::string& address, GetFilTxCountCallback callback); using SendFilecoinTransactionCallback = base::OnceCallback; - void SendFilecoinTransaction(const std::string& signed_tx, + void SendFilecoinTransaction(const std::string& chain_id, + const std::string& signed_tx, SendFilecoinTransactionCallback callback); using GetTxReceiptCallback = base::OnceCallback; - void GetTransactionReceipt(const std::string& tx_hash, + void GetTransactionReceipt(const std::string& chain_id, + const std::string& tx_hash, GetTxReceiptCallback callback); using SendRawTxCallback = base::OnceCallback; - void SendRawTransaction(const std::string& signed_tx, + void SendRawTransaction(const std::string& chain_id, + const std::string& signed_tx, SendRawTxCallback callback); void GetERC20TokenBalance(const std::string& conract_address, @@ -170,6 +180,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { void GetERC20TokenAllowance(const std::string& contract_address, const std::string& owner_address, const std::string& spender_address, + const std::string& chain_id, GetERC20TokenAllowanceCallback callback) override; void GetERC20TokenBalances( @@ -266,7 +277,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { int64_t gas_limit, mojom::FilecoinProviderError error, const std::string& error_message)>; - void GetFilEstimateGas(const std::string& from_address, + void GetFilEstimateGas(const std::string& chain_id, + const std::string& from_address, const std::string& to_address, const std::string& gas_premium, const std::string& gas_fee_cap, @@ -280,7 +292,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { base::OnceCallback; - void GetEstimateGas(const std::string& from_address, + void GetEstimateGas(const std::string& chain_id, + const std::string& from_address, const std::string& to_address, const std::string& gas, const std::string& gas_price, @@ -292,20 +305,21 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { base::OnceCallback; - void GetGasPrice(GetGasPriceCallback callback); + void GetGasPrice(const std::string& chain_id, GetGasPriceCallback callback); using GetIsEip1559Callback = base::OnceCallback; - void GetIsEip1559(GetIsEip1559Callback callback); + void GetIsEip1559(const std::string& chain_id, GetIsEip1559Callback callback); using GetBlockByNumberCallback = base::OnceCallback; // block_number can be kEthereumBlockTagLatest - void GetBlockByNumber(const std::string& block_number, + void GetBlockByNumber(const std::string& chain_id, + const std::string& block_number, GetBlockByNumberCallback callback); void GetERC721OwnerOf(const std::string& contract, @@ -416,6 +430,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { mojom::SolanaProviderError error, const std::string& error_message)>; void SendSolanaTransaction( + const std::string& chain_id, const std::string& signed_tx, absl::optional send_options, SendSolanaTransactionCallback callback); @@ -424,34 +439,36 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { uint64_t last_valid_block_height, mojom::SolanaProviderError error, const std::string& error_message)>; - void GetSolanaLatestBlockhash(GetSolanaLatestBlockhashCallback callback); + void GetSolanaLatestBlockhash(const std::string& chain_id, + GetSolanaLatestBlockhashCallback callback); using GetSolanaSignatureStatusesCallback = base::OnceCallback>& signature_statuses, mojom::SolanaProviderError error, const std::string& error_message)>; - void GetSolanaSignatureStatuses(const std::vector& tx_signatures, + void GetSolanaSignatureStatuses(const std::string& chain_id, + const std::vector& tx_signatures, GetSolanaSignatureStatusesCallback callback); using GetSolanaAccountInfoCallback = base::OnceCallback account_info, mojom::SolanaProviderError error, const std::string& error_message)>; - void GetSolanaAccountInfo(const std::string& pubkey, - const std::string& chain_id, - GetSolanaAccountInfoCallback callback); - void GetSolanaAccountInfo(const std::string& pubkey, + void GetSolanaAccountInfo(const std::string& chain_id, + const std::string& pubkey, GetSolanaAccountInfoCallback callback); using GetSolanaFeeForMessageCallback = base::OnceCallback; - void GetSolanaFeeForMessage(const std::string& message, // base64 encoded + void GetSolanaFeeForMessage(const std::string& chain_id, + const std::string& message, // base64 encoded GetSolanaFeeForMessageCallback callback); using GetSolanaBlockHeightCallback = base::OnceCallback; - void GetSolanaBlockHeight(GetSolanaBlockHeightCallback callback); + void GetSolanaBlockHeight(const std::string& chain_id, + GetSolanaBlockHeightCallback callback); using GetSolanaTokenAccountsByOwnerCallback = base::OnceCallback& token_accounts, @@ -620,6 +637,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { scoped_refptr url_loader_factory_; std::unique_ptr api_request_helper_; std::unique_ptr api_request_helper_ens_offchain_; + // TODO(darkdh): base::flat_map> + // and replace all GetNetworkURL usages base::flat_map network_urls_; // base::flat_map chain_ids_; diff --git a/components/brave_wallet/browser/keyring_service.cc b/components/brave_wallet/browser/keyring_service.cc index 6afa6e0f48e5..d541f1cc469c 100644 --- a/components/brave_wallet/browser/keyring_service.cc +++ b/components/brave_wallet/browser/keyring_service.cc @@ -1383,6 +1383,7 @@ void KeyringService::AddDiscoveryAccountsForKeyring( return; } json_rpc_service_->GetEthTransactionCount( + mojom::kMainnetChainId, keyring->GetDiscoveryAddress(discovery_account_index), base::BindOnce(&KeyringService::OnGetTransactionCount, discovery_weak_factory_.GetWeakPtr(), @@ -1602,7 +1603,7 @@ absl::optional KeyringService::SignTransactionByFilecoinKeyring( return absl::nullopt; } - std::string keyring_id = GetFilecoinKeyringId(tx->from().network()); + const std::string& keyring_id = GetFilecoinKeyringId(tx->from().network()); auto* keyring = GetHDKeyringById(keyring_id); if (!keyring) { return absl::nullopt; diff --git a/components/brave_wallet/browser/nft_metadata_fetcher.cc b/components/brave_wallet/browser/nft_metadata_fetcher.cc index 12d2c5613fd5..a4937bc100f9 100644 --- a/components/brave_wallet/browser/nft_metadata_fetcher.cc +++ b/components/brave_wallet/browser/nft_metadata_fetcher.cc @@ -291,7 +291,7 @@ void NftMetadataFetcher::GetSolTokenMetadata( base::BindOnce(&NftMetadataFetcher::OnGetSolanaAccountInfoTokenMetadata, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); json_rpc_service_->GetSolanaAccountInfo( - *associated_metadata_account, chain_id, std::move(internal_callback)); + chain_id, *associated_metadata_account, std::move(internal_callback)); } void NftMetadataFetcher::OnGetSolanaAccountInfoTokenMetadata( diff --git a/components/brave_wallet/browser/nonce_tracker.cc b/components/brave_wallet/browser/nonce_tracker.cc index b41f990d73d2..c55f9e297cc3 100644 --- a/components/brave_wallet/browser/nonce_tracker.cc +++ b/components/brave_wallet/browser/nonce_tracker.cc @@ -22,20 +22,22 @@ NonceTracker::NonceTracker(TxStateManager* tx_state_manager, NonceTracker::~NonceTracker() = default; -absl::optional NonceTracker::GetFinalNonce(const std::string& from, - uint256_t network_nonce) { +absl::optional NonceTracker::GetFinalNonce( + const std::string& chain_id, + const std::string& from, + uint256_t network_nonce) { if (!nonce_lock_.Try()) { return absl::nullopt; } auto confirmed_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Confirmed, from); + chain_id, mojom::TransactionStatus::Confirmed, from); uint256_t local_highest = GetHighestLocallyConfirmed(confirmed_transactions); uint256_t highest_confirmed = std::max(network_nonce, local_highest); auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, from); + chain_id, mojom::TransactionStatus::Submitted, from); uint256_t highest_continuous_from = GetHighestContinuousFrom(pending_transactions, highest_confirmed); diff --git a/components/brave_wallet/browser/nonce_tracker.h b/components/brave_wallet/browser/nonce_tracker.h index e61afa4c6ae4..3ca6085017ab 100644 --- a/components/brave_wallet/browser/nonce_tracker.h +++ b/components/brave_wallet/browser/nonce_tracker.h @@ -31,7 +31,8 @@ class NonceTracker { using GetNextNonceCallback = base::OnceCallback; - virtual void GetNextNonce(const std::string& from, + virtual void GetNextNonce(const std::string& chain_id, + const std::string& from, GetNextNonceCallback callback) = 0; virtual uint256_t GetHighestContinuousFrom( const std::vector>& metas, @@ -42,7 +43,8 @@ class NonceTracker { base::Lock* GetLock() { return &nonce_lock_; } protected: - absl::optional GetFinalNonce(const std::string& from, + absl::optional GetFinalNonce(const std::string& chain_id, + const std::string& from, uint256_t result); raw_ptr json_rpc_service_ = nullptr; diff --git a/components/brave_wallet/browser/solana_block_tracker.cc b/components/brave_wallet/browser/solana_block_tracker.cc index 9257afa568d1..bcbfda83f8e4 100644 --- a/components/brave_wallet/browser/solana_block_tracker.cc +++ b/components/brave_wallet/browser/solana_block_tracker.cc @@ -5,8 +5,10 @@ #include "brave/components/brave_wallet/browser/solana_block_tracker.h" +#include #include +#include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" @@ -26,32 +28,40 @@ SolanaBlockTracker::SolanaBlockTracker(JsonRpcService* json_rpc_service) SolanaBlockTracker::~SolanaBlockTracker() = default; -void SolanaBlockTracker::Start(base::TimeDelta interval) { - timer_.Start(FROM_HERE, interval, - base::BindRepeating(&SolanaBlockTracker::GetLatestBlockhash, - weak_ptr_factory_.GetWeakPtr(), - base::NullCallback(), false)); -} - -void SolanaBlockTracker::Stop() { - BlockTracker::Stop(); +void SolanaBlockTracker::Start(const std::string& chain_id, + base::TimeDelta interval) { + if (!base::Contains(timers_, chain_id)) { + timers_[chain_id] = std::make_unique(); + } + timers_[chain_id]->Start( + FROM_HERE, interval, + base::BindRepeating(&SolanaBlockTracker::GetLatestBlockhash, + weak_ptr_factory_.GetWeakPtr(), chain_id, + base::NullCallback(), false)); } -void SolanaBlockTracker::GetLatestBlockhash(GetLatestBlockhashCallback callback, +void SolanaBlockTracker::GetLatestBlockhash(const std::string& chain_id, + GetLatestBlockhashCallback callback, bool try_cached_value) { - if (try_cached_value && !latest_blockhash_.empty() && - latest_blockhash_expired_time_ > base::Time::Now()) { - std::move(callback).Run(latest_blockhash_, last_valid_block_height_, + if (try_cached_value && base::Contains(latest_blockhash_map_, chain_id) && + !latest_blockhash_map_[chain_id].empty() && + base::Contains(latest_blockhash_expired_time_map_, chain_id) && + latest_blockhash_expired_time_map_[chain_id] > base::Time::Now() && + base::Contains(last_valid_block_height_map_, chain_id)) { + std::move(callback).Run(latest_blockhash_map_[chain_id], + last_valid_block_height_map_[chain_id], mojom::SolanaProviderError::kSuccess, ""); return; } json_rpc_service_->GetSolanaLatestBlockhash( - base::BindOnce(&SolanaBlockTracker::OnGetLatestBlockhash, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + chain_id, base::BindOnce(&SolanaBlockTracker::OnGetLatestBlockhash, + weak_ptr_factory_.GetWeakPtr(), chain_id, + std::move(callback))); } void SolanaBlockTracker::OnGetLatestBlockhash( + const std::string& chain_id, GetLatestBlockhashCallback callback, const std::string& latest_blockhash, uint64_t last_valid_block_height, @@ -67,14 +77,17 @@ void SolanaBlockTracker::OnGetLatestBlockhash( return; } - if (latest_blockhash_ == latest_blockhash) + if (base::Contains(latest_blockhash_map_, chain_id) && + latest_blockhash_map_[chain_id] == latest_blockhash) { return; + } - latest_blockhash_ = latest_blockhash; - last_valid_block_height_ = last_valid_block_height; - latest_blockhash_expired_time_ = base::Time::Now() + kExpiredTimeDelta; + latest_blockhash_map_[chain_id] = latest_blockhash; + last_valid_block_height_map_[chain_id] = last_valid_block_height; + latest_blockhash_expired_time_map_[chain_id] = + base::Time::Now() + kExpiredTimeDelta; for (auto& observer : observers_) - observer.OnLatestBlockhashUpdated(latest_blockhash, + observer.OnLatestBlockhashUpdated(chain_id, latest_blockhash, last_valid_block_height); } diff --git a/components/brave_wallet/browser/solana_block_tracker.h b/components/brave_wallet/browser/solana_block_tracker.h index 0b73abf1ab08..aedbdc6a89a7 100644 --- a/components/brave_wallet/browser/solana_block_tracker.h +++ b/components/brave_wallet/browser/solana_block_tracker.h @@ -6,6 +6,7 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_SOLANA_BLOCK_TRACKER_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_SOLANA_BLOCK_TRACKER_H_ +#include #include #include "base/memory/weak_ptr.h" @@ -27,7 +28,8 @@ class SolanaBlockTracker : public BlockTracker { class Observer : public base::CheckedObserver { public: - virtual void OnLatestBlockhashUpdated(const std::string& latest_blockhash, + virtual void OnLatestBlockhashUpdated(const std::string& chain_id, + const std::string& latest_blockhash, uint64_t last_valid_block_height) = 0; }; @@ -35,30 +37,30 @@ class SolanaBlockTracker : public BlockTracker { void RemoveObserver(Observer* observer); // If timer is already running, it will be replaced with new interval - void Start(base::TimeDelta interval) override; - void Stop() override; - - std::string latest_blockhash() const { return latest_blockhash_; } - uint64_t last_valid_block_height() const { return last_valid_block_height_; } + void Start(const std::string& chain_id, base::TimeDelta interval) override; using GetLatestBlockhashCallback = base::OnceCallback; - void GetLatestBlockhash(GetLatestBlockhashCallback callback, + void GetLatestBlockhash(const std::string& chain_id, + GetLatestBlockhashCallback callback, bool try_cached_value); private: - void OnGetLatestBlockhash(GetLatestBlockhashCallback callback, + void OnGetLatestBlockhash(const std::string& chain_id, + GetLatestBlockhashCallback callback, const std::string& latest_blockhash, uint64_t last_valid_block_height, mojom::SolanaProviderError error, const std::string& error_message); - - std::string latest_blockhash_; - uint64_t last_valid_block_height_ = 0; - base::Time latest_blockhash_expired_time_; + // + std::map latest_blockhash_map_; + // + std::map last_valid_block_height_map_; + // + std::map latest_blockhash_expired_time_map_; base::ObserverList observers_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/components/brave_wallet/browser/solana_tx_manager.cc b/components/brave_wallet/browser/solana_tx_manager.cc index 09a8aa84dfc0..8417d3f1d1eb 100644 --- a/components/brave_wallet/browser/solana_tx_manager.cc +++ b/components/brave_wallet/browser/solana_tx_manager.cc @@ -32,7 +32,7 @@ SolanaTxManager::SolanaTxManager(TxService* tx_service, JsonRpcService* json_rpc_service, KeyringService* keyring_service, PrefService* prefs) - : TxManager(std::make_unique(prefs, json_rpc_service), + : TxManager(std::make_unique(prefs), std::make_unique(json_rpc_service), tx_service, json_rpc_service, @@ -47,6 +47,7 @@ SolanaTxManager::~SolanaTxManager() { } void SolanaTxManager::AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, @@ -78,15 +79,16 @@ void SolanaTxManager::AddUnapprovedTransaction( meta.set_group_id(group_id); meta.set_created_time(base::Time::Now()); meta.set_status(mojom::TransactionStatus::Unapproved); - meta.set_chain_id(GetCurrentChainId(prefs_, mojom::CoinType::SOL)); + meta.set_chain_id(chain_id); tx_state_manager_->AddOrUpdateTx(meta); std::move(callback).Run(true, meta.id(), ""); } -void SolanaTxManager::ApproveTransaction(const std::string& tx_meta_id, +void SolanaTxManager::ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback) { std::unique_ptr meta = - GetSolanaTxStateManager()->GetSolanaTx(tx_meta_id); + GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_id); if (!meta) { DCHECK(false) << "Transaction should be found"; std::move(callback).Run( @@ -100,6 +102,7 @@ void SolanaTxManager::ApproveTransaction(const std::string& tx_meta_id, const std::string blockhash = meta->tx()->message()->recent_blockhash(); if (blockhash.empty()) { GetSolanaBlockTracker()->GetLatestBlockhash( + chain_id, base::BindOnce(&SolanaTxManager::OnGetLatestBlockhash, weak_ptr_factory_.GetWeakPtr(), std::move(meta), std::move(callback)), @@ -129,11 +132,11 @@ void SolanaTxManager::OnGetLatestBlockhash(std::unique_ptr meta, tx_state_manager_->AddOrUpdateTx(*meta); json_rpc_service_->SendSolanaTransaction( - meta->tx()->GetSignedTransaction(keyring_service_), + meta->chain_id(), meta->tx()->GetSignedTransaction(keyring_service_), meta->tx()->send_options(), base::BindOnce(&SolanaTxManager::OnSendSolanaTransaction, - weak_ptr_factory_.GetWeakPtr(), meta->id(), - std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), meta->chain_id(), + meta->id(), std::move(callback))); } void SolanaTxManager::OnGetLatestBlockhashHardware( @@ -164,12 +167,13 @@ void SolanaTxManager::OnGetLatestBlockhashHardware( } void SolanaTxManager::OnSendSolanaTransaction( + const std::string& chain_id, const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_hash, mojom::SolanaProviderError error, const std::string& error_message) { - std::unique_ptr meta = tx_state_manager_->GetTx(tx_meta_id); + std::unique_ptr meta = tx_state_manager_->GetTx(chain_id, tx_meta_id); if (!meta) { DCHECK(false) << "Transaction should be found"; std::move(callback).Run( @@ -193,7 +197,7 @@ void SolanaTxManager::OnSendSolanaTransaction( tx_state_manager_->AddOrUpdateTx(*meta); if (success) { - UpdatePendingTransactions(); + UpdatePendingTransactions(meta->chain_id()); } std::move(callback).Run( @@ -201,12 +205,14 @@ void SolanaTxManager::OnSendSolanaTransaction( mojom::ProviderErrorUnion::NewSolanaProviderError(error), error_message); } -void SolanaTxManager::UpdatePendingTransactions() { - json_rpc_service_->GetSolanaBlockHeight(base::BindOnce( - &SolanaTxManager::OnGetBlockHeight, weak_ptr_factory_.GetWeakPtr())); +void SolanaTxManager::UpdatePendingTransactions(const std::string& chain_id) { + json_rpc_service_->GetSolanaBlockHeight( + chain_id, base::BindOnce(&SolanaTxManager::OnGetBlockHeight, + weak_ptr_factory_.GetWeakPtr(), chain_id)); } -void SolanaTxManager::OnGetBlockHeight(uint64_t block_height, +void SolanaTxManager::OnGetBlockHeight(const std::string& chain_id, + uint64_t block_height, mojom::SolanaProviderError error, const std::string& error_message) { if (error != mojom::SolanaProviderError::kSuccess) { @@ -214,7 +220,7 @@ void SolanaTxManager::OnGetBlockHeight(uint64_t block_height, } auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); + chain_id, mojom::TransactionStatus::Submitted, absl::nullopt); std::vector tx_meta_ids; std::vector tx_signatures; for (const auto& pending_transaction : pending_transactions) { @@ -222,14 +228,20 @@ void SolanaTxManager::OnGetBlockHeight(uint64_t block_height, tx_signatures.push_back(pending_transaction->tx_hash()); } json_rpc_service_->GetSolanaSignatureStatuses( - tx_signatures, base::BindOnce(&SolanaTxManager::OnGetSignatureStatuses, - weak_ptr_factory_.GetWeakPtr(), tx_meta_ids, - block_height)); - known_no_pending_tx_ = pending_transactions.empty(); - CheckIfBlockTrackerShouldRun(); + chain_id, tx_signatures, + base::BindOnce(&SolanaTxManager::OnGetSignatureStatuses, + weak_ptr_factory_.GetWeakPtr(), chain_id, tx_meta_ids, + block_height)); + if (pending_transactions.empty()) { + known_no_pending_tx_.emplace(chain_id); + } else { + known_no_pending_tx_.erase(chain_id); + } + CheckIfBlockTrackerShouldRun(chain_id); } void SolanaTxManager::OnGetSignatureStatuses( + const std::string& chain_id, const std::vector& tx_meta_ids, uint64_t block_height, const std::vector>& @@ -246,7 +258,7 @@ void SolanaTxManager::OnGetSignatureStatuses( for (size_t i = 0; i < tx_meta_ids.size(); i++) { std::unique_ptr meta = - GetSolanaTxStateManager()->GetSolanaTx(tx_meta_ids[i]); + GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_ids[i]); if (!meta) { continue; } @@ -282,22 +294,25 @@ void SolanaTxManager::OnGetSignatureStatuses( } void SolanaTxManager::SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) { NOTIMPLEMENTED(); } -void SolanaTxManager::RetryTransaction(const std::string& tx_meta_id, +void SolanaTxManager::RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) { NOTIMPLEMENTED(); } void SolanaTxManager::GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) { std::unique_ptr meta = - GetSolanaTxStateManager()->GetSolanaTx(tx_meta_id); + GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_id); if (!meta || !meta->tx()) { VLOG(1) << __FUNCTION__ << "No transaction found with id:" << tx_meta_id; std::move(callback).Run(nullptr); @@ -307,6 +322,7 @@ void SolanaTxManager::GetTransactionMessageToSign( const std::string blockhash = meta->tx()->message()->recent_blockhash(); if (blockhash.empty()) { GetSolanaBlockTracker()->GetLatestBlockhash( + chain_id, base::BindOnce(&SolanaTxManager::OnGetLatestBlockhashHardware, weak_ptr_factory_.GetWeakPtr(), std::move(meta), std::move(callback)), @@ -318,6 +334,10 @@ void SolanaTxManager::GetTransactionMessageToSign( } } +mojom::CoinType SolanaTxManager::GetCoinType() const { + return mojom::CoinType::SOL; +} + void SolanaTxManager::MakeSystemProgramTransferTxData( const std::string& from, const std::string& to, @@ -357,6 +377,7 @@ void SolanaTxManager::MakeSystemProgramTransferTxData( } void SolanaTxManager::MakeTokenProgramTransferTxData( + const std::string& chain_id, const std::string& spl_token_mint_address, const std::string& from_wallet_address, const std::string& to_wallet_address, @@ -377,7 +398,7 @@ void SolanaTxManager::MakeTokenProgramTransferTxData( // Check if the receiver's associated token account is existed or not. json_rpc_service_->GetSolanaAccountInfo( - *to_associated_token_account, + chain_id, *to_associated_token_account, base::BindOnce( &SolanaTxManager::OnGetAccountInfo, weak_ptr_factory_.GetWeakPtr(), spl_token_mint_address, from_wallet_address, to_wallet_address, @@ -499,10 +520,11 @@ void SolanaTxManager::OnGetAccountInfo( mojom::SolanaProviderError::kSuccess, ""); } -void SolanaTxManager::GetEstimatedTxFee(const std::string& tx_meta_id, +void SolanaTxManager::GetEstimatedTxFee(const std::string& chain_id, + const std::string& tx_meta_id, GetEstimatedTxFeeCallback callback) { std::unique_ptr meta = - GetSolanaTxStateManager()->GetSolanaTx(tx_meta_id); + GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_id); if (!meta) { DCHECK(false) << "Transaction should be found"; std::move(callback).Run( @@ -512,6 +534,7 @@ void SolanaTxManager::GetEstimatedTxFee(const std::string& tx_meta_id, } GetSolanaBlockTracker()->GetLatestBlockhash( + chain_id, base::BindOnce(&SolanaTxManager::OnGetLatestBlockhashForGetEstimatedTxFee, weak_ptr_factory_.GetWeakPtr(), std::move(meta), std::move(callback)), @@ -535,7 +558,7 @@ void SolanaTxManager::OnGetLatestBlockhashForGetEstimatedTxFee( const std::string base64_encoded_message = meta->tx()->GetBase64EncodedMessage(); json_rpc_service_->GetSolanaFeeForMessage( - base64_encoded_message, + meta->chain_id(), base64_encoded_message, base::BindOnce(&SolanaTxManager::OnGetFeeForMessage, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } @@ -548,9 +571,10 @@ void SolanaTxManager::OnGetFeeForMessage(GetEstimatedTxFeeCallback callback, } void SolanaTxManager::OnLatestBlockhashUpdated( + const std::string& chain_id, const std::string& blockhash, uint64_t last_valid_block_height) { - UpdatePendingTransactions(); + UpdatePendingTransactions(chain_id); } SolanaTxStateManager* SolanaTxManager::GetSolanaTxStateManager() { @@ -562,16 +586,18 @@ SolanaBlockTracker* SolanaTxManager::GetSolanaBlockTracker() { } std::unique_ptr SolanaTxManager::GetTxForTesting( + const std::string& chain_id, const std::string& tx_meta_id) { - return GetSolanaTxStateManager()->GetSolanaTx(tx_meta_id); + return GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_id); } void SolanaTxManager::ProcessSolanaHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& signature_bytes, ProcessSolanaHardwareSignatureCallback callback) { std::unique_ptr meta = - GetSolanaTxStateManager()->GetSolanaTx(tx_meta_id); + GetSolanaTxStateManager()->GetSolanaTx(chain_id, tx_meta_id); if (!meta) { std::move(callback).Run( false, @@ -595,10 +621,11 @@ void SolanaTxManager::ProcessSolanaHardwareSignature( tx_state_manager_->AddOrUpdateTx(*meta); json_rpc_service_->SendSolanaTransaction( - base::Base64Encode(*transaction_bytes), meta->tx()->send_options(), + meta->chain_id(), base::Base64Encode(*transaction_bytes), + meta->tx()->send_options(), base::BindOnce(&SolanaTxManager::OnSendSolanaTransaction, - weak_ptr_factory_.GetWeakPtr(), meta->id(), - std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), meta->chain_id(), + meta->id(), std::move(callback))); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/solana_tx_manager.h b/components/brave_wallet/browser/solana_tx_manager.h index 2fbce9fc006f..64f918203cb8 100644 --- a/components/brave_wallet/browser/solana_tx_manager.h +++ b/components/brave_wallet/browser/solana_tx_manager.h @@ -1,6 +1,6 @@ /* Copyright (c) 2022 The Brave Authors. All rights reserved. * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this Solanae, + * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_SOLANA_TX_MANAGER_H_ @@ -40,22 +40,27 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { mojom::SolanaTxManagerProxy::ProcessSolanaHardwareSignatureCallback; // TxManager - void AddUnapprovedTransaction(mojom::TxDataUnionPtr tx_data_union, + void AddUnapprovedTransaction(const std::string& chain_id, + mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, const absl::optional& group_id, AddUnapprovedTransactionCallback) override; - void ApproveTransaction(const std::string& tx_meta_id, + void ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback) override; void SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) override; - void RetryTransaction(const std::string& tx_meta_id, + void RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) override; void GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) override; @@ -73,6 +78,7 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { uint64_t lamports, MakeSystemProgramTransferTxDataCallback callback); void MakeTokenProgramTransferTxData( + const std::string& chain_id, const std::string& spl_token_mint_address, const std::string& from_wallet_address, const std::string& to_wallet_address, @@ -83,14 +89,17 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { const mojom::TransactionType tx_type, mojom::SolanaSendTransactionOptionsPtr send_options, MakeTxDataFromBase64EncodedTransactionCallback callback); - void GetEstimatedTxFee(const std::string& tx_meta_id, + void GetEstimatedTxFee(const std::string& chain_id, + const std::string& tx_meta_id, GetEstimatedTxFeeCallback callback); void ProcessSolanaHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& signature_bytes, ProcessSolanaHardwareSignatureCallback callback); - std::unique_ptr GetTxForTesting(const std::string& tx_meta_id); + std::unique_ptr GetTxForTesting(const std::string& chain_id, + const std::string& tx_meta_id); private: FRIEND_TEST_ALL_PREFIXES(SolanaTxManagerUnitTest, AddAndApproveTransaction); @@ -100,10 +109,13 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { FRIEND_TEST_ALL_PREFIXES(SolanaTxManagerUnitTest, ProcessSolanaHardwareSignature); + mojom::CoinType GetCoinType() const override; + // TxManager - void UpdatePendingTransactions() override; + void UpdatePendingTransactions(const std::string& chain_id) override; - void OnGetBlockHeight(uint64_t block_height, + void OnGetBlockHeight(const std::string& chain_id, + uint64_t block_height, mojom::SolanaProviderError error, const std::string& error_message); @@ -120,12 +132,14 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { uint64_t last_valid_block_height, mojom::SolanaProviderError error, const std::string& error_message); - void OnSendSolanaTransaction(const std::string& tx_meta_id, + void OnSendSolanaTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback callback, const std::string& tx_hash, mojom::SolanaProviderError error, const std::string& error_message); void OnGetSignatureStatuses( + const std::string& chain_id, const std::vector& tx_meta_ids, uint64_t block_height, const std::vector>& @@ -155,7 +169,8 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { const std::string& error_message); // SolanaBlockTracker::Observer - void OnLatestBlockhashUpdated(const std::string& blockhash, + void OnLatestBlockhashUpdated(const std::string& chain_id, + const std::string& blockhash, uint64_t last_valid_block_height) override; SolanaTxStateManager* GetSolanaTxStateManager(); diff --git a/components/brave_wallet/browser/solana_tx_state_manager.cc b/components/brave_wallet/browser/solana_tx_state_manager.cc index 44974f56992a..2633f9261993 100644 --- a/components/brave_wallet/browser/solana_tx_state_manager.cc +++ b/components/brave_wallet/browser/solana_tx_state_manager.cc @@ -11,14 +11,12 @@ #include "base/values.h" #include "brave/components/brave_wallet/browser/brave_wallet_constants.h" #include "brave/components/brave_wallet/browser/brave_wallet_utils.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/solana_tx_meta.h" namespace brave_wallet { -SolanaTxStateManager::SolanaTxStateManager(PrefService* prefs, - JsonRpcService* json_rpc_service) - : TxStateManager(prefs, json_rpc_service) {} +SolanaTxStateManager::SolanaTxStateManager(PrefService* prefs) + : TxStateManager(prefs) {} SolanaTxStateManager::~SolanaTxStateManager() = default; @@ -28,45 +26,58 @@ std::unique_ptr SolanaTxStateManager::ValueToSolanaTxMeta( static_cast(ValueToTxMeta(value).release())}; } +mojom::CoinType SolanaTxStateManager::GetCoinType() const { + return mojom::CoinType::SOL; +} + std::unique_ptr SolanaTxStateManager::ValueToTxMeta( const base::Value::Dict& value) { std::unique_ptr meta = std::make_unique(); - if (!TxStateManager::ValueToTxMeta(value, meta.get())) + if (!TxStateManager::ValueToTxMeta(value, meta.get())) { return nullptr; + } const base::Value::Dict* tx_value = value.FindDict("tx"); - if (!tx_value) + if (!tx_value) { return nullptr; + } auto tx = SolanaTransaction::FromValue(*tx_value); - if (!tx) + if (!tx) { return nullptr; + } meta->set_tx(std::move(tx)); const base::Value::Dict* signature_status_value = value.FindDict("signature_status"); - if (!signature_status_value) + if (!signature_status_value) { return nullptr; + } absl::optional signature_status = SolanaSignatureStatus::FromValue(*signature_status_value); - if (!signature_status) + if (!signature_status) { return nullptr; + } meta->set_signature_status(*signature_status); return meta; } -std::string SolanaTxStateManager::GetTxPrefPathPrefix() { - return base::StrCat( - {kSolanaPrefKey, ".", - GetNetworkId(prefs_, mojom::CoinType::SOL, - json_rpc_service_->GetChainId(mojom::CoinType::SOL))}); +std::string SolanaTxStateManager::GetTxPrefPathPrefix( + const absl::optional& chain_id) { + if (chain_id.has_value()) { + return base::StrCat( + {kSolanaPrefKey, ".", + GetNetworkId(prefs_, mojom::CoinType::SOL, *chain_id)}); + } + return kSolanaPrefKey; } std::unique_ptr SolanaTxStateManager::GetSolanaTx( + const std::string& chain_id, const std::string& id) { - return std::unique_ptr{ - static_cast(TxStateManager::GetTx(id).release())}; + return std::unique_ptr{static_cast( + TxStateManager::GetTx(chain_id, id).release())}; } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/solana_tx_state_manager.h b/components/brave_wallet/browser/solana_tx_state_manager.h index a25e203db100..3139431dd8a2 100644 --- a/components/brave_wallet/browser/solana_tx_state_manager.h +++ b/components/brave_wallet/browser/solana_tx_state_manager.h @@ -22,25 +22,28 @@ namespace brave_wallet { class TxMeta; class SolanaTxMeta; -class JsonRpcService; class SolanaTxStateManager : public TxStateManager { public: - SolanaTxStateManager(PrefService* prefs, JsonRpcService* json_rpc_service); + explicit SolanaTxStateManager(PrefService* prefs); ~SolanaTxStateManager() override; SolanaTxStateManager(const SolanaTxStateManager&) = delete; SolanaTxStateManager operator=(const SolanaTxStateManager&) = delete; - std::unique_ptr GetSolanaTx(const std::string& id); + std::unique_ptr GetSolanaTx(const std::string& chain_id, + const std::string& id); std::unique_ptr ValueToSolanaTxMeta( const base::Value::Dict& value); private: FRIEND_TEST_ALL_PREFIXES(SolanaTxStateManagerUnitTest, GetTxPrefPathPrefix); + mojom::CoinType GetCoinType() const override; + std::unique_ptr ValueToTxMeta( const base::Value::Dict& value) override; - std::string GetTxPrefPathPrefix() override; + std::string GetTxPrefPathPrefix( + const absl::optional& chain_id) override; }; } // namespace brave_wallet diff --git a/components/brave_wallet/browser/tx_manager.cc b/components/brave_wallet/browser/tx_manager.cc index 8d87b441542a..a09cf269b81e 100644 --- a/components/brave_wallet/browser/tx_manager.cc +++ b/components/brave_wallet/browser/tx_manager.cc @@ -10,9 +10,12 @@ #include #include "base/check.h" +#include "base/containers/contains.h" #include "base/logging.h" #include "brave/components/brave_wallet/browser/block_tracker.h" #include "brave/components/brave_wallet/browser/brave_wallet_constants.h" +#include "brave/components/brave_wallet/browser/brave_wallet_utils.h" +#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/brave_wallet/browser/tx_meta.h" #include "brave/components/brave_wallet/browser/tx_service.h" @@ -35,7 +38,8 @@ TxManager::TxManager(std::unique_ptr tx_state_manager, DCHECK(json_rpc_service_); DCHECK(keyring_service_); - CheckIfBlockTrackerShouldRun(); + // TODO(darkdh): Check if this is needed. (Unlock should be sufficient) + // CheckIfBlockTrackerShouldRun(absl::nullopt); tx_state_manager_->AddObserver(this); keyring_service_->AddObserver( keyring_observer_receiver_.BindNewPipeAndPassRemote()); @@ -45,9 +49,10 @@ TxManager::~TxManager() { tx_state_manager_->RemoveObserver(this); } -void TxManager::GetTransactionInfo(const std::string& tx_meta_id, +void TxManager::GetTransactionInfo(const std::string& chain_id, + const std::string& tx_meta_id, GetTransactionInfoCallback callback) { - std::unique_ptr meta = tx_state_manager_->GetTx(tx_meta_id); + std::unique_ptr meta = tx_state_manager_->GetTx(chain_id, tx_meta_id); if (!meta) { LOG(ERROR) << "No transaction found"; std::move(callback).Run(nullptr); @@ -57,15 +62,17 @@ void TxManager::GetTransactionInfo(const std::string& tx_meta_id, std::move(callback).Run(meta->ToTransactionInfo()); } -void TxManager::GetAllTransactionInfo(const absl::optional& from, - GetAllTransactionInfoCallback callback) { +void TxManager::GetAllTransactionInfo( + const absl::optional& chain_id, + const absl::optional& from, + GetAllTransactionInfoCallback callback) { if (from.has_value() && from->empty()) { std::move(callback).Run(std::vector()); return; } std::vector> metas = - tx_state_manager_->GetTransactionsByStatus(absl::nullopt, from); + tx_state_manager_->GetTransactionsByStatus(chain_id, absl::nullopt, from); // Convert vector of TxMeta to vector of TransactionInfo std::vector tis(metas.size()); @@ -77,9 +84,10 @@ void TxManager::GetAllTransactionInfo(const absl::optional& from, std::move(callback).Run(std::move(tis)); } -void TxManager::RejectTransaction(const std::string& tx_meta_id, +void TxManager::RejectTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RejectTransactionCallback callback) { - std::unique_ptr meta = tx_state_manager_->GetTx(tx_meta_id); + std::unique_ptr meta = tx_state_manager_->GetTx(chain_id, tx_meta_id); if (!meta) { LOG(ERROR) << "No transaction found"; std::move(callback).Run(false); @@ -90,16 +98,18 @@ void TxManager::RejectTransaction(const std::string& tx_meta_id, std::move(callback).Run(true); } -void TxManager::CheckIfBlockTrackerShouldRun() { - // TODO(darkdh): each keyring should have their own block tracker check. - bool keyring_created = - keyring_service_->IsKeyringCreated(mojom::kDefaultKeyringId); +void TxManager::CheckIfBlockTrackerShouldRun(const std::string& chain_id) { + const auto& keyring_id = CoinTypeToKeyringId(GetCoinType(), chain_id); + CHECK(keyring_id.has_value()); + bool keyring_created = keyring_service_->IsKeyringCreated(*keyring_id); bool locked = keyring_service_->IsLockedSync(); - bool running = block_tracker_->IsRunning(); + bool running = block_tracker_->IsRunning(chain_id); if (keyring_created && !locked && !running) { - block_tracker_->Start(base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - } else if ((locked || known_no_pending_tx_) && running) { - block_tracker_->Stop(); + block_tracker_->Start(chain_id, + base::Seconds(kBlockTrackerDefaultTimeInSeconds)); + } else if ((locked || base::Contains(known_no_pending_tx_, chain_id)) && + running) { + block_tracker_->Stop(chain_id); } } @@ -112,29 +122,37 @@ void TxManager::OnNewUnapprovedTx(mojom::TransactionInfoPtr tx_info) { } void TxManager::Locked() { - CheckIfBlockTrackerShouldRun(); + block_tracker_->Stop(); } void TxManager::Unlocked() { - CheckIfBlockTrackerShouldRun(); - UpdatePendingTransactions(); + const std::string& chain_id = + json_rpc_service_->GetChainId(GetCoinType(), absl::nullopt); + CheckIfBlockTrackerShouldRun(chain_id); + UpdatePendingTransactions(chain_id); } void TxManager::KeyringCreated(const std::string& keyring_id) { - UpdatePendingTransactions(); + /* TODO(darkdh): Check if this is needed (There should be no pending txs) + const auto coin = GetCoinForKeyring(keyring_id); + UpdatePendingTransactions(json_rpc_service_->GetChainId(coin, absl::nullopt)); + */ } void TxManager::KeyringRestored(const std::string& keyring_id) { - UpdatePendingTransactions(); + /* TODO(darkdh): Check if this is needed (There should be no pending txs) + const auto coin = GetCoinForKeyring(keyring_id); + UpdatePendingTransactions(json_rpc_service_->GetChainId(coin, absl::nullopt)); + */ } void TxManager::KeyringReset() { - UpdatePendingTransactions(); + Reset(); } void TxManager::Reset() { block_tracker_->Stop(); - known_no_pending_tx_ = false; + known_no_pending_tx_.clear(); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/tx_manager.h b/components/brave_wallet/browser/tx_manager.h index 905f5f4962e2..766914049328 100644 --- a/components/brave_wallet/browser/tx_manager.h +++ b/components/brave_wallet/browser/tx_manager.h @@ -7,6 +7,7 @@ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_TX_MANAGER_H_ #include +#include #include #include @@ -50,36 +51,45 @@ class TxManager : public TxStateManager::Observer, mojom::TxService::GetTransactionMessageToSignCallback; virtual void AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataUnionPtr tx_data_union, const std::string& from, const absl::optional& origin, const absl::optional& group_id, AddUnapprovedTransactionCallback) = 0; - virtual void ApproveTransaction(const std::string& tx_meta_id, + virtual void ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, ApproveTransactionCallback) = 0; - virtual void RejectTransaction(const std::string& tx_meta_id, + virtual void RejectTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RejectTransactionCallback); - virtual void GetTransactionInfo(const std::string& tx_meta_id, + virtual void GetTransactionInfo(const std::string& chain_id, + const std::string& tx_meta_id, GetTransactionInfoCallback); - virtual void GetAllTransactionInfo(const absl::optional& from, - GetAllTransactionInfoCallback); + virtual void GetAllTransactionInfo( + const absl::optional& chain_id, + const absl::optional& from, + GetAllTransactionInfoCallback); virtual void SpeedupOrCancelTransaction( + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) = 0; - virtual void RetryTransaction(const std::string& tx_meta_id, + virtual void RetryTransaction(const std::string& chain_id, + const std::string& tx_meta_id, RetryTransactionCallback callback) = 0; virtual void GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) = 0; virtual void Reset(); protected: - void CheckIfBlockTrackerShouldRun(); - virtual void UpdatePendingTransactions() = 0; + void CheckIfBlockTrackerShouldRun(const std::string& chain_id); + virtual void UpdatePendingTransactions(const std::string& chain_id) = 0; std::unique_ptr tx_state_manager_; std::unique_ptr block_tracker_; @@ -87,9 +97,12 @@ class TxManager : public TxStateManager::Observer, raw_ptr json_rpc_service_ = nullptr; // NOT OWNED raw_ptr keyring_service_ = nullptr; // NOT OWNED raw_ptr prefs_ = nullptr; // NOT OWNED - bool known_no_pending_tx_ = false; + // chain_id + std::set known_no_pending_tx_; private: + virtual mojom::CoinType GetCoinType() const = 0; + // TxStateManager::Observer void OnTransactionStatusChanged(mojom::TransactionInfoPtr tx_info) override; void OnNewUnapprovedTx(mojom::TransactionInfoPtr tx_info) override; diff --git a/components/brave_wallet/browser/tx_service.cc b/components/brave_wallet/browser/tx_service.cc index 329c3f4693a9..c220122aa7df 100644 --- a/components/brave_wallet/browser/tx_service.cc +++ b/components/brave_wallet/browser/tx_service.cc @@ -134,32 +134,35 @@ void TxService::AddUnapprovedTransaction( } void TxService::ApproveTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, ApproveTransactionCallback callback) { - GetTxManager(coin_type)->ApproveTransaction(tx_meta_id, std::move(callback)); + GetTxManager(coin_type)->ApproveTransaction(chain_id, tx_meta_id, + std::move(callback)); } void TxService::RejectTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, RejectTransactionCallback callback) { - GetTxManager(coin_type)->RejectTransaction(tx_meta_id, std::move(callback)); + GetTxManager(coin_type)->RejectTransaction(chain_id, tx_meta_id, + std::move(callback)); } void TxService::GetTransactionInfo(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionInfoCallback callback) { - GetTxManager(coin_type)->GetTransactionInfo(tx_meta_id, std::move(callback)); -} - -void TxService::GetAllTransactionInfo(mojom::CoinType coin_type, - const std::string& from, - GetAllTransactionInfoCallback callback) { - GetTxManager(coin_type)->GetAllTransactionInfo(from, std::move(callback)); + GetTxManager(coin_type)->GetTransactionInfo(chain_id, tx_meta_id, + std::move(callback)); } -void TxService::GetAllTransactionInfo(mojom::CoinType coin_type, - GetAllTransactionInfoCallback callback) { - GetTxManager(coin_type)->GetAllTransactionInfo(absl::nullopt, +void TxService::GetAllTransactionInfo( + mojom::CoinType coin_type, + const absl::optional& chain_id, + const absl::optional& from, + GetAllTransactionInfoCallback callback) { + GetTxManager(coin_type)->GetAllTransactionInfo(chain_id, from, std::move(callback)); } @@ -172,10 +175,10 @@ void TxService::GetPendingTransactionsCount( auto it = tx_manager_map_.begin(); - GetAllTransactionInfo( - it->first, base::BindOnce(&TxService::OnGetAllTransactionInfo, - weak_factory_.GetWeakPtr(), std::move(callback), - 0u, it->first)); + GetAllTransactionInfo(it->first, absl::nullopt, absl::nullopt, + base::BindOnce(&TxService::OnGetAllTransactionInfo, + weak_factory_.GetWeakPtr(), + std::move(callback), 0u, it->first)); } void TxService::OnGetAllTransactionInfo( @@ -196,7 +199,7 @@ void TxService::OnGetAllTransactionInfo( DCHECK(next_coin_to_check); GetAllTransactionInfo( - *next_coin_to_check, + *next_coin_to_check, absl::nullopt, absl::nullopt, base::BindOnce(&TxService::OnGetAllTransactionInfo, weak_factory_.GetWeakPtr(), std::move(callback), counter, *next_coin_to_check)); @@ -204,24 +207,28 @@ void TxService::OnGetAllTransactionInfo( void TxService::SpeedupOrCancelTransaction( mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) { - GetTxManager(coin_type)->SpeedupOrCancelTransaction(tx_meta_id, cancel, - std::move(callback)); + GetTxManager(coin_type)->SpeedupOrCancelTransaction( + chain_id, tx_meta_id, cancel, std::move(callback)); } void TxService::RetryTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, RetryTransactionCallback callback) { - GetTxManager(coin_type)->RetryTransaction(tx_meta_id, std::move(callback)); + GetTxManager(coin_type)->RetryTransaction(chain_id, tx_meta_id, + std::move(callback)); } void TxService::GetTransactionMessageToSign( mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) { - GetTxManager(coin_type)->GetTransactionMessageToSign(tx_meta_id, + GetTxManager(coin_type)->GetTransactionMessageToSign(chain_id, tx_meta_id, std::move(callback)); } @@ -289,60 +296,67 @@ void TxService::MakeERC1155TransferFromData( } void TxService::SetGasPriceAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& gas_price, const std::string& gas_limit, SetGasPriceAndLimitForUnapprovedTransactionCallback callback) { GetEthTxManager()->SetGasPriceAndLimitForUnapprovedTransaction( - tx_meta_id, gas_price, gas_limit, std::move(callback)); + chain_id, tx_meta_id, gas_price, gas_limit, std::move(callback)); } void TxService::SetGasFeeAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& max_priority_fee_per_gas, const std::string& max_fee_per_gas, const std::string& gas_limit, SetGasFeeAndLimitForUnapprovedTransactionCallback callback) { GetEthTxManager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, - std::move(callback)); + chain_id, tx_meta_id, max_priority_fee_per_gas, max_fee_per_gas, + gas_limit, std::move(callback)); } void TxService::SetDataForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& data, SetDataForUnapprovedTransactionCallback callback) { - GetEthTxManager()->SetDataForUnapprovedTransaction(tx_meta_id, data, + GetEthTxManager()->SetDataForUnapprovedTransaction(chain_id, tx_meta_id, data, std::move(callback)); } void TxService::SetNonceForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& nonce, SetNonceForUnapprovedTransactionCallback callback) { - GetEthTxManager()->SetNonceForUnapprovedTransaction(tx_meta_id, nonce, - std::move(callback)); + GetEthTxManager()->SetNonceForUnapprovedTransaction( + chain_id, tx_meta_id, nonce, std::move(callback)); } void TxService::GetNonceForHardwareTransaction( + const std::string& chain_id, const std::string& tx_meta_id, GetNonceForHardwareTransactionCallback callback) { - GetEthTxManager()->GetNonceForHardwareTransaction(tx_meta_id, + GetEthTxManager()->GetNonceForHardwareTransaction(chain_id, tx_meta_id, std::move(callback)); } void TxService::ProcessHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& v, const std::string& r, const std::string& s, ProcessHardwareSignatureCallback callback) { - GetEthTxManager()->ProcessHardwareSignature(tx_meta_id, v, r, s, + GetEthTxManager()->ProcessHardwareSignature(chain_id, tx_meta_id, v, r, s, std::move(callback)); } -void TxService::GetGasEstimation1559(GetGasEstimation1559Callback callback) { - GetEthTxManager()->GetGasEstimation1559(std::move(callback)); +void TxService::GetGasEstimation1559(const std::string& chain_id, + GetGasEstimation1559Callback callback) { + GetEthTxManager()->GetGasEstimation1559(chain_id, std::move(callback)); } void TxService::MakeSystemProgramTransferTxData( @@ -355,14 +369,15 @@ void TxService::MakeSystemProgramTransferTxData( } void TxService::MakeTokenProgramTransferTxData( + const std::string& chain_id, const std::string& spl_token_mint_address, const std::string& from_wallet_address, const std::string& to_wallet_address, uint64_t amount, MakeTokenProgramTransferTxDataCallback callback) { GetSolanaTxManager()->MakeTokenProgramTransferTxData( - spl_token_mint_address, from_wallet_address, to_wallet_address, amount, - std::move(callback)); + chain_id, spl_token_mint_address, from_wallet_address, to_wallet_address, + amount, std::move(callback)); } void TxService::MakeTxDataFromBase64EncodedTransaction( @@ -375,25 +390,29 @@ void TxService::MakeTxDataFromBase64EncodedTransaction( std::move(callback)); } -void TxService::GetEstimatedTxFee(const std::string& tx_meta_id, +void TxService::GetEstimatedTxFee(const std::string& chain_id, + const std::string& tx_meta_id, GetEstimatedTxFeeCallback callback) { - GetSolanaTxManager()->GetEstimatedTxFee(tx_meta_id, std::move(callback)); + GetSolanaTxManager()->GetEstimatedTxFee(chain_id, tx_meta_id, + std::move(callback)); } void TxService::ProcessSolanaHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& signature, ProcessSolanaHardwareSignatureCallback callback) { - GetSolanaTxManager()->ProcessSolanaHardwareSignature(tx_meta_id, signature, - std::move(callback)); + GetSolanaTxManager()->ProcessSolanaHardwareSignature( + chain_id, tx_meta_id, signature, std::move(callback)); } void TxService::ProcessFilHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& signed_message, ProcessFilHardwareSignatureCallback callback) { - GetFilTxManager()->ProcessFilHardwareSignature(tx_meta_id, signed_message, - std::move(callback)); + GetFilTxManager()->ProcessFilHardwareSignature( + chain_id, tx_meta_id, signed_message, std::move(callback)); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/tx_service.h b/components/brave_wallet/browser/tx_service.h index 7276489081ee..849bf2d066b0 100644 --- a/components/brave_wallet/browser/tx_service.h +++ b/components/brave_wallet/browser/tx_service.h @@ -64,34 +64,39 @@ class TxService : public KeyedService, const absl::optional& group_id, AddUnapprovedTransactionCallback) override; void ApproveTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, ApproveTransactionCallback) override; void RejectTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, RejectTransactionCallback) override; void GetTransactionInfo(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionInfoCallback) override; void GetAllTransactionInfo(mojom::CoinType coin_type, - const std::string& from, + const absl::optional& chain_id, + const absl::optional& from, GetAllTransactionInfoCallback) override; - void GetAllTransactionInfo(mojom::CoinType coin_type, - GetAllTransactionInfoCallback); void GetPendingTransactionsCount( GetPendingTransactionsCountCallback callback) override; void SpeedupOrCancelTransaction( mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, bool cancel, SpeedupOrCancelTransactionCallback callback) override; void RetryTransaction(mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, RetryTransactionCallback callback) override; void GetTransactionMessageToSign( mojom::CoinType coin_type, + const std::string& chain_id, const std::string& tx_meta_id, GetTransactionMessageToSignCallback callback) override; @@ -127,35 +132,42 @@ class TxService : public KeyedService, MakeERC1155TransferFromDataCallback) override; void SetGasPriceAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& gas_price, const std::string& gas_limit, SetGasPriceAndLimitForUnapprovedTransactionCallback callback) override; void SetGasFeeAndLimitForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& max_priority_fee_per_gas, const std::string& max_fee_per_gas, const std::string& gas_limit, SetGasFeeAndLimitForUnapprovedTransactionCallback callback) override; void SetDataForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& data, SetDataForUnapprovedTransactionCallback callback) override; void SetNonceForUnapprovedTransaction( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& nonce, SetNonceForUnapprovedTransactionCallback) override; void GetNonceForHardwareTransaction( + const std::string& chain_id, const std::string& tx_meta_id, GetNonceForHardwareTransactionCallback callback) override; void ProcessHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& v, const std::string& r, const std::string& s, ProcessHardwareSignatureCallback callback) override; // Gas estimation API via eth_feeHistory API - void GetGasEstimation1559(GetGasEstimation1559Callback callback) override; + void GetGasEstimation1559(const std::string& chain_id, + GetGasEstimation1559Callback callback) override; // mojom::SolanaTxManagerProxy void MakeSystemProgramTransferTxData( @@ -164,6 +176,7 @@ class TxService : public KeyedService, uint64_t lamports, MakeSystemProgramTransferTxDataCallback callback) override; void MakeTokenProgramTransferTxData( + const std::string& chain_id, const std::string& spl_token_mint_address, const std::string& from_wallet_address, const std::string& to_wallet_address, @@ -175,15 +188,18 @@ class TxService : public KeyedService, mojom::SolanaSendTransactionOptionsPtr send_options, MakeTxDataFromBase64EncodedTransactionCallback callback) override; - void GetEstimatedTxFee(const std::string& tx_meta_id, + void GetEstimatedTxFee(const std::string& chain_id, + const std::string& tx_meta_id, GetEstimatedTxFeeCallback callback) override; void ProcessSolanaHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& signature, ProcessSolanaHardwareSignatureCallback callback) override; // mojom::FilTxManagerProxy void ProcessFilHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::string& signed_message, ProcessFilHardwareSignatureCallback callback) override; diff --git a/components/brave_wallet/browser/tx_state_manager.cc b/components/brave_wallet/browser/tx_state_manager.cc index 2af9682ffbdd..735673fd4fa1 100644 --- a/components/brave_wallet/browser/tx_state_manager.cc +++ b/components/brave_wallet/browser/tx_state_manager.cc @@ -107,11 +107,8 @@ bool TxStateManager::ValueToTxMeta(const base::Value::Dict& value, return true; } -TxStateManager::TxStateManager(PrefService* prefs, - JsonRpcService* json_rpc_service) - : prefs_(prefs), json_rpc_service_(json_rpc_service), weak_factory_(this) { - DCHECK(json_rpc_service_); -} +TxStateManager::TxStateManager(PrefService* prefs) + : prefs_(prefs), weak_factory_(this) {} TxStateManager::~TxStateManager() = default; @@ -119,7 +116,7 @@ void TxStateManager::AddOrUpdateTx(const TxMeta& meta) { ScopedDictPrefUpdate update(prefs_, kBraveWalletTransactions); base::Value::Dict& dict = update.Get(); const std::string path = - base::JoinString({GetTxPrefPathPrefix(), meta.id()}, "."); + base::JoinString({GetTxPrefPathPrefix(meta.chain_id()), meta.id()}, "."); bool is_add = dict.FindByDottedPath(path) == nullptr; dict.SetByDottedPath(path, meta.ToValue()); @@ -135,14 +132,17 @@ void TxStateManager::AddOrUpdateTx(const TxMeta& meta) { } // We only keep most recent 10 confirmed and rejected tx metas per network - RetireTxByStatus(mojom::TransactionStatus::Confirmed, kMaxConfirmedTxNum); - RetireTxByStatus(mojom::TransactionStatus::Rejected, kMaxRejectedTxNum); + RetireTxByStatus(meta.chain_id(), mojom::TransactionStatus::Confirmed, + kMaxConfirmedTxNum); + RetireTxByStatus(meta.chain_id(), mojom::TransactionStatus::Rejected, + kMaxRejectedTxNum); } -std::unique_ptr TxStateManager::GetTx(const std::string& id) { +std::unique_ptr TxStateManager::GetTx(const std::string& chain_id, + const std::string& id) { const auto& dict = prefs_->GetDict(kBraveWalletTransactions); const base::Value::Dict* value = dict.FindDictByDottedPath( - base::JoinString({GetTxPrefPathPrefix(), id}, ".")); + base::JoinString({GetTxPrefPathPrefix(chain_id), id}, ".")); if (!value) { return nullptr; } @@ -150,50 +150,63 @@ std::unique_ptr TxStateManager::GetTx(const std::string& id) { return ValueToTxMeta(*value); } -void TxStateManager::DeleteTx(const std::string& id) { +void TxStateManager::DeleteTx(const std::string& chain_id, + const std::string& id) { ScopedDictPrefUpdate update(prefs_, kBraveWalletTransactions); update->RemoveByDottedPath( - base::JoinString({GetTxPrefPathPrefix(), id}, ".")); + base::JoinString({GetTxPrefPathPrefix(chain_id), id}, ".")); } void TxStateManager::WipeTxs() { ScopedDictPrefUpdate update(prefs_, kBraveWalletTransactions); - update->RemoveByDottedPath(GetTxPrefPathPrefix()); + update->RemoveByDottedPath(GetTxPrefPathPrefix(absl::nullopt)); } std::vector> TxStateManager::GetTransactionsByStatus( - absl::optional status, - absl::optional from) { + const absl::optional& chain_id, + const absl::optional& status, + const absl::optional& from) { std::vector> result; const auto& dict = prefs_->GetDict(kBraveWalletTransactions); const base::Value::Dict* network_dict = - dict.FindDictByDottedPath(GetTxPrefPathPrefix()); + dict.FindDictByDottedPath(GetTxPrefPathPrefix(chain_id)); if (!network_dict) { return result; } for (const auto it : *network_dict) { - std::unique_ptr meta = ValueToTxMeta(it.second.GetDict()); - if (!meta) { - continue; - } - if (!status.has_value() || meta->status() == *status) { - if (from.has_value() && meta->from() != *from) { + if (chain_id.has_value()) { + std::unique_ptr meta = ValueToTxMeta(it.second.GetDict()); + if (!meta) { + continue; + } + if (!status.has_value() || meta->status() == *status) { + if (from.has_value() && meta->from() != *from) { + continue; + } + result.push_back(std::move(meta)); + } + } else { + auto chain_id_from_pref = GetChainId(prefs_, GetCoinType(), it.first); + if (!chain_id_from_pref) { continue; } - result.push_back(std::move(meta)); + auto metas = GetTransactionsByStatus(chain_id_from_pref, status, from); + result.insert(result.end(), std::make_move_iterator(metas.begin()), + std::make_move_iterator(metas.end())); } } return result; } -void TxStateManager::RetireTxByStatus(mojom::TransactionStatus status, +void TxStateManager::RetireTxByStatus(const std::string& chain_id, + mojom::TransactionStatus status, size_t max_num) { if (status != mojom::TransactionStatus::Confirmed && status != mojom::TransactionStatus::Rejected) { return; } - auto tx_metas = GetTransactionsByStatus(status, absl::nullopt); + auto tx_metas = GetTransactionsByStatus(chain_id, status, absl::nullopt); if (tx_metas.size() > max_num) { TxMeta* oldest_meta = nullptr; for (const auto& tx_meta : tx_metas) { @@ -210,7 +223,7 @@ void TxStateManager::RetireTxByStatus(mojom::TransactionStatus status, } } DCHECK(oldest_meta); - DeleteTx(oldest_meta->id()); + DeleteTx(chain_id, oldest_meta->id()); } } diff --git a/components/brave_wallet/browser/tx_state_manager.h b/components/brave_wallet/browser/tx_state_manager.h index a5f26e5073e9..efd56c338947 100644 --- a/components/brave_wallet/browser/tx_state_manager.h +++ b/components/brave_wallet/browser/tx_state_manager.h @@ -27,17 +27,17 @@ class Value; namespace brave_wallet { class TxMeta; -class JsonRpcService; class TxStateManager { public: - TxStateManager(PrefService* prefs, JsonRpcService* json_rpc_service); + explicit TxStateManager(PrefService* prefs); virtual ~TxStateManager(); TxStateManager(const TxStateManager&) = delete; void AddOrUpdateTx(const TxMeta& meta); - std::unique_ptr GetTx(const std::string& id); - void DeleteTx(const std::string& id); + std::unique_ptr GetTx(const std::string& chain_id, + const std::string& id); + void DeleteTx(const std::string& chain_id, const std::string& id); void WipeTxs(); static void MigrateAddChainIdToTransactionInfo(PrefService* prefs); @@ -45,8 +45,9 @@ class TxStateManager { PrefService* prefs); std::vector> GetTransactionsByStatus( - absl::optional status, - absl::optional from); + const absl::optional& chain_id, + const absl::optional& status, + const absl::optional& from); class Observer : public base::CheckedObserver { public: @@ -63,11 +64,14 @@ class TxStateManager { static bool ValueToTxMeta(const base::Value::Dict& value, TxMeta* tx_meta); raw_ptr prefs_ = nullptr; - raw_ptr json_rpc_service_ = nullptr; private: FRIEND_TEST_ALL_PREFIXES(TxStateManagerUnitTest, TxOperations); - void RetireTxByStatus(mojom::TransactionStatus status, size_t max_num); + void RetireTxByStatus(const std::string& chain_id, + mojom::TransactionStatus status, + size_t max_num); + + virtual mojom::CoinType GetCoinType() const = 0; // Each derived class should implement its own ValueToTxMeta to create a // specific type of tx meta (ex: EthTxMeta) from a value. TxMeta @@ -78,8 +82,11 @@ class TxStateManager { // Each derived class should provide transaction pref path prefix as // coin_type.network_id. For example, ethereum.mainnet or solana.testnet. // This will be used to get/set the transaction pref for a specific - // coin_type. - virtual std::string GetTxPrefPathPrefix() = 0; + // coin_type. When chain_id is not provided, prefix will be just coin_type, + // ex. ethereum and solana and it will be used to acess all the transactions + // across different network for the coin. + virtual std::string GetTxPrefPathPrefix( + const absl::optional& chain_id) = 0; base::ObserverList observers_; diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 5e178f7b952f..70f5dea98431 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -1111,7 +1111,9 @@ interface JsonRpcService { // Obtains the contract's ERC20 allowance for an owner and a spender GetERC20TokenAllowance(string contract, - string owner_address, string spender_address) => (string allowance, ProviderError error, string error_message); + string owner_address, + string spender_address, string chain_id) + => (string allowance, ProviderError error, string error_message); // Obtains the metadata JSON for a token ID of an ERC721 contract GetERC721Metadata(string contract, string token_id, string chain_id) => (string token_url, string response, ProviderError error, string error_message); @@ -1151,7 +1153,12 @@ interface JsonRpcService { // Used for making requests to the currently selected EVM compatible node for // coin ETH and other nodes with corresponding coin types - Request(string json_payload, bool auto_retry_on_network_change, mojo_base.mojom.Value id, CoinType coin) => (mojo_base.mojom.Value id, mojo_base.mojom.Value formed_response, bool reject, string first_allowed_account, bool update_bind_js_properties); + Request(string chain_id, string json_payload, + bool auto_retry_on_network_change, + mojo_base.mojom.Value id, CoinType coin) => + (mojo_base.mojom.Value id, mojo_base.mojom.Value formed_response, + bool reject, string first_allowed_account, + bool update_bind_js_properties); // Adds an observer for the events of JsonRpcService AddObserver(pending_remote observer); @@ -1177,11 +1184,14 @@ interface JsonRpcService { GetSolanaBalance(string pubkey, string chain_id) => (uint64 balance, SolanaProviderError error, string error_message); // Returns the token balance of an SPL Token account. - GetSPLTokenAccountBalance(string wallet_address, string token_mint_address, string chain_id) => + GetSPLTokenAccountBalance(string wallet_address, + string token_mint_address, string chain_id) => (string amount, uint8 decimals, string uiAmountString, SolanaProviderError error, string error_message); // Returns the metadata json associated with the NFT account address - GetSolTokenMetadata(string chain_id, string token_mint_address) => (string token_url, string response, SolanaProviderError error, string error_message); + GetSolTokenMetadata(string chain_id, string token_mint_address) + => (string token_url, string response, SolanaProviderError error, + string error_message); }; enum TransactionStatus { @@ -1269,25 +1279,34 @@ interface TxService { AddUnapprovedTransaction(TxDataUnion tx_data_union, string from, url.mojom.Origin? origin, string? group_id) => (bool success, string tx_meta_id, string error_message); // Used to approve a transaction - ApproveTransaction(CoinType coin_type, string tx_meta_id) => (bool status, ProviderErrorUnion error_union, string error_message); + ApproveTransaction(CoinType coin_type, string chain_id, string tx_meta_id) + => (bool status, ProviderErrorUnion error_union, string error_message); // Used to reject a transaction - RejectTransaction(CoinType coin_type, string tx_meta_id) => (bool status); + RejectTransaction(CoinType coin_type, string chain_id, string tx_meta_id) + => (bool status); // Used to get transaction info - GetTransactionInfo(CoinType coin_type, string tx_meta_id) => (TransactionInfo? transaction_info); + GetTransactionInfo(CoinType coin_type, string chain_id, string tx_meta_id) + => (TransactionInfo? transaction_info); // Obtains a list of all transactions from an address. // This returns different data depending on which network is currently selected in JsonRpcService - GetAllTransactionInfo(CoinType coin_type, string from) => (array transaction_infos); + GetAllTransactionInfo(CoinType coin_type, string? chain_id, string? from) + => (array transaction_infos); // Used to speed-up or cancel a transaction - SpeedupOrCancelTransaction(CoinType coin_type, string tx_meta_id, bool cancel) => (bool success, string tx_meta_id, string error_message); + SpeedupOrCancelTransaction(CoinType coin_type, + string chain_id, string tx_meta_id, bool cancel) + => (bool success, string tx_meta_id, string error_message); // Used to retry a transaction - RetryTransaction(CoinType coin_type, string tx_meta_id) => (bool success, string tx_meta_id, string error_message); + RetryTransaction(CoinType coin_type, string chain_id, string tx_meta_id) + => (bool success, string tx_meta_id, string error_message); - GetTransactionMessageToSign(CoinType coin_type, string tx_meta_id) => (MessageToSignUnion? message); + GetTransactionMessageToSign(CoinType coin_type, + string chain_id, string tx_meta_id) + => (MessageToSignUnion? message); // Adds an observer for TxService AddObserver(pending_remote observer); @@ -1307,10 +1326,16 @@ union MessageToSignUnion { // Transaction related APIs specific to EVM. interface EthTxManagerProxy { // Used for modifying transaction data - SetGasPriceAndLimitForUnapprovedTransaction(string tx_meta_id, string gas_price, string gas_limit) => (bool success); - SetGasFeeAndLimitForUnapprovedTransaction(string tx_meta_id, string max_priority_fee_per_gas, string max_fee_per_gas, string gas_limit) => (bool success); - SetDataForUnapprovedTransaction(string tx_meta_id, array data) => (bool success); - SetNonceForUnapprovedTransaction(string tx_meta_id, string nonce) => (bool success); + SetGasPriceAndLimitForUnapprovedTransaction( + string chain_id, string tx_meta_id, string gas_price, string gas_limit) + => (bool success); + SetGasFeeAndLimitForUnapprovedTransaction( + string chain_id, string tx_meta_id, string max_priority_fee_per_gas, + string max_fee_per_gas, string gas_limit) => (bool success); + SetDataForUnapprovedTransaction( + string chain_id, string tx_meta_id, array data) => (bool success); + SetNonceForUnapprovedTransaction( + string chain_id, string tx_meta_id, string nonce) => (bool success); // Used for creating transaction data MakeERC20TransferData(string to_address, string amount) => (bool success, array data); @@ -1319,10 +1344,13 @@ interface EthTxManagerProxy { MakeERC1155TransferFromData(string from, string to, string token_id, string value, string contract_address) => (bool success, array data); // Gas estimation API via eth_feeHistory API - GetGasEstimation1559() => (GasEstimation1559? estimation); + GetGasEstimation1559(string chain_id) => (GasEstimation1559? estimation); - GetNonceForHardwareTransaction(string tx_meta_id) => (string? nonce); - ProcessHardwareSignature(string tx_meta_id, string v, string r, string s) => (bool status, ProviderError error, string error_message); + GetNonceForHardwareTransaction(string chain_id, string tx_meta_id) + => (string? nonce); + ProcessHardwareSignature( + string chain_id, string tx_meta_id, string v, string r, string s) + => (bool status, ProviderError error, string error_message); }; interface SolanaTxManagerProxy { @@ -1330,7 +1358,11 @@ interface SolanaTxManagerProxy { MakeSystemProgramTransferTxData(string from, string to, uint64 lamports) => (SolanaTxData? tx_data, SolanaProviderError error, string error_message); - ProcessSolanaHardwareSignature(string tx_meta_id, array signature_bytes) => (bool status, ProviderErrorUnion error_union, string error_message); + ProcessSolanaHardwareSignature( + string chain_id, + string tx_meta_id, + array signature_bytes) + => (bool status, ProviderErrorUnion error_union, string error_message); // Get transaction data for transfering SPL tokens from one associated token // account to another. @@ -1342,15 +1374,19 @@ interface SolanaTxManagerProxy { // to create the associated token account for the recipient, and the second // instruction is the transfer instruction. Note that sender will fund the // creation (an additional cost) with the minimum balance for the new account - // to be rent exempt. + // to be rent exempt. `chain_id` is needed here because we need to check if + // the receiving associated token account exists on the specific chain via + // `GetSolanaAccountInfo` which requires chain_id. MakeTokenProgramTransferTxData( + string chain_id, string spl_token_mint_address, string from_wallet_address, string to_wallet_address, uint64 amount) => (SolanaTxData? tx_data, SolanaProviderError error, string error_message); - GetEstimatedTxFee(string tx_meta_id) => (uint64 fee, SolanaProviderError error, string error_message); + GetEstimatedTxFee(string chain_id, string tx_meta_id) + => (uint64 fee, SolanaProviderError error, string error_message); // Get transaction data from transaction bytes encoded in base64 format. // @@ -1365,7 +1401,9 @@ interface SolanaTxManagerProxy { interface FilTxManagerProxy { // Publishes signed transaction. - ProcessFilHardwareSignature(string tx_meta_id, string signed_message) => (bool status, ProviderErrorUnion error_union, string error_message); + ProcessFilHardwareSignature( + string chain_id, string tx_meta_id, string signed_message) + => (bool status, ProviderErrorUnion error_union, string error_message); }; interface BraveWalletServiceObserver { From 1f4d9b4501768614cc095145c0008fe1c4f18275 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Wed, 29 Mar 2023 11:09:31 -0700 Subject: [PATCH 02/15] Support selected network per origin We use different pref(kBraveWalletSelectedNetworksPerOrigin) to store that info, the original kBraveWalletSelectedNetworks will be a fallback pref when origin is not available when setting/getting selected networks. Previously cached `chain_ids_` and `network_urls_` are removed because `JsonPrefStore` already has a layer of memory cache so we won't directly read from disk. --- .../ui/webui/settings/brave_wallet_handler.cc | 15 ++- .../browser/brave_wallet_prefs.cc | 12 ++ .../browser/brave_wallet_service.cc | 28 ++++- .../browser/brave_wallet_service.h | 7 ++ .../browser/brave_wallet_utils.cc | 69 +++++++++-- .../brave_wallet/browser/brave_wallet_utils.h | 15 ++- .../browser/brave_wallet_utils_unittest.cc | 2 + .../browser/ethereum_provider_impl.cc | 48 +------- .../browser/ethereum_provider_impl.h | 6 - .../brave_wallet/browser/json_rpc_service.cc | 109 +++++++----------- .../brave_wallet/browser/json_rpc_service.h | 29 +++-- .../brave_wallet/browser/keyring_service.cc | 4 +- components/brave_wallet/browser/pref_names.cc | 2 + components/brave_wallet/browser/pref_names.h | 1 + .../brave_wallet/browser/swap_service.cc | 55 +++++---- components/brave_wallet/browser/tx_service.cc | 4 +- components/brave_wallet/browser/tx_service.h | 1 + .../brave_wallet/common/brave_wallet.mojom | 21 ++-- 18 files changed, 247 insertions(+), 181 deletions(-) diff --git a/browser/ui/webui/settings/brave_wallet_handler.cc b/browser/ui/webui/settings/brave_wallet_handler.cc index bb4d2c1cc755..875b7a5f018b 100644 --- a/browser/ui/webui/settings/brave_wallet_handler.cc +++ b/browser/ui/webui/settings/brave_wallet_handler.cc @@ -44,8 +44,9 @@ base::Value::Dict MakeSelectValue(const std::u16string& name, absl::optional ToCoinType( absl::optional val) { - if (!val) + if (!val) { return absl::nullopt; + } auto result = static_cast(*val); if (result != brave_wallet::mojom::CoinType::ETH && result != brave_wallet::mojom::CoinType::FIL && @@ -180,7 +181,9 @@ void BraveWalletHandler::GetNetworksList(const base::Value::List& args) { return; } - result.Set("activeNetwork", brave_wallet::GetCurrentChainId(prefs, *coin)); + // TODO(darkdh): change this to default network. + result.Set("activeNetwork", + brave_wallet::GetCurrentChainId(prefs, *coin, absl::nullopt)); auto& networks = result.Set("networks", base::Value::List())->GetList(); for (const auto& it : brave_wallet::GetAllChains(prefs, *coin)) { @@ -236,8 +239,9 @@ void BraveWalletHandler::OnAddChain(base::Value javascript_callback, result.Append(error == brave_wallet::mojom::ProviderError::kSuccess); result.Append(error_message); ResolveJavascriptCallback(javascript_callback, result); - if (chain_callback_for_testing_) + if (chain_callback_for_testing_) { std::move(chain_callback_for_testing_).Run(); + } } void BraveWalletHandler::AddChain(const base::Value::List& args) { @@ -279,8 +283,9 @@ void BraveWalletHandler::SetActiveNetwork(const base::Value::List& args) { auto* json_rpc_service = brave_wallet::JsonRpcServiceFactory::GetServiceForContext( Profile::FromWebUI(web_ui())); - auto result = - json_rpc_service ? json_rpc_service->SetNetwork(*chain_id, *coin) : false; + auto result = json_rpc_service ? json_rpc_service->SetNetwork( + *chain_id, *coin, absl::nullopt) + : false; ResolveJavascriptCallback(args[0], base::Value(result)); } diff --git a/components/brave_wallet/browser/brave_wallet_prefs.cc b/components/brave_wallet/browser/brave_wallet_prefs.cc index 6424e1993d30..b8e1f257e8d4 100644 --- a/components/brave_wallet/browser/brave_wallet_prefs.cc +++ b/components/brave_wallet/browser/brave_wallet_prefs.cc @@ -48,6 +48,15 @@ base::Value::Dict GetDefaultSelectedNetworks() { return selected_networks; } +base::Value::Dict GetDefaultSelectedNetworksPerOrigin() { + base::Value::Dict selected_networks; + selected_networks.Set(kEthereumPrefKey, base::Value::Dict()); + selected_networks.Set(kSolanaPrefKey, base::Value::Dict()); + selected_networks.Set(kFilecoinPrefKey, base::Value::Dict()); + + return selected_networks; +} + base::Value::Dict GetDefaultHiddenNetworks() { base::Value::Dict hidden_networks; @@ -107,6 +116,8 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { GetDefaultHiddenNetworks()); registry->RegisterDictionaryPref(kBraveWalletSelectedNetworks, GetDefaultSelectedNetworks()); + registry->RegisterDictionaryPref(kBraveWalletSelectedNetworksPerOrigin, + GetDefaultSelectedNetworksPerOrigin()); registry->RegisterDictionaryPref(kBraveWalletUserAssets, GetDefaultUserAssets()); registry->RegisterIntegerPref(kBraveWalletAutoLockMinutes, 5); @@ -198,6 +209,7 @@ void ClearJsonRpcServiceProfilePrefs(PrefService* prefs) { prefs->ClearPref(kBraveWalletCustomNetworks); prefs->ClearPref(kBraveWalletHiddenNetworks); prefs->ClearPref(kBraveWalletSelectedNetworks); + prefs->ClearPref(kBraveWalletSelectedNetworksPerOrigin); prefs->ClearPref(kSupportEip1559OnLocalhostChain); } diff --git a/components/brave_wallet/browser/brave_wallet_service.cc b/components/brave_wallet/browser/brave_wallet_service.cc index a3fc64b97bf0..b00be1121e4f 100644 --- a/components/brave_wallet/browser/brave_wallet_service.cc +++ b/components/brave_wallet/browser/brave_wallet_service.cc @@ -707,6 +707,32 @@ void BraveWalletService::SetSelectedCoin(mojom::CoinType coin) { ::brave_wallet::SetSelectedCoin(profile_prefs_, coin); } +void BraveWalletService::GetChainIdForActiveOrigin( + mojom::CoinType coin, + GetChainIdForActiveOriginCallback callback) { + GetActiveOrigin(base::BindOnce( + [](mojom::CoinType coin, GetChainIdForActiveOriginCallback callback, + JsonRpcService* json_rpc_service, mojom::OriginInfoPtr origin_info) { + std::move(callback).Run( + json_rpc_service->GetChainId(coin, origin_info->origin)); + }, + coin, std::move(callback), json_rpc_service_)); +} + +void BraveWalletService::SetChainIdForActiveOrigin( + mojom::CoinType coin, + const std::string& chain_id, + SetChainIdForActiveOriginCallback callback) { + GetActiveOrigin(base::BindOnce( + [](const std::string& chain_id_in, mojom::CoinType coin, + SetChainIdForActiveOriginCallback callback, + JsonRpcService* json_rpc_service, mojom::OriginInfoPtr origin_info) { + std::move(callback).Run(json_rpc_service->SetNetwork( + chain_id_in, coin, origin_info->origin)); + }, + chain_id, coin, std::move(callback), json_rpc_service_)); +} + void BraveWalletService::OnDefaultEthereumWalletChanged() { auto default_wallet = ::brave_wallet::GetDefaultEthereumWallet(profile_prefs_); @@ -1439,8 +1465,6 @@ void BraveWalletService::GetPendingDecryptRequests( void BraveWalletService::NotifyAddSuggestTokenRequestsProcessed( bool approved, const std::vector& contract_addresses) { - const std::string chain_id = - GetCurrentChainId(profile_prefs_, mojom::CoinType::ETH); for (const auto& addr : contract_addresses) { if (add_suggest_token_requests_.contains(addr) && add_suggest_token_callbacks_.contains(addr) && diff --git a/components/brave_wallet/browser/brave_wallet_service.h b/components/brave_wallet/browser/brave_wallet_service.h index 5d6b0eb12be7..d29dd3bd1e63 100644 --- a/components/brave_wallet/browser/brave_wallet_service.h +++ b/components/brave_wallet/browser/brave_wallet_service.h @@ -147,6 +147,13 @@ class BraveWalletService : public KeyedService, void SetDefaultBaseCryptocurrency(const std::string& cryptocurrency) override; void GetSelectedCoin(GetSelectedCoinCallback callback) override; void SetSelectedCoin(mojom::CoinType coin) override; + void GetChainIdForActiveOrigin( + mojom::CoinType coin, + GetChainIdForActiveOriginCallback callback) override; + void SetChainIdForActiveOrigin( + mojom::CoinType coin, + const std::string& chain_id, + SetChainIdForActiveOriginCallback callback) override; void AddPermission(mojom::CoinType coin, const url::Origin& origin, const std::string& account, diff --git a/components/brave_wallet/browser/brave_wallet_utils.cc b/components/brave_wallet/browser/brave_wallet_utils.cc index 191598f14850..a425b04cac98 100644 --- a/components/brave_wallet/browser/brave_wallet_utils.cc +++ b/components/brave_wallet/browser/brave_wallet_utils.cc @@ -502,6 +502,17 @@ std::vector MergeKnownAndCustomChains( return result; } +std::string GetCurrentChainId(PrefService* prefs, mojom::CoinType coin) { + const auto& selected_networks = prefs->GetDict(kBraveWalletSelectedNetworks); + const std::string* chain_id = + selected_networks.FindString(GetPrefKeyForCoinType(coin)); + if (!chain_id) { + return std::string(); + } + + return base::ToLowerASCII(*chain_id); +} + } // namespace GURL AddInfuraProjectId(const GURL& url) { @@ -583,6 +594,9 @@ mojom::NetworkInfoPtr GetCustomChain(PrefService* prefs, mojom::NetworkInfoPtr GetChain(PrefService* prefs, const std::string& chain_id, mojom::CoinType coin) { + if (chain_id.empty()) { + return nullptr; + } if (auto custom_chain = GetCustomChain(prefs, chain_id, coin)) { return custom_chain; } @@ -1414,14 +1428,55 @@ void RemoveHiddenNetwork(PrefService* prefs, }); } -std::string GetCurrentChainId(PrefService* prefs, mojom::CoinType coin) { - const auto& selected_networks = prefs->GetDict(kBraveWalletSelectedNetworks); - const std::string* chain_id = - selected_networks.FindString(GetPrefKeyForCoinType(coin)); - if (!chain_id) - return std::string(); +std::string GetCurrentChainId(PrefService* prefs, + mojom::CoinType coin, + const absl::optional& origin) { + if (!origin) { + return GetCurrentChainId(prefs, coin); + } + const auto& selected_networks = + prefs->GetDict(kBraveWalletSelectedNetworksPerOrigin); + const auto* coin_dict = + selected_networks.FindDict(GetPrefKeyForCoinType(coin)); + if (!coin_dict) { + return GetCurrentChainId(prefs, coin); + } + const auto* chain_id_str = coin_dict->FindString(origin->Serialize()); + if (!chain_id_str) { + return GetCurrentChainId(prefs, coin); + } - return base::ToLowerASCII(*chain_id); + return base::ToLowerASCII(*chain_id_str); +} + +bool SetCurrentChainId(PrefService* prefs, + mojom::CoinType coin, + const absl::optional& origin, + const std::string& chain_id) { + // We cannot switch to an unknown chain_id + if (!KnownChainExists(chain_id, coin) && + !CustomChainExists(prefs, chain_id, coin)) { + return false; + } + if (!origin) { + ScopedDictPrefUpdate update(prefs, kBraveWalletSelectedNetworks); + update->Set(GetPrefKeyForCoinType(coin), chain_id); + } else { + if (origin->opaque()) { + return false; + } + // Only set per origin network for http/https scheme + if (origin->scheme() == url::kHttpScheme || + origin->scheme() == url::kHttpsScheme) { + ScopedDictPrefUpdate update(prefs, kBraveWalletSelectedNetworksPerOrigin); + update->EnsureDict(GetPrefKeyForCoinType(coin)) + ->Set(origin->Serialize(), chain_id); + } else { + ScopedDictPrefUpdate update(prefs, kBraveWalletSelectedNetworks); + update->Set(GetPrefKeyForCoinType(coin), chain_id); + } + } + return true; } std::string GetPrefKeyForCoinType(mojom::CoinType coin) { diff --git a/components/brave_wallet/browser/brave_wallet_utils.h b/components/brave_wallet/browser/brave_wallet_utils.h index cf0adaff551f..2f2dc09ab635 100644 --- a/components/brave_wallet/browser/brave_wallet_utils.h +++ b/components/brave_wallet/browser/brave_wallet_utils.h @@ -150,8 +150,19 @@ mojom::NetworkInfoPtr GetChain(PrefService* prefs, const std::string& chain_id, mojom::CoinType coin); -// Get the current chain ID for coin from kBraveWalletSelectedNetworks pref. -std::string GetCurrentChainId(PrefService* prefs, mojom::CoinType coin); +// Get/Set the current chain ID for coin from kBraveWalletSelectedNetworks pref +// when origin is not presetned. If origin is presented, +// kBraveWalletSelectedNetworksPerOrigin will be used. In addition, if origin is +// opaque, we will also fallback to kBraveWalletSelectedNetworks but it will be +// read only, other non http/https scheme will fallback to r/w +// kBraveWalletSelectedNetworks. +std::string GetCurrentChainId(PrefService* prefs, + mojom::CoinType coin, + const absl::optional& origin); +bool SetCurrentChainId(PrefService* prefs, + mojom::CoinType coin, + const absl::optional& origin, + const std::string& chain_id); std::string GetPrefKeyForCoinType(mojom::CoinType coin); diff --git a/components/brave_wallet/browser/brave_wallet_utils_unittest.cc b/components/brave_wallet/browser/brave_wallet_utils_unittest.cc index 7c6a8849dd92..6b1939f1c0aa 100644 --- a/components/brave_wallet/browser/brave_wallet_utils_unittest.cc +++ b/components/brave_wallet/browser/brave_wallet_utils_unittest.cc @@ -807,6 +807,8 @@ TEST(BraveWalletUtilsUnitTest, GetChain) { values.push_back(NetworkInfoToValue(chain2)); UpdateCustomNetworks(&prefs, std::move(values), mojom::CoinType::ETH); + EXPECT_FALSE(GetChain(&prefs, "", mojom::CoinType::ETH)); + EXPECT_FALSE(GetChain(&prefs, "0x123", mojom::CoinType::ETH)); EXPECT_EQ(GetChain(&prefs, "0x5566", mojom::CoinType::ETH), chain1.Clone()); EXPECT_EQ(GetChain(&prefs, "0x1", mojom::CoinType::ETH), diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index 75e47e483c11..da1a122fd4db 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -316,33 +316,13 @@ void EthereumProviderImpl::OnGetNetworkAndDefaultKeyringInfo( keyring_info->account_infos, from)) { // Set chain_id to current chain_id. tx_data_1559->chain_id = chain->chain_id; - // If the chain id is not known yet, then get it and set it first - if (tx_data_1559->chain_id == "0x0" || tx_data_1559->chain_id.empty()) { - json_rpc_service_->GetChainId( - mojom::CoinType::ETH, origin, - base::BindOnce( - &EthereumProviderImpl::ContinueAddAndApprove1559Transaction, - weak_factory_.GetWeakPtr(), std::move(callback), std::move(id), - std::move(tx_data_1559), from, origin)); - } else { - GetAllowedAccounts( - false, - base::BindOnce(&EthereumProviderImpl:: - ContinueAddAndApprove1559TransactionWithAccounts, - weak_factory_.GetWeakPtr(), std::move(callback), - std::move(id), std::move(tx_data_1559), from, origin)); - } + GetAllowedAccounts( + false, + base::BindOnce(&EthereumProviderImpl:: + ContinueAddAndApprove1559TransactionWithAccounts, + weak_factory_.GetWeakPtr(), std::move(callback), + std::move(id), std::move(tx_data_1559), from, origin)); } else { - if (!tx_data_1559) { - base::Value formed_response = GetProviderErrorDictionary( - brave_wallet::mojom::ProviderError::kInvalidParams, - l10n_util::GetStringUTF8(IDS_WALLET_ETH_SEND_TRANSACTION_NO_TX_DATA)); - reject = true; - std::move(callback).Run(std::move(id), std::move(formed_response), reject, - "", false); - return; - } - GetAllowedAccounts( false, base::BindOnce(&EthereumProviderImpl::ContinueAddAndApproveTransaction, @@ -410,22 +390,6 @@ void EthereumProviderImpl::OnAddUnapprovedTransactionAdapter( success ? "" : error_message); } -void EthereumProviderImpl::ContinueAddAndApprove1559Transaction( - RequestCallback callback, - base::Value id, - mojom::TxData1559Ptr tx_data, - const std::string& from, - const url::Origin& origin, - const std::string& chain_id) { - tx_data->chain_id = chain_id; - GetAllowedAccounts( - false, - base::BindOnce(&EthereumProviderImpl:: - ContinueAddAndApprove1559TransactionWithAccounts, - weak_factory_.GetWeakPtr(), std::move(callback), - std::move(id), std::move(tx_data), from, origin)); -} - void EthereumProviderImpl::ContinueAddAndApprove1559TransactionWithAccounts( RequestCallback callback, base::Value id, diff --git a/components/brave_wallet/browser/ethereum_provider_impl.h b/components/brave_wallet/browser/ethereum_provider_impl.h index 3d6808041b66..a64d5804e858 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.h +++ b/components/brave_wallet/browser/ethereum_provider_impl.h @@ -235,12 +235,6 @@ class EthereumProviderImpl final mojom::ProviderError error, const std::string& error_message); - void ContinueAddAndApprove1559Transaction(RequestCallback callback, - base::Value id, - mojom::TxData1559Ptr tx_data, - const std::string& from, - const url::Origin& origin, - const std::string& chain_id); void ContinueAddAndApprove1559TransactionWithAccounts( RequestCallback callback, base::Value id, diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index 8472fafff119..e7580fdd9a11 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -43,6 +43,7 @@ #include "components/grit/brave_components_strings.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" +#include "net/base/net_errors.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "third_party/re2/src/re2/re2.h" #include "ui/base/l10n/l10n_util.h" @@ -210,19 +211,6 @@ JsonRpcService::JsonRpcService( prefs_(prefs), local_state_prefs_(local_state_prefs), weak_ptr_factory_(this) { - if (!SetNetwork(GetCurrentChainId(prefs_, mojom::CoinType::ETH), - mojom::CoinType::ETH)) { - LOG(ERROR) << "Could not set network from JsonRpcService() for ETH"; - } - if (!SetNetwork(GetCurrentChainId(prefs_, mojom::CoinType::SOL), - mojom::CoinType::SOL)) { - LOG(ERROR) << "Could not set network from JsonRpcService() for SOL"; - } - if (!SetNetwork(GetCurrentChainId(prefs_, mojom::CoinType::FIL), - mojom::CoinType::FIL)) { - LOG(ERROR) << "Could not set network from JsonRpcService() for FIL"; - } - if (EnsL2FeatureEnabled()) { api_request_helper_ens_offchain_ = std::make_unique( GetENSOffchainNetworkTrafficAnnotationTag(), url_loader_factory); @@ -357,7 +345,11 @@ void JsonRpcService::RequestInternal( RequestIntermediateCallback callback, APIRequestHelper::ResponseConversionCallback conversion_callback = base::NullCallback()) { - DCHECK(network_url.is_valid()); + if (!network_url.is_valid()) { + std::move(callback).Run( + APIRequestResult(400, {}, {}, {}, net::ERR_UNEXPECTED, GURL())); + return; + } api_request_helper_->Request("POST", network_url, json_payload, "application/json", auto_retry_on_network_change, @@ -563,19 +555,14 @@ void JsonRpcService::RemoveChain(const std::string& chain_id, bool JsonRpcService::SetNetwork(const std::string& chain_id, mojom::CoinType coin, + const absl::optional& origin, bool silent) { - auto network_url = GetNetworkURL(prefs_, chain_id, coin); - if (!network_url.is_valid()) { + if (!SetCurrentChainId(prefs_, coin, origin, chain_id)) { return false; } - chain_ids_[coin] = chain_id; - network_urls_[coin] = network_url; - ScopedDictPrefUpdate update(prefs_, kBraveWalletSelectedNetworks); - update->Set(GetPrefKeyForCoinType(coin), chain_id); - if (!silent) { - FireNetworkChanged(coin); + FireNetworkChanged(coin, origin); } if (coin == mojom::CoinType::ETH) { MaybeUpdateIsEip1559(chain_id); @@ -585,8 +572,9 @@ bool JsonRpcService::SetNetwork(const std::string& chain_id, void JsonRpcService::SetNetwork(const std::string& chain_id, mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, SetNetworkCallback callback) { - if (!SetNetwork(chain_id, coin)) { + if (!SetNetwork(chain_id, coin, origin)) { std::move(callback).Run(false); } else { std::move(callback).Run(true); @@ -594,12 +582,10 @@ void JsonRpcService::SetNetwork(const std::string& chain_id, } void JsonRpcService::GetNetwork(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, GetNetworkCallback callback) { - if (!chain_ids_.contains(coin)) { - std::move(callback).Run(nullptr); - } else { - std::move(callback).Run(GetChain(prefs_, chain_ids_[coin], coin)); - } + const auto& chain_id = GetChainId(coin, origin); + std::move(callback).Run(GetChain(prefs_, chain_id, coin)); } void JsonRpcService::MaybeUpdateIsEip1559(const std::string& chain_id) { @@ -659,26 +645,25 @@ void JsonRpcService::UpdateIsEip1559(const std::string& chain_id, } } -void JsonRpcService::FireNetworkChanged(mojom::CoinType coin) { +void JsonRpcService::FireNetworkChanged( + mojom::CoinType coin, + const absl::optional& origin) { for (const auto& observer : observers_) { - observer->ChainChangedEvent(GetChainId(coin), coin); + observer->ChainChangedEvent(GetChainId(coin, origin), coin); } } -std::string JsonRpcService::GetChainId(mojom::CoinType coin) const { - return chain_ids_.contains(coin) ? chain_ids_.at(coin) : std::string(); +std::string JsonRpcService::GetChainId( + mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) const { + return GetCurrentChainId(prefs_, coin, origin); } void JsonRpcService::GetChainId( mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, mojom::JsonRpcService::GetChainIdCallback callback) { - std::move(callback).Run(GetChainId(coin)); -} - -void JsonRpcService::GetBlockTrackerUrl( - mojom::JsonRpcService::GetBlockTrackerUrlCallback callback) { - std::move(callback).Run( - GetBlockTrackerUrlFromNetwork(GetChainId(mojom::CoinType::ETH)).spec()); + std::move(callback).Run(GetChainId(coin, origin)); } void JsonRpcService::GetAllNetworks(mojom::CoinType coin, @@ -710,28 +695,26 @@ void JsonRpcService::GetHiddenNetworks(mojom::CoinType coin, // Currently selected chain is never hidden for coin. base::Erase(hidden_networks, - base::ToLowerASCII(GetCurrentChainId(prefs_, coin))); + base::ToLowerASCII(GetChainId(coin, absl::nullopt))); std::move(callback).Run(hidden_networks); } -std::string JsonRpcService::GetNetworkUrl(mojom::CoinType coin) const { - return network_urls_.contains(coin) ? network_urls_.at(coin).spec() - : std::string(); +std::string JsonRpcService::GetNetworkUrl( + mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) const { + auto network_url = GetNetworkURL(prefs_, GetChainId(coin, origin), coin); + if (!network_url.is_valid()) { + return std::string(); + } + return network_url.spec(); } void JsonRpcService::GetNetworkUrl( mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, mojom::JsonRpcService::GetNetworkUrlCallback callback) { - std::move(callback).Run(GetNetworkUrl(coin)); -} - -void JsonRpcService::SetCustomNetworkForTesting(const std::string& chain_id, - mojom::CoinType coin, - const GURL& network_url) { - chain_ids_[coin] = chain_id; - network_urls_[coin] = network_url; - FireNetworkChanged(coin); + std::move(callback).Run(GetNetworkUrl(coin, origin)); } void JsonRpcService::GetBlockNumber(const std::string& chain_id, @@ -1971,16 +1954,6 @@ void JsonRpcService::OnUnstoppableDomainsGetWalletAddr( ud_get_eth_addr_calls_.SetNoResult(key, chain_id); } -GURL JsonRpcService::GetBlockTrackerUrlFromNetwork( - const std::string& chain_id) { - if (auto network = GetChain(prefs_, chain_id, mojom::CoinType::ETH)) { - if (network->block_explorer_urls.size()) { - return GURL(network->block_explorer_urls.front()); - } - } - return GURL(); -} - void JsonRpcService::GetFilEstimateGas(const std::string& chain_id, const std::string& from_address, const std::string& to_address, @@ -2493,7 +2466,6 @@ void JsonRpcService::GetSupportsInterface( auto internal_callback = base::BindOnce(&JsonRpcService::OnGetSupportsInterface, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); - DCHECK(network_urls_.contains(mojom::CoinType::ETH)); RequestInternal(eth::eth_call("", contract_address, "", "", "", data, kEthereumBlockTagLatest), true, network_url, std::move(internal_callback)); @@ -2609,7 +2581,8 @@ void JsonRpcService::NotifySwitchChainRequestProcessed( // JsonRpcService::AddSwitchEthereumChainRequest so this should always // be successful unless chain id differs or we add more check other than // chain id - CHECK(SetNetwork(switch_chain_requests_[origin], mojom::CoinType::ETH)); + CHECK(SetNetwork(switch_chain_requests_[origin], mojom::CoinType::ETH, + origin)); } auto callback = std::move(switch_chain_callbacks_[origin]); base::Value id = std::move(switch_chain_ids_[origin]); @@ -2648,7 +2621,7 @@ bool JsonRpcService::AddSwitchEthereumChainRequest(const std::string& chain_id, } // Already on the chain - if (GetChainId(mojom::CoinType::ETH) == chain_id) { + if (GetChainId(mojom::CoinType::ETH, origin) == chain_id) { reject = false; std::move(callback).Run(std::move(id), base::Value(), reject, "", false); return false; @@ -2672,8 +2645,6 @@ bool JsonRpcService::AddSwitchEthereumChainRequest(const std::string& chain_id, void JsonRpcService::Reset() { ClearJsonRpcServiceProfilePrefs(prefs_); - SetNetwork(GetCurrentChainId(prefs_, mojom::CoinType::ETH), - mojom::CoinType::ETH); add_chain_pending_requests_.clear(); switch_chain_requests_.clear(); @@ -3112,9 +3083,11 @@ void JsonRpcService::GetSolanaTokenAccountsByOwner( auto internal_callback = base::BindOnce(&JsonRpcService::OnGetSolanaTokenAccountsByOwner, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + // TODO(darkdh): bug, this only works on mainnet currently RequestInternal( solana::getTokenAccountsByOwner(pubkey.ToBase58()), true, - network_urls_[mojom::CoinType::SOL], std::move(internal_callback), + GetNetworkURL(prefs_, mojom::kSolanaMainnet, mojom::CoinType::SOL), + std::move(internal_callback), base::BindOnce(&ConvertMultiUint64InObjectArrayToString, "/result/value", "/account", std::vector({"lamports", "rentEpoch"}))); diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 397178be6d31..9054f2b1e5e7 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -7,6 +7,7 @@ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_JSON_RPC_SERVICE_H_ #include +#include #include #include #include @@ -223,11 +224,15 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { bool SetNetwork(const std::string& chain_id, mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, bool silent = false); void SetNetwork(const std::string& chain_id, mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, SetNetworkCallback callback) override; - void GetNetwork(mojom::CoinType coin, GetNetworkCallback callback) override; + void GetNetwork(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, + GetNetworkCallback callback) override; void AddChain(mojom::NetworkInfoPtr chain, AddChainCallback callback) override; void AddEthereumChainForOrigin( @@ -240,11 +245,11 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { mojom::CoinType coin, RemoveChainCallback callback) override; - std::string GetChainId(mojom::CoinType coin) const; + std::string GetChainId(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) const; void GetChainId(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, mojom::JsonRpcService::GetChainIdCallback callback) override; - void GetBlockTrackerUrl( - mojom::JsonRpcService::GetBlockTrackerUrlCallback callback) override; void GetPendingAddChainRequests( GetPendingAddChainRequestsCallback callback) override; void GetPendingSwitchChainRequests( @@ -259,18 +264,16 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { GetKnownNetworksCallback callback) override; void GetHiddenNetworks(mojom::CoinType coin, GetHiddenNetworksCallback callback) override; - std::string GetNetworkUrl(mojom::CoinType coin) const; + std::string GetNetworkUrl(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) const; void GetNetworkUrl( mojom::CoinType coin, + const absl::optional<::url::Origin>& origin, mojom::JsonRpcService::GetNetworkUrlCallback callback) override; - void SetCustomNetworkForTesting(const std::string& chain_id, - mojom::CoinType coin, - const GURL& provider_url) override; void AddObserver( ::mojo::PendingRemote observer) override; - GURL GetBlockTrackerUrlFromNetwork(const std::string& chain_id); using GetFilEstimateGasCallback = base::OnceCallback& origin); void FirePendingRequestCompleted(const std::string& chain_id, const std::string& error); bool HasRequestFromOrigin(const url::Origin& origin) const; @@ -637,11 +641,6 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { scoped_refptr url_loader_factory_; std::unique_ptr api_request_helper_; std::unique_ptr api_request_helper_ens_offchain_; - // TODO(darkdh): base::flat_map> - // and replace all GetNetworkURL usages - base::flat_map network_urls_; - // - base::flat_map chain_ids_; // base::flat_map add_chain_pending_requests_; diff --git a/components/brave_wallet/browser/keyring_service.cc b/components/brave_wallet/browser/keyring_service.cc index d541f1cc469c..45ce5cbb17a1 100644 --- a/components/brave_wallet/browser/keyring_service.cc +++ b/components/brave_wallet/browser/keyring_service.cc @@ -764,7 +764,7 @@ void KeyringService::MaybeCreateDefaultSolanaAccount() { // This is needed for Android to select default coin, because they listen // to network change events. json_rpc_service_->SetNetwork(brave_wallet::mojom::kSolanaMainnet, - mojom::CoinType::SOL, false); + mojom::CoinType::SOL, absl::nullopt, false); NotifyAccountsAdded(mojom::CoinType::SOL, {address.value()}); } @@ -1284,7 +1284,7 @@ bool KeyringService::SetSelectedAccountForCoinSilently( json_rpc_service_->SetNetwork(keyring_id == mojom::kFilecoinKeyringId ? mojom::kFilecoinMainnet : mojom::kFilecoinTestnet, - coin, true /* silent */); + coin, absl::nullopt, true /* silent */); } return true; } diff --git a/components/brave_wallet/browser/pref_names.cc b/components/brave_wallet/browser/pref_names.cc index f1599d6f2e5b..6cc18c975b98 100644 --- a/components/brave_wallet/browser/pref_names.cc +++ b/components/brave_wallet/browser/pref_names.cc @@ -31,6 +31,8 @@ const char kBraveWalletP3AActiveWalletDict[] = const char kBraveWalletCustomNetworks[] = "brave.wallet.custom_networks"; const char kBraveWalletHiddenNetworks[] = "brave.wallet.hidden_networks"; const char kBraveWalletSelectedNetworks[] = "brave.wallet.selected_networks"; +const char kBraveWalletSelectedNetworksPerOrigin[] = + "brave.wallet.selected_networks_origin"; const char kBraveWalletKeyrings[] = "brave.wallet.keyrings"; const char kBraveWalletUserAssets[] = "brave.wallet.wallet_user_assets"; const char kBraveWalletUserAssetEthContractAddressMigrated[] = diff --git a/components/brave_wallet/browser/pref_names.h b/components/brave_wallet/browser/pref_names.h index 23a81c3a2307..b1c5fc53b365 100644 --- a/components/brave_wallet/browser/pref_names.h +++ b/components/brave_wallet/browser/pref_names.h @@ -23,6 +23,7 @@ extern const char kBraveWalletKeyrings[]; extern const char kBraveWalletCustomNetworks[]; extern const char kBraveWalletHiddenNetworks[]; extern const char kBraveWalletSelectedNetworks[]; +extern const char kBraveWalletSelectedNetworksPerOrigin[]; extern const char kBraveWalletUserAssets[]; // Added 10/2021 to migrate contract address to an empty string for ETH. extern const char kBraveWalletUserAssetEthContractAddressMigrated[]; diff --git a/components/brave_wallet/browser/swap_service.cc b/components/brave_wallet/browser/swap_service.cc index e74b87df3b13..c00636bd8a03 100644 --- a/components/brave_wallet/browser/swap_service.cc +++ b/components/brave_wallet/browser/swap_service.cc @@ -97,29 +97,37 @@ GURL Append0xSwapParams(const GURL& swap_url, const brave_wallet::mojom::SwapParams& params, const std::string& chain_id) { GURL url = swap_url; - if (!params.taker_address.empty()) + if (!params.taker_address.empty()) { url = net::AppendQueryParameter(url, "takerAddress", params.taker_address); - if (!params.sell_amount.empty()) + } + if (!params.sell_amount.empty()) { url = net::AppendQueryParameter(url, "sellAmount", params.sell_amount); - if (!params.buy_amount.empty()) + } + if (!params.buy_amount.empty()) { url = net::AppendQueryParameter(url, "buyAmount", params.buy_amount); - if (!params.buy_token.empty()) + } + if (!params.buy_token.empty()) { url = net::AppendQueryParameter(url, "buyToken", params.buy_token); - if (!params.sell_token.empty()) + } + if (!params.sell_token.empty()) { url = net::AppendQueryParameter(url, "sellToken", params.sell_token); + } url = net::AppendQueryParameter(url, "buyTokenPercentageFee", GetFee(chain_id)); url = net::AppendQueryParameter( url, "slippagePercentage", base::StringPrintf("%.6f", params.slippage_percentage)); std::string fee_recipient = GetFeeRecipient(chain_id); - if (!fee_recipient.empty()) + if (!fee_recipient.empty()) { url = net::AppendQueryParameter(url, "feeRecipient", fee_recipient); + } std::string affiliate_address = GetAffiliateAddress(chain_id); - if (!affiliate_address.empty()) + if (!affiliate_address.empty()) { url = net::AppendQueryParameter(url, "affiliateAddress", affiliate_address); - if (!params.gas_price.empty()) + } + if (!params.gas_price.empty()) { url = net::AppendQueryParameter(url, "gasPrice", params.gas_price); + } return url; } @@ -128,12 +136,15 @@ GURL AppendJupiterQuoteParams( const brave_wallet::mojom::JupiterQuoteParams& params, const std::string& chain_id) { GURL url = swap_url; - if (!params.input_mint.empty()) + if (!params.input_mint.empty()) { url = net::AppendQueryParameter(url, "inputMint", params.input_mint); - if (!params.output_mint.empty()) + } + if (!params.output_mint.empty()) { url = net::AppendQueryParameter(url, "outputMint", params.output_mint); - if (!params.amount.empty()) + } + if (!params.amount.empty()) { url = net::AppendQueryParameter(url, "amount", params.amount); + } if (brave_wallet::HasJupiterFeesForTokenMint(params.output_mint)) { url = net::AppendQueryParameter(url, "feeBps", GetFee(chain_id)); @@ -293,7 +304,7 @@ void SwapService::IsSwapSupported(const std::string& chain_id, void SwapService::GetPriceQuote(mojom::SwapParamsPtr swap_params, GetPriceQuoteCallback callback) { if (!IsEVMNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::ETH))) { + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -305,8 +316,9 @@ void SwapService::GetPriceQuote(mojom::SwapParamsPtr swap_params, api_request_helper_.Request( net::HttpRequestHeaders::kGetMethod, - GetPriceQuoteURL(std::move(swap_params), - json_rpc_service_->GetChainId(mojom::CoinType::ETH)), + GetPriceQuoteURL( + std::move(swap_params), + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt)), "", "", true, std::move(internal_callback), Get0xAPIHeaders()); } @@ -336,7 +348,7 @@ void SwapService::GetTransactionPayload( mojom::SwapParamsPtr swap_params, GetTransactionPayloadCallback callback) { if (!IsEVMNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::ETH))) { + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -350,7 +362,7 @@ void SwapService::GetTransactionPayload( net::HttpRequestHeaders::kGetMethod, GetTransactionPayloadURL( std::move(swap_params), - json_rpc_service_->GetChainId(mojom::CoinType::ETH)), + json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt)), "", "", true, std::move(internal_callback), Get0xAPIHeaders()); } @@ -381,7 +393,7 @@ void SwapService::OnGetTransactionPayload( void SwapService::GetJupiterQuote(mojom::JupiterQuoteParamsPtr params, GetJupiterQuoteCallback callback) { if (!IsSolanaNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::SOL))) { + json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -397,8 +409,9 @@ void SwapService::GetJupiterQuote(mojom::JupiterQuoteParamsPtr params, base::flat_map request_headers; api_request_helper_.Request( net::HttpRequestHeaders::kGetMethod, - GetJupiterQuoteURL(std::move(params), - json_rpc_service_->GetChainId(mojom::CoinType::SOL)), + GetJupiterQuoteURL( + std::move(params), + json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt)), "", "", true, std::move(internal_callback), request_headers, -1u, std::move(conversion_callback)); } @@ -428,7 +441,7 @@ void SwapService::GetJupiterSwapTransactions( mojom::JupiterSwapParamsPtr params, GetJupiterSwapTransactionsCallback callback) { if (!IsSolanaNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::SOL))) { + json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -449,7 +462,7 @@ void SwapService::GetJupiterSwapTransactions( api_request_helper_.Request( "POST", GetJupiterSwapTransactionsURL( - json_rpc_service_->GetChainId(mojom::CoinType::SOL)), + json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt)), *encoded_params, "application/json", true, std::move(internal_callback)); } diff --git a/components/brave_wallet/browser/tx_service.cc b/components/brave_wallet/browser/tx_service.cc index c220122aa7df..6314bbb47dce 100644 --- a/components/brave_wallet/browser/tx_service.cc +++ b/components/brave_wallet/browser/tx_service.cc @@ -10,6 +10,7 @@ #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" #include "brave/components/brave_wallet/browser/eth_tx_manager.h" #include "brave/components/brave_wallet/browser/fil_tx_manager.h" +#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/solana_tx_manager.h" #include "brave/components/brave_wallet/browser/tx_manager.h" #include "url/origin.h" @@ -45,7 +46,7 @@ size_t CalculatePendingTxCount( TxService::TxService(JsonRpcService* json_rpc_service, KeyringService* keyring_service, PrefService* prefs) - : prefs_(prefs), weak_factory_(this) { + : prefs_(prefs), json_rpc_service_(json_rpc_service), weak_factory_(this) { tx_manager_map_[mojom::CoinType::ETH] = std::unique_ptr( new EthTxManager(this, json_rpc_service, keyring_service, prefs)); tx_manager_map_[mojom::CoinType::SOL] = std::unique_ptr( @@ -130,6 +131,7 @@ void TxService::AddUnapprovedTransaction( auto coin_type = GetCoinTypeFromTxDataUnion(*tx_data_union); GetTxManager(coin_type)->AddUnapprovedTransaction( + json_rpc_service_->GetChainId(coin_type, origin), std::move(tx_data_union), from, origin, group_id, std::move(callback)); } diff --git a/components/brave_wallet/browser/tx_service.h b/components/brave_wallet/browser/tx_service.h index 849bf2d066b0..6ac9fadb5b76 100644 --- a/components/brave_wallet/browser/tx_service.h +++ b/components/brave_wallet/browser/tx_service.h @@ -220,6 +220,7 @@ class TxService : public KeyedService, FilTxManager* GetFilTxManager(); raw_ptr prefs_; // NOT OWNED + raw_ptr json_rpc_service_ = nullptr; base::flat_map> tx_manager_map_; mojo::RemoteSet observers_; mojo::ReceiverSet tx_service_receivers_; diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 70f5dea98431..0f9e89b343d7 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -1071,21 +1071,20 @@ interface JsonRpcService { NotifySwitchChainRequestProcessed(bool approved, url.mojom.Origin origin); GetPendingSwitchChainRequests() => (array requests); - SetNetwork(string chain_id, CoinType coin) => (bool success); - GetNetwork(CoinType coin) => (NetworkInfo network); + SetNetwork(string chain_id, CoinType coin, url.mojom.Origin? origin) + => (bool success); + GetNetwork(CoinType coin, url.mojom.Origin? origin) => (NetworkInfo network); GetAllNetworks(CoinType coin) => (array networks); GetCustomNetworks(CoinType coin) => (array chain_ids); GetKnownNetworks(CoinType coin) => (array chain_ids); GetHiddenNetworks(CoinType coin) => (array chain_ids); // Obtains the current network's chain ID - GetChainId(CoinType coin) => (string chain_id); - - // Obtains the current network's block tracker URL - GetBlockTrackerUrl() => (string block_tracker_url); + GetChainId(CoinType coin, url.mojom.Origin? origin) => (string chain_id); // Obtains the current network's URL - GetNetworkUrl(CoinType coin) => (string network_url); + GetNetworkUrl(CoinType coin, url.mojom.Origin? origin) + => (string network_url); // Obtains the native balance (e.g. ETH for Ethereum) for the address GetBalance(string address, CoinType coin, string chain_id) => (string balance, ProviderError error, string error_message); @@ -1163,9 +1162,6 @@ interface JsonRpcService { // Adds an observer for the events of JsonRpcService AddObserver(pending_remote observer); - // Sets a custom network for testing - SetCustomNetworkForTesting(string chain_id, CoinType coin, url.mojom.Url provider_url); - // Obtains the owner of a contract's ERC721 token ID GetERC721OwnerOf(string contract, string token_id, string chain_id) => (string owner_address, ProviderError error, string error_message); @@ -1553,6 +1549,11 @@ interface BraveWalletService { GetSelectedCoin() => (CoinType coin); SetSelectedCoin(CoinType coin); + // These will automatically fetch active origin for caller to set/get + // chain_id properly according to the origin. + GetChainIdForActiveOrigin(CoinType coin) => (string chain_id); + SetChainIdForActiveOrigin(CoinType coin, string chain_id) => (bool success); + // Adds the permission of coin type for the account AddPermission(CoinType coin, url.mojom.Origin origin, string account) => (bool success); From 9d3b4fb4cf74206929c6f2d4ba1863d66df628ca Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Thu, 6 Apr 2023 13:48:57 -0700 Subject: [PATCH 03/15] Propagate origin for ChainChangedEvent It's used to filter out unwanted origin events, ex. dapp on origin A should not be notified when network changed on origin B. --- .../brave_wallet/browser/ethereum_provider_impl.cc | 10 ++++++++-- .../brave_wallet/browser/ethereum_provider_impl.h | 3 ++- components/brave_wallet/browser/json_rpc_service.cc | 5 +++-- components/brave_wallet/browser/json_rpc_service.h | 1 + components/brave_wallet/common/brave_wallet.mojom | 2 +- .../brave_wallet_ui/common/constants/action_types.ts | 2 ++ components/brave_wallet_ui/common/wallet_api_proxy.ts | 6 ++++-- 7 files changed, 21 insertions(+), 8 deletions(-) diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index da1a122fd4db..6a15ef50a11d 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -1555,12 +1555,18 @@ void EthereumProviderImpl::Init( } } -void EthereumProviderImpl::ChainChangedEvent(const std::string& chain_id, - mojom::CoinType coin) { +void EthereumProviderImpl::ChainChangedEvent( + const std::string& chain_id, + mojom::CoinType coin, + const absl::optional& origin) { if (!events_listener_.is_bound() || coin != mojom::CoinType::ETH) { return; } + if (origin.has_value() && *origin != delegate_->GetOrigin()) { + return; + } + events_listener_->ChainChangedEvent(chain_id); } diff --git a/components/brave_wallet/browser/ethereum_provider_impl.h b/components/brave_wallet/browser/ethereum_provider_impl.h index a64d5804e858..1bdd668d78f6 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.h +++ b/components/brave_wallet/browser/ethereum_provider_impl.h @@ -191,7 +191,8 @@ class EthereumProviderImpl final // mojom::JsonRpcServiceObserver void ChainChangedEvent(const std::string& chain_id, - mojom::CoinType coin) override; + mojom::CoinType coin, + const absl::optional& origin) override; void OnAddEthereumChainRequestCompleted(const std::string& chain_id, const std::string& error) override; void OnIsEip1559Changed(const std::string& chain_id, diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index e7580fdd9a11..e155520cc255 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -562,7 +562,7 @@ bool JsonRpcService::SetNetwork(const std::string& chain_id, } if (!silent) { - FireNetworkChanged(coin, origin); + FireNetworkChanged(coin, chain_id, origin); } if (coin == mojom::CoinType::ETH) { MaybeUpdateIsEip1559(chain_id); @@ -647,9 +647,10 @@ void JsonRpcService::UpdateIsEip1559(const std::string& chain_id, void JsonRpcService::FireNetworkChanged( mojom::CoinType coin, + const std::string& chain_id, const absl::optional& origin) { for (const auto& observer : observers_) { - observer->ChainChangedEvent(GetChainId(coin, origin), coin); + observer->ChainChangedEvent(chain_id, coin, origin); } } diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 9054f2b1e5e7..d770dc7f0c29 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -483,6 +483,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { private: void FireNetworkChanged(mojom::CoinType coin, + const std::string& chain_id, const absl::optional& origin); void FirePendingRequestCompleted(const std::string& chain_id, const std::string& error); diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 0f9e89b343d7..d2b0ebf3acc6 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -905,7 +905,7 @@ interface IpfsService { interface JsonRpcServiceObserver { // Fired when the selected network changes - ChainChangedEvent(string chain_id, CoinType coin); + ChainChangedEvent(string chain_id, CoinType coin, url.mojom.Origin? origin); // Fired when a wallet_addEthereumChain request is completed OnAddEthereumChainRequestCompleted(string chain_id, string error); diff --git a/components/brave_wallet_ui/common/constants/action_types.ts b/components/brave_wallet_ui/common/constants/action_types.ts index 5a824f1aca4f..d2f170fa9e55 100644 --- a/components/brave_wallet_ui/common/constants/action_types.ts +++ b/components/brave_wallet_ui/common/constants/action_types.ts @@ -5,6 +5,7 @@ import { BraveWallet, + Origin, SerializableOrigin, SerializableTransactionInfo, SlippagePresetObjectType, @@ -19,6 +20,7 @@ export type UnlockWalletPayloadType = { export type ChainChangedEventPayloadType = { chainId: string coin: BraveWallet.CoinType + origin?: Origin } export type SelectedAccountChangedPayloadType = { diff --git a/components/brave_wallet_ui/common/wallet_api_proxy.ts b/components/brave_wallet_ui/common/wallet_api_proxy.ts index 6f033f8acd66..42fb9bca8707 100644 --- a/components/brave_wallet_ui/common/wallet_api_proxy.ts +++ b/components/brave_wallet_ui/common/wallet_api_proxy.ts @@ -32,8 +32,10 @@ export class WalletApiProxy { addJsonRpcServiceObserver (store: Store) { const jsonRpcServiceObserverReceiver = new BraveWallet.JsonRpcServiceObserverReceiver({ - chainChangedEvent: function (chainId, coin) { - store.dispatch(WalletActions.chainChangedEvent({ chainId, coin })) + chainChangedEvent: function (chainId, coin, origin) { + store.dispatch( + WalletActions.chainChangedEvent({ + chainId, coin, origin: !!origin ? origin : undefined})) }, onAddEthereumChainRequestCompleted: function (chainId, error) { // TODO: Handle this event. From 658aae34b3f73668dd21df313762d42c1fceb0e6 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Wed, 29 Mar 2023 11:17:49 -0700 Subject: [PATCH 04/15] Update desktop UI --- .../common/async/__mocks__/bridge.ts | 16 ++- .../brave_wallet_ui/common/async/handlers.ts | 44 +++++-- .../common/async/hardware.test.ts | 29 +++-- .../brave_wallet_ui/common/async/hardware.ts | 36 +++-- .../brave_wallet_ui/common/async/lib.ts | 38 ++++-- .../common/constants/action_types.ts | 4 + .../common/hooks/use-pending-transaction.ts | 1 + .../common/slices/api.slice.ts | 123 ++++++++++++------ .../common/wallet_api_proxy.ts | 2 +- .../portfolio-transaction-item/index.tsx | 3 + .../advanced-transaction-settings/index.tsx | 3 + .../confirm-transaction-panel.tsx | 1 + .../confirm-transaction-panel/swap.tsx | 1 + .../extension/edit-gas/edit-gas.tsx | 3 + .../page/screens/swap/adapters.ts | 4 +- .../panel/async/wallet_panel_async_handler.ts | 3 +- .../brave_wallet_ui/panel/container.tsx | 3 + 17 files changed, 220 insertions(+), 94 deletions(-) diff --git a/components/brave_wallet_ui/common/async/__mocks__/bridge.ts b/components/brave_wallet_ui/common/async/__mocks__/bridge.ts index e8f3dd282959..ecf21f4d868f 100644 --- a/components/brave_wallet_ui/common/async/__mocks__/bridge.ts +++ b/components/brave_wallet_ui/common/async/__mocks__/bridge.ts @@ -161,7 +161,21 @@ export class MockedWalletApiProxy { }), setDefaultBaseCurrency: async (currency: string) => { this.defaultBaseCurrency = currency - } + }, + getActiveOrigin: async () => { + return { + originInfo: { + origin: { + scheme: 'https', + host: 'brave.com', + port: 443, + nonceIfOpaque: undefined + }, + originSpec: 'https://brave.com', + eTldPlusOne: 'brave.com' + } + } + }, } swapService: Partial> = diff --git a/components/brave_wallet_ui/common/async/handlers.ts b/components/brave_wallet_ui/common/async/handlers.ts index 16c4b73a0143..a53f091fa328 100644 --- a/components/brave_wallet_ui/common/async/handlers.ts +++ b/components/brave_wallet_ui/common/async/handlers.ts @@ -136,7 +136,7 @@ async function updateCoinAccountNetworkInfo (store: Store, coin: BraveWallet.Coi if (accounts.length === 0) { return } - const { keyringService, jsonRpcService } = getAPIProxy() + const { braveWalletService, keyringService } = getAPIProxy() // Update Selected Coin & cached selected network await store @@ -148,7 +148,7 @@ async function updateCoinAccountNetworkInfo (store: Store, coin: BraveWallet.Coi coin === BraveWallet.CoinType.FIL ? await keyringService.getFilecoinSelectedAccount( ( - await jsonRpcService.getChainId(coin) + await braveWalletService.getChainIdForActiveOrigin(coin) ).chainId ) : await keyringService.getSelectedAccount(coin) @@ -435,8 +435,18 @@ handler.on(WalletActions.sendTransaction.type, async ( }) handler.on(WalletActions.sendSPLTransfer.type, async (store: Store, payload: SPLTransferFromParams) => { - const { solanaTxManagerProxy } = getAPIProxy() - const value = await solanaTxManagerProxy.makeTokenProgramTransferTxData(payload.splTokenMintAddress, payload.from, payload.to, BigInt(payload.value)) + const { braveWalletService, + jsonRpcService, + solanaTxManagerProxy + } = getAPIProxy() + const { originInfo } = await braveWalletService.getActiveOrigin() + const { network } = await jsonRpcService.getNetwork( + BraveWallet.CoinType.SOL, originInfo.origin) + const value = await solanaTxManagerProxy.makeTokenProgramTransferTxData( + network.chainId, + payload.splTokenMintAddress, + payload.from, payload.to, + BigInt(payload.value)) if (!value.txData) { console.log('Failed making SPL transfer data, to: ', payload.to, ', value: ', payload.value) return @@ -513,7 +523,8 @@ handler.on(WalletActions.approveTransaction.type, async (store: Store, txInfo: B const api = getAPIProxy() const { txService, braveWalletP3A } = api const coin = getCoinFromTxDataUnion(txInfo.txDataUnion) - const result = await txService.approveTransaction(coin, txInfo.id) + const result = await txService.approveTransaction(coin, + txInfo.chainId, txInfo.id) const error = result.errorUnion.providerError ?? result.errorUnion.solanaProviderError ?? result.errorUnion.filecoinProviderError if (error !== BraveWallet.ProviderError.kSuccess) { await store.dispatch(WalletActions.setTransactionProviderError({ @@ -536,7 +547,7 @@ handler.on(WalletActions.approveTransaction.type, async (store: Store, txInfo: B handler.on(WalletActions.rejectTransaction.type, async (store: Store, txInfo: BraveWallet.TransactionInfo) => { const apiProxy = getAPIProxy() const coin = getCoinFromTxDataUnion(txInfo.txDataUnion) - await apiProxy.txService.rejectTransaction(coin, txInfo.id) + await apiProxy.txService.rejectTransaction(coin, txInfo.chainId, txInfo.id) await store.dispatch(refreshTransactionHistory(txInfo.fromAddress)) }) @@ -545,7 +556,8 @@ handler.on(WalletActions.rejectAllTransactions.type, async (store) => { const apiProxy = getAPIProxy() state.pendingTransactions.forEach(async (transaction) => { const coin = getCoinFromTxDataUnion(transaction.txDataUnion) - await apiProxy.txService.rejectTransaction(coin, transaction.id) + await apiProxy.txService.rejectTransaction(coin, transaction.chainId, + transaction.id) }) await refreshWalletInfo(store) }) @@ -558,6 +570,7 @@ handler.on(WalletActions.refreshGasEstimates.type, async (store: Store, txInfo: if (isSolanaTransaction(txInfo)) { const { fee, errorMessage } = await solanaTxManagerProxy.getEstimatedTxFee( + txInfo.chainId, txInfo.id ) if (!fee) { @@ -578,7 +591,8 @@ handler.on(WalletActions.refreshGasEstimates.type, async (store: Store, txInfo: return } - const { estimation } = await ethTxManagerProxy.getGasEstimation1559() + const { estimation } = + await ethTxManagerProxy.getGasEstimation1559(txInfo.chainId) if (!estimation) { console.error('Failed to fetch gas estimates') store.dispatch(WalletActions.setHasFeeEstimatesError(true)) @@ -595,6 +609,7 @@ handler.on(WalletActions.updateUnapprovedTransactionGasFields.type, async (store if (isEIP1559) { const result = await apiProxy.ethTxManagerProxy.setGasFeeAndLimitForUnapprovedTransaction( + payload.chainId, payload.txMetaId, payload.maxPriorityFeePerGas || '0x0', payload.maxFeePerGas || '0x0', @@ -614,7 +629,7 @@ handler.on(WalletActions.updateUnapprovedTransactionGasFields.type, async (store if (!isEIP1559 && payload.gasPrice) { const result = await apiProxy.ethTxManagerProxy.setGasPriceAndLimitForUnapprovedTransaction( - payload.txMetaId, payload.gasPrice, payload.gasLimit + payload.chainId, payload.txMetaId, payload.gasPrice, payload.gasLimit ) if (!result.success) { @@ -640,7 +655,9 @@ handler.on(WalletActions.updateUnapprovedTransactionSpendAllowance.type, async ( return } - const result = await apiProxy.ethTxManagerProxy.setDataForUnapprovedTransaction(payload.txMetaId, data) + const result = + await apiProxy.ethTxManagerProxy.setDataForUnapprovedTransaction( + payload.chainId, payload.txMetaId, data) if (!result.success) { console.error( 'Failed to update unapproved transaction: ' + @@ -653,7 +670,9 @@ handler.on(WalletActions.updateUnapprovedTransactionSpendAllowance.type, async ( handler.on(WalletActions.updateUnapprovedTransactionNonce.type, async (store: Store, payload: UpdateUnapprovedTransactionNonceType) => { const { ethTxManagerProxy } = getAPIProxy() - const result = await ethTxManagerProxy.setNonceForUnapprovedTransaction(payload.txMetaId, payload.nonce) + const result = + await ethTxManagerProxy.setNonceForUnapprovedTransaction( + payload.chainId, payload.txMetaId, payload.nonce) if (!result.success) { console.error( 'Failed to update unapproved transaction: ' + @@ -696,6 +715,7 @@ handler.on( const { txService } = getAPIProxy() const result = await txService.retryTransaction( payload.coinType, + payload.chainId, payload.transactionId ) if (!result.success) { @@ -717,6 +737,7 @@ handler.on( const { txService } = getAPIProxy() const result = await txService.speedupOrCancelTransaction( payload.coinType, + payload.chainId, payload.transactionId, false ) @@ -739,6 +760,7 @@ handler.on( const { txService } = getAPIProxy() const result = await txService.speedupOrCancelTransaction( payload.coinType, + payload.chainId, payload.transactionId, true ) diff --git a/components/brave_wallet_ui/common/async/hardware.test.ts b/components/brave_wallet_ui/common/async/hardware.test.ts index cdd71e5b8fd4..1789c1265366 100644 --- a/components/brave_wallet_ui/common/async/hardware.test.ts +++ b/components/brave_wallet_ui/common/async/hardware.test.ts @@ -124,6 +124,7 @@ const getMockedTrezorKeyring = (expectedDevicePath: string, expectedData: string } const getMockedProxyServices = ( + expectedChainId: string, expectedId: string, nonce?: GetNonceForHardwareTransactionReturnInfo, messageToSign?: GetTransactionMessageToSignReturnInfo | undefined, @@ -137,18 +138,21 @@ const getMockedProxyServices = ( } }, txService: { - getTransactionMessageToSign: (coinType: BraveWallet.CoinType, id: string): GetTransactionMessageToSignReturnInfo | undefined => { + getTransactionMessageToSign: (coinType: BraveWallet.CoinType, chainId: string, id: string): GetTransactionMessageToSignReturnInfo | undefined => { expect(id).toStrictEqual(expectedId) + expect(chainId).toStrictEqual(expectedChainId) return messageToSign } }, ethTxManagerProxy: { - getNonceForHardwareTransaction: (id: string): GetNonceForHardwareTransactionReturnInfo | undefined => { + getNonceForHardwareTransaction: (chainId: string, id: string): GetNonceForHardwareTransactionReturnInfo | undefined => { expect(id).toStrictEqual(expectedId) + expect(chainId).toStrictEqual(expectedChainId) return nonce }, - processHardwareSignature: (id: string, v: string, r: string, s: string): ProcessHardwareSignatureReturnInfo | undefined => { + processHardwareSignature: (chainId: string, id: string, v: string, r: string, s: string): ProcessHardwareSignatureReturnInfo | undefined => { expect(id).toStrictEqual(expectedId) + expect(chainId).toStrictEqual(expectedChainId) expect(v.startsWith('0x')).toStrictEqual(true) expect(r.startsWith('0x')).toStrictEqual(true) expect(s.startsWith('0x')).toStrictEqual(true) @@ -156,15 +160,17 @@ const getMockedProxyServices = ( } }, filTxManagerProxy: { - processFilHardwareSignature: (id: string, signedTx: string): ProcessHardwareSignatureReturnInfo | undefined => { + processFilHardwareSignature: (chainId: string, id: string, signedTx: string): ProcessHardwareSignatureReturnInfo | undefined => { expect(id).toStrictEqual(expectedId) + expect(chainId).toStrictEqual(expectedChainId) expect(signedTx).toStrictEqual(filSignedTransaction) return hardwareSignature } }, solanaTxManagerProxy: { - processSolanaHardwareSignature: (id: string, signature: number[]): ProcessHardwareSignatureReturnInfo | undefined => { + processSolanaHardwareSignature: (chainId: string, id: string, signature: number[]): ProcessHardwareSignatureReturnInfo | undefined => { expect(id).toStrictEqual(expectedId) + expect(chainId).toStrictEqual(expectedChainId) expect(solSignature).toStrictEqual(signature) return hardwareSignature } @@ -180,7 +186,7 @@ const signEthTransactionWithLedger = (vrs?: SignatureVRS, signatureResponse?: bo const signTransactionResult = vrs ? { success: true, payload: vrs } : { success: false } const mockedKeyring = getMockedLedgerEthKeyring(expectedPath, expectedData, signTransactionResult as SignHardwareOperationResult) const signed = signatureResponse ? { status: signatureResponse } : undefined - const apiProxy = getMockedProxyServices(txInfo.id, { nonce: '0x1' }, messageToSign, + const apiProxy = getMockedProxyServices(txInfo.chainId, txInfo.id, { nonce: '0x1' }, messageToSign, signed) return signLedgerEthereumTransaction(apiProxy as unknown as WalletApiProxy, expectedPath, txInfo, BraveWallet.CoinType.ETH, mockedKeyring as unknown as LedgerBridgeKeyring) } @@ -194,6 +200,7 @@ const signSolTransactionWithLedger = (expectedSignature: Buffer, signatureRespon const mockedKeyring = getMockedLedgerSolKeyring(expectedData, signTransactionResult as SignHardwareOperationResult) const signed = signatureResponse ? { status: signatureResponse } : undefined const apiProxy = getMockedProxyServices( + txInfo.chainId, txInfo.id, { nonce: 1 }, messageToSign, @@ -204,7 +211,7 @@ const signSolTransactionWithLedger = (expectedSignature: Buffer, signatureRespon return signLedgerSolanaTransaction( apiProxy as unknown as WalletApiProxy, expectedPath, - txInfo.id, + txInfo, BraveWallet.CoinType.SOL, mockedKeyring as unknown as SolanaLedgerKeyring ) @@ -217,7 +224,7 @@ const signFilTransactionWithLedger = (expectedSignature: SignedLotusMessage, sig const signTransactionResult = expectedSignature ? { success: true, payload: expectedSignature } : { success: false } const mockedKeyring = getMockedLedgerFilKeyring(expectedData, signTransactionResult as SignHardwareOperationResult) const signed = signatureResponse ? { status: signatureResponse } : undefined - const apiProxy = getMockedProxyServices(txInfo.id, { nonce: 1 }, messageToSign, + const apiProxy = getMockedProxyServices(txInfo.chainId, txInfo.id, { nonce: 1 }, messageToSign, signed, JSON.stringify(expectedSignature)) return signLedgerFilecoinTransaction(apiProxy as unknown as WalletApiProxy, txInfo, BraveWallet.CoinType.FIL, mockedKeyring as unknown as FilecoinLedgerKeyring) } @@ -232,7 +239,7 @@ const signTransactionWithTrezor = (signed: Success | Unsuccess const txInfo = getMockedTransactionInfo() const expectedPath = 'path' const mockedKeyring = getMockedTrezorKeyring(expectedPath, txInfo, signed) - const apiProxy = getMockedProxyServices(txInfo.id, { nonce: '0x03' }, undefined, signatureResponse) + const apiProxy = getMockedProxyServices(txInfo.chainId, txInfo.id, { nonce: '0x03' }, undefined, signatureResponse) return signTrezorTransaction(apiProxy as unknown as WalletApiProxy, expectedPath, txInfo, mockedKeyring as unknown as TrezorBridgeKeyring) } @@ -244,7 +251,7 @@ test('Test sign raw Eth Ledger transaction', () => { test('Test sign Ledger transaction, approved, no message to sign', () => { const txInfo = getMockedTransactionInfo() - const apiProxy = getMockedProxyServices(txInfo.id, { nonce: '0x1' }) + const apiProxy = getMockedProxyServices(txInfo.chainId, txInfo.id, { nonce: '0x1' }) return expect(signLedgerEthereumTransaction(apiProxy as unknown as WalletApiProxy, 'path', txInfo, BraveWallet.CoinType.ETH)).resolves.toStrictEqual(hardwareTransactionErrorResponse('braveWalletNoMessageToSignError')) }) @@ -265,7 +272,7 @@ test('Test sign Ledger transaction, approved, processed', () => { test('Test sign Trezor transaction, approve failed', () => { const txInfo = getMockedTransactionInfo() - const apiProxy = getMockedProxyServices(txInfo.id, { nonce: '' }) + const apiProxy = getMockedProxyServices(txInfo.chainId, txInfo.id, { nonce: '' }) return expect(signTrezorTransaction(apiProxy as unknown as WalletApiProxy, 'path', txInfo)).resolves.toStrictEqual( hardwareTransactionErrorResponse('braveWalletApproveTransactionError')) diff --git a/components/brave_wallet_ui/common/async/hardware.ts b/components/brave_wallet_ui/common/async/hardware.ts index cf98c2251553..14cfdfa5f2fd 100644 --- a/components/brave_wallet_ui/common/async/hardware.ts +++ b/components/brave_wallet_ui/common/async/hardware.ts @@ -60,8 +60,9 @@ export async function signTrezorTransaction ( path: string, txInfo: SerializableTransactionInfo, deviceKeyring: TrezorBridgeKeyring = getTrezorHardwareKeyring()): Promise { - const chainId = await apiProxy.jsonRpcService.getChainId(BraveWallet.CoinType.ETH) - const nonce = await apiProxy.ethTxManagerProxy.getNonceForHardwareTransaction(txInfo.id) + const nonce = + await apiProxy.ethTxManagerProxy.getNonceForHardwareTransaction( + txInfo.chainId, txInfo.id) if (!nonce || !nonce.nonce) { return { success: false, error: getLocale('braveWalletApproveTransactionError') } } @@ -81,7 +82,7 @@ export async function signTrezorTransaction ( } } } as SerializableTransactionInfo - const signed = await deviceKeyring.signTransaction(path, tx, chainId.chainId) + const signed = await deviceKeyring.signTransaction(path, tx, tx.chainId) if (!signed || !signed.success || !signed.payload) { const error = (signed.error ? signed.error : getLocale('braveWalletSignOnDeviceError')) as string if (signed.code === TrezorErrorsCodes.CommandInProgress) { @@ -95,7 +96,8 @@ export async function signTrezorTransaction ( } const { v, r, s } = ethereumSignedTx const result = - await apiProxy.ethTxManagerProxy.processHardwareSignature(tx.id, v, r, s) + await apiProxy.ethTxManagerProxy.processHardwareSignature( + tx.chainId, tx.id, v, r, s) if (!result.status) { return { success: false, error: getLocale('braveWalletProcessTransactionError') } } @@ -108,11 +110,14 @@ export async function signLedgerEthereumTransaction ( txInfo: SerializableTransactionInfo, coin: BraveWallet.CoinType, deviceKeyring: LedgerEthereumKeyring = getLedgerEthereumHardwareKeyring()): Promise { - const nonce = await apiProxy.ethTxManagerProxy.getNonceForHardwareTransaction(txInfo.id) + const nonce = + await apiProxy.ethTxManagerProxy.getNonceForHardwareTransaction( + txInfo.chainId, txInfo.id) if (!nonce || !nonce.nonce) { return { success: false, error: getLocale('braveWalletApproveTransactionError') } } - const data = await apiProxy.txService.getTransactionMessageToSign(coin, txInfo.id) + const data = await apiProxy.txService.getTransactionMessageToSign( + coin, txInfo.chainId, txInfo.id) if (!data || !data.message || !data.message.messageStr) { return { success: false, error: getLocale('braveWalletNoMessageToSignError') } } @@ -125,7 +130,9 @@ export async function signLedgerEthereumTransaction ( return { success: false, error: error, code: code } } const { v, r, s } = signed.payload as EthereumSignedTx - const result = await apiProxy.ethTxManagerProxy.processHardwareSignature(txInfo.id, '0x' + v, '0x' + r, '0x' + s) + const result = + await apiProxy.ethTxManagerProxy.processHardwareSignature( + txInfo.chainId, txInfo.id, '0x' + v, '0x' + r, '0x' + s) if (!result || !result.status) { return { success: false, error: getLocale('braveWalletProcessTransactionError') } } @@ -137,7 +144,8 @@ export async function signLedgerFilecoinTransaction ( txInfo: SerializableTransactionInfo, coin: BraveWallet.CoinType, deviceKeyring: LedgerFilecoinKeyring = getLedgerFilecoinHardwareKeyring()): Promise { - const data = await apiProxy.txService.getTransactionMessageToSign(coin, txInfo.id) + const data = await apiProxy.txService.getTransactionMessageToSign( + coin, txInfo.chainId, txInfo.id) if (!data || !data.message || !data.message.messageStr) { return { success: false, error: getLocale('braveWalletNoMessageToSignError') } } @@ -153,7 +161,8 @@ export async function signLedgerFilecoinTransaction ( return { success: false } } - const result = await apiProxy.filTxManagerProxy.processFilHardwareSignature(txInfo.id, JSON.stringify(signedMessage)) + const result = await apiProxy.filTxManagerProxy.processFilHardwareSignature( + txInfo.chainId, txInfo.id, JSON.stringify(signedMessage)) if (!result || !result.status) { return { success: false, error: getLocale('braveWalletProcessTransactionError') } } @@ -163,10 +172,11 @@ export async function signLedgerFilecoinTransaction ( export async function signLedgerSolanaTransaction ( apiProxy: WalletApiProxy, path: string, - txId: string, + txInfo: SerializableTransactionInfo, coin: BraveWallet.CoinType, deviceKeyring: LedgerSolanaKeyring = getLedgerSolanaHardwareKeyring()): Promise { - const data = await apiProxy.txService.getTransactionMessageToSign(coin, txId) + const data = await apiProxy.txService.getTransactionMessageToSign( + coin, txInfo.chainId, txInfo.id) if (!data || !data.message || !data.message.messageBytes) { return { success: false, error: getLocale('braveWalletNoMessageToSignError') } } @@ -182,7 +192,9 @@ export async function signLedgerSolanaTransaction ( return { success: false } } - const result = await apiProxy.solanaTxManagerProxy.processSolanaHardwareSignature(txId, [...signedMessage]) + const result = + await apiProxy.solanaTxManagerProxy.processSolanaHardwareSignature( + txInfo.chainId, txInfo.id, [...signedMessage]) if (!result || !result.status) { return { success: false, error: getLocale('braveWalletProcessTransactionError') } } diff --git a/components/brave_wallet_ui/common/async/lib.ts b/components/brave_wallet_ui/common/async/lib.ts index ed0270f69167..a8500c330152 100644 --- a/components/brave_wallet_ui/common/async/lib.ts +++ b/components/brave_wallet_ui/common/async/lib.ts @@ -59,11 +59,15 @@ export const getERC20Allowance = ( spenderAddress: string ): Promise => { return new Promise(async (resolve, reject) => { - const service = getAPIProxy().jsonRpcService - const result = await service.getERC20TokenAllowance( + const { braveWalletService, jsonRpcService } = getAPIProxy() + const { chainId } + = await braveWalletService.getChainIdForActiveOrigin( + BraveWallet.CoinType.ETH) + const result = await jsonRpcService.getERC20TokenAllowance( contractAddress, ownerAddress, - spenderAddress + spenderAddress, + chainId ) if (result.error === BraveWallet.ProviderError.kSuccess) { @@ -116,9 +120,9 @@ export const onConnectHardwareWallet = (opts: HardwareWalletConnectOpts): Promis } export const getBalance = async (address: string, coin: BraveWallet.CoinType): Promise => { - const { jsonRpcService } = getAPIProxy() - const chainId = await jsonRpcService.getChainId(coin) - return await getBalanceForChainId(address, coin, chainId.chainId) + const { braveWalletService } = getAPIProxy() + const { chainId } = await braveWalletService.getChainIdForActiveOrigin(coin) + return await getBalanceForChainId(address, coin, chainId) } export function getBalanceForChainId (address: string, coin: BraveWallet.CoinType, chainId: string): Promise { @@ -827,7 +831,9 @@ export function refreshTransactionHistory (address?: string) { const freshTransactions: AccountTransactions = await accountsToUpdate.reduce>( async (acc, account) => acc.then(async (obj) => { - const { transactionInfos } = await txService.getAllTransactionInfo(account.coin, account.address) + const { transactionInfos } = + await txService.getAllTransactionInfo( + account.coin, null, account.address) const serializedTransactionInfos = transactionInfos.map(makeSerializableTransaction) obj[account.address] = sortTransactionByDate(serializedTransactionInfos, 'descending') return obj @@ -855,9 +861,9 @@ export function refreshKeyringInfo () { // Get default accounts for each CoinType const defaultAccounts = await Promise.all(SupportedCoinTypes.map(async (coin: BraveWallet.CoinType) => { - const chainId = await jsonRpcService.getChainId(coin) + const { chainId } = await jsonRpcService.getChainId(coin, null) const defaultAccount = coin === BraveWallet.CoinType.FIL - ? await keyringService.getFilecoinSelectedAccount(chainId.chainId) + ? await keyringService.getFilecoinSelectedAccount(chainId) : await keyringService.getSelectedAccount(coin) const defaultAccountAddress = defaultAccount.address return walletInfo.accountInfos.find((account) => account.address.toLowerCase() === defaultAccountAddress?.toLowerCase()) ?? {} as BraveWallet.AccountInfo @@ -871,9 +877,9 @@ export function refreshKeyringInfo () { let selectedAccount = { address: null } as { address: string | null } if (selectedCoin === BraveWallet.CoinType.FIL) { - const coinsChainId = await jsonRpcService.getChainId(selectedCoin) + const { chainId } = await jsonRpcService.getChainId(selectedCoin, null) selectedAccount = await keyringService.getFilecoinSelectedAccount( - coinsChainId.chainId + chainId ) } @@ -960,7 +966,9 @@ export async function sendEthTransaction (payload: SendEthTransactionParams) { isEIP1559 = payload.hasEIP1559Support } - const { chainId } = await apiProxy.jsonRpcService.getChainId(BraveWallet.CoinType.ETH) + const { chainId } = + await apiProxy.braveWalletService.getChainIdForActiveOrigin( + BraveWallet.CoinType.ETH) let addResult const txData: BraveWallet.TxData = { @@ -1060,9 +1068,11 @@ export function getEthTxManagerProxy () { export async function getNFTMetadata (token: BraveWallet.BlockchainToken) { const { jsonRpcService } = getAPIProxy() if (token.coin === BraveWallet.CoinType.ETH) { - return await jsonRpcService.getERC721Metadata(token.contractAddress, token.tokenId, token.chainId) + return await jsonRpcService.getERC721Metadata( + token.contractAddress, token.tokenId, token.chainId) } else if (token.coin === BraveWallet.CoinType.SOL) { - return await jsonRpcService.getSolTokenMetadata(token.chainId, token.contractAddress) + return await jsonRpcService.getSolTokenMetadata( + token.chainId, token.contractAddress) } return undefined diff --git a/components/brave_wallet_ui/common/constants/action_types.ts b/components/brave_wallet_ui/common/constants/action_types.ts index d2f170fa9e55..75fea4d1c3eb 100644 --- a/components/brave_wallet_ui/common/constants/action_types.ts +++ b/components/brave_wallet_ui/common/constants/action_types.ts @@ -61,6 +61,7 @@ export type SwapParamsPayloadType = { } export type UpdateUnapprovedTransactionGasFieldsType = { + chainId: string txMetaId: string gasLimit: string gasPrice?: string @@ -69,12 +70,14 @@ export type UpdateUnapprovedTransactionGasFieldsType = { } export type UpdateUnapprovedTransactionSpendAllowanceType = { + chainId: string txMetaId: string spenderAddress: string allowance: string } export type UpdateUnapprovedTransactionNonceType = { + chainId: string txMetaId: string nonce: string } @@ -127,6 +130,7 @@ export type SetTransactionProviderErrorType = { } export interface RetryTransactionPayload { + chainId: string transactionId: string coinType: BraveWallet.CoinType fromAddress: string diff --git a/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts b/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts index 7868384b985f..d14a1e42b459 100644 --- a/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts +++ b/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts @@ -124,6 +124,7 @@ export const usePendingTransactions = () => { const onEditAllowanceSave = React.useCallback((allowance: string) => { if (transactionInfo?.id && transactionDetails) { dispatch(WalletActions.updateUnapprovedTransactionSpendAllowance({ + chainId: transactionInfo.chainId, txMetaId: transactionInfo.id, spenderAddress: transactionDetails.approvalTarget || '', allowance: new Amount(allowance) diff --git a/components/brave_wallet_ui/common/slices/api.slice.ts b/components/brave_wallet_ui/common/slices/api.slice.ts index 2151eaac0c75..987bbe9f8c7f 100644 --- a/components/brave_wallet_ui/common/slices/api.slice.ts +++ b/components/brave_wallet_ui/common/slices/api.slice.ts @@ -227,13 +227,14 @@ let selectedPendingTransactionId: string = '' getSelectedAccountAddress = async () => { if (!this._selectedAccountAddress) { - const { braveWalletService, jsonRpcService, keyringService } = + const { braveWalletService, keyringService } = apiProxyFetcher() const { coin: selectedCoin } = await braveWalletService.getSelectedCoin() if (selectedCoin === BraveWallet.CoinType.FIL) { - const { chainId } = await jsonRpcService.getChainId(selectedCoin) + const { chainId } + = await braveWalletService.getChainIdForActiveOrigin(selectedCoin) const { address } = await keyringService.getFilecoinSelectedAccount( chainId ) @@ -509,12 +510,14 @@ export function createWalletApi ( getDefaultAccountAddresses: query({ queryFn: async (arg, { dispatch }, extraOptions, baseQuery) => { // apiProxy - const { keyringService, jsonRpcService } = baseQuery(undefined).data + const { braveWalletService, keyringService } + = baseQuery(undefined).data // Get default account addresses for each CoinType const defaultAccountAddresses = await Promise.all( SupportedCoinTypes.map(async (coin: BraveWallet.CoinType) => { - const { chainId } = await jsonRpcService.getChainId(coin) + const { chainId } + = await braveWalletService.getChainIdForActiveOrigin(coin) const defaultAccount = coin === BraveWallet.CoinType.FIL ? await keyringService.getFilecoinSelectedAccount(chainId) @@ -706,11 +709,14 @@ export function createWalletApi ( // Transactions and Sign-Message Requests include a chainId queryFn: async (arg, api, extraOptions, baseQuery) => { try { - const { jsonRpcService } = baseQuery(undefined).data // apiProxy + const { braveWalletService, jsonRpcService } + = baseQuery(undefined).data // apiProxy + const { originInfo } = await braveWalletService.getActiveOrigin() const defaultChains = await Promise.all( SupportedCoinTypes.map(async (coinType) => { - const { network } = await jsonRpcService.getNetwork(coinType) + const { network } + = await jsonRpcService.getNetwork(coinType, originInfo.origin) return network }) ) @@ -775,15 +781,19 @@ export function createWalletApi ( baseQuery ) => { try { - const { jsonRpcService } = baseQuery(undefined).data + const { braveWalletService } + = baseQuery(undefined).data await dispatch( walletApi.endpoints.setSelectedCoin.initiate(coin) ).unwrap() - const { success } = await jsonRpcService.setNetwork(chainId, coin) + const { success } + = await braveWalletService.setChainIdForActiveOrigin(coin, + chainId) if (!success) { - throw new Error('jsonRpcService.setNetwork failed') + throw new Error( + 'braveWalletService.SetChainIdForActiveOrigin failed') } return { data: { chainId, coin } @@ -1553,7 +1563,7 @@ export function createWalletApi ( const transactionInfoResults = await Promise.all( accounts.map(async (a) => { const { transactionInfos } = - await txService.getAllTransactionInfo(a.coin, a.address) + await txService.getAllTransactionInfo(a.coin, null, a.address) // return only pending txs return transactionInfos.filter( @@ -1656,6 +1666,7 @@ export function createWalletApi ( // TODO: Core should allow fetching by chain Id instead of cointype const { transactionInfos } = await txService.getAllTransactionInfo( coinType, + null, address ) @@ -1756,6 +1767,7 @@ export function createWalletApi ( // TODO: Core should allow fetching by chain Id + cointype const { transactionInfos } = await txService.getAllTransactionInfo( coinType, + null, address ) @@ -1792,7 +1804,8 @@ export function createWalletApi ( >({ queryFn: async (payload, { dispatch }, extraOptions, baseQuery) => { try { - const { jsonRpcService, txService } = baseQuery(undefined).data + const { braveWalletService, + txService } = baseQuery(undefined).data /*** * Determine whether to create a legacy or EIP-1559 transaction. * @@ -1814,9 +1827,9 @@ export function createWalletApi ( // Check if network and keyring support EIP-1559. payload.hasEIP1559Support - const { chainId } = await jsonRpcService.getChainId( - BraveWallet.CoinType.ETH - ) + const { chainId } + = await braveWalletService.getChainIdForActiveOrigin( + BraveWallet.CoinType.ETH) const txData: BraveWallet.TxData = { nonce: '', @@ -2107,8 +2120,13 @@ export function createWalletApi ( const { solanaTxManagerProxy, txService } = baseQuery(undefined).data + const selectedNetwork = await getSelectedNetwork( + baseQuery(undefined).data + ) + const { errorMessage: transferTxDataErrorMessage, txData } = await solanaTxManagerProxy.makeTokenProgramTransferTxData( + selectedNetwork.chainId, payload.splTokenMintAddress, payload.from, payload.to, @@ -2305,7 +2323,7 @@ export function createWalletApi ( { success: boolean }, Pick< SerializableTransactionInfo, - 'id' | 'txDataUnion' | 'txType' | 'fromAddress' + 'id' | 'txDataUnion' | 'txType' | 'fromAddress' | 'chainId' > >({ queryFn: async (txInfo, { dispatch }, extraOptions, baseQuery) => { @@ -2317,7 +2335,8 @@ export function createWalletApi ( status: boolean errorUnion: BraveWallet.ProviderErrorUnion errorMessage: string - } = await txService.approveTransaction(coin, txInfo.id) + } = await txService.approveTransaction( + coin, txInfo.chainId, txInfo.id) const error = result.errorUnion.providerError ?? @@ -2373,12 +2392,12 @@ export function createWalletApi ( }), rejectTransaction: mutation< { success: boolean }, - Pick + Pick >({ queryFn: async (tx, api, extraOptions, baseQuery) => { try { const { txService } = baseQuery(undefined).data - await txService.rejectTransaction(tx.coinType, tx.id) + await txService.rejectTransaction(tx.coinType, tx.chainId, tx.id) return { data: { success: true } } @@ -2398,10 +2417,11 @@ export function createWalletApi ( ).unwrap() await Promise.all( - pendingTxs.map(async ({ coinType, id }) => { + pendingTxs.map(async ({ coinType, id , chainId}) => { const { success } = await dispatch( walletApi.endpoints.rejectTransaction.initiate({ coinType, + chainId, id }) ).unwrap() @@ -2436,12 +2456,14 @@ export function createWalletApi ( ethTxManagerProxy if (isEIP1559) { - const result = await setGasFeeAndLimitForUnapprovedTransaction( - payload.txMetaId, - payload.maxPriorityFeePerGas || '', - payload.maxFeePerGas || '', - payload.gasLimit - ) + const result = + await setGasFeeAndLimitForUnapprovedTransaction( + payload.chainId, + payload.txMetaId, + payload.maxPriorityFeePerGas || '', + payload.maxFeePerGas || '', + payload.gasLimit + ) if (!result.success) { return { @@ -2468,11 +2490,13 @@ export function createWalletApi ( const { setGasPriceAndLimitForUnapprovedTransaction } = ethTxManagerProxy - const result = await setGasPriceAndLimitForUnapprovedTransaction( - payload.txMetaId, - payload.gasPrice, - payload.gasLimit - ) + const result = + await setGasPriceAndLimitForUnapprovedTransaction( + payload.chainId, + payload.txMetaId, + payload.gasPrice, + payload.gasLimit + ) if (!result.success) { return { @@ -2526,6 +2550,7 @@ export function createWalletApi ( const result = await ethTxManagerProxy.setDataForUnapprovedTransaction( + payload.chainId, payload.txMetaId, data ) @@ -2560,6 +2585,7 @@ export function createWalletApi ( const result = await ethTxManagerProxy.setNonceForUnapprovedTransaction( + payload.chainId, payload.txMetaId, payload.nonce ) @@ -2582,6 +2608,7 @@ export function createWalletApi ( const result = await txService.retryTransaction( payload.coinType, + payload.chainId, payload.transactionId ) @@ -2626,6 +2653,7 @@ export function createWalletApi ( const result = await txService.speedupOrCancelTransaction( payload.coinType, + payload.chainId, payload.transactionId, true ) @@ -2672,6 +2700,7 @@ export function createWalletApi ( const result = await txService.speedupOrCancelTransaction( payload.coinType, + payload.chainId, payload.transactionId, false ) @@ -2822,8 +2851,15 @@ export function createWalletApi ( } } + if (!selectedNetwork) { + return { + error: + 'No selected network' + } + } const { estimation } = - await ethTxManagerProxy.getGasEstimation1559() + await ethTxManagerProxy.getGasEstimation1559( + selectedNetwork.chainId) if (!estimation) { const msg = 'Failed to fetch gas estimates' @@ -2842,12 +2878,13 @@ export function createWalletApi ( }, providesTags: ['GasEstimation1559'] }), - getSolanaEstimatedFee: query({ - queryFn: async (txIdArg, api, extraOptions, baseQuery) => { + getSolanaEstimatedFee: query({ + queryFn: async (arg, api, extraOptions, baseQuery) => { try { const { solanaTxManagerProxy } = baseQuery(undefined).data const { errorMessage, fee } = - await solanaTxManagerProxy.getEstimatedTxFee(txIdArg) + await solanaTxManagerProxy.getEstimatedTxFee(arg.chainId, + arg.txId) if (!fee) { throw new Error(errorMessage) @@ -2857,7 +2894,7 @@ export function createWalletApi ( data: fee.toString() } } catch (error) { - const msg = `Unable to fetch Solana fees - txId: ${txIdArg}` + const msg = `Unable to fetch Solana fees - txId: ${arg.txId}` console.error(msg) console.error(error) return { @@ -2865,19 +2902,20 @@ export function createWalletApi ( } } }, - providesTags: (res, er, txIdArg) => [ - { type: 'SolanaEstimatedFees', id: txIdArg } + providesTags: (res, er, arg) => [ + { type: 'SolanaEstimatedFees', id: arg.txId } ] }), refreshGasEstimates: mutation< boolean, // success - Pick + Pick >({ queryFn: async (txInfo, { dispatch }, extraOptions, baseQuery) => { try { if (txInfo.isSolanaTransaction) { await dispatch( - walletApi.endpoints.getSolanaEstimatedFee.initiate(txInfo.id) + walletApi.endpoints.getSolanaEstimatedFee.initiate( + {chainId: txInfo.chainId, txId: txInfo.id}) ) return { data: true @@ -3156,7 +3194,9 @@ export async function getSelectedNetwork(api: WalletApiProxy) { throw new Error('selected coin was undefined') } - const { network } = await jsonRpcService.getNetwork(selectedCoin) + const { originInfo } = await braveWalletService.getActiveOrigin() + const { network } = await jsonRpcService.getNetwork(selectedCoin, + originInfo.origin) return network } @@ -3310,7 +3350,8 @@ export const parseTransactionWithoutPricesAsync = async ({ try { solFeeEstimates = isSolanaTransaction(tx) ? await dispatch( - walletApi.endpoints.getSolanaEstimatedFee.initiate(tx.id) + walletApi.endpoints.getSolanaEstimatedFee.initiate( + {chainId: tx.chainId, txId: tx.id}) ).unwrap() : '0' } catch (error) { diff --git a/components/brave_wallet_ui/common/wallet_api_proxy.ts b/components/brave_wallet_ui/common/wallet_api_proxy.ts index 42fb9bca8707..473b71be63b5 100644 --- a/components/brave_wallet_ui/common/wallet_api_proxy.ts +++ b/components/brave_wallet_ui/common/wallet_api_proxy.ts @@ -35,7 +35,7 @@ export class WalletApiProxy { chainChangedEvent: function (chainId, coin, origin) { store.dispatch( WalletActions.chainChangedEvent({ - chainId, coin, origin: !!origin ? origin : undefined})) + chainId, coin, origin: origin || undefined})) }, onAddEthereumChainRequestCompleted: function (chainId, error) { // TODO: Handle this event. diff --git a/components/brave_wallet_ui/components/desktop/portfolio-transaction-item/index.tsx b/components/brave_wallet_ui/components/desktop/portfolio-transaction-item/index.tsx index 7bf77e0f82f8..9a12d5c2b781 100644 --- a/components/brave_wallet_ui/components/desktop/portfolio-transaction-item/index.tsx +++ b/components/brave_wallet_ui/components/desktop/portfolio-transaction-item/index.tsx @@ -222,6 +222,7 @@ export const PortfolioTransactionItem = React.forwardRef( dispatch(WalletActions.retryTransaction({ coinType: transaction.coinType, fromAddress: transaction.accountAddress, + chainId: transaction.chainId, transactionId: transaction.id })) }, @@ -237,6 +238,7 @@ export const PortfolioTransactionItem = React.forwardRef( dispatch(WalletActions.speedupTransaction({ coinType: transaction.coinType, fromAddress: transaction.accountAddress, + chainId: transaction.chainId, transactionId: transaction.id })) }, @@ -252,6 +254,7 @@ export const PortfolioTransactionItem = React.forwardRef( dispatch(WalletActions.cancelTransaction({ coinType: transaction.coinType, fromAddress: transaction.accountAddress, + chainId: transaction.chainId, transactionId: transaction.id })) }, diff --git a/components/brave_wallet_ui/components/extension/advanced-transaction-settings/index.tsx b/components/brave_wallet_ui/components/extension/advanced-transaction-settings/index.tsx index dbcb4d00505f..b2ad6d45c7f4 100644 --- a/components/brave_wallet_ui/components/extension/advanced-transaction-settings/index.tsx +++ b/components/brave_wallet_ui/components/extension/advanced-transaction-settings/index.tsx @@ -23,6 +23,7 @@ import Amount from '../../../utils/amount' export interface Props { onCancel: () => void nonce: string + chainId: string txMetaId: string updateUnapprovedTransactionNonce: (payload: any) => void } @@ -31,6 +32,7 @@ const AdvancedTransactionSettings = (props: Props) => { const { onCancel, nonce, + chainId, txMetaId, updateUnapprovedTransactionNonce } = props @@ -44,6 +46,7 @@ const AdvancedTransactionSettings = (props: Props) => { const onSave = () => { updateUnapprovedTransactionNonce({ + chainId, txMetaId, nonce: customNonce && new Amount(customNonce).toHex() }) diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/confirm-transaction-panel.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/confirm-transaction-panel.tsx index 604712c1c5c3..f966079ecfa5 100644 --- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/confirm-transaction-panel.tsx +++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/confirm-transaction-panel.tsx @@ -183,6 +183,7 @@ export const ConfirmTransactionPanel = ({ diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/swap.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/swap.tsx index 84516997dfa0..9da6ea21c343 100644 --- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/swap.tsx +++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/swap.tsx @@ -121,6 +121,7 @@ export function ConfirmSwapTransaction (props: Props) { diff --git a/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx index 4bd9b6b15d07..14a8d6e3f982 100644 --- a/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx +++ b/components/brave_wallet_ui/components/extension/edit-gas/edit-gas.tsx @@ -157,6 +157,7 @@ export const EditGas = ({ const onSave = () => { if (!isEIP1559Transaction) { updateUnapprovedTransactionGasFields({ + chainId: transactionInfo.chainId, txMetaId: transactionInfo.id, gasPrice: new Amount(gasPrice) .multiplyByDecimals(9) @@ -171,6 +172,7 @@ export const EditGas = ({ if (maxPriorityPanel === MaxPriorityPanels.setCustom) { updateUnapprovedTransactionGasFields({ + chainId: transactionInfo.chainId, txMetaId: transactionInfo.id, maxPriorityFeePerGas: new Amount(maxPriorityFeePerGas) .multiplyByDecimals(9) @@ -183,6 +185,7 @@ export const EditGas = ({ }) } else if (maxPriorityPanel === MaxPriorityPanels.setSuggested) { updateUnapprovedTransactionGasFields({ + chainId: transactionInfo.chainId, txMetaId: transactionInfo.id, gasLimit: new Amount(gasLimit) .toHex(), diff --git a/components/brave_wallet_ui/page/screens/swap/adapters.ts b/components/brave_wallet_ui/page/screens/swap/adapters.ts index d22d697fe2e0..d44ebb426719 100644 --- a/components/brave_wallet_ui/page/screens/swap/adapters.ts +++ b/components/brave_wallet_ui/page/screens/swap/adapters.ts @@ -209,9 +209,9 @@ export function makeGetGasPrice () { } export function makeGetGasPrice1559 () { - async function getGasPrice1559 () { + async function getGasPrice1559 (chainId: string) { const { ethTxManagerProxy } = getAPIProxy() - const result = await ethTxManagerProxy.getGasEstimation1559() + const result = await ethTxManagerProxy.getGasEstimation1559(chainId) if (result && result.estimation) { return result.estimation } else { diff --git a/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts b/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts index 493744f95ee7..89f89d85ab5d 100644 --- a/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts +++ b/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts @@ -220,7 +220,8 @@ handler.on(PanelActions.approveHardwareTransaction.type, async (store: Store, tx ({ success, error, code } = await signLedgerFilecoinTransaction(apiProxy, txInfo, found.coin)) break case BraveWallet.CoinType.SOL: - ({ success, error, code } = await signLedgerSolanaTransaction(apiProxy, hardwareAccount.path, txInfo.id, found.coin)) + ({ success, error, code } = await signLedgerSolanaTransaction( + apiProxy, hardwareAccount.path, txInfo, found.coin)) break default: await store.dispatch(PanelActions.navigateToMain()) diff --git a/components/brave_wallet_ui/panel/container.tsx b/components/brave_wallet_ui/panel/container.tsx index c42a210ccc62..ae54e10bef79 100644 --- a/components/brave_wallet_ui/panel/container.tsx +++ b/components/brave_wallet_ui/panel/container.tsx @@ -299,6 +299,7 @@ function Container () { dispatch(WalletActions.retryTransaction({ coinType: getCoinFromTxDataUnion(transaction.txDataUnion), fromAddress: findTransactionAccount(accounts, transaction)?.address || '', + chainId: transaction.chainId, transactionId: transaction.id })) } @@ -307,6 +308,7 @@ function Container () { dispatch(WalletActions.speedupTransaction({ coinType: getCoinFromTxDataUnion(transaction.txDataUnion), fromAddress: findTransactionAccount(accounts, transaction)?.address || '', + chainId: transaction.chainId, transactionId: transaction.id })) } @@ -315,6 +317,7 @@ function Container () { dispatch(WalletActions.cancelTransaction({ coinType: getCoinFromTxDataUnion(transaction.txDataUnion), fromAddress: findTransactionAccount(accounts, transaction)?.address || '', + chainId: transaction.chainId, transactionId: transaction.id })) } From e3d792dbc13b7065901e99eacfc0f1197bd7c5a7 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Fri, 7 Apr 2023 17:16:19 -0700 Subject: [PATCH 05/15] Optional chain_id for UpdatePendingTransactions & CheckIfBlockTrackerShouldRun We should be able to update all the pending txs without specifying chain_id especially for cases like wallet unlock. When specifying chain_id, we won't need to pull out all the pending txs, ex. approve tx. --- .../browser/eth_pending_tx_tracker.cc | 14 +++++-- .../browser/eth_pending_tx_tracker.h | 6 ++- .../brave_wallet/browser/eth_tx_manager.cc | 17 +++++--- .../brave_wallet/browser/eth_tx_manager.h | 3 +- .../brave_wallet/browser/fil_tx_manager.cc | 15 ++++--- .../brave_wallet/browser/fil_tx_manager.h | 3 +- .../brave_wallet/browser/solana_tx_manager.cc | 35 ++++++++++++----- .../brave_wallet/browser/solana_tx_manager.h | 3 +- components/brave_wallet/browser/tx_manager.cc | 39 ++++++------------- components/brave_wallet/browser/tx_manager.h | 14 +++---- 10 files changed, 84 insertions(+), 65 deletions(-) diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.cc b/components/brave_wallet/browser/eth_pending_tx_tracker.cc index 920fc5cc8fcd..fe4c53227935 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.cc +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.cc @@ -29,8 +29,11 @@ EthPendingTxTracker::EthPendingTxTracker(EthTxStateManager* tx_state_manager, weak_factory_(this) {} EthPendingTxTracker::~EthPendingTxTracker() = default; -bool EthPendingTxTracker::UpdatePendingTransactions(const std::string& chain_id, - size_t* num_pending) { +bool EthPendingTxTracker::UpdatePendingTransactions( + const absl::optional& chain_id, + size_t* num_pending, + std::set* pending_chain_ids) { + CHECK(num_pending && pending_chain_ids); base::Lock* nonce_lock = nonce_tracker_->GetLock(); if (!nonce_lock->Try()) return false; @@ -48,11 +51,14 @@ bool EthPendingTxTracker::UpdatePendingTransactions(const std::string& chain_id, DropTransaction(pending_transaction.get()); continue; } + const auto& pending_chain_id = pending_transaction->chain_id(); + pending_chain_ids->emplace(pending_chain_id); std::string id = pending_transaction->id(); json_rpc_service_->GetTransactionReceipt( - chain_id, pending_transaction->tx_hash(), + pending_chain_id, pending_transaction->tx_hash(), base::BindOnce(&EthPendingTxTracker::OnGetTxReceipt, - weak_factory_.GetWeakPtr(), chain_id, std::move(id))); + weak_factory_.GetWeakPtr(), pending_chain_id, + std::move(id))); } nonce_lock->Release(); diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.h b/components/brave_wallet/browser/eth_pending_tx_tracker.h index 00c1184bda29..28df2d849d76 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.h +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.h @@ -7,6 +7,7 @@ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ETH_PENDING_TX_TRACKER_H_ #include +#include #include #include "base/containers/flat_map.h" @@ -32,8 +33,9 @@ class EthPendingTxTracker { EthPendingTxTracker(const EthPendingTxTracker&) = delete; EthPendingTxTracker operator=(const EthPendingTxTracker&) = delete; - bool UpdatePendingTransactions(const std::string& chain_id, - size_t* num_pending); + bool UpdatePendingTransactions(const absl::optional& chain_id, + size_t* num_pending, + std::set* pending_chain_ids); void Reset(); private: diff --git a/components/brave_wallet/browser/eth_tx_manager.cc b/components/brave_wallet/browser/eth_tx_manager.cc index 28701ca6d97f..460aa5227aed 100644 --- a/components/brave_wallet/browser/eth_tx_manager.cc +++ b/components/brave_wallet/browser/eth_tx_manager.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -950,15 +951,21 @@ void EthTxManager::OnNewBlock(const std::string& chain_id, UpdatePendingTransactions(chain_id); } -void EthTxManager::UpdatePendingTransactions(const std::string& chain_id) { +void EthTxManager::UpdatePendingTransactions( + const absl::optional& chain_id) { + std::set pending_chain_ids; size_t num_pending; - if (pending_tx_tracker_->UpdatePendingTransactions(chain_id, &num_pending)) { + if (pending_tx_tracker_->UpdatePendingTransactions(chain_id, &num_pending, + &pending_chain_ids)) { if (num_pending == 0) { - known_no_pending_tx_.emplace(chain_id); + known_no_pending_tx_ = true; + CheckIfBlockTrackerShouldRun(absl::nullopt); } else { - known_no_pending_tx_.erase(chain_id); + known_no_pending_tx_ = false; + for (const auto& pending_chain_id : pending_chain_ids) { + CheckIfBlockTrackerShouldRun(pending_chain_id); + } } - CheckIfBlockTrackerShouldRun(chain_id); } } diff --git a/components/brave_wallet/browser/eth_tx_manager.h b/components/brave_wallet/browser/eth_tx_manager.h index 00c893cddc03..87869d4a95c8 100644 --- a/components/brave_wallet/browser/eth_tx_manager.h +++ b/components/brave_wallet/browser/eth_tx_manager.h @@ -248,7 +248,8 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { AddUnapprovedTransactionCallback callback, bool sign_only, mojom::GasEstimation1559Ptr gas_estimation); - void UpdatePendingTransactions(const std::string& chain_id) override; + void UpdatePendingTransactions( + const absl::optional& chain_id) override; void ContinueSpeedupOrCancelTransaction( const std::string& chain_id, diff --git a/components/brave_wallet/browser/fil_tx_manager.cc b/components/brave_wallet/browser/fil_tx_manager.cc index 8118da046926..149d9e94def4 100644 --- a/components/brave_wallet/browser/fil_tx_manager.cc +++ b/components/brave_wallet/browser/fil_tx_manager.cc @@ -354,7 +354,8 @@ FilTxStateManager* FilTxManager::GetFilTxStateManager() { return static_cast(tx_state_manager_.get()); } -void FilTxManager::UpdatePendingTransactions(const std::string& chain_id) { +void FilTxManager::UpdatePendingTransactions( + const absl::optional& chain_id) { auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( chain_id, mojom::TransactionStatus::Submitted, absl::nullopt); for (const auto& pending_transaction : pending_transactions) { @@ -367,18 +368,20 @@ void FilTxManager::UpdatePendingTransactions(const std::string& chain_id) { // difference between current time and transaction submission to calculate // the limit. In case of zero we are looking at last message. uint64_t limit_epochs = seconds == 0 ? 1 : seconds; + const auto& pending_chain_id = pending_transaction->chain_id(); json_rpc_service_->GetFilStateSearchMsgLimited( - chain_id, cid, limit_epochs, + pending_chain_id, cid, limit_epochs, base::BindOnce(&FilTxManager::OnGetFilStateSearchMsgLimited, - weak_factory_.GetWeakPtr(), chain_id, + weak_factory_.GetWeakPtr(), pending_chain_id, pending_transaction->id())); + CheckIfBlockTrackerShouldRun(pending_chain_id); } if (pending_transactions.empty()) { - known_no_pending_tx_.emplace(chain_id); + known_no_pending_tx_ = true; + CheckIfBlockTrackerShouldRun(absl::nullopt); } else { - known_no_pending_tx_.erase(chain_id); + known_no_pending_tx_ = false; } - CheckIfBlockTrackerShouldRun(chain_id); } void FilTxManager::OnGetFilStateSearchMsgLimited( diff --git a/components/brave_wallet/browser/fil_tx_manager.h b/components/brave_wallet/browser/fil_tx_manager.h index 19153104a65e..67d6cba2f59e 100644 --- a/components/brave_wallet/browser/fil_tx_manager.h +++ b/components/brave_wallet/browser/fil_tx_manager.h @@ -127,7 +127,8 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer { uint64_t latest_height) override; // TxManager - void UpdatePendingTransactions(const std::string& chain_id) override; + void UpdatePendingTransactions( + const absl::optional& chain_id) override; std::unique_ptr nonce_tracker_; base::WeakPtrFactory weak_factory_{this}; diff --git a/components/brave_wallet/browser/solana_tx_manager.cc b/components/brave_wallet/browser/solana_tx_manager.cc index 8417d3f1d1eb..58994d5bad1e 100644 --- a/components/brave_wallet/browser/solana_tx_manager.cc +++ b/components/brave_wallet/browser/solana_tx_manager.cc @@ -205,10 +205,31 @@ void SolanaTxManager::OnSendSolanaTransaction( mojom::ProviderErrorUnion::NewSolanaProviderError(error), error_message); } -void SolanaTxManager::UpdatePendingTransactions(const std::string& chain_id) { - json_rpc_service_->GetSolanaBlockHeight( - chain_id, base::BindOnce(&SolanaTxManager::OnGetBlockHeight, - weak_ptr_factory_.GetWeakPtr(), chain_id)); +void SolanaTxManager::UpdatePendingTransactions( + const absl::optional& chain_id) { + if (chain_id.has_value()) { + CheckIfBlockTrackerShouldRun(chain_id); + json_rpc_service_->GetSolanaBlockHeight( + *chain_id, base::BindOnce(&SolanaTxManager::OnGetBlockHeight, + weak_ptr_factory_.GetWeakPtr(), *chain_id)); + } else { + auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( + absl::nullopt, mojom::TransactionStatus::Submitted, absl::nullopt); + for (const auto& pending_transaction : pending_transactions) { + const auto& pending_chain_id = pending_transaction->chain_id(); + json_rpc_service_->GetSolanaBlockHeight( + pending_chain_id, + base::BindOnce(&SolanaTxManager::OnGetBlockHeight, + weak_ptr_factory_.GetWeakPtr(), pending_chain_id)); + CheckIfBlockTrackerShouldRun(pending_chain_id); + } + if (pending_transactions.empty()) { + known_no_pending_tx_ = true; + CheckIfBlockTrackerShouldRun(absl::nullopt); + } else { + known_no_pending_tx_ = false; + } + } } void SolanaTxManager::OnGetBlockHeight(const std::string& chain_id, @@ -232,12 +253,6 @@ void SolanaTxManager::OnGetBlockHeight(const std::string& chain_id, base::BindOnce(&SolanaTxManager::OnGetSignatureStatuses, weak_ptr_factory_.GetWeakPtr(), chain_id, tx_meta_ids, block_height)); - if (pending_transactions.empty()) { - known_no_pending_tx_.emplace(chain_id); - } else { - known_no_pending_tx_.erase(chain_id); - } - CheckIfBlockTrackerShouldRun(chain_id); } void SolanaTxManager::OnGetSignatureStatuses( diff --git a/components/brave_wallet/browser/solana_tx_manager.h b/components/brave_wallet/browser/solana_tx_manager.h index 64f918203cb8..81e22cc2d72b 100644 --- a/components/brave_wallet/browser/solana_tx_manager.h +++ b/components/brave_wallet/browser/solana_tx_manager.h @@ -112,7 +112,8 @@ class SolanaTxManager : public TxManager, public SolanaBlockTracker::Observer { mojom::CoinType GetCoinType() const override; // TxManager - void UpdatePendingTransactions(const std::string& chain_id) override; + void UpdatePendingTransactions( + const absl::optional& chain_id) override; void OnGetBlockHeight(const std::string& chain_id, uint64_t block_height, diff --git a/components/brave_wallet/browser/tx_manager.cc b/components/brave_wallet/browser/tx_manager.cc index a09cf269b81e..98446fbf1bc7 100644 --- a/components/brave_wallet/browser/tx_manager.cc +++ b/components/brave_wallet/browser/tx_manager.cc @@ -38,8 +38,6 @@ TxManager::TxManager(std::unique_ptr tx_state_manager, DCHECK(json_rpc_service_); DCHECK(keyring_service_); - // TODO(darkdh): Check if this is needed. (Unlock should be sufficient) - // CheckIfBlockTrackerShouldRun(absl::nullopt); tx_state_manager_->AddObserver(this); keyring_service_->AddObserver( keyring_observer_receiver_.BindNewPipeAndPassRemote()); @@ -98,18 +96,20 @@ void TxManager::RejectTransaction(const std::string& chain_id, std::move(callback).Run(true); } -void TxManager::CheckIfBlockTrackerShouldRun(const std::string& chain_id) { +void TxManager::CheckIfBlockTrackerShouldRun( + const absl::optional& chain_id) { const auto& keyring_id = CoinTypeToKeyringId(GetCoinType(), chain_id); CHECK(keyring_id.has_value()); bool keyring_created = keyring_service_->IsKeyringCreated(*keyring_id); bool locked = keyring_service_->IsLockedSync(); - bool running = block_tracker_->IsRunning(chain_id); - if (keyring_created && !locked && !running) { - block_tracker_->Start(chain_id, + // If a timer in BlockTracker has already stopped, calling Stop() will be a no + // op. + bool running = chain_id.has_value() && block_tracker_->IsRunning(*chain_id); + if (keyring_created && !locked && !running && chain_id.has_value()) { + block_tracker_->Start(*chain_id, base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - } else if ((locked || base::Contains(known_no_pending_tx_, chain_id)) && - running) { - block_tracker_->Stop(chain_id); + } else if (locked || known_no_pending_tx_) { + block_tracker_->Stop(); } } @@ -126,24 +126,7 @@ void TxManager::Locked() { } void TxManager::Unlocked() { - const std::string& chain_id = - json_rpc_service_->GetChainId(GetCoinType(), absl::nullopt); - CheckIfBlockTrackerShouldRun(chain_id); - UpdatePendingTransactions(chain_id); -} - -void TxManager::KeyringCreated(const std::string& keyring_id) { - /* TODO(darkdh): Check if this is needed (There should be no pending txs) - const auto coin = GetCoinForKeyring(keyring_id); - UpdatePendingTransactions(json_rpc_service_->GetChainId(coin, absl::nullopt)); - */ -} - -void TxManager::KeyringRestored(const std::string& keyring_id) { - /* TODO(darkdh): Check if this is needed (There should be no pending txs) - const auto coin = GetCoinForKeyring(keyring_id); - UpdatePendingTransactions(json_rpc_service_->GetChainId(coin, absl::nullopt)); - */ + UpdatePendingTransactions(absl::nullopt); } void TxManager::KeyringReset() { @@ -152,7 +135,7 @@ void TxManager::KeyringReset() { void TxManager::Reset() { block_tracker_->Stop(); - known_no_pending_tx_.clear(); + known_no_pending_tx_ = false; } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/tx_manager.h b/components/brave_wallet/browser/tx_manager.h index 766914049328..f2b417c9a91e 100644 --- a/components/brave_wallet/browser/tx_manager.h +++ b/components/brave_wallet/browser/tx_manager.h @@ -7,7 +7,6 @@ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_TX_MANAGER_H_ #include -#include #include #include @@ -88,8 +87,10 @@ class TxManager : public TxStateManager::Observer, virtual void Reset(); protected: - void CheckIfBlockTrackerShouldRun(const std::string& chain_id); - virtual void UpdatePendingTransactions(const std::string& chain_id) = 0; + void CheckIfBlockTrackerShouldRun( + const absl::optional& chain_id); + virtual void UpdatePendingTransactions( + const absl::optional& chain_id) = 0; std::unique_ptr tx_state_manager_; std::unique_ptr block_tracker_; @@ -97,8 +98,7 @@ class TxManager : public TxStateManager::Observer, raw_ptr json_rpc_service_ = nullptr; // NOT OWNED raw_ptr keyring_service_ = nullptr; // NOT OWNED raw_ptr prefs_ = nullptr; // NOT OWNED - // chain_id - std::set known_no_pending_tx_; + bool known_no_pending_tx_ = false; private: virtual mojom::CoinType GetCoinType() const = 0; @@ -108,8 +108,8 @@ class TxManager : public TxStateManager::Observer, void OnNewUnapprovedTx(mojom::TransactionInfoPtr tx_info) override; // mojom::KeyringServiceObserver - void KeyringCreated(const std::string& keyring_id) override; - void KeyringRestored(const std::string& keyring_id) override; + void KeyringCreated(const std::string& keyring_id) override {} + void KeyringRestored(const std::string& keyring_id) override {} void KeyringReset() override; void Locked() override; void Unlocked() override; From e9101b80ac5ae4532fcb9f2cfd7c261710d64531 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Mon, 3 Apr 2023 17:02:24 -0700 Subject: [PATCH 06/15] Update unit tests --- ...brave_wallet_ethereum_chain_browsertest.cc | 9 +- .../brave_wallet_event_emitter_browsertest.cc | 3 +- .../brave_wallet_service_unittest.cc | 25 +- .../eth_pending_tx_tracker_unittest.cc | 138 +-- .../ethereum_provider_impl_unittest.cc | 129 +-- .../brave_wallet/keyring_service_unittest.cc | 2 +- .../settings/brave_wallet_handler_unittest.cc | 6 +- .../browser/brave_wallet_utils_unittest.cc | 113 ++- .../browser/eth_block_tracker_unittest.cc | 265 +++--- .../browser/eth_nonce_tracker_unittest.cc | 43 +- .../browser/eth_tx_manager_unittest.cc | 473 +++++++---- .../browser/eth_tx_state_manager_unittest.cc | 45 +- .../browser/fil_block_tracker_unittest.cc | 123 +-- .../browser/fil_nonce_tracker_unittest.cc | 54 +- .../browser/fil_tx_manager_unittest.cc | 184 ++-- .../browser/fil_tx_state_manager_unittest.cc | 37 +- .../browser/json_rpc_service_unittest.cc | 801 ++++++++++-------- .../browser/nft_metadata_fetcher_unittest.cc | 31 +- .../browser/solana_block_tracker_unittest.cc | 241 +++--- .../browser/solana_tx_manager_unittest.cc | 234 ++--- .../solana_tx_state_manager_unittest.cc | 41 +- .../browser/swap_service_unittest.cc | 10 +- .../browser/tx_state_manager_unittest.cc | 247 +++--- components/brave_wallet/common/BUILD.gn | 2 + components/brave_wallet/common/test_utils.h | 10 + .../test/js_ethereum_provider_browsertest.cc | 4 +- 26 files changed, 1869 insertions(+), 1401 deletions(-) diff --git a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc index 530e0a885807..acbae1df3c0a 100644 --- a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc +++ b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc @@ -299,7 +299,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddEthereumChainApproved) { EXPECT_EQ( chain->block_explorer_urls, std::vector({"https://bscscan.com/", "http://localhost/"})); - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH), + EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, + absl::nullopt), kSomeChainId); } @@ -425,7 +426,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, ASSERT_FALSE(GetAllEthCustomChains().empty()); EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); // But current chain should not change - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH), + EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, + absl::nullopt), "0x1"); } @@ -473,7 +475,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddDifferentChainsSwitch) { base::RunLoop().RunUntilIdle(); ASSERT_FALSE(GetAllEthCustomChains().empty()); EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH), + EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, + absl::nullopt), "0x11"); } diff --git a/browser/brave_wallet/brave_wallet_event_emitter_browsertest.cc b/browser/brave_wallet/brave_wallet_event_emitter_browsertest.cc index 30169a89aa37..042076422550 100644 --- a/browser/brave_wallet/brave_wallet_event_emitter_browsertest.cc +++ b/browser/brave_wallet/brave_wallet_event_emitter_browsertest.cc @@ -196,7 +196,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEventEmitterTest, browser()->tab_strip_model()->GetActiveWebContents(); auto service = GetJsonRpcService(); service->SetNetwork(brave_wallet::mojom::kGoerliChainId, - brave_wallet::mojom::CoinType::ETH, base::DoNothing()); + brave_wallet::mojom::CoinType::ETH, absl::nullopt, + base::DoNothing()); auto result_first = EvalJs(contents, CheckForEventScript("received_chain_changed_event"), diff --git a/browser/brave_wallet/brave_wallet_service_unittest.cc b/browser/brave_wallet/brave_wallet_service_unittest.cc index 585d9b6d7baf..e8c4d388ac03 100644 --- a/browser/brave_wallet/brave_wallet_service_unittest.cc +++ b/browser/brave_wallet/brave_wallet_service_unittest.cc @@ -617,8 +617,9 @@ class BraveWalletServiceUnitTest : public testing::Test { [&](bool success, const absl::optional& error_message) { *success_out = success; - if (error_message) + if (error_message) { *error_message_out = *error_message; + } run_loop.Quit(); }), result, info, error); @@ -631,8 +632,9 @@ class BraveWalletServiceUnitTest : public testing::Test { std::vector requests_out; service_->GetPendingSignMessageRequests(base::BindLambdaForTesting( [&](std::vector requests) { - for (const auto& request : requests) + for (const auto& request : requests) { requests_out.push_back(request.Clone()); + } run_loop.Quit(); })); run_loop.Run(); @@ -671,8 +673,9 @@ class BraveWalletServiceUnitTest : public testing::Test { for (size_t i = 0; i < addresses.size(); ++i) { *valid_addresses = (keyring_info->account_infos[i]->address == addresses[i]); - if (!*valid_addresses) + if (!*valid_addresses) { break; + } } } run_loop.Quit(); @@ -721,8 +724,8 @@ class BraveWalletServiceUnitTest : public testing::Test { EXPECT_EQ(requests[0]->token, expected_token); if (run_switch_network) { - json_rpc_service_->SetNetwork(mojom::kGoerliChainId, - mojom::CoinType::ETH); + json_rpc_service_->SetNetwork(mojom::kGoerliChainId, mojom::CoinType::ETH, + absl::nullopt); } else { service_->NotifyAddSuggestTokenRequestsProcessed( approve, {suggested_token->contract_address}); @@ -739,8 +742,9 @@ class BraveWalletServiceUnitTest : public testing::Test { std::vector requests_out; service_->GetPendingAddSuggestTokenRequests(base::BindLambdaForTesting( [&](std::vector requests) { - for (const auto& request : requests) + for (const auto& request : requests) { requests_out.push_back(request.Clone()); + } run_loop.Quit(); })); run_loop.Run(); @@ -1409,8 +1413,9 @@ TEST_F(BraveWalletServiceUnitTest, NetworkListChangedEvent) { base::Value::List* list = update->FindList(kEthereumPrefKey); list->EraseIf([&](const base::Value& v) { auto* chain_id_value = v.GetDict().FindString("chainId"); - if (!chain_id_value) + if (!chain_id_value) { return false; + } return *chain_id_value == "0x5566"; }); } @@ -1780,8 +1785,9 @@ TEST_F(BraveWalletServiceUnitTest, MigrateUserAssetsAddPreloadingNetworks) { std::vector tokens; GetUserAssets(chain->chain_id, mojom::CoinType::ETH, &tokens); - if (chain->chain_id == mojom::kMainnetChainId) + if (chain->chain_id == mojom::kMainnetChainId) { native_asset->visible = false; + } if (chain->chain_id == mojom::kFantomMainnetChainId) { EXPECT_EQ(tokens.size(), 2u); @@ -2204,7 +2210,8 @@ TEST_F(BraveWalletServiceUnitTest, AddSuggestToken) { std::vector chain_ids = {mojom::kMainnetChainId, mojom::kGoerliChainId}; for (const std::string& chain_id : chain_ids) { - json_rpc_service_->SetNetwork(chain_id, mojom::CoinType::ETH); + json_rpc_service_->SetNetwork(chain_id, mojom::CoinType::ETH, + absl::nullopt); mojom::BlockchainTokenPtr usdc_from_blockchain_registry = mojom::BlockchainToken::New( "0x6B175474E89094C44Da98b954EedeAC495271d0F", "USD Coin", diff --git a/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc b/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc index 44d383a318b9..2cb3a73a89ba 100644 --- a/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc +++ b/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc @@ -8,7 +8,9 @@ #include #include +#include "base/containers/contains.h" #include "base/functional/bind.h" +#include "base/strings/strcat.h" #include "base/test/bind.h" #include "brave/components/brave_wallet/browser/brave_wallet_constants.h" #include "brave/components/brave_wallet/browser/eth_nonce_tracker.h" @@ -71,7 +73,7 @@ class EthPendingTxTrackerUnitTest : public testing::Test { TEST_F(EthPendingTxTrackerUnitTest, IsNonceTaken) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); EthPendingTxTracker pending_tx_tracker(&tx_state_manager, &service, &nonce_tracker); @@ -81,18 +83,23 @@ TEST_F(EthPendingTxTrackerUnitTest, IsNonceTaken) { EthAddress::FromHex("0x2f015c60e0be116b1f0cd534704db9c92118fb6a") .ToChecksumAddress()); meta.set_id(TxMeta::GenerateMetaID()); + meta.set_chain_id(mojom::kMainnetChainId); meta.tx()->set_nonce(uint256_t(123)); EXPECT_FALSE(pending_tx_tracker.IsNonceTaken(meta)); EthTxMeta meta_in_state; meta_in_state.set_id(TxMeta::GenerateMetaID()); + meta_in_state.set_chain_id(meta.chain_id()); meta_in_state.set_status(mojom::TransactionStatus::Confirmed); meta_in_state.set_from(meta.from()); - meta_in_state.tx()->set_nonce(uint256_t(123)); + meta_in_state.tx()->set_nonce(meta.tx()->nonce()); tx_state_manager.AddOrUpdateTx(meta_in_state); EXPECT_TRUE(pending_tx_tracker.IsNonceTaken(meta)); + + meta.set_chain_id(mojom::kGoerliChainId); + EXPECT_FALSE(pending_tx_tracker.IsNonceTaken(meta)); } TEST_F(EthPendingTxTrackerUnitTest, ShouldTxDropped) { @@ -100,21 +107,22 @@ TEST_F(EthPendingTxTrackerUnitTest, ShouldTxDropped) { EthAddress::FromHex("0x2f015c60e0be116b1f0cd534704db9c92118fb6a") .ToChecksumAddress(); JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); EthPendingTxTracker pending_tx_tracker(&tx_state_manager, &service, &nonce_tracker); - pending_tx_tracker.network_nonce_map_[addr] = uint256_t(3); + pending_tx_tracker.network_nonce_map_[addr][mojom::kMainnetChainId] = + uint256_t(3); EthTxMeta meta; meta.set_from(addr); meta.set_id(TxMeta::GenerateMetaID()); + meta.set_chain_id(mojom::kMainnetChainId); meta.set_tx_hash( "0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"); meta.tx()->set_nonce(uint256_t(1)); EXPECT_TRUE(pending_tx_tracker.ShouldTxDropped(meta)); - EXPECT_TRUE(pending_tx_tracker.network_nonce_map_.find(addr) == - pending_tx_tracker.network_nonce_map_.end()); + EXPECT_FALSE(base::Contains(pending_tx_tracker.network_nonce_map_, addr)); meta.tx()->set_nonce(uint256_t(4)); EXPECT_FALSE(pending_tx_tracker.ShouldTxDropped(meta)); @@ -123,23 +131,24 @@ TEST_F(EthPendingTxTrackerUnitTest, ShouldTxDropped) { // drop EXPECT_EQ(pending_tx_tracker.dropped_blocks_counter_[meta.tx_hash()], 3); EXPECT_TRUE(pending_tx_tracker.ShouldTxDropped(meta)); - EXPECT_TRUE(pending_tx_tracker.dropped_blocks_counter_.find(meta.tx_hash()) == - pending_tx_tracker.dropped_blocks_counter_.end()); + EXPECT_FALSE(base::Contains(pending_tx_tracker.dropped_blocks_counter_, + (meta.tx_hash()))); } TEST_F(EthPendingTxTrackerUnitTest, DropTransaction) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); EthPendingTxTracker pending_tx_tracker(&tx_state_manager, &service, &nonce_tracker); EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kMainnetChainId); meta.set_status(mojom::TransactionStatus::Submitted); tx_state_manager.AddOrUpdateTx(meta); pending_tx_tracker.DropTransaction(&meta); - EXPECT_EQ(tx_state_manager.GetTx("001"), nullptr); + EXPECT_EQ(tx_state_manager.GetTx(mojom::kMainnetChainId, "001"), nullptr); } TEST_F(EthPendingTxTrackerUnitTest, UpdatePendingTransactions) { @@ -150,36 +159,42 @@ TEST_F(EthPendingTxTrackerUnitTest, UpdatePendingTransactions) { EthAddress::FromHex("0x2f015c60e0be116b1f0cd534704db9c92118fb6b") .ToChecksumAddress(); JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); EthPendingTxTracker pending_tx_tracker(&tx_state_manager, &service, &nonce_tracker); base::RunLoop().RunUntilIdle(); - EthTxMeta meta; - meta.set_id("001"); - meta.set_from(addr1); - meta.set_status(mojom::TransactionStatus::Submitted); - tx_state_manager.AddOrUpdateTx(meta); - meta.set_id("002"); - meta.set_from(addr2); - meta.tx()->set_nonce(uint256_t(4)); - meta.set_status(mojom::TransactionStatus::Confirmed); - tx_state_manager.AddOrUpdateTx(meta); - meta.set_id("003"); - meta.set_from(addr2); - meta.tx()->set_nonce(uint256_t(4)); - meta.set_status(mojom::TransactionStatus::Submitted); - tx_state_manager.AddOrUpdateTx(meta); - meta.set_id("004"); - meta.set_from(addr2); - meta.tx()->set_nonce(uint256_t(4)); - meta.set_status(mojom::TransactionStatus::Signed); - tx_state_manager.AddOrUpdateTx(meta); - meta.set_id("005"); - meta.set_from(addr2); - meta.tx()->set_nonce(uint256_t(5)); - meta.set_status(mojom::TransactionStatus::Signed); - tx_state_manager.AddOrUpdateTx(meta); + + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId, + mojom::kSepoliaChainId}) { + EthTxMeta meta; + meta.set_id(base::StrCat({chain_id, "001"})); + meta.set_chain_id(chain_id); + meta.set_from(addr1); + meta.set_status(mojom::TransactionStatus::Submitted); + tx_state_manager.AddOrUpdateTx(meta); + meta.set_id(base::StrCat({chain_id, "002"})); + meta.set_from(addr2); + meta.tx()->set_nonce(uint256_t(4)); + meta.set_status(mojom::TransactionStatus::Confirmed); + tx_state_manager.AddOrUpdateTx(meta); + meta.set_id(base::StrCat({chain_id, "003"})); + meta.set_from(addr2); + meta.tx()->set_nonce(uint256_t(4)); + meta.set_status(mojom::TransactionStatus::Submitted); + tx_state_manager.AddOrUpdateTx(meta); + meta.set_id(base::StrCat({chain_id, "004"})); + meta.set_from(addr2); + meta.tx()->set_nonce(uint256_t(4)); + meta.set_status(mojom::TransactionStatus::Signed); + tx_state_manager.AddOrUpdateTx(meta); + meta.set_id(base::StrCat({chain_id, "005"})); + meta.set_from(addr2); + meta.tx()->set_nonce(uint256_t(5)); + meta.set_status(mojom::TransactionStatus::Signed); + tx_state_manager.AddOrUpdateTx(meta); + } test_url_loader_factory()->SetInterceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { @@ -203,26 +218,37 @@ TEST_F(EthPendingTxTrackerUnitTest, UpdatePendingTransactions) { "\"status\": \"0x1\"}}"); })); - size_t num_pending; - EXPECT_TRUE(pending_tx_tracker.UpdatePendingTransactions(&num_pending)); - EXPECT_EQ(4UL, num_pending); - WaitForResponse(); - auto meta_from_state = tx_state_manager.GetEthTx("001"); - ASSERT_NE(meta_from_state, nullptr); - EXPECT_EQ(meta_from_state->status(), mojom::TransactionStatus::Confirmed); - EXPECT_EQ(meta_from_state->from(), addr1); - EXPECT_EQ(meta_from_state->tx_receipt().contract_address, - "0xb60e8dd61c5d32be8058bb8eb970870f07233155"); - - meta_from_state = tx_state_manager.GetEthTx("003"); - ASSERT_EQ(meta_from_state, nullptr); - meta_from_state = tx_state_manager.GetEthTx("004"); - ASSERT_EQ(meta_from_state, nullptr); - meta_from_state = tx_state_manager.GetEthTx("005"); - ASSERT_NE(meta_from_state, nullptr); - EXPECT_EQ(meta_from_state->status(), mojom::TransactionStatus::Confirmed); - EXPECT_EQ(meta_from_state->tx_receipt().contract_address, - "0xb60e8dd61c5d32be8058bb8eb970870f07233155"); + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId, + mojom::kSepoliaChainId}) { + size_t num_pending; + std::set pending_chain_ids; + EXPECT_TRUE(pending_tx_tracker.UpdatePendingTransactions( + chain_id, &num_pending, &pending_chain_ids)); + EXPECT_EQ(4UL, num_pending); + EXPECT_EQ(1UL, pending_chain_ids.size()); + WaitForResponse(); + auto meta_from_state = + tx_state_manager.GetEthTx(chain_id, base::StrCat({chain_id, "001"})); + ASSERT_NE(meta_from_state, nullptr); + EXPECT_EQ(meta_from_state->status(), mojom::TransactionStatus::Confirmed); + EXPECT_EQ(meta_from_state->from(), addr1); + EXPECT_EQ(meta_from_state->tx_receipt().contract_address, + "0xb60e8dd61c5d32be8058bb8eb970870f07233155"); + + meta_from_state = + tx_state_manager.GetEthTx(chain_id, base::StrCat({chain_id, "003"})); + ASSERT_EQ(meta_from_state, nullptr); + meta_from_state = + tx_state_manager.GetEthTx(chain_id, base::StrCat({chain_id, "004"})); + ASSERT_EQ(meta_from_state, nullptr); + meta_from_state = + tx_state_manager.GetEthTx(chain_id, base::StrCat({chain_id, "005"})); + ASSERT_NE(meta_from_state, nullptr); + EXPECT_EQ(meta_from_state->status(), mojom::TransactionStatus::Confirmed); + EXPECT_EQ(meta_from_state->tx_receipt().contract_address, + "0xb60e8dd61c5d32be8058bb8eb970870f07233155"); + } } } // namespace brave_wallet diff --git a/browser/brave_wallet/ethereum_provider_impl_unittest.cc b/browser/brave_wallet/ethereum_provider_impl_unittest.cc index 2fb9381711f6..859833dab0ce 100644 --- a/browser/brave_wallet/ethereum_provider_impl_unittest.cc +++ b/browser/brave_wallet/ethereum_provider_impl_unittest.cc @@ -66,6 +66,7 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/l10n/l10n_util.h" @@ -141,10 +142,7 @@ class TestEventsListener : public brave_wallet::mojom::EventsListener { public: TestEventsListener() = default; - void ChainChangedEvent(const std::string& chain_id) override { - chain_id_ = chain_id; - chain_changed_fired_ = true; - } + MOCK_METHOD1(ChainChangedEvent, void(const std::string&)); void AccountsChangedEvent(const std::vector& accounts) override { lowercase_accounts_.resize(accounts.size()); @@ -160,11 +158,6 @@ class TestEventsListener : public brave_wallet::mojom::EventsListener { last_message_ = std::move(result); } - bool ChainChangedFired() const { - base::RunLoop().RunUntilIdle(); - return chain_changed_fired_; - } - bool AccountsChangedFired() const { base::RunLoop().RunUntilIdle(); return accounts_changed_fired_; @@ -175,11 +168,6 @@ class TestEventsListener : public brave_wallet::mojom::EventsListener { return message_event_fired_; } - std::string GetChainId() const { - base::RunLoop().RunUntilIdle(); - return chain_id_; - } - base::Value GetLastMessage() const { base::RunLoop().RunUntilIdle(); return last_message_.Clone(); @@ -195,21 +183,16 @@ class TestEventsListener : public brave_wallet::mojom::EventsListener { } void Reset() { - chain_id_.clear(); lowercase_accounts_.clear(); - chain_changed_fired_ = false; accounts_changed_fired_ = false; message_event_fired_ = false; - EXPECT_FALSE(ChainChangedFired()); EXPECT_FALSE(AccountsChangedFired()); EXPECT_FALSE(MessageEventFired()); } - bool chain_changed_fired_ = false; bool accounts_changed_fired_ = false; bool message_event_fired_ = false; std::vector lowercase_accounts_; - std::string chain_id_; base::Value last_message_; private: @@ -241,7 +224,7 @@ class EthereumProviderImplUnitTest : public testing::Test { JsonRpcServiceFactory::GetServiceForContext(browser_context()); json_rpc_service_->SetAPIRequestHelperForTesting( shared_url_loader_factory_); - SetNetwork("0x1"); + SetNetwork(mojom::kMainnetChainId, absl::nullopt); keyring_service_ = KeyringServiceFactory::GetServiceForContext(browser_context()); asset_ratio_service_ = @@ -277,10 +260,11 @@ class EthereumProviderImplUnitTest : public testing::Test { })); } - void SetNetwork(const std::string& chain_id) { + void SetNetwork(const std::string& chain_id, + const absl::optional<::url::Origin>& origin) { base::RunLoop run_loop; json_rpc_service_->SetNetwork( - chain_id, mojom::CoinType::ETH, + chain_id, mojom::CoinType::ETH, origin, base::BindLambdaForTesting([&run_loop](bool success) { EXPECT_TRUE(success); run_loop.Quit(); @@ -756,11 +740,12 @@ class EthereumProviderImplUnitTest : public testing::Test { return result; } - mojom::TransactionInfoPtr GetTransactionInfo(const std::string& meta_id) { + mojom::TransactionInfoPtr GetTransactionInfo(const std::string& chain_id, + const std::string& meta_id) { mojom::TransactionInfoPtr transaction_info; base::RunLoop run_loop; tx_service()->GetTransactionInfo( - mojom::CoinType::ETH, meta_id, + mojom::CoinType::ETH, chain_id, meta_id, base::BindLambdaForTesting([&](mojom::TransactionInfoPtr v) { transaction_info = std::move(v); run_loop.Quit(); @@ -769,11 +754,12 @@ class EthereumProviderImplUnitTest : public testing::Test { return transaction_info; } - std::vector GetAllTransactionInfo() { + std::vector GetAllTransactionInfo( + const std::string& chain_id) { std::vector transaction_infos; base::RunLoop run_loop; tx_service()->GetAllTransactionInfo( - mojom::CoinType::ETH, from(), + mojom::CoinType::ETH, chain_id, from(), base::BindLambdaForTesting( [&](std::vector v) { transaction_infos = std::move(v); @@ -783,13 +769,14 @@ class EthereumProviderImplUnitTest : public testing::Test { return transaction_infos; } - bool ApproveTransaction(const std::string& tx_meta_id, + bool ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id, mojom::ProviderError* error_out, std::string* error_message_out) { bool success; base::RunLoop run_loop; tx_service()->ApproveTransaction( - mojom::CoinType::ETH, tx_meta_id, + mojom::CoinType::ETH, chain_id, tx_meta_id, base::BindLambdaForTesting([&](bool v, mojom::ProviderErrorUnionPtr error, const std::string& error_message) { @@ -1136,14 +1123,18 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApproveTransaction) { callback_called = true; })); base::RunLoop().RunUntilIdle(); - std::vector infos = GetAllTransactionInfo(); + const auto& chain_id = + json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + std::vector infos = + GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); EXPECT_TRUE(base::EqualsCaseInsensitiveASCII(infos[0]->from_address, from())); EXPECT_EQ(infos[0]->tx_status, mojom::TransactionStatus::Unapproved); EXPECT_EQ(infos[0]->tx_hash, tx_hash); + EXPECT_EQ(infos[0]->chain_id, chain_id); - EXPECT_EQ(*GetTransactionInfo(infos[0]->id), *infos[0]); - EXPECT_TRUE(GetTransactionInfo("unknown_id").is_null()); + EXPECT_EQ(*GetTransactionInfo(chain_id, infos[0]->id), *infos[0]); + EXPECT_TRUE(GetTransactionInfo(chain_id, "unknown_id").is_null()); // Set an interceptor and just fake a common repsonse for // eth_getTransactionCount and eth_sendRawTransaction @@ -1152,13 +1143,14 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApproveTransaction) { mojom::ProviderError error = mojom::ProviderError::kUnknown; std::string error_message; - EXPECT_TRUE(ApproveTransaction(infos[0]->id, &error, &error_message)); + EXPECT_TRUE( + ApproveTransaction(chain_id, infos[0]->id, &error, &error_message)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(error, mojom::ProviderError::kSuccess); EXPECT_TRUE(error_message.empty()); EXPECT_TRUE(callback_called); - infos = GetAllTransactionInfo(); + infos = GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); EXPECT_TRUE(base::EqualsCaseInsensitiveASCII(infos[0]->from_address, from())); EXPECT_EQ(infos[0]->tx_status, mojom::TransactionStatus::Submitted); @@ -1283,11 +1275,15 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559Transaction) { callback_called = true; })); browser_task_environment_.RunUntilIdle(); - std::vector infos = GetAllTransactionInfo(); + const auto& chain_id = + json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + std::vector infos = + GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); EXPECT_TRUE(base::EqualsCaseInsensitiveASCII(infos[0]->from_address, from())); EXPECT_EQ(infos[0]->tx_status, mojom::TransactionStatus::Unapproved); EXPECT_EQ(infos[0]->tx_hash, tx_hash); + EXPECT_EQ(infos[0]->chain_id, chain_id); // Set an interceptor and just fake a common repsonse for // eth_getTransactionCount and eth_sendRawTransaction @@ -1296,17 +1292,19 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559Transaction) { mojom::ProviderError error = mojom::ProviderError::kUnknown; std::string error_message; - EXPECT_TRUE(ApproveTransaction(infos[0]->id, &error, &error_message)); + EXPECT_TRUE( + ApproveTransaction(chain_id, infos[0]->id, &error, &error_message)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(error, mojom::ProviderError::kSuccess); EXPECT_TRUE(error_message.empty()); EXPECT_TRUE(callback_called); - infos = GetAllTransactionInfo(); + infos = GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); EXPECT_TRUE(base::EqualsCaseInsensitiveASCII(infos[0]->from_address, from())); EXPECT_EQ(infos[0]->tx_status, mojom::TransactionStatus::Submitted); EXPECT_EQ(infos[0]->tx_hash, tx_hash); + EXPECT_EQ(infos[0]->chain_id, chain_id); } TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559TransactionNoChainId) { @@ -1315,7 +1313,7 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559TransactionNoChainId) { AddAccount(); GURL url("https://brave.com"); Navigate(url); - SetNetwork("0xaa36a7"); + SetNetwork(mojom::kSepoliaChainId, GetOrigin()); // Wait for EthTxStateManager::ChainChangedEvent to be called. browser_task_environment_.RunUntilIdle(); @@ -1368,13 +1366,14 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559TransactionNoChainId) { EXPECT_TRUE(error_message.empty()); })); browser_task_environment_.RunUntilIdle(); - std::vector infos = GetAllTransactionInfo(); + std::vector infos = + GetAllTransactionInfo(mojom::kSepoliaChainId); ASSERT_EQ(infos.size(), 2UL); ASSERT_TRUE(infos[0]->tx_data_union->is_eth_tx_data_1559()); EXPECT_EQ(infos[0]->tx_data_union->get_eth_tx_data_1559()->chain_id, - "0xaa36a7"); + mojom::kSepoliaChainId); EXPECT_EQ(infos[1]->tx_data_union->get_eth_tx_data_1559()->chain_id, - "0xaa36a7"); + mojom::kSepoliaChainId); } TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559TransactionError) { @@ -1776,7 +1775,8 @@ TEST_F(EthereumProviderImplUnitTest, RecoverAddress) { } TEST_F(EthereumProviderImplUnitTest, SignTypedMessage) { - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH), "0x1"); + EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, absl::nullopt), + "0x1"); CreateWallet(); AddAccount(); std::string signature; @@ -2002,16 +2002,31 @@ TEST_F(EthereumProviderImplUnitTest, SignMessageRequestQueue) { } TEST_F(EthereumProviderImplUnitTest, ChainChangedEvent) { - EXPECT_FALSE(observer_->ChainChangedFired()); - SetNetwork(mojom::kGoerliChainId); - EXPECT_TRUE(observer_->ChainChangedFired()); - EXPECT_EQ(mojom::kGoerliChainId, observer_->GetChainId()); + GURL url("https://brave.com"); + Navigate(url); + + EXPECT_CALL(*observer_, ChainChangedEvent(mojom::kGoerliChainId)).Times(1); + SetNetwork(mojom::kGoerliChainId, absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(observer_.get())); // Works a second time - observer_->Reset(); - SetNetwork(mojom::kMainnetChainId); - EXPECT_TRUE(observer_->ChainChangedFired()); - EXPECT_EQ(mojom::kMainnetChainId, observer_->GetChainId()); + EXPECT_CALL(*observer_, ChainChangedEvent(mojom::kMainnetChainId)).Times(1); + SetNetwork(mojom::kMainnetChainId, absl::nullopt); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(observer_.get())); + + EXPECT_CALL(*observer_, ChainChangedEvent(mojom::kSepoliaChainId)).Times(1); + SetNetwork(mojom::kSepoliaChainId, GetOrigin()); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(observer_.get())); + + // SetNetwork for other origin will be ignored. + EXPECT_CALL(*observer_, ChainChangedEvent(testing::_)).Times(0); + SetNetwork(mojom::kLocalhostChainId, + url::Origin::Create(GURL("https://a.com"))); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(observer_.get())); } TEST_F(EthereumProviderImplUnitTest, AccountsChangedEvent) { @@ -2124,7 +2139,10 @@ TEST_F(EthereumProviderImplUnitTest, EthSubscribe) { request_payload_json, base::JSON_PARSE_CHROMIUM_EXTENSIONS | base::JSONParserOptions::JSON_PARSE_RFC); response = CommonRequestOrSendAsync(request_payload.value()); - EXPECT_TRUE(provider_->eth_block_tracker_.IsRunning()); + + const auto& chain_id = + json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + EXPECT_TRUE(provider_->eth_block_tracker_.IsRunning(chain_id)); // The second unsubscribe should stop the block tracker request_payload_json = base::StringPrintf(R"({"id":1,"jsonrpc:": "2.0", @@ -2135,7 +2153,7 @@ TEST_F(EthereumProviderImplUnitTest, EthSubscribe) { request_payload_json, base::JSON_PARSE_CHROMIUM_EXTENSIONS | base::JSONParserOptions::JSON_PARSE_RFC); response = CommonRequestOrSendAsync(request_payload.value()); - EXPECT_FALSE(provider_->eth_block_tracker_.IsRunning()); + EXPECT_FALSE(provider_->eth_block_tracker_.IsRunning(chain_id)); } TEST_F(EthereumProviderImplUnitTest, EthSubscribeLogs) { @@ -2496,7 +2514,8 @@ TEST_F(EthereumProviderImplUnitTest, SwitchEthereumChain) { EXPECT_TRUE(brave_wallet_tab_helper()->IsShowingBubble()); brave_wallet_tab_helper()->CloseBubble(); EXPECT_FALSE(brave_wallet_tab_helper()->IsShowingBubble()); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH), "0xaa36a7"); + EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), + "0xaa36a7"); // one request per origin base::RunLoop run_loop; @@ -2517,7 +2536,8 @@ TEST_F(EthereumProviderImplUnitTest, SwitchEthereumChain) { l10n_util::GetStringUTF8(IDS_WALLET_ALREADY_IN_PROGRESS_ERROR)); json_rpc_service()->NotifySwitchChainRequestProcessed(true, GetOrigin()); run_loop.Run(); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH), "0x1"); + EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), + "0x1"); } TEST_F(EthereumProviderImplUnitTest, AddEthereumChainSwitchesForInnactive) { @@ -2552,7 +2572,8 @@ TEST_F(EthereumProviderImplUnitTest, AddEthereumChainSwitchesForInnactive) { run_loop.Run(); brave_wallet_tab_helper()->CloseBubble(); EXPECT_FALSE(brave_wallet_tab_helper()->IsShowingBubble()); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH), "0x5"); + EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), + "0x5"); } TEST_F(EthereumProviderImplUnitTest, AddSuggestToken) { diff --git a/browser/brave_wallet/keyring_service_unittest.cc b/browser/brave_wallet/keyring_service_unittest.cc index e836cf309c1b..d05964da2da9 100644 --- a/browser/brave_wallet/keyring_service_unittest.cc +++ b/browser/brave_wallet/keyring_service_unittest.cc @@ -668,7 +668,7 @@ class KeyringServiceUnitTest : public testing::Test { bool SetNetwork(const std::string& chain_id, mojom::CoinType coin) { bool result; base::RunLoop run_loop; - json_rpc_service_->SetNetwork(chain_id, coin, + json_rpc_service_->SetNetwork(chain_id, coin, absl::nullopt, base::BindLambdaForTesting([&](bool success) { result = success; run_loop.Quit(); diff --git a/browser/ui/webui/settings/brave_wallet_handler_unittest.cc b/browser/ui/webui/settings/brave_wallet_handler_unittest.cc index 69d21faf8746..3f40b9196df6 100644 --- a/browser/ui/webui/settings/brave_wallet_handler_unittest.cc +++ b/browser/ui/webui/settings/brave_wallet_handler_unittest.cc @@ -357,7 +357,8 @@ TEST(TestBraveWalletHandler, SetActiveNetwork) { ASSERT_TRUE(data.arg3()->is_bool()); EXPECT_EQ(data.arg3()->GetBool(), true); - EXPECT_EQ(brave_wallet::GetCurrentChainId(handler.prefs(), CoinType::ETH), + EXPECT_EQ(brave_wallet::GetCurrentChainId(handler.prefs(), CoinType::ETH, + absl::nullopt), "chain_id2"); } { @@ -371,7 +372,8 @@ TEST(TestBraveWalletHandler, SetActiveNetwork) { ASSERT_TRUE(data.arg3()->is_bool()); EXPECT_EQ(data.arg3()->GetBool(), false); - EXPECT_EQ(brave_wallet::GetCurrentChainId(handler.prefs(), CoinType::ETH), + EXPECT_EQ(brave_wallet::GetCurrentChainId(handler.prefs(), CoinType::ETH, + absl::nullopt), "chain_id2"); } } diff --git a/components/brave_wallet/browser/brave_wallet_utils_unittest.cc b/components/brave_wallet/browser/brave_wallet_utils_unittest.cc index 6b1939f1c0aa..94fda1be5425 100644 --- a/components/brave_wallet/browser/brave_wallet_utils_unittest.cc +++ b/components/brave_wallet/browser/brave_wallet_utils_unittest.cc @@ -1118,16 +1118,113 @@ TEST(BraveWalletUtilsUnitTest, GetPrefKeyForCoinType) { GetPrefKeyForCoinType(static_cast(2016))); } -TEST(BraveWalletUtilsUnitTest, GetCurrentChainId) { +TEST(BraveWalletUtilsUnitTest, CoinTypeToKeyringId) { + auto id = CoinTypeToKeyringId(mojom::CoinType::ETH, absl::nullopt); + EXPECT_EQ(id, mojom::kDefaultKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::ETH, "not_used"); + EXPECT_EQ(id, mojom::kDefaultKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::SOL, absl::nullopt); + EXPECT_EQ(id, mojom::kSolanaKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::SOL, "not_used"); + EXPECT_EQ(id, mojom::kSolanaKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::FIL, absl::nullopt); + EXPECT_EQ(id, mojom::kFilecoinKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::FIL, mojom::kFilecoinMainnet); + EXPECT_EQ(id, mojom::kFilecoinKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::FIL, mojom::kFilecoinTestnet); + EXPECT_EQ(id, mojom::kFilecoinTestnetKeyringId); + id = CoinTypeToKeyringId(mojom::CoinType::FIL, mojom::kLocalhostChainId); + EXPECT_EQ(id, mojom::kFilecoinTestnetKeyringId); + + EXPECT_DCHECK_DEATH( + CoinTypeToKeyringId(static_cast(2016), absl::nullopt)); + EXPECT_DCHECK_DEATH( + CoinTypeToKeyringId(static_cast(2016), "not_used")); + EXPECT_DCHECK_DEATH( + CoinTypeToKeyringId(mojom::CoinType::FIL, "not_supported")); +} + +TEST(BraveWalletUtilsUnitTest, GetAndSetCurrentChainId) { sync_preferences::TestingPrefServiceSyncable prefs; RegisterProfilePrefs(prefs.registry()); - // default value - EXPECT_EQ(GetCurrentChainId(&prefs, mojom::CoinType::ETH), - mojom::kMainnetChainId); - EXPECT_EQ(GetCurrentChainId(&prefs, mojom::CoinType::SOL), - mojom::kSolanaMainnet); - EXPECT_EQ(GetCurrentChainId(&prefs, mojom::CoinType::FIL), - mojom::kFilecoinMainnet); + const base::flat_map default_chain_ids = { + {mojom::CoinType::ETH, mojom::kMainnetChainId}, + {mojom::CoinType::SOL, mojom::kSolanaMainnet}, + {mojom::CoinType::FIL, mojom::kFilecoinMainnet}}; + const base::flat_map new_default_chain_ids = { + {mojom::CoinType::ETH, mojom::kGoerliChainId}, + {mojom::CoinType::SOL, mojom::kSolanaTestnet}, + {mojom::CoinType::FIL, mojom::kFilecoinTestnet}}; + for (const auto coin_type : + {mojom::CoinType::ETH, mojom::CoinType::SOL, mojom::CoinType::FIL}) { + // default value + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + default_chain_ids.at(coin_type)); + + // fallback to default + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com"))), + default_chain_ids.at(coin_type)); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, url::Origin()), + default_chain_ids.at(coin_type)); + EXPECT_EQ( + GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("file:///etc/passwd"))), + default_chain_ids.at(coin_type)); + + // unknown chain_id + EXPECT_FALSE(SetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com")), + "0x5566")); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com"))), + default_chain_ids.at(coin_type)); + EXPECT_FALSE(SetCurrentChainId(&prefs, coin_type, absl::nullopt, "0x5566")); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + default_chain_ids.at(coin_type)); + + EXPECT_TRUE(SetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com")), + mojom::kLocalhostChainId)); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com"))), + mojom::kLocalhostChainId); + // other origin still use default + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://b.com"))), + default_chain_ids.at(coin_type)); + + // opaque cannot change the default + EXPECT_FALSE(SetCurrentChainId(&prefs, coin_type, url::Origin(), + mojom::kLocalhostChainId)); + EXPECT_FALSE(SetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("about:blank")), + mojom::kLocalhostChainId)); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + default_chain_ids.at(coin_type)); + + // now we change the default + EXPECT_TRUE(SetCurrentChainId(&prefs, coin_type, absl::nullopt, + new_default_chain_ids.at(coin_type))); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + new_default_chain_ids.at(coin_type)); + // should not affect per origin pref + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("https://a.com"))), + mojom::kLocalhostChainId); + + // non http/https scheme will change the default + EXPECT_TRUE(SetCurrentChainId( + &prefs, coin_type, url::Origin::Create(GURL("file:///etc/passwd")), + default_chain_ids.at(coin_type))); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + default_chain_ids.at(coin_type)); + EXPECT_TRUE(SetCurrentChainId(&prefs, coin_type, + url::Origin::Create(GURL("chrome://wallet")), + new_default_chain_ids.at(coin_type))); + EXPECT_EQ(GetCurrentChainId(&prefs, coin_type, absl::nullopt), + new_default_chain_ids.at(coin_type)); + } } TEST(BraveWalletUtilsUnitTest, eTLDPlusOne) { diff --git a/components/brave_wallet/browser/eth_block_tracker_unittest.cc b/components/brave_wallet/browser/eth_block_tracker_unittest.cc index 9040094295ed..d42fbbdf2dd8 100644 --- a/components/brave_wallet/browser/eth_block_tracker_unittest.cc +++ b/components/brave_wallet/browser/eth_block_tracker_unittest.cc @@ -8,6 +8,7 @@ #include #include +#include "base/scoped_observation.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" @@ -17,28 +18,30 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" +using testing::_; + namespace brave_wallet { namespace { -class TrackerObserver : public EthBlockTracker::Observer { + +class MockTrackerObserver : public EthBlockTracker::Observer { public: - void OnLatestBlock(uint256_t block_num) override { - block_num_ = block_num; - ++latest_block_fired_; - } - void OnNewBlock(uint256_t block_num) override { - ++new_block_fired_; - block_num_from_new_block_ = block_num; + explicit MockTrackerObserver(EthBlockTracker* tracker) { + observation_.Observe(tracker); } - size_t latest_block_fired_ = 0; - size_t new_block_fired_ = 0; - uint256_t block_num_ = 0; - uint256_t block_num_from_new_block_ = 0; + MOCK_METHOD2(OnLatestBlock, void(const std::string&, uint256_t)); + MOCK_METHOD2(OnNewBlock, void(const std::string&, uint256_t)); + + private: + base::ScopedObservation + observation_{this}; }; + } // namespace class EthBlockTrackerUnitTest : public testing::Test { @@ -73,26 +76,36 @@ TEST_F(EthBlockTrackerUnitTest, Timer) { bool request_sent = false; url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( [&](const network::ResourceRequest& request) { request_sent = true; })); - EXPECT_FALSE(tracker.IsRunning()); - tracker.Start(base::Seconds(5)); + EXPECT_FALSE(tracker.IsRunning(mojom::kMainnetChainId)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); task_environment_.FastForwardBy(base::Seconds(1)); - EXPECT_TRUE(tracker.IsRunning()); + EXPECT_TRUE(tracker.IsRunning(mojom::kMainnetChainId)); EXPECT_FALSE(request_sent); task_environment_.FastForwardBy(base::Seconds(4)); EXPECT_TRUE(request_sent); + EXPECT_FALSE(tracker.IsRunning(mojom::kGoerliChainId)); // interval will be changed - tracker.Start(base::Seconds(30)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(30)); request_sent = false; task_environment_.FastForwardBy(base::Seconds(5)); EXPECT_FALSE(request_sent); task_environment_.FastForwardBy(base::Seconds(25)); EXPECT_TRUE(request_sent); + EXPECT_FALSE(tracker.IsRunning(mojom::kGoerliChainId)); + + tracker.Stop(mojom::kMainnetChainId); + EXPECT_FALSE(tracker.IsRunning(mojom::kMainnetChainId)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + EXPECT_TRUE(tracker.IsRunning(mojom::kMainnetChainId)); request_sent = false; + tracker.Start(mojom::kGoerliChainId, base::Seconds(10)); + EXPECT_TRUE(tracker.IsRunning(mojom::kGoerliChainId)); tracker.Stop(); - EXPECT_FALSE(tracker.IsRunning()); - task_environment_.FastForwardBy(base::Seconds(40)); + EXPECT_FALSE(tracker.IsRunning(mojom::kMainnetChainId)); + EXPECT_FALSE(tracker.IsRunning(mojom::kGoerliChainId)); + task_environment_.FastForwardBy(base::Seconds(10)); EXPECT_FALSE(request_sent); } @@ -105,54 +118,64 @@ TEST_F(EthBlockTrackerUnitTest, GetBlockNumber) { GetResponseString()); })); response_block_num_ = 1; - TrackerObserver observer; - tracker.AddObserver(&observer); + MockTrackerObserver observer(&tracker); - tracker.Start(base::Seconds(5)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + tracker.Start(mojom::kGoerliChainId, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlock(mojom::kMainnetChainId, 1)).Times(1); + EXPECT_CALL(observer, OnLatestBlock(mojom::kGoerliChainId, 1)).Times(2); + EXPECT_CALL(observer, OnNewBlock(mojom::kMainnetChainId, 1)).Times(1); + EXPECT_CALL(observer, OnNewBlock(mojom::kGoerliChainId, 1)).Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.block_num_, uint256_t(1)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(1)); - EXPECT_EQ(observer.latest_block_fired_, 1u); - EXPECT_EQ(observer.new_block_fired_, 1u); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(1)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(1)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(1)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); response_block_num_ = 3; - tracker.Start(base::Seconds(5)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + tracker.Start(mojom::kGoerliChainId, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlock(mojom::kMainnetChainId, 3)).Times(1); + EXPECT_CALL(observer, OnLatestBlock(mojom::kGoerliChainId, 3)).Times(2); + EXPECT_CALL(observer, OnNewBlock(mojom::kMainnetChainId, 3)).Times(1); + EXPECT_CALL(observer, OnNewBlock(mojom::kGoerliChainId, 3)).Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.block_num_, uint256_t(3)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(3)); - EXPECT_EQ(observer.latest_block_fired_, 2u); - EXPECT_EQ(observer.new_block_fired_, 2u); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(3)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(3)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(3)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); // Still response_block_num_ 3 + EXPECT_CALL(observer, OnLatestBlock(mojom::kMainnetChainId, 3)).Times(1); + EXPECT_CALL(observer, OnLatestBlock(mojom::kGoerliChainId, 3)).Times(3); + EXPECT_CALL(observer, OnNewBlock(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.block_num_, uint256_t(3)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(3)); - EXPECT_EQ(observer.latest_block_fired_, 3u); - EXPECT_EQ(observer.new_block_fired_, 2u); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(3)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(3)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(3)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); tracker.Stop(); response_block_num_ = 4; // Explicity check latest block won't trigger observer nor update current // block - bool callback_called = false; - tracker.CheckForLatestBlock(base::BindLambdaForTesting( - [&](uint256_t block_num, brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - callback_called = true; - EXPECT_EQ(error, mojom::ProviderError::kSuccess); - EXPECT_TRUE(error_message.empty()); - EXPECT_EQ(block_num, uint256_t(4)); - })); - task_environment_.RunUntilIdle(); - EXPECT_TRUE(callback_called); - EXPECT_EQ(observer.block_num_, uint256_t(3)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(3)); - EXPECT_EQ(observer.latest_block_fired_, 3u); - EXPECT_EQ(observer.new_block_fired_, 2u); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(3)); + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId}) { + SCOPED_TRACE(chain_id); + EXPECT_CALL(observer, OnLatestBlock(_, _)).Times(0); + EXPECT_CALL(observer, OnNewBlock(_, _)).Times(0); + base::RunLoop run_loop; + tracker.CheckForLatestBlock( + chain_id, + base::BindLambdaForTesting([&](uint256_t block_num, + brave_wallet::mojom::ProviderError error, + const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kSuccess); + EXPECT_TRUE(error_message.empty()); + EXPECT_EQ(block_num, uint256_t(4)); + run_loop.Quit(); + })); + run_loop.Run(); + EXPECT_EQ(tracker.GetCurrentBlock(chain_id), uint256_t(3)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + } } TEST_F(EthBlockTrackerUnitTest, GetBlockNumberInvalidResponseJSON) { @@ -165,28 +188,34 @@ TEST_F(EthBlockTrackerUnitTest, GetBlockNumberInvalidResponseJSON) { })); response_block_num_ = 3; - TrackerObserver observer; - tracker.AddObserver(&observer); + MockTrackerObserver observer(&tracker); - tracker.Start(base::Seconds(5)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + tracker.Start(mojom::kGoerliChainId, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlock(_, _)).Times(0); + EXPECT_CALL(observer, OnNewBlock(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_block_fired_, 0u); - EXPECT_EQ(observer.block_num_, uint256_t(0)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(0)); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(0)); - - bool callback_called = false; - tracker.CheckForLatestBlock(base::BindLambdaForTesting( - [&](uint256_t block_num, brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - callback_called = true; - EXPECT_EQ(error, mojom::ProviderError::kParsingError); - EXPECT_EQ(error_message, - l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); - EXPECT_EQ(block_num, uint256_t(0)); - })); - task_environment_.RunUntilIdle(); - EXPECT_TRUE(callback_called); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(0)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(0)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId}) { + SCOPED_TRACE(chain_id); + base::RunLoop run_loop; + tracker.CheckForLatestBlock( + chain_id, + base::BindLambdaForTesting([&](uint256_t block_num, + brave_wallet::mojom::ProviderError error, + const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kParsingError); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); + EXPECT_EQ(block_num, uint256_t(0)); + run_loop.Quit(); + })); + run_loop.Run(); + } } TEST_F(EthBlockTrackerUnitTest, GetBlockNumberLimitExceeded) { @@ -206,27 +235,33 @@ TEST_F(EthBlockTrackerUnitTest, GetBlockNumberLimitExceeded) { })); response_block_num_ = 3; - TrackerObserver observer; - tracker.AddObserver(&observer); + MockTrackerObserver observer(&tracker); - tracker.Start(base::Seconds(5)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + tracker.Start(mojom::kGoerliChainId, base::Seconds(2)); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_block_fired_, 0u); - EXPECT_EQ(observer.block_num_, uint256_t(0)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(0)); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(0)); - - bool callback_called = false; - tracker.CheckForLatestBlock(base::BindLambdaForTesting( - [&](uint256_t block_num, brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - callback_called = true; - EXPECT_EQ(error, mojom::ProviderError::kLimitExceeded); - EXPECT_EQ(error_message, "Request exceeds defined limit"); - EXPECT_EQ(block_num, uint256_t(0)); - })); - task_environment_.RunUntilIdle(); - EXPECT_TRUE(callback_called); + EXPECT_CALL(observer, OnLatestBlock(testing::_, testing::_)).Times(0); + EXPECT_CALL(observer, OnNewBlock(testing::_, testing::_)).Times(0); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(0)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(0)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId}) { + SCOPED_TRACE(chain_id); + base::RunLoop run_loop; + tracker.CheckForLatestBlock( + chain_id, + base::BindLambdaForTesting([&](uint256_t block_num, + brave_wallet::mojom::ProviderError error, + const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kLimitExceeded); + EXPECT_EQ(error_message, "Request exceeds defined limit"); + EXPECT_EQ(block_num, uint256_t(0)); + run_loop.Quit(); + })); + run_loop.Run(); + } } TEST_F(EthBlockTrackerUnitTest, GetBlockNumberRequestTimeout) { @@ -239,28 +274,34 @@ TEST_F(EthBlockTrackerUnitTest, GetBlockNumberRequestTimeout) { })); response_block_num_ = 3; - TrackerObserver observer; - tracker.AddObserver(&observer); + MockTrackerObserver observer(&tracker); - tracker.Start(base::Seconds(5)); + tracker.Start(mojom::kMainnetChainId, base::Seconds(5)); + tracker.Start(mojom::kGoerliChainId, base::Seconds(2)); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_block_fired_, 0u); - EXPECT_EQ(observer.block_num_, uint256_t(0)); - EXPECT_EQ(observer.block_num_from_new_block_, uint256_t(0)); - EXPECT_EQ(tracker.GetCurrentBlock(), uint256_t(0)); - - bool callback_called = false; - tracker.CheckForLatestBlock(base::BindLambdaForTesting( - [&](uint256_t block_num, brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - callback_called = true; - EXPECT_EQ(error, mojom::ProviderError::kInternalError); - EXPECT_EQ(error_message, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); - EXPECT_EQ(block_num, uint256_t(0)); - })); - task_environment_.RunUntilIdle(); - EXPECT_TRUE(callback_called); + EXPECT_CALL(observer, OnLatestBlock(testing::_, testing::_)).Times(0); + EXPECT_CALL(observer, OnNewBlock(testing::_, testing::_)).Times(0); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kMainnetChainId), uint256_t(0)); + EXPECT_EQ(tracker.GetCurrentBlock(mojom::kGoerliChainId), uint256_t(0)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + for (const std::string& chain_id : + {mojom::kMainnetChainId, mojom::kGoerliChainId}) { + SCOPED_TRACE(chain_id); + base::RunLoop run_loop; + tracker.CheckForLatestBlock( + chain_id, + base::BindLambdaForTesting([&](uint256_t block_num, + brave_wallet::mojom::ProviderError error, + const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kInternalError); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + EXPECT_EQ(block_num, uint256_t(0)); + run_loop.Quit(); + })); + run_loop.Run(); + } } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/eth_nonce_tracker_unittest.cc b/components/brave_wallet/browser/eth_nonce_tracker_unittest.cc index 015bafc25527..67b14e5729a0 100644 --- a/components/brave_wallet/browser/eth_nonce_tracker_unittest.cc +++ b/components/brave_wallet/browser/eth_nonce_tracker_unittest.cc @@ -54,12 +54,14 @@ class EthNonceTrackerUnitTest : public testing::Test { void WaitForResponse() { task_environment_.RunUntilIdle(); } void GetNextNonce(EthNonceTracker* tracker, + const std::string& chain_id, const std::string& address, bool expected_success, uint256_t expected_nonce) { base::RunLoop run_loop; tracker->GetNextNonce( - address, base::BindLambdaForTesting([&](bool success, uint256_t nonce) { + chain_id, address, + base::BindLambdaForTesting([&](bool success, uint256_t nonce) { EXPECT_EQ(expected_success, success); EXPECT_EQ(expected_nonce, nonce); run_loop.Quit(); @@ -78,6 +80,11 @@ class EthNonceTrackerUnitTest : public testing::Test { mojom::CoinType::ETH) .spec(), GetResultString()); + url_loader_factory_.AddResponse( + brave_wallet::GetNetworkURL(GetPrefs(), mojom::kMainnetChainId, + mojom::CoinType::ETH) + .spec(), + GetResultString()); } private: @@ -96,30 +103,26 @@ class EthNonceTrackerUnitTest : public testing::Test { TEST_F(EthNonceTrackerUnitTest, GetNonce) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - base::RunLoop run_loop; - service.SetNetwork( - brave_wallet::mojom::kLocalhostChainId, mojom::CoinType::ETH, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); SetTransactionCount(2); const std::string address("0x2f015c60e0be116b1f0cd534704db9c92118fb6a"); // tx count: 2, confirmed: null, pending: null - GetNextNonce(&nonce_tracker, address, true, 2); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, address, true, 2); // tx count: 2, confirmed: [2], pending: null EthTxMeta meta; meta.set_id(TxMeta::GenerateMetaID()); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from(EthAddress::FromHex(address).ToChecksumAddress()); meta.set_status(mojom::TransactionStatus::Confirmed); meta.tx()->set_nonce(uint256_t(2)); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, 3); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, address, true, 3); // tx count: 2, confirmed: [2, 3], pending: null meta.set_id(TxMeta::GenerateMetaID()); @@ -127,7 +130,7 @@ TEST_F(EthNonceTrackerUnitTest, GetNonce) { meta.tx()->set_nonce(uint256_t(3)); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, 4); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, address, true, 4); // tx count: 2, confirmed: [2, 3], pending: [4, 4] meta.set_status(mojom::TransactionStatus::Submitted); @@ -137,24 +140,22 @@ TEST_F(EthNonceTrackerUnitTest, GetNonce) { meta.set_id(TxMeta::GenerateMetaID()); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, 5); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, address, true, 5); // tx count: 2, confirmed: [2, 3], pending: [4, 4], sign: [5] meta.set_status(mojom::TransactionStatus::Signed); meta.set_id(TxMeta::GenerateMetaID()); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, 5); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, address, true, 5); + + // tx count: 2, confirmed: null, pending: null (mainnet) + GetNextNonce(&nonce_tracker, mojom::kMainnetChainId, address, true, 2); } TEST_F(EthNonceTrackerUnitTest, NonceLock) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - base::RunLoop run_loop; - service.SetNetwork( - brave_wallet::mojom::kLocalhostChainId, mojom::CoinType::ETH, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); - EthTxStateManager tx_state_manager(GetPrefs(), &service); + EthTxStateManager tx_state_manager(GetPrefs()); EthNonceTracker nonce_tracker(&tx_state_manager, &service); SetTransactionCount(4); @@ -162,11 +163,13 @@ TEST_F(EthNonceTrackerUnitTest, NonceLock) { base::Lock* lock = nonce_tracker.GetLock(); lock->Acquire(); const std::string addr("0x2f015c60e0be116b1f0cd534704db9c92118fb6a"); - GetNextNonce(&nonce_tracker, addr, false, 0); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, addr, false, 0); + GetNextNonce(&nonce_tracker, mojom::kMainnetChainId, addr, false, 0); lock->Release(); - GetNextNonce(&nonce_tracker, addr, true, 4); + GetNextNonce(&nonce_tracker, mojom::kLocalhostChainId, addr, true, 4); + GetNextNonce(&nonce_tracker, mojom::kMainnetChainId, addr, true, 4); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/eth_tx_manager_unittest.cc b/components/brave_wallet/browser/eth_tx_manager_unittest.cc index d55a84ebbbd1..1ff37bcaf542 100644 --- a/components/brave_wallet/browser/eth_tx_manager_unittest.cc +++ b/components/brave_wallet/browser/eth_tx_manager_unittest.cc @@ -259,14 +259,6 @@ class EthTxManagerUnitTest : public testing::Test { tx_service_ = std::make_unique( json_rpc_service_.get(), keyring_service_.get(), &profile_prefs_); - base::RunLoop run_loop; - json_rpc_service_->SetNetwork(brave_wallet::mojom::kLocalhostChainId, - mojom::CoinType::ETH, - base::BindLambdaForTesting([&](bool success) { - EXPECT_TRUE(success); - run_loop.Quit(); - })); - run_loop.Run(); keyring_service_->CreateWallet("testing123", base::DoNothing()); base::RunLoop().RunUntilIdle(); keyring_service_->AddAccount("Account 1", mojom::CoinType::ETH, @@ -311,6 +303,7 @@ class EthTxManagerUnitTest : public testing::Test { } void DoSpeedupOrCancelTransactionSuccess( + const std::string& chain_id, const std::string& nonce, const std::string& gas_price, const std::vector& data, @@ -328,6 +321,7 @@ class EthTxManagerUnitTest : public testing::Test { EthTxMeta meta; meta.set_id(orig_meta_id); + meta.set_chain_id(chain_id); meta.set_from( EthAddress::FromHex("0xbe862ad9abfe6f22bcb087716c7d89a26051f74a") .ToChecksumAddress()); @@ -338,7 +332,7 @@ class EthTxManagerUnitTest : public testing::Test { bool callback_called = false; eth_tx_manager()->SpeedupOrCancelTransaction( - orig_meta_id, cancel, + chain_id, orig_meta_id, cancel, base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, tx_meta_id)); base::RunLoop().RunUntilIdle(); @@ -346,6 +340,7 @@ class EthTxManagerUnitTest : public testing::Test { } void DoSpeedupOrCancel1559TransactionSuccess( + const std::string& chain_id, const std::string& nonce, const std::vector& data, const std::string& max_priority_fee_per_gas, @@ -367,6 +362,7 @@ class EthTxManagerUnitTest : public testing::Test { EthTxMeta meta; meta.set_id(orig_meta_id); + meta.set_chain_id(chain_id); meta.set_from( EthAddress::FromHex("0xbe862ad9abfe6f22bcb087716c7d89a26051f74a") .ToChecksumAddress()); @@ -377,18 +373,19 @@ class EthTxManagerUnitTest : public testing::Test { bool callback_called = false; eth_tx_manager()->SpeedupOrCancelTransaction( - orig_meta_id, cancel, + chain_id, orig_meta_id, cancel, base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); } - void DoSpeedupOrCancelTransactionFailure(const std::string& orig_meta_id, + void DoSpeedupOrCancelTransactionFailure(const std::string& chain_id, + const std::string& orig_meta_id, bool cancel) { bool callback_called = false; eth_tx_manager()->SpeedupOrCancelTransaction( - orig_meta_id, false, + chain_id, orig_meta_id, false, base::BindOnce(&AddUnapprovedTransactionFailureCallback, &callback_called)); base::RunLoop().RunUntilIdle(); @@ -396,30 +393,36 @@ class EthTxManagerUnitTest : public testing::Test { } void AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataUnionPtr tx_data, const std::string& from, const absl::optional& origin, EthTxManager::AddUnapprovedTransactionCallback callback) { - eth_tx_manager()->AddUnapprovedTransaction( - std::move(tx_data), from, origin, absl::nullopt, std::move(callback)); + eth_tx_manager()->AddUnapprovedTransaction(chain_id, std::move(tx_data), + from, origin, absl::nullopt, + std::move(callback)); } void AddUnapprovedTransaction( + const std::string& chain_id, mojom::TxDataPtr tx_data, const std::string& from, EthTxManager::AddUnapprovedTransactionCallback callback, const absl::optional& group_id = absl::nullopt) { - eth_tx_manager()->AddUnapprovedTransaction( - std::move(tx_data), from, GetOrigin(), group_id, std::move(callback)); + eth_tx_manager()->AddUnapprovedTransaction(chain_id, std::move(tx_data), + from, GetOrigin(), group_id, + std::move(callback)); } void AddUnapproved1559Transaction( + const std::string& chain_id, mojom::TxData1559Ptr tx_data, const std::string& from, EthTxManager::AddUnapprovedTransactionCallback callback, const absl::optional& group_id = absl::nullopt) { - eth_tx_manager()->AddUnapproved1559Transaction( - std::move(tx_data), from, GetOrigin(), group_id, std::move(callback)); + eth_tx_manager()->AddUnapproved1559Transaction(chain_id, std::move(tx_data), + from, GetOrigin(), group_id, + std::move(callback)); } void TestMakeERC1155TransferFromDataTxType( @@ -488,13 +491,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapprovedTransactionWithGasPriceAndGasLimit) { std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -514,6 +518,7 @@ TEST_F(EthTxManagerUnitTest, WalletOrigin) { std::string tx_meta_id; AddUnapprovedTransaction( + mojom::kLocalhostChainId, mojom::TxDataUnion::NewEthTxData(std::move(tx_data)), from(), absl::nullopt, base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, @@ -521,7 +526,8 @@ TEST_F(EthTxManagerUnitTest, WalletOrigin) { base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->origin(), url::Origin::Create(GURL("chrome://wallet"))); @@ -536,6 +542,7 @@ TEST_F(EthTxManagerUnitTest, SomeSiteOrigin) { std::string tx_meta_id; AddUnapprovedTransaction( + mojom::kLocalhostChainId, mojom::TxDataUnion::NewEthTxData(std::move(tx_data)), from(), url::Origin::Create(GURL("https://some.site.com")), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, @@ -543,7 +550,8 @@ TEST_F(EthTxManagerUnitTest, SomeSiteOrigin) { base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->origin(), @@ -561,25 +569,27 @@ TEST_F(EthTxManagerUnitTest, // Legacy transaction with group_id AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id), "mockGroupId"); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); // Legacy transaction with empty group_id callback_called = false; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), absl::nullopt); @@ -592,25 +602,27 @@ TEST_F(EthTxManagerUnitTest, // EIP-1559 transaction with group_id callback_called = false; AddUnapproved1559Transaction( - tx_data_1559.Clone(), from(), + mojom::kLocalhostChainId, tx_data_1559.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id), "mockGroupId1559"); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId1559"); // EIP-1559 transaction with empty group_id callback_called = false; AddUnapproved1559Transaction( - std::move(tx_data_1559), from(), + mojom::kLocalhostChainId, std::move(tx_data_1559), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), absl::nullopt); } @@ -625,13 +637,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapprovedTransactionWithoutGasLimit) { std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -675,12 +688,13 @@ TEST_F(EthTxManagerUnitTest, AddUnapprovedTransactionWithoutGasLimit) { SetErrorInterceptor(); callback_called = false; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_TRUE(HexValueToUint256(gas_price, &gas_price_value)); EXPECT_TRUE( @@ -699,13 +713,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapprovedTransactionWithoutGasPrice) { std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -719,7 +734,7 @@ TEST_F(EthTxManagerUnitTest, AddUnapprovedTransactionWithoutGasPrice) { SetErrorInterceptor(); callback_called = false; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionFailureCallback, &callback_called)); base::RunLoop().RunUntilIdle(); @@ -736,13 +751,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -755,7 +771,7 @@ TEST_F(EthTxManagerUnitTest, SetErrorInterceptor(); callback_called = false; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionFailureCallback, &callback_called)); base::RunLoop().RunUntilIdle(); @@ -772,13 +788,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -798,13 +815,14 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_price_value; @@ -817,7 +835,8 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { // Fail if transaction is not found. callback_called = false; eth_tx_manager()->SetGasPriceAndLimitForUnapprovedTransaction( - "not_exist", "0x1", Uint256ValueToHex(kDefaultSendEthGasLimit), + mojom::kLocalhostChainId, "not_exist", "0x1", + Uint256ValueToHex(kDefaultSendEthGasLimit), base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -828,7 +847,8 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { // Fail if passing an empty gas price. callback_called = false; eth_tx_manager()->SetGasPriceAndLimitForUnapprovedTransaction( - tx_meta_id, "", Uint256ValueToHex(kDefaultSendEthGasLimit), + mojom::kLocalhostChainId, tx_meta_id, "", + Uint256ValueToHex(kDefaultSendEthGasLimit), base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -839,7 +859,8 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { // Fail if passing an empty gas limit. callback_called = false; eth_tx_manager()->SetGasPriceAndLimitForUnapprovedTransaction( - tx_meta_id, "0x1", "", base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, tx_meta_id, "0x1", "", + base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; })); @@ -862,7 +883,8 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { callback_called = false; eth_tx_manager()->SetGasPriceAndLimitForUnapprovedTransaction( - tx_meta_id, update_gas_price_hex_string, update_gas_limit_hex_string, + mojom::kLocalhostChainId, tx_meta_id, update_gas_price_hex_string, + update_gas_limit_hex_string, base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); callback_called = true; @@ -872,7 +894,8 @@ TEST_F(EthTxManagerUnitTest, SetGasPriceAndLimitForUnapprovedTransaction) { EXPECT_TRUE(observer.TxUpdated()); // Get the updated TX. - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->gas_price(), update_gas_price); EXPECT_EQ(tx_meta->tx()->gas_limit(), update_gas_limit); @@ -887,13 +910,14 @@ TEST_F(EthTxManagerUnitTest, SetDataForUnapprovedTransaction) { bool callback_called = false; std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->data(), initial_data); @@ -902,7 +926,8 @@ TEST_F(EthTxManagerUnitTest, SetDataForUnapprovedTransaction) { std::vector new_data1; base::RunLoop run_loop; eth_tx_manager()->SetDataForUnapprovedTransaction( - "", new_data1, base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, "", new_data1, + base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -915,7 +940,8 @@ TEST_F(EthTxManagerUnitTest, SetDataForUnapprovedTransaction) { // Change the data base::RunLoop run_loop2; eth_tx_manager()->SetDataForUnapprovedTransaction( - tx_meta_id, new_data2, base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, tx_meta_id, new_data2, + base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); run_loop2.Quit(); })); @@ -925,7 +951,8 @@ TEST_F(EthTxManagerUnitTest, SetDataForUnapprovedTransaction) { EXPECT_TRUE(observer.TxUpdated()); // Get the updated TX. - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->data(), new_data2); } @@ -938,13 +965,14 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { bool callback_called = false; std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->nonce(), 6ULL); @@ -952,7 +980,8 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { // Invalid tx_meta id should fail base::RunLoop run_loop; eth_tx_manager()->SetNonceForUnapprovedTransaction( - "", "0x02", base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, "", "0x02", + base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop.Quit(); })); @@ -962,7 +991,7 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { // Invalid nonce value should fail base::RunLoop run_loop2; eth_tx_manager()->SetNonceForUnapprovedTransaction( - tx_meta_id, "invalid nonce", + mojom::kLocalhostChainId, tx_meta_id, "invalid nonce", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); run_loop2.Quit(); @@ -976,7 +1005,8 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { // Change the nonce base::RunLoop run_loop3; eth_tx_manager()->SetNonceForUnapprovedTransaction( - tx_meta_id, "0x3", base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, tx_meta_id, "0x3", + base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); run_loop3.Quit(); })); @@ -986,7 +1016,8 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { EXPECT_TRUE(observer.TxUpdated()); // Get the updated TX. - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->nonce(), 3ULL); @@ -994,7 +1025,8 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { observer.SetExpectedNonce(""); base::RunLoop run_loop4; eth_tx_manager()->SetNonceForUnapprovedTransaction( - tx_meta_id, "", base::BindLambdaForTesting([&](bool success) { + mojom::kLocalhostChainId, tx_meta_id, "", + base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); run_loop4.Quit(); })); @@ -1004,7 +1036,8 @@ TEST_F(EthTxManagerUnitTest, SetNonceForUnapprovedTransaction) { EXPECT_TRUE(observer.TxUpdated()); // Get the updated TX. - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->nonce(), absl::nullopt); } @@ -1093,7 +1126,7 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignature) { std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); TestTxServiceObserver observer("0x6", "", "", "", "", std::vector(), @@ -1108,7 +1141,7 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignature) { base::RunLoop run_loop; eth_tx_manager()->ProcessHardwareSignature( - tx_meta_id, "0x00", + mojom::kLocalhostChainId, tx_meta_id, "0x00", "0x93b9121e82df014428924df439ff044f89c205dd76a194f8b11f50d2eade744e", "0x7aa705c9144742836b7fbbd0745c57f67b60df7b8d1790fe59f91ed8d2bfc11d", base::BindLambdaForTesting([&](bool success, @@ -1117,7 +1150,8 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignature) { EXPECT_TRUE(success); EXPECT_EQ(error_out, mojom::ProviderError::kSuccess); EXPECT_TRUE(error_message_out.empty()); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = eth_tx_manager()->GetTxForTesting( + mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Submitted); run_loop.Quit(); @@ -1135,7 +1169,7 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignatureFail) { std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); TestTxServiceObserver observer("0x6", "", "", "", "", std::vector(), @@ -1145,7 +1179,8 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignatureFail) { EXPECT_TRUE(callback_called); callback_called = false; eth_tx_manager()->ProcessHardwareSignature( - tx_meta_id, "0x00", "9ff044f89c205dd76a194f8b11f50d2eade744e", "", + mojom::kLocalhostChainId, tx_meta_id, "0x00", + "9ff044f89c205dd76a194f8b11f50d2eade744e", "", base::BindLambdaForTesting([&](bool success, mojom::ProviderError error_out, const std::string& error_message_out) { @@ -1154,7 +1189,8 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignatureFail) { EXPECT_EQ(error_message_out, l10n_util::GetStringUTF8( IDS_BRAVE_WALLET_HARDWARE_PROCESS_TRANSACTION_ERROR)); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = eth_tx_manager()->GetTxForTesting( + mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Error); callback_called = true; @@ -1165,7 +1201,8 @@ TEST_F(EthTxManagerUnitTest, ProcessHardwareSignatureFail) { observer.Reset(); callback_called = false; eth_tx_manager()->ProcessHardwareSignature( - "-1", "0x00", "9ff044f89c205dd76a194f8b11f50d2eade744e", "", + mojom::kLocalhostChainId, "-1", "0x00", + "9ff044f89c205dd76a194f8b11f50d2eade744e", "", base::BindLambdaForTesting([&](bool success, mojom::ProviderError error_out, const std::string& error_message_out) { @@ -1190,7 +1227,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction) { std::string tx_meta_id; AddUnapprovedTransaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); @@ -1201,11 +1238,12 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction) { tx_service_->AddObserver(observer.GetReceiver()); callback_called = false; eth_tx_manager()->GetNonceForHardwareTransaction( - tx_meta_id, + mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](const absl::optional& nonce) { EXPECT_TRUE(nonce); EXPECT_FALSE(nonce->empty()); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = eth_tx_manager()->GetTxForTesting( + mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); EXPECT_EQ(Uint256ValueToHex(tx_meta->tx()->nonce().value()), nonce); @@ -1216,7 +1254,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction) { callback_called = false; eth_tx_manager()->GetTransactionMessageToSign( - tx_meta_id, + mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](mojom::MessageToSignUnionPtr message) { ASSERT_TRUE(message->is_message_str()); absl::optional message_str = message->get_message_str(); @@ -1244,7 +1282,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction1559) { std::string tx_meta_id; AddUnapproved1559Transaction( - tx_data.Clone(), from(), + mojom::kLocalhostChainId, tx_data.Clone(), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); @@ -1255,11 +1293,12 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction1559) { tx_service_->AddObserver(observer.GetReceiver()); callback_called = false; eth_tx_manager()->GetNonceForHardwareTransaction( - tx_meta_id, + mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](const absl::optional& nonce) { EXPECT_TRUE(nonce); EXPECT_FALSE(nonce->empty()); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = eth_tx_manager()->GetTxForTesting( + mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); EXPECT_EQ(Uint256ValueToHex(tx_meta->tx()->nonce().value()), nonce); @@ -1270,7 +1309,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransaction1559) { callback_called = false; eth_tx_manager()->GetTransactionMessageToSign( - tx_meta_id, + mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](mojom::MessageToSignUnionPtr message) { ASSERT_TRUE(message->is_message_str()); absl::optional message_str = message->get_message_str(); @@ -1289,7 +1328,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransactionFail) { TestTxServiceObserver observer("0x1", "", ""); tx_service_->AddObserver(observer.GetReceiver()); eth_tx_manager()->GetNonceForHardwareTransaction( - std::string(), + mojom::kLocalhostChainId, std::string(), base::BindLambdaForTesting([&](const absl::optional& nonce) { EXPECT_FALSE(nonce); callback_called = true; @@ -1299,7 +1338,7 @@ TEST_F(EthTxManagerUnitTest, GetNonceForHardwareTransactionFail) { callback_called = false; eth_tx_manager()->GetTransactionMessageToSign( - std::string(), + mojom::kLocalhostChainId, std::string(), base::BindLambdaForTesting([&](mojom::MessageToSignUnionPtr message) { ASSERT_FALSE(message); callback_called = true; @@ -1322,13 +1361,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapproved1559TransactionWithGasFeeAndLimit) { std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1351,13 +1391,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapproved1559TransactionWithoutGasLimit) { std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1381,13 +1422,14 @@ TEST_F(EthTxManagerUnitTest, AddUnapproved1559TransactionWithoutGasFee) { std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1413,13 +1455,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1445,13 +1488,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); // Gas limit obtained by querying eth_estimateGas. @@ -1480,13 +1524,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1509,13 +1554,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); // Gas limit obtained by querying eth_estimateGas. @@ -1540,13 +1586,14 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); uint256_t gas_limit_value; @@ -1572,13 +1619,14 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { std::string tx_meta_id; AddUnapproved1559Transaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); // Gas limit should be filled by requesting eth_estimateGas. @@ -1597,7 +1645,7 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { // Fail if transaction is not found. callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - "not_exist", "0x1", "0x2", "0x3", + mojom::kLocalhostChainId, "not_exist", "0x1", "0x2", "0x3", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -1608,7 +1656,7 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { // Fail if passing an empty gas limit. callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, "0x1", "0x2", "", + mojom::kLocalhostChainId, tx_meta_id, "0x1", "0x2", "", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -1619,7 +1667,7 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { // Fail if passing an empty max_priority_fee_per_gas. callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, "", "0x2", "0x3", + mojom::kLocalhostChainId, tx_meta_id, "", "0x2", "0x3", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -1630,7 +1678,7 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { // Fail if passing an empty max_fee_per_gas. callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, "0x1", "", "0x3", + mojom::kLocalhostChainId, tx_meta_id, "0x1", "", "0x3", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -1659,7 +1707,8 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, update_max_priority_fee_per_gas_hex_string, + mojom::kLocalhostChainId, tx_meta_id, + update_max_priority_fee_per_gas_hex_string, update_max_fee_per_gas_hex_string, update_gas_limit_hex_string, base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); @@ -1670,7 +1719,8 @@ TEST_F(EthTxManagerUnitTest, SetGasFeeAndLimitForUnapprovedTransaction) { EXPECT_TRUE(observer.TxUpdated()); // Get the updated TX. - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->gas_limit(), update_gas_limit); tx1559 = static_cast(tx_meta->tx()); @@ -1689,18 +1739,19 @@ TEST_F(EthTxManagerUnitTest, std::string tx_meta_id; AddUnapprovedTransaction( - std::move(tx_data), from(), + mojom::kLocalhostChainId, std::move(tx_data), from(), base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); EXPECT_TRUE(tx_meta); callback_called = false; eth_tx_manager()->SetGasFeeAndLimitForUnapprovedTransaction( - tx_meta_id, "0x3344", "0x5566", "0xFED8", + mojom::kLocalhostChainId, tx_meta_id, "0x3344", "0x5566", "0xFED8", base::BindLambdaForTesting([&](bool success) { EXPECT_FALSE(success); callback_called = true; @@ -1717,15 +1768,19 @@ TEST_F(EthTxManagerUnitTest, TestSubmittedToConfirmed) { base::RunLoop().RunUntilIdle(); EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from(addr1.ToChecksumAddress()); meta.set_status(mojom::TransactionStatus::Submitted); eth_tx_manager()->tx_state_manager_->AddOrUpdateTx(meta); meta.set_id("002"); + meta.set_chain_id(mojom::kMainnetChainId); meta.set_from(addr2.ToChecksumAddress()); meta.tx()->set_nonce(uint256_t(4)); meta.set_status(mojom::TransactionStatus::Submitted); eth_tx_manager()->tx_state_manager_->AddOrUpdateTx(meta); + eth_tx_manager()->UpdatePendingTransactions(absl::nullopt); + url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( [this](const network::ResourceRequest& request) { url_loader_factory_.ClearResponses(); @@ -1763,23 +1818,27 @@ TEST_F(EthTxManagerUnitTest, TestSubmittedToConfirmed) { // Nothing is triggered after 10s task_environment_.FastForwardBy( base::Seconds(kBlockTrackerDefaultTimeInSeconds - 1)); - auto tx_meta1 = eth_tx_manager()->GetTxForTesting("001"); - EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta1->status()); - auto tx_meta2 = eth_tx_manager()->GetTxForTesting("002"); + auto tx_meta1 = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, "001"); EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta1->status()); + auto tx_meta2 = + eth_tx_manager()->GetTxForTesting(mojom::kMainnetChainId, "002"); + EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta2->status()); - task_environment_.FastForwardBy(base::Seconds(1)); - tx_meta1 = eth_tx_manager()->GetTxForTesting("001"); - EXPECT_EQ(mojom::TransactionStatus::Confirmed, tx_meta1->status()); - tx_meta2 = eth_tx_manager()->GetTxForTesting("002"); + task_environment_.FastForwardBy(base::Seconds(2)); + tx_meta1 = eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, "001"); EXPECT_EQ(mojom::TransactionStatus::Confirmed, tx_meta1->status()); + tx_meta2 = eth_tx_manager()->GetTxForTesting(mojom::kMainnetChainId, "002"); + EXPECT_EQ(mojom::TransactionStatus::Confirmed, tx_meta2->status()); // If the keyring is locked, nothing should update meta.set_id("001"); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from(addr1.ToChecksumAddress()); meta.set_status(mojom::TransactionStatus::Submitted); eth_tx_manager()->tx_state_manager_->AddOrUpdateTx(meta); meta.set_id("002"); + meta.set_chain_id(mojom::kMainnetChainId); meta.set_from(addr2.ToChecksumAddress()); meta.tx()->set_nonce(uint256_t(4)); meta.set_status(mojom::TransactionStatus::Submitted); @@ -1787,9 +1846,9 @@ TEST_F(EthTxManagerUnitTest, TestSubmittedToConfirmed) { keyring_service_->Lock(); task_environment_.FastForwardBy( base::Seconds(kBlockTrackerDefaultTimeInSeconds + 1)); - tx_meta1 = eth_tx_manager()->GetTxForTesting("001"); + tx_meta1 = eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, "001"); EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta1->status()); - tx_meta2 = eth_tx_manager()->GetTxForTesting("002"); + tx_meta2 = eth_tx_manager()->GetTxForTesting(mojom::kMainnetChainId, "002"); EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta1->status()); } @@ -1803,13 +1862,15 @@ TEST_F(EthTxManagerUnitTest, SpeedupTransaction) { std::string orig_meta_id = "001"; std::string tx_meta_id; DoSpeedupOrCancelTransactionSuccess( - "0x05", "0xa", std::vector(), orig_meta_id, - mojom::TransactionStatus::Submitted, false, &tx_meta_id); + mojom::kLocalhostChainId, "0x05", "0xa", std::vector(), + orig_meta_id, mojom::TransactionStatus::Submitted, false, &tx_meta_id); - auto expected_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + auto expected_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(expected_tx_meta); expected_tx_meta->tx()->set_gas_price(103027933985ULL); // 0x17fcf18321 - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(*expected_tx_meta->tx(), *tx_meta->tx()); @@ -1820,14 +1881,16 @@ TEST_F(EthTxManagerUnitTest, SpeedupTransaction) { // gas price + 10% => 0xb (11 wei) // eth_getGasPrice => 0x17fcf18321 (103 Gwei) orig_meta_id = "002"; - DoSpeedupOrCancelTransactionSuccess("0x06", "0xa", data_, orig_meta_id, - mojom::TransactionStatus::Submitted, - false, &tx_meta_id); + DoSpeedupOrCancelTransactionSuccess( + mojom::kLocalhostChainId, "0x06", "0xa", data_, orig_meta_id, + mojom::TransactionStatus::Submitted, false, &tx_meta_id); - expected_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + expected_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(expected_tx_meta); expected_tx_meta->tx()->set_gas_price(103027933985ULL); // 0x17fcf18321 - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(*expected_tx_meta->tx(), *tx_meta->tx()); @@ -1839,33 +1902,39 @@ TEST_F(EthTxManagerUnitTest, SpeedupTransaction) { // eth_getGasPrice => 0x17fcf18321 (103 Gwei) orig_meta_id = "003"; DoSpeedupOrCancelTransactionSuccess( - "0x07", "0x174876e800", data_, orig_meta_id, + mojom::kLocalhostChainId, "0x07", "0x174876e800", data_, orig_meta_id, mojom::TransactionStatus::Submitted, false, &tx_meta_id); - expected_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + expected_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(expected_tx_meta); expected_tx_meta->tx()->set_gas_price(110000000000ULL); // 0x174876e800 * 1.1 - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(*expected_tx_meta->tx(), *tx_meta->tx()); // Speedup should reuse group_id orig_meta_id = "004"; - DoSpeedupOrCancelTransactionSuccess( - "0x05", "0xa", std::vector(), orig_meta_id, - mojom::TransactionStatus::Submitted, false, &tx_meta_id, "mockGroupId"); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + DoSpeedupOrCancelTransactionSuccess(mojom::kLocalhostChainId, "0x05", "0xa", + std::vector(), orig_meta_id, + mojom::TransactionStatus::Submitted, + false, &tx_meta_id, "mockGroupId"); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); // Non-exist transaction should fail. - DoSpeedupOrCancelTransactionFailure("123", false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, "123", false); // Unapproved transaction should fail. - DoSpeedupOrCancelTransactionFailure(tx_meta_id, false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, tx_meta_id, + false); SetErrorInterceptor(); - DoSpeedupOrCancelTransactionFailure(orig_meta_id, false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, orig_meta_id, + false); } TEST_F(EthTxManagerUnitTest, Speedup1559Transaction) { @@ -1874,17 +1943,20 @@ TEST_F(EthTxManagerUnitTest, Speedup1559Transaction) { std::string orig_meta_id = "001"; std::string tx_meta_id; DoSpeedupOrCancel1559TransactionSuccess( - "0x05", data_, "0x77359400" /* 2 Gwei */, "0xb2d05e000" /* 48 Gwei */, - orig_meta_id, mojom::TransactionStatus::Submitted, false, &tx_meta_id); + mojom::kLocalhostChainId, "0x05", data_, "0x77359400" /* 2 Gwei */, + "0xb2d05e000" /* 48 Gwei */, orig_meta_id, + mojom::TransactionStatus::Submitted, false, &tx_meta_id); - auto expected_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + auto expected_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(expected_tx_meta); auto* expected_tx1559_ptr = static_cast(expected_tx_meta->tx()); expected_tx1559_ptr->set_max_priority_fee_per_gas( 2200000000ULL); // 2 * 1.1 gwei expected_tx1559_ptr->set_max_fee_per_gas(52800000000ULL); // 48 * 1.1 gwei - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); auto* tx1559_ptr = static_cast(tx_meta->tx()); EXPECT_EQ(*expected_tx1559_ptr, *tx1559_ptr); @@ -1893,16 +1965,19 @@ TEST_F(EthTxManagerUnitTest, Speedup1559Transaction) { // gas fees (2 gwei for priority fee and 48 gwei for max fee). orig_meta_id = "002"; DoSpeedupOrCancel1559TransactionSuccess( - "0x06", data_, "0x7735940" /* 0.125 Gwei */, "0xb2d05e00" /* 3 Gwei */, - orig_meta_id, mojom::TransactionStatus::Submitted, false, &tx_meta_id); + mojom::kLocalhostChainId, "0x06", data_, "0x7735940" /* 0.125 Gwei */, + "0xb2d05e00" /* 3 Gwei */, orig_meta_id, + mojom::TransactionStatus::Submitted, false, &tx_meta_id); - expected_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + expected_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(expected_tx_meta); expected_tx1559_ptr = static_cast(expected_tx_meta->tx()); expected_tx1559_ptr->set_max_priority_fee_per_gas(2000000000ULL); // 2 Gwei expected_tx1559_ptr->set_max_fee_per_gas(48000000000ULL); // 48 Gwei - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); tx1559_ptr = static_cast(tx_meta->tx()); EXPECT_EQ(*expected_tx1559_ptr, *tx1559_ptr); @@ -1910,21 +1985,24 @@ TEST_F(EthTxManagerUnitTest, Speedup1559Transaction) { // Speedup should reuse group_id orig_meta_id = "003"; DoSpeedupOrCancel1559TransactionSuccess( - "0x05", data_, "0x77359400" /* 2 Gwei */, "0xb2d05e000" /* 48 Gwei */, - orig_meta_id, mojom::TransactionStatus::Submitted, false, &tx_meta_id, - "mockGroupId"); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + mojom::kLocalhostChainId, "0x05", data_, "0x77359400" /* 2 Gwei */, + "0xb2d05e000" /* 48 Gwei */, orig_meta_id, + mojom::TransactionStatus::Submitted, false, &tx_meta_id, "mockGroupId"); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); // Non-exist transaction should fail. - DoSpeedupOrCancelTransactionFailure("123", false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, "123", false); // Unapproved transaction should fail. - DoSpeedupOrCancelTransactionFailure(tx_meta_id, false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, tx_meta_id, + false); SetErrorInterceptor(); - DoSpeedupOrCancelTransactionFailure(orig_meta_id, false); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, orig_meta_id, + false); } TEST_F(EthTxManagerUnitTest, CancelTransaction) { @@ -1937,12 +2015,14 @@ TEST_F(EthTxManagerUnitTest, CancelTransaction) { std::string orig_meta_id = "001"; std::string tx_meta_id; DoSpeedupOrCancelTransactionSuccess( - "0x06", "0x2540BE4000" /* 160 gwei */, data_, orig_meta_id, - mojom::TransactionStatus::Submitted, true, &tx_meta_id); + mojom::kLocalhostChainId, "0x06", "0x2540BE4000" /* 160 gwei */, data_, + orig_meta_id, mojom::TransactionStatus::Submitted, true, &tx_meta_id); - auto orig_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + auto orig_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(orig_tx_meta); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->nonce(), orig_tx_meta->tx()->nonce()); EXPECT_EQ(Uint256ValueToHex(tx_meta->tx()->nonce().value()), "0x6"); @@ -1958,13 +2038,15 @@ TEST_F(EthTxManagerUnitTest, CancelTransaction) { // gas price + 10% => 0xb (11 wei) // eth_getGasPrice => 0x17fcf18321 (103 Gwei) orig_meta_id = "002"; - DoSpeedupOrCancelTransactionSuccess("0x07", "0x1", data_, orig_meta_id, - mojom::TransactionStatus::Submitted, true, - &tx_meta_id); + DoSpeedupOrCancelTransactionSuccess( + mojom::kLocalhostChainId, "0x07", "0x1", data_, orig_meta_id, + mojom::TransactionStatus::Submitted, true, &tx_meta_id); - orig_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + orig_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(orig_tx_meta); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->tx()->nonce(), orig_tx_meta->tx()->nonce()); EXPECT_EQ(Uint256ValueToHex(tx_meta->tx()->nonce().value()), "0x7"); @@ -1975,10 +2057,11 @@ TEST_F(EthTxManagerUnitTest, CancelTransaction) { // Cancel should reuse group_id orig_meta_id = "003"; - DoSpeedupOrCancelTransactionSuccess("0x07", "0x1", data_, orig_meta_id, - mojom::TransactionStatus::Submitted, true, - &tx_meta_id, "mockGroupId"); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + DoSpeedupOrCancelTransactionSuccess( + mojom::kLocalhostChainId, "0x07", "0x1", data_, orig_meta_id, + mojom::TransactionStatus::Submitted, true, &tx_meta_id, "mockGroupId"); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); @@ -1987,12 +2070,15 @@ TEST_F(EthTxManagerUnitTest, CancelTransaction) { // original gas fees + 10%. orig_meta_id = "004"; DoSpeedupOrCancel1559TransactionSuccess( - "0x08", data_, "0x77359400" /* 2 Gwei */, "0xb2d05e000" /* 48 Gwei */, - orig_meta_id, mojom::TransactionStatus::Submitted, true, &tx_meta_id); + mojom::kLocalhostChainId, "0x08", data_, "0x77359400" /* 2 Gwei */, + "0xb2d05e000" /* 48 Gwei */, orig_meta_id, + mojom::TransactionStatus::Submitted, true, &tx_meta_id); - orig_tx_meta = eth_tx_manager()->GetTxForTesting(orig_meta_id); + orig_tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, orig_meta_id); ASSERT_TRUE(orig_tx_meta); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); auto* orig_tx1559_ptr = static_cast(orig_tx_meta->tx()); auto* tx1559_ptr = static_cast(tx_meta->tx()); @@ -2007,21 +2093,24 @@ TEST_F(EthTxManagerUnitTest, CancelTransaction) { // Cancel should reuse group_id DoSpeedupOrCancel1559TransactionSuccess( - "0x08", data_, "0x77359400" /* 2 Gwei */, "0xb2d05e000" /* 48 Gwei */, - orig_meta_id, mojom::TransactionStatus::Submitted, true, &tx_meta_id, - "mockGroupId"); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + mojom::kLocalhostChainId, "0x08", data_, "0x77359400" /* 2 Gwei */, + "0xb2d05e000" /* 48 Gwei */, orig_meta_id, + mojom::TransactionStatus::Submitted, true, &tx_meta_id, "mockGroupId"); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); // Non-exist transaction should fail. - DoSpeedupOrCancelTransactionFailure("123", true); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, "123", true); // Unapproved transaction should fail. - DoSpeedupOrCancelTransactionFailure(tx_meta_id, true); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, tx_meta_id, + true); SetErrorInterceptor(); - DoSpeedupOrCancelTransactionFailure(orig_meta_id, true); + DoSpeedupOrCancelTransactionFailure(mojom::kLocalhostChainId, orig_meta_id, + true); } TEST_F(EthTxManagerUnitTest, RetryTransaction) { @@ -2034,6 +2123,7 @@ TEST_F(EthTxManagerUnitTest, RetryTransaction) { EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from( EthAddress::FromHex("0xbe862ad9abfe6f22bcb087716c7d89a26051f74a") .ToChecksumAddress()); @@ -2045,12 +2135,14 @@ TEST_F(EthTxManagerUnitTest, RetryTransaction) { std::string tx_meta_id; eth_tx_manager()->RetryTransaction( - "001", base::BindOnce(&AddUnapprovedTransactionSuccessCallback, - &callback_called, &tx_meta_id)); + mojom::kLocalhostChainId, "001", + base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, + &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - auto tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + auto tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(*tx_meta->tx(), tx.value()); @@ -2066,17 +2158,20 @@ TEST_F(EthTxManagerUnitTest, RetryTransaction) { ASSERT_TRUE(tx1559); meta.set_id("002"); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_status(mojom::TransactionStatus::Error); meta.set_tx(std::make_unique(*tx1559)); eth_tx_manager()->tx_state_manager_->AddOrUpdateTx(meta); eth_tx_manager()->RetryTransaction( - "002", base::BindOnce(&AddUnapprovedTransactionSuccessCallback, - &callback_called, &tx_meta_id)); + mojom::kLocalhostChainId, "002", + base::BindOnce(&AddUnapprovedTransactionSuccessCallback, &callback_called, + &tx_meta_id)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); - tx_meta = eth_tx_manager()->GetTxForTesting(tx_meta_id); + tx_meta = + eth_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, tx_meta_id); ASSERT_TRUE(tx_meta); auto* tx1559_ptr = static_cast(tx_meta->tx()); EXPECT_EQ(*tx1559_ptr, tx1559.value()); @@ -2084,16 +2179,18 @@ TEST_F(EthTxManagerUnitTest, RetryTransaction) { // Non-exist transaction should fail. callback_called = false; eth_tx_manager()->RetryTransaction( - "123", base::BindOnce(&AddUnapprovedTransactionFailureCallback, - &callback_called)); + mojom::kLocalhostChainId, "123", + base::BindOnce(&AddUnapprovedTransactionFailureCallback, + &callback_called)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); // Retry unapproved transaction should fail. callback_called = false; eth_tx_manager()->RetryTransaction( - tx_meta_id, base::BindOnce(&AddUnapprovedTransactionFailureCallback, - &callback_called)); + mojom::kLocalhostChainId, tx_meta_id, + base::BindOnce(&AddUnapprovedTransactionFailureCallback, + &callback_called)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); } @@ -2198,10 +2295,13 @@ TEST_F(EthTxManagerUnitTest, MakeERC1155TransferFromData) { TEST_F(EthTxManagerUnitTest, Reset) { eth_tx_manager()->known_no_pending_tx_ = true; - eth_tx_manager()->block_tracker_->Start(base::Seconds(10)); - EXPECT_TRUE(eth_tx_manager()->block_tracker_->IsRunning()); + eth_tx_manager()->block_tracker_->Start(mojom::kLocalhostChainId, + base::Seconds(10)); + EXPECT_TRUE( + eth_tx_manager()->block_tracker_->IsRunning(mojom::kLocalhostChainId)); EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from( EthAddress::FromHex("0xbe862ad9abfe6f22bcb087716c7d89a26051f74a") .ToChecksumAddress()); @@ -2217,7 +2317,8 @@ TEST_F(EthTxManagerUnitTest, Reset) { tx_service_->Reset(); EXPECT_FALSE(eth_tx_manager()->known_no_pending_tx_); - EXPECT_FALSE(eth_tx_manager()->block_tracker_->IsRunning()); + EXPECT_FALSE( + eth_tx_manager()->block_tracker_->IsRunning(mojom::kLocalhostChainId)); EXPECT_FALSE(GetPrefs()->HasPrefPath(kBraveWalletTransactions)); } diff --git a/components/brave_wallet/browser/eth_tx_state_manager_unittest.cc b/components/brave_wallet/browser/eth_tx_state_manager_unittest.cc index f1cbe746e78e..744550ce9cca 100644 --- a/components/brave_wallet/browser/eth_tx_state_manager_unittest.cc +++ b/components/brave_wallet/browser/eth_tx_state_manager_unittest.cc @@ -18,13 +18,10 @@ #include "brave/components/brave_wallet/browser/eip1559_transaction.h" #include "brave/components/brave_wallet/browser/eip2930_transaction.h" #include "brave/components/brave_wallet/browser/eth_tx_meta.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "brave/components/brave_wallet/common/eth_address.h" #include "components/prefs/pref_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/origin.h" @@ -33,38 +30,19 @@ namespace brave_wallet { class EthTxStateManagerUnitTest : public testing::Test { public: EthTxStateManagerUnitTest() - : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - shared_url_loader_factory_( - base::MakeRefCounted( - &url_loader_factory_)) {} + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} ~EthTxStateManagerUnitTest() override = default; protected: void SetUp() override { brave_wallet::RegisterProfilePrefs(prefs_.registry()); - json_rpc_service_ = std::make_unique( - shared_url_loader_factory_, GetPrefs()); - eth_tx_state_manager_ = std::make_unique( - GetPrefs(), json_rpc_service_.get()); - } - - void SetNetwork(const std::string& chain_id) { - base::RunLoop run_loop; - json_rpc_service_->SetNetwork( - chain_id, mojom::CoinType::ETH, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); - // Wait for network info - base::RunLoop().RunUntilIdle(); + eth_tx_state_manager_ = std::make_unique(GetPrefs()); } PrefService* GetPrefs() { return &prefs_; } base::test::TaskEnvironment task_environment_; - network::TestURLLoaderFactory url_loader_factory_; - scoped_refptr shared_url_loader_factory_; sync_preferences::TestingPrefServiceSyncable prefs_; - std::unique_ptr json_rpc_service_; std::unique_ptr eth_tx_state_manager_; }; @@ -101,6 +79,7 @@ TEST_F(EthTxStateManagerUnitTest, TxMetaAndValue) { meta.set_tx_hash( "0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"); meta.set_origin(url::Origin::Create(GURL("https://test.brave.com"))); + meta.set_chain_id(mojom::kMainnetChainId); base::Value::Dict meta_value = meta.ToValue(); const std::string* from = meta_value.FindString("from"); @@ -117,6 +96,7 @@ TEST_F(EthTxStateManagerUnitTest, TxMetaAndValue) { EXPECT_EQ(meta_from_value->tx_receipt(), meta.tx_receipt()); EXPECT_EQ(meta_from_value->tx_hash(), meta.tx_hash()); EXPECT_EQ(meta_from_value->origin(), meta.origin()); + EXPECT_EQ(meta_from_value->chain_id(), meta.chain_id()); ASSERT_EQ(meta_from_value->tx()->type(), 0); EXPECT_EQ(*meta_from_value->tx(), *meta.tx()); // optional sign_only will be false by default @@ -195,12 +175,17 @@ TEST_F(EthTxStateManagerUnitTest, TxMetaAndValue) { } TEST_F(EthTxStateManagerUnitTest, GetTxPrefPathPrefix) { - EXPECT_EQ("ethereum.mainnet", eth_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork("0x5"); - EXPECT_EQ("ethereum.goerli", eth_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork(brave_wallet::mojom::kLocalhostChainId); - EXPECT_EQ("ethereum.http://localhost:7545/", - eth_tx_state_manager_->GetTxPrefPathPrefix()); + EXPECT_EQ("ethereum.mainnet", + eth_tx_state_manager_->GetTxPrefPathPrefix(mojom::kMainnetChainId)); + EXPECT_EQ("ethereum.goerli", + eth_tx_state_manager_->GetTxPrefPathPrefix(mojom::kGoerliChainId)); + EXPECT_EQ("ethereum.sepolia", + eth_tx_state_manager_->GetTxPrefPathPrefix(mojom::kSepoliaChainId)); + EXPECT_EQ( + "ethereum.http://localhost:7545/", + eth_tx_state_manager_->GetTxPrefPathPrefix(mojom::kLocalhostChainId)); + EXPECT_EQ("ethereum", + eth_tx_state_manager_->GetTxPrefPathPrefix(absl::nullopt)); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/fil_block_tracker_unittest.cc b/components/brave_wallet/browser/fil_block_tracker_unittest.cc index a741302378b4..e9e65361c189 100644 --- a/components/brave_wallet/browser/fil_block_tracker_unittest.cc +++ b/components/brave_wallet/browser/fil_block_tracker_unittest.cc @@ -8,6 +8,7 @@ #include #include +#include "base/scoped_observation.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" @@ -16,28 +17,27 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" +using testing::_; + namespace brave_wallet { namespace { -class TrackerObserver : public FilBlockTracker::Observer { +class MockTrackerObserver : public FilBlockTracker::Observer { public: - void OnLatestHeightUpdated(uint64_t latest_height) override { - latest_height_ = latest_height; - ++latest_height_updated_fired_; + explicit MockTrackerObserver(FilBlockTracker* tracker) { + observation_.Observe(tracker); } - size_t latest_height_updated_fired() const { - return latest_height_updated_fired_; - } - uint64_t latest_height() const { return latest_height_; } + MOCK_METHOD2(OnLatestHeightUpdated, void(const std::string&, uint64_t)); private: - size_t latest_height_updated_fired_ = 0; - uint64_t latest_height_ = 0; + base::ScopedObservation + observation_{this}; }; } // namespace @@ -65,13 +65,16 @@ class FilBlockTrackerUnitTest : public testing::Test { std::to_string(response_height_) + "}}"; } - void TestGetLatestHeight(uint64_t expected_latest_height, + void TestGetLatestHeight(const std::string& chain_id, + uint64_t expected_latest_height, mojom::FilecoinProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; - tracker_->GetFilBlockHeight(base::BindLambdaForTesting( - [&](uint64_t latest_height, mojom::FilecoinProviderError error, - const std::string& error_message) { + tracker_->GetFilBlockHeight( + chain_id, + base::BindLambdaForTesting([&](uint64_t latest_height, + mojom::FilecoinProviderError error, + const std::string& error_message) { EXPECT_EQ(latest_height, expected_latest_height); EXPECT_EQ(error, expected_error); EXPECT_EQ(error_message, expected_error_message); @@ -99,27 +102,40 @@ TEST_F(FilBlockTrackerUnitTest, GetLatestHeight) { GetResponseString()); })); response_height_ = UINT64_MAX; - TrackerObserver observer; - tracker_->AddObserver(&observer); - - tracker_->Start(base::Seconds(5)); + MockTrackerObserver observer(tracker_.get()); + + tracker_->Start(mojom::kFilecoinMainnet, base::Seconds(5)); + tracker_->Start(mojom::kFilecoinTestnet, base::Seconds(2)); + EXPECT_CALL(observer, + OnLatestHeightUpdated(mojom::kFilecoinMainnet, UINT64_MAX)) + .Times(1); + EXPECT_CALL(observer, + OnLatestHeightUpdated(mojom::kFilecoinTestnet, UINT64_MAX)) + .Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), UINT64_MAX); - EXPECT_EQ(observer.latest_height_updated_fired(), 1u); - EXPECT_EQ(tracker_->latest_height(), UINT64_MAX); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), UINT64_MAX); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), UINT64_MAX); + EXPECT_EQ(tracker_->GetLatestHeight("skynet"), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); response_height_ = 1; - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kFilecoinMainnet, base::Seconds(5)); + tracker_->Start(mojom::kFilecoinTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestHeightUpdated(mojom::kFilecoinMainnet, 1u)) + .Times(1); + EXPECT_CALL(observer, OnLatestHeightUpdated(mojom::kFilecoinTestnet, 1u)) + .Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), 1u); - EXPECT_EQ(observer.latest_height_updated_fired(), 2u); - EXPECT_EQ(tracker_->latest_height(), 1u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), 1u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), 1u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); // Still response_height_ 1, shouldn't fire updated event. + EXPECT_CALL(observer, OnLatestHeightUpdated(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), 1u); - EXPECT_EQ(observer.latest_height_updated_fired(), 2u); - EXPECT_EQ(tracker_->latest_height(), 1u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), 1u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), 1u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(FilBlockTrackerUnitTest, GetLatestHeightInvalidResponseJSON) { @@ -131,14 +147,15 @@ TEST_F(FilBlockTrackerUnitTest, GetLatestHeightInvalidResponseJSON) { })); response_height_ = UINT64_MAX; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kFilecoinMainnet, base::Seconds(5)); + tracker_->Start(mojom::kFilecoinTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestHeightUpdated(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), 0u); - EXPECT_EQ(observer.latest_height_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_height(), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(FilBlockTrackerUnitTest, GetLatestHeightInternalError) { @@ -157,14 +174,15 @@ TEST_F(FilBlockTrackerUnitTest, GetLatestHeightInternalError) { })); response_height_ = 3; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kFilecoinMainnet, base::Seconds(5)); + tracker_->Start(mojom::kFilecoinTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestHeightUpdated(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), 0u); - EXPECT_EQ(observer.latest_height_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_height(), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(FilBlockTrackerUnitTest, GetLatestHeightRequestTimeout) { @@ -176,19 +194,18 @@ TEST_F(FilBlockTrackerUnitTest, GetLatestHeightRequestTimeout) { })); response_height_ = 3; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kFilecoinMainnet, base::Seconds(5)); + tracker_->Start(mojom::kFilecoinTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestHeightUpdated(_, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_height(), 0u); - EXPECT_EQ(observer.latest_height_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_height(), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinMainnet), 0u); + EXPECT_EQ(tracker_->GetLatestHeight(mojom::kFilecoinTestnet), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(FilBlockTrackerUnitTest, GetLatestHeightWithoutStartTracker) { - ASSERT_FALSE(tracker_->IsRunning()); - url_loader_factory_.SetInterceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { url_loader_factory_.ClearResponses(); @@ -197,7 +214,15 @@ TEST_F(FilBlockTrackerUnitTest, GetLatestHeightWithoutStartTracker) { })); response_height_ = 1; - TestGetLatestHeight(1, mojom::FilecoinProviderError::kSuccess, ""); + MockTrackerObserver observer(tracker_.get()); + for (const std::string& chain_id : + {mojom::kFilecoinMainnet, mojom::kFilecoinTestnet}) { + ASSERT_FALSE(tracker_->IsRunning(chain_id)); + EXPECT_CALL(observer, OnLatestHeightUpdated(chain_id, 1u)).Times(1); + TestGetLatestHeight(chain_id, 1, mojom::FilecoinProviderError::kSuccess, + ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + } } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/fil_nonce_tracker_unittest.cc b/components/brave_wallet/browser/fil_nonce_tracker_unittest.cc index 94f304598997..b77bfa2bf007 100644 --- a/components/brave_wallet/browser/fil_nonce_tracker_unittest.cc +++ b/components/brave_wallet/browser/fil_nonce_tracker_unittest.cc @@ -52,15 +52,24 @@ class FilNonceTrackerUnitTest : public testing::Test { mojom::CoinType::FIL) .spec(), GetResultString()); + url_loader_factory_.AddResponse( + brave_wallet::GetNetworkURL(GetPrefs(), mojom::kFilecoinMainnet, + mojom::CoinType::FIL) + .spec(), + GetResultString()); } - void GetNextNonce(FilNonceTracker* tracker, + void GetNextNonce(const base::Location& location, + FilNonceTracker* tracker, + const std::string& chain_id, const std::string& address, bool expected_success, uint64_t expected_nonce) { + SCOPED_TRACE(testing::Message() << location.ToString()); base::RunLoop run_loop; tracker->GetNextNonce( - address, base::BindLambdaForTesting([&](bool success, uint256_t nonce) { + chain_id, address, + base::BindLambdaForTesting([&](bool success, uint256_t nonce) { EXPECT_EQ(expected_success, success); EXPECT_EQ(expected_nonce, nonce); run_loop.Quit(); @@ -84,29 +93,27 @@ class FilNonceTrackerUnitTest : public testing::Test { TEST_F(FilNonceTrackerUnitTest, GetNonce) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - base::RunLoop run_loop; - service.SetNetwork( - mojom::kLocalhostChainId, mojom::CoinType::FIL, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); - FilTxStateManager tx_state_manager(GetPrefs(), &service); + FilTxStateManager tx_state_manager(GetPrefs()); FilNonceTracker nonce_tracker(&tx_state_manager, &service); SetTransactionCount(2); const std::string address("t1lqarsh4nkg545ilaoqdsbtj4uofplt6sto26ziy"); - GetNextNonce(&nonce_tracker, address, true, uint64_t(2)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + true, uint64_t(2)); // tx count: 2, confirmed: [2], pending: null FilTxMeta meta; meta.set_id(TxMeta::GenerateMetaID()); + meta.set_chain_id(mojom::kLocalhostChainId); meta.set_from(FilAddress::FromAddress(address).EncodeAsString()); meta.set_status(mojom::TransactionStatus::Confirmed); meta.tx()->set_nonce(uint64_t(2)); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, uint64_t(3)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + true, uint64_t(3)); // tx count: 2, confirmed: [2, 3], pending: null meta.set_id(TxMeta::GenerateMetaID()); @@ -114,7 +121,8 @@ TEST_F(FilNonceTrackerUnitTest, GetNonce) { meta.tx()->set_nonce(uint64_t(3)); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, uint64_t(4)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + true, uint64_t(4)); // tx count: 2, confirmed: [2, 3], pending: [4, 4] meta.set_status(mojom::TransactionStatus::Submitted); @@ -124,17 +132,17 @@ TEST_F(FilNonceTrackerUnitTest, GetNonce) { meta.set_id(TxMeta::GenerateMetaID()); tx_state_manager.AddOrUpdateTx(meta); - GetNextNonce(&nonce_tracker, address, true, uint64_t(5)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + true, uint64_t(5)); + + // tx count: 2, confirmed: null, pending: null (mainnet) + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kFilecoinMainnet, address, + true, uint64_t(2)); } TEST_F(FilNonceTrackerUnitTest, NonceLock) { JsonRpcService service(shared_url_loader_factory(), GetPrefs()); - base::RunLoop run_loop; - service.SetNetwork( - mojom::kLocalhostChainId, mojom::CoinType::FIL, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); - FilTxStateManager tx_state_manager(GetPrefs(), &service); + FilTxStateManager tx_state_manager(GetPrefs()); FilNonceTracker nonce_tracker(&tx_state_manager, &service); SetTransactionCount(4); @@ -142,10 +150,16 @@ TEST_F(FilNonceTrackerUnitTest, NonceLock) { base::Lock* lock = nonce_tracker.GetLock(); lock->Acquire(); const std::string address("t1lqarsh4nkg545ilaoqdsbtj4uofplt6sto26ziy"); - GetNextNonce(&nonce_tracker, address, false, 0u); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + false, 0u); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kFilecoinMainnet, address, + false, 0u); lock->Release(); - GetNextNonce(&nonce_tracker, address, true, uint64_t(4)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kLocalhostChainId, address, + true, uint64_t(4)); + GetNextNonce(FROM_HERE, &nonce_tracker, mojom::kFilecoinMainnet, address, + true, uint64_t(4)); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/fil_tx_manager_unittest.cc b/components/brave_wallet/browser/fil_tx_manager_unittest.cc index 3bce97891c3f..7d8d6db06221 100644 --- a/components/brave_wallet/browser/fil_tx_manager_unittest.cc +++ b/components/brave_wallet/browser/fil_tx_manager_unittest.cc @@ -83,21 +83,10 @@ class FilTxManagerUnitTest : public testing::Test { tx_service_ = std::make_unique(json_rpc_service_.get(), keyring_service_.get(), &prefs_); - base::RunLoop run_loop; - json_rpc_service_->SetNetwork(brave_wallet::mojom::kLocalhostChainId, - mojom::CoinType::FIL, - base::BindLambdaForTesting([&](bool success) { - EXPECT_TRUE(success); - run_loop.Quit(); - })); - run_loop.Run(); keyring_service_->CreateWallet("testing123", base::DoNothing()); base::RunLoop().RunUntilIdle(); keyring_service_->AddFilecoinAccount("Account 1", mojom::kFilecoinTestnet, base::DoNothing()); - json_rpc_service_->SetNetwork(brave_wallet::mojom::kLocalhostChainId, - mojom::CoinType::FIL); - base::RunLoop().RunUntilIdle(); } std::string from(const std::string& keyring_id) { @@ -133,11 +122,12 @@ class FilTxManagerUnitTest : public testing::Test { } void GetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, absl::optional expected_message) { base::RunLoop run_loop; fil_tx_manager()->GetTransactionMessageToSign( - tx_meta_id, + chain_id, tx_meta_id, base::BindLambdaForTesting([&](mojom::MessageToSignUnionPtr message) { EXPECT_EQ(!!message, expected_message.has_value()); if (expected_message.has_value()) { @@ -161,6 +151,7 @@ class FilTxManagerUnitTest : public testing::Test { } void AddUnapprovedTransaction( + const std::string& chain_id, mojom::FilTxDataPtr tx_data, const std::string& from, const absl::optional& origin, @@ -170,7 +161,7 @@ class FilTxManagerUnitTest : public testing::Test { base::RunLoop run_loop; fil_tx_manager()->AddUnapprovedTransaction( - std::move(tx_data_union), from, origin, group_id, + chain_id, std::move(tx_data_union), from, origin, group_id, base::BindLambdaForTesting([&](bool success, const std::string& id, const std::string& err_message) { ASSERT_TRUE(success); @@ -182,13 +173,14 @@ class FilTxManagerUnitTest : public testing::Test { run_loop.Run(); } - void ApproveTransaction(const std::string& meta_id, + void ApproveTransaction(const std::string& chain_id, + const std::string& meta_id, bool is_error, mojom::FilecoinProviderError error, const std::string& expected_err_message) { base::RunLoop run_loop; fil_tx_manager()->ApproveTransaction( - meta_id, + chain_id, meta_id, base::BindLambdaForTesting([&](bool success, mojom::ProviderErrorUnionPtr error_union, const std::string& err_message) { @@ -256,13 +248,13 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactions) { auto tx = FilTransaction::FromTxData(tx_data.Clone()); std::string meta_id1; - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id1); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id1); - auto tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + auto tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); EXPECT_TRUE(tx_meta1); - EXPECT_EQ(tx_meta1->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta1->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta1->tx()->gas_fee_cap(), "100820"); EXPECT_EQ(tx_meta1->tx()->gas_limit(), 598585); @@ -271,12 +263,12 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactions) { EXPECT_EQ(tx_meta1->status(), mojom::TransactionStatus::Unapproved); std::string meta_id2; - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id2); - auto tx_meta2 = fil_tx_manager()->GetTxForTesting(meta_id2); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id2); + auto tx_meta2 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id2); ASSERT_TRUE(tx_meta2); - EXPECT_EQ(tx_meta2->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta2->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta2->from(), from_account); EXPECT_EQ(tx_meta2->status(), mojom::TransactionStatus::Unapproved); @@ -295,22 +287,24 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactions) { } })"); - ApproveTransaction(meta_id1, false, mojom::FilecoinProviderError::kSuccess, - std::string()); + ApproveTransaction(mojom::kLocalhostChainId, meta_id1, false, + mojom::FilecoinProviderError::kSuccess, std::string()); // Wait for tx to be updated. base::RunLoop().RunUntilIdle(); - tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); ASSERT_TRUE(tx_meta1); EXPECT_FALSE(tx_meta1->tx_hash().empty()); EXPECT_EQ(tx_meta1->from(), from_account); EXPECT_EQ(tx_meta1->status(), mojom::TransactionStatus::Submitted); // Send another tx. - ApproveTransaction(meta_id2, false, mojom::FilecoinProviderError::kSuccess, - std::string()); + ApproveTransaction(mojom::kLocalhostChainId, meta_id2, false, + mojom::FilecoinProviderError::kSuccess, std::string()); base::RunLoop().RunUntilIdle(); - tx_meta2 = fil_tx_manager()->GetTxForTesting(meta_id2); + tx_meta2 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id2); ASSERT_TRUE(tx_meta2); EXPECT_EQ(tx_meta2->from(), from_account); EXPECT_FALSE(tx_meta2->tx_hash().empty()); @@ -328,10 +322,11 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactionError) { auto tx = FilTransaction::FromTxData(tx_data.Clone()); std::string meta_id1; - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id1); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id1); - auto tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + auto tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); EXPECT_TRUE(tx_meta1); EXPECT_EQ(tx_meta1->tx()->gas_fee_cap(), "100820"); @@ -356,12 +351,13 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactionError) { AddInterceptorResponse("Filecoin.MpoolPush", R"({ "id": 1, "jsonrpc": "2.0", "result":{} })"); - ApproveTransaction(meta_id1, true, + ApproveTransaction(mojom::kLocalhostChainId, meta_id1, true, mojom::FilecoinProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // Wait for tx to be updated. base::RunLoop().RunUntilIdle(); - tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); ASSERT_TRUE(tx_meta1); EXPECT_TRUE(tx_meta1->tx_hash().empty()); EXPECT_EQ(tx_meta1->from(), from_account); @@ -379,13 +375,13 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactionConfirmed) { auto tx = FilTransaction::FromTxData(tx_data.Clone()); std::string meta_id1; - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id1); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id1); - auto tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + auto tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); EXPECT_TRUE(tx_meta1); - EXPECT_EQ(tx_meta1->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta1->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta1->tx()->gas_fee_cap(), "100820"); EXPECT_EQ(tx_meta1->tx()->gas_limit(), 598585); @@ -418,11 +414,12 @@ TEST_F(FilTxManagerUnitTest, SubmitTransactionConfirmed) { "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" } })"); - ApproveTransaction(meta_id1, false, mojom::FilecoinProviderError::kSuccess, - std::string()); + ApproveTransaction(mojom::kLocalhostChainId, meta_id1, false, + mojom::FilecoinProviderError::kSuccess, std::string()); // Wait for tx to be updated. base::RunLoop().RunUntilIdle(); - tx_meta1 = fil_tx_manager()->GetTxForTesting(meta_id1); + tx_meta1 = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id1); ASSERT_TRUE(tx_meta1); EXPECT_FALSE(tx_meta1->tx_hash().empty()); EXPECT_EQ(tx_meta1->from(), from_account); @@ -437,13 +434,13 @@ TEST_F(FilTxManagerUnitTest, WalletOrigin) { "" /* nonce */, "" /* gas_premium */, "" /* gas_fee_cap */, "" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt, - &meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, std::move(tx_data), + from_account, absl::nullopt, &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta->origin(), url::Origin::Create(GURL("chrome://wallet"))); } @@ -456,16 +453,16 @@ TEST_F(FilTxManagerUnitTest, SomeSiteOrigin) { "" /* nonce */, "" /* gas_premium */, "" /* gas_fee_cap */, "" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, - url::Origin::Create(GURL("https://some.site.com")), - &meta_id); + AddUnapprovedTransaction( + mojom::kLocalhostChainId, std::move(tx_data), from_account, + url::Origin::Create(GURL("https://some.site.com")), &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->origin(), url::Origin::Create(GURL("https://some.site.com"))); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); } TEST_F(FilTxManagerUnitTest, AddUnapprovedTransactionWithGroupId) { @@ -478,22 +475,23 @@ TEST_F(FilTxManagerUnitTest, AddUnapprovedTransactionWithGroupId) { std::string meta_id; // Transaction with group_id - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id, "mockGroupId"); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id, + "mockGroupId"); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); // Transaction with empty group_id - AddUnapprovedTransaction(tx_data.Clone(), from_account, absl::nullopt, - &meta_id); - tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, tx_data.Clone(), + from_account, absl::nullopt, &meta_id); + tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); EXPECT_EQ(tx_meta->group_id(), absl::nullopt); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); } TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) { @@ -505,15 +503,15 @@ TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) { "1" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */, "4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt, - &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, std::move(tx_data), + from_account, absl::nullopt, &meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta->from(), from_account); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); - GetTransactionMessageToSign(meta_id, R"( + GetTransactionMessageToSign(mojom::kLocalhostChainId, meta_id, R"( { "From": "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", "GasFeeCap": "3", @@ -538,15 +536,15 @@ TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) { "" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */, "4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt, - &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, std::move(tx_data), + from_account, absl::nullopt, &meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta->from(), from_account); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); - GetTransactionMessageToSign(meta_id, R"( + GetTransactionMessageToSign(mojom::kLocalhostChainId, meta_id, R"( { "From": "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", "GasFeeCap": "3", @@ -562,8 +560,9 @@ TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) { )"); } - GetTransactionMessageToSign("unknown id", absl::nullopt); - GetTransactionMessageToSign("", absl::nullopt); + GetTransactionMessageToSign(mojom::kLocalhostChainId, "unknown id", + absl::nullopt); + GetTransactionMessageToSign(mojom::kLocalhostChainId, "", absl::nullopt); } TEST_F(FilTxManagerUnitTest, ProcessHardwareSignature) { @@ -574,12 +573,12 @@ TEST_F(FilTxManagerUnitTest, ProcessHardwareSignature) { "1" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */, "4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt, - &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, std::move(tx_data), + from_account, absl::nullopt, &meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta->from(), from_account); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); auto signed_message = @@ -616,7 +615,7 @@ TEST_F(FilTxManagerUnitTest, ProcessHardwareSignature) { base::RunLoop run_loop; fil_tx_manager()->ProcessFilHardwareSignature( - meta_id, signed_message, + mojom::kLocalhostChainId, meta_id, signed_message, base::BindLambdaForTesting([&](bool success, mojom::ProviderErrorUnionPtr error_union, const std::string& err_message) { @@ -625,7 +624,8 @@ TEST_F(FilTxManagerUnitTest, ProcessHardwareSignature) { ASSERT_EQ(error_union->get_filecoin_provider_error(), mojom::FilecoinProviderError::kSuccess); ASSERT_TRUE(err_message.empty()); - auto fil_tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + auto fil_tx_meta = fil_tx_manager()->GetTxForTesting( + mojom::kLocalhostChainId, meta_id); EXPECT_EQ(fil_tx_meta->status(), mojom::TransactionStatus::Submitted); run_loop.Quit(); })); @@ -640,19 +640,19 @@ TEST_F(FilTxManagerUnitTest, ProcessHardwareSignatureError) { "1" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */, "4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11"); std::string meta_id; - AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt, - &meta_id); - auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id); + AddUnapprovedTransaction(mojom::kLocalhostChainId, std::move(tx_data), + from_account, absl::nullopt, &meta_id); + auto tx_meta = + fil_tx_manager()->GetTxForTesting(mojom::kLocalhostChainId, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::FIL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kLocalhostChainId); EXPECT_EQ(tx_meta->from(), from_account); EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved); auto signed_message = GetSignedMessage(*tx_meta->tx()->GetMessageToSign(), "data"); base::RunLoop run_loop; fil_tx_manager()->ProcessFilHardwareSignature( - "fake", signed_message, + mojom::kLocalhostChainId, "fake", signed_message, base::BindLambdaForTesting([&](bool success, mojom::ProviderErrorUnionPtr error_union, const std::string& err_message) { diff --git a/components/brave_wallet/browser/fil_tx_state_manager_unittest.cc b/components/brave_wallet/browser/fil_tx_state_manager_unittest.cc index cab00d821b3a..1370d0d858a1 100644 --- a/components/brave_wallet/browser/fil_tx_state_manager_unittest.cc +++ b/components/brave_wallet/browser/fil_tx_state_manager_unittest.cc @@ -14,11 +14,8 @@ #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" #include "brave/components/brave_wallet/browser/fil_transaction.h" #include "brave/components/brave_wallet/browser/fil_tx_meta.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" namespace brave_wallet { @@ -26,32 +23,19 @@ namespace brave_wallet { class FilTxStateManagerUnitTest : public testing::Test { public: FilTxStateManagerUnitTest() - : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - shared_url_loader_factory_( - base::MakeRefCounted( - &url_loader_factory_)) {} + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} ~FilTxStateManagerUnitTest() override = default; protected: void SetUp() override { brave_wallet::RegisterProfilePrefs(prefs_.registry()); - json_rpc_service_ = std::make_unique( - shared_url_loader_factory_, GetPrefs()); - fil_tx_state_manager_ = std::make_unique( - GetPrefs(), json_rpc_service_.get()); - } - - void SetNetwork(const std::string& chain_id) { - ASSERT_TRUE(json_rpc_service_->SetNetwork(chain_id, mojom::CoinType::FIL)); + fil_tx_state_manager_ = std::make_unique(GetPrefs()); } PrefService* GetPrefs() { return &prefs_; } base::test::TaskEnvironment task_environment_; - network::TestURLLoaderFactory url_loader_factory_; - scoped_refptr shared_url_loader_factory_; sync_preferences::TestingPrefServiceSyncable prefs_; - std::unique_ptr json_rpc_service_; std::unique_ptr fil_tx_state_manager_; }; @@ -76,6 +60,7 @@ TEST_F(FilTxStateManagerUnitTest, FilTxMetaAndValue) { meta.set_confirmed_time(base::Time::Now()); meta.set_tx_hash("cid"); meta.set_origin(url::Origin::Create(GURL("https://test.brave.com"))); + meta.set_chain_id(mojom::kFilecoinMainnet); base::Value::Dict meta_value = meta.ToValue(); auto meta_from_value = fil_tx_state_manager_->ValueToFilTxMeta(meta_value); @@ -84,13 +69,15 @@ TEST_F(FilTxStateManagerUnitTest, FilTxMetaAndValue) { } TEST_F(FilTxStateManagerUnitTest, GetTxPrefPathPrefix) { - SetNetwork(mojom::kFilecoinMainnet); - EXPECT_EQ("filecoin.mainnet", fil_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork(mojom::kFilecoinTestnet); - EXPECT_EQ("filecoin.testnet", fil_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork(mojom::kLocalhostChainId); - EXPECT_EQ("filecoin.http://localhost:1234/rpc/v0", - fil_tx_state_manager_->GetTxPrefPathPrefix()); + EXPECT_EQ("filecoin.mainnet", fil_tx_state_manager_->GetTxPrefPathPrefix( + mojom::kFilecoinMainnet)); + EXPECT_EQ("filecoin.testnet", fil_tx_state_manager_->GetTxPrefPathPrefix( + mojom::kFilecoinTestnet)); + EXPECT_EQ( + "filecoin.http://localhost:1234/rpc/v0", + fil_tx_state_manager_->GetTxPrefPathPrefix(mojom::kLocalhostChainId)); + EXPECT_EQ("filecoin", + fil_tx_state_manager_->GetTxPrefPathPrefix(absl::nullopt)); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/json_rpc_service_unittest.cc b/components/brave_wallet/browser/json_rpc_service_unittest.cc index 9e0d3a600f28..dfd219fd4e19 100644 --- a/components/brave_wallet/browser/json_rpc_service_unittest.cc +++ b/components/brave_wallet/browser/json_rpc_service_unittest.cc @@ -63,6 +63,7 @@ #include "url/gurl.h" #include "url/origin.h" +using testing::_; using testing::ElementsAreArray; MATCHER_P(MatchesCIDv1URL, ipfs_url, "") { @@ -253,31 +254,15 @@ void OnFilUint256Response( class TestJsonRpcServiceObserver : public brave_wallet::mojom::JsonRpcServiceObserver { public: + TestJsonRpcServiceObserver() = default; TestJsonRpcServiceObserver(base::OnceClosure callback, const std::string& expected_chain_id, - mojom::CoinType expected_coin, const std::string& expected_error) { callback_ = std::move(callback); expected_chain_id_ = expected_chain_id; - expected_coin_ = expected_coin; expected_error_ = expected_error; } - TestJsonRpcServiceObserver(const std::string& expected_chain_id, - mojom::CoinType expected_coin, - bool expected_is_eip1559) { - expected_chain_id_ = expected_chain_id; - expected_coin_ = expected_coin; - expected_is_eip1559_ = expected_is_eip1559; - } - - void Reset(const std::string& expected_chain_id, bool expected_is_eip1559) { - expected_chain_id_ = expected_chain_id; - expected_is_eip1559_ = expected_is_eip1559; - chain_changed_called_ = false; - is_eip1559_changed_called_ = false; - } - void OnAddEthereumChainRequestCompleted(const std::string& chain_id, const std::string& error) override { EXPECT_EQ(chain_id, expected_chain_id_); @@ -285,29 +270,12 @@ class TestJsonRpcServiceObserver std::move(callback_).Run(); } - void ChainChangedEvent(const std::string& chain_id, - mojom::CoinType coin) override { - chain_changed_called_ = true; - EXPECT_EQ(chain_id, expected_chain_id_); - EXPECT_EQ(coin, expected_coin_); - } + MOCK_METHOD3(ChainChangedEvent, + void(const std::string&, + mojom::CoinType, + const absl::optional& origin)); - void OnIsEip1559Changed(const std::string& chain_id, - bool is_eip1559) override { - is_eip1559_changed_called_ = true; - EXPECT_EQ(chain_id, expected_chain_id_); - EXPECT_EQ(is_eip1559, expected_is_eip1559_); - } - - bool is_eip1559_changed_called() { - base::RunLoop().RunUntilIdle(); - return is_eip1559_changed_called_; - } - - bool chain_changed_called() { - base::RunLoop().RunUntilIdle(); - return chain_changed_called_; - } + MOCK_METHOD2(OnIsEip1559Changed, void(const std::string&, bool)); ::mojo::PendingRemote GetReceiver() { @@ -316,11 +284,7 @@ class TestJsonRpcServiceObserver base::OnceClosure callback_; std::string expected_chain_id_; - mojom::CoinType expected_coin_; std::string expected_error_; - bool expected_is_eip1559_; - bool chain_changed_called_ = false; - bool is_eip1559_changed_called_ = false; mojo::Receiver observer_receiver_{this}; }; @@ -727,9 +691,9 @@ class JsonRpcServiceUnitTest : public testing::Test { ipfs::IpfsService::RegisterProfilePrefs(prefs_.registry()); json_rpc_service_ = std::make_unique( shared_url_loader_factory_, &prefs_, &local_state_prefs_); - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH); - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); + SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, absl::nullopt); + SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL, absl::nullopt); + SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL, absl::nullopt); } ~JsonRpcServiceUnitTest() override = default; @@ -1080,26 +1044,12 @@ class JsonRpcServiceUnitTest : public testing::Test { } } - void ValidateStartWithNetwork(const std::string& chain_id, - const std::string& expected_id) { - ScopedDictPrefUpdate update(prefs(), kBraveWalletSelectedNetworks); - update->Set(kEthereumPrefKey, chain_id); - JsonRpcService service(shared_url_loader_factory(), prefs()); - bool callback_is_called = false; - service.GetChainId( - mojom::CoinType::ETH, - base::BindLambdaForTesting( - [&callback_is_called, &expected_id](const std::string& chain_id) { - EXPECT_EQ(chain_id, expected_id); - callback_is_called = true; - })); - ASSERT_TRUE(callback_is_called); - } - - bool SetNetwork(const std::string& chain_id, mojom::CoinType coin) { + bool SetNetwork(const std::string& chain_id, + mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) { bool result; base::RunLoop run_loop; - json_rpc_service_->SetNetwork(chain_id, coin, + json_rpc_service_->SetNetwork(chain_id, coin, origin, base::BindLambdaForTesting([&](bool success) { result = success; run_loop.Quit(); @@ -1108,6 +1058,33 @@ class JsonRpcServiceUnitTest : public testing::Test { return result; } + std::string GetChainId(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) { + std::string chain_id_out; + base::RunLoop run_loop; + json_rpc_service_->GetChainId( + coin, origin, + base::BindLambdaForTesting([&](const std::string& chain_id) { + chain_id_out = chain_id; + run_loop.Quit(); + })); + run_loop.Run(); + return chain_id_out; + } + + std::string GetNetworkUrl(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) { + std::string url_out; + base::RunLoop run_loop; + json_rpc_service_->GetNetworkUrl( + coin, origin, base::BindLambdaForTesting([&](const std::string& url) { + url_out = url; + run_loop.Quit(); + })); + run_loop.Run(); + return url_out; + } + void TestGetCode(const std::string& address, mojom::CoinType coin, const std::string& chain_id, @@ -1301,24 +1278,27 @@ class JsonRpcServiceUnitTest : public testing::Test { })); run_loop.Run(); } - void GetFilBlockHeight(uint64_t expected_height, + void GetFilBlockHeight(const std::string& chain_id, + uint64_t expected_height, mojom::FilecoinProviderError expected_error, const std::string& expected_error_message) { bool callback_called = false; base::RunLoop run_loop; - json_rpc_service_->GetFilBlockHeight(base::BindLambdaForTesting( - [&](uint64_t height, mojom::FilecoinProviderError error, - const std::string& error_message) { - EXPECT_EQ(height, expected_height); - EXPECT_EQ(error, expected_error); - EXPECT_EQ(error_message, expected_error_message); - callback_called = true; - run_loop.Quit(); - })); + json_rpc_service_->GetFilBlockHeight( + chain_id, base::BindLambdaForTesting( + [&](uint64_t height, mojom::FilecoinProviderError error, + const std::string& error_message) { + EXPECT_EQ(height, expected_height); + EXPECT_EQ(error, expected_error); + EXPECT_EQ(error_message, expected_error_message); + callback_called = true; + run_loop.Quit(); + })); run_loop.Run(); EXPECT_TRUE(callback_called); } - void GetFilStateSearchMsgLimited(const std::string& cid, + void GetFilStateSearchMsgLimited(const std::string& chain_id, + const std::string& cid, uint64_t period, int64_t expected_exit_code, mojom::FilecoinProviderError expected_error, @@ -1326,7 +1306,7 @@ class JsonRpcServiceUnitTest : public testing::Test { bool callback_called = false; base::RunLoop run_loop; json_rpc_service_->GetFilStateSearchMsgLimited( - cid, period, + chain_id, cid, period, base::BindLambdaForTesting([&](int64_t exit_code, mojom::FilecoinProviderError error, const std::string& error_message) { @@ -1339,13 +1319,14 @@ class JsonRpcServiceUnitTest : public testing::Test { run_loop.Run(); EXPECT_TRUE(callback_called); } - void GetSendFilecoinTransaction(const std::string& signed_tx, + void GetSendFilecoinTransaction(const std::string& chain_id, + const std::string& signed_tx, const std::string& expected_cid, mojom::FilecoinProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; json_rpc_service_->SendFilecoinTransaction( - signed_tx, + chain_id, signed_tx, base::BindLambdaForTesting([&](const std::string& cid, mojom::FilecoinProviderError error, const std::string& error_message) { @@ -1382,13 +1363,14 @@ class JsonRpcServiceUnitTest : public testing::Test { run_loop.Run(); } - void TestSendSolanaTransaction(const std::string& expected_tx_id, + void TestSendSolanaTransaction(const std::string& chain_id, + const std::string& expected_tx_id, mojom::SolanaProviderError expected_error, const std::string& expected_error_message, const std::string& signed_tx = "signed_tx") { base::RunLoop run_loop; json_rpc_service_->SendSolanaTransaction( - signed_tx, absl::nullopt, + chain_id, signed_tx, absl::nullopt, base::BindLambdaForTesting([&](const std::string& tx_id, mojom::SolanaProviderError error, const std::string& error_message) { @@ -1400,15 +1382,18 @@ class JsonRpcServiceUnitTest : public testing::Test { run_loop.Run(); } - void TestGetSolanaLatestBlockhash(const std::string& expected_hash, + void TestGetSolanaLatestBlockhash(const std::string& chain_id, + const std::string& expected_hash, uint64_t expected_last_valid_block_height, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; - json_rpc_service_->GetSolanaLatestBlockhash(base::BindLambdaForTesting( - [&](const std::string& hash, uint64_t last_valid_block_height, - mojom::SolanaProviderError error, - const std::string& error_message) { + json_rpc_service_->GetSolanaLatestBlockhash( + chain_id, + base::BindLambdaForTesting([&](const std::string& hash, + uint64_t last_valid_block_height, + mojom::SolanaProviderError error, + const std::string& error_message) { EXPECT_EQ(hash, expected_hash); EXPECT_EQ(last_valid_block_height, expected_last_valid_block_height); EXPECT_EQ(error, expected_error); @@ -1419,13 +1404,14 @@ class JsonRpcServiceUnitTest : public testing::Test { } void TestGetSolanaSignatureStatuses( + const std::string& chain_id, const std::vector& tx_signatures, const std::vector>& expected_stats, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; json_rpc_service_->GetSolanaSignatureStatuses( - tx_signatures, + chain_id, tx_signatures, base::BindLambdaForTesting( [&](const std::vector>& stats, mojom::SolanaProviderError error, @@ -1439,12 +1425,13 @@ class JsonRpcServiceUnitTest : public testing::Test { } void TestGetSolanaAccountInfo( + const std::string& chain_id, absl::optional expected_account_info, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; json_rpc_service_->GetSolanaAccountInfo( - "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg", + chain_id, "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg", base::BindLambdaForTesting( [&](absl::optional account_info, mojom::SolanaProviderError error, @@ -1457,30 +1444,35 @@ class JsonRpcServiceUnitTest : public testing::Test { run_loop.Run(); } - void TestGetSolanaFeeForMessage(const std::string& message, + void TestGetSolanaFeeForMessage(const std::string& chain_id, + const std::string& message, uint64_t expected_tx_fee, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; json_rpc_service_->GetSolanaFeeForMessage( - message, base::BindLambdaForTesting( - [&](uint64_t tx_fee, mojom::SolanaProviderError error, - const std::string& error_message) { - EXPECT_EQ(tx_fee, expected_tx_fee); - EXPECT_EQ(error, expected_error); - EXPECT_EQ(error_message, expected_error_message); - run_loop.Quit(); - })); + chain_id, message, + base::BindLambdaForTesting([&](uint64_t tx_fee, + mojom::SolanaProviderError error, + const std::string& error_message) { + EXPECT_EQ(tx_fee, expected_tx_fee); + EXPECT_EQ(error, expected_error); + EXPECT_EQ(error_message, expected_error_message); + run_loop.Quit(); + })); run_loop.Run(); } - void TestGetSolanaBlockHeight(uint64_t expected_block_height, + void TestGetSolanaBlockHeight(const std::string& chain_id, + uint64_t expected_block_height, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop run_loop; - json_rpc_service_->GetSolanaBlockHeight(base::BindLambdaForTesting( - [&](uint64_t block_height, mojom::SolanaProviderError error, - const std::string& error_message) { + json_rpc_service_->GetSolanaBlockHeight( + chain_id, + base::BindLambdaForTesting([&](uint64_t block_height, + mojom::SolanaProviderError error, + const std::string& error_message) { EXPECT_EQ(block_height, expected_block_height); EXPECT_EQ(error, expected_error); EXPECT_EQ(error_message, expected_error_message); @@ -1509,7 +1501,8 @@ class JsonRpcServiceUnitTest : public testing::Test { run_loop.Run(); } - void GetFilEstimateGas(const std::string& from, + void GetFilEstimateGas(const std::string& chain_id, + const std::string& from, const std::string& to, const std::string& value, const std::string& expected_gas_premium, @@ -1518,7 +1511,7 @@ class JsonRpcServiceUnitTest : public testing::Test { mojom::FilecoinProviderError expected_error) { base::RunLoop loop; json_rpc_service_->GetFilEstimateGas( - from, to, "", "", 0, 0, "", value, + chain_id, from, to, "", "", 0, 0, "", value, base::BindLambdaForTesting( [&](const std::string& gas_premium, const std::string& gas_fee_cap, int64_t gas_limit, mojom::FilecoinProviderError error, @@ -1587,65 +1580,74 @@ class JsonRpcServiceUnitTest : public testing::Test { }; TEST_F(JsonRpcServiceUnitTest, SetNetwork) { + const auto& origin_a = url::Origin::Create(GURL("https://a.com")); + const auto& origin_b = url::Origin::Create(GURL("https://b.com")); for (const auto& network : brave_wallet::GetAllKnownChains(prefs(), mojom::CoinType::ETH)) { - bool callback_is_called = false; - EXPECT_TRUE(SetNetwork(network->chain_id, mojom::CoinType::ETH)); + SCOPED_TRACE(network->chain_id); + EXPECT_TRUE( + SetNetwork(network->chain_id, mojom::CoinType::ETH, absl::nullopt)); + EXPECT_TRUE( + SetNetwork(mojom::kGoerliChainId, mojom::CoinType::ETH, origin_a)); EXPECT_EQ(network->chain_id, - GetCurrentChainId(prefs(), mojom::CoinType::ETH)); - const std::string& expected_id = network->chain_id; - json_rpc_service_->GetChainId( - mojom::CoinType::ETH, - base::BindLambdaForTesting( - [&callback_is_called, &expected_id](const std::string& chain_id) { - EXPECT_EQ(chain_id, expected_id); - callback_is_called = true; - })); - ASSERT_TRUE(callback_is_called); + GetCurrentChainId(prefs(), mojom::CoinType::ETH, absl::nullopt)); + EXPECT_EQ(mojom::kGoerliChainId, + GetCurrentChainId(prefs(), mojom::CoinType::ETH, origin_a)); + EXPECT_EQ(network->chain_id, + GetCurrentChainId(prefs(), mojom::CoinType::ETH, origin_b)); - callback_is_called = false; - const GURL expected_url = GetActiveEndpointUrl(*network); - json_rpc_service_->GetNetworkUrl( - mojom::CoinType::ETH, - base::BindLambdaForTesting( - [&callback_is_called, &expected_url](const std::string& spec) { - EXPECT_EQ(url::Origin::Create(GURL(spec)), - url::Origin::Create(expected_url)); - callback_is_called = true; - })); - ASSERT_TRUE(callback_is_called); + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, absl::nullopt), + network->chain_id); + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, origin_a), + mojom::kGoerliChainId); + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, origin_b), network->chain_id); + + EXPECT_EQ(url::Origin::Create( + GURL(GetNetworkUrl(mojom::CoinType::ETH, absl::nullopt))), + url::Origin::Create(GetActiveEndpointUrl(*network))); + EXPECT_EQ(url::Origin::Create( + GURL(GetNetworkUrl(mojom::CoinType::ETH, origin_a))), + url::Origin::Create(GURL("https://goerli-infura.brave.com"))); + EXPECT_EQ(url::Origin::Create( + GURL(GetNetworkUrl(mojom::CoinType::ETH, origin_b))), + url::Origin::Create(GetActiveEndpointUrl(*network))); } - base::RunLoop().RunUntilIdle(); // Solana - EXPECT_TRUE(SetNetwork(mojom::kSolanaMainnet, mojom::CoinType::SOL)); - ASSERT_EQ(mojom::kSolanaMainnet, - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); - EXPECT_FALSE(SetNetwork("0x1234", mojom::CoinType::SOL)); - EXPECT_TRUE(SetNetwork(mojom::kSolanaTestnet, mojom::CoinType::SOL)); - - base::RunLoop run_loop; - json_rpc_service_->GetChainId( - mojom::CoinType::SOL, - base::BindLambdaForTesting([&run_loop](const std::string& chain_id) { - EXPECT_EQ(chain_id, mojom::kSolanaTestnet); - run_loop.Quit(); - })); - run_loop.Run(); - - base::RunLoop run_loop2; - json_rpc_service_->GetNetworkUrl( - mojom::CoinType::SOL, - base::BindLambdaForTesting([&run_loop2](const std::string& spec) { - EXPECT_EQ(url::Origin::Create(GURL(spec)), - url::Origin::Create(GURL("https://api.testnet.solana.com"))); - run_loop2.Quit(); - })); - run_loop2.Run(); + EXPECT_TRUE( + SetNetwork(mojom::kSolanaMainnet, mojom::CoinType::SOL, absl::nullopt)); + EXPECT_FALSE(SetNetwork("0x1234", mojom::CoinType::SOL, absl::nullopt)); + EXPECT_TRUE( + SetNetwork(mojom::kSolanaTestnet, mojom::CoinType::SOL, origin_a)); + + EXPECT_EQ(mojom::kSolanaMainnet, + GetCurrentChainId(prefs(), mojom::CoinType::SOL, absl::nullopt)); + EXPECT_EQ(mojom::kSolanaTestnet, + GetCurrentChainId(prefs(), mojom::CoinType::SOL, origin_a)); + EXPECT_EQ(mojom::kSolanaMainnet, + GetCurrentChainId(prefs(), mojom::CoinType::SOL, origin_b)); + + EXPECT_EQ(GetChainId(mojom::CoinType::SOL, absl::nullopt), + mojom::kSolanaMainnet); + EXPECT_EQ(GetChainId(mojom::CoinType::SOL, origin_a), mojom::kSolanaTestnet); + EXPECT_EQ(GetChainId(mojom::CoinType::SOL, origin_b), mojom::kSolanaMainnet); + + EXPECT_EQ(url::Origin::Create( + GURL(GetNetworkUrl(mojom::CoinType::SOL, absl::nullopt))), + url::Origin::Create(GURL("https://mainnet-beta-solana.brave.com"))); + EXPECT_EQ( + url::Origin::Create(GURL(GetNetworkUrl(mojom::CoinType::SOL, origin_a))), + url::Origin::Create(GURL("https://api.testnet.solana.com"))); + EXPECT_EQ( + url::Origin::Create(GURL(GetNetworkUrl(mojom::CoinType::SOL, origin_b))), + url::Origin::Create(GURL("https://mainnet-beta-solana.brave.com"))); } TEST_F(JsonRpcServiceUnitTest, SetCustomNetwork) { + const auto& origin_a = url::Origin::Create(GURL("https://a.com")); + const auto& origin_b = url::Origin::Create(GURL("https://b.com")); + std::vector values; mojom::NetworkInfo chain1 = GetTestNetworkInfo1(); values.push_back(NetworkInfoToValue(chain1)); @@ -1654,33 +1656,25 @@ TEST_F(JsonRpcServiceUnitTest, SetCustomNetwork) { values.push_back(NetworkInfoToValue(chain2)); UpdateCustomNetworks(prefs(), &values); - bool callback_is_called = false; - EXPECT_TRUE(SetNetwork(chain1.chain_id, mojom::CoinType::ETH)); - const std::string& expected_id = chain1.chain_id; - json_rpc_service_->GetChainId( - mojom::CoinType::ETH, - base::BindLambdaForTesting( - [&callback_is_called, &expected_id](const std::string& chain_id) { - EXPECT_EQ(chain_id, expected_id); - callback_is_called = true; - })); - ASSERT_TRUE(callback_is_called); - callback_is_called = false; - const GURL expected_url = GetActiveEndpointUrl(chain1); - json_rpc_service_->GetNetworkUrl( - mojom::CoinType::ETH, - base::BindLambdaForTesting( - [&callback_is_called, &expected_url](const std::string& spec) { - EXPECT_EQ(url::Origin::Create(GURL(spec)), - url::Origin::Create(expected_url)); - callback_is_called = true; - })); - ASSERT_TRUE(callback_is_called); - base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(SetNetwork(chain1.chain_id, mojom::CoinType::ETH, absl::nullopt)); + EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH, origin_a)); + + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, absl::nullopt), chain1.chain_id); + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, origin_a), chain2.chain_id); + EXPECT_EQ(GetChainId(mojom::CoinType::ETH, origin_b), chain1.chain_id); + + EXPECT_EQ(GetNetworkUrl(mojom::CoinType::ETH, absl::nullopt), + GetActiveEndpointUrl(chain1)); + EXPECT_EQ(GetNetworkUrl(mojom::CoinType::ETH, origin_a), + GetActiveEndpointUrl(chain2)); + EXPECT_EQ(GetNetworkUrl(mojom::CoinType::ETH, origin_b), + GetActiveEndpointUrl(chain1)); } TEST_F(JsonRpcServiceUnitTest, GetAllNetworks) { std::vector values; + const auto& origin_a = url::Origin::Create(GURL("https://a.com")); + const auto& origin_b = url::Origin::Create(GURL("https://b.com")); mojom::NetworkInfo chain1 = GetTestNetworkInfo1(); values.push_back(NetworkInfoToValue(chain1)); @@ -1790,7 +1784,7 @@ TEST_F(JsonRpcServiceUnitTest, GetHiddenNetworks) { testing::Mock::VerifyAndClearExpectations(&callback); // Change active network so kLocalhostChainId becomes hidden. - SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH); + SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH, absl::nullopt); EXPECT_CALL( callback, Run(ElementsAreArray({mojom::kSepoliaChainId, mojom::kLocalhostChainId, @@ -1864,7 +1858,8 @@ TEST_F(JsonRpcServiceUnitTest, EnsGetEthAddr) { feature_list.InitAndDisableFeature(features::kBraveWalletENSL2Feature); SetUDENSInterceptor(mojom::kMainnetChainId); - EXPECT_TRUE(SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH)); + EXPECT_TRUE( + SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH, absl::nullopt)); base::MockCallback callback; EXPECT_CALL(callback, Run("0x983110309620D911731Ac0932219af06091b6744", false, @@ -1878,7 +1873,8 @@ TEST_F(JsonRpcServiceUnitTest, EnsGetEthAddr_ZeroAddress) { feature_list.InitAndDisableFeature(features::kBraveWalletENSL2Feature); SetENSZeroAddressInterceptor(mojom::kMainnetChainId); - EXPECT_TRUE(SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH)); + EXPECT_TRUE( + SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH, absl::nullopt)); base::MockCallback callback; EXPECT_CALL(callback, @@ -1962,8 +1958,7 @@ TEST_F(JsonRpcServiceUnitTest, AddEthereumChainApprovedForOrigin) { base::RunLoop loop; std::unique_ptr observer( - new TestJsonRpcServiceObserver(loop.QuitClosure(), "0x111", - mojom::CoinType::ETH, "")); + new TestJsonRpcServiceObserver(loop.QuitClosure(), "0x111", "")); json_rpc_service_->AddObserver(observer->GetReceiver()); @@ -2027,7 +2022,7 @@ TEST_F(JsonRpcServiceUnitTest, AddEthereumChainForOriginRejected) { base::RunLoop loop; std::unique_ptr observer( new TestJsonRpcServiceObserver( - loop.QuitClosure(), "0x111", mojom::CoinType::ETH, + loop.QuitClosure(), "0x111", l10n_util::GetStringUTF8(IDS_WALLET_USER_REJECTED_REQUEST))); json_rpc_service_->AddObserver(observer->GetReceiver()); @@ -2277,7 +2272,7 @@ TEST_F(JsonRpcServiceUnitTest, AddEthereumChainForOriginError) { base::RunLoop loop; std::unique_ptr observer( new TestJsonRpcServiceObserver( - loop.QuitClosure(), "0x333", mojom::CoinType::ETH, + loop.QuitClosure(), "0x333", l10n_util::GetStringFUTF8(IDS_BRAVE_WALLET_ETH_CHAIN_ID_FAILED, base::ASCIIToUTF16(network_url.spec())))); @@ -2301,7 +2296,7 @@ TEST_F(JsonRpcServiceUnitTest, AddEthereumChainForOriginError) { base::RunLoop loop; std::unique_ptr observer( new TestJsonRpcServiceObserver( - loop.QuitClosure(), "0x444", mojom::CoinType::ETH, + loop.QuitClosure(), "0x444", l10n_util::GetStringFUTF8( IDS_BRAVE_WALLET_ETH_CHAIN_ID_FAILED, base::ASCIIToUTF16(GURL(network_url).spec())))); @@ -2322,13 +2317,6 @@ TEST_F(JsonRpcServiceUnitTest, AddEthereumChainForOriginError) { } } -TEST_F(JsonRpcServiceUnitTest, StartWithNetwork) { - ValidateStartWithNetwork(std::string(), std::string()); - ValidateStartWithNetwork("SomeBadChainId", std::string()); - ValidateStartWithNetwork(brave_wallet::mojom::kGoerliChainId, - brave_wallet::mojom::kGoerliChainId); -} - TEST_F(JsonRpcServiceUnitTest, Request) { bool callback_called = false; std::string request = @@ -2340,7 +2328,8 @@ TEST_F(JsonRpcServiceUnitTest, Request) { SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH), "eth_blockNumber", "true", expected_response); json_rpc_service_->Request( - request, true, base::Value(), mojom::CoinType::ETH, + mojom::kLocalhostChainId, request, true, base::Value(), + mojom::CoinType::ETH, base::BindOnce(&OnRequestResponse, &callback_called, true /* success */, result)); base::RunLoop().RunUntilIdle(); @@ -2357,7 +2346,8 @@ TEST_F(JsonRpcServiceUnitTest, Request) { SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH), "eth_getBlockByNumber", "0x5BAD55,true", expected_response); json_rpc_service_->Request( - request, true, base::Value(), mojom::CoinType::ETH, + mojom::kLocalhostChainId, request, true, base::Value(), + mojom::CoinType::ETH, base::BindOnce(&OnRequestResponse, &callback_called, true /* success */, result)); base::RunLoop().RunUntilIdle(); @@ -2366,7 +2356,8 @@ TEST_F(JsonRpcServiceUnitTest, Request) { callback_called = false; SetHTTPRequestTimeoutInterceptor(); json_rpc_service_->Request( - request, true, base::Value(), mojom::CoinType::ETH, + mojom::kLocalhostChainId, request, true, base::Value(), + mojom::CoinType::ETH, base::BindOnce(&OnRequestResponse, &callback_called, false /* success */, "")); base::RunLoop().RunUntilIdle(); @@ -2389,7 +2380,8 @@ TEST_F(JsonRpcServiceUnitTest, Request_BadHeaderValues) { "", mock_response); bool callback_called = false; json_rpc_service_->Request( - request, true, base::Value(), mojom::CoinType::ETH, + mojom::kLocalhostChainId, request, true, base::Value(), + mojom::CoinType::ETH, base::BindOnce(&OnRequestResponse, &callback_called, false, "")); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); @@ -2540,12 +2532,16 @@ TEST_F(JsonRpcServiceUnitTest, GetFeeHistory) { SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH), "eth_feeHistory", "", json); base::RunLoop run_loop; - json_rpc_service_->GetFeeHistory(base::BindLambdaForTesting( - [&](const std::vector& base_fee_per_gas, - const std::vector& gas_used_ratio, - const std::string& oldest_block, - const std::vector>& reward, - mojom::ProviderError error, const std::string& error_message) { + json_rpc_service_->GetFeeHistory( + mojom::kLocalhostChainId, + base::BindLambdaForTesting([&](const std::vector& + base_fee_per_gas, + const std::vector& gas_used_ratio, + const std::string& oldest_block, + const std::vector< + std::vector>& reward, + mojom::ProviderError error, + const std::string& error_message) { EXPECT_EQ(error, mojom::ProviderError::kSuccess); EXPECT_TRUE(error_message.empty()); EXPECT_EQ(base_fee_per_gas, @@ -2560,46 +2556,52 @@ TEST_F(JsonRpcServiceUnitTest, GetFeeHistory) { SetHTTPRequestTimeoutInterceptor(); base::RunLoop run_loop2; - json_rpc_service_->GetFeeHistory(base::BindLambdaForTesting( - [&](const std::vector& base_fee_per_gas, - const std::vector& gas_used_ratio, - const std::string& oldest_block, - const std::vector>& reward, - mojom::ProviderError error, const std::string& error_message) { - EXPECT_EQ(error, mojom::ProviderError::kInternalError); - EXPECT_EQ(error_message, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); - run_loop2.Quit(); - })); + json_rpc_service_->GetFeeHistory( + mojom::kLocalhostChainId, + base::BindLambdaForTesting( + [&](const std::vector& base_fee_per_gas, + const std::vector& gas_used_ratio, + const std::string& oldest_block, + const std::vector>& reward, + mojom::ProviderError error, const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kInternalError); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + run_loop2.Quit(); + })); run_loop2.Run(); SetInvalidJsonInterceptor(); base::RunLoop run_loop3; - json_rpc_service_->GetFeeHistory(base::BindLambdaForTesting( - [&](const std::vector& base_fee_per_gas, - const std::vector& gas_used_ratio, - const std::string& oldest_block, - const std::vector>& reward, - mojom::ProviderError error, const std::string& error_message) { - EXPECT_EQ(error, mojom::ProviderError::kParsingError); - EXPECT_EQ(error_message, - l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); - run_loop3.Quit(); - })); + json_rpc_service_->GetFeeHistory( + mojom::kLocalhostChainId, + base::BindLambdaForTesting( + [&](const std::vector& base_fee_per_gas, + const std::vector& gas_used_ratio, + const std::string& oldest_block, + const std::vector>& reward, + mojom::ProviderError error, const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kParsingError); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); + run_loop3.Quit(); + })); run_loop3.Run(); SetLimitExceededJsonErrorResponse(); base::RunLoop run_loop4; - json_rpc_service_->GetFeeHistory(base::BindLambdaForTesting( - [&](const std::vector& base_fee_per_gas, - const std::vector& gas_used_ratio, - const std::string& oldest_block, - const std::vector>& reward, - mojom::ProviderError error, const std::string& error_message) { - EXPECT_EQ(error, mojom::ProviderError::kLimitExceeded); - EXPECT_EQ(error_message, "Request exceeds defined limit"); - run_loop4.Quit(); - })); + json_rpc_service_->GetFeeHistory( + mojom::kLocalhostChainId, + base::BindLambdaForTesting( + [&](const std::vector& base_fee_per_gas, + const std::vector& gas_used_ratio, + const std::string& oldest_block, + const std::vector>& reward, + mojom::ProviderError error, const std::string& error_message) { + EXPECT_EQ(error, mojom::ProviderError::kLimitExceeded); + EXPECT_EQ(error_message, "Request exceeds defined limit"); + run_loop4.Quit(); + })); run_loop4.Run(); } @@ -2679,8 +2681,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenBalance) { TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { bool callback_called = false; SetInterceptor( - GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH), "eth_call", - "", + GetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH), "eth_call", "", "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":" "\"0x00000000000000000000000000000000000000000000000166e12cfce39a0000\"" "}"); @@ -2688,7 +2689,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { json_rpc_service_->GetERC20TokenAllowance( "0x0d8775f648430679a709e98d2b0cb6250d2887ef", "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460f", - "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", + "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", mojom::kMainnetChainId, base::BindOnce(&OnStringResponse, &callback_called, mojom::ProviderError::kSuccess, "", "0x166e12cfce39a0000")); @@ -2700,7 +2701,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { json_rpc_service_->GetERC20TokenAllowance( "0x0d8775f648430679a709e98d2b0cb6250d2887ef", "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460f", - "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", + "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", mojom::kMainnetChainId, base::BindOnce(&OnStringResponse, &callback_called, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), "")); @@ -2712,7 +2713,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { json_rpc_service_->GetERC20TokenAllowance( "0x0d8775f648430679a709e98d2b0cb6250d2887ef", "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460f", - "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", + "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", mojom::kMainnetChainId, base::BindOnce(&OnStringResponse, &callback_called, mojom::ProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), "")); @@ -2724,7 +2725,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { json_rpc_service_->GetERC20TokenAllowance( "0x0d8775f648430679a709e98d2b0cb6250d2887ef", "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460f", - "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", + "0xBFb30a082f650C2A15D0632f0e87bE4F8e64460a", mojom::kMainnetChainId, base::BindOnce(&OnStringResponse, &callback_called, mojom::ProviderError::kLimitExceeded, "Request exceeds defined limit", "")); @@ -2734,7 +2735,7 @@ TEST_F(JsonRpcServiceUnitTest, GetERC20TokenAllowance) { // Invalid input should fail. callback_called = false; json_rpc_service_->GetERC20TokenAllowance( - "", "", "", + "", "", "", mojom::kMainnetChainId, base::BindOnce(&OnStringResponse, &callback_called, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS), @@ -3380,6 +3381,7 @@ TEST_F(JsonRpcServiceUnitTest, GetIsEip1559) { // Successful path when the network is EIP1559 SetIsEip1559Interceptor(expected_network, true); json_rpc_service_->GetIsEip1559( + mojom::kLocalhostChainId, base::BindOnce(&OnBoolResponse, &callback_called, mojom::ProviderError::kSuccess, "", true)); base::RunLoop().RunUntilIdle(); @@ -3389,6 +3391,7 @@ TEST_F(JsonRpcServiceUnitTest, GetIsEip1559) { callback_called = false; SetIsEip1559Interceptor(expected_network, false); json_rpc_service_->GetIsEip1559( + mojom::kLocalhostChainId, base::BindOnce(&OnBoolResponse, &callback_called, mojom::ProviderError::kSuccess, "", false)); base::RunLoop().RunUntilIdle(); @@ -3396,41 +3399,53 @@ TEST_F(JsonRpcServiceUnitTest, GetIsEip1559) { callback_called = false; SetHTTPRequestTimeoutInterceptor(); - json_rpc_service_->GetIsEip1559(base::BindOnce( - &OnBoolResponse, &callback_called, mojom::ProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), false)); + json_rpc_service_->GetIsEip1559( + mojom::kLocalhostChainId, + base::BindOnce(&OnBoolResponse, &callback_called, + mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), + false)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); callback_called = false; SetInvalidJsonInterceptor(); - json_rpc_service_->GetIsEip1559(base::BindOnce( - &OnBoolResponse, &callback_called, mojom::ProviderError::kParsingError, - l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), false)); + json_rpc_service_->GetIsEip1559( + mojom::kLocalhostChainId, + base::BindOnce(&OnBoolResponse, &callback_called, + mojom::ProviderError::kParsingError, + l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), + false)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); callback_called = false; SetLimitExceededJsonErrorResponse(); - json_rpc_service_->GetIsEip1559(base::BindOnce( - &OnBoolResponse, &callback_called, mojom::ProviderError::kLimitExceeded, - "Request exceeds defined limit", false)); + json_rpc_service_->GetIsEip1559( + mojom::kLocalhostChainId, + base::BindOnce(&OnBoolResponse, &callback_called, + mojom::ProviderError::kLimitExceeded, + "Request exceeds defined limit", false)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(callback_called); } TEST_F(JsonRpcServiceUnitTest, UpdateIsEip1559NotCalledForKnownChains) { - TestJsonRpcServiceObserver observer(mojom::kMainnetChainId, - mojom::CoinType::ETH, false); + TestJsonRpcServiceObserver observer; json_rpc_service_->AddObserver(observer.GetReceiver()); + EXPECT_CALL(observer, OnIsEip1559Changed(_, _)).Times(0); + EXPECT_CALL(observer, + ChainChangedEvent(mojom::kMainnetChainId, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); EXPECT_TRUE( - SetNetwork(brave_wallet::mojom::kMainnetChainId, mojom::CoinType::ETH)); - EXPECT_FALSE(observer.is_eip1559_changed_called()); + SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH, absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(JsonRpcServiceUnitTest, UpdateIsEip1559LocalhostChain) { - TestJsonRpcServiceObserver observer(mojom::kLocalhostChainId, - mojom::CoinType::ETH, true); + TestJsonRpcServiceObserver observer; json_rpc_service_->AddObserver(observer.GetReceiver()); GURL expected_network = GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH); @@ -3438,36 +3453,59 @@ TEST_F(JsonRpcServiceUnitTest, UpdateIsEip1559LocalhostChain) { // true in the RPC response. EXPECT_FALSE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); SetIsEip1559Interceptor(expected_network, true); - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_TRUE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(mojom::kLocalhostChainId, true)) + .Times(1); + EXPECT_CALL(observer, + ChainChangedEvent(mojom::kLocalhostChainId, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, + absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_TRUE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); // Switching to localhost should update is_eip1559 to false when is_eip1559 // is false in the RPC response. - observer.Reset(mojom::kLocalhostChainId, false); SetIsEip1559Interceptor(expected_network, false); - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_TRUE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(mojom::kLocalhostChainId, false)) + .Times(1); + EXPECT_CALL(observer, + ChainChangedEvent(mojom::kLocalhostChainId, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, + absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); // Switch to localhost again without changing is_eip1559 should not trigger // event. - observer.Reset(mojom::kLocalhostChainId, false); EXPECT_FALSE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); SetIsEip1559Interceptor(expected_network, false); - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_FALSE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(_, _)).Times(0); + EXPECT_CALL(observer, + ChainChangedEvent(mojom::kLocalhostChainId, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, + absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); // OnEip1559Changed will not be called if RPC fails. - observer.Reset(mojom::kLocalhostChainId, false); SetHTTPRequestTimeoutInterceptor(); - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_FALSE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(_, _)).Times(0); + EXPECT_CALL(observer, + ChainChangedEvent(mojom::kLocalhostChainId, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, + absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(mojom::kLocalhostChainId)); } @@ -3482,43 +3520,58 @@ TEST_F(JsonRpcServiceUnitTest, UpdateIsEip1559CustomChain) { // Switch to chain1 should trigger is_eip1559 being updated to true when // is_eip1559 is true in the RPC response. - TestJsonRpcServiceObserver observer(chain1.chain_id, mojom::CoinType::ETH, - true); + TestJsonRpcServiceObserver observer; json_rpc_service_->AddObserver(observer.GetReceiver()); EXPECT_FALSE(GetIsEip1559FromPrefs(chain1.chain_id)); SetIsEip1559Interceptor(GetActiveEndpointUrl(chain1), true); - EXPECT_TRUE(SetNetwork(chain1.chain_id, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_TRUE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(chain1.chain_id, true)).Times(1); + EXPECT_CALL(observer, ChainChangedEvent(chain1.chain_id, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(chain1.chain_id, mojom::CoinType::ETH, absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_TRUE(GetIsEip1559FromPrefs(chain1.chain_id)); // Switch to chain2 should trigger is_eip1559 being updated to false when // is_eip1559 is false in the RPC response. - observer.Reset(chain2.chain_id, false); EXPECT_TRUE(GetIsEip1559FromPrefs(chain2.chain_id)); SetIsEip1559Interceptor(GetActiveEndpointUrl(chain2), false); - EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_TRUE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(chain2.chain_id, false)).Times(1); + EXPECT_CALL(observer, ChainChangedEvent(chain2.chain_id, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH, absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(chain2.chain_id)); // Switch to chain2 again without changing is_eip1559 should not trigger // event. - observer.Reset(chain2.chain_id, false); EXPECT_FALSE(GetIsEip1559FromPrefs(chain2.chain_id)); SetIsEip1559Interceptor(GetActiveEndpointUrl(chain2), false); - EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_FALSE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(_, _)).Times(0); + EXPECT_CALL(observer, ChainChangedEvent(chain2.chain_id, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH, absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(chain2.chain_id)); // OnEip1559Changed will not be called if RPC fails. - observer.Reset(chain2.chain_id, false); SetHTTPRequestTimeoutInterceptor(); - EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH)); - EXPECT_TRUE(observer.chain_changed_called()); - EXPECT_FALSE(observer.is_eip1559_changed_called()); + EXPECT_CALL(observer, OnIsEip1559Changed(_, _)).Times(0); + EXPECT_CALL(observer, ChainChangedEvent(chain2.chain_id, mojom::CoinType::ETH, + testing::Eq(absl::nullopt))) + .Times(1); + EXPECT_TRUE(SetNetwork(chain2.chain_id, mojom::CoinType::ETH, absl::nullopt)); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); EXPECT_FALSE(GetIsEip1559FromPrefs(chain2.chain_id)); } @@ -3986,10 +4039,11 @@ TEST_F(JsonRpcServiceUnitTest, Reset) { UpdateCustomNetworks(prefs(), &values); ASSERT_FALSE(GetAllEthCustomChains(prefs()).empty()); - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH)); + EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH, + absl::nullopt)); prefs()->SetBoolean(kSupportEip1559OnLocalhostChain, true); EXPECT_TRUE(prefs()->HasPrefPath(kBraveWalletCustomNetworks)); - EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH), + EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH, absl::nullopt), mojom::kLocalhostChainId); // This isn't valid data for these maps but we are just checking to make sure // it gets cleared @@ -4006,7 +4060,7 @@ TEST_F(JsonRpcServiceUnitTest, Reset) { ASSERT_TRUE(GetAllEthCustomChains(prefs()).empty()); EXPECT_FALSE(prefs()->HasPrefPath(kBraveWalletCustomNetworks)); - EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH), + EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH, absl::nullopt), mojom::kMainnetChainId); EXPECT_FALSE(prefs()->HasPrefPath(kSupportEip1559OnLocalhostChain)); EXPECT_TRUE(json_rpc_service_->add_chain_pending_requests_.empty()); @@ -4083,7 +4137,7 @@ TEST_F(JsonRpcServiceUnitTest, GetSPLTokenAccountBalance) { TEST_F(JsonRpcServiceUnitTest, SendSolanaTransaction) { TestSendSolanaTransaction( - "", mojom::SolanaProviderError::kInvalidParams, + mojom::kLocalhostChainId, "", mojom::SolanaProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS), "" /* signed_tx */); @@ -4096,6 +4150,7 @@ TEST_F(JsonRpcServiceUnitTest, SendSolanaTransaction) { "o6iR6ykBvDxrTQrtpb\"}"); TestSendSolanaTransaction( + mojom::kLocalhostChainId, "2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6" "iR6ykBvDxrTQrtpb", mojom::SolanaProviderError::kSuccess, ""); @@ -4103,25 +4158,26 @@ TEST_F(JsonRpcServiceUnitTest, SendSolanaTransaction) { // Response parsing error SetInterceptor(expected_network_url, "sendTransaction", "", "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":0}"); - TestSendSolanaTransaction("", mojom::SolanaProviderError::kParsingError, + TestSendSolanaTransaction(mojom::kLocalhostChainId, "", + mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // JSON RPC error SetInterceptor(expected_network_url, "sendTransaction", "", "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":" "{\"code\":-32601, \"message\": \"method does not exist\"}}"); - TestSendSolanaTransaction("", mojom::SolanaProviderError::kMethodNotFound, + TestSendSolanaTransaction(mojom::kLocalhostChainId, "", + mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); TestSendSolanaTransaction( - "", mojom::SolanaProviderError::kInternalError, + mojom::kLocalhostChainId, "", mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } TEST_F(JsonRpcServiceUnitTest, GetSolanaLatestBlockhash) { - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL)); auto expected_network_url = GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); SetInterceptor(expected_network_url, "getLatestBlockhash", "", @@ -4130,29 +4186,31 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaLatestBlockhash) { "\"EkSnNWid2cvwEVnVx9aBqawnmiCNiDgp3gUdkDPTKN1N\", " "\"lastValidBlockHeight\":18446744073709551615}}}"); - TestGetSolanaLatestBlockhash("EkSnNWid2cvwEVnVx9aBqawnmiCNiDgp3gUdkDPTKN1N", - UINT64_MAX, mojom::SolanaProviderError::kSuccess, - ""); + TestGetSolanaLatestBlockhash( + mojom::kLocalhostChainId, "EkSnNWid2cvwEVnVx9aBqawnmiCNiDgp3gUdkDPTKN1N", + UINT64_MAX, mojom::SolanaProviderError::kSuccess, ""); // Response parsing error SetInterceptor(expected_network_url, "getLatestBlockhash", "", "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0\"}"); TestGetSolanaLatestBlockhash( - "", 0, mojom::SolanaProviderError::kParsingError, + mojom::kLocalhostChainId, "", 0, + mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // JSON RPC error SetInterceptor(expected_network_url, "getLatestBlockhash", "", "{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":" "{\"code\":-32601, \"message\": \"method does not exist\"}}"); - TestGetSolanaLatestBlockhash("", 0, + TestGetSolanaLatestBlockhash(mojom::kLocalhostChainId, "", 0, mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); TestGetSolanaLatestBlockhash( - "", 0, mojom::SolanaProviderError::kInternalError, + mojom::kLocalhostChainId, "", 0, + mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } @@ -4186,7 +4244,7 @@ TEST_F(JsonRpcServiceUnitTest, MigrateDeprecatedEthereumTestnets) { EXPECT_EQ(*selected_eth_network, mojom::kMainnetChainId); EXPECT_TRUE( prefs()->GetBoolean(kBraveWalletDeprecateEthereumTestNetworksMigrated)); - EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH), + EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH, absl::nullopt), mojom::kMainnetChainId); } @@ -4214,7 +4272,7 @@ TEST_F(JsonRpcServiceUnitTest, MigrateDeprecatedEthereumTestnets) { EXPECT_EQ(*selected_eth_network, mojom::kSepoliaChainId); EXPECT_TRUE( prefs()->GetBoolean(kBraveWalletDeprecateEthereumTestNetworksMigrated)); - EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH), + EXPECT_EQ(GetCurrentChainId(prefs(), mojom::CoinType::ETH, absl::nullopt), mojom::kSepoliaChainId); } @@ -4320,7 +4378,6 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaSignatureStatuses) { } } )"; - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL)); auto expected_network_url = GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); SetInterceptor(expected_network_url, "getSignatureStatuses", "", json); @@ -4341,14 +4398,16 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaSignatureStatuses) { SolanaSignatureStatus( 1092u, 0u, R"({"InstructionError":[0,{"Custom":1}]})", "finalized"), absl::nullopt}); - TestGetSolanaSignatureStatuses(tx_sigs, expected_statuses, + TestGetSolanaSignatureStatuses(mojom::kLocalhostChainId, tx_sigs, + expected_statuses, mojom::SolanaProviderError::kSuccess, ""); // Response parsing error SetInterceptor(expected_network_url, "getSignatureStatuses", "", R"({"jsonrpc":"2.0","id":1,"result":"0"})"); TestGetSolanaSignatureStatuses( - tx_sigs, std::vector>(), + mojom::kLocalhostChainId, tx_sigs, + std::vector>(), mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -4357,13 +4416,15 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaSignatureStatuses) { R"({"jsonrpc":"2.0","id":1,"error":{ "code":-32601, "message": "method does not exist"}})"); TestGetSolanaSignatureStatuses( - tx_sigs, std::vector>(), + mojom::kLocalhostChainId, tx_sigs, + std::vector>(), mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); TestGetSolanaSignatureStatuses( - tx_sigs, std::vector>(), + mojom::kLocalhostChainId, tx_sigs, + std::vector>(), mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } @@ -4395,20 +4456,20 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaAccountInfo) { expected_info.data = "SEVMTE8gV09STEQ="; expected_info.executable = false; expected_info.rent_epoch = UINT64_MAX; - TestGetSolanaAccountInfo(expected_info, mojom::SolanaProviderError::kSuccess, - ""); + TestGetSolanaAccountInfo(mojom::kLocalhostChainId, expected_info, + mojom::SolanaProviderError::kSuccess, ""); // value can be null for an account not on chain. SetInterceptor( expected_network_url, "getAccountInfo", "", R"({"jsonrpc":"2.0","result":{"context":{"slot":123121238},"value":null},"id":1})"); - TestGetSolanaAccountInfo(absl::nullopt, mojom::SolanaProviderError::kSuccess, - ""); + TestGetSolanaAccountInfo(mojom::kLocalhostChainId, absl::nullopt, + mojom::SolanaProviderError::kSuccess, ""); // Response parsing error SetInterceptor(expected_network_url, "getAccountInfo", "", R"({"jsonrpc":"2.0","id":1,"result":"0"})"); - TestGetSolanaAccountInfo(absl::nullopt, + TestGetSolanaAccountInfo(mojom::kLocalhostChainId, absl::nullopt, mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -4416,13 +4477,13 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaAccountInfo) { SetInterceptor(expected_network_url, "getAccountInfo", "", R"({"jsonrpc":"2.0","id":1,"error":{ "code":-32601, "message": "method does not exist"}})"); - TestGetSolanaAccountInfo(absl::nullopt, + TestGetSolanaAccountInfo(mojom::kLocalhostChainId, absl::nullopt, mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); - TestGetSolanaAccountInfo(absl::nullopt, + TestGetSolanaAccountInfo(mojom::kLocalhostChainId, absl::nullopt, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } @@ -4444,15 +4505,18 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaFeeForMessage) { std::string base64_encoded_string; base::Base64Encode("test", &base64_encoded_string); - TestGetSolanaFeeForMessage(base64_encoded_string, UINT64_MAX, - mojom::SolanaProviderError::kSuccess, ""); + TestGetSolanaFeeForMessage(mojom::kLocalhostChainId, base64_encoded_string, + UINT64_MAX, mojom::SolanaProviderError::kSuccess, + ""); std::string base58_encoded_string = "JvSKSz9YHfqEQ8j"; // Message has to be base64 encoded string and non-empty. TestGetSolanaFeeForMessage( - "", 0, mojom::SolanaProviderError::kInvalidParams, + mojom::kLocalhostChainId, "", 0, + mojom::SolanaProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); TestGetSolanaFeeForMessage( - base58_encoded_string, 0, mojom::SolanaProviderError::kInvalidParams, + mojom::kLocalhostChainId, base58_encoded_string, 0, + mojom::SolanaProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); // value can be null for an account not on chain. @@ -4462,14 +4526,15 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaFeeForMessage) { "result":{ "context":{"slot":123121238},"value":null},"id":1 })"); - TestGetSolanaFeeForMessage(base64_encoded_string, 0, + TestGetSolanaFeeForMessage(mojom::kLocalhostChainId, base64_encoded_string, 0, mojom::SolanaProviderError::kSuccess, ""); // Response parsing error SetInterceptor(expected_network_url, "getFeeForMessage", "", R"({"jsonrpc":"2.0","id":1,"result":"0"})"); TestGetSolanaFeeForMessage( - base64_encoded_string, 0, mojom::SolanaProviderError::kParsingError, + mojom::kLocalhostChainId, base64_encoded_string, 0, + mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // JSON RPC error @@ -4479,14 +4544,15 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaFeeForMessage) { "error": {"code":-32601, "message": "method does not exist"} })"); - TestGetSolanaFeeForMessage(base64_encoded_string, 0, + TestGetSolanaFeeForMessage(mojom::kLocalhostChainId, base64_encoded_string, 0, mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); TestGetSolanaFeeForMessage( - base64_encoded_string, 0, mojom::SolanaProviderError::kInternalError, + mojom::kLocalhostChainId, base64_encoded_string, 0, + mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } @@ -4497,7 +4563,7 @@ TEST_F(JsonRpcServiceUnitTest, GetEthTransactionCount) { "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x1\"}"); json_rpc_service_->GetEthTransactionCount( - "0x4e02f254184E904300e0775E4b8eeCB1", + mojom::kLocalhostChainId, "0x4e02f254184E904300e0775E4b8eeCB1", base::BindOnce(&OnEthUint256Response, &callback_called, mojom::ProviderError::kSuccess, "", 1)); base::RunLoop().RunUntilIdle(); @@ -4506,7 +4572,7 @@ TEST_F(JsonRpcServiceUnitTest, GetEthTransactionCount) { callback_called = false; SetHTTPRequestTimeoutInterceptor(); json_rpc_service_->GetEthTransactionCount( - "0x4e02f254184E904300e0775E4b8eeCB1", + mojom::kLocalhostChainId, "0x4e02f254184E904300e0775E4b8eeCB1", base::BindOnce(&OnEthUint256Response, &callback_called, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), 0)); @@ -4516,7 +4582,7 @@ TEST_F(JsonRpcServiceUnitTest, GetEthTransactionCount) { callback_called = false; SetInvalidJsonInterceptor(); json_rpc_service_->GetEthTransactionCount( - "0x4e02f254184E904300e0775E4b8eeCB1", + mojom::kLocalhostChainId, "0x4e02f254184E904300e0775E4b8eeCB1", base::BindOnce(&OnEthUint256Response, &callback_called, mojom::ProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), 0)); @@ -4526,7 +4592,7 @@ TEST_F(JsonRpcServiceUnitTest, GetEthTransactionCount) { callback_called = false; SetLimitExceededJsonErrorResponse(); json_rpc_service_->GetEthTransactionCount( - "0x4e02f254184E904300e0775E4b8eeCB1", + mojom::kLocalhostChainId, "0x4e02f254184E904300e0775E4b8eeCB1", base::BindOnce(&OnEthUint256Response, &callback_called, mojom::ProviderError::kLimitExceeded, "Request exceeds defined limit", 0)); @@ -4536,13 +4602,12 @@ TEST_F(JsonRpcServiceUnitTest, GetEthTransactionCount) { TEST_F(JsonRpcServiceUnitTest, GetFilTransactionCount) { bool callback_called = false; - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.MpoolGetNonce", "", R"({"jsonrpc":"2.0","id":1,"result":18446744073709551615})"); json_rpc_service_->GetFilTransactionCount( - "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", + mojom::kLocalhostChainId, "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", base::BindOnce(&OnFilUint256Response, &callback_called, mojom::FilecoinProviderError::kSuccess, "", UINT64_MAX)); base::RunLoop().RunUntilIdle(); @@ -4551,7 +4616,7 @@ TEST_F(JsonRpcServiceUnitTest, GetFilTransactionCount) { callback_called = false; SetHTTPRequestTimeoutInterceptor(); json_rpc_service_->GetFilTransactionCount( - "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", + mojom::kLocalhostChainId, "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", base::BindOnce(&OnFilUint256Response, &callback_called, mojom::FilecoinProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), 0)); @@ -4562,7 +4627,7 @@ TEST_F(JsonRpcServiceUnitTest, GetFilTransactionCount) { SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.MpoolGetNonce", "", R"({"jsonrpc":"2.0","id":1})"); json_rpc_service_->GetFilTransactionCount( - "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", + mojom::kLocalhostChainId, "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", base::BindOnce(&OnFilUint256Response, &callback_called, mojom::FilecoinProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), 0)); @@ -4572,7 +4637,7 @@ TEST_F(JsonRpcServiceUnitTest, GetFilTransactionCount) { callback_called = false; SetFilecoinActorErrorJsonErrorResponse(); json_rpc_service_->GetFilTransactionCount( - "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", + mojom::kLocalhostChainId, "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q", base::BindOnce(&OnFilUint256Response, &callback_called, mojom::FilecoinProviderError::kActorNotFound, "resolution lookup failed", 0)); @@ -4581,19 +4646,19 @@ TEST_F(JsonRpcServiceUnitTest, GetFilTransactionCount) { } TEST_F(JsonRpcServiceUnitTest, GetSolanaBlockHeight) { - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL)); auto expected_network_url = GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); SetInterceptor(expected_network_url, "getBlockHeight", "", R"({"jsonrpc":"2.0", "id":1, "result":18446744073709551615})"); - TestGetSolanaBlockHeight(UINT64_MAX, mojom::SolanaProviderError::kSuccess, - ""); + TestGetSolanaBlockHeight(mojom::kLocalhostChainId, UINT64_MAX, + mojom::SolanaProviderError::kSuccess, ""); // Response parsing error SetInterceptor(expected_network_url, "getBlockHeight", "", R"({"jsonrpc":"2.0","id":1})"); - TestGetSolanaBlockHeight(0, mojom::SolanaProviderError::kParsingError, + TestGetSolanaBlockHeight(mojom::kLocalhostChainId, 0, + mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // JSON RPC error @@ -4604,19 +4669,20 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaBlockHeight) { "message":"method does not exist" } })"); - TestGetSolanaBlockHeight(0, mojom::SolanaProviderError::kMethodNotFound, + TestGetSolanaBlockHeight(mojom::kLocalhostChainId, 0, + mojom::SolanaProviderError::kMethodNotFound, "method does not exist"); // HTTP error SetHTTPRequestTimeoutInterceptor(); - TestGetSolanaBlockHeight(0, mojom::SolanaProviderError::kInternalError, + TestGetSolanaBlockHeight(mojom::kLocalhostChainId, 0, + mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } TEST_F(JsonRpcServiceUnitTest, GetSolanaTokenAccountsByOwner) { - EXPECT_TRUE(SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL)); auto expected_network_url = - GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); + GetNetwork(mojom::kSolanaMainnet, mojom::CoinType::SOL); // Valid SetInterceptor(expected_network_url, "getTokenAccountsByOwner", "", R"({ @@ -4718,42 +4784,42 @@ TEST_F(JsonRpcServiceUnitTest, GetSolanaTokenAccountsByOwner) { } TEST_F(JsonRpcServiceUnitTest, GetFilEstimateGas) { - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.GasEstimateMessageGas", "", GetGasFilEstimateResponse(INT64_MAX)); - GetFilEstimateGas("t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", - "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", - "1000000000000000000", "100466", "101520", INT64_MAX, - mojom::FilecoinProviderError::kSuccess); + GetFilEstimateGas( + mojom::kLocalhostChainId, "t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", + "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", "1000000000000000000", + "100466", "101520", INT64_MAX, mojom::FilecoinProviderError::kSuccess); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.GasEstimateMessageGas", "", GetGasFilEstimateResponse(INT64_MIN)); - GetFilEstimateGas("t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", - "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", - "1000000000000000000", "100466", "101520", INT64_MIN, - mojom::FilecoinProviderError::kSuccess); + GetFilEstimateGas( + mojom::kLocalhostChainId, "t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", + "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", "1000000000000000000", + "100466", "101520", INT64_MIN, mojom::FilecoinProviderError::kSuccess); - GetFilEstimateGas("", "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", + GetFilEstimateGas(mojom::kLocalhostChainId, "", + "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", "1000000000000000000", "", "", 0, mojom::FilecoinProviderError::kInvalidParams); - GetFilEstimateGas("t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", "", + GetFilEstimateGas(mojom::kLocalhostChainId, + "t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", "", "1000000000000000000", "", "", 0, mojom::FilecoinProviderError::kInvalidParams); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.GasEstimateMessageGas", "", ""); - GetFilEstimateGas("t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", - "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", - "1000000000000000000", "", "", 0, - mojom::FilecoinProviderError::kInternalError); + GetFilEstimateGas( + mojom::kLocalhostChainId, "t1tquwkjo6qvweah2g2yikewr7y5dyjds42pnrn3a", + "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", "1000000000000000000", "", + "", 0, mojom::FilecoinProviderError::kInternalError); } TEST_F(JsonRpcServiceUnitTest, GetFilChainHead) { - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); std::string response = R"( { "id": 1, "jsonrpc": "2.0", "result": { @@ -4766,10 +4832,12 @@ TEST_F(JsonRpcServiceUnitTest, GetFilChainHead) { })"; SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.ChainHead", "", response); - GetFilBlockHeight(UINT64_MAX, mojom::FilecoinProviderError::kSuccess, ""); + GetFilBlockHeight(mojom::kLocalhostChainId, UINT64_MAX, + mojom::FilecoinProviderError::kSuccess, ""); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.ChainHead", "", ""); - GetFilBlockHeight(0, mojom::FilecoinProviderError::kInternalError, + GetFilBlockHeight(mojom::kLocalhostChainId, 0, + mojom::FilecoinProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.ChainHead", "", R"( @@ -4779,17 +4847,18 @@ TEST_F(JsonRpcServiceUnitTest, GetFilChainHead) { "message":"wrong param count (method 'Filecoin.ChainHead'): 1 != 0" } })"); - GetFilBlockHeight(0, mojom::FilecoinProviderError::kInvalidParams, + GetFilBlockHeight(mojom::kLocalhostChainId, 0, + mojom::FilecoinProviderError::kInvalidParams, "wrong param count (method 'Filecoin.ChainHead'): 1 != 0"); } TEST_F(JsonRpcServiceUnitTest, GetFilStateSearchMsgLimited) { - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.StateSearchMsgLimited", "", GetFilStateSearchMsgLimitedResponse(0)); GetFilStateSearchMsgLimited( + mojom::kLocalhostChainId, "bafy2bzacebundyopm3trenj47hxkwiqn2cbvvftz3fss4dxuttu2u6xbbtkqy", 30, 0, mojom::FilecoinProviderError::kSuccess, ""); @@ -4804,12 +4873,14 @@ TEST_F(JsonRpcServiceUnitTest, GetFilStateSearchMsgLimited) { } })"); GetFilStateSearchMsgLimited( + mojom::kLocalhostChainId, "bafy2bzacebundyopm3trenj47hxkwiqn2cbvvftz3fss4dxuttu2u6xbbtkqy", 30, -1, mojom::FilecoinProviderError::kInvalidParams, "wrong param count"); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.StateSearchMsgLimited", "", R"({,})"); GetFilStateSearchMsgLimited( + mojom::kLocalhostChainId, "bafy2bzacebundyopm3trenj47hxkwiqn2cbvvftz3fss4dxuttu2u6xbbtkqy", 30, -1, mojom::FilecoinProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); @@ -4818,6 +4889,7 @@ TEST_F(JsonRpcServiceUnitTest, GetFilStateSearchMsgLimited) { "Filecoin.StateSearchMsgLimited", "", GetFilStateSearchMsgLimitedResponse(INT64_MAX)); GetFilStateSearchMsgLimited( + mojom::kLocalhostChainId, "bafy2bzacebundyopm3trenj47hxkwiqn2cbvvftz3fss4dxuttu2u6xbbtkqy", 30, INT64_MAX, mojom::FilecoinProviderError::kSuccess, ""); @@ -4825,12 +4897,12 @@ TEST_F(JsonRpcServiceUnitTest, GetFilStateSearchMsgLimited) { "Filecoin.StateSearchMsgLimited", "", GetFilStateSearchMsgLimitedResponse(INT64_MIN)); GetFilStateSearchMsgLimited( + mojom::kLocalhostChainId, "bafy2bzacebundyopm3trenj47hxkwiqn2cbvvftz3fss4dxuttu2u6xbbtkqy", 30, INT64_MIN, mojom::FilecoinProviderError::kSuccess, ""); } TEST_F(JsonRpcServiceUnitTest, SendFilecoinTransaction) { - SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.MpoolPush", "", R"({ @@ -4840,7 +4912,7 @@ TEST_F(JsonRpcServiceUnitTest, SendFilecoinTransaction) { "/": "cid" } })"); - GetSendFilecoinTransaction("{}", "cid", + GetSendFilecoinTransaction(mojom::kLocalhostChainId, "{}", "cid", mojom::FilecoinProviderError::kSuccess, ""); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), @@ -4853,20 +4925,23 @@ TEST_F(JsonRpcServiceUnitTest, SendFilecoinTransaction) { "message":"wrong param count" } })"); - GetSendFilecoinTransaction("{}", "", + GetSendFilecoinTransaction(mojom::kLocalhostChainId, "{}", "", mojom::FilecoinProviderError::kInvalidParams, "wrong param count"); SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL), "Filecoin.MpoolPush", "", ""); GetSendFilecoinTransaction( - "{}", "", mojom::FilecoinProviderError::kParsingError, + mojom::kLocalhostChainId, "{}", "", + mojom::FilecoinProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); GetSendFilecoinTransaction( - "broken json", "", mojom::FilecoinProviderError::kInternalError, + mojom::kLocalhostChainId, "broken json", "", + mojom::FilecoinProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); GetSendFilecoinTransaction( - "", "", mojom::FilecoinProviderError::kInternalError, + mojom::kLocalhostChainId, "", "", + mojom::FilecoinProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } diff --git a/components/brave_wallet/browser/nft_metadata_fetcher_unittest.cc b/components/brave_wallet/browser/nft_metadata_fetcher_unittest.cc index 18c204786814..68544ee49878 100644 --- a/components/brave_wallet/browser/nft_metadata_fetcher_unittest.cc +++ b/components/brave_wallet/browser/nft_metadata_fetcher_unittest.cc @@ -159,13 +159,14 @@ class NftMetadataFetcherUnitTest : public testing::Test { run_loop.Run(); } - void TestGetSolTokenMetadata(const std::string& token_mint_address, + void TestGetSolTokenMetadata(const std::string& chain_id, + const std::string& token_mint_address, const std::string& expected_response, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { base::RunLoop loop; nft_metadata_fetcher_->GetSolTokenMetadata( - mojom::kSolanaMainnet, token_mint_address, + chain_id, token_mint_address, base::BindLambdaForTesting([&](const std::string& token_url, const std::string& response, mojom::SolanaProviderError error, @@ -693,9 +694,9 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", - valid_metadata_response, - mojom::SolanaProviderError::kSuccess, ""); + TestGetSolTokenMetadata( + mojom::kSolanaMainnet, "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", + valid_metadata_response, mojom::SolanaProviderError::kSuccess, ""); // Invalid token_mint_address yields internal error. SetSolTokenMetadataInterceptor( @@ -704,13 +705,14 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("Invalid", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, "Invalid", "", mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); // Non 200 getAccountInfo response of yields internal server error. SetHTTPRequestTimeoutInterceptor(); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); @@ -721,7 +723,8 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); @@ -752,7 +755,8 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -784,7 +788,8 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -816,7 +821,8 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -849,7 +855,8 @@ TEST_F(NftMetadataFetcherUnitTest, GetSolTokenMetadata) { "bafkreif4wx54wjr7pgfug3wlatr3nfntsfwngv6eusebbquezrxenj6ck4.ipfs." "dweb.link/?ext="), valid_metadata_response); - TestGetSolTokenMetadata("5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", + TestGetSolTokenMetadata(mojom::kSolanaMainnet, + "5ZXToo7froykjvjnpHtTLYr9u2tW3USMwPg3sNkiaQVh", "", mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); } diff --git a/components/brave_wallet/browser/solana_block_tracker_unittest.cc b/components/brave_wallet/browser/solana_block_tracker_unittest.cc index 91744ef531f6..ae9ff08fe171 100644 --- a/components/brave_wallet/browser/solana_block_tracker_unittest.cc +++ b/components/brave_wallet/browser/solana_block_tracker_unittest.cc @@ -8,6 +8,7 @@ #include #include +#include "base/scoped_observation.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" @@ -16,32 +17,28 @@ #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" +using testing::_; + namespace brave_wallet { namespace { -class TrackerObserver : public SolanaBlockTracker::Observer { +class MockTrackerObserver : public SolanaBlockTracker::Observer { public: - void OnLatestBlockhashUpdated(const std::string& latest_blockhash, - uint64_t last_valid_block_height) override { - latest_blockhash_ = latest_blockhash; - last_valid_block_height_ = last_valid_block_height; - ++latest_blockhash_updated_fired_; + explicit MockTrackerObserver(SolanaBlockTracker* tracker) { + observation_.Observe(tracker); } - size_t latest_blockhash_updated_fired() const { - return latest_blockhash_updated_fired_; - } - std::string latest_blockhash() const { return latest_blockhash_; } - uint64_t last_valid_block_height() const { return last_valid_block_height_; } + MOCK_METHOD3(OnLatestBlockhashUpdated, + void(const std::string&, const std::string&, uint64_t)); private: - size_t latest_blockhash_updated_fired_ = 0; - std::string latest_blockhash_; - uint64_t last_valid_block_height_ = 0; + base::ScopedObservation + observation_{this}; }; } // namespace @@ -70,17 +67,23 @@ class SolanaBlockTrackerUnitTest : public testing::Test { std::to_string(response_last_valid_block_height_) + "}}}"; } - void TestGetLatestBlockhash(bool try_cached_value, + void TestGetLatestBlockhash(const base::Location& location, + const std::string& chain_id, + bool try_cached_value, const std::string& expected_latest_blockhash, uint64_t expected_last_valid_block_height, mojom::SolanaProviderError expected_error, const std::string& expected_error_message) { + SCOPED_TRACE(testing::Message() << location.ToString()); base::RunLoop run_loop; tracker_->GetLatestBlockhash( + chain_id, base::BindLambdaForTesting([&](const std::string& latest_blockhash, uint64_t last_valid_block_height, mojom::SolanaProviderError error, const std::string& error_message) { + EXPECT_EQ(error_message, expected_error_message); + ASSERT_EQ(error, expected_error); EXPECT_EQ(latest_blockhash, expected_latest_blockhash); EXPECT_EQ(last_valid_block_height, expected_last_valid_block_height); EXPECT_EQ(error, expected_error); @@ -112,34 +115,36 @@ TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhash) { })); response_blockhash_ = "hash1"; response_last_valid_block_height_ = 3090; - TrackerObserver observer; - tracker_->AddObserver(&observer); - - tracker_->Start(base::Seconds(5)); + MockTrackerObserver observer(tracker_.get()); + + tracker_->Start(mojom::kSolanaMainnet, base::Seconds(5)); + tracker_->Start(mojom::kSolanaTestnet, base::Seconds(2)); + EXPECT_CALL(observer, + OnLatestBlockhashUpdated(mojom::kSolanaMainnet, "hash1", 3090u)) + .Times(1); + EXPECT_CALL(observer, + OnLatestBlockhashUpdated(mojom::kSolanaTestnet, "hash1", 3090u)) + .Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), "hash1"); - EXPECT_EQ(observer.last_valid_block_height(), 3090u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 1u); - EXPECT_EQ(tracker_->latest_blockhash(), "hash1"); - EXPECT_EQ(tracker_->last_valid_block_height(), 3090u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); response_blockhash_ = "hash2"; response_last_valid_block_height_ = 3290; - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kSolanaMainnet, base::Seconds(5)); + tracker_->Start(mojom::kSolanaTestnet, base::Seconds(2)); + EXPECT_CALL(observer, + OnLatestBlockhashUpdated(mojom::kSolanaMainnet, "hash2", 3290u)) + .Times(1); + EXPECT_CALL(observer, + OnLatestBlockhashUpdated(mojom::kSolanaTestnet, "hash2", 3290u)) + .Times(1); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), "hash2"); - EXPECT_EQ(observer.last_valid_block_height(), 3290u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 2u); - EXPECT_EQ(tracker_->latest_blockhash(), "hash2"); - EXPECT_EQ(tracker_->last_valid_block_height(), 3290u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); // Still response_blockhash_ hash2, shouldn't fire updated event. + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), "hash2"); - EXPECT_EQ(observer.last_valid_block_height(), 3290u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 2u); - EXPECT_EQ(tracker_->latest_blockhash(), "hash2"); - EXPECT_EQ(tracker_->last_valid_block_height(), 3290u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashInvalidResponseJSON) { @@ -152,16 +157,13 @@ TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashInvalidResponseJSON) { response_blockhash_ = "hash3"; response_last_valid_block_height_ = 3290; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kSolanaMainnet, base::Seconds(5)); + tracker_->Start(mojom::kSolanaTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), ""); - EXPECT_EQ(observer.last_valid_block_height(), 0u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_blockhash(), ""); - EXPECT_EQ(tracker_->last_valid_block_height(), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashInternalError) { @@ -181,16 +183,13 @@ TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashInternalError) { response_blockhash_ = "hash3"; response_last_valid_block_height_ = 3290; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kSolanaMainnet, base::Seconds(5)); + tracker_->Start(mojom::kSolanaTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), ""); - EXPECT_EQ(observer.last_valid_block_height(), 0u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_blockhash(), ""); - EXPECT_EQ(tracker_->last_valid_block_height(), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashRequestTimeout) { @@ -203,72 +202,90 @@ TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashRequestTimeout) { response_blockhash_ = "hash3"; response_last_valid_block_height_ = 3290; - TrackerObserver observer; - tracker_->AddObserver(&observer); + MockTrackerObserver observer(tracker_.get()); - tracker_->Start(base::Seconds(5)); + tracker_->Start(mojom::kSolanaMainnet, base::Seconds(5)); + tracker_->Start(mojom::kSolanaTestnet, base::Seconds(2)); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); task_environment_.FastForwardBy(base::Seconds(5)); - EXPECT_EQ(observer.latest_blockhash(), ""); - EXPECT_EQ(observer.last_valid_block_height(), 0u); - EXPECT_EQ(observer.latest_blockhash_updated_fired(), 0u); - EXPECT_EQ(tracker_->latest_blockhash(), ""); - EXPECT_EQ(tracker_->last_valid_block_height(), 0u); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(SolanaBlockTrackerUnitTest, GetLatestBlockhashWithoutStartTracker) { - ASSERT_FALSE(tracker_->IsRunning()); - - url_loader_factory_.SetInterceptor( - base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - url_loader_factory_.ClearResponses(); - url_loader_factory_.AddResponse(request.url.spec(), - GetResponseString()); - })); - - response_blockhash_ = "hash1"; - response_last_valid_block_height_ = 3090; - TestGetLatestBlockhash(false, "hash1", 3090, - mojom::SolanaProviderError::kSuccess, ""); - - // Cached value would be used if it's not expired yet. - response_blockhash_ = "hash2"; - response_last_valid_block_height_ = 3290; - TestGetLatestBlockhash(true, "hash1", 3090, - mojom::SolanaProviderError::kSuccess, ""); - TestGetLatestBlockhash(false, "hash2", 3290, - mojom::SolanaProviderError::kSuccess, ""); - - // Cached value would expire after kBlockTrackerDefaultTimeInSeconds. - response_blockhash_ = "hash3"; - response_last_valid_block_height_ = 3490; - task_environment_.FastForwardBy( - base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - TestGetLatestBlockhash(true, "hash3", 3490, - mojom::SolanaProviderError::kSuccess, ""); - TestGetLatestBlockhash(false, "hash3", 3490, - mojom::SolanaProviderError::kSuccess, ""); - - // Callback should be called when JSON-RPC failed, cached blockhash won't be - // updated and can continue to be used until expired. - url_loader_factory_.SetInterceptor( - base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - url_loader_factory_.ClearResponses(); - url_loader_factory_.AddResponse(request.url.spec(), "", - net::HTTP_REQUEST_TIMEOUT); - })); - TestGetLatestBlockhash(false, "", 0, - mojom::SolanaProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); - TestGetLatestBlockhash(true, "hash3", 3490, - mojom::SolanaProviderError::kSuccess, ""); - task_environment_.FastForwardBy( - base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - TestGetLatestBlockhash(false, "", 0, - mojom::SolanaProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); - TestGetLatestBlockhash(true, "", 0, - mojom::SolanaProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + MockTrackerObserver observer(tracker_.get()); + for (const std::string& chain_id : + {mojom::kSolanaMainnet, mojom::kSolanaTestnet}) { + SCOPED_TRACE(chain_id); + url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( + [&](const network::ResourceRequest& request) { + url_loader_factory_.ClearResponses(); + url_loader_factory_.AddResponse(request.url.spec(), + GetResponseString()); + })); + + ASSERT_FALSE(tracker_->IsRunning(chain_id)); + + response_blockhash_ = "hash1"; + response_last_valid_block_height_ = 3090; + EXPECT_CALL(observer, OnLatestBlockhashUpdated(chain_id, "hash1", 3090u)) + .Times(1); + TestGetLatestBlockhash(FROM_HERE, chain_id, false, "hash1", 3090, + mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + // Cached value would be used if it's not expired yet. + response_blockhash_ = "hash2"; + response_last_valid_block_height_ = 3290; + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); + TestGetLatestBlockhash(FROM_HERE, chain_id, true, "hash1", 3090, + mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + EXPECT_CALL(observer, OnLatestBlockhashUpdated(chain_id, "hash2", 3290u)) + .Times(1); + TestGetLatestBlockhash(FROM_HERE, chain_id, false, "hash2", 3290, + mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + // Cached value would expire after kBlockTrackerDefaultTimeInSeconds. + response_blockhash_ = "hash3"; + response_last_valid_block_height_ = 3490; + task_environment_.FastForwardBy( + base::Seconds(kBlockTrackerDefaultTimeInSeconds)); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(chain_id, "hash3", 3490u)) + .Times(1); + TestGetLatestBlockhash(FROM_HERE, chain_id, true, "hash3", 3490, + mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); + TestGetLatestBlockhash(FROM_HERE, chain_id, true, "hash3", 3490, + mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + + // Callback should be called when JSON-RPC failed, cached blockhash won't be + // updated and can continue to be used until expired. + url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( + [&](const network::ResourceRequest& request) { + url_loader_factory_.ClearResponses(); + url_loader_factory_.AddResponse(request.url.spec(), "", + net::HTTP_REQUEST_TIMEOUT); + })); + EXPECT_CALL(observer, OnLatestBlockhashUpdated(_, _, _)).Times(0); + TestGetLatestBlockhash(FROM_HERE, chain_id, false, "", 0, + mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + TestGetLatestBlockhash(FROM_HERE, chain_id, true, "hash3", 3490, + mojom::SolanaProviderError::kSuccess, ""); + task_environment_.FastForwardBy( + base::Seconds(kBlockTrackerDefaultTimeInSeconds)); + TestGetLatestBlockhash(FROM_HERE, chain_id, false, "", 0, + mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + TestGetLatestBlockhash(FROM_HERE, chain_id, true, "", 0, + mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + } } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/solana_tx_manager_unittest.cc b/components/brave_wallet/browser/solana_tx_manager_unittest.cc index d5d1b771c6a8..518a0a42d0d7 100644 --- a/components/brave_wallet/browser/solana_tx_manager_unittest.cc +++ b/components/brave_wallet/browser/solana_tx_manager_unittest.cc @@ -228,14 +228,16 @@ class SolanaTxManagerUnitTest : public testing::Test { return url::Origin::Create(GURL("https://brave.com")); } - void AddUnapprovedTransaction(mojom::SolanaTxDataPtr solana_tx_data, + void AddUnapprovedTransaction(const std::string& chain_id, + mojom::SolanaTxDataPtr solana_tx_data, const std::string& from, std::string* meta_id) { - AddUnapprovedTransaction(std::move(solana_tx_data), from, GetOrigin(), - meta_id, absl::nullopt); + AddUnapprovedTransaction(chain_id, std::move(solana_tx_data), from, + GetOrigin(), meta_id, absl::nullopt); } void AddUnapprovedTransaction( + const std::string& chain_id, mojom::SolanaTxDataPtr solana_tx_data, const std::string& from, const absl::optional& origin, @@ -246,7 +248,7 @@ class SolanaTxManagerUnitTest : public testing::Test { base::RunLoop run_loop; solana_tx_manager()->AddUnapprovedTransaction( - std::move(tx_data_union), from, origin, group_id, + chain_id, std::move(tx_data_union), from, origin, group_id, base::BindLambdaForTesting([&](bool success, const std::string& id, const std::string& err_message) { ASSERT_TRUE(success); @@ -258,19 +260,21 @@ class SolanaTxManagerUnitTest : public testing::Test { run_loop.Run(); } - void ApproveTransaction(const std::string& meta_id) { + void ApproveTransaction(const std::string& chain_id, + const std::string& meta_id) { base::RunLoop run_loop; solana_tx_manager()->ApproveTransaction( - meta_id, base::BindLambdaForTesting( - [&](bool success, mojom::ProviderErrorUnionPtr error_union, - const std::string& err_message) { - ASSERT_TRUE(success); - ASSERT_TRUE(error_union->is_solana_provider_error()); - ASSERT_EQ(error_union->get_solana_provider_error(), - mojom::SolanaProviderError::kSuccess); - ASSERT_TRUE(err_message.empty()); - run_loop.Quit(); - })); + chain_id, meta_id, + base::BindLambdaForTesting([&](bool success, + mojom::ProviderErrorUnionPtr error_union, + const std::string& err_message) { + ASSERT_TRUE(success); + ASSERT_TRUE(error_union->is_solana_provider_error()); + ASSERT_EQ(error_union->get_solana_provider_error(), + mojom::SolanaProviderError::kSuccess); + ASSERT_TRUE(err_message.empty()); + run_loop.Quit(); + })); run_loop.Run(); } @@ -301,6 +305,7 @@ class SolanaTxManagerUnitTest : public testing::Test { } void TestMakeTokenProgramTransferTxData( + const std::string& chain_id, const std::string& spl_token_mint_address, const std::string& from_wallet_address, const std::string& to_wallet_address, @@ -310,7 +315,8 @@ class SolanaTxManagerUnitTest : public testing::Test { const std::string& expected_err_message) { base::RunLoop run_loop; solana_tx_manager()->MakeTokenProgramTransferTxData( - spl_token_mint_address, from_wallet_address, to_wallet_address, amount, + chain_id, spl_token_mint_address, from_wallet_address, + to_wallet_address, amount, base::BindLambdaForTesting([&](mojom::SolanaTxDataPtr tx_data, mojom::SolanaProviderError error, const std::string& err_message) { @@ -343,29 +349,32 @@ class SolanaTxManagerUnitTest : public testing::Test { run_loop.Run(); } - void TestGetEstimatedTxFee(const std::string& tx_meta_id, + void TestGetEstimatedTxFee(const std::string& chain_id, + const std::string& tx_meta_id, uint64_t expected_tx_fee, mojom::SolanaProviderError expected_error, const std::string& expected_err_message) { base::RunLoop run_loop; solana_tx_manager()->GetEstimatedTxFee( - tx_meta_id, base::BindLambdaForTesting( - [&](uint64_t tx_fee, mojom::SolanaProviderError error, - const std::string& err_message) { - EXPECT_EQ(expected_tx_fee, tx_fee); - EXPECT_EQ(expected_error, error); - EXPECT_EQ(expected_err_message, err_message); - run_loop.Quit(); - })); + chain_id, tx_meta_id, + base::BindLambdaForTesting([&](uint64_t tx_fee, + mojom::SolanaProviderError error, + const std::string& err_message) { + EXPECT_EQ(expected_tx_fee, tx_fee); + EXPECT_EQ(expected_error, error); + EXPECT_EQ(expected_err_message, err_message); + run_loop.Quit(); + })); run_loop.Run(); } void TestGetTransactionMessageToSign( + const std::string& chain_id, const std::string& tx_meta_id, absl::optional> expected_tx_message) { base::RunLoop run_loop; solana_tx_manager()->GetTransactionMessageToSign( - tx_meta_id, + chain_id, tx_meta_id, base::BindLambdaForTesting( [&](mojom::MessageToSignUnionPtr tx_message) { EXPECT_EQ(!!tx_message, expected_tx_message.has_value()); @@ -381,6 +390,7 @@ class SolanaTxManagerUnitTest : public testing::Test { } void TestProcessSolanaHardwareSignature( + const std::string& chain_id, const std::string& tx_meta_id, const std::vector& signature, bool expected_result, @@ -388,7 +398,7 @@ class SolanaTxManagerUnitTest : public testing::Test { const std::string& expected_error_message) { base::RunLoop run_loop; solana_tx_manager()->ProcessSolanaHardwareSignature( - tx_meta_id, signature, + chain_id, tx_meta_id, signature, base::BindLambdaForTesting([&](bool result, mojom::ProviderErrorUnionPtr error_union, const std::string& error_message) { @@ -457,12 +467,13 @@ TEST_F(SolanaTxManagerUnitTest, AddAndApproveTransaction) { ASSERT_TRUE(tx); std::string meta_id1; - AddUnapprovedTransaction(solana_tx_data.Clone(), from_account, &meta_id1); + AddUnapprovedTransaction(mojom::kSolanaMainnet, solana_tx_data.Clone(), + from_account, &meta_id1); - auto tx_meta1 = solana_tx_manager()->GetTxForTesting(meta_id1); + auto tx_meta1 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id1); ASSERT_TRUE(tx_meta1); - EXPECT_EQ(tx_meta1->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta1->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(*tx_meta1->tx(), *tx); EXPECT_EQ(tx_meta1->signature_status(), SolanaSignatureStatus()); @@ -470,27 +481,28 @@ TEST_F(SolanaTxManagerUnitTest, AddAndApproveTransaction) { EXPECT_EQ(tx_meta1->status(), mojom::TransactionStatus::Unapproved); std::string meta_id2; - AddUnapprovedTransaction(solana_tx_data.Clone(), from_account, &meta_id2); - auto tx_meta2 = solana_tx_manager()->GetTxForTesting(meta_id2); + AddUnapprovedTransaction(mojom::kSolanaMainnet, solana_tx_data.Clone(), + from_account, &meta_id2); + auto tx_meta2 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id2); ASSERT_TRUE(tx_meta2); - EXPECT_EQ(tx_meta2->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta2->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(*tx_meta2->tx(), *tx); EXPECT_EQ(tx_meta2->signature_status(), SolanaSignatureStatus()); EXPECT_EQ(tx_meta2->from(), from_account); EXPECT_EQ(tx_meta2->status(), mojom::TransactionStatus::Unapproved); - ApproveTransaction(meta_id1); + ApproveTransaction(mojom::kSolanaMainnet, meta_id1); // Wait for tx to be updated. base::RunLoop().RunUntilIdle(); tx->message()->set_recent_blockhash(latest_blockhash1_); tx->message()->set_last_valid_block_height(last_valid_block_height1_); - tx_meta1 = solana_tx_manager()->GetTxForTesting(meta_id1); + tx_meta1 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id1); ASSERT_TRUE(tx_meta1); - EXPECT_EQ(tx_meta1->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta1->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(*tx_meta1->tx(), *tx); EXPECT_EQ(tx_meta1->signature_status(), SolanaSignatureStatus()); EXPECT_EQ(tx_meta1->from(), from_account); @@ -500,13 +512,13 @@ TEST_F(SolanaTxManagerUnitTest, AddAndApproveTransaction) { // Send another tx. SetInterceptor(latest_blockhash1_, last_valid_block_height1_, tx_hash2_, "", false, last_valid_block_height1_); - ApproveTransaction(meta_id2); + ApproveTransaction(mojom::kSolanaMainnet, meta_id2); base::RunLoop().RunUntilIdle(); - tx_meta2 = solana_tx_manager()->GetTxForTesting(meta_id2); + tx_meta2 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id2); ASSERT_TRUE(tx_meta2); - EXPECT_EQ(tx_meta2->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta2->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(*tx_meta2->tx(), *tx); EXPECT_EQ(tx_meta2->signature_status(), SolanaSignatureStatus()); EXPECT_EQ(tx_meta2->from(), from_account); @@ -523,12 +535,14 @@ TEST_F(SolanaTxManagerUnitTest, AddAndApproveTransaction) { // Fast forward again to have block tracker run with the new interceptor. task_environment_.FastForwardBy( base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - tx_meta1 = solana_tx_manager()->GetTxForTesting(meta_id1); + tx_meta1 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id1); EXPECT_EQ(mojom::TransactionStatus::Submitted, tx_meta1->status()); EXPECT_EQ(tx_meta1->signature_status(), SolanaSignatureStatus(100u, 10u, "", "confirmed")); - tx_meta2 = solana_tx_manager()->GetTxForTesting(meta_id2); + tx_meta2 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id2); EXPECT_EQ(mojom::TransactionStatus::Confirmed, tx_meta2->status()); EXPECT_EQ(tx_meta2->signature_status(), SolanaSignatureStatus(72u, 0u, "", "finalized")); @@ -544,13 +558,14 @@ TEST_F(SolanaTxManagerUnitTest, WalletOrigin) { ASSERT_TRUE(system_transfer_data); std::string meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, absl::nullopt, + AddUnapprovedTransaction(mojom::kSolanaMainnet, + std::move(system_transfer_data), from, absl::nullopt, &meta_id); - auto tx_meta = solana_tx_manager()->GetTxForTesting(meta_id); + auto tx_meta = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(tx_meta->origin(), url::Origin::Create(GURL("chrome://wallet"))); } @@ -564,14 +579,14 @@ TEST_F(SolanaTxManagerUnitTest, SomeSiteOrigin) { ASSERT_TRUE(system_transfer_data); std::string meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, - url::Origin::Create(GURL("https://some.site.com")), - &meta_id); + AddUnapprovedTransaction( + mojom::kSolanaMainnet, std::move(system_transfer_data), from, + url::Origin::Create(GURL("https://some.site.com")), &meta_id); - auto tx_meta = solana_tx_manager()->GetTxForTesting(meta_id); + auto tx_meta = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(tx_meta->origin(), url::Origin::Create(GURL("https://some.site.com"))); } @@ -586,13 +601,14 @@ TEST_F(SolanaTxManagerUnitTest, AddUnapprovedTransactionWithGroupId) { ASSERT_TRUE(system_transfer_data); std::string meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, absl::nullopt, + AddUnapprovedTransaction(mojom::kSolanaMainnet, + std::move(system_transfer_data), from, absl::nullopt, &meta_id, "mockGroupId"); - auto tx_meta = solana_tx_manager()->GetTxForTesting(meta_id); + auto tx_meta = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id); ASSERT_TRUE(tx_meta); - EXPECT_EQ(tx_meta->chain_id(), - GetCurrentChainId(prefs(), mojom::CoinType::SOL)); + EXPECT_EQ(tx_meta->chain_id(), mojom::kSolanaMainnet); EXPECT_EQ(tx_meta->group_id(), "mockGroupId"); } @@ -726,8 +742,9 @@ TEST_F(SolanaTxManagerUnitTest, MakeTokenProgramTransferTxData) { )"; SetInterceptor("", 0, "", json); TestMakeTokenProgramTransferTxData( - spl_token_mint_address, from_wallet_address, to_wallet_address, 10000000, - std::move(tx_data), mojom::SolanaProviderError::kSuccess, ""); + mojom::kSolanaMainnet, spl_token_mint_address, from_wallet_address, + to_wallet_address, 10000000, std::move(tx_data), + mojom::SolanaProviderError::kSuccess, ""); account_metas.clear(); auto solana_account_meta4 = @@ -791,8 +808,9 @@ TEST_F(SolanaTxManagerUnitTest, MakeTokenProgramTransferTxData) { )"; SetInterceptor("", 0, "", json); TestMakeTokenProgramTransferTxData( - spl_token_mint_address, from_wallet_address, to_wallet_address, 10000000, - tx_data.Clone(), mojom::SolanaProviderError::kSuccess, ""); + mojom::kSolanaMainnet, spl_token_mint_address, from_wallet_address, + to_wallet_address, 10000000, tx_data.Clone(), + mojom::SolanaProviderError::kSuccess, ""); // Test receiving associated token account does not exist. json = R"( @@ -805,21 +823,22 @@ TEST_F(SolanaTxManagerUnitTest, MakeTokenProgramTransferTxData) { })"; SetInterceptor("", 0, "", json); TestMakeTokenProgramTransferTxData( - spl_token_mint_address, from_wallet_address, to_wallet_address, 10000000, - std::move(tx_data), mojom::SolanaProviderError::kSuccess, ""); + mojom::kSolanaMainnet, spl_token_mint_address, from_wallet_address, + to_wallet_address, 10000000, std::move(tx_data), + mojom::SolanaProviderError::kSuccess, ""); // Empty addresses should be handled. TestMakeTokenProgramTransferTxData( - "", to_wallet_address, spl_token_mint_address, 10000000, nullptr, - mojom::SolanaProviderError::kInternalError, + mojom::kSolanaMainnet, "", to_wallet_address, spl_token_mint_address, + 10000000, nullptr, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); TestMakeTokenProgramTransferTxData( - from_wallet_address, "", spl_token_mint_address, 10000000, nullptr, - mojom::SolanaProviderError::kInternalError, + mojom::kSolanaMainnet, from_wallet_address, "", spl_token_mint_address, + 10000000, nullptr, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); TestMakeTokenProgramTransferTxData( - from_wallet_address, to_wallet_address, "", 10000000, nullptr, - mojom::SolanaProviderError::kInternalError, + mojom::kSolanaMainnet, from_wallet_address, to_wallet_address, "", + 10000000, nullptr, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); } @@ -914,7 +933,8 @@ TEST_F(SolanaTxManagerUnitTest, GetEstimatedTxFee) { ASSERT_TRUE(system_transfer_data); std::string system_transfer_meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, + AddUnapprovedTransaction(mojom::kSolanaMainnet, + std::move(system_transfer_data), from, &system_transfer_meta_id); ASSERT_FALSE(system_transfer_meta_id.empty()); @@ -927,7 +947,7 @@ TEST_F(SolanaTxManagerUnitTest, GetEstimatedTxFee) { // GetEstimatedTxFee without a valid latest blockhash being returned by // remote. SetInterceptor("", 0, "", json); - TestGetEstimatedTxFee(system_transfer_meta_id, 0, + TestGetEstimatedTxFee(mojom::kSolanaMainnet, system_transfer_meta_id, 0, mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); @@ -939,25 +959,25 @@ TEST_F(SolanaTxManagerUnitTest, GetEstimatedTxFee) { // GetEstimatedTxFee with latest blockhash and non-null tx fee from remote. SetInterceptor(latest_blockhash1_, last_valid_block_height1_, "", json); - TestGetEstimatedTxFee(system_transfer_meta_id, UINT64_MAX, - mojom::SolanaProviderError::kSuccess, ""); + TestGetEstimatedTxFee(mojom::kSolanaMainnet, system_transfer_meta_id, + UINT64_MAX, mojom::SolanaProviderError::kSuccess, ""); // GetEstimatedTxFee with cached blockhash and error at parsing tx fee. SetInterceptor(latest_blockhash1_, last_valid_block_height1_, "", "{}"); - TestGetEstimatedTxFee(system_transfer_meta_id, 0, + TestGetEstimatedTxFee(mojom::kSolanaMainnet, system_transfer_meta_id, 0, mojom::SolanaProviderError::kParsingError, l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)); // GetEstimatedTxFee with cached blockhash and null tx fee from remote. SetInterceptor(latest_blockhash1_, last_valid_block_height1_, "", json2); - TestGetEstimatedTxFee(system_transfer_meta_id, 0, + TestGetEstimatedTxFee(mojom::kSolanaMainnet, system_transfer_meta_id, 0, mojom::SolanaProviderError::kSuccess, ""); // GetEstimatedTxFee with cached latest blockhash and non-null tx fee from // remote. SetInterceptor("", 0, "", json); - TestGetEstimatedTxFee(system_transfer_meta_id, UINT64_MAX, - mojom::SolanaProviderError::kSuccess, ""); + TestGetEstimatedTxFee(mojom::kSolanaMainnet, system_transfer_meta_id, + UINT64_MAX, mojom::SolanaProviderError::kSuccess, ""); } TEST_F(SolanaTxManagerUnitTest, DropTxWithInvalidBlockhash) { @@ -972,9 +992,10 @@ TEST_F(SolanaTxManagerUnitTest, DropTxWithInvalidBlockhash) { SetInterceptor(latest_blockhash1_, last_valid_block_height1_, tx_hash1_, "", false, last_valid_block_height1_, false); std::string meta_id1; - AddUnapprovedTransaction(system_transfer_data.Clone(), from, &meta_id1); + AddUnapprovedTransaction(mojom::kSolanaMainnet, system_transfer_data.Clone(), + from, &meta_id1); ASSERT_FALSE(meta_id1.empty()); - ApproveTransaction(meta_id1); + ApproveTransaction(mojom::kSolanaMainnet, meta_id1); SetInterceptor(latest_blockhash2_, last_valid_block_height2_, tx_hash2_, "", false, last_valid_block_height1_, false); @@ -983,9 +1004,10 @@ TEST_F(SolanaTxManagerUnitTest, DropTxWithInvalidBlockhash) { base::Seconds(kBlockTrackerDefaultTimeInSeconds)); std::string meta_id2; - AddUnapprovedTransaction(system_transfer_data.Clone(), from, &meta_id2); + AddUnapprovedTransaction(mojom::kSolanaMainnet, system_transfer_data.Clone(), + from, &meta_id2); ASSERT_FALSE(meta_id2.empty()); - ApproveTransaction(meta_id2); + ApproveTransaction(mojom::kSolanaMainnet, meta_id2); // Wait for tx to be updated. base::RunLoop().RunUntilIdle(); @@ -993,16 +1015,19 @@ TEST_F(SolanaTxManagerUnitTest, DropTxWithInvalidBlockhash) { // Check two submitted tx. auto pending_transactions = solana_tx_manager()->GetSolanaTxStateManager()->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); + mojom::kSolanaMainnet, mojom::TransactionStatus::Submitted, + absl::nullopt); EXPECT_EQ(pending_transactions.size(), 2u); - auto tx1 = solana_tx_manager()->GetTxForTesting(meta_id1); + auto tx1 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id1); ASSERT_TRUE(tx1); EXPECT_EQ(tx1->status(), mojom::TransactionStatus::Submitted); EXPECT_EQ(tx1->tx()->message()->recent_blockhash(), latest_blockhash1_); EXPECT_EQ(tx1->tx()->message()->last_valid_block_height(), last_valid_block_height1_); - auto tx2 = solana_tx_manager()->GetTxForTesting(meta_id2); + auto tx2 = + solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, meta_id2); ASSERT_TRUE(tx2); EXPECT_EQ(tx2->status(), mojom::TransactionStatus::Submitted); EXPECT_EQ(tx2->tx()->message()->recent_blockhash(), latest_blockhash2_); @@ -1022,20 +1047,23 @@ TEST_F(SolanaTxManagerUnitTest, DropTxWithInvalidBlockhash) { // Check blockhash1 should be dropped, blockhash2 stay as submitted. auto dropped_transactions = solana_tx_manager()->GetSolanaTxStateManager()->GetTransactionsByStatus( - mojom::TransactionStatus::Dropped, absl::nullopt); + mojom::kSolanaMainnet, mojom::TransactionStatus::Dropped, + absl::nullopt); ASSERT_EQ(dropped_transactions.size(), 1u); EXPECT_EQ(dropped_transactions[0]->id(), meta_id1); pending_transactions = solana_tx_manager()->GetSolanaTxStateManager()->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, absl::nullopt); + mojom::kSolanaMainnet, mojom::TransactionStatus::Submitted, + absl::nullopt); ASSERT_EQ(pending_transactions.size(), 1u); EXPECT_EQ(pending_transactions[0]->id(), meta_id2); } TEST_F(SolanaTxManagerUnitTest, GetTransactionMessageToSign) { // Unknown tx_meta_id yields null message - TestGetTransactionMessageToSign("Unknown", absl::nullopt); + TestGetTransactionMessageToSign(mojom::kSolanaMainnet, "Unknown", + absl::nullopt); const std::string from = "89DzXVKJ79xf9MkzTxatQESh5fcvsqBo9fCsbAXkCaZE"; const std::string to = "148FvZU6e67eSB12wv7fXCH5FsTDW8tsxXo3nFuZhfCF"; @@ -1045,13 +1073,15 @@ TEST_F(SolanaTxManagerUnitTest, GetTransactionMessageToSign) { &system_transfer_data); ASSERT_TRUE(system_transfer_data); std::string system_transfer_meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, + AddUnapprovedTransaction(mojom::kSolanaMainnet, + std::move(system_transfer_data), from, &system_transfer_meta_id); ASSERT_FALSE(system_transfer_meta_id.empty()); // Invalid latest blockhash yields null message SetInterceptor("", 0, ""); - TestGetTransactionMessageToSign(system_transfer_meta_id, absl::nullopt); + TestGetTransactionMessageToSign(mojom::kSolanaMainnet, + system_transfer_meta_id, absl::nullopt); // Valid latest blockhash yields valid transaction message to sign SetInterceptor(latest_blockhash1_, last_valid_block_height1_, ""); @@ -1061,17 +1091,19 @@ TEST_F(SolanaTxManagerUnitTest, GetTransactionMessageToSign) { "aezhZAMzywrLOSju1o9VJQ5KaB2lsblgqvdjtkDFlmZHz4KQAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAMxJDpKM0uOHO7ND/" "JXaMxecpg9Nv0bCw26RKZ1V1Oa5AQICAAEMAgAAAAEAAAAAAAAA"); - TestGetTransactionMessageToSign(system_transfer_meta_id, message); + TestGetTransactionMessageToSign(mojom::kSolanaMainnet, + system_transfer_meta_id, message); // Valid cached latest blockhash SetInterceptor("", 0, "", ""); - TestGetTransactionMessageToSign(system_transfer_meta_id, message); + TestGetTransactionMessageToSign(mojom::kSolanaMainnet, + system_transfer_meta_id, message); } TEST_F(SolanaTxManagerUnitTest, ProcessSolanaHardwareSignature) { // Unknown tx_meta_id is invalid TestProcessSolanaHardwareSignature( - "Unknown", std::vector(), false, + mojom::kSolanaMainnet, "Unknown", std::vector(), false, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_TRANSACTION_NOT_FOUND)); @@ -1083,7 +1115,8 @@ TEST_F(SolanaTxManagerUnitTest, ProcessSolanaHardwareSignature) { &system_transfer_data); ASSERT_TRUE(system_transfer_data); std::string system_transfer_meta_id; - AddUnapprovedTransaction(std::move(system_transfer_data), from, + AddUnapprovedTransaction(mojom::kSolanaMainnet, + std::move(system_transfer_data), from, &system_transfer_meta_id); ASSERT_FALSE(system_transfer_meta_id.empty()); @@ -1096,19 +1129,20 @@ TEST_F(SolanaTxManagerUnitTest, ProcessSolanaHardwareSignature) { // Blockhash not set is invalid TestProcessSolanaHardwareSignature( - system_transfer_meta_id, signature_bytes, false, + mojom::kSolanaMainnet, system_transfer_meta_id, signature_bytes, false, mojom::SolanaProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); - auto meta = solana_tx_manager()->GetTxForTesting(system_transfer_meta_id); + auto meta = solana_tx_manager()->GetTxForTesting(mojom::kSolanaMainnet, + system_transfer_meta_id); meta->tx()->message()->set_recent_blockhash(latest_blockhash1_); meta->tx()->message()->set_last_valid_block_height(last_valid_block_height1_); solana_tx_manager()->GetSolanaTxStateManager()->AddOrUpdateTx(*meta); // Valid blockhash and valid number of signers is valid - TestProcessSolanaHardwareSignature(system_transfer_meta_id, signature_bytes, - true, mojom::SolanaProviderError::kSuccess, - ""); + TestProcessSolanaHardwareSignature( + mojom::kSolanaMainnet, system_transfer_meta_id, signature_bytes, true, + mojom::SolanaProviderError::kSuccess, ""); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/solana_tx_state_manager_unittest.cc b/components/brave_wallet/browser/solana_tx_state_manager_unittest.cc index ce9dfa44a53a..ffe38f01219f 100644 --- a/components/brave_wallet/browser/solana_tx_state_manager_unittest.cc +++ b/components/brave_wallet/browser/solana_tx_state_manager_unittest.cc @@ -12,7 +12,6 @@ #include "base/test/bind.h" #include "base/test/task_environment.h" #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/solana_account_meta.h" #include "brave/components/brave_wallet/browser/solana_instruction.h" #include "brave/components/brave_wallet/browser/solana_transaction.h" @@ -21,8 +20,6 @@ #include "brave/components/brave_wallet/common/brave_wallet_constants.h" #include "brave/components/brave_wallet/common/brave_wallet_types.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" namespace brave_wallet { @@ -30,32 +27,20 @@ namespace brave_wallet { class SolanaTxStateManagerUnitTest : public testing::Test { public: SolanaTxStateManagerUnitTest() - : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - shared_url_loader_factory_( - base::MakeRefCounted( - &url_loader_factory_)) {} + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} ~SolanaTxStateManagerUnitTest() override = default; protected: void SetUp() override { brave_wallet::RegisterProfilePrefs(prefs_.registry()); - json_rpc_service_ = std::make_unique( - shared_url_loader_factory_, GetPrefs()); - solana_tx_state_manager_ = std::make_unique( - GetPrefs(), json_rpc_service_.get()); - } - - void SetNetwork(const std::string& chain_id) { - ASSERT_TRUE(json_rpc_service_->SetNetwork(chain_id, mojom::CoinType::SOL)); + solana_tx_state_manager_ = + std::make_unique(GetPrefs()); } PrefService* GetPrefs() { return &prefs_; } base::test::TaskEnvironment task_environment_; - network::TestURLLoaderFactory url_loader_factory_; - scoped_refptr shared_url_loader_factory_; sync_preferences::TestingPrefServiceSyncable prefs_; - std::unique_ptr json_rpc_service_; std::unique_ptr solana_tx_state_manager_; }; @@ -92,6 +77,7 @@ TEST_F(SolanaTxStateManagerUnitTest, SolanaTxMetaAndValue) { "FmBV6UjKdiSZkQUW"); meta.set_origin(url::Origin::Create(GURL("https://test.brave.com/"))); meta.set_group_id("mockGroupId"); + meta.set_chain_id(mojom::kSolanaMainnet); base::Value::Dict meta_value = meta.ToValue(); auto meta_from_value = @@ -101,14 +87,17 @@ TEST_F(SolanaTxStateManagerUnitTest, SolanaTxMetaAndValue) { } TEST_F(SolanaTxStateManagerUnitTest, GetTxPrefPathPrefix) { - EXPECT_EQ("solana.mainnet", solana_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork("0x66"); - EXPECT_EQ("solana.testnet", solana_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork("0x67"); - EXPECT_EQ("solana.devnet", solana_tx_state_manager_->GetTxPrefPathPrefix()); - SetNetwork(brave_wallet::mojom::kLocalhostChainId); - EXPECT_EQ("solana.http://localhost:8899/", - solana_tx_state_manager_->GetTxPrefPathPrefix()); + EXPECT_EQ("solana.mainnet", solana_tx_state_manager_->GetTxPrefPathPrefix( + mojom::kSolanaMainnet)); + EXPECT_EQ("solana.testnet", solana_tx_state_manager_->GetTxPrefPathPrefix( + mojom::kSolanaTestnet)); + EXPECT_EQ("solana.devnet", solana_tx_state_manager_->GetTxPrefPathPrefix( + mojom::kSolanaDevnet)); + EXPECT_EQ( + "solana.http://localhost:8899/", + solana_tx_state_manager_->GetTxPrefPathPrefix(mojom::kLocalhostChainId)); + EXPECT_EQ("solana", + solana_tx_state_manager_->GetTxPrefPathPrefix(absl::nullopt)); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/swap_service_unittest.cc b/components/brave_wallet/browser/swap_service_unittest.cc index 15817f24e739..f6fda1d0d8a4 100644 --- a/components/brave_wallet/browser/swap_service_unittest.cc +++ b/components/brave_wallet/browser/swap_service_unittest.cc @@ -17,6 +17,7 @@ #include "brave/components/brave_wallet/browser/swap_response_parser.h" #include "brave/components/brave_wallet/browser/swap_service.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" +#include "brave/components/brave_wallet/common/test_utils.h" #include "components/grit/brave_components_strings.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" @@ -30,15 +31,6 @@ using base::test::ParseJson; namespace { -// Matcher to check equality of two mojo structs. Matcher needs copyable value -// which is not possible for some mojo types, so wrapping it with RefCounted. -template -auto EqualsMojo(const T& value) { - return testing::Truly( - [value = base::MakeRefCounted>(value.Clone())]( - const T& candidate) { return mojo::Equals(candidate, value->data); }); -} - auto IsTruthy(bool truthy) { return testing::Truly( [=](const auto& candidate) { return !!candidate == truthy; }); diff --git a/components/brave_wallet/browser/tx_state_manager_unittest.cc b/components/brave_wallet/browser/tx_state_manager_unittest.cc index 390dbabd2a7e..75bb1b2cef0d 100644 --- a/components/brave_wallet/browser/tx_state_manager_unittest.cc +++ b/components/brave_wallet/browser/tx_state_manager_unittest.cc @@ -8,6 +8,7 @@ #include "brave/components/brave_wallet/browser/tx_state_manager.h" #include "base/run_loop.h" +#include "base/scoped_observation.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "base/test/values_test_util.h" @@ -17,98 +18,50 @@ #include "brave/components/brave_wallet/browser/brave_wallet_utils.h" #include "brave/components/brave_wallet/browser/eth_tx_meta.h" #include "brave/components/brave_wallet/browser/eth_tx_state_manager.h" -#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/pref_names.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" +#include "brave/components/brave_wallet/common/test_utils.h" #include "components/prefs/pref_service.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using base::test::ParseJson; using base::test::ParseJsonDict; +using testing::_; namespace brave_wallet { -class TestTxStateManagerObserver : public TxStateManager::Observer { +class MockTxStateManagerObserver : public TxStateManager::Observer { public: - TestTxStateManagerObserver() = default; - - void OnNewUnapprovedTx(mojom::TransactionInfoPtr tx) override { - new_unapproved_tx_fired_ = true; - tx_status_ = tx->tx_status; - tx_id_ = tx->id; - } - - void OnTransactionStatusChanged(mojom::TransactionInfoPtr tx) override { - tx_status_changed_fired_ = true; - tx_status_ = tx->tx_status; - tx_id_ = tx->id; + explicit MockTxStateManagerObserver(TxStateManager* tx_state_manager) { + observation_.Observe(tx_state_manager); } - void ExpectMatch(const std::string& expected_tx_id, - mojom::TransactionStatus expected_status) { - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(expected_tx_id, tx_id_); - EXPECT_EQ(expected_status, tx_status_); - } - - void Reset() { - new_unapproved_tx_fired_ = false; - tx_status_changed_fired_ = false; - } - - bool NewUnapprovedTxFired() const { - base::RunLoop().RunUntilIdle(); - return new_unapproved_tx_fired_; - } - - bool TxStatusChangedFired() const { - base::RunLoop().RunUntilIdle(); - return tx_status_changed_fired_; - } + MOCK_METHOD1(OnTransactionStatusChanged, void(mojom::TransactionInfoPtr)); + MOCK_METHOD1(OnNewUnapprovedTx, void(mojom::TransactionInfoPtr)); private: - std::string tx_id_; - mojom::TransactionStatus tx_status_; - bool new_unapproved_tx_fired_ = false; - bool tx_status_changed_fired_ = false; + base::ScopedObservation + observation_{this}; }; class TxStateManagerUnitTest : public testing::Test { public: - TxStateManagerUnitTest() - : shared_url_loader_factory_( - base::MakeRefCounted( - &url_loader_factory_)) {} + TxStateManagerUnitTest() {} protected: void SetUp() override { brave_wallet::RegisterProfilePrefs(prefs_.registry()); brave_wallet::RegisterProfilePrefsForMigration(prefs_.registry()); - json_rpc_service_ = - std::make_unique(shared_url_loader_factory_, &prefs_); // The only different between each coin type's tx state manager in these // base functions are their pref paths, so here we just use // EthTxStateManager to test common methods in TxStateManager. - tx_state_manager_ = - std::make_unique(&prefs_, json_rpc_service_.get()); - } - - void SetNetwork(const std::string& chain_id, mojom::CoinType coin) { - base::RunLoop run_loop; - json_rpc_service_->SetNetwork( - chain_id, coin, - base::BindLambdaForTesting([&](bool success) { run_loop.Quit(); })); - run_loop.Run(); + tx_state_manager_ = std::make_unique(&prefs_); } base::test::TaskEnvironment task_environment_; - network::TestURLLoaderFactory url_loader_factory_; - scoped_refptr shared_url_loader_factory_; sync_preferences::TestingPrefServiceSyncable prefs_; - std::unique_ptr json_rpc_service_; std::unique_ptr tx_state_manager_; }; @@ -117,6 +70,7 @@ TEST_F(TxStateManagerUnitTest, TxOperations) { EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kMainnetChainId); EXPECT_FALSE(prefs_.HasPrefPath(kBraveWalletTransactions)); // Add tx_state_manager_->AddOrUpdateTx(meta); @@ -173,23 +127,25 @@ TEST_F(TxStateManagerUnitTest, TxOperations) { // Get { - auto meta_fetched = tx_state_manager_->GetTx("001"); + auto meta_fetched = tx_state_manager_->GetTx(mojom::kMainnetChainId, "001"); ASSERT_NE(meta_fetched, nullptr); - ASSERT_EQ(tx_state_manager_->GetTx("003"), nullptr); + ASSERT_EQ(tx_state_manager_->GetTx(mojom::kMainnetChainId, "003"), nullptr); + ASSERT_EQ(tx_state_manager_->GetTx(mojom::kGoerliChainId, "001"), nullptr); EXPECT_EQ(meta_fetched->id(), "001"); EXPECT_EQ(meta_fetched->tx_hash(), "0xabcd"); - auto meta_fetched2 = tx_state_manager_->GetTx("002"); + auto meta_fetched2 = + tx_state_manager_->GetTx(mojom::kMainnetChainId, "002"); ASSERT_NE(meta_fetched2, nullptr); EXPECT_EQ(meta_fetched2->id(), "002"); EXPECT_EQ(meta_fetched2->tx_hash(), "0xabff"); - auto meta_fetched3 = tx_state_manager_->GetTx(""); + auto meta_fetched3 = tx_state_manager_->GetTx(mojom::kMainnetChainId, ""); EXPECT_EQ(meta_fetched3, nullptr); } // Delete - tx_state_manager_->DeleteTx("001"); + tx_state_manager_->DeleteTx(mojom::kMainnetChainId, "001"); { const auto& dict = prefs_.GetDict(kBraveWalletTransactions); EXPECT_EQ(dict.size(), 1u); @@ -221,50 +177,110 @@ TEST_F(TxStateManagerUnitTest, GetTransactionsByStatus) { if (i % 2 == 0) { if (i % 4 == 0) meta.set_from(addr1); + if (i % 6 == 0) { + meta.set_chain_id(mojom::kMainnetChainId); + } else { + meta.set_chain_id(mojom::kGoerliChainId); + } meta.set_status(mojom::TransactionStatus::Confirmed); } else { if (i % 5 == 0) meta.set_from(addr2); + if (i % 7 == 0) { + meta.set_chain_id(mojom::kMainnetChainId); + } else { + meta.set_chain_id(mojom::kGoerliChainId); + } meta.set_status(mojom::TransactionStatus::Submitted); } tx_state_manager_->AddOrUpdateTx(meta); } + EXPECT_EQ( + tx_state_manager_ + ->GetTransactionsByStatus( + absl::nullopt, mojom::TransactionStatus::Approved, absl::nullopt) + .size(), + 0u); + EXPECT_EQ( + tx_state_manager_ + ->GetTransactionsByStatus( + absl::nullopt, mojom::TransactionStatus::Confirmed, absl::nullopt) + .size(), + 10u); EXPECT_EQ(tx_state_manager_ - ->GetTransactionsByStatus(mojom::TransactionStatus::Approved, + ->GetTransactionsByStatus(mojom::kMainnetChainId, + mojom::TransactionStatus::Confirmed, absl::nullopt) .size(), - 0u); + 4u); EXPECT_EQ(tx_state_manager_ - ->GetTransactionsByStatus(mojom::TransactionStatus::Confirmed, + ->GetTransactionsByStatus(mojom::kGoerliChainId, + mojom::TransactionStatus::Confirmed, absl::nullopt) .size(), - 10u); + 6u); + EXPECT_EQ( + tx_state_manager_ + ->GetTransactionsByStatus( + absl::nullopt, mojom::TransactionStatus::Submitted, absl::nullopt) + .size(), + 10u); EXPECT_EQ(tx_state_manager_ - ->GetTransactionsByStatus(mojom::TransactionStatus::Submitted, + ->GetTransactionsByStatus(mojom::kMainnetChainId, + mojom::TransactionStatus::Submitted, absl::nullopt) .size(), - 10u); + 1u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus(mojom::kGoerliChainId, + mojom::TransactionStatus::Submitted, + absl::nullopt) + .size(), + 9u); - EXPECT_EQ( - tx_state_manager_ - ->GetTransactionsByStatus(mojom::TransactionStatus::Approved, addr1) - .size(), - 0u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus( + absl::nullopt, mojom::TransactionStatus::Approved, addr1) + .size(), + 0u); EXPECT_EQ( - tx_state_manager_->GetTransactionsByStatus(absl::nullopt, absl::nullopt) + tx_state_manager_ + ->GetTransactionsByStatus(absl::nullopt, absl::nullopt, absl::nullopt) .size(), 20u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus(absl::nullopt, absl::nullopt, addr1) + .size(), + 5u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus(mojom::kMainnetChainId, absl::nullopt, + addr1) + .size(), + 2u); EXPECT_EQ( - tx_state_manager_->GetTransactionsByStatus(absl::nullopt, addr1).size(), - 5u); + tx_state_manager_ + ->GetTransactionsByStatus(mojom::kGoerliChainId, absl::nullopt, addr1) + .size(), + 3u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus(absl::nullopt, absl::nullopt, addr2) + .size(), + 2u); + EXPECT_EQ(tx_state_manager_ + ->GetTransactionsByStatus(mojom::kMainnetChainId, absl::nullopt, + addr2) + .size(), + 0u); EXPECT_EQ( - tx_state_manager_->GetTransactionsByStatus(absl::nullopt, addr2).size(), + tx_state_manager_ + ->GetTransactionsByStatus(mojom::kGoerliChainId, absl::nullopt, addr2) + .size(), 2u); auto confirmed_addr1 = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Confirmed, addr1); + absl::nullopt, mojom::TransactionStatus::Confirmed, addr1); EXPECT_EQ(confirmed_addr1.size(), 5u); for (const auto& meta : confirmed_addr1) { unsigned id; @@ -273,7 +289,7 @@ TEST_F(TxStateManagerUnitTest, GetTransactionsByStatus) { } auto submitted_addr2 = tx_state_manager_->GetTransactionsByStatus( - mojom::TransactionStatus::Submitted, addr2); + absl::nullopt, mojom::TransactionStatus::Submitted, addr2); EXPECT_EQ(submitted_addr2.size(), 2u); for (const auto& meta : submitted_addr2) { unsigned id; @@ -282,23 +298,20 @@ TEST_F(TxStateManagerUnitTest, GetTransactionsByStatus) { } } -TEST_F(TxStateManagerUnitTest, SwitchNetwork) { +TEST_F(TxStateManagerUnitTest, MultiChainId) { prefs_.ClearPref(kBraveWalletTransactions); EthTxMeta meta; meta.set_id("001"); + meta.set_chain_id(mojom::kMainnetChainId); tx_state_manager_->AddOrUpdateTx(meta); - SetNetwork("0x5", mojom::CoinType::ETH); - // Wait for network info - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(tx_state_manager_->GetTx("001"), nullptr); + EXPECT_EQ(tx_state_manager_->GetTx(mojom::kGoerliChainId, "001"), nullptr); + meta.set_chain_id(mojom::kGoerliChainId); tx_state_manager_->AddOrUpdateTx(meta); - SetNetwork(brave_wallet::mojom::kLocalhostChainId, mojom::CoinType::ETH); - // Wait for network info - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(tx_state_manager_->GetTx("001"), nullptr); + EXPECT_EQ(tx_state_manager_->GetTx(mojom::kLocalhostChainId, "001"), nullptr); + meta.set_chain_id(mojom::kLocalhostChainId); tx_state_manager_->AddOrUpdateTx(meta); const auto& dict = prefs_.GetDict(kBraveWalletTransactions); @@ -330,6 +343,7 @@ TEST_F(TxStateManagerUnitTest, RetireOldTxMeta) { for (size_t i = 0; i < 20; ++i) { EthTxMeta meta; meta.set_id(base::NumberToString(i)); + meta.set_chain_id(mojom::kMainnetChainId); if (i % 2 == 0) { meta.set_status(mojom::TransactionStatus::Confirmed); meta.set_confirmed_time(base::Time::Now()); @@ -340,53 +354,68 @@ TEST_F(TxStateManagerUnitTest, RetireOldTxMeta) { tx_state_manager_->AddOrUpdateTx(meta); } - EXPECT_TRUE(tx_state_manager_->GetTx("0")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "0")); EthTxMeta meta21; meta21.set_id("20"); + meta21.set_chain_id(mojom::kMainnetChainId); meta21.set_status(mojom::TransactionStatus::Confirmed); meta21.set_confirmed_time(base::Time::Now()); tx_state_manager_->AddOrUpdateTx(meta21); - EXPECT_FALSE(tx_state_manager_->GetTx("0")); + EXPECT_FALSE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "0")); - EXPECT_TRUE(tx_state_manager_->GetTx("1")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "1")); EthTxMeta meta22; meta22.set_id("21"); + meta22.set_chain_id(mojom::kMainnetChainId); meta22.set_status(mojom::TransactionStatus::Rejected); meta22.set_created_time(base::Time::Now()); tx_state_manager_->AddOrUpdateTx(meta22); - EXPECT_FALSE(tx_state_manager_->GetTx("1")); + EXPECT_FALSE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "1")); // Other status doesn't matter - EXPECT_TRUE(tx_state_manager_->GetTx("2")); - EXPECT_TRUE(tx_state_manager_->GetTx("3")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "2")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "3")); EthTxMeta meta23; meta23.set_id("22"); + meta23.set_chain_id(mojom::kMainnetChainId); meta23.set_status(mojom::TransactionStatus::Submitted); meta23.set_created_time(base::Time::Now()); tx_state_manager_->AddOrUpdateTx(meta23); - EXPECT_TRUE(tx_state_manager_->GetTx("2")); - EXPECT_TRUE(tx_state_manager_->GetTx("3")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "2")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "3")); + + // Other chain id doesn't matter + EthTxMeta meta24; + meta24.set_id("23"); + meta23.set_chain_id(mojom::kGoerliChainId); + meta24.set_status(mojom::TransactionStatus::Confirmed); + meta24.set_created_time(base::Time::Now()); + tx_state_manager_->AddOrUpdateTx(meta24); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "2")); + EXPECT_TRUE(tx_state_manager_->GetTx(mojom::kMainnetChainId, "3")); } TEST_F(TxStateManagerUnitTest, Observer) { - TestTxStateManagerObserver observer; - tx_state_manager_->AddObserver(&observer); + prefs_.ClearPref(kBraveWalletTransactions); + MockTxStateManagerObserver observer(tx_state_manager_.get()); EthTxMeta meta; meta.set_id("001"); // Add + EXPECT_CALL(observer, + OnNewUnapprovedTx(EqualsMojo(meta.ToTransactionInfo()))); + EXPECT_CALL(observer, OnTransactionStatusChanged(_)).Times(0); tx_state_manager_->AddOrUpdateTx(meta); - observer.ExpectMatch("001", mojom::TransactionStatus::Unapproved); - EXPECT_TRUE(observer.NewUnapprovedTxFired()); - EXPECT_FALSE(observer.TxStatusChangedFired()); - observer.Reset(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); + // Modify meta.set_status(mojom::TransactionStatus::Approved); + EXPECT_CALL(observer, OnNewUnapprovedTx(_)).Times(0); + EXPECT_CALL(observer, + OnTransactionStatusChanged(EqualsMojo(meta.ToTransactionInfo()))) + .Times(1); tx_state_manager_->AddOrUpdateTx(meta); - observer.ExpectMatch("001", mojom::TransactionStatus::Approved); - EXPECT_FALSE(observer.NewUnapprovedTxFired()); - EXPECT_TRUE(observer.TxStatusChangedFired()); - observer.Reset(); + EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&observer)); } TEST_F(TxStateManagerUnitTest, diff --git a/components/brave_wallet/common/BUILD.gn b/components/brave_wallet/common/BUILD.gn index f9a98b8d23a9..d0903b0e58f9 100644 --- a/components/brave_wallet/common/BUILD.gn +++ b/components/brave_wallet/common/BUILD.gn @@ -176,5 +176,7 @@ source_set("test_support") { "test_utils.h", ] + deps = [ "//testing/gmock" ] + public_deps = [ ":mojom" ] } # source_set("test_support") diff --git a/components/brave_wallet/common/test_utils.h b/components/brave_wallet/common/test_utils.h index 64c48e59d054..02b29ab6f390 100644 --- a/components/brave_wallet/common/test_utils.h +++ b/components/brave_wallet/common/test_utils.h @@ -9,6 +9,7 @@ #include #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" namespace brave_wallet { @@ -17,6 +18,15 @@ mojom::NetworkInfo GetTestNetworkInfo1( mojom::NetworkInfo GetTestNetworkInfo2( const std::string& chain_id = "chain_id2"); +// Matcher to check equality of two mojo structs. Matcher needs copyable value +// which is not possible for some mojo types, so wrapping it with RefCounted. +template +auto EqualsMojo(const T& value) { + return testing::Truly( + [value = base::MakeRefCounted>(value.Clone())]( + const T& candidate) { return mojo::Equals(candidate, value->data); }); +} + } // namespace brave_wallet #endif // BRAVE_COMPONENTS_BRAVE_WALLET_COMMON_TEST_UTILS_H_ diff --git a/renderer/test/js_ethereum_provider_browsertest.cc b/renderer/test/js_ethereum_provider_browsertest.cc index 05777a4e64b5..989556b44fec 100644 --- a/renderer/test/js_ethereum_provider_browsertest.cc +++ b/renderer/test/js_ethereum_provider_browsertest.cc @@ -268,7 +268,7 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, OnlyWriteOwnProperty) { "0x1"); GetJsonRpcService()->SetNetwork("0x5", brave_wallet::mojom::CoinType::ETH, - false); + absl::nullopt, false); // Needed so ChainChangedEvent observers run base::RunLoop().RunUntilIdle(); EXPECT_EQ(content::EvalJs(primary_main_frame(), get_chain_id).ExtractString(), @@ -285,7 +285,7 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, OnlyWriteOwnProperty) { "0x89"); GetJsonRpcService()->SetNetwork("0x4", brave_wallet::mojom::CoinType::ETH, - false); + absl::nullopt, false); // Needed so ChainChangedEvent observers run base::RunLoop().RunUntilIdle(); EXPECT_EQ(content::EvalJs(primary_main_frame(), get_chain_id).ExtractString(), From 42fbb9f8d3752fb635a81be388b270df1c25e27c Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Mon, 10 Apr 2023 15:55:17 -0700 Subject: [PATCH 07/15] Update browser tests --- ...brave_wallet_ethereum_chain_browsertest.cc | 21 +- .../send_or_sign_transaction_browsertest.cc | 186 +++++++++++++----- .../solana_provider_browsertest.cc | 36 +++- .../wallet_watch_asset_browsertest.cc | 2 +- ..._button_notification_source_browsertest.cc | 22 ++- .../brave_wallet/browser/json_rpc_service.cc | 6 +- .../brave_wallet/browser/json_rpc_service.h | 6 + 7 files changed, 210 insertions(+), 69 deletions(-) diff --git a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc index acbae1df3c0a..a4e6ebaea12a 100644 --- a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc +++ b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc @@ -126,7 +126,8 @@ class TestJsonRpcServiceObserver } void ChainChangedEvent(const std::string& chain_id, - brave_wallet::mojom::CoinType coin) override { + brave_wallet::mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) override { chain_changed_called_ = true; EXPECT_EQ(chain_id, expected_chain_id_); EXPECT_EQ(coin, expected_coin_); @@ -285,8 +286,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddEthereumChainApproved) { ->IsShowingBubble()); CallAndWaitForEthereumChainRequestCompleted( kSomeChainId, true, brave_wallet::mojom::CoinType::ETH, ""); - GetJsonRpcService()->NotifySwitchChainRequestProcessed( - true, url::Origin::Create(url)); + const url::Origin origin = url::Origin::Create(url); + GetJsonRpcService()->NotifySwitchChainRequestProcessed(true, origin); auto result_first = EvalJs(contents, kScriptWaitForEvent, content::EXECUTE_SCRIPT_USE_MANUAL_REPLY); EXPECT_EQ(base::Value(true), result_first.value); @@ -300,7 +301,7 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddEthereumChainApproved) { chain->block_explorer_urls, std::vector({"https://bscscan.com/", "http://localhost/"})); EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - absl::nullopt), + origin), kSomeChainId); } @@ -416,8 +417,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, // Add Ethereum chain but don't switch CallAndWaitForEthereumChainRequestCompleted( "0x11", true, brave_wallet::mojom::CoinType::ETH, ""); - GetJsonRpcService()->NotifySwitchChainRequestProcessed( - false, url::Origin::Create(urlB)); + const url::Origin origin = url::Origin::Create(urlB); + GetJsonRpcService()->NotifySwitchChainRequestProcessed(false, origin); auto rejected_same_id = EvalJs(web_contentsB, kScriptWaitForEvent, content::EXECUTE_SCRIPT_USE_MANUAL_REPLY); EXPECT_EQ(base::Value(false), rejected_same_id.value); @@ -427,7 +428,7 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); // But current chain should not change EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - absl::nullopt), + origin), "0x1"); } @@ -467,8 +468,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddDifferentChainsSwitch) { // Add Ethereum chain and switch CallAndWaitForEthereumChainRequestCompleted( "0x11", true, brave_wallet::mojom::CoinType::ETH, ""); - GetJsonRpcService()->NotifySwitchChainRequestProcessed( - true, url::Origin::Create(urlB)); + const url::Origin origin = url::Origin::Create(urlB); + GetJsonRpcService()->NotifySwitchChainRequestProcessed(true, origin); auto rejected_same_id = EvalJs(web_contentsB, kScriptWaitForEvent, content::EXECUTE_SCRIPT_USE_MANUAL_REPLY); EXPECT_EQ(base::Value(true), rejected_same_id.value); @@ -476,7 +477,7 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddDifferentChainsSwitch) { ASSERT_FALSE(GetAllEthCustomChains().empty()); EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - absl::nullopt), + origin), "0x11"); } diff --git a/browser/brave_wallet/send_or_sign_transaction_browsertest.cc b/browser/brave_wallet/send_or_sign_transaction_browsertest.cc index c72d99359184..4ab3fd30aabd 100644 --- a/browser/brave_wallet/send_or_sign_transaction_browsertest.cc +++ b/browser/brave_wallet/send_or_sign_transaction_browsertest.cc @@ -20,6 +20,7 @@ #include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/brave_wallet/browser/permission_utils.h" +#include "brave/components/brave_wallet/browser/pref_names.h" #include "brave/components/brave_wallet/browser/tx_service.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "brave/components/brave_wallet/common/features.h" @@ -35,12 +36,14 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/grit/brave_components_strings.h" #include "components/network_session_configurator/common/network_switches.h" +#include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_mock_cert_verifier.h" #include "content/public/test/test_utils.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -120,6 +123,32 @@ class TestTxServiceObserver : public brave_wallet::mojom::TxServiceObserver { bool expect_eip1559_tx_ = false; }; +class TestJsonRpcServiceObserver : public mojom::JsonRpcServiceObserver { + public: + explicit TestJsonRpcServiceObserver(base::OnceClosure callback) + : callback_(std::move(callback)) {} + + void OnAddEthereumChainRequestCompleted(const std::string& chain_id, + const std::string& error) override { + std::move(callback_).Run(); + } + + void ChainChangedEvent(const std::string& chain_id, + brave_wallet::mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) override { + } + + void OnIsEip1559Changed(const std::string& chain_id, + bool is_eip1559) override {} + + ::mojo::PendingRemote GetReceiver() { + return observer_receiver_.BindNewPipeAndPassRemote(); + } + + base::OnceClosure callback_; + mojo::Receiver observer_receiver_{this}; +}; + class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { public: SendOrSignTransactionBrowserTest() @@ -165,6 +194,7 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { tx_service_ = TxServiceFactory::GetServiceForContext(browser()->profile()); json_rpc_service_ = JsonRpcServiceFactory::GetServiceForContext(browser()->profile()); + json_rpc_service_->SetSkipEthChainIdValidationForTesting(true); tx_service_->AddObserver(observer()->GetReceiver()); @@ -176,7 +206,7 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { https_server_for_rpc()->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); https_server_for_rpc()->RegisterRequestHandler(callback); ASSERT_TRUE(https_server_for_rpc()->Start()); - SetNetworkForTesting("0x539"); + SetNetworkForTesting(mojom::kLocalhostChainId, absl::nullopt); } content::WebContents* web_contents() { @@ -249,8 +279,37 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { run_loop.Run(); } - void AddEthereumChain(const std::string& chain_id) { + void AddEthereumChain(const url::Origin& origin, + const std::string& chain_id) { + mojom::NetworkInfo chain = GetTestNetworkInfo1(chain_id); + chain.rpc_endpoints = + std::vector({https_server_for_rpc()->base_url()}); + base::RunLoop run_loop; + mojom::ProviderError error_out; + json_rpc_service_->AddEthereumChainForOrigin( + chain.Clone(), origin, + base::BindLambdaForTesting( + [&run_loop, &error_out](const std::string& chain_id, + mojom::ProviderError error, + const std::string& error_message) { + error_out = error; + run_loop.Quit(); + })); + run_loop.Run(); + if (error_out != mojom::ProviderError::kSuccess) { + return; + } + + // Wait for OnAddEthereumChainRequestCompleted + base::RunLoop run_loop_chain_request_completed; + auto observer = std::make_unique( + run_loop_chain_request_completed.QuitClosure()); + json_rpc_service_->AddObserver(observer->GetReceiver()); + mojo::PendingRemote receiver; + mojo::MakeSelfOwnedReceiver(std::move(observer), + receiver.InitWithNewPipeAndPassReceiver()); json_rpc_service_->AddEthereumChainRequestCompleted(chain_id, true); + run_loop_chain_request_completed.Run(); } void CallEthereumEnable(bool is_repeat_call = false) { @@ -315,10 +374,11 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { return ""; } - void ApproveTransaction(const std::string& tx_meta_id) { + void ApproveTransaction(const std::string& chain_id, + const std::string& tx_meta_id) { base::RunLoop run_loop; tx_service_->ApproveTransaction( - mojom::CoinType::ETH, tx_meta_id, + mojom::CoinType::ETH, chain_id, tx_meta_id, base::BindLambdaForTesting([&](bool success, mojom::ProviderErrorUnionPtr error_union, const std::string& error_message) { @@ -332,10 +392,11 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { run_loop.Run(); } - void RejectTransaction(const std::string& tx_meta_id) { + void RejectTransaction(const std::string& chain_id, + const std::string& tx_meta_id) { base::RunLoop run_loop; tx_service_->RejectTransaction( - mojom::CoinType::ETH, tx_meta_id, + mojom::CoinType::ETH, chain_id, tx_meta_id, base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); observer()->WaitForRjectedStatus(); @@ -351,10 +412,12 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { EXPECT_EQ("\"result ready\"", message); } - void TestUserApproved(absl::optional expected_signed_tx, - const std::string& test_method, - const std::string& data = "", - bool skip_restore = false) { + void TestUserApproved( + absl::optional expected_signed_tx, + const std::string& test_method, + const std::string& data = "", + bool skip_restore = false, + const std::string& chain_id = mojom::kLocalhostChainId) { if (!skip_restore) { RestoreWallet(); } @@ -381,7 +444,7 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { brave_wallet::BraveWalletTabHelper::FromWebContents(web_contents()) ->IsShowingBubble()); - auto infos = GetAllTransactionInfo(); + auto infos = GetAllTransactionInfo(chain_id); ASSERT_EQ(1UL, infos.size()); EXPECT_TRUE( base::EqualsCaseInsensitiveASCII(from(), infos[0]->from_address)); @@ -393,9 +456,9 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { ->tx_data_union->get_eth_tx_data_1559() ->base_data->nonce.empty()); - ApproveTransaction(infos[0]->id); + ApproveTransaction(chain_id, infos[0]->id); - infos = GetAllTransactionInfo(); + infos = GetAllTransactionInfo(chain_id); EXPECT_EQ(1UL, infos.size()); EXPECT_TRUE( base::EqualsCaseInsensitiveASCII(from(), infos[0]->from_address)); @@ -423,7 +486,10 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { } } - void TestUserRejected(bool sign_only, const std::string& test_method) { + void TestUserRejected( + bool sign_only, + const std::string& test_method, + const std::string& chain_id = mojom::kLocalhostChainId) { RestoreWallet(); GURL url = https_server_for_files()->GetURL( "a.com", "/send_or_sign_transaction.html"); @@ -445,7 +511,7 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { brave_wallet::BraveWalletTabHelper::FromWebContents(web_contents()) ->IsShowingBubble()); - auto infos = GetAllTransactionInfo(); + auto infos = GetAllTransactionInfo(chain_id); EXPECT_EQ(1UL, infos.size()); EXPECT_TRUE( base::EqualsCaseInsensitiveASCII(from(), infos[0]->from_address)); @@ -457,9 +523,9 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { ->tx_data_union->get_eth_tx_data_1559() ->base_data->nonce.empty()); - RejectTransaction(infos[0]->id); + RejectTransaction(mojom::kLocalhostChainId, infos[0]->id); - infos = GetAllTransactionInfo(); + infos = GetAllTransactionInfo(chain_id); EXPECT_EQ(1UL, infos.size()); EXPECT_TRUE( base::EqualsCaseInsensitiveASCII(from(), infos[0]->from_address)); @@ -478,11 +544,12 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { IDS_WALLET_ETH_SEND_TRANSACTION_USER_REJECTED)); } - std::vector GetAllTransactionInfo() { + std::vector GetAllTransactionInfo( + const std::string& chain_id) { std::vector transaction_infos; base::RunLoop run_loop; tx_service_->GetAllTransactionInfo( - mojom::CoinType::ETH, from(), + mojom::CoinType::ETH, chain_id, from(), base::BindLambdaForTesting( [&](std::vector v) { transaction_infos = std::move(v); @@ -518,15 +585,44 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { "Internal JSON-RPC error"); } - void SetNetworkForTesting(const std::string& chain_id) { - json_rpc_service_->SetCustomNetworkForTesting( - chain_id, mojom::CoinType::ETH, https_server_for_rpc()->base_url()); + void SetNetworkForTesting(const std::string& chain_id, + const absl::optional<::url::Origin>& origin, + bool skip_rpc_url_override = false) { + mojom::NetworkInfoPtr chain; + ASSERT_TRUE(json_rpc_service_->SetNetwork(chain_id, mojom::CoinType::ETH, + origin, false)); + base::RunLoop run_loop; + json_rpc_service_->GetNetwork( + mojom::CoinType::ETH, origin, + base::BindLambdaForTesting([&](mojom::NetworkInfoPtr info) { + chain = info.Clone(); + run_loop.Quit(); + })); + run_loop.Run(); + if (chain && !skip_rpc_url_override) { + base::RunLoop run_loop1; + browser()->profile()->GetPrefs()->ClearPref(kBraveWalletCustomNetworks); + chain->rpc_endpoints = + std::vector({https_server_for_rpc()->base_url()}); + json_rpc_service_->AddChain( + std::move(chain), + base::BindLambdaForTesting([&](const std::string& chain_id_out, + mojom::ProviderError error, + const std::string& error_message) { + ASSERT_EQ(chain_id_out, chain_id); + ASSERT_EQ(error, mojom::ProviderError::kSuccess); + ASSERT_TRUE(error_message.empty()); + run_loop1.Quit(); + })); + run_loop1.Run(); + } // Needed so ChainChangedEvent observers run base::RunLoop().RunUntilIdle(); - chain_id_ = chain_id; } - std::string chain_id() { return chain_id_; } + std::string chain_id(const absl::optional<::url::Origin>& origin) { + return json_rpc_service_->GetChainId(mojom::CoinType::ETH, origin); + } protected: raw_ptr brave_wallet_service_ = nullptr; @@ -540,7 +636,6 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { raw_ptr keyring_service_ = nullptr; raw_ptr tx_service_ = nullptr; raw_ptr json_rpc_service_ = nullptr; - std::string chain_id_; }; IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, @@ -819,15 +914,15 @@ IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, NetworkVersion) { RestoreWallet(); GURL url = https_server_for_files()->GetURL("a.com", "/send_or_sign_transaction.html"); + const auto& origin = url::Origin::Create(url); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); EXPECT_TRUE(WaitForLoadStop(web_contents())); - EXPECT_EQ(EvalJs(web_contents(), "getChainId()", content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) .ExtractString(), - chain_id()); + chain_id(origin)); uint256_t chain_id_uint256; - EXPECT_TRUE(HexValueToUint256(chain_id(), &chain_id_uint256)); + EXPECT_TRUE(HexValueToUint256(chain_id(origin), &chain_id_uint256)); EXPECT_EQ(EvalJs(web_contents(), "getNetworkVersion()", content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) .ExtractString(), @@ -835,8 +930,8 @@ IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, NetworkVersion) { // Newly added network change std::string chain_id = "0x38"; - AddEthereumChain(chain_id); - SetNetworkForTesting(chain_id); + AddEthereumChain(origin, chain_id); + SetNetworkForTesting(chain_id, origin, true); EXPECT_EQ(EvalJs(web_contents(), "getChainId()", content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) .ExtractString(), @@ -850,8 +945,8 @@ IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, NetworkVersion) { // Make sure chainId > uint64_t has networkVersion undefined. This is // just a current limitation that we will likely get rid of in the future. chain_id = "0x878678326eac900000000"; - AddEthereumChain(chain_id); - SetNetworkForTesting(chain_id); + AddEthereumChain(origin, chain_id); + SetNetworkForTesting(chain_id, origin, true); EXPECT_EQ(EvalJs(web_contents(), "getChainId()", content::EXECUTE_SCRIPT_USE_MANUAL_REPLY) .ExtractString(), @@ -910,63 +1005,66 @@ IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, CallViaProxy) { IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSendTransactionEIP1559Tx) { - SetNetworkForTesting("0x1"); // mainnet + SetNetworkForTesting(mojom::kMainnetChainId, absl::nullopt); observer()->SetExpectEip1559Tx(true); - TestUserApproved(absl::nullopt, "request"); + TestUserApproved(absl::nullopt, "request", "", false, mojom::kMainnetChainId); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSendTransactionLegacyTx) { - SetNetworkForTesting("0x539"); // localhost + SetNetworkForTesting(mojom::kLocalhostChainId, absl::nullopt); observer()->SetExpectEip1559Tx(false); TestUserApproved(absl::nullopt, "request"); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSendTransactionCustomNetworkLegacyTx) { - SetNetworkForTesting("0x5566"); - observer()->SetExpectEip1559Tx(false); RestoreWallet(); mojom::NetworkInfo chain = GetTestNetworkInfo1("0x5566"); AddCustomNetwork(browser()->profile()->GetPrefs(), chain); - TestUserApproved(absl::nullopt, "request", "", true /* skip_restore */); + SetNetworkForTesting("0x5566", absl::nullopt); + observer()->SetExpectEip1559Tx(false); + + TestUserApproved(absl::nullopt, "request", "", true /* skip_restore */, + "0x5566"); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSignTransactionEIP1559Tx) { - SetNetworkForTesting("0x1"); // mainnet + SetNetworkForTesting(mojom::kMainnetChainId, absl::nullopt); observer()->SetExpectEip1559Tx(true); TestUserApproved( "0x02f86d0182960484f38e9e008525f38e9e0082960494084dcb94038af1715963f14907" "9ce011c4b229621180c001a0e152033adac7e7316007446c0cd45b97a21911b4e414b087" "2d0f207dd9ac4226a07ed1a15909a925716d97ab6e2c7077c7b4b0616c8bc522bcd4914a" "79ef5e6d1d", - "request"); + "request", "", false, mojom::kMainnetChainId); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSignTransactionLegacyTx) { - SetNetworkForTesting("0x539"); // localhost + SetNetworkForTesting(mojom::kLocalhostChainId, absl::nullopt); // localhost observer()->SetExpectEip1559Tx(false); TestUserApproved(kSignedTransaction, "request"); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, EthSignTransactionCustomNetworkLegacyTx) { - SetNetworkForTesting("0x5566"); - observer()->SetExpectEip1559Tx(false); RestoreWallet(); mojom::NetworkInfo chain = GetTestNetworkInfo1("0x5566"); AddCustomNetwork(browser()->profile()->GetPrefs(), chain); + SetNetworkForTesting("0x5566", absl::nullopt); + observer()->SetExpectEip1559Tx(false); + TestUserApproved( "0xf8688296048525f38e9e0082960494084dcb94038af1715963f149079ce011c4b22962" "118082aaf0a01789b12329c3b46db7bc23af14df45ebc54f6ce8da40f4db4cec866c73bf" "2ed5a0642ca22062c10f05bfce787107c44001ed8bf1a1d8416cf2e9b133aadbc88076", - "request", "", true /* skip_restore */); + "request", "", true /* skip_restore */, "0x5566"); } IN_PROC_BROWSER_TEST_F(SendOrSignTransactionBrowserTest, diff --git a/browser/brave_wallet/solana_provider_browsertest.cc b/browser/brave_wallet/solana_provider_browsertest.cc index 04645bf04ee6..a21ef280cefb 100644 --- a/browser/brave_wallet/solana_provider_browsertest.cc +++ b/browser/brave_wallet/solana_provider_browsertest.cc @@ -362,9 +362,33 @@ class SolanaProviderTest : public InProcessBrowserTest { https_server_for_rpc()->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); https_server_for_rpc()->RegisterRequestHandler(callback); ASSERT_TRUE(https_server_for_rpc()->Start()); - json_rpc_service_->SetCustomNetworkForTesting( - mojom::kLocalhostChainId, mojom::CoinType::SOL, - https_server_for_rpc()->base_url()); + + // Update rpc url for kLocalhostChainId + mojom::NetworkInfoPtr chain; + json_rpc_service_->SetNetwork(mojom::kLocalhostChainId, + mojom::CoinType::SOL, absl::nullopt, true); + base::RunLoop run_loop; + json_rpc_service_->GetNetwork( + mojom::CoinType::SOL, absl::nullopt, + base::BindLambdaForTesting([&](mojom::NetworkInfoPtr info) { + chain = info.Clone(); + run_loop.Quit(); + })); + run_loop.Run(); + base::RunLoop run_loop1; + chain->rpc_endpoints = + std::vector({https_server_for_rpc()->base_url()}); + json_rpc_service_->AddChain( + std::move(chain), + base::BindLambdaForTesting([&](const std::string& chain_id, + mojom::ProviderError error, + const std::string& error_message) { + ASSERT_EQ(chain_id, mojom::kLocalhostChainId); + ASSERT_EQ(error, mojom::ProviderError::kSuccess); + ASSERT_TRUE(error_message.empty()); + run_loop1.Quit(); + })); + run_loop1.Run(); } content::WebContents* web_contents() { @@ -449,7 +473,7 @@ class SolanaProviderTest : public InProcessBrowserTest { std::vector transaction_infos; base::RunLoop run_loop; tx_service_->GetAllTransactionInfo( - mojom::CoinType::SOL, kFirstAccount, + mojom::CoinType::SOL, mojom::kLocalhostChainId, kFirstAccount, base::BindLambdaForTesting( [&](std::vector v) { transaction_infos = std::move(v); @@ -462,7 +486,7 @@ class SolanaProviderTest : public InProcessBrowserTest { void ApproveTransaction(const std::string& tx_meta_id) { base::RunLoop run_loop; tx_service_->ApproveTransaction( - mojom::CoinType::SOL, tx_meta_id, + mojom::CoinType::SOL, mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](bool success, mojom::ProviderErrorUnionPtr error_union, const std::string& error_message) { @@ -479,7 +503,7 @@ class SolanaProviderTest : public InProcessBrowserTest { void RejectTransaction(const std::string& tx_meta_id) { base::RunLoop run_loop; tx_service_->RejectTransaction( - mojom::CoinType::SOL, tx_meta_id, + mojom::CoinType::SOL, mojom::kLocalhostChainId, tx_meta_id, base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); observer()->WaitForRjectedStatus(); diff --git a/browser/brave_wallet/wallet_watch_asset_browsertest.cc b/browser/brave_wallet/wallet_watch_asset_browsertest.cc index c2f74d94623d..2065e91e0c86 100644 --- a/browser/brave_wallet/wallet_watch_asset_browsertest.cc +++ b/browser/brave_wallet/wallet_watch_asset_browsertest.cc @@ -98,7 +98,7 @@ class WalletWatchAssetBrowserTest : public InProcessBrowserTest { std::vector tokens_out; brave_wallet_service_->GetUserAssets( GetCurrentChainId(browser()->profile()->GetPrefs(), - mojom::CoinType::ETH), + mojom::CoinType::ETH, absl::nullopt), mojom::CoinType::ETH, base::BindLambdaForTesting( [&](std::vector tokens) { diff --git a/browser/ui/views/toolbar/wallet_button_notification_source_browsertest.cc b/browser/ui/views/toolbar/wallet_button_notification_source_browsertest.cc index 0f8863f89ad0..e274cd0b2d9f 100644 --- a/browser/ui/views/toolbar/wallet_button_notification_source_browsertest.cc +++ b/browser/ui/views/toolbar/wallet_button_notification_source_browsertest.cc @@ -10,6 +10,7 @@ #include "base/test/bind.h" #include "brave/browser/brave_wallet/keyring_service_factory.h" #include "brave/browser/brave_wallet/tx_service_factory.h" +#include "brave/components/brave_wallet/browser/brave_wallet_utils.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -288,8 +289,11 @@ IN_PROC_BROWSER_TEST_F(WalletButtonNotificationSourceTest, { base::RunLoop run_loop; tx_service()->RejectTransaction( - brave_wallet::mojom::CoinType::FIL, first_tx_meta_id, - base::BindLambdaForTesting([&](bool result) { + brave_wallet::mojom::CoinType::FIL, + brave_wallet::GetCurrentChainId(browser()->profile()->GetPrefs(), + brave_wallet::mojom::CoinType::FIL, + absl::nullopt), + first_tx_meta_id, base::BindLambdaForTesting([&](bool result) { EXPECT_TRUE(result); run_loop.Quit(); })); @@ -306,8 +310,11 @@ IN_PROC_BROWSER_TEST_F(WalletButtonNotificationSourceTest, { base::RunLoop run_loop; tx_service()->RejectTransaction( - brave_wallet::mojom::CoinType::ETH, second_tx_meta_id, - base::BindLambdaForTesting([&](bool result) { + brave_wallet::mojom::CoinType::ETH, + brave_wallet::GetCurrentChainId(browser()->profile()->GetPrefs(), + brave_wallet::mojom::CoinType::ETH, + absl::nullopt), + second_tx_meta_id, base::BindLambdaForTesting([&](bool result) { EXPECT_TRUE(result); run_loop.Quit(); })); @@ -324,8 +331,11 @@ IN_PROC_BROWSER_TEST_F(WalletButtonNotificationSourceTest, { base::RunLoop run_loop; tx_service()->RejectTransaction( - brave_wallet::mojom::CoinType::SOL, third_tx_meta_id, - base::BindLambdaForTesting([&](bool result) { + brave_wallet::mojom::CoinType::SOL, + brave_wallet::GetCurrentChainId(browser()->profile()->GetPrefs(), + brave_wallet::mojom::CoinType::SOL, + absl::nullopt), + third_tx_meta_id, base::BindLambdaForTesting([&](bool result) { EXPECT_TRUE(result); run_loop.Quit(); })); diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index e155520cc255..712241b59c13 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -455,7 +455,8 @@ void JsonRpcService::OnEthChainIdValidated( AddChainCallback callback, APIRequestResult api_request_result) { if (ParseSingleStringResult(api_request_result.value_body()) != - chain->chain_id) { + chain->chain_id && + !skip_eth_chain_id_validation_for_testing_) { std::move(callback).Run( chain->chain_id, mojom::ProviderError::kUserRejectedRequest, l10n_util::GetStringFUTF8(IDS_BRAVE_WALLET_ETH_CHAIN_ID_FAILED, @@ -532,7 +533,8 @@ void JsonRpcService::OnEthChainIdValidatedForOrigin( } const auto& chain = *add_chain_pending_requests_.at(chain_id)->network_info; - if (ParseSingleStringResult(api_request_result.value_body()) != chain_id) { + if (ParseSingleStringResult(api_request_result.value_body()) != chain_id && + !skip_eth_chain_id_validation_for_testing_) { FirePendingRequestCompleted( chain_id, l10n_util::GetStringFUTF8(IDS_BRAVE_WALLET_ETH_CHAIN_ID_FAILED, diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index d770dc7f0c29..1999bec11f9a 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -416,6 +416,10 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { void SetAPIRequestHelperForTesting( scoped_refptr url_loader_factory); + void SetSkipEthChainIdValidationForTesting(bool skipped) { + skip_eth_chain_id_validation_for_testing_ = skipped; + } + // Solana JSON RPCs void GetSolanaBalance(const std::string& pubkey, const std::string& chain_id, @@ -665,6 +669,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { SnsResolverTaskContainer sns_get_sol_addr_tasks_; SnsResolverTaskContainer sns_resolve_host_tasks_; + bool skip_eth_chain_id_validation_for_testing_ = false; + mojo::ReceiverSet receivers_; PrefService* prefs_ = nullptr; PrefService* local_state_prefs_ = nullptr; From cfd775fb7986b2619dcd9a9831849303f330e108 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Mon, 10 Apr 2023 16:33:12 -0700 Subject: [PATCH 08/15] Change active network to default network Since now we will consider origin when determining active network, brave://settings/wallet/networks will be used to manage default network when per origin network is not set yet. --- app/brave_settings_strings.grdp | 4 +-- .../brave_wallet_browser_proxy.ts | 8 ++--- .../wallet_networks_list.html | 10 +++--- .../brave_wallet_page/wallet_networks_list.ts | 32 +++++++++---------- ...ave_settings_localized_strings_provider.cc | 6 ++-- .../ui/webui/settings/brave_wallet_handler.cc | 9 +++--- .../ui/webui/settings/brave_wallet_handler.h | 2 +- .../settings/brave_wallet_handler_unittest.cc | 10 +++--- components/resources/wallet_strings.grdp | 2 +- 9 files changed, 41 insertions(+), 42 deletions(-) diff --git a/app/brave_settings_strings.grdp b/app/brave_settings_strings.grdp index 4efdd8eb2979..22eb5c77b6b5 100644 --- a/app/brave_settings_strings.grdp +++ b/app/brave_settings_strings.grdp @@ -1137,8 +1137,8 @@ Do you really want to delete $1NetworkName? - - Active network is always visible in wallet network list + + Default network is always visible in wallet network list Show/hide network in wallet network list diff --git a/browser/resources/settings/brave_wallet_page/brave_wallet_browser_proxy.ts b/browser/resources/settings/brave_wallet_page/brave_wallet_browser_proxy.ts index f87bdcf127a7..eeff4613bce3 100644 --- a/browser/resources/settings/brave_wallet_page/brave_wallet_browser_proxy.ts +++ b/browser/resources/settings/brave_wallet_page/brave_wallet_browser_proxy.ts @@ -30,7 +30,7 @@ export type NetworkInfo = { } export type NetworksList = { - activeNetwork: string + defaultNetwork: string networks: NetworkInfo[] knownNetworks: string[] customNetworks: string[] @@ -56,7 +56,7 @@ export interface BraveWalletBrowserProxy { addChain(value: NetworkInfo): Promise<[boolean, string]> addHiddenNetwork(chainId: string, coin: number): Promise removeHiddenNetwork(chainId: string, coin: number): Promise - setActiveNetwork(chainId: string, coin: number): Promise + setDefaultNetwork(chainId: string, coin: number): Promise resetTransactionInfo (): void getPinnedNftCount(): Promise clearPinnedNft(): Promise @@ -83,8 +83,8 @@ export class BraveWalletBrowserProxyImpl implements BraveWalletBrowserProxy { return sendWithPromise('getPrepopulatedNetworksList') } - setActiveNetwork (chainId: string, coin: number) { - return sendWithPromise('setActiveNetwork', chainId, coin) + setDefaultNetwork (chainId: string, coin: number) { + return sendWithPromise('setDefaultNetwork', chainId, coin) } removeChain (chainId: string, coin: number) { diff --git a/browser/resources/settings/brave_wallet_page/wallet_networks_list.html b/browser/resources/settings/brave_wallet_page/wallet_networks_list.html index 699ea04a4f9c..9da77418fe1f 100644 --- a/browser/resources/settings/brave_wallet_page/wallet_networks_list.html +++ b/browser/resources/settings/brave_wallet_page/wallet_networks_list.html @@ -7,7 +7,7 @@ padding-inline-end: var(--cr-section-padding); padding-inline-start: var(--cr-section-indent-padding); } - .active-network { + .default-network { font-weight: bold; } @@ -68,10 +68,10 @@ on-click="onResetActionTapped_"> $i18n{walletNetworkReset} - diff --git a/browser/resources/settings/brave_wallet_page/wallet_networks_list.ts b/browser/resources/settings/brave_wallet_page/wallet_networks_list.ts index efdbe163163f..daac2d701f76 100644 --- a/browser/resources/settings/brave_wallet_page/wallet_networks_list.ts +++ b/browser/resources/settings/brave_wallet_page/wallet_networks_list.ts @@ -66,11 +66,11 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { type: Object, value: {} }, - activeNetwork: { + defaultNetwork: { type: String, value: '' }, - isActiveNetwork: { + isDefaultNetwork: { type: Boolean, value: true }, @@ -120,14 +120,14 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { } getNetworkItemClass(item) { - if (this.isDefaultNetwork(item.chainId)) { - return "flex cr-padded-text active-network" + if (this.checkIsDefaultNetwork(item.chainId)) { + return "flex cr-padded-text default-network" } return "flex cr-padded-text" } getHideButtonClass(hiddenNetworks, item) { - if (!this.isDefaultNetwork(item.chainId) && hiddenNetworks.indexOf(item.chainId) > -1) { + if (!this.checkIsDefaultNetwork(item.chainId) && hiddenNetworks.indexOf(item.chainId) > -1) { return "hide-network-button icon-visibility-off" } return "hide-network-button icon-visibility" @@ -137,23 +137,23 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { return 'chain-' + item.chainId } - isDefaultNetwork(chainId) { - return chainId === this.activeNetwork + checkIsDefaultNetwork(chainId) { + return chainId === this.defaultNetwork } canRemoveNetwork_(item) { - if (this.isActiveNetwork) return false + if (this.checkIsDefaultNetwork) return false return this.knownNetworks.indexOf(item.chainId) == -1 } canHideNetwork_(item) { - return !this.isDefaultNetwork(item.chainId); + return !this.checkIsDefaultNetwork(item.chainId); } eyeButtonTitle_(item) { - if (this.isDefaultNetwork(item.chainId)) { - return this.i18n('walletActiveNetworkIsAlwaysVisible') + if (this.checkIsDefaultNetwork(item.chainId)) { + return this.i18n('walletDefaultNetworkIsAlwaysVisible') } return this.i18n('walletShowHideNetwork') @@ -177,10 +177,10 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { return item.chainId + ' ' + url } - onSetAsActiveActionTapped_(event) { + onSetAsDefaultActionTapped_(event) { const chainId = this.selectedNetwork.chainId this.selectedNetwork = {} - this.browserProxy_.setActiveNetwork(chainId, this.coin). + this.browserProxy_.setDefaultNetwork(chainId, this.coin). then(success => { this.updateNetworks() }) this.$$('cr-action-menu').close(); } @@ -190,7 +190,7 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { const chainName = this.selectedNetwork.chainName this.selectedNetwork = {} this.$$('cr-action-menu').close(); - if (this.isDefaultNetwork(chainId)) { + if (this.checkIsDefaultNetwork(chainId)) { this.updateNetworks() return } @@ -232,7 +232,7 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { this.browserProxy_.getNetworksList(this.coin).then(payload => { if (!payload) return - this.activeNetwork = payload.activeNetwork + this.defaultNetwork = payload.defaultNetwork this.networks = payload.networks this.knownNetworks = payload.knownNetworks this.customNetworks = payload.customNetworks @@ -262,7 +262,7 @@ class SettingsWalletNetworksList extends SettingsWalletNetworksListBase { onNetworkMenuTapped_(event) { this.selectedNetwork = event.model.item - this.isActiveNetwork = this.isDefaultNetwork(this.selectedNetwork.chainId) + this.isDefaultNetwork = this.checkIsDefaultNetwork(this.selectedNetwork.chainId) this.canRemoveNetwork = this.canRemoveNetwork_(this.selectedNetwork) this.canResetNetwork = this.canResetNetwork_(this.selectedNetwork) const actionMenu = diff --git a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc index b5433aa3d0f1..c091a17536ca 100644 --- a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc +++ b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc @@ -553,8 +553,8 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, {"walletNetworksError", IDS_SETTINGS_WALLET_NETWORKS_ERROR}, {"walletDeleteNetworkConfirmation", IDS_SETTINGS_WALLET_DELETE_NETWORK_CONFIRMATION}, - {"walletActiveNetworkIsAlwaysVisible", - IDS_SETTINGS_WALLET_ACTIVE_NETWORK_IS_ALWAYS_VISIBLE}, + {"walletDefaultNetworkIsAlwaysVisible", + IDS_SETTINGS_WALLET_DEFAULT_NETWORK_IS_ALWAYS_VISIBLE}, {"walletShowHideNetwork", IDS_SETTINGS_WALLET_SHOW_HIDE_NETWORK}, {"walletResetNetworkConfirmation", IDS_SETTINGS_WALLET_RESET_NETWORK_CONFIRMATION}, @@ -600,7 +600,7 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, {"walletNetworkEdit", IDS_BRAVE_WALLET_NETWORK_EDIT}, {"walletNetworkRemove", IDS_BRAVE_WALLET_NETWORK_REMOVE}, {"walletNetworkReset", IDS_BRAVE_WALLET_NETWORK_RESET}, - {"walletNetworkSetAsActive", IDS_BRAVE_WALLET_NETWORK_SET_AS_ACTIVE}, + {"walletNetworkSetAsDefault", IDS_BRAVE_WALLET_NETWORK_SET_AS_DEFAULT}, {"adblockContentFilteringLabel", IDS_BRAVE_ADBLOCK_CONTENT_FILTERING_LABEL}, {"adblockAddCustomFiltersListsLabel", IDS_BRAVE_ADBLOCK_ADD_CUSTOM_FILTERS_LISTS_LABEL}, diff --git a/browser/ui/webui/settings/brave_wallet_handler.cc b/browser/ui/webui/settings/brave_wallet_handler.cc index 875b7a5f018b..745af8beef8d 100644 --- a/browser/ui/webui/settings/brave_wallet_handler.cc +++ b/browser/ui/webui/settings/brave_wallet_handler.cc @@ -86,8 +86,8 @@ void BraveWalletHandler::RegisterMessages() { "addChain", base::BindRepeating(&BraveWalletHandler::AddChain, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "setActiveNetwork", - base::BindRepeating(&BraveWalletHandler::SetActiveNetwork, + "setDefaultNetwork", + base::BindRepeating(&BraveWalletHandler::SetDefaultNetwork, base::Unretained(this))); web_ui()->RegisterMessageCallback( "addHiddenNetwork", @@ -181,8 +181,7 @@ void BraveWalletHandler::GetNetworksList(const base::Value::List& args) { return; } - // TODO(darkdh): change this to default network. - result.Set("activeNetwork", + result.Set("defaultNetwork", brave_wallet::GetCurrentChainId(prefs, *coin, absl::nullopt)); auto& networks = result.Set("networks", base::Value::List())->GetList(); @@ -269,7 +268,7 @@ void BraveWalletHandler::AddChain(const base::Value::List& args) { weak_ptr_factory_.GetWeakPtr(), args[0].Clone())); } -void BraveWalletHandler::SetActiveNetwork(const base::Value::List& args) { +void BraveWalletHandler::SetDefaultNetwork(const base::Value::List& args) { CHECK_EQ(args.size(), 3U); auto* chain_id = args[1].GetIfString(); diff --git a/browser/ui/webui/settings/brave_wallet_handler.h b/browser/ui/webui/settings/brave_wallet_handler.h index 34be12c0bf3b..1b42897f1730 100644 --- a/browser/ui/webui/settings/brave_wallet_handler.h +++ b/browser/ui/webui/settings/brave_wallet_handler.h @@ -45,7 +45,7 @@ class BraveWalletHandler : public settings::SettingsPageUIHandler { void GetNetworksList(const base::Value::List& args); void GetPrepopulatedNetworksList(const base::Value::List& args); void AddChain(const base::Value::List& args); - void SetActiveNetwork(const base::Value::List& args); + void SetDefaultNetwork(const base::Value::List& args); void AddHiddenNetwork(const base::Value::List& args); void RemoveHiddenNetwork(const base::Value::List& args); void IsNftPinningEnabled(const base::Value::List& args); diff --git a/browser/ui/webui/settings/brave_wallet_handler_unittest.cc b/browser/ui/webui/settings/brave_wallet_handler_unittest.cc index 3f40b9196df6..990380fc7723 100644 --- a/browser/ui/webui/settings/brave_wallet_handler_unittest.cc +++ b/browser/ui/webui/settings/brave_wallet_handler_unittest.cc @@ -130,8 +130,8 @@ class TestBraveWalletHandler : public BraveWalletHandler { void AddChain(const base::Value::List& args) { BraveWalletHandler::AddChain(args); } - void SetActiveNetwork(const base::Value::List& args) { - BraveWalletHandler::SetActiveNetwork(args); + void SetDefaultNetwork(const base::Value::List& args) { + BraveWalletHandler::SetDefaultNetwork(args); } content::TestWebUI* web_ui() { return &test_web_ui_; } PrefService* prefs() { return profile_->GetPrefs(); } @@ -332,7 +332,7 @@ TEST(TestBraveWalletHandler, GetNetworkListFilSol) { } } -TEST(TestBraveWalletHandler, SetActiveNetwork) { +TEST(TestBraveWalletHandler, SetDefaultNetwork) { TestBraveWalletHandler handler; std::vector values; @@ -352,7 +352,7 @@ TEST(TestBraveWalletHandler, SetActiveNetwork) { args.Append(base::Value("chain_id2")); args.Append(base::Value(static_cast(CoinType::ETH))); - handler.SetActiveNetwork(args); + handler.SetDefaultNetwork(args); const auto& data = *handler.web_ui()->call_data()[0]; ASSERT_TRUE(data.arg3()->is_bool()); EXPECT_EQ(data.arg3()->GetBool(), true); @@ -367,7 +367,7 @@ TEST(TestBraveWalletHandler, SetActiveNetwork) { args.Append(base::Value("unknown_chain_id")); args.Append(base::Value(static_cast(CoinType::ETH))); - handler.SetActiveNetwork(args); + handler.SetDefaultNetwork(args); const auto& data = *handler.web_ui()->call_data()[1]; ASSERT_TRUE(data.arg3()->is_bool()); EXPECT_EQ(data.arg3()->GetBool(), false); diff --git a/components/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp index b018b9abe039..b0c029f12da8 100644 --- a/components/resources/wallet_strings.grdp +++ b/components/resources/wallet_strings.grdp @@ -490,7 +490,7 @@ Edit Remove Reset - Set as active + Set as default Error processing the transaction Error processing the transaction Unable to find hardware transaction, please try again From c05fc3ef505c0103ecb920c96ca665d18c857f38 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Mon, 10 Apr 2023 21:45:45 -0700 Subject: [PATCH 09/15] Fix Android build This only preseves backward compatibility with what current Android behavior is to comply with new interfaces. It doesn't update Android with new core network per origin capacity nor some new interfaces with fine-grained chain id option. --- .../browser/app/domain/NetworkModel.java | 18 +++--- .../chrome/browser/app/domain/SendModel.java | 10 +-- .../activities/AccountDetailActivity.java | 4 +- .../activities/AdvanceTxSettingActivity.java | 26 ++++---- .../activities/BraveWalletDAppsActivity.java | 2 +- .../activities/BuySendSwapActivity.java | 11 ++-- .../ApproveTxBottomSheetDialogFragment.java | 64 ++++++++++--------- ...isibleAssetsBottomSheetDialogFragment.java | 2 +- .../crypto_wallet/fragments/TxFragment.java | 11 ++-- .../fragments/dapps/AddTokenFragment.java | 4 +- .../fragments/dapps/SignMessageFragment.java | 4 +- .../crypto_wallet/modal/BraveWalletPanel.java | 2 +- .../crypto_wallet/util/PendingTxHelper.java | 3 +- .../util/SolanaTransactionsGasHelper.java | 2 +- .../browser/crypto_wallet/util/Utils.java | 4 +- .../crypto_wallet/util/WalletConstants.java | 2 + .../BraveWalletNetworksPreference.java | 4 +- 17 files changed, 95 insertions(+), 78 deletions(-) diff --git a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java index f87b3fae9289..a2892cef9121 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java @@ -34,6 +34,7 @@ import org.chromium.chrome.browser.util.Triple; import org.chromium.mojo.bindings.Callbacks; import org.chromium.mojo.system.MojoException; +import org.chromium.url.internal.mojom.Origin; import java.util.ArrayList; import java.util.Arrays; @@ -123,10 +124,11 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData, } }); _mChainId.addSource(mSharedData.getCoinTypeLd(), coinType -> { - mJsonRpcService.getChainId(coinType, chainId -> { + mJsonRpcService.getChainId(coinType, null, chainId -> { String id = BraveWalletConstants.MAINNET_CHAIN_ID; if (TextUtils.isEmpty(chainId)) { - mJsonRpcService.setNetwork(id, mSharedData.getCoinType(), hasSetNetwork -> {}); + mJsonRpcService.setNetwork( + id, mSharedData.getCoinType(), null, hasSetNetwork -> {}); } else { id = chainId; } @@ -292,8 +294,8 @@ public void setNetworkWithAccountCheck( if (isSameNetwork(networkToBeSetAsSelected, selectedNetwork)) return; boolean hasAccountOfNetworkType = hasAccountOfNetworkType(networkToBeSetAsSelected); if (hasAccountOfNetworkType) { - mJsonRpcService.setNetwork( - networkToBeSetAsSelected.chainId, networkToBeSetAsSelected.coin, isSelected -> { + mJsonRpcService.setNetwork(networkToBeSetAsSelected.chainId, + networkToBeSetAsSelected.coin, null, isSelected -> { callback.call(isSelected); mCryptoActions.updateCoinType(); init(); @@ -311,8 +313,8 @@ public void setNetworkWithAccountCheck(String chainId, Callbacks.Callback1 callback) { - mJsonRpcService.setNetwork( - networkToBeSetAsSelected.chainId, networkToBeSetAsSelected.coin, isSelected -> { + mJsonRpcService.setNetwork(networkToBeSetAsSelected.chainId, networkToBeSetAsSelected.coin, + null, isSelected -> { callback.call(isSelected); mCryptoActions.updateCoinType(); init(); @@ -320,7 +322,7 @@ public void setNetwork( } public void getNetwork(@CoinType.EnumType int coin, Callbacks.Callback1 callback) { - mJsonRpcService.getNetwork(coin, networkInfo -> { callback.call(networkInfo); }); + mJsonRpcService.getNetwork(coin, null, networkInfo -> { callback.call(networkInfo); }); } public void clearCreateAccountState() { @@ -413,7 +415,7 @@ private boolean isSameNetwork( } @Override - public void chainChangedEvent(String chainId, int coin) { + public void chainChangedEvent(String chainId, int coin, Origin origin) { _mChainId.postValue(chainId); mCryptoActions.updateCoinAccountNetworkInfo(coin); } diff --git a/android/java/org/chromium/chrome/browser/app/domain/SendModel.java b/android/java/org/chromium/chrome/browser/app/domain/SendModel.java index 5e9f5906a87d..2627a993ec86 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/SendModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/SendModel.java @@ -65,14 +65,16 @@ public void setTxToken(BlockchainToken mTxToken) { // create and update balance and other corresponding details } - public void sendSolanaToken(BlockchainToken token, String fromAddress, String toAddress, - long lamportsValue, Callbacks.Callback3 callback) { + public void sendSolanaToken(String chainId, BlockchainToken token, String fromAddress, + String toAddress, long lamportsValue, + Callbacks.Callback3 callback) { if (token == null) return; if (token.coin == CoinType.SOL && !TextUtils.isEmpty(token.contractAddress)) { // process SPL (Solana Program Library) tokens - mSolanaTxManagerProxy.makeTokenProgramTransferTxData(token.contractAddress, fromAddress, - toAddress, lamportsValue, (solanaTxData, error, errorMessageMakeData) -> { + mSolanaTxManagerProxy.makeTokenProgramTransferTxData(chainId, token.contractAddress, + fromAddress, toAddress, lamportsValue, + (solanaTxData, error, errorMessageMakeData) -> { if (error == 0) { mTxService.addUnapprovedTransaction( WalletUtils.toTxDataUnion(solanaTxData), fromAddress, null, diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java index 9af576fd71c8..b834088ab92e 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java @@ -233,7 +233,7 @@ public void finishNativeInitialization() { Log.e(TAG, "finishNativeInitialization " + e); } assert mJsonRpcService != null; - mJsonRpcService.getNetwork(mCoinType, selectedNetwork -> { + mJsonRpcService.getNetwork(mCoinType, null, selectedNetwork -> { setUpAssetList(selectedNetwork); fetchAccountInfo(selectedNetwork); }); @@ -242,7 +242,7 @@ public void finishNativeInitialization() { @Override public void onAssetClick(BlockchainToken asset) { assert mJsonRpcService != null; - mJsonRpcService.getChainId(mCoinType, chainId -> { + mJsonRpcService.getChainId(mCoinType, null, chainId -> { Utils.openAssetDetailsActivity(AccountDetailActivity.this, chainId, asset); }); } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AdvanceTxSettingActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AdvanceTxSettingActivity.java index e2cffe3cdf33..385e8a09f981 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AdvanceTxSettingActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AdvanceTxSettingActivity.java @@ -26,6 +26,8 @@ protected void triggerLayoutInflation() { mEtCustomNonce = findViewById(R.id.activity_advance_setting_et_nonce); String txId = getIntent().getStringExtra(WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_ID); + String chainId = + getIntent().getStringExtra(WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_CHAIN_ID); String nonce = getIntent().getStringExtra(WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_NONCE); mEtCustomNonce.setText(Utils.hexToIntString(nonce)); @@ -35,16 +37,18 @@ protected void triggerLayoutInflation() { if (!TextUtils.isEmpty(newNonce)) { newNonce = Utils.toHex(mEtCustomNonce.getText().toString()); } - getEthTxManagerProxy().setNonceForUnapprovedTransaction(txId, newNonce, isSet -> { - if (isSet) { - Intent result = new Intent().putExtra( - WalletConstants.ADVANCE_TX_SETTING_INTENT_RESULT_NONCE, newNonce); - setResult(Activity.RESULT_OK, result); - finish(); - } else { - Log.e(TAG, "Unable to set nonce "); - } - }); + getEthTxManagerProxy().setNonceForUnapprovedTransaction( + chainId, txId, newNonce, isSet -> { + if (isSet) { + Intent result = new Intent().putExtra( + WalletConstants.ADVANCE_TX_SETTING_INTENT_RESULT_NONCE, + newNonce); + setResult(Activity.RESULT_OK, result); + finish(); + } else { + Log.e(TAG, "Unable to set nonce "); + } + }); }); onInitialLayoutInflationComplete(); } @@ -54,4 +58,4 @@ private void setupBraveToolBar(@StringRes int title) { toolbar.setTitle(title); setSupportActionBar(toolbar); } -} \ No newline at end of file +} diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BraveWalletDAppsActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BraveWalletDAppsActivity.java index f592617c92ad..1e144e98bee2 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BraveWalletDAppsActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BraveWalletDAppsActivity.java @@ -147,7 +147,7 @@ public void onRejectAllTransactions() { for (TransactionInfo transactionInfo : mPendingTxHelper.getPendingTransactions()) { getTxService().rejectTransaction( TransactionUtils.getCoinFromTxDataUnion(transactionInfo.txDataUnion), - transactionInfo.id, success -> { + transactionInfo.chainId, transactionInfo.id, success -> { if (!success) { Log.e(TAG, "Transaction failed " + transactionInfo.id); } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java index 6230b27f8e70..4b86a20fae37 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java @@ -357,7 +357,7 @@ private void workWithSwapQuota(SwapResponse response, SwapErrorResponse errorRes private void sendSwapTransaction(TxData data, String from) { assert mEthTxManagerProxy != null; - mEthTxManagerProxy.getGasEstimation1559(estimation -> { + mEthTxManagerProxy.getGasEstimation1559(mSelectedNetwork.chainId, estimation -> { String maxPriorityFeePerGas = ""; String maxFeePerGas = ""; if (estimation.fastMaxPriorityFeePerGas.equals(estimation.avgMaxPriorityFeePerGas)) { @@ -587,8 +587,8 @@ private void checkAllowance(String contract, String spenderAddress, double amoun assert mCurrentBlockchainToken != null; String ownerAddress = mCustomAccountAdapter.getAccountAddressAtPosition( mAccountSpinner.getSelectedItemPosition()); - mJsonRpcService.getErc20TokenAllowance( - contract, ownerAddress, spenderAddress, (allowance, error, errorMessage) -> { + mJsonRpcService.getErc20TokenAllowance(contract, ownerAddress, spenderAddress, + mSelectedNetwork.chainId, (allowance, error, errorMessage) -> { warnWhenError(TAG, "getErc20TokenAllowance", error, errorMessage); if (error != ProviderError.SUCCESS || amountToSend <= Utils.fromHexWei( @@ -1011,8 +1011,9 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { if (mCurrentBlockchainToken.isNft) { amount = "1"; } - mSendModel.sendSolanaToken(mCurrentBlockchainToken, mSelectedAccount.address, - to, Utils.toDecimalLamport(amount, mCurrentBlockchainToken.decimals), + mSendModel.sendSolanaToken(mSelectedNetwork.chainId, mCurrentBlockchainToken, + mSelectedAccount.address, to, + Utils.toDecimalLamport(amount, mCurrentBlockchainToken.decimals), (success, txMetaId, errorMessage) -> { // Do nothing here when success as we will receive an // unapproved transaction in TxServiceObserver. diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/ApproveTxBottomSheetDialogFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/ApproveTxBottomSheetDialogFragment.java index 26d83e8f5df8..9bb1c075049d 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/ApproveTxBottomSheetDialogFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/ApproveTxBottomSheetDialogFragment.java @@ -270,7 +270,7 @@ public void setupDialog(@NonNull Dialog dialog, int style) { associatedSplTokenInfo.setText(associatedSPLTokenAccountInfo); } mCoinType = TransactionUtils.getCoinFromTxDataUnion(mTxInfo.txDataUnion); - jsonRpcService.getNetwork(mCoinType, selectedNetwork -> { + jsonRpcService.getNetwork(mCoinType, null, selectedNetwork -> { networkName.setText(selectedNetwork.chainName); keyringService.getKeyringInfo( AssetUtils.getKeyringForCoinType(mCoinType), keyringInfo -> { @@ -471,7 +471,7 @@ private void rejectTransaction(boolean dismiss) { if (txService == null) { return; } - txService.rejectTransaction(mCoinType, mTxInfo.id, success -> { + txService.rejectTransaction(mCoinType, mTxInfo.chainId, mTxInfo.id, success -> { assert success : "tx is not rejected"; if (!success || !dismiss) { return; @@ -489,34 +489,36 @@ private void approveTransaction() { if (txService == null) { return; } - txService.approveTransaction(mCoinType, mTxInfo.id, (success, error, errorMessage) -> { - if (!success) { - int providerError = -1; - switch (error.which()) { - case ProviderErrorUnion.Tag.ProviderError: - providerError = error.getProviderError(); - break; - case ProviderErrorUnion.Tag.SolanaProviderError: - providerError = error.getSolanaProviderError(); - break; - case ProviderErrorUnion.Tag.FilecoinProviderError: - providerError = error.getFilecoinProviderError(); - break; - default: - assert false : "unknown error " + errorMessage; - } - assert success : "tx is not approved error: " + providerError + ", " + errorMessage; - Utils.warnWhenError(ApproveTxBottomSheetDialogFragment.TAG_FRAGMENT, - "approveTransaction", providerError, errorMessage); - return; - } - reportTransactionForP3A(); - mApproved = true; - if (mTransactionConfirmationListener != null) { - mTransactionConfirmationListener.onApproveTransaction(); - } - dismiss(); - }); + txService.approveTransaction( + mCoinType, mTxInfo.chainId, mTxInfo.id, (success, error, errorMessage) -> { + if (!success) { + int providerError = -1; + switch (error.which()) { + case ProviderErrorUnion.Tag.ProviderError: + providerError = error.getProviderError(); + break; + case ProviderErrorUnion.Tag.SolanaProviderError: + providerError = error.getSolanaProviderError(); + break; + case ProviderErrorUnion.Tag.FilecoinProviderError: + providerError = error.getFilecoinProviderError(); + break; + default: + assert false : "unknown error " + errorMessage; + } + assert success : "tx is not approved error: " + providerError + ", " + + errorMessage; + Utils.warnWhenError(ApproveTxBottomSheetDialogFragment.TAG_FRAGMENT, + "approveTransaction", providerError, errorMessage); + return; + } + reportTransactionForP3A(); + mApproved = true; + if (mTransactionConfirmationListener != null) { + mTransactionConfirmationListener.onApproveTransaction(); + } + dismiss(); + }); } private void reportTransactionForP3A() { @@ -528,7 +530,7 @@ private void reportTransactionForP3A() { BraveWalletP3a braveWalletP3A = getBraveWalletP3A(); assert jsonRpcService != null && braveWalletP3A != null; - jsonRpcService.getNetwork(mCoinType, selectedNetwork -> { + jsonRpcService.getNetwork(mCoinType, null, selectedNetwork -> { boolean countTestNetworks = CommandLine.getInstance().hasSwitch( BraveWalletConstants.P3A_COUNT_TEST_NETWORKS_SWITCH); if (countTestNetworks diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/EditVisibleAssetsBottomSheetDialogFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/EditVisibleAssetsBottomSheetDialogFragment.java index e7e63de76ebc..7f96117efa3d 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/EditVisibleAssetsBottomSheetDialogFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/EditVisibleAssetsBottomSheetDialogFragment.java @@ -614,7 +614,7 @@ public void onMaybeShowTrashButton( JsonRpcService jsonRpcService = getJsonRpcService(); if (jsonRpcService == null) return; jsonRpcService.getNetwork( - walletListItemModel.getBlockchainToken().coin, selectedNetwork -> { + walletListItemModel.getBlockchainToken().coin, null, selectedNetwork -> { TokenUtils.isCustomToken(getBlockchainRegistry(), selectedNetwork, selectedNetwork.coin, walletListItemModel.getBlockchainToken(), isCustom -> { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/TxFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/TxFragment.java index 5dd5ab8a8a7a..181c0edf5c5b 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/TxFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/TxFragment.java @@ -126,6 +126,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c new Intent(requireActivity(), AdvanceTxSettingActivity.class); String nonce = mParsedTx.getNonce(); toAdvanceTxSetting.putExtra(WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_ID, mTxInfo.id) + .putExtra( + WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_CHAIN_ID, mTxInfo.chainId) .putExtra(WalletConstants.ADVANCE_TX_SETTING_INTENT_TX_NONCE, nonce); startActivityForResult(toAdvanceTxSetting, START_ADVANCE_SETTING_ACTIVITY_CODE); }); @@ -163,7 +165,7 @@ public void onClick(View v) { radioGroup.setOnCheckedChangeListener((group, checkedId) -> { EthTxManagerProxy ethTxManagerProxy = getEthTxManagerProxy(); assert ethTxManagerProxy != null; - ethTxManagerProxy.getGasEstimation1559(estimation -> { + ethTxManagerProxy.getGasEstimation1559(mTxInfo.chainId, estimation -> { mTxInfo.txDataUnion.getEthTxData1559().gasEstimation = estimation; mCheckedPriorityId = checkedId; String maxPriorityFeePerGas = mParsedTx.getMaxPriorityFeePerGas(); @@ -272,7 +274,7 @@ public void onClick(View v) { mTxInfo.txDataUnion.getEthTxData1559().baseData.gasPrice = Utils.toHexWei(gasFeeEdit.getText().toString(), 9); ethTxManagerProxy.setGasPriceAndLimitForUnapprovedTransaction( - mTxInfo.id, + mTxInfo.chainId, mTxInfo.id, mTxInfo.txDataUnion.getEthTxData1559().baseData.gasPrice, mTxInfo.txDataUnion.getEthTxData1559().baseData.gasLimit, success -> { @@ -324,8 +326,9 @@ public void onClick(View v) { mTxInfo.txDataUnion.getEthTxData1559().maxPriorityFeePerGas = maxPriorityFeePerGas; mTxInfo.txDataUnion.getEthTxData1559().maxFeePerGas = maxFeePerGas; - ethTxManagerProxy.setGasFeeAndLimitForUnapprovedTransaction(mTxInfo.id, - maxPriorityFeePerGas, maxFeePerGas, gasLimit, success -> { + ethTxManagerProxy.setGasFeeAndLimitForUnapprovedTransaction( + mTxInfo.chainId, mTxInfo.id, maxPriorityFeePerGas, maxFeePerGas, + gasLimit, success -> { if (!success) { return; } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/AddTokenFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/AddTokenFragment.java index 59348b5362ea..6b84abd643b5 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/AddTokenFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/AddTokenFragment.java @@ -110,8 +110,8 @@ private void fillOriginInfo(OriginInfo originInfo) { } private void updateNetwork(@CoinType.EnumType int coin) { - getJsonRpcService().getNetwork( - coin, selectedNetwork -> { mNetworkName.setText(selectedNetwork.chainName); }); + getJsonRpcService().getNetwork(coin, null, + selectedNetwork -> { mNetworkName.setText(selectedNetwork.chainName); }); } private void initToken() { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/SignMessageFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/SignMessageFragment.java index 990c315133a5..ce84310efc29 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/SignMessageFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/dapps/SignMessageFragment.java @@ -141,7 +141,7 @@ private void updateAccount(String address) { } private void updateNetwork(@CoinType.EnumType int coin) { - getJsonRpcService().getNetwork( - coin, selectedNetwork -> { mNetworkName.setText(selectedNetwork.chainName); }); + getJsonRpcService().getNetwork(coin, null, + selectedNetwork -> { mNetworkName.setText(selectedNetwork.chainName); }); } } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/modal/BraveWalletPanel.java b/android/java/org/chromium/chrome/browser/crypto_wallet/modal/BraveWalletPanel.java index 958ef1232d82..161c0a8fc8cd 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/modal/BraveWalletPanel.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/modal/BraveWalletPanel.java @@ -354,7 +354,7 @@ private void getBalance(AccountInfo selectedAccount) { return; } mBraveWalletPanelServices.getJsonRpcService().getNetwork( - selectedAccount.coin, selectedNetwork -> { + selectedAccount.coin, null, selectedNetwork -> { BlockchainToken asset = Utils.makeNetworkAsset(selectedNetwork); AssetsPricesHelper.fetchPrices(mBraveWalletPanelServices.getAssetRatioService(), new BlockchainToken[] {asset}, assetPrices -> { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java index 70ec44c35974..b0298370cbde 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java @@ -102,7 +102,8 @@ public void fetchTransactions(Runnable runWhenDone) { new AsyncUtils.GetAllTransactionInfoResponseContext( allTxMultiResponse.singleResponseComplete, accountInfo.name); allTxContexts.add(allTxContext); - mTxService.getAllTransactionInfo(accountInfo.coin, accountInfo.address, allTxContext); + mTxService.getAllTransactionInfo( + accountInfo.coin, null, accountInfo.address, allTxContext); } allTxMultiResponse.setWhenAllCompletedAction(() -> { for (AsyncUtils.GetAllTransactionInfoResponseContext allTxContext : allTxContexts) { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/SolanaTransactionsGasHelper.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/SolanaTransactionsGasHelper.java index 1a50dc6e58e0..4ccf3a17c189 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/SolanaTransactionsGasHelper.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/SolanaTransactionsGasHelper.java @@ -63,7 +63,7 @@ public void maybeGetSolanaGasEstimations(Runnable runWhenDone) { if (mActivity.get() != null) mActivity.get().getSolanaTxManagerProxy().getEstimatedTxFee( - txInfo.id, estimatesContext); + txInfo.chainId, txInfo.id, estimatesContext); } estimatesMultiResponse.setWhenAllCompletedAction(() -> { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/Utils.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/Utils.java index 4feaaeb5f9f9..bcfb785d6ae3 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/Utils.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/Utils.java @@ -1101,7 +1101,7 @@ public static void openTransaction(TransactionInfo txInfo, JsonRpcService jsonRp public static void openAddress(String toAppend, JsonRpcService jsonRpcService, AppCompatActivity activity, int coinType) { assert jsonRpcService != null; - jsonRpcService.getNetwork(coinType, network -> { + jsonRpcService.getNetwork(coinType, null, network -> { String blockExplorerUrl = Arrays.toString(network.blockExplorerUrls); if (blockExplorerUrl.length() > 2) { blockExplorerUrl = blockExplorerUrl.substring(1, blockExplorerUrl.length() - 1); @@ -1148,7 +1148,7 @@ public static void setUpTransactionList(BraveWalletBaseActivity activity, coinType = walletListItemModel.getBlockchainToken().coin; } - jsonRpcService.getNetwork(coinType, selectedNetwork -> { + jsonRpcService.getNetwork(coinType, null, selectedNetwork -> { PendingTxHelper pendingTxHelper = new PendingTxHelper(txService, accounts, true); pendingTxHelper.fetchTransactions(() -> { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/WalletConstants.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/WalletConstants.java index ae4fccb8e27a..8e45387ba82c 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/WalletConstants.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/WalletConstants.java @@ -51,6 +51,8 @@ public final class WalletConstants { // AdvanceTxSettingActivity public static final String ADVANCE_TX_SETTING_INTENT_TX_ID = "advance-tx-setting-intent-tx-id"; + public static final String ADVANCE_TX_SETTING_INTENT_TX_CHAIN_ID = + "advance-tx-setting-intent-tx-chain-id"; public static final String ADVANCE_TX_SETTING_INTENT_TX_NONCE = "advance-tx-setting-intent-tx-nonce"; public static final String ADVANCE_TX_SETTING_INTENT_RESULT_NONCE = diff --git a/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java b/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java index ae5f2a412a41..16d50f23f2a9 100644 --- a/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java +++ b/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java @@ -94,7 +94,7 @@ public void onItemRemove(NetworkInfo chain) { @Override public void onItemSetAsActive(NetworkInfo chain) { assert mJsonRpcService != null; - mJsonRpcService.setNetwork(chain.chainId, CoinType.ETH, success -> { + mJsonRpcService.setNetwork(chain.chainId, CoinType.ETH, null, success -> { if (!success) { return; } @@ -127,7 +127,7 @@ private void updateNetworksList() { Log.e(TAG, "updateNetworksList " + e); } assert mJsonRpcService != null; - mJsonRpcService.getChainId(CoinType.ETH, chainId -> { + mJsonRpcService.getChainId(CoinType.ETH, null, chainId -> { mJsonRpcService.getAllNetworks(CoinType.ETH, chains -> { mJsonRpcService.getCustomNetworks(CoinType.ETH, customNetworkIds -> { mAdapter.setDisplayedNetworks( From e19615b62d51234c3726c5abaa70beacafbf4ed8 Mon Sep 17 00:00:00 2001 From: Josh Leonard <30185185+josheleonard@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:05:25 -0400 Subject: [PATCH 10/15] fix: remove `getNetworkFromTXDataUnion` --- .../common/hooks/use-pending-transaction.ts | 26 +++++------- .../common/hooks/use-transactions-network.ts | 15 +++---- .../common/slices/api.slice.ts | 13 ++++-- .../desktop/views/accounts/account.tsx | 29 ++++++++----- .../transaction-detail-panel/index.tsx | 15 +++---- .../extension/transaction-list-item/index.tsx | 13 +++--- .../brave_wallet_ui/panel/container.tsx | 1 - .../mock-data/mock-parsed-transaction-info.ts | 17 ++++---- .../stories/wallet-extension-panels.tsx | 2 - .../brave_wallet_ui/utils/network-utils.ts | 42 ------------------- 10 files changed, 67 insertions(+), 106 deletions(-) diff --git a/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts b/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts index d14a1e42b459..7e6b76851b2d 100644 --- a/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts +++ b/components/brave_wallet_ui/common/hooks/use-pending-transaction.ts @@ -14,7 +14,7 @@ import * as WalletActions from '../actions/wallet_actions' import Amount from '../../utils/amount' import { findAccountName } from '../../utils/account-utils' import { getLocale } from '../../../common/locale' -import { getNetworkFromTXDataUnion } from '../../utils/network-utils' +import { getCoinFromTxDataUnion } from '../../utils/network-utils' import { reduceAddress } from '../../utils/reduce-address' import { WalletSelectors } from '../selectors' @@ -27,10 +27,7 @@ import { useSafeWalletSelector, useUnsafeWalletSelector } from './use-safe-selector' -import { - useGetDefaultNetworksQuery, - useGetSelectedChainQuery -} from '../slices/api.slice' +import { useGetNetworkQuery } from '../slices/api.slice' // Constants import { BraveWallet } from '../../constants/types' @@ -65,19 +62,18 @@ export const usePendingTransactions = () => { ) // queries - const { data: selectedNetwork } = useGetSelectedChainQuery() - const { data: defaultNetworks = [] } = useGetDefaultNetworksQuery() - + const { data: transactionsNetwork } = useGetNetworkQuery( + transactionInfo + ? { + chainId: transactionInfo.chainId, + coin: getCoinFromTxDataUnion(transactionInfo.txDataUnion) + } + : undefined, + { skip: !transactionInfo } + ) const transactionGasEstimates = transactionInfo?.txDataUnion.ethTxData1559?.gasEstimation - const transactionsNetwork = React.useMemo(() => { - if (!transactionInfo) { - return selectedNetwork - } - return getNetworkFromTXDataUnion(transactionInfo.txDataUnion, defaultNetworks, selectedNetwork) - }, [defaultNetworks, transactionInfo, selectedNetwork]) - // custom hooks const { getBlockchainTokenInfo, getERC20Allowance } = useLib() const parseTransaction = useTransactionParser(transactionsNetwork) diff --git a/components/brave_wallet_ui/common/hooks/use-transactions-network.ts b/components/brave_wallet_ui/common/hooks/use-transactions-network.ts index f523b12f2e79..a6f66ab13c03 100644 --- a/components/brave_wallet_ui/common/hooks/use-transactions-network.ts +++ b/components/brave_wallet_ui/common/hooks/use-transactions-network.ts @@ -2,22 +2,19 @@ // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // you can obtain one at https://mozilla.org/MPL/2.0/. -import * as React from 'react' import { BraveWallet, SerializableTransactionInfo } from '../../constants/types' -import { getNetworkFromTXDataUnion } from '../../utils/network-utils' -import { useGetDefaultNetworksQuery, useGetSelectedChainQuery } from '../slices/api.slice' +import { getCoinFromTxDataUnion } from '../../utils/network-utils' +import { useGetNetworkQuery } from '../slices/api.slice' export const useTransactionsNetwork = < T extends SerializableTransactionInfo | BraveWallet.TransactionInfo >(transaction: T) => { // queries - const { data: selectedNetwork } = useGetSelectedChainQuery() - const { data: defaultNetworks = [] } = useGetDefaultNetworksQuery() - - const txNetwork = React.useMemo(() => { - return getNetworkFromTXDataUnion(transaction.txDataUnion, defaultNetworks, selectedNetwork) - }, [defaultNetworks, transaction, selectedNetwork]) + const { data: txNetwork } = useGetNetworkQuery({ + chainId: transaction.chainId, + coin: getCoinFromTxDataUnion(transaction.txDataUnion) + }) return txNetwork } diff --git a/components/brave_wallet_ui/common/slices/api.slice.ts b/components/brave_wallet_ui/common/slices/api.slice.ts index 987bbe9f8c7f..7eaf45d65e91 100644 --- a/components/brave_wallet_ui/common/slices/api.slice.ts +++ b/components/brave_wallet_ui/common/slices/api.slice.ts @@ -80,7 +80,11 @@ import { getEntitiesListFromEntityState } from '../../utils/entities.utils' import { makeNetworkAsset } from '../../options/asset-options' import { getTokenParam } from '../../utils/api-utils' import { getAccountType, getAddressLabelFromRegistry } from '../../utils/account-utils' -import { getCoinFromTxDataUnion, getFilecoinKeyringIdFromNetwork, getNetworkFromTXDataUnion, hasEIP1559Support } from '../../utils/network-utils' +import { + getCoinFromTxDataUnion, + getFilecoinKeyringIdFromNetwork, + hasEIP1559Support +} from '../../utils/network-utils' import Amount from '../../utils/amount' import { accountHasInsufficientFundsForGas, @@ -3321,9 +3325,10 @@ export const parseTransactionWithoutPricesAsync = async ({ dispatch: ThunkDispatch }): Promise => { const networks = getEntitiesListFromEntityState(networksRegistry) - const transactionNetwork = getNetworkFromTXDataUnion( - tx.txDataUnion, - networks + const transactionNetwork = networks.find( + (n) => + n.chainId === tx.chainId && + n.coin === getCoinFromTxDataUnion(tx.txDataUnion) ) // Tokens lists diff --git a/components/brave_wallet_ui/components/desktop/views/accounts/account.tsx b/components/brave_wallet_ui/components/desktop/views/accounts/account.tsx index 521e3599328f..bd802aaf4795 100644 --- a/components/brave_wallet_ui/components/desktop/views/accounts/account.tsx +++ b/components/brave_wallet_ui/components/desktop/views/accounts/account.tsx @@ -28,7 +28,10 @@ import { sortTransactionByDate } from '../../../../utils/tx-utils' import { getBalance } from '../../../../utils/balance-utils' -import { getFilecoinKeyringIdFromNetwork, getNetworkFromTXDataUnion } from '../../../../utils/network-utils' +import { + getCoinFromTxDataUnion, + getFilecoinKeyringIdFromNetwork +} from '../../../../utils/network-utils' import { selectAllBlockchainTokensFromQueryResult, selectAllUserAssetsFromQueryResult } from '../../../../common/slices/entities/blockchain-token.entity' // Styled Components @@ -145,15 +148,21 @@ export const Account = ({ return sortTransactionByDate( transactions[selectedAccount.address], 'descending' - ).map(tx => parseTransactionWithPrices({ - tx, - accounts, - fullTokenList, - userVisibleTokensList, - solFeeEstimates, - transactionNetwork: getNetworkFromTXDataUnion(tx.txDataUnion, networkList), - spotPrices - })) + ).map((tx) => + parseTransactionWithPrices({ + tx, + accounts, + fullTokenList, + userVisibleTokensList, + solFeeEstimates, + transactionNetwork: networkList.find( + (n) => + n.chainId === tx.chainId && + n.coin === getCoinFromTxDataUnion(tx.txDataUnion) + ), + spotPrices + }) + ) } else { return [] } diff --git a/components/brave_wallet_ui/components/extension/transaction-detail-panel/index.tsx b/components/brave_wallet_ui/components/extension/transaction-detail-panel/index.tsx index 7f03a6a836bb..cf76c55e1131 100644 --- a/components/brave_wallet_ui/components/extension/transaction-detail-panel/index.tsx +++ b/components/brave_wallet_ui/components/extension/transaction-detail-panel/index.tsx @@ -15,7 +15,7 @@ import { reduceAddress } from '../../../utils/reduce-address' import { getTransactionStatusString, isSolanaTransaction } from '../../../utils/tx-utils' import { toProperCase } from '../../../utils/string-utils' import Amount from '../../../utils/amount' -import { getNetworkFromTXDataUnion, getCoinFromTxDataUnion } from '../../../utils/network-utils' +import { getCoinFromTxDataUnion } from '../../../utils/network-utils' import { getLocale } from '../../../../common/locale' // Constants @@ -55,11 +55,10 @@ import { StatusBubble } from '../../shared/style' import { TransactionStatusTooltip } from '../transaction-status-tooltip' import { Tooltip } from '../../shared' import { serializedTimeDeltaToJSDate } from '../../../utils/datetime-utils' -import { useGetDefaultNetworksQuery } from '../../../common/slices/api.slice' +import { useGetNetworkQuery } from '../../../common/slices/api.slice' export interface Props { transaction: SerializableTransactionInfo - selectedNetwork?: BraveWallet.NetworkInfo accounts: WalletAccountType[] visibleTokens: BraveWallet.BlockchainToken[] transactionSpotPrices: BraveWallet.AssetPrice[] @@ -74,7 +73,6 @@ const TransactionDetailPanel = (props: Props) => { // props const { transaction, - selectedNetwork, accounts, defaultCurrencies, onBack, @@ -90,11 +88,10 @@ const TransactionDetailPanel = (props: Props) => { } = useSelector((state: { wallet: WalletState }) => state.wallet) // queries - const { data: defaultNetworks = [] } = useGetDefaultNetworksQuery() - - const transactionsNetwork = React.useMemo(() => { - return getNetworkFromTXDataUnion(transaction.txDataUnion, defaultNetworks, selectedNetwork) - }, [defaultNetworks, transaction, selectedNetwork]) + const { data: transactionsNetwork } = useGetNetworkQuery({ + chainId: transaction.chainId, + coin: getCoinFromTxDataUnion(transaction.txDataUnion) + }) const transactionsList = React.useMemo(() => { return accounts.map((account) => { diff --git a/components/brave_wallet_ui/components/extension/transaction-list-item/index.tsx b/components/brave_wallet_ui/components/extension/transaction-list-item/index.tsx index c28ca5620f02..b1b167cede4b 100644 --- a/components/brave_wallet_ui/components/extension/transaction-list-item/index.tsx +++ b/components/brave_wallet_ui/components/extension/transaction-list-item/index.tsx @@ -11,10 +11,10 @@ import { getLocale } from '../../../../common/locale' import { toProperCase } from '../../../utils/string-utils' import { getTransactionStatusString } from '../../../utils/tx-utils' import { formatDateAsRelative, serializedTimeDeltaToJSDate } from '../../../utils/datetime-utils' -import { getNetworkFromTXDataUnion } from '../../../utils/network-utils' import { reduceAddress } from '../../../utils/reduce-address' import { WalletSelectors } from '../../../common/selectors' import Amount from '../../../utils/amount' +import { getCoinFromTxDataUnion } from '../../../utils/network-utils' // Types import { BraveWallet, SerializableTransactionInfo } from '../../../constants/types' @@ -23,6 +23,7 @@ import { SwapExchangeProxy } from '../../../common/constants/registry' // Hooks import { useTransactionParser } from '../../../common/hooks' import { useSafeWalletSelector } from '../../../common/hooks/use-safe-selector' +import { useGetNetworkQuery } from '../../../common/slices/api.slice' // Components import { TransactionIntentDescription } from './transaction-intent-description' @@ -42,7 +43,6 @@ import { ToCircle, TransactionDetailRow } from './style' -import { useGetDefaultNetworksQuery } from '../../../common/slices/api.slice' export interface Props { selectedNetwork?: BraveWallet.NetworkInfo @@ -61,7 +61,10 @@ export const TransactionsListItem = ({ const defaultFiatCurrency = useSafeWalletSelector(WalletSelectors.defaultFiatCurrency) // queries - const { data: defaultNetworks = [] } = useGetDefaultNetworksQuery() + const { data: transactionsNetwork } = useGetNetworkQuery({ + chainId: transaction.chainId, + coin: getCoinFromTxDataUnion(transaction.txDataUnion) + }) // methods const onClickTransaction = () => { @@ -69,10 +72,6 @@ export const TransactionsListItem = ({ } // memos & custom hooks - const transactionsNetwork = React.useMemo(() => { - return getNetworkFromTXDataUnion(transaction.txDataUnion, defaultNetworks, selectedNetwork) - }, [defaultNetworks, transaction, selectedNetwork]) - const parseTransaction = useTransactionParser(transactionsNetwork) const transactionDetails = React.useMemo( diff --git a/components/brave_wallet_ui/panel/container.tsx b/components/brave_wallet_ui/panel/container.tsx index ae54e10bef79..40818b3a6407 100644 --- a/components/brave_wallet_ui/panel/container.tsx +++ b/components/brave_wallet_ui/panel/container.tsx @@ -643,7 +643,6 @@ function Container () { onBack={onGoBackToTransactions} accounts={accounts} defaultCurrencies={defaultCurrencies} - selectedNetwork={selectedNetwork} transaction={selectedTransaction} transactionSpotPrices={transactionSpotPrices} visibleTokens={userVisibleTokensInfo} diff --git a/components/brave_wallet_ui/stories/mock-data/mock-parsed-transaction-info.ts b/components/brave_wallet_ui/stories/mock-data/mock-parsed-transaction-info.ts index cf22044e2853..5b14e1f97f6b 100644 --- a/components/brave_wallet_ui/stories/mock-data/mock-parsed-transaction-info.ts +++ b/components/brave_wallet_ui/stories/mock-data/mock-parsed-transaction-info.ts @@ -4,7 +4,7 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. // utils -import { getNetworkFromTXDataUnion } from '../../utils/network-utils' +import { getCoinFromTxDataUnion } from '../../utils/network-utils' import { parseTransactionWithPrices } from '../../utils/tx-utils' // mocks @@ -19,9 +19,10 @@ export const mockParsedTransactionInfo = parseTransactionWithPrices({ tx: mockTransactionInfo, userVisibleTokensList: mockWalletState.userVisibleTokensInfo, solFeeEstimates: mockWalletState.solFeeEstimates, - transactionNetwork: getNetworkFromTXDataUnion( - mockTransactionInfo.txDataUnion, - mockNetworks + transactionNetwork: mockNetworks.find( + (n) => + n.chainId === mockTransactionInfo.chainId && + n.coin === getCoinFromTxDataUnion(mockTransactionInfo.txDataUnion) ) }) @@ -32,8 +33,10 @@ export const mockedParsedErc20ApprovalTransaction = parseTransactionWithPrices({ tx: mockedErc20ApprovalTransaction, userVisibleTokensList: mockWalletState.userVisibleTokensInfo, solFeeEstimates: mockWalletState.solFeeEstimates, - transactionNetwork: getNetworkFromTXDataUnion( - mockedErc20ApprovalTransaction.txDataUnion, - mockNetworks + transactionNetwork: mockNetworks.find( + (n) => + n.chainId === mockedErc20ApprovalTransaction.chainId && + n.coin === + getCoinFromTxDataUnion(mockedErc20ApprovalTransaction.txDataUnion) ) }) diff --git a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx index a89b7adc5fea..65dc801998c2 100644 --- a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx +++ b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx @@ -730,7 +730,6 @@ export const _ConnectedPanel = (args: { locked: boolean }) => { onSpeedupTransaction={onClickSpeedupTransaction} accounts={mockAccounts} defaultCurrencies={mockDefaultCurrencies} - selectedNetwork={mockNetworks[0]} visibleTokens={mockNewAssetOptions} transactionSpotPrices={[]} /> @@ -897,7 +896,6 @@ export const _TransactionDetail = () => { onSpeedupTransaction={mockedFunction} accounts={mockedTransactionAccounts} defaultCurrencies={mockDefaultCurrencies} - selectedNetwork={mockNetworks[0]} visibleTokens={mockNewAssetOptions} transactionSpotPrices={[]} transaction={tx} diff --git a/components/brave_wallet_ui/utils/network-utils.ts b/components/brave_wallet_ui/utils/network-utils.ts index 4975703c852b..d5a24d9d895c 100644 --- a/components/brave_wallet_ui/utils/network-utils.ts +++ b/components/brave_wallet_ui/utils/network-utils.ts @@ -10,9 +10,6 @@ import { WalletAccountTypeName } from '../constants/types' -// utils -import { isFilecoinTransaction } from './tx-utils' - export const emptyNetwork: BraveWallet.NetworkInfo = { chainId: '', chainName: '', @@ -71,45 +68,6 @@ export const getCoinFromTxDataUnion = (txDataUnion: T return BraveWallet.CoinType.ETH } -export const getNetworkFromTXDataUnion = < - T extends TxDataPresence, - N extends BraveWallet.NetworkInfo -> ( - txDataUnion: T, - networks: N[], - selectedNetwork?: N | undefined -): N | undefined => { - const tx = { txDataUnion } - const coin = getCoinFromTxDataUnion(tx.txDataUnion) - - const isFilTx = isFilecoinTransaction(tx) - const isFilTestNetTx = tx.txDataUnion.filTxData?.from?.startsWith( - BraveWallet.FILECOIN_TESTNET - ) - - return ( - networks.find((network) => { - switch (network.coin) { - case BraveWallet.CoinType.ETH: - return network.chainId === txDataUnion.ethTxData1559?.chainId - - case BraveWallet.CoinType.FIL: - // fil addresses on testnet start with 't' - return isFilTestNetTx - ? network.chainId === BraveWallet.FILECOIN_TESTNET - : isFilTx - ? network.chainId === BraveWallet.FILECOIN_MAINNET - : network.coin === coin - - // TODO: find a way to get SOL chainIds - case BraveWallet.CoinType.SOL: - default: - return network.coin === coin - } - }) ?? selectedNetwork - ) -} - export function getFilecoinKeyringIdFromNetwork ( network: Pick ) { From defb633e0c8aea43020674483bd69b998d69fa36 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Wed, 12 Apr 2023 16:28:10 -0700 Subject: [PATCH 11/15] Add chain_id to SignMessageRequest, SignTransactionRequest and SignAllTransactionsRequest To simplify front end displaying correct chain_id initiated from the dapp rather than the current selected network. --- browser/brave_content_browser_client.cc | 3 ++- .../brave_wallet_service_unittest.cc | 15 ++++++++++----- .../ethereum_provider_impl_unittest.cc | 10 +++++++--- .../solana_provider_impl_unittest.cc | 18 ++++++++++++++---- .../browser/ethereum_provider_impl.cc | 4 +++- .../browser/solana_provider_impl.cc | 13 +++++++++---- .../browser/solana_provider_impl.h | 7 ++++++- .../brave_wallet/common/brave_wallet.mojom | 3 +++ .../brave_wallet_ui/common/constants/mocks.ts | 6 ++++-- .../panel/reducers/panel_reducer.ts | 3 ++- .../stories/mock-data/mock-eth-requests.ts | 1 + .../stories/wallet-extension-panels.tsx | 1 + .../api/brave_wallet/brave_wallet_api.mm | 3 ++- 13 files changed, 64 insertions(+), 23 deletions(-) diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index ee6bfc8d6866..7f8a603046bf 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -345,7 +345,8 @@ void MaybeBindSolanaProvider( std::make_unique( keyring_service, brave_wallet_service, tx_service, std::make_unique( - web_contents, frame_host)), + web_contents, frame_host), + user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())), std::move(receiver)); } diff --git a/browser/brave_wallet/brave_wallet_service_unittest.cc b/browser/brave_wallet/brave_wallet_service_unittest.cc index e8c4d388ac03..a9e18629296d 100644 --- a/browser/brave_wallet/brave_wallet_service_unittest.cc +++ b/browser/brave_wallet/brave_wallet_service_unittest.cc @@ -2110,7 +2110,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessageHardware) { std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( origin_info.Clone(), 1, address, domain, message, false, absl::nullopt, - absl::nullopt, absl::nullopt, mojom::CoinType::ETH); + absl::nullopt, absl::nullopt, mojom::CoinType::ETH, + mojom::kMainnetChainId); bool callback_is_called = false; service_->AddSignMessageRequest( std::move(request1), @@ -2137,7 +2138,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessageHardware) { std::string expected_error = "error"; auto request2 = mojom::SignMessageRequest::New( origin_info.Clone(), 2, address, domain, message, false, absl::nullopt, - absl::nullopt, absl::nullopt, mojom::CoinType::ETH); + absl::nullopt, absl::nullopt, mojom::CoinType::ETH, + mojom::kMainnetChainId); service_->AddSignMessageRequest( std::move(request2), base::BindLambdaForTesting([&](bool approved, @@ -2167,7 +2169,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessage) { std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( origin_info.Clone(), 1, address, domain, message, false, absl::nullopt, - absl::nullopt, absl::nullopt, mojom::CoinType::ETH); + absl::nullopt, absl::nullopt, mojom::CoinType::ETH, + mojom::kMainnetChainId); bool callback_is_called = false; service_->AddSignMessageRequest( std::move(request1), @@ -2189,7 +2192,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessage) { std::string expected_error = "error"; auto request2 = mojom::SignMessageRequest::New( origin_info.Clone(), 2, address, domain, message, false, absl::nullopt, - absl::nullopt, absl::nullopt, mojom::CoinType::ETH); + absl::nullopt, absl::nullopt, mojom::CoinType::ETH, + mojom::kMainnetChainId); service_->AddSignMessageRequest( std::move(request2), base::BindLambdaForTesting([&](bool approved, @@ -2400,7 +2404,8 @@ TEST_F(BraveWalletServiceUnitTest, Reset) { std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( origin_info.Clone(), 1, address, domain, message, false, absl::nullopt, - absl::nullopt, absl::nullopt, mojom::CoinType::ETH); + absl::nullopt, absl::nullopt, mojom::CoinType::ETH, + mojom::kMainnetChainId); service_->AddSignMessageRequest( std::move(request1), base::BindLambdaForTesting([](bool, mojom::ByteArrayStringUnionPtr, diff --git a/browser/brave_wallet/ethereum_provider_impl_unittest.cc b/browser/brave_wallet/ethereum_provider_impl_unittest.cc index 859833dab0ce..fef243f3aa39 100644 --- a/browser/brave_wallet/ethereum_provider_impl_unittest.cc +++ b/browser/brave_wallet/ethereum_provider_impl_unittest.cc @@ -682,15 +682,19 @@ class EthereumProviderImplUnitTest : public testing::Test { return brave_wallet_service_->sign_message_requests_.front(); } - std::vector GetPendingSignMessageRequests() - const { + std::vector GetPendingSignMessageRequests() { base::RunLoop run_loop; std::vector requests_out; brave_wallet_service_->GetPendingSignMessageRequests( base::BindLambdaForTesting( [&](std::vector requests) { - for (const auto& request : requests) + for (const auto& request : requests) { + SCOPED_TRACE(request->message); + EXPECT_EQ(request->chain_id, + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + GetOrigin())); requests_out.push_back(request.Clone()); + } run_loop.Quit(); })); run_loop.Run(); diff --git a/browser/brave_wallet/solana_provider_impl_unittest.cc b/browser/brave_wallet/solana_provider_impl_unittest.cc index 9672df2d9ee0..865d13d48cbc 100644 --- a/browser/brave_wallet/solana_provider_impl_unittest.cc +++ b/browser/brave_wallet/solana_provider_impl_unittest.cc @@ -16,9 +16,11 @@ #include "brave/browser/brave_wallet/brave_wallet_provider_delegate_impl_helper.h" #include "brave/browser/brave_wallet/brave_wallet_service_factory.h" #include "brave/browser/brave_wallet/brave_wallet_tab_helper.h" +#include "brave/browser/brave_wallet/json_rpc_service_factory.h" #include "brave/browser/brave_wallet/keyring_service_factory.h" #include "brave/browser/brave_wallet/tx_service_factory.h" #include "brave/components/brave_wallet/browser/brave_wallet_service.h" +#include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/brave_wallet/browser/solana_account_meta.h" #include "brave/components/brave_wallet/browser/solana_instruction.h" @@ -117,6 +119,8 @@ class SolanaProviderImplUnitTest : public testing::Test { web_contents_.get()); brave_wallet_tab_helper()->SetSkipDelegateForTesting(true); permissions::PermissionRequestManager::CreateForWebContents(web_contents()); + json_rpc_service_ = + JsonRpcServiceFactory::GetServiceForContext(browser_context()); keyring_service_ = KeyringServiceFactory::GetServiceForContext(browser_context()); brave_wallet_service_ = @@ -131,7 +135,8 @@ class SolanaProviderImplUnitTest : public testing::Test { provider_ = std::make_unique( keyring_service_, brave_wallet_service_, tx_service_, std::make_unique( - web_contents(), web_contents()->GetPrimaryMainFrame())); + web_contents(), web_contents()->GetPrimaryMainFrame()), + profile_.GetPrefs()); observer_ = std::make_unique(); provider_->Init(observer_->GetReceiver()); } @@ -149,14 +154,17 @@ class SolanaProviderImplUnitTest : public testing::Test { return web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin(); } - std::vector GetPendingSignMessageRequests() - const { + std::vector GetPendingSignMessageRequests() { base::RunLoop run_loop; std::vector requests_out; brave_wallet_service_->GetPendingSignMessageRequests( base::BindLambdaForTesting( [&](std::vector requests) { for (const auto& request : requests) { + SCOPED_TRACE(request->message); + EXPECT_EQ(request->chain_id, + json_rpc_service_->GetChainId(mojom::CoinType::SOL, + GetOrigin())); requests_out.push_back(request.Clone()); } run_loop.Quit(); @@ -450,6 +458,7 @@ class SolanaProviderImplUnitTest : public testing::Test { protected: std::unique_ptr provider_; std::unique_ptr observer_; + raw_ptr json_rpc_service_ = nullptr; raw_ptr keyring_service_ = nullptr; private: @@ -752,7 +761,8 @@ TEST_F(SolanaProviderImplUnitTest, SignMessage) { AddAccount(); std::string address = GetAddressByIndex(0); SetSelectedAccount(address, mojom::CoinType::SOL); - Navigate(GURL("https://brave.com")); + GURL url("https://brave.com"); + Navigate(url); mojom::SolanaProviderError error; std::string error_message; diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index 6a15ef50a11d..4f8708913e44 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -885,7 +885,9 @@ void EthereumProviderImpl::ContinueSignMessage( auto request = mojom::SignMessageRequest::New( MakeOriginInfo(origin), -1, address, domain, message, is_eip712, - domain_hash, primary_hash, absl::nullopt, mojom::CoinType::ETH); + domain_hash, primary_hash, absl::nullopt, mojom::CoinType::ETH, + json_rpc_service_->GetChainId(mojom::CoinType::ETH, + delegate_->GetOrigin())); brave_wallet_service_->AddSignMessageRequest( std::move(request), diff --git a/components/brave_wallet/browser/solana_provider_impl.cc b/components/brave_wallet/browser/solana_provider_impl.cc index a23800464b71..7d6dcf5d1dd2 100644 --- a/components/brave_wallet/browser/solana_provider_impl.cc +++ b/components/brave_wallet/browser/solana_provider_impl.cc @@ -41,11 +41,13 @@ SolanaProviderImpl::SolanaProviderImpl( KeyringService* keyring_service, BraveWalletService* brave_wallet_service, TxService* tx_service, - std::unique_ptr delegate) + std::unique_ptr delegate, + PrefService* prefs) : keyring_service_(keyring_service), brave_wallet_service_(brave_wallet_service), tx_service_(tx_service), delegate_(std::move(delegate)), + prefs_(prefs), weak_factory_(this) { DCHECK(keyring_service_); keyring_service_->AddObserver( @@ -212,7 +214,8 @@ void SolanaProviderImpl::SignTransaction( MakeOriginInfo(delegate_->GetOrigin()), -1, *account, mojom::TxDataUnion::NewSolanaTxData(tx->ToSolanaTxData()), mojom::ByteArrayStringUnion::NewBytes(std::move(msg_pair->second)), - mojom::CoinType::SOL); + mojom::CoinType::SOL, + GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); brave_wallet_service_->AddSignTransactionRequest( std::move(request), base::BindOnce(&SolanaProviderImpl::OnSignTransactionRequestProcessed, @@ -310,7 +313,8 @@ void SolanaProviderImpl::SignAllTransactions( auto request = mojom::SignAllTransactionsRequest::New( MakeOriginInfo(delegate_->GetOrigin()), -1, *account, std::move(tx_datas), - std::move(raw_messages), mojom::CoinType::SOL); + std::move(raw_messages), mojom::CoinType::SOL, + GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); brave_wallet_service_->AddSignAllTransactionsRequest( std::move(request), @@ -509,7 +513,8 @@ void SolanaProviderImpl::SignMessage( } auto request = mojom::SignMessageRequest::New( MakeOriginInfo(delegate_->GetOrigin()), -1, *account, "", message, false, - absl::nullopt, absl::nullopt, blob_msg, mojom::CoinType::SOL); + absl::nullopt, absl::nullopt, blob_msg, mojom::CoinType::SOL, + GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); brave_wallet_service_->AddSignMessageRequest( std::move(request), diff --git a/components/brave_wallet/browser/solana_provider_impl.h b/components/brave_wallet/browser/solana_provider_impl.h index d98e6956ba97..f418dcf1e79b 100644 --- a/components/brave_wallet/browser/solana_provider_impl.h +++ b/components/brave_wallet/browser/solana_provider_impl.h @@ -12,6 +12,7 @@ #include #include "base/gtest_prod_util.h" +#include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -19,6 +20,8 @@ #include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" +class PrefService; + namespace brave_wallet { class BraveWalletProviderDelegate; @@ -37,7 +40,8 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, SolanaProviderImpl(KeyringService* keyring_service, BraveWalletService* brave_wallet_service, TxService* tx_service, - std::unique_ptr delegate); + std::unique_ptr delegate, + PrefService* prefs); ~SolanaProviderImpl() override; SolanaProviderImpl(const SolanaProviderImpl&) = delete; SolanaProviderImpl& operator=(const SolanaProviderImpl&) = delete; @@ -158,6 +162,7 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, keyring_observer_receiver_{this}; mojo::Receiver tx_observer_receiver_{this}; std::unique_ptr delegate_; + const raw_ptr prefs_ = nullptr; base::WeakPtrFactory weak_factory_; }; diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index d2b0ebf3acc6..064499b8e830 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -1449,6 +1449,7 @@ struct SignMessageRequest { // to sign. array? message_bytes; CoinType coin; + string chain_id; }; struct SignTransactionRequest { @@ -1458,6 +1459,7 @@ struct SignTransactionRequest { TxDataUnion tx_data; ByteArrayStringUnion raw_message; CoinType coin; + string chain_id; }; struct SignAllTransactionsRequest { @@ -1467,6 +1469,7 @@ struct SignAllTransactionsRequest { array tx_datas; array raw_messages; CoinType coin; + string chain_id; }; enum ExternalWalletType { diff --git a/components/brave_wallet_ui/common/constants/mocks.ts b/components/brave_wallet_ui/common/constants/mocks.ts index 72894f145c0f..f568670faa81 100644 --- a/components/brave_wallet_ui/common/constants/mocks.ts +++ b/components/brave_wallet_ui/common/constants/mocks.ts @@ -336,7 +336,8 @@ export const mockSolDappSignTransactionRequest: BraveWallet.SignTransactionReque } }, 'rawMessage': { bytes: [1], str: undefined }, - 'coin': BraveWallet.CoinType.SOL + 'coin': BraveWallet.CoinType.SOL, + 'chainId': BraveWallet.SOLANA_MAINNET } // BraveWallet.TransactionInfo (selectedPendingTransaction) @@ -546,5 +547,6 @@ export const mockSolDappSignAllTransactionsRequest: BraveWallet.SignAllTransacti } ], 'rawMessages': [{ bytes: [1], str: undefined }], - 'coin': BraveWallet.CoinType.SOL + 'coin': BraveWallet.CoinType.SOL, + 'chainId': BraveWallet.SOLANA_MAINNET } diff --git a/components/brave_wallet_ui/panel/reducers/panel_reducer.ts b/components/brave_wallet_ui/panel/reducers/panel_reducer.ts index ad92c9207804..d07c189fae43 100644 --- a/components/brave_wallet_ui/panel/reducers/panel_reducer.ts +++ b/components/brave_wallet_ui/panel/reducers/panel_reducer.ts @@ -58,7 +58,8 @@ const defaultState: PanelState = { domainHash: '', primaryHash: '', messageBytes: undefined, - coin: BraveWallet.CoinType.ETH + coin: BraveWallet.CoinType.ETH, + chainId: '' }], signAllTransactionsRequests: [], signTransactionRequests: [], diff --git a/components/brave_wallet_ui/stories/mock-data/mock-eth-requests.ts b/components/brave_wallet_ui/stories/mock-data/mock-eth-requests.ts index 1c016716f9c8..7d0b9dec6fea 100644 --- a/components/brave_wallet_ui/stories/mock-data/mock-eth-requests.ts +++ b/components/brave_wallet_ui/stories/mock-data/mock-eth-requests.ts @@ -17,6 +17,7 @@ export const mockSignMessageRequest = { domain: '', primaryHash: '', coin: BraveWallet.CoinType.ETH, + chainId: BraveWallet.MAINNET_CHAIN_ID, messageBytes: undefined } diff --git a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx index 65dc801998c2..43d6da578552 100644 --- a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx +++ b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx @@ -483,6 +483,7 @@ export const _SignData = () => { domain: '', originInfo: mockOriginInfo, coin: BraveWallet.CoinType.ETH, + chainId: BraveWallet.MAINNET_CHAIN_ID, isEip712: true, domainHash: '', primaryHash: '', diff --git a/ios/browser/api/brave_wallet/brave_wallet_api.mm b/ios/browser/api/brave_wallet/brave_wallet_api.mm index e6e558e6ce75..2324b6a6174a 100644 --- a/ios/browser/api/brave_wallet/brave_wallet_api.mm +++ b/ios/browser/api/brave_wallet/brave_wallet_api.mm @@ -128,7 +128,8 @@ - (instancetype)initWithBrowserState:(ChromeBrowserState*)mainBrowserState { auto provider = std::make_unique( keyring_service, brave_wallet_service, tx_service, std::make_unique( - delegate)); + delegate), + browserState->GetPrefs()); return [[BraveWalletSolanaProviderOwnedImpl alloc] initWithSolanaProvider:std::move(provider)]; } From d080694faff2f5f999787efd25a246160861cdc6 Mon Sep 17 00:00:00 2001 From: Josh Leonard <30185185+josheleonard@users.noreply.github.com> Date: Thu, 13 Apr 2023 11:08:20 -0400 Subject: [PATCH 12/15] fix: utilize chainId within Signature Requests --- .../components/extension/sign-panel/index.tsx | 21 ++++++++----------- .../sign-panel/sign-transaction-panel.tsx | 14 ++++++------- .../brave_wallet_ui/panel/container.tsx | 1 - .../stories/wallet-extension-panels.tsx | 1 - 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/components/brave_wallet_ui/components/extension/sign-panel/index.tsx b/components/brave_wallet_ui/components/extension/sign-panel/index.tsx index b88e21df2282..d416595bfdf3 100644 --- a/components/brave_wallet_ui/components/extension/sign-panel/index.tsx +++ b/components/brave_wallet_ui/components/extension/sign-panel/index.tsx @@ -5,11 +5,15 @@ import * as React from 'react' // Types -import { BraveWallet, SerializableSignMessageRequest, WalletAccountType } from '../../../constants/types' +import { + SerializableSignMessageRequest, + WalletAccountType +} from '../../../constants/types' // Utils import { getLocale } from '../../../../common/locale' import { unicodeEscape, hasUnicode } from '../../../utils/string-utils' +import { useGetNetworkQuery } from '../../../common/slices/api.slice' // Components import { NavButton, PanelTab } from '../' @@ -46,11 +50,9 @@ import { URLText, WarningIcon } from '../shared-panel-styles' -import { useGetDefaultNetworksQuery } from '../../../common/slices/api.slice' export interface Props { accounts: WalletAccountType[] - selectedNetwork?: BraveWallet.NetworkInfo signMessageData: SerializableSignMessageRequest[] onSign: () => void onCancel: () => void @@ -75,7 +77,6 @@ const onClickLearnMore = () => { export const SignPanel = (props: Props) => { const { accounts, - selectedNetwork, signMessageData, onSign, onCancel, @@ -83,7 +84,10 @@ export const SignPanel = (props: Props) => { } = props // queries - const { data: defaultNetworks = [] } = useGetDefaultNetworksQuery() + const { data: network } = useGetNetworkQuery({ + chainId: signMessageData[0].chainId, + coin: signMessageData[0].coin + }) // state const [signStep, setSignStep] = React.useState(SignDataSteps.SignData) @@ -108,13 +112,6 @@ export const SignPanel = (props: Props) => { , [signMessageData, selectedQueueData] ) - const network = React.useMemo( - () => - defaultNetworks.find((n) => n.coin === signMessageData[0].coin) ?? - selectedNetwork, - [defaultNetworks, selectedNetwork, signMessageData[0].coin] - ) - // methods const findAccountName = (address: string) => { return accounts.find((account) => account.address.toLowerCase() === address.toLowerCase())?.name diff --git a/components/brave_wallet_ui/components/extension/sign-panel/sign-transaction-panel.tsx b/components/brave_wallet_ui/components/extension/sign-panel/sign-transaction-panel.tsx index 0997965bebab..2a1f2cdd1b5f 100644 --- a/components/brave_wallet_ui/components/extension/sign-panel/sign-transaction-panel.tsx +++ b/components/brave_wallet_ui/components/extension/sign-panel/sign-transaction-panel.tsx @@ -20,7 +20,7 @@ import { findAccountName } from '../../../utils/account-utils' import { useUnsafePanelSelector, useUnsafeWalletSelector } from '../../../common/hooks/use-safe-selector' import { WalletSelectors } from '../../../common/selectors' import { PanelSelectors } from '../../../panel/selectors' -import { useGetDefaultNetworksQuery } from '../../../common/slices/api.slice' +import { useGetNetworkQuery } from '../../../common/slices/api.slice' // Components import NavButton from '../buttons/nav-button/index' @@ -84,18 +84,16 @@ export const SignTransactionPanel = ({ signMode }: Props) => { const signAllTransactionsRequests = useUnsafePanelSelector( PanelSelectors.signAllTransactionsRequests ) - - // queries - const { data: defaultNetworks } = useGetDefaultNetworksQuery() - const signTransactionData = signMode === 'signTx' ? signTransactionRequests : signAllTransactionsRequests - const network = defaultNetworks?.find( - (net) => net.coin === signTransactionData[0].coin - ) + // queries + const { data: network } = useGetNetworkQuery({ + chainId: signTransactionData[0].chainId, + coin: signTransactionData[0].coin + }) // state const [signStep, setSignStep] = React.useState(SignDataSteps.SignRisk) diff --git a/components/brave_wallet_ui/panel/container.tsx b/components/brave_wallet_ui/panel/container.tsx index 40818b3a6407..fe9f185d9eaf 100644 --- a/components/brave_wallet_ui/panel/container.tsx +++ b/components/brave_wallet_ui/panel/container.tsx @@ -505,7 +505,6 @@ function Container () { accounts={accounts} onCancel={onCancelSigning} onSign={onSignData} - selectedNetwork={selectedNetwork} // Pass a boolean here if the signing method is risky showWarning={false} /> diff --git a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx index 43d6da578552..6ff7efb13113 100644 --- a/components/brave_wallet_ui/stories/wallet-extension-panels.tsx +++ b/components/brave_wallet_ui/stories/wallet-extension-panels.tsx @@ -495,7 +495,6 @@ export const _SignData = () => { Date: Mon, 17 Apr 2023 21:42:06 -0700 Subject: [PATCH 13/15] CheckIfBlockTrackerShouldRun refactor We now have cached pending_chain_ids and new pending_chain_ids as input. When the function is called, it will stop out dated chain_id tracker and start tracker for new chain_id. If wallet is locked, all trackers will be stopped. --- .../eth_pending_tx_tracker_unittest.cc | 4 +- .../browser/eth_pending_tx_tracker.cc | 4 +- .../browser/eth_pending_tx_tracker.h | 1 - .../brave_wallet/browser/eth_tx_manager.cc | 47 ++++++++----------- .../brave_wallet/browser/eth_tx_manager.h | 1 - .../browser/eth_tx_manager_unittest.cc | 4 +- .../brave_wallet/browser/fil_tx_manager.cc | 11 ++--- .../brave_wallet/browser/solana_tx_manager.cc | 14 +++--- components/brave_wallet/browser/tx_manager.cc | 34 +++++++++----- components/brave_wallet/browser/tx_manager.h | 5 +- 10 files changed, 58 insertions(+), 67 deletions(-) diff --git a/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc b/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc index 2cb3a73a89ba..1d77d71c1890 100644 --- a/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc +++ b/browser/brave_wallet/eth_pending_tx_tracker_unittest.cc @@ -221,11 +221,9 @@ TEST_F(EthPendingTxTrackerUnitTest, UpdatePendingTransactions) { for (const std::string& chain_id : {mojom::kMainnetChainId, mojom::kGoerliChainId, mojom::kSepoliaChainId}) { - size_t num_pending; std::set pending_chain_ids; EXPECT_TRUE(pending_tx_tracker.UpdatePendingTransactions( - chain_id, &num_pending, &pending_chain_ids)); - EXPECT_EQ(4UL, num_pending); + chain_id, &pending_chain_ids)); EXPECT_EQ(1UL, pending_chain_ids.size()); WaitForResponse(); auto meta_from_state = diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.cc b/components/brave_wallet/browser/eth_pending_tx_tracker.cc index fe4c53227935..3563f1913adf 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.cc +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.cc @@ -31,9 +31,8 @@ EthPendingTxTracker::~EthPendingTxTracker() = default; bool EthPendingTxTracker::UpdatePendingTransactions( const absl::optional& chain_id, - size_t* num_pending, std::set* pending_chain_ids) { - CHECK(num_pending && pending_chain_ids); + CHECK(pending_chain_ids); base::Lock* nonce_lock = nonce_tracker_->GetLock(); if (!nonce_lock->Try()) return false; @@ -62,7 +61,6 @@ bool EthPendingTxTracker::UpdatePendingTransactions( } nonce_lock->Release(); - *num_pending = pending_transactions.size(); return true; } diff --git a/components/brave_wallet/browser/eth_pending_tx_tracker.h b/components/brave_wallet/browser/eth_pending_tx_tracker.h index 28df2d849d76..58867bff61a5 100644 --- a/components/brave_wallet/browser/eth_pending_tx_tracker.h +++ b/components/brave_wallet/browser/eth_pending_tx_tracker.h @@ -34,7 +34,6 @@ class EthPendingTxTracker { EthPendingTxTracker operator=(const EthPendingTxTracker&) = delete; bool UpdatePendingTransactions(const absl::optional& chain_id, - size_t* num_pending, std::set* pending_chain_ids); void Reset(); diff --git a/components/brave_wallet/browser/eth_tx_manager.cc b/components/brave_wallet/browser/eth_tx_manager.cc index 460aa5227aed..5c0440b03dee 100644 --- a/components/brave_wallet/browser/eth_tx_manager.cc +++ b/components/brave_wallet/browser/eth_tx_manager.cc @@ -518,11 +518,11 @@ void EthTxManager::ContinueProcessHardwareSignature( error_message); } -void EthTxManager::ApproveTransaction(const std::string& chain_id_str, +void EthTxManager::ApproveTransaction(const std::string& chain_id, const std::string& tx_meta_id, ApproveTransactionCallback callback) { std::unique_ptr meta = - GetEthTxStateManager()->GetEthTx(chain_id_str, tx_meta_id); + GetEthTxStateManager()->GetEthTx(chain_id, tx_meta_id); if (!meta) { LOG(ERROR) << "No transaction found"; std::move(callback).Run( @@ -533,32 +533,20 @@ void EthTxManager::ApproveTransaction(const std::string& chain_id_str, return; } - uint256_t chain_id = 0; - if (!HexValueToUint256(meta->chain_id(), &chain_id)) { - LOG(ERROR) << "Could not convert chain ID"; - std::move(callback).Run( - false, - mojom::ProviderErrorUnion::NewProviderError( - mojom::ProviderError::kInternalError), - l10n_util::GetStringUTF8(IDS_WALLET_ETH_INVALID_CHAIN_ID_RPC)); - return; - } - if (!meta->tx()->nonce()) { auto from = meta->from(); nonce_tracker_->GetNextNonce( - chain_id_str, from, + chain_id, from, base::BindOnce(&EthTxManager::OnGetNextNonce, - weak_factory_.GetWeakPtr(), std::move(meta), chain_id, + weak_factory_.GetWeakPtr(), std::move(meta), std::move(callback))); } else { uint256_t nonce = meta->tx()->nonce().value(); - OnGetNextNonce(std::move(meta), chain_id, std::move(callback), true, nonce); + OnGetNextNonce(std::move(meta), std::move(callback), true, nonce); } } void EthTxManager::OnGetNextNonce(std::unique_ptr meta, - uint256_t chain_id, ApproveTransactionCallback callback, bool success, uint256_t nonce) { @@ -573,6 +561,18 @@ void EthTxManager::OnGetNextNonce(std::unique_ptr meta, l10n_util::GetStringUTF8(IDS_WALLET_GET_NONCE_ERROR)); return; } + + uint256_t chain_id = 0; + if (!HexValueToUint256(meta->chain_id(), &chain_id)) { + LOG(ERROR) << "Could not convert chain ID"; + std::move(callback).Run( + false, + mojom::ProviderErrorUnion::NewProviderError( + mojom::ProviderError::kInternalError), + l10n_util::GetStringUTF8(IDS_WALLET_ETH_INVALID_CHAIN_ID_RPC)); + return; + } + meta->tx()->set_nonce(nonce); DCHECK(!keyring_service_->IsLocked(mojom::kDefaultKeyringId)); keyring_service_->SignTransactionByDefaultKeyring(meta->from(), meta->tx(), @@ -954,18 +954,9 @@ void EthTxManager::OnNewBlock(const std::string& chain_id, void EthTxManager::UpdatePendingTransactions( const absl::optional& chain_id) { std::set pending_chain_ids; - size_t num_pending; - if (pending_tx_tracker_->UpdatePendingTransactions(chain_id, &num_pending, + if (pending_tx_tracker_->UpdatePendingTransactions(chain_id, &pending_chain_ids)) { - if (num_pending == 0) { - known_no_pending_tx_ = true; - CheckIfBlockTrackerShouldRun(absl::nullopt); - } else { - known_no_pending_tx_ = false; - for (const auto& pending_chain_id : pending_chain_ids) { - CheckIfBlockTrackerShouldRun(pending_chain_id); - } - } + CheckIfBlockTrackerShouldRun(pending_chain_ids); } } diff --git a/components/brave_wallet/browser/eth_tx_manager.h b/components/brave_wallet/browser/eth_tx_manager.h index 87869d4a95c8..a87d291130cb 100644 --- a/components/brave_wallet/browser/eth_tx_manager.h +++ b/components/brave_wallet/browser/eth_tx_manager.h @@ -183,7 +183,6 @@ class EthTxManager : public TxManager, public EthBlockTracker::Observer { void NotifyUnapprovedTxUpdated(TxMeta* meta); void OnConnectionError(); void OnGetNextNonce(std::unique_ptr meta, - uint256_t chain_id, ApproveTransactionCallback callback, bool success, uint256_t nonce); diff --git a/components/brave_wallet/browser/eth_tx_manager_unittest.cc b/components/brave_wallet/browser/eth_tx_manager_unittest.cc index 1ff37bcaf542..458e4e0af07a 100644 --- a/components/brave_wallet/browser/eth_tx_manager_unittest.cc +++ b/components/brave_wallet/browser/eth_tx_manager_unittest.cc @@ -2294,7 +2294,7 @@ TEST_F(EthTxManagerUnitTest, MakeERC1155TransferFromData) { } TEST_F(EthTxManagerUnitTest, Reset) { - eth_tx_manager()->known_no_pending_tx_ = true; + eth_tx_manager()->pending_chain_ids_.emplace(mojom::kLocalhostChainId); eth_tx_manager()->block_tracker_->Start(mojom::kLocalhostChainId, base::Seconds(10)); EXPECT_TRUE( @@ -2316,7 +2316,7 @@ TEST_F(EthTxManagerUnitTest, Reset) { tx_service_->Reset(); - EXPECT_FALSE(eth_tx_manager()->known_no_pending_tx_); + EXPECT_TRUE(eth_tx_manager()->pending_chain_ids_.empty()); EXPECT_FALSE( eth_tx_manager()->block_tracker_->IsRunning(mojom::kLocalhostChainId)); EXPECT_FALSE(GetPrefs()->HasPrefPath(kBraveWalletTransactions)); diff --git a/components/brave_wallet/browser/fil_tx_manager.cc b/components/brave_wallet/browser/fil_tx_manager.cc index 149d9e94def4..f391fcfdce2b 100644 --- a/components/brave_wallet/browser/fil_tx_manager.cc +++ b/components/brave_wallet/browser/fil_tx_manager.cc @@ -6,6 +6,7 @@ #include "brave/components/brave_wallet/browser/fil_tx_manager.h" #include +#include #include #include #include @@ -358,6 +359,7 @@ void FilTxManager::UpdatePendingTransactions( const absl::optional& chain_id) { auto pending_transactions = tx_state_manager_->GetTransactionsByStatus( chain_id, mojom::TransactionStatus::Submitted, absl::nullopt); + std::set pending_chain_ids; for (const auto& pending_transaction : pending_transactions) { auto cid = pending_transaction->tx_hash(); uint64_t seconds = @@ -374,14 +376,9 @@ void FilTxManager::UpdatePendingTransactions( base::BindOnce(&FilTxManager::OnGetFilStateSearchMsgLimited, weak_factory_.GetWeakPtr(), pending_chain_id, pending_transaction->id())); - CheckIfBlockTrackerShouldRun(pending_chain_id); - } - if (pending_transactions.empty()) { - known_no_pending_tx_ = true; - CheckIfBlockTrackerShouldRun(absl::nullopt); - } else { - known_no_pending_tx_ = false; + pending_chain_ids.emplace(pending_chain_id); } + CheckIfBlockTrackerShouldRun(pending_chain_ids); } void FilTxManager::OnGetFilStateSearchMsgLimited( diff --git a/components/brave_wallet/browser/solana_tx_manager.cc b/components/brave_wallet/browser/solana_tx_manager.cc index 58994d5bad1e..0eb76f47ce98 100644 --- a/components/brave_wallet/browser/solana_tx_manager.cc +++ b/components/brave_wallet/browser/solana_tx_manager.cc @@ -6,6 +6,7 @@ #include "brave/components/brave_wallet/browser/solana_tx_manager.h" #include +#include #include #include "base/base64.h" @@ -207,8 +208,10 @@ void SolanaTxManager::OnSendSolanaTransaction( void SolanaTxManager::UpdatePendingTransactions( const absl::optional& chain_id) { + std::set pending_chain_ids; if (chain_id.has_value()) { - CheckIfBlockTrackerShouldRun(chain_id); + pending_chain_ids = pending_chain_ids_; + pending_chain_ids.emplace(*chain_id); json_rpc_service_->GetSolanaBlockHeight( *chain_id, base::BindOnce(&SolanaTxManager::OnGetBlockHeight, weak_ptr_factory_.GetWeakPtr(), *chain_id)); @@ -221,15 +224,10 @@ void SolanaTxManager::UpdatePendingTransactions( pending_chain_id, base::BindOnce(&SolanaTxManager::OnGetBlockHeight, weak_ptr_factory_.GetWeakPtr(), pending_chain_id)); - CheckIfBlockTrackerShouldRun(pending_chain_id); - } - if (pending_transactions.empty()) { - known_no_pending_tx_ = true; - CheckIfBlockTrackerShouldRun(absl::nullopt); - } else { - known_no_pending_tx_ = false; + pending_chain_ids.emplace(pending_chain_id); } } + CheckIfBlockTrackerShouldRun(pending_chain_ids); } void SolanaTxManager::OnGetBlockHeight(const std::string& chain_id, diff --git a/components/brave_wallet/browser/tx_manager.cc b/components/brave_wallet/browser/tx_manager.cc index 98446fbf1bc7..c47bd94fab1f 100644 --- a/components/brave_wallet/browser/tx_manager.cc +++ b/components/brave_wallet/browser/tx_manager.cc @@ -97,19 +97,29 @@ void TxManager::RejectTransaction(const std::string& chain_id, } void TxManager::CheckIfBlockTrackerShouldRun( - const absl::optional& chain_id) { - const auto& keyring_id = CoinTypeToKeyringId(GetCoinType(), chain_id); - CHECK(keyring_id.has_value()); - bool keyring_created = keyring_service_->IsKeyringCreated(*keyring_id); + const std::set& new_pending_chain_ids) { bool locked = keyring_service_->IsLockedSync(); - // If a timer in BlockTracker has already stopped, calling Stop() will be a no - // op. - bool running = chain_id.has_value() && block_tracker_->IsRunning(*chain_id); - if (keyring_created && !locked && !running && chain_id.has_value()) { - block_tracker_->Start(*chain_id, - base::Seconds(kBlockTrackerDefaultTimeInSeconds)); - } else if (locked || known_no_pending_tx_) { + + if (locked) { block_tracker_->Stop(); + } else if (new_pending_chain_ids != pending_chain_ids_) { + // Stop tracker that is no longer needed. + for (const auto& pending_chain_id : pending_chain_ids_) { + if (!base::Contains(new_pending_chain_ids, pending_chain_id)) { + block_tracker_->Stop(pending_chain_id); + } + } + for (const auto& chain_id : new_pending_chain_ids) { + const auto& keyring_id = CoinTypeToKeyringId(GetCoinType(), chain_id); + CHECK(keyring_id.has_value()); + bool keyring_created = keyring_service_->IsKeyringCreated(*keyring_id); + bool running = block_tracker_->IsRunning(chain_id); + if (keyring_created && !running) { + block_tracker_->Start(chain_id, + base::Seconds(kBlockTrackerDefaultTimeInSeconds)); + } + } + pending_chain_ids_ = new_pending_chain_ids; } } @@ -135,7 +145,7 @@ void TxManager::KeyringReset() { void TxManager::Reset() { block_tracker_->Stop(); - known_no_pending_tx_ = false; + pending_chain_ids_.clear(); } } // namespace brave_wallet diff --git a/components/brave_wallet/browser/tx_manager.h b/components/brave_wallet/browser/tx_manager.h index f2b417c9a91e..f768c180265b 100644 --- a/components/brave_wallet/browser/tx_manager.h +++ b/components/brave_wallet/browser/tx_manager.h @@ -7,6 +7,7 @@ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_TX_MANAGER_H_ #include +#include #include #include @@ -88,7 +89,7 @@ class TxManager : public TxStateManager::Observer, protected: void CheckIfBlockTrackerShouldRun( - const absl::optional& chain_id); + const std::set& new_pending_chain_ids); virtual void UpdatePendingTransactions( const absl::optional& chain_id) = 0; @@ -98,7 +99,7 @@ class TxManager : public TxStateManager::Observer, raw_ptr json_rpc_service_ = nullptr; // NOT OWNED raw_ptr keyring_service_ = nullptr; // NOT OWNED raw_ptr prefs_ = nullptr; // NOT OWNED - bool known_no_pending_tx_ = false; + std::set pending_chain_ids_; private: virtual mojom::CoinType GetCoinType() const = 0; From 6f41ae7de26ad009068c2c0ed52a9d0cbe046a4c Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Tue, 18 Apr 2023 11:18:44 -0700 Subject: [PATCH 14/15] EthLogTracker should be started with chain_id determined from origin. It should also be stopped when chain_id changed. --- components/brave_wallet/browser/eth_logs_tracker.cc | 10 ++++------ components/brave_wallet/browser/eth_logs_tracker.h | 4 ++-- .../brave_wallet/browser/ethereum_provider_impl.cc | 10 ++++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/components/brave_wallet/browser/eth_logs_tracker.cc b/components/brave_wallet/browser/eth_logs_tracker.cc index 244347183454..d5b50559c837 100644 --- a/components/brave_wallet/browser/eth_logs_tracker.cc +++ b/components/brave_wallet/browser/eth_logs_tracker.cc @@ -17,10 +17,11 @@ EthLogsTracker::EthLogsTracker(JsonRpcService* json_rpc_service) EthLogsTracker::~EthLogsTracker() = default; -void EthLogsTracker::Start(base::TimeDelta interval) { +void EthLogsTracker::Start(const std::string& chain_id, + base::TimeDelta interval) { timer_.Start(FROM_HERE, interval, base::BindRepeating(&EthLogsTracker::GetLogs, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), chain_id)); } void EthLogsTracker::Stop() { @@ -49,10 +50,7 @@ void EthLogsTracker::RemoveObserver(EthLogsTracker::Observer* observer) { observers_.RemoveObserver(observer); } -void EthLogsTracker::GetLogs() { - const auto chain_id = - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt); - +void EthLogsTracker::GetLogs(const std::string& chain_id) { for (auto const& esi : std::as_const(eth_logs_subscription_info_)) { json_rpc_service_->EthGetLogs( chain_id, esi.second.Clone(), diff --git a/components/brave_wallet/browser/eth_logs_tracker.h b/components/brave_wallet/browser/eth_logs_tracker.h index d39a81c1848f..b7165dba80be 100644 --- a/components/brave_wallet/browser/eth_logs_tracker.h +++ b/components/brave_wallet/browser/eth_logs_tracker.h @@ -40,7 +40,7 @@ class EthLogsTracker { }; // If timer is already running, it will be replaced with new interval - void Start(base::TimeDelta interval); + void Start(const std::string& chain_id, base::TimeDelta interval); void Stop(); bool IsRunning() const; @@ -52,7 +52,7 @@ class EthLogsTracker { void RemoveObserver(Observer* observer); private: - void GetLogs(); + void GetLogs(const std::string& chain_id); void OnGetLogs(const std::string& subscription, const std::vector& logs, base::Value rawlogs, diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index 4f8708913e44..bd229ee63bd9 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -557,13 +557,13 @@ void EthereumProviderImpl::EthSubscribe( return std::tuple{subscriptions.size() == 1, hex_bytes}; }; + const std::string& chain_id = json_rpc_service_->GetChainId( + mojom::CoinType::ETH, delegate_->GetOrigin()); if (event_type == kEthSubscribeNewHeads) { const auto gen_res = generateHexBytes(eth_subscriptions_); if (std::get<0>(gen_res)) { eth_block_tracker_.Start( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin()), - base::Seconds(kBlockTrackerDefaultTimeInSeconds)); + chain_id, base::Seconds(kBlockTrackerDefaultTimeInSeconds)); } std::move(callback).Run(std::move(id), base::Value(std::get<1>(gen_res)), false, "", false); @@ -571,7 +571,8 @@ void EthereumProviderImpl::EthSubscribe( const auto gen_res = generateHexBytes(eth_log_subscriptions_); if (std::get<0>(gen_res)) { - eth_logs_tracker_.Start(base::Seconds(kLogTrackerDefaultTimeInSeconds)); + eth_logs_tracker_.Start(chain_id, + base::Seconds(kLogTrackerDefaultTimeInSeconds)); } eth_logs_tracker_.AddSubscriber(std::get<1>(gen_res), std::move(*filter)); @@ -1569,6 +1570,7 @@ void EthereumProviderImpl::ChainChangedEvent( return; } + eth_logs_tracker_.Stop(); events_listener_->ChainChangedEvent(chain_id); } From 0fcaa64f71d7a05df19c028183023598ae4e7bf2 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Tue, 18 Apr 2023 15:58:51 -0700 Subject: [PATCH 15/15] Split JsonRpcService.GetChainId into GetDefaultChainId and GetChainIdForOrigin Both of them call non mojo GetChainIdSync --- .../browser/app/domain/NetworkModel.java | 2 +- .../activities/AccountDetailActivity.java | 2 +- .../BraveWalletNetworksPreference.java | 2 +- ...brave_wallet_ethereum_chain_browsertest.cc | 12 +++--- .../ethereum_provider_impl_unittest.cc | 30 ++++++++------- .../send_or_sign_transaction_browsertest.cc | 2 +- .../solana_provider_impl_unittest.cc | 4 +- .../browser/brave_wallet_service.cc | 2 +- .../brave_wallet/browser/eth_tx_manager.cc | 2 +- .../browser/ethereum_provider_impl.cc | 30 +++++++-------- .../brave_wallet/browser/json_rpc_service.cc | 24 +++++++----- .../brave_wallet/browser/json_rpc_service.h | 14 ++++--- .../browser/json_rpc_service_unittest.cc | 20 +++++++--- .../brave_wallet/browser/swap_service.cc | 38 +++++++++---------- components/brave_wallet/browser/tx_service.cc | 2 +- .../brave_wallet/common/brave_wallet.mojom | 7 +++- .../common/async/__mocks__/bridge.ts | 2 +- .../brave_wallet_ui/common/async/lib.ts | 4 +- 18 files changed, 112 insertions(+), 87 deletions(-) diff --git a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java index a2892cef9121..1486baf5769f 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java @@ -124,7 +124,7 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData, } }); _mChainId.addSource(mSharedData.getCoinTypeLd(), coinType -> { - mJsonRpcService.getChainId(coinType, null, chainId -> { + mJsonRpcService.getDefaultChainId(coinType, chainId -> { String id = BraveWalletConstants.MAINNET_CHAIN_ID; if (TextUtils.isEmpty(chainId)) { mJsonRpcService.setNetwork( diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java index b834088ab92e..7ce2880090be 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java @@ -242,7 +242,7 @@ public void finishNativeInitialization() { @Override public void onAssetClick(BlockchainToken asset) { assert mJsonRpcService != null; - mJsonRpcService.getChainId(mCoinType, null, chainId -> { + mJsonRpcService.getDefaultChainId(mCoinType, chainId -> { Utils.openAssetDetailsActivity(AccountDetailActivity.this, chainId, asset); }); } diff --git a/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java b/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java index 16d50f23f2a9..5d38ee0e8f8a 100644 --- a/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java +++ b/android/java/org/chromium/chrome/browser/settings/BraveWalletNetworksPreference.java @@ -127,7 +127,7 @@ private void updateNetworksList() { Log.e(TAG, "updateNetworksList " + e); } assert mJsonRpcService != null; - mJsonRpcService.getChainId(CoinType.ETH, null, chainId -> { + mJsonRpcService.getDefaultChainId(CoinType.ETH, chainId -> { mJsonRpcService.getAllNetworks(CoinType.ETH, chains -> { mJsonRpcService.getCustomNetworks(CoinType.ETH, customNetworkIds -> { mAdapter.setDisplayedNetworks( diff --git a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc index a4e6ebaea12a..04066e0f3d73 100644 --- a/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc +++ b/browser/brave_wallet/brave_wallet_ethereum_chain_browsertest.cc @@ -300,8 +300,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddEthereumChainApproved) { EXPECT_EQ( chain->block_explorer_urls, std::vector({"https://bscscan.com/", "http://localhost/"})); - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - origin), + EXPECT_EQ(GetJsonRpcService()->GetChainIdSync( + brave_wallet::mojom::CoinType::ETH, origin), kSomeChainId); } @@ -427,8 +427,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, ASSERT_FALSE(GetAllEthCustomChains().empty()); EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); // But current chain should not change - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - origin), + EXPECT_EQ(GetJsonRpcService()->GetChainIdSync( + brave_wallet::mojom::CoinType::ETH, origin), "0x1"); } @@ -476,8 +476,8 @@ IN_PROC_BROWSER_TEST_F(BraveWalletEthereumChainTest, AddDifferentChainsSwitch) { base::RunLoop().RunUntilIdle(); ASSERT_FALSE(GetAllEthCustomChains().empty()); EXPECT_EQ(GetAllEthCustomChains().front()->chain_id, "0x11"); - EXPECT_EQ(GetJsonRpcService()->GetChainId(brave_wallet::mojom::CoinType::ETH, - origin), + EXPECT_EQ(GetJsonRpcService()->GetChainIdSync( + brave_wallet::mojom::CoinType::ETH, origin), "0x11"); } diff --git a/browser/brave_wallet/ethereum_provider_impl_unittest.cc b/browser/brave_wallet/ethereum_provider_impl_unittest.cc index fef243f3aa39..161bd4a1b927 100644 --- a/browser/brave_wallet/ethereum_provider_impl_unittest.cc +++ b/browser/brave_wallet/ethereum_provider_impl_unittest.cc @@ -691,8 +691,8 @@ class EthereumProviderImplUnitTest : public testing::Test { for (const auto& request : requests) { SCOPED_TRACE(request->message); EXPECT_EQ(request->chain_id, - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - GetOrigin())); + json_rpc_service_->GetChainIdSync( + mojom::CoinType::ETH, GetOrigin())); requests_out.push_back(request.Clone()); } run_loop.Quit(); @@ -1128,7 +1128,7 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApproveTransaction) { })); base::RunLoop().RunUntilIdle(); const auto& chain_id = - json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()); std::vector infos = GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); @@ -1280,7 +1280,7 @@ TEST_F(EthereumProviderImplUnitTest, AddAndApprove1559Transaction) { })); browser_task_environment_.RunUntilIdle(); const auto& chain_id = - json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()); std::vector infos = GetAllTransactionInfo(chain_id); ASSERT_EQ(infos.size(), 1UL); @@ -1779,8 +1779,9 @@ TEST_F(EthereumProviderImplUnitTest, RecoverAddress) { } TEST_F(EthereumProviderImplUnitTest, SignTypedMessage) { - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, absl::nullopt), - "0x1"); + EXPECT_EQ( + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, absl::nullopt), + "0x1"); CreateWallet(); AddAccount(); std::string signature; @@ -2145,7 +2146,7 @@ TEST_F(EthereumProviderImplUnitTest, EthSubscribe) { response = CommonRequestOrSendAsync(request_payload.value()); const auto& chain_id = - json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()); + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()); EXPECT_TRUE(provider_->eth_block_tracker_.IsRunning(chain_id)); // The second unsubscribe should stop the block tracker @@ -2518,8 +2519,9 @@ TEST_F(EthereumProviderImplUnitTest, SwitchEthereumChain) { EXPECT_TRUE(brave_wallet_tab_helper()->IsShowingBubble()); brave_wallet_tab_helper()->CloseBubble(); EXPECT_FALSE(brave_wallet_tab_helper()->IsShowingBubble()); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), - "0xaa36a7"); + EXPECT_EQ( + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()), + "0xaa36a7"); // one request per origin base::RunLoop run_loop; @@ -2540,8 +2542,9 @@ TEST_F(EthereumProviderImplUnitTest, SwitchEthereumChain) { l10n_util::GetStringUTF8(IDS_WALLET_ALREADY_IN_PROGRESS_ERROR)); json_rpc_service()->NotifySwitchChainRequestProcessed(true, GetOrigin()); run_loop.Run(); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), - "0x1"); + EXPECT_EQ( + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()), + "0x1"); } TEST_F(EthereumProviderImplUnitTest, AddEthereumChainSwitchesForInnactive) { @@ -2576,8 +2579,9 @@ TEST_F(EthereumProviderImplUnitTest, AddEthereumChainSwitchesForInnactive) { run_loop.Run(); brave_wallet_tab_helper()->CloseBubble(); EXPECT_FALSE(brave_wallet_tab_helper()->IsShowingBubble()); - EXPECT_EQ(json_rpc_service()->GetChainId(mojom::CoinType::ETH, GetOrigin()), - "0x5"); + EXPECT_EQ( + json_rpc_service()->GetChainIdSync(mojom::CoinType::ETH, GetOrigin()), + "0x5"); } TEST_F(EthereumProviderImplUnitTest, AddSuggestToken) { diff --git a/browser/brave_wallet/send_or_sign_transaction_browsertest.cc b/browser/brave_wallet/send_or_sign_transaction_browsertest.cc index 4ab3fd30aabd..6d98eea2d59a 100644 --- a/browser/brave_wallet/send_or_sign_transaction_browsertest.cc +++ b/browser/brave_wallet/send_or_sign_transaction_browsertest.cc @@ -621,7 +621,7 @@ class SendOrSignTransactionBrowserTest : public InProcessBrowserTest { } std::string chain_id(const absl::optional<::url::Origin>& origin) { - return json_rpc_service_->GetChainId(mojom::CoinType::ETH, origin); + return json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, origin); } protected: diff --git a/browser/brave_wallet/solana_provider_impl_unittest.cc b/browser/brave_wallet/solana_provider_impl_unittest.cc index 865d13d48cbc..7a8f08a2c5b8 100644 --- a/browser/brave_wallet/solana_provider_impl_unittest.cc +++ b/browser/brave_wallet/solana_provider_impl_unittest.cc @@ -163,8 +163,8 @@ class SolanaProviderImplUnitTest : public testing::Test { for (const auto& request : requests) { SCOPED_TRACE(request->message); EXPECT_EQ(request->chain_id, - json_rpc_service_->GetChainId(mojom::CoinType::SOL, - GetOrigin())); + json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, GetOrigin())); requests_out.push_back(request.Clone()); } run_loop.Quit(); diff --git a/components/brave_wallet/browser/brave_wallet_service.cc b/components/brave_wallet/browser/brave_wallet_service.cc index b00be1121e4f..83cb7956abb5 100644 --- a/components/brave_wallet/browser/brave_wallet_service.cc +++ b/components/brave_wallet/browser/brave_wallet_service.cc @@ -714,7 +714,7 @@ void BraveWalletService::GetChainIdForActiveOrigin( [](mojom::CoinType coin, GetChainIdForActiveOriginCallback callback, JsonRpcService* json_rpc_service, mojom::OriginInfoPtr origin_info) { std::move(callback).Run( - json_rpc_service->GetChainId(coin, origin_info->origin)); + json_rpc_service->GetChainIdSync(coin, origin_info->origin)); }, coin, std::move(callback), json_rpc_service_)); } diff --git a/components/brave_wallet/browser/eth_tx_manager.cc b/components/brave_wallet/browser/eth_tx_manager.cc index 5c0440b03dee..afbf0ffe04fc 100644 --- a/components/brave_wallet/browser/eth_tx_manager.cc +++ b/components/brave_wallet/browser/eth_tx_manager.cc @@ -720,7 +720,7 @@ void EthTxManager::MakeERC721TransferFromData( } const std::string chain_id = - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt); + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, absl::nullopt); // Check if safeTransferFrom is supported first. json_rpc_service_->GetSupportsInterface( contract_address, kERC721InterfaceId, chain_id, diff --git a/components/brave_wallet/browser/ethereum_provider_impl.cc b/components/brave_wallet/browser/ethereum_provider_impl.cc index bd229ee63bd9..0e4537f608bf 100644 --- a/components/brave_wallet/browser/ethereum_provider_impl.cc +++ b/components/brave_wallet/browser/ethereum_provider_impl.cc @@ -179,8 +179,8 @@ void EthereumProviderImpl::AddEthereumChain(const std::string& json_payload, // Check if we already have the chain if (GetNetworkURL(prefs_, chain_id_lower, mojom::CoinType::ETH).is_valid()) { if (base::CompareCaseInsensitiveASCII( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin()), + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, + delegate_->GetOrigin()), chain_id_lower) != 0) { SwitchEthereumChain(chain_id_lower, std::move(callback), std::move(id)); return; @@ -557,7 +557,7 @@ void EthereumProviderImpl::EthSubscribe( return std::tuple{subscriptions.size() == 1, hex_bytes}; }; - const std::string& chain_id = json_rpc_service_->GetChainId( + const std::string& chain_id = json_rpc_service_->GetChainIdSync( mojom::CoinType::ETH, delegate_->GetOrigin()); if (event_type == kEthSubscribeNewHeads) { const auto gen_res = generateHexBytes(eth_subscriptions_); @@ -606,7 +606,7 @@ bool EthereumProviderImpl::UnsubscribeBlockObserver( bool found = it != eth_subscriptions_.end(); if (found) { if (eth_subscriptions_.size() == 1) { - eth_block_tracker_.Stop(json_rpc_service_->GetChainId( + eth_block_tracker_.Stop(json_rpc_service_->GetChainIdSync( mojom::CoinType::ETH, delegate_->GetOrigin())); } eth_subscriptions_.erase(it); @@ -801,7 +801,7 @@ void EthereumProviderImpl::SignTypedMessage( const std::string chain_id_hex = Uint256ValueToHex((uint256_t)(uint64_t)*chain_id); if (base::CompareCaseInsensitiveASCII( - chain_id_hex, json_rpc_service_->GetChainId( + chain_id_hex, json_rpc_service_->GetChainIdSync( mojom::CoinType::ETH, delegate_->GetOrigin())) != 0) { base::Value formed_response = GetProviderErrorDictionary( @@ -887,8 +887,8 @@ void EthereumProviderImpl::ContinueSignMessage( auto request = mojom::SignMessageRequest::New( MakeOriginInfo(origin), -1, address, domain, message, is_eip712, domain_hash, primary_hash, absl::nullopt, mojom::CoinType::ETH, - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin())); + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, + delegate_->GetOrigin())); brave_wallet_service_->AddSignMessageRequest( std::move(request), @@ -1112,8 +1112,8 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( return; } json_rpc_service_->SendRawTransaction( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin()), + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, + delegate_->GetOrigin()), signed_transaction, base::BindOnce(&EthereumProviderImpl::OnSendRawTransaction, weak_factory_.GetWeakPtr(), std::move(callback), @@ -1195,8 +1195,8 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( std::move(callback), std::move(id)); } else if (method == kWalletWatchAsset || method == kMetamaskWatchAsset) { mojom::BlockchainTokenPtr token; - const auto chain_id = json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin()); + const auto chain_id = json_rpc_service_->GetChainIdSync( + mojom::CoinType::ETH, delegate_->GetOrigin()); if (!ParseWalletWatchAssetParams(normalized_json_request, chain_id, mojom::CoinType::ETH, &token, &error_message)) { @@ -1253,8 +1253,8 @@ void EthereumProviderImpl::CommonRequestOrSendAsync( EthUnsubscribe(subscription_id, std::move(callback), std::move(id)); } else { json_rpc_service_->Request( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, - delegate_->GetOrigin()), + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, + delegate_->GetOrigin()), normalized_json_request, true, std::move(id), mojom::CoinType::ETH, std::move(callback)); } @@ -1546,8 +1546,8 @@ void EthereumProviderImpl::Web3ClientVersion(RequestCallback callback, void EthereumProviderImpl::GetChainId(GetChainIdCallback callback) { if (json_rpc_service_) { - json_rpc_service_->GetChainId(mojom::CoinType::ETH, delegate_->GetOrigin(), - std::move(callback)); + json_rpc_service_->GetChainIdForOrigin( + mojom::CoinType::ETH, delegate_->GetOrigin(), std::move(callback)); } } diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index 712241b59c13..ec7b92ce1519 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -586,7 +586,7 @@ void JsonRpcService::SetNetwork(const std::string& chain_id, void JsonRpcService::GetNetwork(mojom::CoinType coin, const absl::optional<::url::Origin>& origin, GetNetworkCallback callback) { - const auto& chain_id = GetChainId(coin, origin); + const auto& chain_id = GetChainIdSync(coin, origin); std::move(callback).Run(GetChain(prefs_, chain_id, coin)); } @@ -656,17 +656,23 @@ void JsonRpcService::FireNetworkChanged( } } -std::string JsonRpcService::GetChainId( +std::string JsonRpcService::GetChainIdSync( mojom::CoinType coin, const absl::optional<::url::Origin>& origin) const { return GetCurrentChainId(prefs_, coin, origin); } -void JsonRpcService::GetChainId( +void JsonRpcService::GetDefaultChainId( mojom::CoinType coin, - const absl::optional<::url::Origin>& origin, - mojom::JsonRpcService::GetChainIdCallback callback) { - std::move(callback).Run(GetChainId(coin, origin)); + mojom::JsonRpcService::GetDefaultChainIdCallback callback) { + std::move(callback).Run(GetChainIdSync(coin, absl::nullopt)); +} + +void JsonRpcService::GetChainIdForOrigin( + mojom::CoinType coin, + const ::url::Origin& origin, + mojom::JsonRpcService::GetChainIdForOriginCallback callback) { + std::move(callback).Run(GetChainIdSync(coin, origin)); } void JsonRpcService::GetAllNetworks(mojom::CoinType coin, @@ -698,7 +704,7 @@ void JsonRpcService::GetHiddenNetworks(mojom::CoinType coin, // Currently selected chain is never hidden for coin. base::Erase(hidden_networks, - base::ToLowerASCII(GetChainId(coin, absl::nullopt))); + base::ToLowerASCII(GetChainIdSync(coin, absl::nullopt))); std::move(callback).Run(hidden_networks); } @@ -706,7 +712,7 @@ void JsonRpcService::GetHiddenNetworks(mojom::CoinType coin, std::string JsonRpcService::GetNetworkUrl( mojom::CoinType coin, const absl::optional<::url::Origin>& origin) const { - auto network_url = GetNetworkURL(prefs_, GetChainId(coin, origin), coin); + auto network_url = GetNetworkURL(prefs_, GetChainIdSync(coin, origin), coin); if (!network_url.is_valid()) { return std::string(); } @@ -2624,7 +2630,7 @@ bool JsonRpcService::AddSwitchEthereumChainRequest(const std::string& chain_id, } // Already on the chain - if (GetChainId(mojom::CoinType::ETH, origin) == chain_id) { + if (GetChainIdSync(mojom::CoinType::ETH, origin) == chain_id) { reject = false; std::move(callback).Run(std::move(id), base::Value(), reject, "", false); return false; diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 1999bec11f9a..427d68d0d130 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -245,11 +245,15 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { mojom::CoinType coin, RemoveChainCallback callback) override; - std::string GetChainId(mojom::CoinType coin, - const absl::optional<::url::Origin>& origin) const; - void GetChainId(mojom::CoinType coin, - const absl::optional<::url::Origin>& origin, - mojom::JsonRpcService::GetChainIdCallback callback) override; + std::string GetChainIdSync(mojom::CoinType coin, + const absl::optional<::url::Origin>& origin) const; + void GetDefaultChainId( + mojom::CoinType coin, + mojom::JsonRpcService::GetDefaultChainIdCallback callback) override; + void GetChainIdForOrigin( + mojom::CoinType coin, + const ::url::Origin& origin, + mojom::JsonRpcService::GetChainIdForOriginCallback callback) override; void GetPendingAddChainRequests( GetPendingAddChainRequestsCallback callback) override; void GetPendingSwitchChainRequests( diff --git a/components/brave_wallet/browser/json_rpc_service_unittest.cc b/components/brave_wallet/browser/json_rpc_service_unittest.cc index dfd219fd4e19..bfbc988e9b27 100644 --- a/components/brave_wallet/browser/json_rpc_service_unittest.cc +++ b/components/brave_wallet/browser/json_rpc_service_unittest.cc @@ -1062,12 +1062,20 @@ class JsonRpcServiceUnitTest : public testing::Test { const absl::optional<::url::Origin>& origin) { std::string chain_id_out; base::RunLoop run_loop; - json_rpc_service_->GetChainId( - coin, origin, - base::BindLambdaForTesting([&](const std::string& chain_id) { - chain_id_out = chain_id; - run_loop.Quit(); - })); + if (!origin) { + json_rpc_service_->GetDefaultChainId( + coin, base::BindLambdaForTesting([&](const std::string& chain_id) { + chain_id_out = chain_id; + run_loop.Quit(); + })); + } else { + json_rpc_service_->GetChainIdForOrigin( + coin, *origin, + base::BindLambdaForTesting([&](const std::string& chain_id) { + chain_id_out = chain_id; + run_loop.Quit(); + })); + } run_loop.Run(); return chain_id_out; } diff --git a/components/brave_wallet/browser/swap_service.cc b/components/brave_wallet/browser/swap_service.cc index c00636bd8a03..c89ca82484de 100644 --- a/components/brave_wallet/browser/swap_service.cc +++ b/components/brave_wallet/browser/swap_service.cc @@ -303,8 +303,8 @@ void SwapService::IsSwapSupported(const std::string& chain_id, void SwapService::GetPriceQuote(mojom::SwapParamsPtr swap_params, GetPriceQuoteCallback callback) { - if (!IsEVMNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt))) { + if (!IsEVMNetworkSupported(json_rpc_service_->GetChainIdSync( + mojom::CoinType::ETH, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -316,9 +316,9 @@ void SwapService::GetPriceQuote(mojom::SwapParamsPtr swap_params, api_request_helper_.Request( net::HttpRequestHeaders::kGetMethod, - GetPriceQuoteURL( - std::move(swap_params), - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt)), + GetPriceQuoteURL(std::move(swap_params), + json_rpc_service_->GetChainIdSync(mojom::CoinType::ETH, + absl::nullopt)), "", "", true, std::move(internal_callback), Get0xAPIHeaders()); } @@ -347,8 +347,8 @@ void SwapService::OnGetPriceQuote(GetPriceQuoteCallback callback, void SwapService::GetTransactionPayload( mojom::SwapParamsPtr swap_params, GetTransactionPayloadCallback callback) { - if (!IsEVMNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt))) { + if (!IsEVMNetworkSupported(json_rpc_service_->GetChainIdSync( + mojom::CoinType::ETH, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -360,9 +360,9 @@ void SwapService::GetTransactionPayload( api_request_helper_.Request( net::HttpRequestHeaders::kGetMethod, - GetTransactionPayloadURL( - std::move(swap_params), - json_rpc_service_->GetChainId(mojom::CoinType::ETH, absl::nullopt)), + GetTransactionPayloadURL(std::move(swap_params), + json_rpc_service_->GetChainIdSync( + mojom::CoinType::ETH, absl::nullopt)), "", "", true, std::move(internal_callback), Get0xAPIHeaders()); } @@ -392,8 +392,8 @@ void SwapService::OnGetTransactionPayload( void SwapService::GetJupiterQuote(mojom::JupiterQuoteParamsPtr params, GetJupiterQuoteCallback callback) { - if (!IsSolanaNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt))) { + if (!IsSolanaNetworkSupported(json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -409,9 +409,9 @@ void SwapService::GetJupiterQuote(mojom::JupiterQuoteParamsPtr params, base::flat_map request_headers; api_request_helper_.Request( net::HttpRequestHeaders::kGetMethod, - GetJupiterQuoteURL( - std::move(params), - json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt)), + GetJupiterQuoteURL(std::move(params), + json_rpc_service_->GetChainIdSync(mojom::CoinType::SOL, + absl::nullopt)), "", "", true, std::move(internal_callback), request_headers, -1u, std::move(conversion_callback)); } @@ -440,8 +440,8 @@ void SwapService::OnGetJupiterQuote(GetJupiterQuoteCallback callback, void SwapService::GetJupiterSwapTransactions( mojom::JupiterSwapParamsPtr params, GetJupiterSwapTransactionsCallback callback) { - if (!IsSolanaNetworkSupported( - json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt))) { + if (!IsSolanaNetworkSupported(json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, absl::nullopt))) { std::move(callback).Run( nullptr, nullptr, l10n_util::GetStringUTF8(IDS_BRAVE_WALLET_UNSUPPORTED_NETWORK)); @@ -461,8 +461,8 @@ void SwapService::GetJupiterSwapTransactions( api_request_helper_.Request( "POST", - GetJupiterSwapTransactionsURL( - json_rpc_service_->GetChainId(mojom::CoinType::SOL, absl::nullopt)), + GetJupiterSwapTransactionsURL(json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, absl::nullopt)), *encoded_params, "application/json", true, std::move(internal_callback)); } diff --git a/components/brave_wallet/browser/tx_service.cc b/components/brave_wallet/browser/tx_service.cc index 6314bbb47dce..0043ae138838 100644 --- a/components/brave_wallet/browser/tx_service.cc +++ b/components/brave_wallet/browser/tx_service.cc @@ -131,7 +131,7 @@ void TxService::AddUnapprovedTransaction( auto coin_type = GetCoinTypeFromTxDataUnion(*tx_data_union); GetTxManager(coin_type)->AddUnapprovedTransaction( - json_rpc_service_->GetChainId(coin_type, origin), + json_rpc_service_->GetChainIdSync(coin_type, origin), std::move(tx_data_union), from, origin, group_id, std::move(callback)); } diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 064499b8e830..6593c03b8995 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -1079,8 +1079,11 @@ interface JsonRpcService { GetKnownNetworks(CoinType coin) => (array chain_ids); GetHiddenNetworks(CoinType coin) => (array chain_ids); - // Obtains the current network's chain ID - GetChainId(CoinType coin, url.mojom.Origin? origin) => (string chain_id); + // Obtains the default network's chain ID when there is no origin info + // available. Ex. wallet page. + GetDefaultChainId(CoinType coin) => (string chain_id); + // Obtains the selected network's chain ID for origin. + GetChainIdForOrigin(CoinType coin, url.mojom.Origin origin) => (string chain_id); // Obtains the current network's URL GetNetworkUrl(CoinType coin, url.mojom.Origin? origin) diff --git a/components/brave_wallet_ui/common/async/__mocks__/bridge.ts b/components/brave_wallet_ui/common/async/__mocks__/bridge.ts index ecf21f4d868f..342289a9a762 100644 --- a/components/brave_wallet_ui/common/async/__mocks__/bridge.ts +++ b/components/brave_wallet_ui/common/async/__mocks__/bridge.ts @@ -290,7 +290,7 @@ export class MockedWalletApiProxy { getHiddenNetworks: async () => { return { chainIds: [] } }, - getChainId: async (coin) => { + getDefaultChainId: async (coin) => { return { chainId: this.chainIdsForCoins[coin] } }, getNetwork: async (coin) => { diff --git a/components/brave_wallet_ui/common/async/lib.ts b/components/brave_wallet_ui/common/async/lib.ts index a8500c330152..07d42a2b90c6 100644 --- a/components/brave_wallet_ui/common/async/lib.ts +++ b/components/brave_wallet_ui/common/async/lib.ts @@ -861,7 +861,7 @@ export function refreshKeyringInfo () { // Get default accounts for each CoinType const defaultAccounts = await Promise.all(SupportedCoinTypes.map(async (coin: BraveWallet.CoinType) => { - const { chainId } = await jsonRpcService.getChainId(coin, null) + const { chainId } = await jsonRpcService.getDefaultChainId(coin) const defaultAccount = coin === BraveWallet.CoinType.FIL ? await keyringService.getFilecoinSelectedAccount(chainId) : await keyringService.getSelectedAccount(coin) @@ -877,7 +877,7 @@ export function refreshKeyringInfo () { let selectedAccount = { address: null } as { address: string | null } if (selectedCoin === BraveWallet.CoinType.FIL) { - const { chainId } = await jsonRpcService.getChainId(selectedCoin, null) + const { chainId } = await jsonRpcService.getDefaultChainId(selectedCoin) selectedAccount = await keyringService.getFilecoinSelectedAccount( chainId )