Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wallet-standard-brave to register Solana wallet-standard (1.47.x) #16907

Merged
merged 2 commits into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions browser/brave_wallet/solana_provider_renderer_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ std::string VectorToArrayString(const std::vector<uint8_t>& vec) {
std::string result;
for (size_t i = 0; i < vec.size(); ++i) {
base::StrAppend(&result, {base::NumberToString(vec[i])});
if (i != vec.size() - 1)
if (i != vec.size() - 1) {
base::StrAppend(&result, {", "});
}
}
return result;
}
Expand Down Expand Up @@ -305,10 +306,11 @@ class TestSolanaProvider final : public brave_wallet::mojom::SolanaProvider {
}
void Disconnect() override {
// Used to test onAccountChanged
if (emit_empty_account_changed_)
if (emit_empty_account_changed_) {
events_listener_->AccountChangedEvent(absl::nullopt);
else
} else {
events_listener_->AccountChangedEvent(kTestPublicKey);
}
}
void IsConnected(IsConnectedCallback callback) override {
if (error_ == SolanaProviderError::kSuccess) {
Expand All @@ -335,9 +337,10 @@ class TestSolanaProvider final : public brave_wallet::mojom::SolanaProvider {
void SignAllTransactions(
std::vector<brave_wallet::mojom::SolanaSignTransactionParamPtr> params,
SignAllTransactionsCallback callback) override {
for (const auto& param : params)
for (const auto& param : params) {
EXPECT_EQ(param->encoded_serialized_msg,
brave_wallet::Base58Encode(kSerializedMessage));
}
if (error_ == SolanaProviderError::kSuccess) {
std::move(callback).Run(SolanaProviderError::kSuccess, "",
{kSignedTx, kSignedTx});
Expand Down Expand Up @@ -400,6 +403,11 @@ class TestSolanaProvider final : public brave_wallet::mojom::SolanaProvider {
}
}

void IsSolanaKeyringCreated(
IsSolanaKeyringCreatedCallback callback) override {
std::move(callback).Run(true);
}

void SetError(SolanaProviderError error, const std::string& error_message) {
error_ = error;
error_message_ = error_message;
Expand Down Expand Up @@ -445,15 +453,17 @@ class TestBraveContentBrowserClient : public BraveContentBrowserClient {
}

TestSolanaProvider* GetProvider(content::RenderFrameHost* frame_host) {
if (!provider_map_.contains(frame_host))
if (!provider_map_.contains(frame_host)) {
return nullptr;
}
return static_cast<TestSolanaProvider*>(
provider_map_.at(frame_host)->impl());
}
bool WaitForBinding(content::RenderFrameHost* render_frame_host,
base::OnceClosure callback) {
if (IsBound(render_frame_host))
if (IsBound(render_frame_host)) {
return false;
}
quit_on_binding_ = std::move(callback);
return true;
}
Expand All @@ -471,8 +481,9 @@ class TestBraveContentBrowserClient : public BraveContentBrowserClient {
base::BindOnce(&TestBraveContentBrowserClient::OnDisconnect,
weak_ptr_factory_.GetWeakPtr(), frame_host));
provider_map_[frame_host] = provider;
if (quit_on_binding_)
if (quit_on_binding_) {
std::move(quit_on_binding_).Run();
}
}
void OnDisconnect(content::RenderFrameHost* frame_host) {
provider_map_.erase(frame_host);
Expand Down
5 changes: 5 additions & 0 deletions browser/speedreader/speedreader_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "brave/browser/speedreader/speedreader_service_factory.h"
#include "brave/browser/speedreader/speedreader_tab_helper.h"
#include "brave/browser/ui/webui/speedreader/speedreader_panel_data_handler_impl.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/constants/brave_paths.h"
#include "brave/components/speedreader/common/constants.h"
#include "brave/components/speedreader/common/features.h"
Expand Down Expand Up @@ -183,6 +184,10 @@ IN_PROC_BROWSER_TEST_F(SpeedReaderBrowserTest, DisableSiteWorks) {
}

IN_PROC_BROWSER_TEST_F(SpeedReaderBrowserTest, SmokeTest) {
// Solana web3.js console warning will interfere with console observer
brave_wallet::SetDefaultSolanaWallet(
browser()->profile()->GetPrefs(),
brave_wallet::mojom::DefaultWallet::None);
ToggleSpeedreader();
NavigateToPageSynchronously(kTestPageReadable);
const std::string kGetStyleLength =
Expand Down
7 changes: 7 additions & 0 deletions components/brave_wallet/browser/solana_provider_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,13 @@ void SolanaProviderImpl::Request(base::Value::Dict arg,
}
}

void SolanaProviderImpl::IsSolanaKeyringCreated(
IsSolanaKeyringCreatedCallback callback) {
DCHECK(keyring_service_);
std::move(callback).Run(
!!keyring_service_->GetSelectedAccount(mojom::CoinType::SOL));
}

bool SolanaProviderImpl::IsAccountConnected(const std::string& account) {
return delegate_->IsSolanaAccountConnected(account);
}
Expand Down
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/solana_provider_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class SolanaProviderImpl final : public mojom::SolanaProvider,
SignMessageCallback callback) override;
void Request(base::Value::Dict arg, RequestCallback callback) override;

void IsSolanaKeyringCreated(IsSolanaKeyringCreatedCallback callback) override;

private:
FRIEND_TEST_ALL_PREFIXES(SolanaProviderImplUnitTest, GetDeserializedMessage);

Expand Down
3 changes: 3 additions & 0 deletions components/brave_wallet/common/brave_wallet.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ interface SolanaProvider {
=> (SolanaProviderError error, string error_message,
mojo_base.mojom.DictionaryValue result);

// DO NOT USE: This is supposed to be a temporary solution for us to decide
// whether to load wallet-standard js module
IsSolanaKeyringCreated() => (bool created);
};

// Used by the WebUI page to bootstrap bidirectional communication.
Expand Down
62 changes: 38 additions & 24 deletions components/brave_wallet/renderer/js_ethereum_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@

namespace {

static base::NoDestructor<std::string> g_provider_script("");

constexpr char kEthereum[] = "ethereum";
constexpr char kEmit[] = "emit";
constexpr char kIsBraveWallet[] = "isBraveWallet";
Expand Down Expand Up @@ -74,8 +72,9 @@ void JSEthereumProvider::SendResponse(
bool force_json_response,
base::Value formed_response,
bool success) {
if (!render_frame())
if (!render_frame()) {
return;
}
v8::HandleScope handle_scope(isolate);
v8::MicrotasksScope microtasks(isolate,
v8::MicrotasksScope::kDoNotRunMicrotasks);
Expand Down Expand Up @@ -112,10 +111,6 @@ void JSEthereumProvider::SendResponse(

JSEthereumProvider::JSEthereumProvider(content::RenderFrame* render_frame)
: RenderFrameObserver(render_frame) {
if (g_provider_script->empty()) {
*g_provider_script = LoadDataResource(
IDR_BRAVE_WALLET_SCRIPT_ETHEREUM_PROVIDER_SCRIPT_BUNDLE_JS);
}
EnsureConnected();
}

Expand All @@ -125,22 +120,25 @@ gin::WrapperInfo JSEthereumProvider::kWrapperInfo = {gin::kEmbedderNativeGin};

void JSEthereumProvider::WillReleaseScriptContext(v8::Local<v8::Context>,
int32_t world_id) {
if (world_id != content::ISOLATED_WORLD_ID_GLOBAL)
if (world_id != content::ISOLATED_WORLD_ID_GLOBAL) {
return;
}
// Close mojo connection from browser to renderer.
receiver_.reset();
script_context_released_ = true;
}

void JSEthereumProvider::DidDispatchDOMContentLoadedEvent() {
if (script_context_released_)
if (script_context_released_) {
return;
}
ConnectEvent();
}

bool JSEthereumProvider::EnsureConnected() {
if (!render_frame())
if (!render_frame()) {
return false;
}

if (!ethereum_provider_.is_bound()) {
render_frame()->GetBrowserInterfaceBroker()->GetInterface(
Expand All @@ -160,22 +158,25 @@ void JSEthereumProvider::Install(bool allow_overwrite_window_ethereum_provider,
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
render_frame->GetWebFrame()->MainWorldScriptContext();
if (context.IsEmpty())
if (context.IsEmpty()) {
return;
}
v8::Context::Scope context_scope(context);

// Check window.ethereum existence.
v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Value> ethereum_value =
global->Get(context, gin::StringToV8(isolate, kEthereum))
.ToLocalChecked();
if (!ethereum_value->IsUndefined())
if (!ethereum_value->IsUndefined()) {
return;
}

gin::Handle<JSEthereumProvider> provider =
gin::CreateHandle(isolate, new JSEthereumProvider(render_frame));
if (provider.IsEmpty())
if (provider.IsEmpty()) {
return;
}
v8::Local<v8::Value> provider_value = provider.ToV8();

if (!allow_overwrite_window_ethereum_provider) {
Expand Down Expand Up @@ -226,7 +227,10 @@ void JSEthereumProvider::Install(bool allow_overwrite_window_ethereum_provider,
gin::StringToV8(isolate, kIsUnlocked), false);

blink::WebLocalFrame* web_frame = render_frame->GetWebFrame();
ExecuteScript(web_frame, *g_provider_script, kEthereumProviderScript);
ExecuteScript(web_frame,
LoadDataResource(
IDR_BRAVE_WALLET_SCRIPT_ETHEREUM_PROVIDER_SCRIPT_BUNDLE_JS),
kEthereumProviderScript);
}

bool JSEthereumProvider::GetIsBraveWallet() {
Expand Down Expand Up @@ -260,8 +264,9 @@ v8::Local<v8::Value> JSEthereumProvider::GetSelectedAddress(
v8::Isolate* isolate) {
// Note this does not return the selected account, but it returns the first
// connected account that was given permissions.
if (first_allowed_account_.empty())
if (first_allowed_account_.empty()) {
return v8::Undefined(isolate);
}
return gin::StringToV8(isolate, first_allowed_account_);
}

Expand Down Expand Up @@ -296,8 +301,9 @@ const char* JSEthereumProvider::GetTypeName() {
// 3) ethereum.send(payload: JsonRpcRequest): unknown;
// Only valid for: eth_accounts, eth_coinbase, eth_uninstallFilter, etc.
v8::Local<v8::Promise> JSEthereumProvider::SendMethod(gin::Arguments* args) {
if (!EnsureConnected())
if (!EnsureConnected()) {
return v8::Local<v8::Promise>();
}
v8::Isolate* isolate = args->isolate();
if (args->Length() == 0) {
args->ThrowError();
Expand Down Expand Up @@ -363,8 +369,9 @@ v8::Local<v8::Promise> JSEthereumProvider::SendMethod(gin::Arguments* args) {
params = base::Value::ToUniquePtrValue(base::ListValue());
}

if (!EnsureConnected())
if (!EnsureConnected()) {
return v8::Local<v8::Promise>();
}

v8::MaybeLocal<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(isolate->GetCurrentContext());
Expand All @@ -387,8 +394,9 @@ v8::Local<v8::Promise> JSEthereumProvider::SendMethod(gin::Arguments* args) {
}

void JSEthereumProvider::SendAsync(gin::Arguments* args) {
if (!EnsureConnected())
if (!EnsureConnected()) {
return;
}
v8::Isolate* isolate = args->isolate();
v8::Local<v8::Value> input;
v8::Local<v8::Function> callback;
Expand Down Expand Up @@ -420,14 +428,16 @@ bool JSEthereumProvider::IsConnected() {

v8::Local<v8::Promise> JSEthereumProvider::Request(v8::Isolate* isolate,
v8::Local<v8::Value> input) {
if (!input->IsObject())
if (!input->IsObject()) {
return v8::Local<v8::Promise>();
}
std::unique_ptr<base::Value> input_value =
content::V8ValueConverter::Create()->FromV8Value(
input, isolate->GetCurrentContext());

if (!EnsureConnected())
if (!EnsureConnected()) {
return v8::Local<v8::Promise>();
}

v8::MaybeLocal<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(isolate->GetCurrentContext());
Expand Down Expand Up @@ -469,8 +479,9 @@ void JSEthereumProvider::OnRequestOrSendAsync(
}

v8::Local<v8::Promise> JSEthereumProvider::Enable(v8::Isolate* isolate) {
if (!EnsureConnected())
if (!EnsureConnected()) {
return v8::Local<v8::Promise>();
}

v8::MaybeLocal<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(isolate->GetCurrentContext());
Expand All @@ -493,8 +504,9 @@ v8::Local<v8::Promise> JSEthereumProvider::Enable(v8::Isolate* isolate) {
}

v8::Local<v8::Promise> JSEthereumProvider::IsUnlocked(v8::Isolate* isolate) {
if (!EnsureConnected())
if (!EnsureConnected()) {
return v8::Local<v8::Promise>();
}

v8::MaybeLocal<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(isolate->GetCurrentContext());
Expand Down Expand Up @@ -537,8 +549,9 @@ void JSEthereumProvider::FireEvent(const std::string& event,
}

void JSEthereumProvider::ConnectEvent() {
if (!EnsureConnected())
if (!EnsureConnected()) {
return;
}

ethereum_provider_->GetChainId(base::BindOnce(
&JSEthereumProvider::OnGetChainId, weak_ptr_factory_.GetWeakPtr()));
Expand All @@ -557,8 +570,9 @@ void JSEthereumProvider::DisconnectEvent(const std::string& message) {
}

void JSEthereumProvider::ChainChangedEvent(const std::string& chain_id) {
if (chain_id_ == chain_id)
if (chain_id_ == chain_id) {
return;
}

FireEvent(ethereum::kChainChangedEvent, base::Value(chain_id));
chain_id_ = chain_id;
Expand Down
Loading