From bf6ffdf23751451d01a449029aef3ffb63d33d9d Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Fri, 21 Apr 2023 16:23:45 -0700 Subject: [PATCH] Reject Solana SignTransaction/SignAllTransactions when blockhash is invalid --- browser/brave_content_browser_client.cc | 12 ++- .../solana_provider_browsertest.cc | 79 ++++++++++++--- .../solana_provider_impl_unittest.cc | 49 ++++++++-- .../browser/brave_wallet_service.cc | 7 +- .../browser/brave_wallet_service.h | 13 +++ .../browser/solana_provider_impl.cc | 98 ++++++++++++++++--- .../browser/solana_provider_impl.h | 26 ++++- components/resources/wallet_strings.grdp | 1 + .../api/brave_wallet/brave_wallet_api.mm | 11 ++- 9 files changed, 246 insertions(+), 50 deletions(-) diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index 7f8a603046bf..a17dad877171 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -339,14 +339,20 @@ void MaybeBindSolanaProvider( return; } + auto* json_rpc_service = + brave_wallet::JsonRpcServiceFactory::GetServiceForContext( + frame_host->GetBrowserContext()); + if (!json_rpc_service) { + return; + } + content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(frame_host); mojo::MakeSelfOwnedReceiver( std::make_unique( - keyring_service, brave_wallet_service, tx_service, + keyring_service, brave_wallet_service, tx_service, json_rpc_service, std::make_unique( - web_contents, frame_host), - user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())), + web_contents, frame_host)), std::move(receiver)); } diff --git a/browser/brave_wallet/solana_provider_browsertest.cc b/browser/brave_wallet/solana_provider_browsertest.cc index a21ef280cefb..92bc18f9e967 100644 --- a/browser/brave_wallet/solana_provider_browsertest.cc +++ b/browser/brave_wallet/solana_provider_browsertest.cc @@ -8,8 +8,10 @@ #include "base/memory/raw_ptr.h" #include "base/path_service.h" #include "base/strings/strcat.h" +#include "base/strings/string_util.h" #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "base/test/values_test_util.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" @@ -228,21 +230,6 @@ constexpr char kSignedTxArrayStrV0[] = "62,117,14,95,59,44,129,146,205,25,85,231,59,33,111,45,217,138,53,56,53,66," "159,240,201,66,1,1,0"; -std::unique_ptr HandleRequest( - const net::test_server::HttpRequest& request) { - std::unique_ptr http_response( - new net::test_server::BasicHttpResponse()); - http_response->set_code(net::HTTP_OK); - http_response->set_content_type("text/html"); - std::string request_path = request.GetURL().path(); - http_response->set_content(R"({ - "jsonrpc": "2.0", - "id": 1, - "result": "ns1aBL6AowxpiPzQL3ZeBK1RpCSLq1VfhqNw9KFSsytayARYdYrqrmbmhaizUTTkT4SXEnjnbVmPBrie3o9yuyB" - })"); - return std::move(http_response); -} - // signMessage constexpr char kMessage[] = "bravey baby!"; constexpr char kEncodedMessage[] = "98,114,97,118,121,32,98,97,98,121,33"; @@ -305,6 +292,13 @@ bool WaitForWalletBubble(content::WebContents* web_contents) { return tab_helper->IsShowingBubble(); } + +void CloseWalletBubble(content::WebContents* web_contents) { + auto* tab_helper = + brave_wallet::BraveWalletTabHelper::FromWebContents(web_contents); + tab_helper->CloseBubble(); +} + } // namespace class SolanaProviderTest : public InProcessBrowserTest { @@ -348,7 +342,8 @@ class SolanaProviderTest : public InProcessBrowserTest { tx_service_ = TxServiceFactory::GetServiceForContext(browser()->profile()); tx_service_->AddObserver(observer()->GetReceiver()); - StartRPCServer(base::BindRepeating(&HandleRequest)); + StartRPCServer(base::BindRepeating(&SolanaProviderTest::HandleRequest, + base::Unretained(this))); // load solana web3 script if (g_provider_solana_web3_script->empty()) { @@ -357,6 +352,38 @@ class SolanaProviderTest : public InProcessBrowserTest { } } + std::unique_ptr HandleRequest( + const net::test_server::HttpRequest& request) { + std::unique_ptr http_response( + new net::test_server::BasicHttpResponse()); + http_response->set_code(net::HTTP_OK); + http_response->set_content_type("text/html"); + std::string request_path = request.GetURL().path(); + + auto body = base::test::ParseJsonDict(request.content); + auto* method = body.FindString("method"); + EXPECT_TRUE(method); + if (*method == "isBlockhashValid") { + std::string reply = R"({ + "jsonrpc": "2.0", + "id": 1, + "result": { + "value": {valid} + } + })"; + base::ReplaceFirstSubstringAfterOffset( + &reply, 0, "{valid}", mock_blockhash_is_valid_ ? "true" : "false"); + http_response->set_content(reply); + } else { + http_response->set_content(R"({ + "jsonrpc": "2.0", + "id": 1, + "result": "ns1aBL6AowxpiPzQL3ZeBK1RpCSLq1VfhqNw9KFSsytayARYdYrqrmbmhaizUTTkT4SXEnjnbVmPBrie3o9yuyB" + })"); + } + return std::move(http_response); + } + void StartRPCServer( const net::EmbeddedTestServer::HandleRequestCallback& callback) { https_server_for_rpc()->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); @@ -534,12 +561,14 @@ class SolanaProviderTest : public InProcessBrowserTest { void CallSolanaSignMessage(const std::string& message, const std::string& encoding) { + CloseWalletBubble(web_contents()); ASSERT_TRUE(ExecJs(web_contents(), base::StringPrintf(R"(solanaSignMessage('%s', '%s'))", message.c_str(), encoding.c_str()))); } void CallSolanaRequest(const std::string& json) { + CloseWalletBubble(web_contents()); ASSERT_TRUE( ExecJs(web_contents(), base::StringPrintf(R"(solanaRequest(%s))", json.c_str()))); @@ -557,6 +586,7 @@ class SolanaProviderTest : public InProcessBrowserTest { const std::string& pubkey = "", const std::string& signature_array_string = "", bool v0 = false) { + CloseWalletBubble(web_contents()); const std::string script = pubkey.empty() ? base::StringPrintf( @@ -583,6 +613,7 @@ class SolanaProviderTest : public InProcessBrowserTest { const std::string& pubkey = "", const std::string& signature_array_string = "", bool v0 = false) { + CloseWalletBubble(web_contents()); const std::string script = pubkey.empty() ? base::StringPrintf( @@ -604,6 +635,7 @@ class SolanaProviderTest : public InProcessBrowserTest { const std::string& pubkey = "", const std::string& signature_array_string = "", bool v0 = false) { + CloseWalletBubble(web_contents()); const std::string script = pubkey.empty() ? base::StringPrintf( @@ -672,6 +704,7 @@ class SolanaProviderTest : public InProcessBrowserTest { protected: raw_ptr brave_wallet_service_ = nullptr; raw_ptr keyring_service_ = nullptr; + bool mock_blockhash_is_valid_ = true; private: TestTxServiceObserver observer_; @@ -1133,6 +1166,13 @@ IN_PROC_BROWSER_TEST_F(SolanaProviderTest, SignTransaction) { true, request_index++, nullptr, absl::nullopt); WaitForResultReady(); EXPECT_EQ(GetSignTransactionResult(), kSignedTxArrayStrV0); + + // Test blockhash is invalid. + mock_blockhash_is_valid_ = false; + CallSolanaSignTransaction(kUnsignedTxArrayStr); + WaitForResultReady(); + EXPECT_EQ(GetSignTransactionResult(), + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_BLOCKHASH_ERROR)); } IN_PROC_BROWSER_TEST_F(SolanaProviderTest, SignAllTransactions) { @@ -1184,6 +1224,13 @@ IN_PROC_BROWSER_TEST_F(SolanaProviderTest, SignAllTransactions) { true, request_index++, absl::nullopt, absl::nullopt); WaitForResultReady(); EXPECT_EQ(GetSignAllTransactionsResult(), "success"); + + // Test blockhash is invalid. + mock_blockhash_is_valid_ = false; + CallSolanaSignAllTransactions(kUnsignedTxArrayStr, kSignedTxArrayStr); + WaitForResultReady(); + EXPECT_EQ(GetSignAllTransactionsResult(), + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_BLOCKHASH_ERROR)); } IN_PROC_BROWSER_TEST_F(SolanaProviderTest, Request) { diff --git a/browser/brave_wallet/solana_provider_impl_unittest.cc b/browser/brave_wallet/solana_provider_impl_unittest.cc index 7a8f08a2c5b8..9fe685215729 100644 --- a/browser/brave_wallet/solana_provider_impl_unittest.cc +++ b/browser/brave_wallet/solana_provider_impl_unittest.cc @@ -41,6 +41,9 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_web_contents_factory.h" #include "content/test/test_web_contents.h" +#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/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" @@ -98,7 +101,10 @@ class TestEventsListener : public mojom::SolanaEventsListener { class SolanaProviderImplUnitTest : public testing::Test { public: - SolanaProviderImplUnitTest() { + SolanaProviderImplUnitTest() + : shared_url_loader_factory_( + base::MakeRefCounted( + &url_loader_factory_)) { feature_list_.InitAndEnableFeature( brave_wallet::features::kBraveWalletSolanaFeature); } @@ -121,6 +127,18 @@ class SolanaProviderImplUnitTest : public testing::Test { permissions::PermissionRequestManager::CreateForWebContents(web_contents()); json_rpc_service_ = JsonRpcServiceFactory::GetServiceForContext(browser_context()); + json_rpc_service_->SetAPIRequestHelperForTesting( + shared_url_loader_factory_); + + // Return true for checking blockhash. + url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( + [&](const network::ResourceRequest& request) { + url_loader_factory_.ClearResponses(); + url_loader_factory_.AddResponse( + request.url.spec(), + R"({"jsonrpc": "2.0", "id": 1, "result": { "value": true }})"); + })); + keyring_service_ = KeyringServiceFactory::GetServiceForContext(browser_context()); brave_wallet_service_ = @@ -133,10 +151,9 @@ class SolanaProviderImplUnitTest : public testing::Test { PermissionManagerFactory::GetInstance()->BuildServiceInstanceFor( browser_context())))); provider_ = std::make_unique( - keyring_service_, brave_wallet_service_, tx_service_, + keyring_service_, brave_wallet_service_, tx_service_, json_rpc_service_, std::make_unique( - web_contents(), web_contents()->GetPrimaryMainFrame()), - profile_.GetPrefs()); + web_contents(), web_contents()->GetPrimaryMainFrame())); observer_ = std::make_unique(); provider_->Init(observer_->GetReceiver()); } @@ -372,9 +389,12 @@ class SolanaProviderImplUnitTest : public testing::Test { })); if (run_notify) { - brave_wallet_service_->NotifySignTransactionRequestProcessed( - approve, brave_wallet_service_->sign_transaction_id_ - 1, - std::move(hw_sig), err_in); + brave_wallet_service_->SetSignTransactionRequestAddedCallbackForTesting( + base::BindLambdaForTesting([&]() { + brave_wallet_service_->NotifySignTransactionRequestProcessed( + approve, brave_wallet_service_->sign_transaction_id_ - 1, + std::move(hw_sig), err_in); + })); } run_loop.Run(); @@ -412,9 +432,15 @@ class SolanaProviderImplUnitTest : public testing::Test { })); if (run_notify) { - brave_wallet_service_->NotifySignAllTransactionsRequestProcessed( - approve, brave_wallet_service_->sign_all_transactions_id_ - 1, - std::move(hw_sigs), err_in); + brave_wallet_service_ + ->SetSignAllTransactionsRequestAddedCallbackForTesting( + base::BindLambdaForTesting([&]() { + brave_wallet_service_ + ->NotifySignAllTransactionsRequestProcessed( + approve, + brave_wallet_service_->sign_all_transactions_id_ - 1, + std::move(hw_sigs), err_in); + })); } run_loop.Run(); @@ -470,6 +496,9 @@ class SolanaProviderImplUnitTest : public testing::Test { content::TestWebContentsFactory factory_; TestingProfile profile_; base::test::ScopedFeatureList feature_list_; + data_decoder::test::InProcessDataDecoder in_process_data_decoder_; + network::TestURLLoaderFactory url_loader_factory_; + scoped_refptr shared_url_loader_factory_; }; TEST_F(SolanaProviderImplUnitTest, Connect) { diff --git a/components/brave_wallet/browser/brave_wallet_service.cc b/components/brave_wallet/browser/brave_wallet_service.cc index 83cb7956abb5..dfb9bbb0d73c 100644 --- a/components/brave_wallet/browser/brave_wallet_service.cc +++ b/components/brave_wallet/browser/brave_wallet_service.cc @@ -6,7 +6,6 @@ #include "brave/components/brave_wallet/browser/brave_wallet_service.h" #include -#include #include #include "base/metrics/histogram_macros.h" @@ -1340,6 +1339,9 @@ void BraveWalletService::AddSignTransactionRequest( } sign_transaction_requests_.push_back(std::move(request)); sign_transaction_callbacks_.push_back(std::move(callback)); + if (sign_tx_request_added_cb_for_testing_) { + std::move(sign_tx_request_added_cb_for_testing_).Run(); + } } void BraveWalletService::AddSignAllTransactionsRequest( @@ -1350,6 +1352,9 @@ void BraveWalletService::AddSignAllTransactionsRequest( } sign_all_transactions_requests_.push_back(std::move(request)); sign_all_transactions_callbacks_.push_back(std::move(callback)); + if (sign_all_txs_request_added_cb_for_testing_) { + std::move(sign_all_txs_request_added_cb_for_testing_).Run(); + } } void BraveWalletService::AddSuggestTokenRequest( diff --git a/components/brave_wallet/browser/brave_wallet_service.h b/components/brave_wallet/browser/brave_wallet_service.h index d29dd3bd1e63..7b4996fcddcb 100644 --- a/components/brave_wallet/browser/brave_wallet_service.h +++ b/components/brave_wallet/browser/brave_wallet_service.h @@ -8,6 +8,7 @@ #include #include +#include #include #include "base/containers/circular_deque.h" @@ -258,6 +259,15 @@ class BraveWalletService : public KeyedService, BraveWalletP3A* GetBraveWalletP3A(); + void SetSignTransactionRequestAddedCallbackForTesting( + base::OnceClosure callback) { + sign_tx_request_added_cb_for_testing_ = std::move(callback); + } + void SetSignAllTransactionsRequestAddedCallbackForTesting( + base::OnceClosure callback) { + sign_all_txs_request_added_cb_for_testing_ = std::move(callback); + } + protected: // For tests BraveWalletService(); @@ -313,6 +323,9 @@ class BraveWalletService : public KeyedService, void CancelAllGetEncryptionPublicKeyCallbacks(); void CancelAllDecryptCallbacks(); + base::OnceClosure sign_tx_request_added_cb_for_testing_; + base::OnceClosure sign_all_txs_request_added_cb_for_testing_; + int sign_message_id_ = 0; int sign_transaction_id_ = 0; int sign_all_transactions_id_ = 0; diff --git a/components/brave_wallet/browser/solana_provider_impl.cc b/components/brave_wallet/browser/solana_provider_impl.cc index 7d6dcf5d1dd2..295ccc76dcfb 100644 --- a/components/brave_wallet/browser/solana_provider_impl.cc +++ b/components/brave_wallet/browser/solana_provider_impl.cc @@ -13,6 +13,7 @@ #include "brave/components/brave_wallet/browser/brave_wallet_provider_delegate.h" #include "brave/components/brave_wallet/browser/brave_wallet_service.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/solana_message.h" #include "brave/components/brave_wallet/browser/solana_transaction.h" @@ -41,13 +42,13 @@ SolanaProviderImpl::SolanaProviderImpl( KeyringService* keyring_service, BraveWalletService* brave_wallet_service, TxService* tx_service, - std::unique_ptr delegate, - PrefService* prefs) + JsonRpcService* json_rpc_service, + std::unique_ptr delegate) : keyring_service_(keyring_service), brave_wallet_service_(brave_wallet_service), tx_service_(tx_service), + json_rpc_service_(json_rpc_service), delegate_(std::move(delegate)), - prefs_(prefs), weak_factory_(this) { DCHECK(keyring_service_); keyring_service_->AddObserver( @@ -207,19 +208,46 @@ void SolanaProviderImpl::SignTransaction( return; } + const std::string chain_id = json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, delegate_->GetOrigin()); + const std::string blockhash = msg_pair->first.recent_blockhash(); + auto internal_callback = + base::BindOnce(&SolanaProviderImpl::ContinueSignTransaction, + weak_factory_.GetWeakPtr(), std::move(msg_pair), + std::move(param), *account, chain_id, std::move(callback)); + json_rpc_service_->IsSolanaBlockhashValid(chain_id, blockhash, absl::nullopt, + std::move(internal_callback)); +} + +void SolanaProviderImpl::ContinueSignTransaction( + absl::optional>> msg_pair, + mojom::SolanaSignTransactionParamPtr param, + const std::string& account, + const std::string& chain_id, + SignTransactionCallback callback, + bool is_valid, + mojom::SolanaProviderError error, + const std::string& error_message) { + if (error != mojom::SolanaProviderError::kSuccess || !is_valid) { + std::move(callback).Run( + mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_BLOCKHASH_ERROR), + std::vector(), mojom::SolanaMessageVersion::kLegacy); + return; + } + auto tx = std::make_unique(std::move(msg_pair->first), std::move(param)); tx->set_tx_type(mojom::TransactionType::SolanaDappSignTransaction); auto request = mojom::SignTransactionRequest::New( - MakeOriginInfo(delegate_->GetOrigin()), -1, *account, + MakeOriginInfo(delegate_->GetOrigin()), -1, account, mojom::TxDataUnion::NewSolanaTxData(tx->ToSolanaTxData()), mojom::ByteArrayStringUnion::NewBytes(std::move(msg_pair->second)), - mojom::CoinType::SOL, - GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); + mojom::CoinType::SOL, chain_id); brave_wallet_service_->AddSignTransactionRequest( std::move(request), base::BindOnce(&SolanaProviderImpl::OnSignTransactionRequestProcessed, - weak_factory_.GetWeakPtr(), std::move(tx), *account, + weak_factory_.GetWeakPtr(), std::move(tx), account, std::move(callback))); delegate_->ShowPanel(); } @@ -289,6 +317,9 @@ void SolanaProviderImpl::SignAllTransactions( std::vector tx_datas; std::vector> txs; std::vector raw_messages; + std::vector blockhashs; + const std::string chain_id = json_rpc_service_->GetChainIdSync( + mojom::CoinType::SOL, delegate_->GetOrigin()); for (auto& param : params) { auto msg_pair = GetDeserializedMessage(param->encoded_serialized_msg, *account); @@ -301,6 +332,7 @@ void SolanaProviderImpl::SignAllTransactions( return; } + blockhashs.emplace_back(msg_pair->first.recent_blockhash()); auto tx = std::make_unique(std::move(msg_pair->first), std::move(param)); tx->set_tx_type(mojom::TransactionType::SolanaDappSignTransaction); @@ -311,15 +343,56 @@ void SolanaProviderImpl::SignAllTransactions( txs.push_back(std::move(tx)); } + const auto barrier_callback = base::BarrierCallback( + params.size(), + base::BindOnce(&SolanaProviderImpl::ContinueSignAllTransactions, + weak_factory_.GetWeakPtr(), std::move(tx_datas), + std::move(txs), std::move(raw_messages), *account, + json_rpc_service_->GetChainIdSync(mojom::CoinType::SOL, + delegate_->GetOrigin()), + std::move(callback))); + for (const auto& blockhash : blockhashs) { + json_rpc_service_->IsSolanaBlockhashValid( + chain_id, blockhash, absl::nullopt, + base::BindOnce( + [](base::OnceCallback barrier_callback, bool is_valid, + mojom::SolanaProviderError error, + const std::string& error_message) { + std::move(barrier_callback) + .Run(is_valid && + error == mojom::SolanaProviderError::kSuccess); + }, + barrier_callback)); + } +} + +void SolanaProviderImpl::ContinueSignAllTransactions( + std::vector tx_datas, + std::vector> txs, + std::vector raw_messages, + const std::string& account, + const std::string& chain_id, + SignAllTransactionsCallback callback, + const std::vector& is_valids) { + if (std::find_if_not(is_valids.begin(), is_valids.end(), [](auto is_valid) { + return is_valid; + }) != is_valids.end()) { + std::move(callback).Run( + mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_BLOCKHASH_ERROR), + std::vector>(), + std::vector()); + return; + } + auto request = mojom::SignAllTransactionsRequest::New( - MakeOriginInfo(delegate_->GetOrigin()), -1, *account, std::move(tx_datas), - std::move(raw_messages), mojom::CoinType::SOL, - GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); + MakeOriginInfo(delegate_->GetOrigin()), -1, account, std::move(tx_datas), + std::move(raw_messages), mojom::CoinType::SOL, chain_id); brave_wallet_service_->AddSignAllTransactionsRequest( std::move(request), base::BindOnce(&SolanaProviderImpl::OnSignAllTransactionsRequestProcessed, - weak_factory_.GetWeakPtr(), std::move(txs), *account, + weak_factory_.GetWeakPtr(), std::move(txs), account, std::move(callback))); delegate_->ShowPanel(); } @@ -514,7 +587,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, - GetCurrentChainId(prefs_, mojom::CoinType::SOL, delegate_->GetOrigin())); + json_rpc_service_->GetChainIdSync(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 f418dcf1e79b..8296def5cf44 100644 --- a/components/brave_wallet/browser/solana_provider_impl.h +++ b/components/brave_wallet/browser/solana_provider_impl.h @@ -20,12 +20,11 @@ #include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" -class PrefService; - namespace brave_wallet { class BraveWalletProviderDelegate; class BraveWalletService; +class JsonRpcService; class KeyringService; class SolanaMessage; class SolanaTransaction; @@ -40,8 +39,8 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, SolanaProviderImpl(KeyringService* keyring_service, BraveWalletService* brave_wallet_service, TxService* tx_service, - std::unique_ptr delegate, - PrefService* prefs); + JsonRpcService* json_rpc_service, + std::unique_ptr delegate); ~SolanaProviderImpl() override; SolanaProviderImpl(const SolanaProviderImpl&) = delete; SolanaProviderImpl& operator=(const SolanaProviderImpl&) = delete; @@ -88,6 +87,15 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, bool approved, mojom::ByteArrayStringUnionPtr signature, const absl::optional& error); + void ContinueSignTransaction( + absl::optional>> msg_pair, + mojom::SolanaSignTransactionParamPtr param, + const std::string& account, + const std::string& chain_id, + SignTransactionCallback callback, + bool is_valid, + mojom::SolanaProviderError error, + const std::string& error_message); void OnSignTransactionRequestProcessed( std::unique_ptr tx, const std::string& account, @@ -95,6 +103,14 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, bool approved, mojom::ByteArrayStringUnionPtr signature, const absl::optional& error); + void ContinueSignAllTransactions( + std::vector tx_datas, + std::vector> txs, + std::vector raw_messages, + const std::string& account, + const std::string& chain_id, + SignAllTransactionsCallback callback, + const std::vector& is_valids); void OnSignAllTransactionsRequestProcessed( const std::vector>& txs, const std::string& account, @@ -158,11 +174,11 @@ class SolanaProviderImpl final : public mojom::SolanaProvider, raw_ptr keyring_service_ = nullptr; raw_ptr brave_wallet_service_ = nullptr; raw_ptr tx_service_ = nullptr; + raw_ptr json_rpc_service_ = nullptr; mojo::Receiver 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/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp index 3f0e8cf87d80..7b7eec4350c7 100644 --- a/components/resources/wallet_strings.grdp +++ b/components/resources/wallet_strings.grdp @@ -9,6 +9,7 @@ Expected single, object parameter. This Chain ID is currently used An internal error has occurred + Blockhash is invalid or can not be validated Unsupported subscription type This RPC method is not supported. A response parsing error has occurred diff --git a/ios/browser/api/brave_wallet/brave_wallet_api.mm b/ios/browser/api/brave_wallet/brave_wallet_api.mm index 2324b6a6174a..8562292c3192 100644 --- a/ios/browser/api/brave_wallet/brave_wallet_api.mm +++ b/ios/browser/api/brave_wallet/brave_wallet_api.mm @@ -125,11 +125,16 @@ - (instancetype)initWithBrowserState:(ChromeBrowserState*)mainBrowserState { return nil; } + auto* json_rpc_service = + brave_wallet::JsonRpcServiceFactory::GetServiceForState(browserState); + if (!json_rpc_service) { + return nil; + } + auto provider = std::make_unique( - keyring_service, brave_wallet_service, tx_service, + keyring_service, brave_wallet_service, tx_service, json_rpc_service, std::make_unique( - delegate), - browserState->GetPrefs()); + delegate)); return [[BraveWalletSolanaProviderOwnedImpl alloc] initWithSolanaProvider:std::move(provider)]; }