From 5b8ea34b7306d534e0e4ef33b84b63775f482741 Mon Sep 17 00:00:00 2001 From: cypt4 <106654560+cypt4@users.noreply.github.com> Date: Tue, 30 Jan 2024 03:26:41 +0700 Subject: [PATCH] Move Zcash protobuf parsing to separate process (#21627) * Move Zcash protobuf parsing to separate process Introduces BraveWalletUtilsService that is able to provide ZCashDecoder to convert protobufs to mojo structs and pass them to the mai. Resolves https://github.com/brave/brave-browser/issues/34561 --- app/brave_generated_resources.grd | 4 + components/brave_wallet/browser/BUILD.gn | 9 +- components/brave_wallet/browser/test/BUILD.gn | 2 + .../browser/zcash/zcash_block_tracker.cc | 10 +- .../browser/zcash/zcash_block_tracker.h | 4 +- .../browser/zcash/zcash_grpc_utils.cc | 29 ---- .../browser/zcash/zcash_grpc_utils.h | 10 -- .../zcash/zcash_grpc_utils_unittest.cc | 1 + .../brave_wallet/browser/zcash/zcash_rpc.cc | 113 +++++-------- .../brave_wallet/browser/zcash/zcash_rpc.h | 47 ++--- .../browser/zcash/zcash_transaction.cc | 16 +- .../browser/zcash/zcash_transaction.h | 4 +- .../browser/zcash/zcash_wallet_service.cc | 27 +-- .../browser/zcash/zcash_wallet_service.h | 11 +- .../zcash/zcash_wallet_service_tasks.cc | 18 +- .../zcash/zcash_wallet_service_tasks.h | 4 +- .../zcash/zcash_wallet_service_unittest.cc | 17 +- components/services/brave_wallet/BUILD.gn | 22 +++ .../brave_wallet_utils_service_impl.cc | 30 ++++ .../brave_wallet_utils_service_impl.h | 39 +++++ .../services/brave_wallet/content/BUILD.gn | 20 +++ components/services/brave_wallet/content/DEPS | 4 + .../brave_wallet_utils_service_launcher.cc | 24 +++ .../brave_wallet_utils_service_launcher.h | 20 +++ .../services/brave_wallet/public/cpp/BUILD.gn | 29 ++++ .../public/cpp/brave_wallet_utils_service.cc | 50 ++++++ .../public/cpp/brave_wallet_utils_service.h | 41 +++++ ...allet_utils_service_in_process_launcher.cc | 29 ++++ ...wallet_utils_service_in_process_launcher.h | 19 +++ .../brave_wallet/public/cpp/utils/BUILD.gn | 13 ++ .../public/cpp/utils/protobuf_utils.cc | 48 ++++++ .../public/cpp/utils/protobuf_utils.h | 25 +++ .../brave_wallet/public/mojom/BUILD.gn | 17 ++ .../mojom/brave_wallet_utils_service.mojom | 15 ++ .../public/mojom/zcash_decoder.mojom | 42 +++++ .../brave_wallet/public/proto/BUILD.gn | 10 ++ .../public/proto}/zcash_grpc_data.proto | 0 .../services/brave_wallet/zcash/BUILD.gn | 38 +++++ .../brave_wallet/zcash/zcash_decoder.cc | 84 +++++++++ .../brave_wallet/zcash/zcash_decoder.h | 39 +++++ .../zcash/zcash_decoder_unittest.cc | 160 ++++++++++++++++++ test/BUILD.gn | 1 + utility/brave_content_utility_client.cc | 12 ++ utility/sources.gni | 2 + 44 files changed, 975 insertions(+), 184 deletions(-) create mode 100644 components/services/brave_wallet/BUILD.gn create mode 100644 components/services/brave_wallet/brave_wallet_utils_service_impl.cc create mode 100644 components/services/brave_wallet/brave_wallet_utils_service_impl.h create mode 100644 components/services/brave_wallet/content/BUILD.gn create mode 100644 components/services/brave_wallet/content/DEPS create mode 100644 components/services/brave_wallet/content/brave_wallet_utils_service_launcher.cc create mode 100644 components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h create mode 100644 components/services/brave_wallet/public/cpp/BUILD.gn create mode 100644 components/services/brave_wallet/public/cpp/brave_wallet_utils_service.cc create mode 100644 components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h create mode 100644 components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.cc create mode 100644 components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h create mode 100644 components/services/brave_wallet/public/cpp/utils/BUILD.gn create mode 100644 components/services/brave_wallet/public/cpp/utils/protobuf_utils.cc create mode 100644 components/services/brave_wallet/public/cpp/utils/protobuf_utils.h create mode 100644 components/services/brave_wallet/public/mojom/BUILD.gn create mode 100644 components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom create mode 100644 components/services/brave_wallet/public/mojom/zcash_decoder.mojom create mode 100644 components/services/brave_wallet/public/proto/BUILD.gn rename components/{brave_wallet/browser/zcash/protos => services/brave_wallet/public/proto}/zcash_grpc_data.proto (100%) create mode 100644 components/services/brave_wallet/zcash/BUILD.gn create mode 100644 components/services/brave_wallet/zcash/zcash_decoder.cc create mode 100644 components/services/brave_wallet/zcash/zcash_decoder.h create mode 100644 components/services/brave_wallet/zcash/zcash_decoder_unittest.cc diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index f8609d5c292f..c0ed468d6a21 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -898,6 +898,10 @@ Or change later at $2brave://settings/ext Cancel + + + Brave Wallet Utility Service + diff --git a/components/brave_wallet/browser/BUILD.gn b/components/brave_wallet/browser/BUILD.gn index 3641df4d2597..5a8241057f0d 100644 --- a/components/brave_wallet/browser/BUILD.gn +++ b/components/brave_wallet/browser/BUILD.gn @@ -250,7 +250,6 @@ static_library("browser") { ":pref_names", ":transaction", ":utils", - ":zcash_proto", "//base", "//brave/components/brave_component_updater/browser", "//brave/components/brave_stats/browser", @@ -267,6 +266,10 @@ static_library("browser") { "//brave/components/json/rs:rust_lib", "//brave/components/p3a_utils", "//brave/components/resources:strings_grit", + "//brave/components/services/brave_wallet/public/cpp", + "//brave/components/services/brave_wallet/public/cpp/utils", + "//brave/components/services/brave_wallet/public/mojom", + "//brave/components/services/brave_wallet/public/proto:zcash_proto", "//brave/third_party/argon2", "//components/component_updater", "//components/content_settings/core/browser", @@ -490,10 +493,6 @@ generated_types("generated_swap_responses") { ] } -proto_library("zcash_proto") { - sources = [ "zcash/protos/zcash_grpc_data.proto" ] -} - config("sardine_config") { defines = [ "SARDINE_CLIENT_ID=\"$sardine_client_id\"", diff --git a/components/brave_wallet/browser/test/BUILD.gn b/components/brave_wallet/browser/test/BUILD.gn index 0915b08cc281..829cc0ceb735 100644 --- a/components/brave_wallet/browser/test/BUILD.gn +++ b/components/brave_wallet/browser/test/BUILD.gn @@ -135,6 +135,8 @@ source_set("brave_wallet_unit_tests") { "//brave/components/ipfs", "//brave/components/json/rs:rust_lib", "//brave/components/resources:strings_grit", + "//brave/components/services/brave_wallet/public/cpp/utils", + "//brave/components/services/brave_wallet/public/mojom", "//components/component_updater:test_support", "//components/permissions", "//components/prefs", diff --git a/components/brave_wallet/browser/zcash/zcash_block_tracker.cc b/components/brave_wallet/browser/zcash/zcash_block_tracker.cc index f0915b6e29d9..627fdacdd4e3 100644 --- a/components/brave_wallet/browser/zcash/zcash_block_tracker.cc +++ b/components/brave_wallet/browser/zcash/zcash_block_tracker.cc @@ -48,18 +48,18 @@ std::optional ZCashBlockTracker::GetLatestHeight( void ZCashBlockTracker::OnGetLatestBlockForHeight( const std::string& chain_id, - base::expected latest_block) { - if (!latest_block.has_value()) { + base::expected latest_block) { + if (!latest_block.has_value() || !latest_block.value()) { return; } auto cur_latest_height = GetLatestHeight(chain_id); if (cur_latest_height && - cur_latest_height.value() == latest_block->height()) { + cur_latest_height.value() == (*latest_block)->height) { return; } - latest_height_map_[chain_id] = latest_block->height(); + latest_height_map_[chain_id] = (*latest_block)->height; for (auto& observer : observers_) { - observer.OnLatestHeightUpdated(chain_id, latest_block->height()); + observer.OnLatestHeightUpdated(chain_id, (*latest_block)->height); } } diff --git a/components/brave_wallet/browser/zcash/zcash_block_tracker.h b/components/brave_wallet/browser/zcash/zcash_block_tracker.h index 27b1313bb90a..3d87a2044fdc 100644 --- a/components/brave_wallet/browser/zcash/zcash_block_tracker.h +++ b/components/brave_wallet/browser/zcash/zcash_block_tracker.h @@ -15,7 +15,7 @@ #include "base/time/time.h" #include "base/types/expected.h" #include "brave/components/brave_wallet/browser/block_tracker.h" -#include "brave/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.pb.h" +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" namespace brave_wallet { @@ -44,7 +44,7 @@ class ZCashBlockTracker : public BlockTracker { void GetBlockHeight(const std::string& chain_id); void OnGetLatestBlockForHeight( const std::string& chain_id, - base::expected latest_height); + base::expected latest_height); // std::map latest_height_map_; diff --git a/components/brave_wallet/browser/zcash/zcash_grpc_utils.cc b/components/brave_wallet/browser/zcash/zcash_grpc_utils.cc index 16822ca7c3ef..5ae5a30522ee 100644 --- a/components/brave_wallet/browser/zcash/zcash_grpc_utils.cc +++ b/components/brave_wallet/browser/zcash/zcash_grpc_utils.cc @@ -18,35 +18,6 @@ constexpr size_t kGrpcHeaderSize = 5; constexpr char kNoCompression = 0; } // namespace -std::string GetPrefixedProtobuf(const std::string& serialized_proto) { - std::string result(kGrpcHeaderSize, 0); - result[0] = kNoCompression; - base::WriteBigEndian(&result[1], serialized_proto.size()); - result.append(serialized_proto); - return result; -} - -// Resolves serialized protobuf from length-prefixed string -std::optional ResolveSerializedMessage( - const std::string& grpc_response_body) { - if (grpc_response_body.size() < kGrpcHeaderSize) { - return std::nullopt; - } - if (grpc_response_body[0] != kNoCompression) { - // Compression is not supported yet - return std::nullopt; - } - uint32_t size = 0; - base::ReadBigEndian( - reinterpret_cast(&(grpc_response_body[1])), &size); - - if (grpc_response_body.size() != size + kGrpcHeaderSize) { - return std::nullopt; - } - - return grpc_response_body.substr(kGrpcHeaderSize); -} - GRrpcMessageStreamHandler::GRrpcMessageStreamHandler() = default; GRrpcMessageStreamHandler::~GRrpcMessageStreamHandler() = default; diff --git a/components/brave_wallet/browser/zcash/zcash_grpc_utils.h b/components/brave_wallet/browser/zcash/zcash_grpc_utils.h index 924a4fe3e159..f8d09c33dcc0 100644 --- a/components/brave_wallet/browser/zcash/zcash_grpc_utils.h +++ b/components/brave_wallet/browser/zcash/zcash_grpc_utils.h @@ -6,7 +6,6 @@ #ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ZCASH_ZCASH_GRPC_UTILS_H_ #define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ZCASH_ZCASH_GRPC_UTILS_H_ -#include #include #include @@ -14,15 +13,6 @@ namespace brave_wallet { -// Resolves serialized protobuf from length-prefixed string -std::optional ResolveSerializedMessage( - const std::string& grpc_response_body); - -// Prefixes provided serialized protobuf with compression byte and 4 bytes of -// message size. See -// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md -std::string GetPrefixedProtobuf(const std::string& serialized_proto); - // Handles a stream of GRPC objects class GRrpcMessageStreamHandler : public network::SimpleURLLoaderStreamConsumer { diff --git a/components/brave_wallet/browser/zcash/zcash_grpc_utils_unittest.cc b/components/brave_wallet/browser/zcash/zcash_grpc_utils_unittest.cc index ddde406b5097..00f911fb6846 100644 --- a/components/brave_wallet/browser/zcash/zcash_grpc_utils_unittest.cc +++ b/components/brave_wallet/browser/zcash/zcash_grpc_utils_unittest.cc @@ -14,6 +14,7 @@ #include "base/functional/callback.h" #include "base/strings/strcat.h" #include "base/test/bind.h" +#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace brave_wallet { diff --git a/components/brave_wallet/browser/zcash/zcash_rpc.cc b/components/brave_wallet/browser/zcash/zcash_rpc.cc index d5697e13a012..fce78324a818 100644 --- a/components/brave_wallet/browser/zcash/zcash_rpc.cc +++ b/components/brave_wallet/browser/zcash/zcash_rpc.cc @@ -8,6 +8,9 @@ #include "base/functional/bind.h" #include "brave/components/brave_wallet/browser/brave_wallet_utils.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" +#include "brave/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h" +#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h" +#include "brave/components/services/brave_wallet/public/proto/zcash_grpc_data.pb.h" #include "components/grit/brave_components_strings.h" #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" @@ -319,10 +322,9 @@ void ZCashRpc::GetTransaction(const std::string& chain_id, 5000); } -void ZCashRpc::OnGetUtxosResponse( - ZCashRpc::GetUtxoListCallback callback, - UrlLoadersList::iterator it, - const std::unique_ptr response_body) { +void ZCashRpc::OnGetUtxosResponse(ZCashRpc::GetUtxoListCallback callback, + UrlLoadersList::iterator it, + std::unique_ptr response_body) { auto current_loader = std::move(*it); url_loaders_list_.erase(it); if (current_loader->NetError()) { @@ -337,35 +339,32 @@ void ZCashRpc::OnGetUtxosResponse( return; } - auto message = ResolveSerializedMessage(*response_body); - if (!message) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } + GetDecoder()->ParseGetAddressUtxos( + *response_body, + base::BindOnce( + &ZCashRpc::OnParseResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} - zcash::GetAddressUtxosResponse response; - if (!response.ParseFromString(message.value())) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); +template +void ZCashRpc::OnParseResult( + base::OnceCallback)> callback, + T value) { + if (value) { + std::move(callback).Run(std::move(value)); return; } - std::vector result; - for (const auto& item : response.addressutxos()) { - result.push_back(item); - } - - std::move(callback).Run(result); + std::move(callback).Run( + base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); } void ZCashRpc::OnGetLatestBlockResponse( ZCashRpc::GetLatestBlockCallback callback, UrlLoadersList::iterator it, - const std::unique_ptr response_body) { + std::unique_ptr response_body) { auto current_loader = std::move(*it); url_loaders_list_.erase(it); - zcash::BlockID response; if (current_loader->NetError()) { std::move(callback).Run( base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); @@ -378,29 +377,18 @@ void ZCashRpc::OnGetLatestBlockResponse( return; } - auto message = ResolveSerializedMessage(*response_body); - if (!message) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - if (!response.ParseFromString(message.value())) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - std::move(callback).Run(response); + GetDecoder()->ParseBlockID( + *response_body, + base::BindOnce(&ZCashRpc::OnParseResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void ZCashRpc::OnGetTransactionResponse( ZCashRpc::GetTransactionCallback callback, UrlLoadersList::iterator it, - const std::unique_ptr response_body) { + std::unique_ptr response_body) { auto current_loader = std::move(*it); url_loaders_list_.erase(it); - zcash::RawTransaction response; if (current_loader->NetError()) { std::move(callback).Run( base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); @@ -413,20 +401,10 @@ void ZCashRpc::OnGetTransactionResponse( return; } - auto message = ResolveSerializedMessage(*response_body); - if (!message) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - if (!response.ParseFromString(message.value())) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - std::move(callback).Run(response); + GetDecoder()->ParseRawTransaction( + *response_body, + base::BindOnce(&ZCashRpc::OnParseResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void ZCashRpc::SendTransaction(const std::string& chain_id, @@ -488,10 +466,9 @@ void ZCashRpc::IsKnownAddress(const std::string& chain_id, void ZCashRpc::OnSendTransactionResponse( ZCashRpc::SendTransactionCallback callback, UrlLoadersList::iterator it, - const std::unique_ptr response_body) { + std::unique_ptr response_body) { auto current_loader = std::move(*it); url_loaders_list_.erase(it); - zcash::SendResponse response; if (current_loader->NetError()) { std::move(callback).Run( base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); @@ -504,20 +481,10 @@ void ZCashRpc::OnSendTransactionResponse( return; } - auto message = ResolveSerializedMessage(*response_body); - if (!message) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - if (!response.ParseFromString(message.value())) { - std::move(callback).Run( - base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); - return; - } - - std::move(callback).Run(response); + GetDecoder()->ParseSendResponse( + *response_body, + base::BindOnce(&ZCashRpc::OnParseResult, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void ZCashRpc::OnGetAddressTxResponse( @@ -540,4 +507,14 @@ void ZCashRpc::OnGetAddressTxResponse( std::move(callback).Run(result.value()); } +mojo::AssociatedRemote& ZCashRpc::GetDecoder() { + if (zcash_decoder_.is_bound()) { + return zcash_decoder_; + } + BraveWalletUtilsService::GetInstance()->CreateZCashDecoder( + zcash_decoder_.BindNewEndpointAndPassReceiver()); + zcash_decoder_.reset_on_disconnect(); + return zcash_decoder_; +} + } // namespace brave_wallet diff --git a/components/brave_wallet/browser/zcash/zcash_rpc.h b/components/brave_wallet/browser/zcash/zcash_rpc.h index d9a29684bf5a..9562b28b3326 100644 --- a/components/brave_wallet/browser/zcash/zcash_rpc.h +++ b/components/brave_wallet/browser/zcash/zcash_rpc.h @@ -15,9 +15,12 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" #include "base/types/expected.h" -#include "brave/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.pb.h" #include "brave/components/brave_wallet/browser/zcash/zcash_grpc_utils.h" +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" #include "components/prefs/pref_service.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/cpp/simple_url_loader_stream_consumer.h" @@ -28,15 +31,15 @@ namespace brave_wallet { class ZCashRpc { public: using GetUtxoListCallback = base::OnceCallback, std::string>)>; + base::expected)>; using GetLatestBlockCallback = - base::OnceCallback)>; + base::OnceCallback)>; using GetTransactionCallback = base::OnceCallback)>; + base::expected)>; using SendTransactionCallback = base::OnceCallback)>; + base::expected)>; using GetTransactionsCallback = base::OnceCallback)>; + base::expected)>; using IsKnownAddressCallback = base::OnceCallback)>; @@ -74,32 +77,38 @@ class ZCashRpc { void OnGetUtxosResponse(ZCashRpc::GetUtxoListCallback callback, UrlLoadersList::iterator it, - const std::unique_ptr response_body); + std::unique_ptr response_body); - void OnGetLatestBlockResponse( - ZCashRpc::GetLatestBlockCallback callback, - UrlLoadersList::iterator it, - const std::unique_ptr response_body); + void OnGetLatestBlockResponse(ZCashRpc::GetLatestBlockCallback callback, + UrlLoadersList::iterator it, + std::unique_ptr response_body); - void OnGetTransactionResponse( - ZCashRpc::GetTransactionCallback callback, - UrlLoadersList::iterator it, - const std::unique_ptr response_body); + void OnGetTransactionResponse(ZCashRpc::GetTransactionCallback callback, + UrlLoadersList::iterator it, + std::unique_ptr response_body); - void OnSendTransactionResponse( - ZCashRpc::SendTransactionCallback callback, - UrlLoadersList::iterator it, - const std::unique_ptr response_body); + void OnSendTransactionResponse(ZCashRpc::SendTransactionCallback callback, + UrlLoadersList::iterator it, + std::unique_ptr response_body); void OnGetAddressTxResponse(ZCashRpc::IsKnownAddressCallback callback, UrlLoadersList::iterator it, StreamHandlersList::iterator handler_it, base::expected result); + template + void OnParseResult(base::OnceCallback)>, + T value); + + mojo::AssociatedRemote& GetDecoder(); + UrlLoadersList url_loaders_list_; StreamHandlersList stream_handlers_list_; raw_ptr prefs_ = nullptr; scoped_refptr url_loader_factory_ = nullptr; + + mojo::AssociatedRemote zcash_decoder_; + base::WeakPtrFactory weak_ptr_factory_{this}; }; diff --git a/components/brave_wallet/browser/zcash/zcash_transaction.cc b/components/brave_wallet/browser/zcash/zcash_transaction.cc index 0601978c5943..14fac2632b4a 100644 --- a/components/brave_wallet/browser/zcash/zcash_transaction.cc +++ b/components/brave_wallet/browser/zcash/zcash_transaction.cc @@ -218,20 +218,20 @@ std::optional ZCashTransaction::TxInput::FromValue( // static std::optional ZCashTransaction::TxInput::FromRpcUtxo( const std::string& address, - const zcash::ZCashUtxo& utxo) { - if (address != utxo.address()) { + const mojom::ZCashUtxo& utxo) { + if (address != utxo.address) { return std::nullopt; } ZCashTransaction::TxInput result; - result.utxo_address = utxo.address(); + result.utxo_address = utxo.address; result.script_pub_key.insert(result.script_pub_key.begin(), - utxo.script().begin(), utxo.script().end()); - if (utxo.txid().size() != 32) { + utxo.script.begin(), utxo.script.end()); + if (utxo.tx_id.size() != 32) { return std::nullopt; } - std::copy_n(utxo.txid().begin(), 32, result.utxo_outpoint.txid.begin()); - result.utxo_outpoint.index = utxo.index(); - result.utxo_value = utxo.valuezat(); + std::copy_n(utxo.tx_id.begin(), 32, result.utxo_outpoint.txid.begin()); + result.utxo_outpoint.index = utxo.index; + result.utxo_value = utxo.value_zat; return result; } diff --git a/components/brave_wallet/browser/zcash/zcash_transaction.h b/components/brave_wallet/browser/zcash/zcash_transaction.h index 34d2bdcc76eb..6eda8cd22034 100644 --- a/components/brave_wallet/browser/zcash/zcash_transaction.h +++ b/components/brave_wallet/browser/zcash/zcash_transaction.h @@ -12,8 +12,8 @@ #include #include -#include "brave/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.pb.h" #include "brave/components/brave_wallet/common/hash_utils.h" +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" namespace brave_wallet { @@ -51,7 +51,7 @@ class ZCashTransaction { static std::optional FromValue(const base::Value::Dict& value); static std::optional FromRpcUtxo(const std::string& address, - const zcash::ZCashUtxo& utxo); + const mojom::ZCashUtxo& utxo); std::string utxo_address; Outpoint utxo_outpoint; diff --git a/components/brave_wallet/browser/zcash/zcash_wallet_service.cc b/components/brave_wallet/browser/zcash/zcash_wallet_service.cc index 2da00cd02762..69862d8b2d8b 100644 --- a/components/brave_wallet/browser/zcash/zcash_wallet_service.cc +++ b/components/brave_wallet/browser/zcash/zcash_wallet_service.cc @@ -268,15 +268,15 @@ void ZCashWalletService::OnResolveLastBlockHeightForSendTransaction( const mojom::AccountIdPtr& account_id, ZCashTransaction zcash_transaction, SignAndPostTransactionCallback callback, - base::expected result) { - if (!result.has_value()) { + base::expected result) { + if (!result.has_value() || !result.value()) { std::move(callback).Run( "", std::move(zcash_transaction), l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); return; } - zcash_transaction.set_expiry_height(result->height() + + zcash_transaction.set_expiry_height((*result)->height + kDefaultBlockHeightDelta); if (!SignTransactionInternal(zcash_transaction, account_id)) { @@ -298,8 +298,8 @@ void ZCashWalletService::OnResolveLastBlockHeightForSendTransaction( void ZCashWalletService::OnSendTransactionResult( SignAndPostTransactionCallback callback, ZCashTransaction tx, - base::expected result) { - if (result.has_value() && result->errorcode() == 0) { + base::expected result) { + if (result.has_value() && result.value() && (*result)->error_code == 0) { auto tx_id = ZCashSerializer::CalculateTxIdDigest(tx); auto tx_id_hex = ToHex(tx_id); CHECK(tx_id_hex.starts_with("0x")); @@ -313,18 +313,18 @@ void ZCashWalletService::OnSendTransactionResult( void ZCashWalletService::OnGetUtxos( scoped_refptr context, const std::string& address, - base::expected, std::string> result) { + base::expected result) { DCHECK(context->addresses.contains(address)); DCHECK(!context->utxos.contains(address)); - if (!result.has_value()) { + if (!result.has_value() || !result.value()) { context->SetError(result.error()); WorkOnGetUtxos(std::move(context)); return; } context->addresses.erase(address); - context->utxos[address] = result.value(); + context->utxos[address] = std::move(result.value()->address_utxos); WorkOnGetUtxos(std::move(context)); } @@ -350,7 +350,8 @@ void ZCashWalletService::OnDiscoveryDoneForBalance( GetBalanceCallback callback, RunDiscoveryResult discovery_result) { if (!discovery_result.has_value()) { - std::move(callback).Run(nullptr, "Failed to fetch balance"); + std::move(callback).Run( + nullptr, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); return; } GetUtxos(chain_id, std::move(account_id), @@ -371,7 +372,7 @@ void ZCashWalletService::OnUtxosResolvedForBalance( for (const auto& by_addr : utxos.value()) { uint64_t balance_by_addr = 0; for (const auto& by_utxo : by_addr.second) { - balance_by_addr += by_utxo.valuezat(); + balance_by_addr += by_utxo->value_zat; } result->total_balance += balance_by_addr; result->balances[by_addr.first] = balance_by_addr; @@ -415,13 +416,13 @@ void ZCashWalletService::GetTransactionStatus( void ZCashWalletService::OnTransactionResolvedForStatus( GetTransactionStatusCallback callback, - base::expected result) { - if (!result.has_value()) { + base::expected result) { + if (!result.has_value() || !result.value()) { std::move(callback).Run(base::unexpected(result.error())); return; } - std::move(callback).Run(result.value().height() > 0); + std::move(callback).Run((*result)->height > 0); } void ZCashWalletService::CreateTransactionTaskDone( diff --git a/components/brave_wallet/browser/zcash/zcash_wallet_service.h b/components/brave_wallet/browser/zcash/zcash_wallet_service.h index 9f000ad9e86f..2f565609e2b9 100644 --- a/components/brave_wallet/browser/zcash/zcash_wallet_service.h +++ b/components/brave_wallet/browser/zcash/zcash_wallet_service.h @@ -17,7 +17,6 @@ #include "base/types/expected.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/brave_wallet/browser/keyring_service_observer_base.h" -#include "brave/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.pb.h" #include "brave/components/brave_wallet/browser/zcash/zcash_rpc.h" #include "brave/components/brave_wallet/browser/zcash/zcash_transaction.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" @@ -32,7 +31,7 @@ class ZCashWalletService : public KeyedService, public mojom::ZCashWalletService, KeyringServiceObserverBase { public: - using UtxoMap = std::map>; + using UtxoMap = std::map>; using RunDiscoveryResult = base::expected, std::string>; using GetUtxosCallback = @@ -122,7 +121,7 @@ class ZCashWalletService : public KeyedService, void OnGetUtxos( scoped_refptr context, const std::string& current_address, - base::expected, std::string> result); + base::expected result); void WorkOnGetUtxos(scoped_refptr context); void OnDiscoveryDoneForBalance(mojom::AccountIdPtr account_id, @@ -133,19 +132,19 @@ class ZCashWalletService : public KeyedService, base::expected result); void OnTransactionResolvedForStatus( GetTransactionStatusCallback callback, - base::expected result); + base::expected result); void OnResolveLastBlockHeightForSendTransaction( const std::string& chain_id, const mojom::AccountIdPtr& account_id, ZCashTransaction zcash_transaction, SignAndPostTransactionCallback callback, - base::expected result); + base::expected result); void OnSendTransactionResult( SignAndPostTransactionCallback callback, ZCashTransaction zcash_transaction, - base::expected result); + base::expected result); void CreateTransactionTaskDone(CreateTransparentTransactionTask* task); diff --git a/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.cc b/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.cc index a3b740b9c0ee..ae9fb293520e 100644 --- a/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.cc +++ b/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.cc @@ -128,14 +128,14 @@ void DiscoverNextUnusedZCashAddressTask::WorkOnTask() { } void DiscoverNextUnusedZCashAddressTask::OnGetLastBlock( - base::expected result) { - if (!result.has_value()) { + base::expected result) { + if (!result.has_value() || !result.value()) { error_ = result.error(); WorkOnTask(); return; } - block_end_ = result.value().height(); + block_end_ = (*result)->height; WorkOnTask(); } @@ -237,14 +237,14 @@ void CreateTransparentTransactionTask::WorkOnTask() { } void CreateTransparentTransactionTask::OnGetChainHeight( - base::expected result) { - if (!result.has_value()) { + base::expected result) { + if (!result.has_value() || !result.value()) { SetError(std::move(result).error()); WorkOnTask(); return; } - chain_height_ = result.value().height(); + chain_height_ = (*result)->height; WorkOnTask(); } @@ -281,8 +281,12 @@ bool CreateTransparentTransactionTask::PickInputs() { std::vector all_inputs; for (const auto& item : utxo_map_) { for (const auto& utxo : item.second) { + if (!utxo) { + error_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + return false; + } if (auto input = - ZCashTransaction::TxInput::FromRpcUtxo(item.first, utxo)) { + ZCashTransaction::TxInput::FromRpcUtxo(item.first, *utxo)) { all_inputs.emplace_back(std::move(*input)); } } diff --git a/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.h b/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.h index 25ba5c822924..7468fd1993b7 100644 --- a/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.h +++ b/components/brave_wallet/browser/zcash/zcash_wallet_service_tasks.h @@ -54,7 +54,7 @@ class DiscoverNextUnusedZCashAddressTask void WorkOnTask(); void OnGetIsKnownAddress(base::expected stats); - void OnGetLastBlock(base::expected result); + void OnGetLastBlock(base::expected result); base::WeakPtr zcash_wallet_service_; mojom::AccountIdPtr account_id_; @@ -91,7 +91,7 @@ class CreateTransparentTransactionTask { bool PickInputs(); bool PrepareOutputs(); - void OnGetChainHeight(base::expected result); + void OnGetChainHeight(base::expected result); void OnGetUtxos( base::expected utxo_map); void OnGetChangeAddress( diff --git a/components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc b/components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc index e91a27db953d..11a5602dbb9e 100644 --- a/components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc +++ b/components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc @@ -25,6 +25,7 @@ #include "brave/components/brave_wallet/common/features.h" #include "brave/components/brave_wallet/common/hex_utils.h" #include "brave/components/brave_wallet/common/zcash_utils.h" +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -179,8 +180,8 @@ TEST_F(ZCashWalletServiceUnitTest, SignAndPostTransaction) { .WillByDefault( ::testing::Invoke([](const std::string& chain_id, ZCashRpc::GetLatestBlockCallback callback) { - zcash::BlockID response; - response.set_height(2286687); + mojom::BlockIDPtr response = mojom::BlockID::New(); + response->height = 2286687; std::move(callback).Run(std::move(response)); })); @@ -200,8 +201,8 @@ TEST_F(ZCashWalletServiceUnitTest, SignAndPostTransaction) { .WillOnce([&](const std::string& chain_id, const std::string& data, ZCashRpc::SendTransactionCallback callback) { captured_data = data; - zcash::SendResponse response; - response.set_errorcode(0); + mojom::SendResponsePtr response = mojom::SendResponse::New(); + response->error_code = 0; std::move(callback).Run(std::move(response)); }); zcash_wallet_service_->SignAndPostTransaction( @@ -232,8 +233,8 @@ TEST_F(ZCashWalletServiceUnitTest, AddressDiscovery) { .WillByDefault( ::testing::Invoke([](const std::string& chain_id, ZCashRpc::GetLatestBlockCallback callback) { - zcash::BlockID response; - response.set_height(2286687); + mojom::BlockIDPtr response = mojom::BlockID::New(); + response->height = 2286687; std::move(callback).Run(std::move(response)); })); @@ -347,8 +348,8 @@ TEST_F(ZCashWalletServiceUnitTest, AddressDiscovery_FromPrefs) { .WillByDefault( ::testing::Invoke([](const std::string& chain_id, ZCashRpc::GetLatestBlockCallback callback) { - zcash::BlockID response; - response.set_height(2286687); + mojom::BlockIDPtr response = mojom::BlockID::New(); + response->height = 2286687; std::move(callback).Run(std::move(response)); })); diff --git a/components/services/brave_wallet/BUILD.gn b/components/services/brave_wallet/BUILD.gn new file mode 100644 index 000000000000..4d9f06ece78a --- /dev/null +++ b/components/services/brave_wallet/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +source_set("lib") { + visibility = [ + "//brave/components/services/brave_wallet/public/cpp", + "//chrome/utility:*", + ] + + sources = [ + "brave_wallet_utils_service_impl.cc", + "brave_wallet_utils_service_impl.h", + ] + + deps = [ + "//brave/components/services/brave_wallet/public/mojom", + "//brave/components/services/brave_wallet/zcash:zcash_decoder", + "//mojo/public/cpp/system", + ] +} diff --git a/components/services/brave_wallet/brave_wallet_utils_service_impl.cc b/components/services/brave_wallet/brave_wallet_utils_service_impl.cc new file mode 100644 index 000000000000..e34ed0f59fd8 --- /dev/null +++ b/components/services/brave_wallet/brave_wallet_utils_service_impl.cc @@ -0,0 +1,30 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/brave_wallet_utils_service_impl.h" + +#include +#include + +#include "brave/components/services/brave_wallet/zcash/zcash_decoder.h" + +namespace brave_wallet { + +BraveWalletUtilsServiceImpl::BraveWalletUtilsServiceImpl( + mojo::PendingReceiver receiver) + : receiver_(this, std::move(receiver)) {} + +BraveWalletUtilsServiceImpl::~BraveWalletUtilsServiceImpl() = default; + +void BraveWalletUtilsServiceImpl::CreateZCashDecoderService( + mojo::PendingAssociatedReceiver + zcash_decoder_receiver) { + if (!instance_) { + instance_ = mojo::MakeSelfOwnedAssociatedReceiver( + std::make_unique(), std::move(zcash_decoder_receiver)); + } +} + +} // namespace brave_wallet diff --git a/components/services/brave_wallet/brave_wallet_utils_service_impl.h b/components/services/brave_wallet/brave_wallet_utils_service_impl.h new file mode 100644 index 000000000000..4de96489216e --- /dev/null +++ b/components/services/brave_wallet/brave_wallet_utils_service_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_BRAVE_WALLET_UTILS_SERVICE_IMPL_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_BRAVE_WALLET_UTILS_SERVICE_IMPL_H_ + +#include "brave/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom.h" +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h" + +namespace brave_wallet { + +class BraveWalletUtilsServiceImpl : public mojom::BraveWalletUtilsService { + public: + explicit BraveWalletUtilsServiceImpl( + mojo::PendingReceiver receiver); + + ~BraveWalletUtilsServiceImpl() override; + + BraveWalletUtilsServiceImpl(const BraveWalletUtilsServiceImpl&) = delete; + BraveWalletUtilsServiceImpl& operator=(const BraveWalletUtilsServiceImpl&) = + delete; + + void CreateZCashDecoderService( + mojo::PendingAssociatedReceiver + zcash_decoder_receiver) override; + + private: + mojo::Receiver receiver_; + mojo::SelfOwnedAssociatedReceiverRef instance_; +}; + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_BRAVE_WALLET_UTILS_SERVICE_IMPL_H_ diff --git a/components/services/brave_wallet/content/BUILD.gn b/components/services/brave_wallet/content/BUILD.gn new file mode 100644 index 000000000000..0d391fe1099c --- /dev/null +++ b/components/services/brave_wallet/content/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +source_set("content") { + visibility = [ "//brave/components/services/brave_wallet/public/cpp" ] + + sources = [ + "brave_wallet_utils_service_launcher.cc", + "brave_wallet_utils_service_launcher.h", + ] + + deps = [ + "//brave/app:brave_generated_resources_grit", + "//brave/components/services/brave_wallet/public/mojom", + "//content/public/browser", + "//mojo/public/cpp/bindings", + ] +} diff --git a/components/services/brave_wallet/content/DEPS b/components/services/brave_wallet/content/DEPS new file mode 100644 index 000000000000..435980ed55d6 --- /dev/null +++ b/components/services/brave_wallet/content/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/browser", +] + diff --git a/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.cc b/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.cc new file mode 100644 index 000000000000..074e13484c8e --- /dev/null +++ b/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.cc @@ -0,0 +1,24 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h" + +#include + +#include "brave/grit/brave_generated_resources.h" +#include "content/public/browser/service_process_host.h" + +namespace brave_wallet { + +void LaunchBraveWalletUtilsService( + mojo::PendingReceiver receiver) { + content::ServiceProcessHost::Launch( + std::move(receiver), + content::ServiceProcessHost::Options() + .WithDisplayName(IDS_UTILITY_PROCESS_WALLET_UTILS_NAME) + .Pass()); +} + +} // namespace brave_wallet diff --git a/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h b/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h new file mode 100644 index 000000000000..686e337cf007 --- /dev/null +++ b/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ + +#include "mojo/public/cpp/bindings/pending_receiver.h" + +#include "brave/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom.h" + +namespace brave_wallet { + +void LaunchBraveWalletUtilsService( + mojo::PendingReceiver receiver); + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ diff --git a/components/services/brave_wallet/public/cpp/BUILD.gn b/components/services/brave_wallet/public/cpp/BUILD.gn new file mode 100644 index 000000000000..f6e732258174 --- /dev/null +++ b/components/services/brave_wallet/public/cpp/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +source_set("cpp") { + visibility = [ + "//brave/components/brave_wallet/browser:*", + "//chrome/utility:*", + ] + + sources = [ + "brave_wallet_utils_service.cc", + "brave_wallet_utils_service.h", + "brave_wallet_utils_service_in_process_launcher.cc", + "brave_wallet_utils_service_in_process_launcher.h", + ] + + deps = [ + "//brave/components/services/brave_wallet:lib", + "//brave/components/services/brave_wallet/public/mojom", + "//brave/components/services/brave_wallet/zcash:zcash_decoder", + "//mojo/public/cpp/bindings", + ] + + if (!is_ios) { + deps += [ "//brave/components/services/brave_wallet/content" ] + } +} diff --git a/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.cc b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.cc new file mode 100644 index 000000000000..76fe4e042e1e --- /dev/null +++ b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.cc @@ -0,0 +1,50 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h" + +#include + +#include "base/no_destructor.h" +#include "build/build_config.h" + +#if BUILDFLAG(IS_IOS) +#include "brave/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h" +#else +#include "brave/components/services/brave_wallet/content/brave_wallet_utils_service_launcher.h" +#endif + +namespace brave_wallet { + +BraveWalletUtilsService::BraveWalletUtilsService() = default; +BraveWalletUtilsService::~BraveWalletUtilsService() = default; + +// static +BraveWalletUtilsService* BraveWalletUtilsService::GetInstance() { + static base::NoDestructor service; + return service.get(); +} + +void BraveWalletUtilsService::CreateZCashDecoder( + mojo::PendingAssociatedReceiver receiver) { + MaybeLaunchService(); + brave_wallet_utils_service_->CreateZCashDecoderService(std::move(receiver)); +} + +void BraveWalletUtilsService::MaybeLaunchService() { +#if BUILDFLAG(IS_IOS) + LaunchInProcessBraveWalletUtilsService( + brave_wallet_utils_service_.BindNewPipeAndPassReceiver()); + brave_wallet_utils_service_.reset_on_disconnect(); +#else + LaunchBraveWalletUtilsService( + brave_wallet_utils_service_.BindNewPipeAndPassReceiver()); + brave_wallet_utils_service_.reset_on_disconnect(); + // 10 minutes is a default wallet lock time + brave_wallet_utils_service_.reset_on_idle_timeout(base::Minutes(10)); +#endif +} + +} // namespace brave_wallet diff --git a/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h new file mode 100644 index 000000000000..d0a4cd06e097 --- /dev/null +++ b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_H_ + +#include "brave/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace brave_wallet { + +/** + * Launches and communicates mojom::BraveWalletUtilsService in separate process. + */ +class BraveWalletUtilsService { + public: + BraveWalletUtilsService(); + ~BraveWalletUtilsService(); + BraveWalletUtilsService(const BraveWalletUtilsService&) = delete; + BraveWalletUtilsService& operator=(const BraveWalletUtilsService&) = delete; + + // Creates decoder in brave wallet utils process and provides handles. + void CreateZCashDecoder( + mojo::PendingAssociatedReceiver receiver); + + static BraveWalletUtilsService* GetInstance(); + + private: + void MaybeLaunchService(); + + mojo::Remote brave_wallet_utils_service_; + + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_H_ diff --git a/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.cc b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.cc new file mode 100644 index 000000000000..76cd8e5c3513 --- /dev/null +++ b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.cc @@ -0,0 +1,29 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ + +#include "brave/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h" + +#include +#include + +#include "brave/components/services/brave_wallet/brave_wallet_utils_service_impl.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" + +namespace brave_wallet { + +void LaunchInProcessBraveWalletUtilsService( + mojo::PendingReceiver receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique( + mojo::PendingReceiver()), + std::move(receiver)); +} + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_CONTENT_BRAVE_WALLET_UTILS_SERVICE_LAUNCHER_H_ diff --git a/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h new file mode 100644 index 000000000000..9015700f31ab --- /dev/null +++ b/components/services/brave_wallet/public/cpp/brave_wallet_utils_service_in_process_launcher.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_IN_PROCESS_LAUNCHER_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_IN_PROCESS_LAUNCHER_H_ + +#include "brave/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" + +namespace brave_wallet { + +void LaunchInProcessBraveWalletUtilsService( + mojo::PendingReceiver receiver); + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_BRAVE_WALLET_UTILS_SERVICE_IN_PROCESS_LAUNCHER_H_ diff --git a/components/services/brave_wallet/public/cpp/utils/BUILD.gn b/components/services/brave_wallet/public/cpp/utils/BUILD.gn new file mode 100644 index 000000000000..8b49c4dc3f74 --- /dev/null +++ b/components/services/brave_wallet/public/cpp/utils/BUILD.gn @@ -0,0 +1,13 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +source_set("utils") { + sources = [ + "protobuf_utils.cc", + "protobuf_utils.h", + ] + + deps = [ "//base" ] +} diff --git a/components/services/brave_wallet/public/cpp/utils/protobuf_utils.cc b/components/services/brave_wallet/public/cpp/utils/protobuf_utils.cc new file mode 100644 index 000000000000..5d7ddb75ac86 --- /dev/null +++ b/components/services/brave_wallet/public/cpp/utils/protobuf_utils.cc @@ -0,0 +1,48 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h" + +#include + +#include "base/big_endian.h" +#include "base/functional/callback.h" + +namespace brave_wallet { + +namespace { +constexpr size_t kGrpcHeaderSize = 5; +constexpr char kNoCompression = 0; +} // namespace + +std::string GetPrefixedProtobuf(const std::string& serialized_proto) { + std::string result(kGrpcHeaderSize, 0); + result[0] = kNoCompression; + base::WriteBigEndian(&result[1], serialized_proto.size()); + result.append(serialized_proto); + return result; +} + +std::optional ResolveSerializedMessage( + const std::string& grpc_response_body) { + if (grpc_response_body.size() < kGrpcHeaderSize) { + return std::nullopt; + } + if (grpc_response_body[0] != kNoCompression) { + // Compression is not supported yet + return std::nullopt; + } + uint32_t size = 0; + base::ReadBigEndian( + reinterpret_cast(&(grpc_response_body[1])), &size); + + if (grpc_response_body.size() != size + kGrpcHeaderSize) { + return std::nullopt; + } + + return grpc_response_body.substr(kGrpcHeaderSize); +} + +} // namespace brave_wallet diff --git a/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h b/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h new file mode 100644 index 000000000000..7afada1bb9da --- /dev/null +++ b/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_UTILS_PROTOBUF_UTILS_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_UTILS_PROTOBUF_UTILS_H_ + +#include +#include + +namespace brave_wallet { + +// Prefixes provided serialized protobuf with compression byte and 4 bytes of +// message size. See +// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md +std::string GetPrefixedProtobuf(const std::string& serialized_proto); + +// Resolves serialized protobuf from length-prefixed string +std::optional ResolveSerializedMessage( + const std::string& grpc_response_body); + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_PUBLIC_CPP_UTILS_PROTOBUF_UTILS_H_ diff --git a/components/services/brave_wallet/public/mojom/BUILD.gn b/components/services/brave_wallet/public/mojom/BUILD.gn new file mode 100644 index 000000000000..25af0fb112d0 --- /dev/null +++ b/components/services/brave_wallet/public/mojom/BUILD.gn @@ -0,0 +1,17 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("mojom") { + sources = [ + "brave_wallet_utils_service.mojom", + "zcash_decoder.mojom", + ] + + public_deps = [ "//mojo/public/mojom/base" ] + + deps = [ "//sandbox/policy/mojom" ] +} diff --git a/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom b/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom new file mode 100644 index 000000000000..20a78d87c10e --- /dev/null +++ b/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom @@ -0,0 +1,15 @@ +// Copyright (c) 2024 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 file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +module brave_wallet.mojom; + +import "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom"; +import "sandbox/policy/mojom/sandbox.mojom"; + +[ServiceSandbox=sandbox.mojom.Sandbox.kService] +interface BraveWalletUtilsService { + CreateZCashDecoderService( + pending_associated_receiver zcash_decoder_receiver); +}; diff --git a/components/services/brave_wallet/public/mojom/zcash_decoder.mojom b/components/services/brave_wallet/public/mojom/zcash_decoder.mojom new file mode 100644 index 000000000000..4375c6dc9527 --- /dev/null +++ b/components/services/brave_wallet/public/mojom/zcash_decoder.mojom @@ -0,0 +1,42 @@ +// Copyright (c) 2024 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 file, +// You can obtain one at https://mozilla.org/MPL/2.0/. + +module brave_wallet.mojom; + +struct ZCashUtxo { + string address; + array tx_id; + int32 index; + array script; + int64 value_zat; + uint64 height; +}; + +struct GetAddressUtxosResponse { + array address_utxos; +}; + +struct BlockID { + uint64 height; + array hash; +}; + +struct SendResponse { + int32 error_code; + string error_message; +}; + +struct RawTransaction { + array data; + uint64 height; +}; + +interface ZCashDecoder { + ParseBlockID(string data) => (BlockID? value); + ParseGetAddressUtxos(string data) => (GetAddressUtxosResponse? value); + ParseSendResponse(string data) => (SendResponse? value); + ParseRawTransaction(string adata) => (RawTransaction? tx); +}; + diff --git a/components/services/brave_wallet/public/proto/BUILD.gn b/components/services/brave_wallet/public/proto/BUILD.gn new file mode 100644 index 000000000000..3c327539d853 --- /dev/null +++ b/components/services/brave_wallet/public/proto/BUILD.gn @@ -0,0 +1,10 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +import("//third_party/protobuf/proto_library.gni") + +proto_library("zcash_proto") { + sources = [ "zcash_grpc_data.proto" ] +} diff --git a/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.proto b/components/services/brave_wallet/public/proto/zcash_grpc_data.proto similarity index 100% rename from components/brave_wallet/browser/zcash/protos/zcash_grpc_data.proto rename to components/services/brave_wallet/public/proto/zcash_grpc_data.proto diff --git a/components/services/brave_wallet/zcash/BUILD.gn b/components/services/brave_wallet/zcash/BUILD.gn new file mode 100644 index 000000000000..5a8589677a7d --- /dev/null +++ b/components/services/brave_wallet/zcash/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2024 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 file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +import("//mojo/public/tools/bindings/mojom.gni") + +source_set("zcash_decoder") { + visibility = [ "//brave/components/services/brave_wallet/*" ] + + sources = [ + "zcash_decoder.cc", + "zcash_decoder.h", + ] + + deps = [ + "//base", + "//brave/components/services/brave_wallet/public/cpp/utils", + "//brave/components/services/brave_wallet/public/mojom", + "//brave/components/services/brave_wallet/public/proto:zcash_proto", + ] +} + +source_set("zcash_decoder_unit_tests") { + testonly = true + sources = [ + "//brave/components/services/brave_wallet/zcash/zcash_decoder_unittest.cc", + ] + + deps = [ + "//base/test:test_support", + "//brave/components/brave_wallet/common:test_support", + "//brave/components/services/brave_wallet/public/cpp/utils", + "//brave/components/services/brave_wallet/public/proto:zcash_proto", + "//brave/components/services/brave_wallet/zcash:zcash_decoder", + "//testing/gtest", + ] +} diff --git a/components/services/brave_wallet/zcash/zcash_decoder.cc b/components/services/brave_wallet/zcash/zcash_decoder.cc new file mode 100644 index 000000000000..d07f2f32911a --- /dev/null +++ b/components/services/brave_wallet/zcash/zcash_decoder.cc @@ -0,0 +1,84 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/zcash/zcash_decoder.h" + +#include + +#include "base/big_endian.h" +#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h" +#include "brave/components/services/brave_wallet/public/proto/zcash_grpc_data.pb.h" + +namespace brave_wallet { + +ZCashDecoder::ZCashDecoder() = default; + +ZCashDecoder::~ZCashDecoder() = default; + +void ZCashDecoder::ParseRawTransaction(const std::string& data, + ParseRawTransactionCallback callback) { + zcash::RawTransaction result; + auto serialized_message = ResolveSerializedMessage(data); + if (!serialized_message || + !result.ParseFromString(serialized_message.value())) { + std::move(callback).Run(nullptr); + return; + } + std::vector tx_data(result.data().begin(), result.data().end()); + std::move(callback).Run( + mojom::RawTransaction::New(std::move(tx_data), result.height())); +} + +void ZCashDecoder::ParseBlockID(const std::string& data, + ParseBlockIDCallback callback) { + zcash::BlockID result; + auto serialized_message = ResolveSerializedMessage(data); + if (!serialized_message || + !result.ParseFromString(serialized_message.value())) { + std::move(callback).Run(nullptr); + return; + } + std::vector hash(result.hash().begin(), result.hash().end()); + std::move(callback).Run( + mojom::BlockID::New(result.height(), std::move(hash))); +} + +void ZCashDecoder::ParseGetAddressUtxos(const std::string& data, + ParseGetAddressUtxosCallback callback) { + zcash::GetAddressUtxosResponse result; + auto serialized_message = ResolveSerializedMessage(data); + if (!serialized_message || + !result.ParseFromString(serialized_message.value())) { + std::move(callback).Run(nullptr); + return; + } + std::vector utxos; + for (int i = 0; i < result.addressutxos_size(); i++) { + const zcash::ZCashUtxo& item = result.addressutxos(i); + std::vector tx_id(item.txid().begin(), item.txid().end()); + std::vector script(item.script().begin(), item.script().end()); + + utxos.push_back(mojom::ZCashUtxo::New(item.address(), std::move(tx_id), + item.index(), std::move(script), + item.valuezat(), item.height())); + } + std::move(callback).Run( + mojom::GetAddressUtxosResponse::New(std::move(utxos))); +} + +void ZCashDecoder::ParseSendResponse(const std::string& data, + ParseSendResponseCallback callback) { + zcash::SendResponse result; + auto serialized_message = ResolveSerializedMessage(data); + if (!serialized_message || + !result.ParseFromString(serialized_message.value())) { + std::move(callback).Run(nullptr); + return; + } + std::move(callback).Run( + mojom::SendResponse::New(result.errorcode(), result.errormessage())); +} + +} // namespace brave_wallet diff --git a/components/services/brave_wallet/zcash/zcash_decoder.h b/components/services/brave_wallet/zcash/zcash_decoder.h new file mode 100644 index 000000000000..d53c16c768e2 --- /dev/null +++ b/components/services/brave_wallet/zcash/zcash_decoder.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_ZCASH_ZCASH_DECODER_H_ +#define BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_ZCASH_ZCASH_DECODER_H_ + +#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h" + +#include +#include + +#include "mojo/public/cpp/bindings/receiver_set.h" + +namespace brave_wallet { + +// Parses Zcash protobuf objects and translates them to mojo. +class ZCashDecoder : public mojom::ZCashDecoder { + public: + ZCashDecoder(); + ~ZCashDecoder() override; + + ZCashDecoder(const ZCashDecoder&) = delete; + ZCashDecoder& operator=(const ZCashDecoder&) = delete; + + void ParseRawTransaction(const std::string& data, + ParseRawTransactionCallback callback) override; + void ParseBlockID(const std::string& data, + ParseBlockIDCallback callback) override; + void ParseGetAddressUtxos(const std::string& data, + ParseGetAddressUtxosCallback callback) override; + void ParseSendResponse(const std::string& data, + ParseSendResponseCallback) override; +}; + +} // namespace brave_wallet + +#endif // BRAVE_COMPONENTS_SERVICES_BRAVE_WALLET_ZCASH_ZCASH_DECODER_H_ diff --git a/components/services/brave_wallet/zcash/zcash_decoder_unittest.cc b/components/services/brave_wallet/zcash/zcash_decoder_unittest.cc new file mode 100644 index 000000000000..25e8e4331954 --- /dev/null +++ b/components/services/brave_wallet/zcash/zcash_decoder_unittest.cc @@ -0,0 +1,160 @@ +/* Copyright (c) 2024 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 file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/services/brave_wallet/zcash/zcash_decoder.h" + +#include +#include +#include + +#include "base/test/bind.h" +#include "base/test/mock_callback.h" +#include "brave/components/brave_wallet/common/test_utils.h" +#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h" +#include "brave/components/services/brave_wallet/public/proto/zcash_grpc_data.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace brave_wallet { + +namespace { +std::vector ToBytes(const std::string& str) { + return std::vector(str.begin(), str.end()); +} +} // namespace + +class ZCashDecoderUnitTest : public testing::Test { + public: + ZCashDecoderUnitTest() = default; + ZCashDecoderUnitTest(const ZCashDecoderUnitTest&) = delete; + ZCashDecoderUnitTest& operator=(const ZCashDecoderUnitTest&) = delete; + ~ZCashDecoderUnitTest() override = default; + + void SetUp() override { decoder_ = std::make_unique(); } + + void TearDown() override {} + + ZCashDecoder* decoder() { return decoder_.get(); } + + private: + std::unique_ptr decoder_; +}; + +TEST_F(ZCashDecoderUnitTest, ParseBlockID) { + // Correct + { + zcash::BlockID block_id; + block_id.set_height(64u); + block_id.set_hash("abcd"); + mojom::BlockIDPtr result; + base::MockCallback callback; + EXPECT_CALL(callback, + Run(EqualsMojo(mojom::BlockID::New(64u, ToBytes("abcd"))))); + decoder()->ParseBlockID(GetPrefixedProtobuf(block_id.SerializeAsString()), + callback.Get()); + } + // Incorrect + { + mojom::BlockIDPtr result; + std::optional error; + base::MockCallback callback; + EXPECT_CALL(callback, Run(EqualsMojo(mojom::BlockIDPtr()))); + decoder()->ParseBlockID("123", callback.Get()); + } +} + +TEST_F(ZCashDecoderUnitTest, ParseGetAddressUtxos) { + // Correct + { + zcash::ZCashUtxo utxo1; + utxo1.set_address("addr1"); + utxo1.set_txid("txid1"); + utxo1.set_valuezat(1u); + + zcash::ZCashUtxo utxo2; + utxo2.set_address("addr2"); + utxo2.set_txid("txid2"); + utxo2.set_valuezat(2u); + + zcash::GetAddressUtxosResponse response; + *(response.add_addressutxos()) = utxo1; + *(response.add_addressutxos()) = utxo2; + + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(testing::Truly( + [&](const mojom::GetAddressUtxosResponsePtr& result) { + EXPECT_TRUE(result); + EXPECT_EQ(result->address_utxos[0]->address, "addr1"); + EXPECT_EQ(result->address_utxos[0]->tx_id, ToBytes("txid1")); + EXPECT_EQ(result->address_utxos[0]->value_zat, 1u); + + EXPECT_EQ(result->address_utxos[1]->address, "addr2"); + EXPECT_EQ(result->address_utxos[1]->tx_id, ToBytes("txid2")); + EXPECT_EQ(result->address_utxos[1]->value_zat, 2u); + return true; + }))); + decoder()->ParseGetAddressUtxos( + GetPrefixedProtobuf(response.SerializeAsString()), callback.Get()); + } + // Incorrect + { + mojom::GetAddressUtxosResponsePtr result; + std::optional error; + base::MockCallback callback; + EXPECT_CALL(callback, Run(EqualsMojo(mojom::GetAddressUtxosResponsePtr()))); + decoder()->ParseGetAddressUtxos("123", callback.Get()); + } +} + +TEST_F(ZCashDecoderUnitTest, ParseSendResponse) { + // Correct + { + zcash::SendResponse response; + response.set_errorcode(1); + response.set_errormessage("123"); + mojom::SendResponsePtr result; + base::MockCallback callback; + EXPECT_CALL(callback, Run(EqualsMojo(mojom::SendResponse::New(1, "123")))); + decoder()->ParseSendResponse( + GetPrefixedProtobuf(response.SerializeAsString()), callback.Get()); + } + // Incorrect + { + mojom::SendResponsePtr result; + std::optional error; + base::MockCallback callback; + EXPECT_CALL(callback, Run(EqualsMojo(mojom::SendResponsePtr()))); + decoder()->ParseSendResponse("123", callback.Get()); + } +} + +TEST_F(ZCashDecoderUnitTest, ParseRawTransaction) { + // Correct + { + zcash::RawTransaction response; + response.set_height(2); + response.set_data("data"); + + mojom::RawTransactionPtr result; + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(EqualsMojo(mojom::RawTransaction::New(ToBytes("data"), 2u)))); + decoder()->ParseRawTransaction( + GetPrefixedProtobuf(response.SerializeAsString()), callback.Get()); + } + // Incorrect + { + mojom::RawTransactionPtr result; + std::optional error; + base::MockCallback callback; + EXPECT_CALL(callback, Run(EqualsMojo(mojom::RawTransactionPtr()))); + decoder()->ParseRawTransaction("123", callback.Get()); + } +} + +} // namespace brave_wallet diff --git a/test/BUILD.gn b/test/BUILD.gn index 9b0c8b63a604..fe8362b06cca 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -257,6 +257,7 @@ test("brave_unit_tests") { "//brave/components/resources:strings_grit", "//brave/components/script_injector/renderer:unit_tests", "//brave/components/search_engines:unit_tests", + "//brave/components/services/brave_wallet/zcash:zcash_decoder_unit_tests", "//brave/components/services/ipfs/test:ipfs_service_unit_tests", "//brave/components/sessions/content:unit_tests", "//brave/components/signin/public/identity_manager:unit_tests", diff --git a/utility/brave_content_utility_client.cc b/utility/brave_content_utility_client.cc index a7941691db28..ffdbd6125551 100644 --- a/utility/brave_content_utility_client.cc +++ b/utility/brave_content_utility_client.cc @@ -30,6 +30,9 @@ #include "brave/components/services/tor/tor_launcher_impl.h" #endif +#include "brave/components/services/brave_wallet/brave_wallet_utils_service_impl.h" +#include "brave/components/services/brave_wallet/public/mojom/brave_wallet_utils_service.mojom.h" + namespace { #if !BUILDFLAG(IS_ANDROID) @@ -63,6 +66,13 @@ auto RunBatAdsService( return std::make_unique(std::move(receiver)); } +auto RunBraveWalletUtilsService( + mojo::PendingReceiver + receiver) { + return std::make_unique( + std::move(receiver)); +} + } // namespace BraveContentUtilityClient::BraveContentUtilityClient() = default; @@ -86,5 +96,7 @@ void BraveContentUtilityClient::RegisterMainThreadServices( services.Add(RunBatAdsService); + services.Add(RunBraveWalletUtilsService); + return ChromeContentUtilityClient::RegisterMainThreadServices(services); } diff --git a/utility/sources.gni b/utility/sources.gni index 75c8f7ddc568..fe4177bd0aaa 100644 --- a/utility/sources.gni +++ b/utility/sources.gni @@ -27,6 +27,8 @@ brave_utility_deps = [ "//brave/components/services/bat_ads/public/interfaces", "//brave/components/services/bat_rewards:lib", "//brave/components/services/bat_rewards/public/interfaces", + "//brave/components/services/brave_wallet:lib", + "//brave/components/services/brave_wallet/public/mojom", "//brave/components/tor/buildflags", "//mojo/public/cpp/bindings", ]