Wallet notifications (#35992)

This commit is contained in:
Anton Paymyshev
2026-05-11 09:55:12 +07:00
committed by GitHub
parent b149d70e12
commit 180de92d08
29 changed files with 513 additions and 437 deletions
+1 -1
View File
@@ -89,6 +89,7 @@ source_set("brave_wallet_delegate") {
"brave_wallet_service_delegate_impl.h",
]
deps += [
"//chrome/browser/notifications",
"//chrome/browser/ui",
"//chrome/browser/ui:browser_tab_strip",
"//chrome/browser/ui/tabs:tab_strip",
@@ -210,7 +211,6 @@ source_set("unit_tests") {
"brave_wallet_hid_chooser_unittest.cc",
"brave_wallet_tab_helper_unittest.cc",
"ethereum_provider_impl_unittest.cc",
"notifications/wallet_notification_service_unittest.cc",
"solana_provider_impl_unittest.cc",
]
deps += [
@@ -5,27 +5,43 @@
#include "brave/components/brave_wallet/browser/brave_wallet_service.h"
#include "base/memory/raw_ptr.h"
#include <optional>
#include "base/command_line.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/run_until.h"
#include "base/test/test_future.h"
#include "brave/browser/brave_wallet/brave_wallet_service_factory.h"
#include "brave/components/brave_wallet/browser/brave_wallet_service_observer_base.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/pref_names.h"
#include "brave/components/brave_wallet/browser/test_utils.h"
#include "brave/components/brave_wallet/browser/tx_service.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "brave/components/constants/brave_paths.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/notification_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/grit/brave_components_strings.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/test_navigation_observer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/public/cpp/notification.h"
#include "url/origin.h"
using base::test::TestFuture;
@@ -72,10 +88,29 @@ class TestBraveWalletServiceObserver
class BraveWalletServiceTest : public InProcessBrowserTest {
public:
BraveWalletServiceTest()
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
: https_server_for_rpc_(net::EmbeddedTestServer::TYPE_HTTPS),
https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
mock_cert_verifier_.SetUpCommandLine(command_line);
}
void SetUpInProcessBrowserTestFixture() override {
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}
void TearDownInProcessBrowserTestFixture() override {
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
notification_tester_ = std::make_unique<NotificationDisplayServiceTester>(
browser()->profile());
base::FilePath test_data_dir;
base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
@@ -102,6 +137,8 @@ class BraveWalletServiceTest : public InProcessBrowserTest {
browser()->profile());
}
TxService* tx_service() { return wallet_service()->tx_service(); }
BraveWalletService* incognito_wallet_service() {
if (!incognito_browser_) {
incognito_browser_ = CreateIncognitoBrowser(browser()->profile());
@@ -116,7 +153,23 @@ class BraveWalletServiceTest : public InProcessBrowserTest {
const net::EmbeddedTestServer* https_server() const { return &https_server_; }
std::vector<message_center::Notification> GetWalletNotifications() {
return notification_tester_->GetDisplayedNotificationsForType(
NotificationHandler::Type::BRAVE_WALLET);
}
void SimulateWalletNotificationClick(const std::string& notification_id) {
notification_tester_->SimulateClick(NotificationHandler::Type::BRAVE_WALLET,
notification_id, std::nullopt,
std::nullopt);
}
protected:
net::EmbeddedTestServer https_server_for_rpc_;
private:
content::ContentMockCertVerifier mock_cert_verifier_;
std::unique_ptr<NotificationDisplayServiceTester> notification_tester_;
raw_ptr<Browser> incognito_browser_ = nullptr;
net::EmbeddedTestServer https_server_;
};
@@ -178,6 +231,59 @@ IN_PROC_BROWSER_TEST_F(BraveWalletServiceTest, IsPrivateWindow) {
TestIsPrivateWindow(wallet_service(), false);
}
IN_PROC_BROWSER_TEST_F(BraveWalletServiceTest, DisplayTxNotification) {
AccountUtils account_utils(wallet_service()->keyring_service());
account_utils.CreateWallet(kMnemonicDripCaution, kTestWalletPassword);
auto account = account_utils.EnsureEthAccount(0);
ASSERT_TRUE(account);
const GURL expected_tx_url("chrome://wallet/crypto/accounts/" +
account->address + "/transactions");
const std::string tx_meta_id = "tx_meta_id";
auto tx_info = mojom::TransactionInfo::New(
tx_meta_id, account->account_id.Clone(), "",
mojom::TxDataUnion::NewEthTxData(
mojom::TxData::New(mojom::kLocalhostChainId, "0x0", "0x1", "0x5208",
"0xbe862ad9abfe6f22bcb087716c7d89a26051f74c",
"0x0", std::vector<uint8_t>())),
mojom::TransactionStatus::Confirmed, mojom::TransactionType::ETHSend,
std::vector<std::string>(), std::vector<std::string>(),
base::Milliseconds(0), base::Milliseconds(0), base::Milliseconds(0),
nullptr, mojom::kLocalhostChainId, std::nullopt, false, nullptr, nullptr);
tx_service()->OnTransactionStatusChanged(std::move(tx_info));
ASSERT_TRUE(base::test::RunUntil(
[&]() { return GetWalletNotifications().size() == 1u; }));
auto notifications = GetWalletNotifications();
ASSERT_EQ(notifications.size(), 1u);
const auto& notification = notifications.front();
EXPECT_EQ(notification.id(), tx_meta_id);
EXPECT_EQ(notification.title(),
l10n_util::GetStringUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_CONFIRMED));
EXPECT_EQ(notification.message(),
l10n_util::GetStringFUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TEXT,
base::UTF8ToUTF16(account->name)));
EXPECT_EQ(notification.origin_url(), expected_tx_url);
EXPECT_TRUE(notification.rich_notification_data().remove_on_click);
EXPECT_EQ(notification.rich_notification_data().context_message, u" ");
content::TestNavigationObserver nav_observer(expected_tx_url);
nav_observer.WatchExistingWebContents();
nav_observer.StartWatchingNewWebContents();
SimulateWalletNotificationClick(tx_meta_id);
nav_observer.Wait();
EXPECT_EQ(browser()
->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL(),
expected_tx_url);
}
IN_PROC_BROWSER_TEST_F(BraveWalletServiceTest,
IsolateTransactionInPrivateWindow) {
AccountUtils account_utils(wallet_service()->keyring_service());
@@ -10,18 +10,24 @@
#include "base/check.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "base/types/expected.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/brave_wallet/browser/permission_utils.h"
#include "brave/components/constants/webui_url_constants.h"
#include "brave/components/permissions/contexts/brave_wallet_permission_context.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/grit/brave_components_strings.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/public/cpp/notification.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -50,6 +56,52 @@ void ClearWalletStoragePartition(content::BrowserContext* context,
base::DoNothing());
}
std::u16string GetStatusTitle(brave_wallet::mojom::TransactionStatus status) {
switch (status) {
case brave_wallet::mojom::TransactionStatus::Confirmed:
return l10n_util::GetStringUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_CONFIRMED);
case brave_wallet::mojom::TransactionStatus::Error:
return l10n_util::GetStringUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_ERROR);
case brave_wallet::mojom::TransactionStatus::Dropped:
return l10n_util::GetStringUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_DROPPED);
default:
break;
}
return std::u16string();
}
void DisplayTxNotificationImpl(content::BrowserContext* context,
brave_wallet::mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url) {
if (auto* notification_display_service =
NotificationDisplayServiceFactory::GetForProfile(
Profile::FromBrowserContext(context))) {
message_center::RichNotificationData notification_data;
notification_data.remove_on_click = true;
notification_data.context_message =
u" "; // Prevent origin from showing in the notification.
auto notification = std::make_unique<message_center::Notification>(
message_center::NOTIFICATION_TYPE_SIMPLE, tx_id, GetStatusTitle(status),
l10n_util::GetStringFUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TEXT,
base::UTF8ToUTF16(account_name)),
ui::ImageModel(), std::u16string(), tx_url,
message_center::NotifierId(
message_center::NotifierType::SYSTEM_COMPONENT, "service.wallet"),
notification_data, nullptr);
notification_display_service->Display(
NotificationHandler::Type::BRAVE_WALLET, *notification, nullptr);
}
}
} // namespace
BraveWalletServiceDelegateImpl::BraveWalletServiceDelegateImpl(
@@ -194,4 +246,12 @@ void BraveWalletServiceDelegateImpl::ClearWalletUIStoragePartition() {
ClearWalletStoragePartition(context_, GURL(kBraveUIWalletPanelURL));
}
void BraveWalletServiceDelegateImpl::DisplayTxNotification(
brave_wallet::mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url) {
DisplayTxNotificationImpl(context_, status, account_name, tx_id, tx_url);
}
} // namespace brave_wallet
@@ -11,7 +11,6 @@
#include <string>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "brave/browser/brave_wallet/brave_wallet_service_delegate_base.h"
@@ -43,6 +42,7 @@ class BraveWalletServiceDelegateImpl : public BraveWalletServiceDelegateBase,
static void SetActiveWebContentsForTesting(
content::WebContents* web_contents);
// BraveWalletServiceDelegateBase:
void IsExternalWalletInstalled(mojom::ExternalWalletType,
IsExternalWalletInstalledCallback) override;
void IsExternalWalletInitialized(
@@ -56,6 +56,11 @@ class BraveWalletServiceDelegateImpl : public BraveWalletServiceDelegateBase,
void ClearWalletUIStoragePartition() override;
void DisplayTxNotification(brave_wallet::mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url) override;
void AddObserver(BraveWalletServiceDelegate::Observer* observer) override;
void RemoveObserver(BraveWalletServiceDelegate::Observer* observer) override;
@@ -60,6 +60,7 @@
#include "content/public/test/browser_task_environment.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "ui/base/l10n/l10n_util.h"
@@ -302,6 +303,22 @@ class TestBraveWalletServiceObserver
observer_receiver_{this};
};
class MockBraveWalletServiceDelegate : public BraveWalletServiceDelegate {
public:
MockBraveWalletServiceDelegate() = default;
~MockBraveWalletServiceDelegate() override = default;
MOCK_METHOD(void,
DisplayTxNotification,
(mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url),
(override));
MOCK_METHOD(base::FilePath, GetWalletBaseDirectory, (), (override));
MOCK_METHOD(bool, IsPrivateWindow, (), (override));
};
class BraveWalletServiceUnitTest : public testing::Test {
public:
BraveWalletServiceUnitTest()
@@ -888,6 +905,11 @@ class BraveWalletServiceUnitTest : public testing::Test {
AccountUtils GetAccountUtils() { return AccountUtils(keyring_service_); }
mojo::Receiver<brave_wallet::mojom::TxServiceObserver>&
GetTxServiceObserverReceiver() {
return service_->tx_service_observer_receiver_;
}
content::BrowserTaskEnvironment task_environment_;
network::TestURLLoaderFactory url_loader_factory_;
TestingPrefServiceSimple local_state_;
@@ -3430,4 +3452,56 @@ TEST_F(BraveWalletServiceUnitTest, GetNetworkForAccountOnActiveOrigin) {
mojom::kCardanoTestnet);
}
TEST_F(BraveWalletServiceUnitTest, DisplayTxNotification) {
SetupWallet();
auto delegate =
std::make_unique<testing::NiceMock<MockBraveWalletServiceDelegate>>();
auto* delegate_ptr = delegate.get();
service_->SetDelegateForTesting(std::move(delegate));
auto account = GetAccountUtils().EnsureEthAccount(0);
ASSERT_TRUE(account);
const GURL expected_tx_url("chrome://wallet/crypto/accounts/" +
account->address + "/transactions");
struct TestCase {
mojom::TransactionStatus status;
uint32_t times_called;
};
std::vector<TestCase> test_cases = {
{mojom::TransactionStatus::Unapproved, 0},
{mojom::TransactionStatus::Approved, 0},
{mojom::TransactionStatus::Rejected, 0},
{mojom::TransactionStatus::Submitted, 0},
{mojom::TransactionStatus::Confirmed, 1},
{mojom::TransactionStatus::Error, 1},
{mojom::TransactionStatus::Dropped, 1},
{mojom::TransactionStatus::Signed, 0},
};
for (auto test_case : test_cases) {
SCOPED_TRACE(test_case.status);
auto tx_info = mojom::TransactionInfo::New(
"tx_meta_id", account->account_id.Clone(), "",
mojom::TxDataUnion::NewEthTxData(
mojom::TxData::New(mojom::kLocalhostChainId, "0x0", "0x1", "0x5208",
"0xbe862ad9abfe6f22bcb087716c7d89a26051f74c",
"0x0", std::vector<uint8_t>())),
test_case.status, mojom::TransactionType::ETHSend,
std::vector<std::string>(), std::vector<std::string>(),
base::Milliseconds(0), base::Milliseconds(0), base::Milliseconds(0),
nullptr, mojom::kLocalhostChainId, std::nullopt, false, nullptr,
nullptr);
EXPECT_CALL(*delegate_ptr,
DisplayTxNotification(test_case.status, account->name,
tx_info->id, expected_tx_url))
.Times(test_case.times_called);
tx_service_->OnTransactionStatusChanged(tx_info.Clone());
GetTxServiceObserverReceiver().FlushForTesting();
testing::Mock::VerifyAndClearExpectations(delegate_ptr);
}
}
} // namespace brave_wallet
@@ -0,0 +1,28 @@
# Copyright (c) 2026 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("//brave/components/brave_wallet/common/buildflags/buildflags.gni")
assert(enable_brave_wallet)
assert(!is_android)
source_set("notifications") {
sources = [
"brave_wallet_notification_handler.cc",
"brave_wallet_notification_handler.h",
]
deps = [
"//brave/browser/brave_wallet",
"//brave/components/brave_wallet/browser",
"//chrome/browser/ui",
"//chrome/browser/ui/browser_window",
]
public_deps = [
"//base",
"//chrome/browser/notifications",
]
}
@@ -0,0 +1,51 @@
/* Copyright (c) 2026 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/browser/brave_wallet/notifications/brave_wallet_notification_handler.h"
#include <optional>
#include "brave/browser/ui/brave_pages.h"
#include "build/build_config.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h"
#include "url/gurl.h"
namespace brave_wallet {
BraveWalletNotificationHandler::BraveWalletNotificationHandler(Profile& profile)
: profile_(profile) {}
BraveWalletNotificationHandler::~BraveWalletNotificationHandler() = default;
void BraveWalletNotificationHandler::OnClick(
Profile* profile,
const GURL& origin,
const std::string& notification_id,
const std::optional<int>& action_index,
const std::optional<std::u16string>& reply,
base::OnceClosure completed_closure) {
BrowserWindowInterface* browser = nullptr;
ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
[profile, &browser](BrowserWindowInterface* bwi) {
if (bwi->GetProfile() == profile) {
browser = bwi;
return false;
}
return true;
});
if (browser) {
brave::ShowBraveWalletTxNotificationUrl(browser, origin);
}
std::move(completed_closure).Run();
}
} // namespace brave_wallet
@@ -0,0 +1,49 @@
/* Copyright (c) 2026 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_BROWSER_BRAVE_WALLET_NOTIFICATIONS_BRAVE_WALLET_NOTIFICATION_HANDLER_H_
#define BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_BRAVE_WALLET_NOTIFICATION_HANDLER_H_
#include <optional>
#include <string>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "chrome/browser/notifications/notification_handler.h"
class GURL;
class Profile;
namespace brave_wallet {
class BraveWalletNotificationHandler : public NotificationHandler {
public:
explicit BraveWalletNotificationHandler(Profile& profile);
BraveWalletNotificationHandler(const BraveWalletNotificationHandler&) =
delete;
BraveWalletNotificationHandler& operator=(
const BraveWalletNotificationHandler&) = delete;
BraveWalletNotificationHandler(BraveWalletNotificationHandler&&) = delete;
BraveWalletNotificationHandler& operator=(BraveWalletNotificationHandler&&) =
delete;
~BraveWalletNotificationHandler() override;
// NotificationHandler:
void OnClick(Profile* profile,
const GURL& origin,
const std::string& notification_id,
const std::optional<int>& action_index,
const std::optional<std::u16string>& reply,
base::OnceClosure completed_closure) override;
private:
const raw_ref<Profile> profile_;
};
} // namespace brave_wallet
#endif // BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_BRAVE_WALLET_NOTIFICATION_HANDLER_H_
@@ -1,17 +0,0 @@
# Copyright (c) 2022 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
brave_browser_brave_wallet_deps =
[ "//brave/components/brave_wallet/browser:pref_names" ]
brave_browser_brave_wallet_sources = []
if (!is_android) {
brave_browser_brave_wallet_sources += [
"//brave/browser/brave_wallet/notifications/wallet_notification_service.cc",
"//brave/browser/brave_wallet/notifications/wallet_notification_service.h",
"//brave/browser/brave_wallet/notifications/wallet_notification_service_factory.cc",
"//brave/browser/brave_wallet/notifications/wallet_notification_service_factory.h",
]
}
@@ -1,117 +0,0 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/browser/brave_wallet/notifications/wallet_notification_service.h"
#include <memory>
#include <string>
#include "base/strings/utf_string_conversions.h"
#include "brave/components/brave_wallet/browser/brave_wallet_service.h"
#include "brave/components/brave_wallet/browser/tx_service.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/grit/brave_components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/public/cpp/notifier_id.h"
namespace {
int GetStatusTitle(brave_wallet::mojom::TransactionStatus status) {
switch (status) {
case brave_wallet::mojom::TransactionStatus::Confirmed:
return IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_CONFIRMED;
case brave_wallet::mojom::TransactionStatus::Error:
return IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_ERROR;
case brave_wallet::mojom::TransactionStatus::Dropped:
return IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TITLE_DROPPED;
default:
break;
}
return -1;
}
std::unique_ptr<message_center::Notification> CreateMessageCenterNotification(
const std::u16string& title,
const std::u16string& body,
const std::string& uuid,
const GURL& link) {
message_center::RichNotificationData notification_data;
// hack to prevent origin from showing in the notification
notification_data.context_message = u" ";
auto notification = std::make_unique<message_center::Notification>(
message_center::NOTIFICATION_TYPE_SIMPLE, uuid, title, body,
ui::ImageModel(), std::u16string(), link,
message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
"service.wallet"),
notification_data, nullptr);
return notification;
}
void PushNotification(content::BrowserContext* context,
const std::string& uuid,
const std::string& from,
const std::u16string& title,
const std::u16string& body) {
auto notification = CreateMessageCenterNotification(
title, body, uuid,
GURL("brave://wallet/crypto/accounts/" + from + "#" + uuid));
auto* profile = Profile::FromBrowserContext(context);
NotificationDisplayServiceFactory::GetForProfile(profile)->Display(
NotificationHandler::Type::ANNOUNCEMENT, *notification, nullptr);
}
} // namespace
namespace brave_wallet {
WalletNotificationService::WalletNotificationService(
BraveWalletService* brave_wallet_service,
content::BrowserContext* context)
: brave_wallet_service_(brave_wallet_service), context_(context) {
if (brave_wallet_service_) {
brave_wallet_service_->tx_service()->AddObserver(
tx_observer_receiver_.BindNewPipeAndPassRemote());
}
}
WalletNotificationService::~WalletNotificationService() = default;
bool WalletNotificationService::ShouldDisplayUserNotification(
mojom::TransactionStatus status) {
return (status == mojom::TransactionStatus::Confirmed ||
status == mojom::TransactionStatus::Error ||
status == mojom::TransactionStatus::Dropped);
}
void WalletNotificationService::DisplayUserNotification(
mojom::TransactionStatus status,
const std::string& address,
const std::string& tx_id) {
PushNotification(context_, tx_id, address,
l10n_util::GetStringUTF16(GetStatusTitle(status)),
l10n_util::GetStringFUTF16(
IDS_WALLET_TRANSACTION_STATUS_UPDATE_MESSAGE_TEXT,
base::UTF8ToUTF16(address)));
}
void WalletNotificationService::OnTransactionStatusChanged(
mojom::TransactionInfoPtr tx_info) {
if (ShouldDisplayUserNotification(tx_info->tx_status)) {
auto account = brave_wallet_service_->keyring_service()->FindAccount(
tx_info->from_account_id);
if (!account) {
return;
}
DisplayUserNotification(tx_info->tx_status, account->name, tx_info->id);
}
}
} // namespace brave_wallet
@@ -1,54 +0,0 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_H_
#define BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_H_
#include <string>
#include "base/memory/raw_ptr.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "components/keyed_service/core/keyed_service.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace content {
class BrowserContext;
} // namespace content
namespace brave_wallet {
class BraveWalletService;
class WalletNotificationService : public KeyedService,
public mojom::TxServiceObserver {
public:
WalletNotificationService(BraveWalletService* brave_wallet_service,
content::BrowserContext* context);
~WalletNotificationService() override;
WalletNotificationService(const WalletNotificationService&) = delete;
WalletNotificationService operator=(const WalletNotificationService&) =
delete;
// mojom::TxServiceObserver
void OnNewUnapprovedTx(mojom::TransactionInfoPtr tx_info) override {}
void OnUnapprovedTxUpdated(mojom::TransactionInfoPtr tx_info) override {}
void OnTransactionStatusChanged(mojom::TransactionInfoPtr tx_info) override;
void OnTxServiceReset() override {}
private:
friend class WalletNotificationServiceUnitTest;
bool ShouldDisplayUserNotification(mojom::TransactionStatus status);
void DisplayUserNotification(mojom::TransactionStatus status,
const std::string& address,
const std::string& tx_id);
raw_ptr<BraveWalletService> brave_wallet_service_;
raw_ptr<content::BrowserContext> context_;
mojo::Receiver<mojom::TxServiceObserver> tx_observer_receiver_{this};
};
} // namespace brave_wallet
#endif // BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_H_
@@ -1,54 +0,0 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/browser/brave_wallet/notifications/wallet_notification_service_factory.h"
#include <memory>
#include "base/no_destructor.h"
#include "brave/browser/brave_wallet/brave_wallet_context_utils.h"
#include "brave/browser/brave_wallet/brave_wallet_service_factory.h"
#include "brave/browser/brave_wallet/notifications/wallet_notification_service.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
namespace brave_wallet {
// static
WalletNotificationServiceFactory*
WalletNotificationServiceFactory::GetInstance() {
static base::NoDestructor<WalletNotificationServiceFactory> instance;
return instance.get();
}
WalletNotificationServiceFactory::WalletNotificationServiceFactory()
: BrowserContextKeyedServiceFactory(
"WalletNotificationService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(NotificationDisplayServiceFactory::GetInstance());
DependsOn(brave_wallet::BraveWalletServiceFactory::GetInstance());
}
WalletNotificationServiceFactory::~WalletNotificationServiceFactory() = default;
std::unique_ptr<KeyedService>
WalletNotificationServiceFactory::BuildServiceInstanceForBrowserContext(
content::BrowserContext* context) const {
return std::make_unique<WalletNotificationService>(
BraveWalletServiceFactory::GetServiceForContext(context), context);
}
// static
WalletNotificationService*
WalletNotificationServiceFactory::GetServiceForContext(
content::BrowserContext* context) {
if (!IsAllowedForContext(context)) {
return nullptr;
}
return static_cast<WalletNotificationService*>(
GetInstance()->GetServiceForBrowserContext(context, true));
}
} // namespace brave_wallet
@@ -1,50 +0,0 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_FACTORY_H_
#define BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_FACTORY_H_
#include <memory>
#include "brave/browser/brave_wallet/notifications/wallet_notification_service.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
static_assert(BUILDFLAG(ENABLE_BRAVE_WALLET));
namespace base {
template <typename T>
class NoDestructor;
} // namespace base
namespace brave_wallet {
// Singleton that owns all WalletNotificationService and associates them with
// BrowserContext.
class WalletNotificationServiceFactory
: public BrowserContextKeyedServiceFactory {
public:
WalletNotificationServiceFactory(const WalletNotificationServiceFactory&) =
delete;
WalletNotificationServiceFactory& operator=(
const WalletNotificationServiceFactory&) = delete;
static WalletNotificationServiceFactory* GetInstance();
static WalletNotificationService* GetServiceForContext(
content::BrowserContext* context);
private:
friend base::NoDestructor<WalletNotificationServiceFactory>;
WalletNotificationServiceFactory();
~WalletNotificationServiceFactory() override;
// BrowserContextKeyedServiceFactory:
std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
content::BrowserContext* context) const override;
};
} // namespace brave_wallet
#endif // BRAVE_BROWSER_BRAVE_WALLET_NOTIFICATIONS_WALLET_NOTIFICATION_SERVICE_FACTORY_H_
@@ -1,118 +0,0 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/browser/brave_wallet/notifications/wallet_notification_service.h"
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/files/scoped_temp_dir.h"
#include "brave/components/brave_wallet/browser/brave_wallet_service.h"
#include "brave/components/brave_wallet/browser/eth_transaction.h"
#include "brave/components/brave_wallet/browser/eth_tx_meta.h"
#include "brave/components/brave_wallet/browser/keyring_service.h"
#include "brave/components/brave_wallet/browser/pref_names.h"
#include "brave/components/brave_wallet/browser/test_utils.h"
#include "brave/components/brave_wallet/browser/tx_service.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace brave_wallet {
class WalletNotificationServiceUnitTest : public testing::Test {
public:
WalletNotificationServiceUnitTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
void SetUp() override {
RegisterLocalStatePrefs(local_state_.registry());
RegisterLocalStatePrefsForMigration(local_state_.registry());
brave_wallet_service_ = std::make_unique<BraveWalletService>(
url_loader_factory_.GetSafeWeakWrapper(),
TestBraveWalletServiceDelegate::Create(), prefs(), local_state());
notification_service_ = std::make_unique<WalletNotificationService>(
brave_wallet_service_.get(), profile());
tester_ = std::make_unique<NotificationDisplayServiceTester>(profile());
GetAccountUtils().CreateWallet(kMnemonicDivideCruise, kTestWalletPassword);
}
Profile* profile() { return &profile_; }
PrefService* prefs() { return profile_.GetPrefs(); }
PrefService* local_state() { return &local_state_; }
AccountUtils GetAccountUtils() {
return AccountUtils(brave_wallet_service_->keyring_service());
}
mojom::AccountIdPtr EthAccount(size_t index) {
return GetAccountUtils().EnsureEthAccount(index)->account_id->Clone();
}
bool ShouldDisplayNotifications(mojom::TransactionStatus status) {
return notification_service_->ShouldDisplayUserNotification(status);
}
bool WasNotificationDisplayedOnStatusChange(mojom::TransactionStatus status) {
std::unique_ptr<EthTransaction> tx = std::make_unique<EthTransaction>(
*EthTransaction::FromTxData(mojom::TxData::New(
mojom::kMainnetChainId, "0x01", "0x4a817c800", "0x5208",
"0x3535353535353535353535353535353535353535", "0x0de0b6b3a7640000",
std::vector<uint8_t>())));
EthTxMeta meta(EthAccount(0), std::move(tx));
meta.set_status(status);
notification_service_->OnTransactionStatusChanged(meta.ToTransactionInfo());
auto notification = tester_->GetNotification(meta.id());
tester_->RemoveAllNotifications(NotificationHandler::Type::ANNOUNCEMENT,
true /* by_user */);
return notification.has_value();
}
private:
content::BrowserTaskEnvironment task_environment_;
base::ScopedTempDir temp_dir_;
std::unique_ptr<NotificationDisplayServiceTester> tester_;
TestingProfile profile_;
TestingPrefServiceSimple local_state_;
network::TestURLLoaderFactory url_loader_factory_;
std::unique_ptr<BraveWalletService> brave_wallet_service_;
std::unique_ptr<WalletNotificationService> notification_service_;
};
TEST_F(WalletNotificationServiceUnitTest, ShouldShowNotifications) {
EXPECT_TRUE(ShouldDisplayNotifications(mojom::TransactionStatus::Confirmed));
EXPECT_TRUE(ShouldDisplayNotifications(mojom::TransactionStatus::Error));
EXPECT_TRUE(ShouldDisplayNotifications(mojom::TransactionStatus::Dropped));
EXPECT_FALSE(ShouldDisplayNotifications(mojom::TransactionStatus::Approved));
EXPECT_FALSE(ShouldDisplayNotifications(mojom::TransactionStatus::Rejected));
EXPECT_FALSE(ShouldDisplayNotifications(mojom::TransactionStatus::Submitted));
}
TEST_F(WalletNotificationServiceUnitTest, TransactionStatusChanged) {
EXPECT_TRUE(WasNotificationDisplayedOnStatusChange(
mojom::TransactionStatus::Confirmed));
EXPECT_TRUE(
WasNotificationDisplayedOnStatusChange(mojom::TransactionStatus::Error));
EXPECT_TRUE(WasNotificationDisplayedOnStatusChange(
mojom::TransactionStatus::Dropped));
EXPECT_FALSE(WasNotificationDisplayedOnStatusChange(
mojom::TransactionStatus::Approved));
EXPECT_FALSE(WasNotificationDisplayedOnStatusChange(
mojom::TransactionStatus::Rejected));
EXPECT_FALSE(WasNotificationDisplayedOnStatusChange(
mojom::TransactionStatus::Submitted));
}
} // namespace brave_wallet
@@ -106,7 +106,6 @@
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
#include "brave/browser/brave_wallet/brave_wallet_service_factory.h"
#include "brave/browser/brave_wallet/notifications/wallet_notification_service_factory.h"
#endif
#if BUILDFLAG(ENABLE_BRAVE_NEWS)
@@ -169,9 +168,6 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
#endif
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
#if !BUILDFLAG(IS_ANDROID)
brave_wallet::WalletNotificationServiceFactory::GetInstance();
#endif
brave_wallet::BraveWalletServiceFactory::GetInstance();
#endif
+1
View File
@@ -4,6 +4,7 @@
# You can obtain one at https://mozilla.org/MPL/2.0/.
import("//brave/components/brave_ads/buildflags/buildflags.gni")
import("//brave/components/brave_wallet/common/buildflags/buildflags.gni")
assert(enable_brave_ads)
+4 -6
View File
@@ -63,7 +63,6 @@ if (enable_brave_rewards) {
if (enable_brave_wallet) {
import("//brave/browser/brave_wallet/android/sources.gni")
import("//brave/browser/brave_wallet/notifications/sources.gni")
}
if (enable_playlist) {
@@ -355,6 +354,10 @@ if (enable_brave_wallet) {
"//brave/components/decentralized_dns/content",
"//brave/components/decentralized_dns/core",
]
if (!is_android) {
brave_chrome_browser_deps +=
[ "//brave/browser/brave_wallet/notifications" ]
}
}
if (enable_email_aliases) {
@@ -767,11 +770,6 @@ brave_chrome_browser_deps += brave_browser_webcompat_reporter_deps
brave_chrome_browser_deps += brave_chromium_src_chrome_browser_deps
brave_chrome_browser_deps += brave_chromium_src_chrome_browser_prefs_deps
if (enable_brave_wallet) {
brave_chrome_browser_sources += brave_browser_brave_wallet_sources
brave_chrome_browser_deps += brave_browser_brave_wallet_deps
}
brave_chrome_browser_ui_allow_circular_includes_from = [ "//brave/browser/ui" ]
brave_chrome_browser_ui_allow_circular_includes_from +=
brave_ui_allow_circular_includes_from
+10 -9
View File
@@ -7,7 +7,6 @@
#include <string_view>
#include "base/strings/strcat.h"
#include "brave/browser/ui/webui/webcompat_reporter/webcompat_reporter_dialog.h"
#include "brave/components/brave_talk/buildflags/buildflags.h"
#include "brave/components/constants/webui_url_constants.h"
@@ -76,6 +75,7 @@ void ShowWebcompatReporter(Browser* browser) {
web_contents, webcompat_reporter::UISource::kAppMenu);
}
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
void ShowBraveWallet(Browser* browser) {
ShowSingletonTabOverwritingNTP(browser, GURL(kBraveUIWalletURL));
}
@@ -84,20 +84,21 @@ void ShowBraveWalletOnboarding(Browser* browser) {
ShowSingletonTabOverwritingNTP(browser, GURL(kBraveUIWalletOnboardingURL));
}
void ShowBraveWalletTxNotificationUrl(BrowserWindowInterface* browser,
GURL url) {
if (url.GetWithEmptyPath() != GURL(kBraveUIWalletURL)) {
return;
}
ShowSingletonTabOverwritingNTP(browser, url);
}
void ShowBraveWalletAccountCreation(Browser* browser,
std::string_view coin_name) {
ShowSingletonTabOverwritingNTP(
browser,
GURL(base::StrCat({kBraveUIWalletAccountCreationURL, coin_name})));
}
void ShowExtensionSettings(Browser* browser) {
ShowSingletonTabOverwritingNTP(browser, GURL(kExtensionSettingsURL));
}
void ShowWalletSettings(Browser* browser) {
ShowSingletonTabOverwritingNTP(browser, GURL(kWalletSettingsURL));
}
#endif
void ShowAppsPage(Browser* browser) {
ShowSingletonTabOverwritingNTP(browser, GURL(chrome::kChromeUIAppsURL));
+7 -1
View File
@@ -10,20 +10,26 @@
#include "brave/components/ai_chat/core/common/buildflags/buildflags.h"
#include "brave/components/brave_talk/buildflags/buildflags.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
class Browser;
class BrowserWindowInterface;
class GURL;
namespace brave {
void ShowBraveAdblock(Browser* browser);
void ShowWebcompatReporter(Browser* browser);
void ShowBraveRewards(Browser* browser);
#if BUILDFLAG(ENABLE_BRAVE_WALLET)
void ShowBraveWallet(Browser* browser);
void ShowBraveWalletOnboarding(Browser* browser);
void ShowBraveWalletTxNotificationUrl(BrowserWindowInterface* browser,
GURL url);
void ShowBraveWalletAccountCreation(Browser* browser,
std::string_view coin_name);
#endif
void ShowExtensionSettings(Browser* browser);
void ShowWalletSettings(Browser* browser);
void ShowSync(Browser* browser);
void ShowBraveNewsConfigure(Browser* browser);
void ShowShortcutsPage(Browser* browser);
@@ -1,5 +1,6 @@
specific_include_rules = {
"notification_display_service_impl\.cc": [
"+brave/components/brave_ads/buildflags/buildflags.h",
"+brave/components/brave_wallet/common/buildflags/buildflags.h",
],
}
@@ -4,10 +4,13 @@
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/components/brave_ads/buildflags/buildflags.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
#include "build/build_config.h"
#if BUILDFLAG(ENABLE_BRAVE_ADS)
#include "brave/browser/notifications/ads_notification_handler.h"
#include "brave/browser/notifications/ads_notification_handler.h" // IWYU pragma: keep
// CHROMIUM_SRC_INTERNAL_USE
#define BRAVE_ADD_BRAVE_ADS_NOTIFICATION_HANDLER \
AddNotificationHandler( \
NotificationHandler::Type::BRAVE_ADS, \
@@ -16,5 +19,24 @@
#define BRAVE_ADD_BRAVE_ADS_NOTIFICATION_HANDLER
#endif // BUILDFLAG(ENABLE_BRAVE_ADS)
#if BUILDFLAG(ENABLE_BRAVE_WALLET) && !BUILDFLAG(IS_ANDROID)
#include "brave/browser/brave_wallet/notifications/brave_wallet_notification_handler.h" // IWYU pragma: keep
// CHROMIUM_SRC_INTERNAL_USE
#define BRAVE_ADD_BRAVE_WALLET_NOTIFICATION_HANDLER \
AddNotificationHandler( \
NotificationHandler::Type::BRAVE_WALLET, \
std::make_unique<brave_wallet::BraveWalletNotificationHandler>( \
*profile));
#else
#define BRAVE_ADD_BRAVE_WALLET_NOTIFICATION_HANDLER
#endif // BUILDFLAG(ENABLE_BRAVE_WALLET) && !BUILDFLAG(IS_ANDROID)
#define BRAVE_NOTIFICATION_DISPLAY_SERVICE_IMPL_CONSTRUCTOR \
BRAVE_ADD_BRAVE_ADS_NOTIFICATION_HANDLER; \
BRAVE_ADD_BRAVE_WALLET_NOTIFICATION_HANDLER
#include <chrome/browser/notifications/notification_display_service_impl.cc>
#undef BRAVE_ADD_BRAVE_ADS_NOTIFICATION_HANDLER
#undef BRAVE_ADD_BRAVE_WALLET_NOTIFICATION_HANDLER
#undef BRAVE_NOTIFICATION_DISPLAY_SERVICE_IMPL_CONSTRUCTOR
@@ -27,7 +27,8 @@ class NotificationHandler : public NotificationHandler_ChromiumImpl {
NOTIFICATIONS_MUTED = 10,
TAILORED_SECURITY = 11,
DEFAULT_BROWSER_CHANGED = 12,
MAX = DEFAULT_BROWSER_CHANGED,
BRAVE_WALLET = 13,
MAX = BRAVE_WALLET,
};
static_assert(
+1
View File
@@ -270,6 +270,7 @@ static_library("browser") {
"tx_meta.h",
"tx_service.cc",
"tx_service.h",
"tx_service_observer_base.h",
"tx_state_manager.cc",
"tx_state_manager.h",
"tx_storage.cc",
@@ -62,6 +62,22 @@ namespace {
inline constexpr char kZCashDataFolderName[] = "zcash_data";
bool ShouldDisplayTxNotification(mojom::TransactionStatus status) {
return (status == mojom::TransactionStatus::Confirmed ||
status == mojom::TransactionStatus::Error ||
status == mojom::TransactionStatus::Dropped);
}
GURL GetTxNotificationUrl(const mojom::AccountInfoPtr& account) {
// Matches `makeAccountRoute` in brave_wallet_routes.ts
auto account_route_entry = account->address.empty()
? account->account_id->unique_key
: account->address;
return GURL(base::StrCat({"chrome://wallet/crypto/accounts/",
account_route_entry, "/transactions"}));
}
bool AccountMatchesCoinAndChain(const mojom::AccountId& account_id,
mojom::CoinType coin,
const std::string& chain_id) {
@@ -272,6 +288,8 @@ BraveWalletService::BraveWalletService(
&BraveWalletService::OnWalletReset, weak_ptr_factory_.GetWeakPtr()));
keyring_service_->AddObserver(
keyring_observer_receiver_.BindNewPipeAndPassRemote());
tx_service_->AddObserver(
tx_service_observer_receiver_.BindNewPipeAndPassRemote());
DCHECK(profile_prefs_);
@@ -1411,6 +1429,21 @@ void BraveWalletService::WalletRestored() {
account_discovery_manager_->StartDiscovery();
}
void BraveWalletService::OnTransactionStatusChanged(
mojom::TransactionInfoPtr tx_info) {
if (!ShouldDisplayTxNotification(tx_info->tx_status)) {
return;
}
auto account = keyring_service()->FindAccount(tx_info->from_account_id);
if (!account) {
return;
}
delegate_->DisplayTxNotification(tx_info->tx_status, account->name,
tx_info->id, GetTxNotificationUrl(account));
}
void BraveWalletService::OnDiscoverAssetsStarted() {
for (const auto& observer : observers_) {
observer->OnDiscoverAssetsStarted();
@@ -2164,4 +2197,9 @@ void BraveWalletService::OnWalletReset() {
account_discovery_manager_.reset();
}
void BraveWalletService::SetDelegateForTesting( // IN-TEST
std::unique_ptr<BraveWalletServiceDelegate> delegate) {
delegate_ = std::move(delegate);
}
} // namespace brave_wallet
@@ -23,8 +23,10 @@
#include "brave/components/brave_wallet/browser/brave_wallet_p3a.h"
#include "brave/components/brave_wallet/browser/brave_wallet_service_delegate.h"
#include "brave/components/brave_wallet/browser/cardano/cardano_wallet_service.h"
#include "brave/components/brave_wallet/browser/keyring_service_observer_base.h"
#include "brave/components/brave_wallet/browser/polkadot/polkadot_wallet_service.h"
#include "brave/components/brave_wallet/browser/simple_hash_client.h"
#include "brave/components/brave_wallet/browser/tx_service_observer_base.h"
#include "brave/components/brave_wallet/browser/zcash/zcash_wallet_service.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
@@ -63,6 +65,7 @@ struct PendingGetEncryptPublicKeyRequest;
class BraveWalletService : public KeyedService,
public mojom::BraveWalletService,
public KeyringServiceObserverBase,
public TxServiceObserverBase,
public BraveWalletServiceDelegate::Observer {
public:
using APIRequestHelper = api_request_helper::APIRequestHelper;
@@ -299,6 +302,9 @@ class BraveWalletService : public KeyedService,
// KeyringServiceObserverBase:
void WalletRestored() override;
// TxServiceObserverBase:
void OnTransactionStatusChanged(mojom::TransactionInfoPtr tx_info) override;
void OnDiscoverAssetsStarted();
void OnDiscoverAssetsCompleted(
@@ -350,6 +356,9 @@ class BraveWalletService : public KeyedService,
return delegate_.get();
}
void SetDelegateForTesting(
std::unique_ptr<BraveWalletServiceDelegate> delegate);
base::CallbackListSubscription RegisterSignMessageRequestAddedCallback(
base::RepeatingClosure cb);
base::CallbackListSubscription RegisterSignTransactionRequestAddedCallback(
@@ -507,6 +516,8 @@ class BraveWalletService : public KeyedService,
mojo::ReceiverSet<mojom::BraveWalletService> receivers_;
mojo::Receiver<brave_wallet::mojom::KeyringServiceObserver>
keyring_observer_receiver_{this};
mojo::Receiver<brave_wallet::mojom::TxServiceObserver>
tx_service_observer_receiver_{this};
PrefChangeRegistrar pref_change_registrar_;
base::WeakPtrFactory<BraveWalletService> weak_ptr_factory_;
};
@@ -85,4 +85,12 @@ void BraveWalletServiceDelegate::ResetWebSitePermission(
std::move(callback).Run(false);
}
void BraveWalletServiceDelegate::DisplayTxNotification(
brave_wallet::mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url) {
NOTIMPLEMENTED();
}
} // namespace brave_wallet
@@ -82,6 +82,11 @@ class BraveWalletServiceDelegate {
virtual bool IsPrivateWindow() = 0;
virtual void DisplayTxNotification(mojom::TransactionStatus status,
const std::string& account_name,
const std::string& tx_id,
const GURL& tx_url);
static std::unique_ptr<BraveWalletServiceDelegate> Create(
content::BrowserContext* browser_context);
};
@@ -0,0 +1,24 @@
/* Copyright (c) 2026 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_BRAVE_WALLET_BROWSER_TX_SERVICE_OBSERVER_BASE_H_
#define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_TX_SERVICE_OBSERVER_BASE_H_
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "brave/components/brave_wallet/common/buildflags/buildflags.h"
static_assert(BUILDFLAG(ENABLE_BRAVE_WALLET));
namespace brave_wallet {
class TxServiceObserverBase : public mojom::TxServiceObserver {
void OnNewUnapprovedTx(mojom::TransactionInfoPtr tx_info) override {}
void OnUnapprovedTxUpdated(mojom::TransactionInfoPtr tx_info) override {}
void OnTransactionStatusChanged(mojom::TransactionInfoPtr tx_info) override {}
void OnTxServiceReset() override {}
};
} // namespace brave_wallet
#endif // BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_TX_SERVICE_OBSERVER_BASE_H_
@@ -6,7 +6,7 @@ index c185575c57d0f0e72edc3c9bcfc5874e4c2a63dd..0632480d7827cf594eb696db0237068e
std::make_unique<NearbyNotificationHandler>());
}
#endif
+ BRAVE_ADD_BRAVE_ADS_NOTIFICATION_HANDLER;
+ BRAVE_NOTIFICATION_DISPLAY_SERVICE_IMPL_CONSTRUCTOR;
}
bridge_delegator_ = std::make_unique<NotificationPlatformBridgeDelegator>(