diff --git a/android/BUILD.gn b/android/BUILD.gn index 475eed353c08..14050578f924 100644 --- a/android/BUILD.gn +++ b/android/BUILD.gn @@ -8,7 +8,7 @@ declare_args() { java_cpp_enum("brave_android_java_enums_srcjar") { sources = [ "//brave/chromium_src/chrome/browser/notifications/notification_handler.h", - "//brave/components/decentralized_dns/constants.h", + "//brave/components/decentralized_dns/core/constants.h", ] } diff --git a/app/brave_settings_strings.grdp b/app/brave_settings_strings.grdp index 600ddd192746..a2ba34f2c1ea 100644 --- a/app/brave_settings_strings.grdp +++ b/app/brave_settings_strings.grdp @@ -670,6 +670,12 @@ Method to resolve Ethereum Name Service (ENS) + + Allow ENS offchain lookup. + + + <a target="_blank" href="$1">Learn More</a> about ENS offchain lookup privacy considerations. + Private window with Tor diff --git a/browser/android/preferences/brave_pref_service_bridge.cc b/browser/android/preferences/brave_pref_service_bridge.cc index 5058fd1dcf23..ae8921655895 100644 --- a/browser/android/preferences/brave_pref_service_bridge.cc +++ b/browser/android/preferences/brave_pref_service_bridge.cc @@ -16,7 +16,7 @@ #include "brave/components/brave_today/common/pref_names.h" #include "brave/components/constants/pref_names.h" #include "brave/components/de_amp/common/pref_names.h" -#include "brave/components/decentralized_dns/pref_names.h" +#include "brave/components/decentralized_dns/core/pref_names.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/p3a/buildflags.h" #include "build/build_config.h" diff --git a/browser/brave_content_browser_client.cc b/browser/brave_content_browser_client.cc index 73c5b5953e9f..c5cca9761d0a 100644 --- a/browser/brave_content_browser_client.cc +++ b/browser/brave_content_browser_client.cc @@ -61,7 +61,7 @@ #include "brave/components/cosmetic_filters/common/cosmetic_filters.mojom.h" #include "brave/components/de_amp/browser/de_amp_throttle.h" #include "brave/components/debounce/browser/debounce_navigation_throttle.h" -#include "brave/components/decentralized_dns/decentralized_dns_navigation_throttle.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_navigation_throttle.h" #include "brave/components/ftx/browser/buildflags/buildflags.h" #include "brave/components/gemini/browser/buildflags/buildflags.h" #include "brave/components/ipfs/buildflags/buildflags.h" diff --git a/browser/brave_local_state_prefs.cc b/browser/brave_local_state_prefs.cc index aa89a1b5b7f0..0e0130093f22 100644 --- a/browser/brave_local_state_prefs.cc +++ b/browser/brave_local_state_prefs.cc @@ -16,7 +16,7 @@ #include "brave/components/brave_shields/browser/brave_shields_p3a.h" #include "brave/components/brave_vpn/buildflags/buildflags.h" #include "brave/components/constants/pref_names.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ntp_background_images/browser/ntp_background_images_service.h" #include "brave/components/ntp_background_images/browser/view_counter_service.h" #include "brave/components/p3a/brave_p3a_service.h" diff --git a/browser/brave_wallet/BUILD.gn b/browser/brave_wallet/BUILD.gn index a7b3636051ec..50c19defb85e 100644 --- a/browser/brave_wallet/BUILD.gn +++ b/browser/brave_wallet/BUILD.gn @@ -30,6 +30,7 @@ source_set("brave_wallet") { "//brave/components/brave_wallet/browser:constants", "//brave/components/brave_wallet/common", "//brave/components/brave_wallet/common:mojom", + "//chrome/browser:browser_process", "//chrome/browser/profiles:profiles", "//components/keyed_service/content", "//components/keyed_service/core", diff --git a/browser/brave_wallet/json_rpc_service_factory.cc b/browser/brave_wallet/json_rpc_service_factory.cc index f0f096a0ec59..0616a2e19140 100644 --- a/browser/brave_wallet/json_rpc_service_factory.cc +++ b/browser/brave_wallet/json_rpc_service_factory.cc @@ -10,6 +10,7 @@ #include "brave/browser/brave_wallet/brave_wallet_context_utils.h" #include "brave/components/brave_wallet/browser/brave_wallet_constants.h" #include "brave/components/brave_wallet/browser/json_rpc_service.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/user_prefs/user_prefs.h" @@ -68,7 +69,8 @@ KeyedService* JsonRpcServiceFactory::BuildServiceInstanceFor( auto shared_url_loader_factory = default_storage_partition->GetURLLoaderFactoryForBrowserProcess(); return new JsonRpcService(shared_url_loader_factory, - user_prefs::UserPrefs::Get(context)); + user_prefs::UserPrefs::Get(context), + g_browser_process->local_state()); } content::BrowserContext* JsonRpcServiceFactory::GetBrowserContextToUse( diff --git a/browser/decentralized_dns/test/BUILD.gn b/browser/decentralized_dns/test/BUILD.gn index 306a361e1590..218faab2a63b 100644 --- a/browser/decentralized_dns/test/BUILD.gn +++ b/browser/decentralized_dns/test/BUILD.gn @@ -12,10 +12,11 @@ source_set("browser_tests") { if (!is_android) { defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - sources = [ "//brave/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc" ] + sources = [ "decentralized_dns_navigation_throttle_browsertest.cc" ] deps = [ "//base/test:test_support", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", + "//brave/components/decentralized_dns/core", "//chrome/browser:browser_process", "//chrome/test:test_support", "//chrome/test:test_support_ui", @@ -30,9 +31,9 @@ source_set("browser_tests") { source_set("unit_tests") { testonly = true sources = [ - "//brave/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_unittest.cc", - "//brave/browser/decentralized_dns/test/utils_unittest.cc", "//brave/browser/net/decentralized_dns_network_delegate_helper_unittest.cc", + "decentralized_dns_navigation_throttle_unittest.cc", + "utils_unittest.cc", ] deps = [ @@ -44,7 +45,8 @@ source_set("unit_tests") { "//brave/components/brave_wallet/browser:utils", "//brave/components/brave_wallet/browser/test:test_support", "//brave/components/brave_wallet/common:mojom", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", + "//brave/components/decentralized_dns/core", "//brave/components/tor/buildflags", "//chrome/test:test_support", "//components/prefs", diff --git a/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc index 6f360c26be36..6d70dfe81765 100644 --- a/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc +++ b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc @@ -4,9 +4,9 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "base/test/scoped_feature_list.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/decentralized_dns_opt_in_page.h" -#include "brave/components/decentralized_dns/pref_names.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_opt_in_page.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" diff --git a/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_unittest.cc b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_unittest.cc index 67fdbb936d12..65609982267c 100644 --- a/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_unittest.cc +++ b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_unittest.cc @@ -3,7 +3,7 @@ * 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/. */ -#include "brave/components/decentralized_dns/decentralized_dns_navigation_throttle.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_navigation_throttle.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" diff --git a/browser/decentralized_dns/test/utils_unittest.cc b/browser/decentralized_dns/test/utils_unittest.cc index 41f654b5c5af..d5faac550243 100644 --- a/browser/decentralized_dns/test/utils_unittest.cc +++ b/browser/decentralized_dns/test/utils_unittest.cc @@ -3,11 +3,11 @@ * 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/. */ -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "base/test/task_environment.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/pref_names.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "components/prefs/testing_pref_service.h" diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index ea707548394d..0697fec788f4 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -74,7 +74,7 @@ source_set("extensions") { "//brave/components/brave_wayback_machine:buildflags", "//brave/components/constants", "//brave/components/de_amp/common", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", "//brave/components/ipfs/buildflags", "//brave/components/ntp_widget_utils/browser", "//brave/components/sidebar/buildflags", diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index dc6978e71f81..c96208db49ff 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -16,7 +16,7 @@ #include "brave/components/constants/pref_names.h" #include "brave/components/crypto_dot_com/browser/buildflags/buildflags.h" #include "brave/components/de_amp/common/pref_names.h" -#include "brave/components/decentralized_dns/pref_names.h" +#include "brave/components/decentralized_dns/core/pref_names.h" #include "brave/components/ftx/browser/buildflags/buildflags.h" #include "brave/components/ipfs/buildflags/buildflags.h" #include "brave/components/ntp_background_images/common/pref_names.h" @@ -319,6 +319,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { settings_api::PrefType::PREF_TYPE_NUMBER; (*s_brave_allowlist)[decentralized_dns::kENSResolveMethod] = settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_brave_allowlist)[decentralized_dns::kEnsOffchainResolveMethod] = + settings_api::PrefType::PREF_TYPE_NUMBER; // Media router pref (*s_brave_allowlist)[kEnableMediaRouterOnRestart] = diff --git a/browser/ipfs/content_browser_client_helper.cc b/browser/ipfs/content_browser_client_helper.cc index d22a5161d01f..fa55029dabc5 100644 --- a/browser/ipfs/content_browser_client_helper.cc +++ b/browser/ipfs/content_browser_client_helper.cc @@ -13,7 +13,7 @@ #include "brave/browser/profiles/profile_util.h" #include "brave/components/constants/url_constants.h" #include "brave/components/constants/webui_url_constants.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/ipfs_constants.h" #include "brave/components/ipfs/ipfs_utils.h" #include "brave/components/ipfs/pref_names.h" diff --git a/browser/ipfs/content_browser_client_helper_unittest.cc b/browser/ipfs/content_browser_client_helper_unittest.cc index 104f9875fee4..4417f543ef3d 100644 --- a/browser/ipfs/content_browser_client_helper_unittest.cc +++ b/browser/ipfs/content_browser_client_helper_unittest.cc @@ -13,9 +13,9 @@ #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "brave/components/constants/webui_url_constants.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/pref_names.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/features.h" #include "brave/components/ipfs/ipfs_constants.h" #include "brave/components/ipfs/ipfs_ports.h" diff --git a/browser/ipfs/test/BUILD.gn b/browser/ipfs/test/BUILD.gn index 0039962b1b48..6da5421d315b 100644 --- a/browser/ipfs/test/BUILD.gn +++ b/browser/ipfs/test/BUILD.gn @@ -25,7 +25,8 @@ source_set("unittests") { "//brave/browser/net", "//brave/browser/tor", "//brave/common", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", + "//brave/components/decentralized_dns/core", "//brave/components/ipfs", "//brave/components/tor/buildflags", "//chrome/common:channel_info", diff --git a/browser/net/BUILD.gn b/browser/net/BUILD.gn index 00e5d28b7e63..433c5c3b9bd4 100644 --- a/browser/net/BUILD.gn +++ b/browser/net/BUILD.gn @@ -72,7 +72,7 @@ source_set("net") { "//brave/components/brave_wallet/browser", "//brave/components/brave_wallet/common", "//brave/components/brave_webtorrent/browser/buildflags", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", "//brave/components/ipfs/buildflags", "//brave/components/update_client:buildflags", "//brave/extensions:common", diff --git a/browser/net/decentralized_dns_network_delegate_helper.cc b/browser/net/decentralized_dns_network_delegate_helper.cc index bc41faa824a4..2013ca640812 100644 --- a/browser/net/decentralized_dns_network_delegate_helper.cc +++ b/browser/net/decentralized_dns_network_delegate_helper.cc @@ -11,8 +11,8 @@ #include "brave/browser/brave_wallet/json_rpc_service_factory.h" #include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/ipfs_utils.h" #include "chrome/browser/browser_process.h" #include "content/public/browser/browser_context.h" @@ -62,8 +62,12 @@ void OnBeforeURLRequest_EnsRedirectWork( const brave::ResponseCallback& next_callback, std::shared_ptr ctx, const std::vector& content_hash, + bool require_offchain_consent, brave_wallet::mojom::ProviderError error, const std::string& error_message) { + // TODO(apaymyshev): implement interstitial page. + DCHECK(!require_offchain_consent); + if (error != brave_wallet::mojom::ProviderError::kSuccess) { if (!next_callback.is_null()) next_callback.Run(); diff --git a/browser/net/decentralized_dns_network_delegate_helper.h b/browser/net/decentralized_dns_network_delegate_helper.h index aa04e9369cea..8ebf2e51dd39 100644 --- a/browser/net/decentralized_dns_network_delegate_helper.h +++ b/browser/net/decentralized_dns_network_delegate_helper.h @@ -33,6 +33,7 @@ void OnBeforeURLRequest_EnsRedirectWork( const brave::ResponseCallback& next_callback, std::shared_ptr ctx, const std::vector& content_hash, + bool require_offchain_consent, brave_wallet::mojom::ProviderError error, const std::string& error_message); diff --git a/browser/net/decentralized_dns_network_delegate_helper_unittest.cc b/browser/net/decentralized_dns_network_delegate_helper_unittest.cc index 432a8dfda7b3..23b73fed274d 100644 --- a/browser/net/decentralized_dns_network_delegate_helper_unittest.cc +++ b/browser/net/decentralized_dns_network_delegate_helper_unittest.cc @@ -17,9 +17,9 @@ #include "brave/components/brave_wallet/common/brave_wallet.mojom.h" #include "brave/components/brave_wallet/common/eth_abi_utils.h" #include "brave/components/brave_wallet/common/hex_utils.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/pref_names.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" @@ -241,12 +241,12 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, EnsRedirectWork) { // No redirect for failed requests. OnBeforeURLRequest_EnsRedirectWork( - ResponseCallback(), brave_request_info, {}, + ResponseCallback(), brave_request_info, {}, false, brave_wallet::mojom::ProviderError::kInternalError, "todo"); EXPECT_TRUE(brave_request_info->new_url_spec.empty()); OnBeforeURLRequest_EnsRedirectWork( - ResponseCallback(), brave_request_info, {}, + ResponseCallback(), brave_request_info, {}, false, brave_wallet::mojom::ProviderError::kSuccess, ""); EXPECT_TRUE(brave_request_info->new_url_spec.empty()); @@ -260,7 +260,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, EnsRedirectWork) { auto content_hash = *brave_wallet::eth_abi::ExtractBytesFromTuple( *brave_wallet::PrefixedHexStringToBytes(content_hash_encoded_string), 0); OnBeforeURLRequest_EnsRedirectWork( - ResponseCallback(), brave_request_info, content_hash, + ResponseCallback(), brave_request_info, content_hash, false, brave_wallet::mojom::ProviderError::kSuccess, ""); EXPECT_TRUE(brave_request_info->new_url_spec.empty()); @@ -274,7 +274,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, EnsRedirectWork) { content_hash = *brave_wallet::eth_abi::ExtractBytesFromTuple( *brave_wallet::PrefixedHexStringToBytes(content_hash_encoded_string), 0); OnBeforeURLRequest_EnsRedirectWork( - ResponseCallback(), brave_request_info, content_hash, + ResponseCallback(), brave_request_info, content_hash, false, brave_wallet::mojom::ProviderError::kSuccess, ""); EXPECT_EQ(brave_request_info->new_url_spec, "ipfs://" diff --git a/browser/resources/settings/BUILD.gn b/browser/resources/settings/BUILD.gn index bab6b67e58f2..4c52476bccea 100644 --- a/browser/resources/settings/BUILD.gn +++ b/browser/resources/settings/BUILD.gn @@ -147,7 +147,7 @@ preprocess_if_expr("preprocess_generated") { "brave_ipfs_page/ipfs_peers_subpage.m.js", "brave_ipfs_page/add_ipfs_peer_dialog.js", "brave_default_extensions_page/brave_default_extensions_browser_proxy.m.js", - "brave_default_extensions_page/brave_default_extensions_page.m.js", + "brave_default_extensions_page/brave_default_extensions_page.js", "brave_help_tips_page/brave_help_tips_page.js", "brave_icons.m.js", "brave_new_tab_page/brave_new_tab_browser_proxy.m.js", diff --git a/browser/resources/settings/brave_default_extensions_page/BUILD.gn b/browser/resources/settings/brave_default_extensions_page/BUILD.gn index d4199560ea7d..fa14f5668b86 100644 --- a/browser/resources/settings/brave_default_extensions_page/BUILD.gn +++ b/browser/resources/settings/brave_default_extensions_page/BUILD.gn @@ -12,20 +12,16 @@ import("../settings.gni") group("web_modules") { public_deps = [ - ":brave_default_extensions_page_module", ":modules", + ":templatize", ] } -polymer_modulizer("brave_default_extensions_page") { - js_file = "brave_default_extensions_page.js" - html_file = "brave_default_extensions_page.html" - html_type = "dom-module" - auto_imports = settings_auto_imports + [ "brave/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.html|BraveDefaultExtensionsBrowserProxy, BraveDefaultExtensionsBrowserProxyImpl" ] - namespace_rewrites = settings_namespace_rewrites -} - js_modulizer("modules") { input_files = [ "brave_default_extensions_browser_proxy.js" ] namespace_rewrites = settings_namespace_rewrites } + +html_to_js("templatize") { + js_files = [ "brave_default_extensions_page.js" ] +} diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js index e83a9f0461b3..bfa83e1ead32 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.js @@ -6,69 +6,70 @@ // #import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; // clang-format on -cr.define('settings', function () { - /** @interface */ - /* #export */ class BraveDefaultExtensionsBrowserProxy { - /** - * @param {boolean} value name. - */ - setWebTorrentEnabled (value) {} - setHangoutsEnabled (value) {} - setWidevineEnabled() {} - isWidevineEnabled() {} - getRestartNeeded () {} - wasSignInEnabledAtStartup () {} - isMediaRouterEnabled () {} - getDecentralizedDnsResolveMethodList() {} - } - +export class BraveDefaultExtensionsBrowserProxy { /** - * @implements {settings.BraveDefaultExtensionsBrowserProxy} + * @param {boolean} value name. */ - /* #export */ class BraveDefaultExtensionsBrowserProxyImpl { - /** @override */ - setWebTorrentEnabled (value) { - chrome.send('setWebTorrentEnabled', [value]) - } + setWebTorrentEnabled(value) { } + setHangoutsEnabled(value) { } + setWidevineEnabled() { } + isWidevineEnabled() { } + getRestartNeeded() { } + wasSignInEnabledAtStartup() { } + isMediaRouterEnabled() { } + getDecentralizedDnsResolveMethodList() { } + getEnsOffchainResolveMethodList() { } + isENSL2Enabled() { } +} - setHangoutsEnabled (value) { - chrome.send('setHangoutsEnabled', [value]) - } +/** + * @implements {settings.BraveDefaultExtensionsBrowserProxy} + */ +export class BraveDefaultExtensionsBrowserProxyImpl { + /** @override */ + setWebTorrentEnabled(value) { + chrome.send('setWebTorrentEnabled', [value]) + } - setMediaRouterEnabled (value) { - chrome.send('setMediaRouterEnabled', [value]) - } + setHangoutsEnabled(value) { + chrome.send('setHangoutsEnabled', [value]) + } - setWidevineEnabled (value) { - chrome.send('setWidevineEnabled', [value]) - } + setMediaRouterEnabled(value) { + chrome.send('setMediaRouterEnabled', [value]) + } - isWidevineEnabled () { - return cr.sendWithPromise('isWidevineEnabled') - } + setWidevineEnabled(value) { + chrome.send('setWidevineEnabled', [value]) + } - getRestartNeeded () { - return cr.sendWithPromise('getRestartNeeded') - } + isWidevineEnabled() { + return cr.sendWithPromise('isWidevineEnabled') + } - wasSignInEnabledAtStartup () { - return loadTimeData.getBoolean('signInAllowedOnNextStartupInitialValue') - } + getRestartNeeded() { + return cr.sendWithPromise('getRestartNeeded') + } + + wasSignInEnabledAtStartup() { + return loadTimeData.getBoolean('signInAllowedOnNextStartupInitialValue') + } - isMediaRouterEnabled () { - return loadTimeData.getBoolean('isMediaRouterEnabled') - } + isMediaRouterEnabled() { + return loadTimeData.getBoolean('isMediaRouterEnabled') + } - getDecentralizedDnsResolveMethodList () { - return cr.sendWithPromise('getDecentralizedDnsResolveMethodList') - } + getDecentralizedDnsResolveMethodList() { + return cr.sendWithPromise('getDecentralizedDnsResolveMethodList') } - cr.addSingletonGetter(BraveDefaultExtensionsBrowserProxyImpl) + getEnsOffchainResolveMethodList() { + return cr.sendWithPromise('getEnsOffchainResolveMethodList') + } - // #cr_define_end - return { - BraveDefaultExtensionsBrowserProxy, - BraveDefaultExtensionsBrowserProxyImpl + isENSL2Enabled() { + return loadTimeData.getBoolean('isENSL2Enabled') } -}) +} + +cr.addSingletonGetter(BraveDefaultExtensionsBrowserProxyImpl) diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html index 6e479780a7dc..c3f005bcd611 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.html @@ -1,162 +1,157 @@ - - + - .restart-notice { - font-size: .9375rem; - line-height: 1.4; - } - - button.primary { - background: var(--interactive-color); - border: 0; - border-radius: 3px; - color: white; - font-size: .875rem; - padding: 14px 38px; - } - - - - - - - - - - -
-
-
$i18n{resolveUnstoppableDomainsDesc}
-
$i18nRaw{resolveUnstoppableDomainsSubDesc}
-
- -
-
-
$i18n{resolveENSDesc}
- -
- - - - -
- - -
-
- - -
-
- - + + + + + + + + +
+
+
$i18n{resolveUnstoppableDomainsDesc}
+
$i18nRaw{resolveUnstoppableDomainsSubDesc}
+
+ +
+
+
$i18n{resolveENSDesc}
+ +
+ - - +
+ + diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.js b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.js index f2dfae9792f3..885faecf420b 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.js +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_page.js @@ -2,59 +2,53 @@ * 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/. */ -(function() { -'use strict'; +import { html, PolymerElement } from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import { PrefsMixin } from '../prefs/prefs_mixin.js'; +import { WebUIListenerMixin } from 'chrome://resources/js/web_ui_listener_mixin.js'; +import { BraveDefaultExtensionsBrowserProxyImpl } from './brave_default_extensions_browser_proxy.m.js'; + +const SettingBraveDefaultExtensionsPageElementBase = WebUIListenerMixin(PrefsMixin(PolymerElement)) /** * 'settings-brave-default-extensions-page' is the settings page containing * brave's default extensions. */ -Polymer({ - is: 'settings-brave-default-extensions-page', - - behaviors: [ - WebUIListenerBehavior, - ], - - /** - * Keep it the same as Provider in - * brave/componentsdecentralized_dns/constants.h. - */ - Provider: { - UNSTOPPABLE_DOMAINS: 0, - ENS: 1 - }, - - properties: { - showRestartToast_: Boolean, - unstoppableDomainsResolveMethod_: Array, - ensResolveMethod_: Array, - widevineEnabledPref_: { - type: Object, - value() { - // TODO(dbeam): this is basically only to appease PrefControlMixin. - // Maybe add a no-validate attribute instead? This makes little sense. - return {}; - }, - }, - }, +class SettingBraveDefaultExtensionsPageElement extends SettingBraveDefaultExtensionsPageElementBase { + static get is() { + return 'settings-brave-default-extensions-page' + } - /** @private {?settings.BraveDefaultExtensionsBrowserProxy} */ - browserProxy_: null, + static get template() { + return html`{__html_template__}` + } - /** @override */ - created: function() { - this.browserProxy_ = settings.BraveDefaultExtensionsBrowserProxyImpl.getInstance(); - }, + static get properties() { + return { + showRestartToast_: Boolean, + unstoppableDomainsResolveMethod_: Array, + ensResolveMethod_: Array, + ensOffchainResolveMethod_: Array, + showEnsOffchainLookupRow_: { + type: Boolean, + computed: 'computeShowEnsOffchainLookupRow_(prefs.*)', + }, + widevineEnabledPref_: { + type: Object, + value() { + // TODO(dbeam): this is basically only to appease PrefControlMixin. + // Maybe add a no-validate attribute instead? This makes little sense. + return {}; + }, + } + } + } + + /** @private {?BraveDefaultExtensionsBrowserProxy} */ + browserProxy_ = BraveDefaultExtensionsBrowserProxyImpl.getInstance() /** @override */ - ready: function() { - this.onWebTorrentEnabledChange_ = this.onWebTorrentEnabledChange_.bind(this) - this.onHangoutsEnabledChange_ = this.onHangoutsEnabledChange_.bind(this) - this.openExtensionsPage_ = this.openExtensionsPage_.bind(this) - this.openKeyboardShortcutsPage_ = this.openKeyboardShortcutsPage_.bind(this) - this.onWidevineEnabledChange_ = this.onWidevineEnabledChange_.bind(this) - this.restartBrowser_ = this.restartBrowser_.bind(this) + ready() { + super.ready() this.addWebUIListener('brave-needs-restart-changed', (needsRestart) => { this.showRestartToast_ = needsRestart @@ -64,64 +58,74 @@ Polymer({ this.showRestartToast_ = show; }); this.browserProxy_.getDecentralizedDnsResolveMethodList().then(list => { - this.unstoppableDomainsResolveMethod_ = list + this.unstoppableDomainsResolveMethod_ = list }) this.browserProxy_.getDecentralizedDnsResolveMethodList().then(list => { this.ensResolveMethod_ = list }) + this.browserProxy_.getEnsOffchainResolveMethodList().then(list => { + this.ensOffchainResolveMethod_ = list + }) // PrefControlMixin checks for a pref being valid, so have to fake it, // same as upstream. const setWidevineEnabledPref = (enabled) => this.setWidevineEnabledPref_(enabled); this.addWebUIListener('widevine-enabled-changed', setWidevineEnabledPref); this.browserProxy_.isWidevineEnabled().then(setWidevineEnabledPref); - }, + } - onWebTorrentEnabledChange_: function() { + onWebTorrentEnabledChange_() { this.browserProxy_.setWebTorrentEnabled(this.$.webTorrentEnabled.checked); - }, + } - onHangoutsEnabledChange_: function() { + onHangoutsEnabledChange_() { this.browserProxy_.setHangoutsEnabled(this.$.hangoutsEnabled.checked); - }, + } - restartBrowser_: function(e) { + restartBrowser_(e) { e.stopPropagation(); window.open("chrome://restart", "_self"); - }, + } - setWidevineEnabledPref_: function (enabled) { + setWidevineEnabledPref_(enabled) { const pref = { key: '', type: chrome.settingsPrivate.PrefType.BOOLEAN, value: enabled, }; this.widevineEnabledPref_ = pref; - }, + } - onWidevineEnabledChange_: function() { + onWidevineEnabledChange_() { this.browserProxy_.setWidevineEnabled(this.$.widevineEnabled.checked); - }, + } - openExtensionsPage_: function() { + openExtensionsPage_() { window.open("chrome://extensions", "_self"); - }, + } - openKeyboardShortcutsPage_: function() { + openKeyboardShortcutsPage_() { window.open("chrome://extensions/shortcuts", "_self"); - }, + } - openWebStoreUrl_: function() { + openWebStoreUrl_() { window.open(loadTimeData.getString('getMoreExtensionsUrl')); - }, + } - shouldShowRestartForGoogleLogin_: function(value) { + shouldShowRestartForGoogleLogin_(value) { return this.browserProxy_.wasSignInEnabledAtStartup() != value; - }, + } - shouldShowRestartForMediaRouter_: function(value) { + shouldShowRestartForMediaRouter_(value) { return this.browserProxy_.isMediaRouterEnabled() != value; } -}); -})(); + computeShowEnsOffchainLookupRow_() { + if (!this.browserProxy_.isENSL2Enabled()) + return false; + return !!this.prefs && this.getPref('brave.ens.resolve_method').value === 3 + } +} + +customElements.define( + SettingBraveDefaultExtensionsPageElement.is, SettingBraveDefaultExtensionsPageElement) \ No newline at end of file diff --git a/browser/resources/settings/brave_overrides/basic_page.js b/browser/resources/settings/brave_overrides/basic_page.js index f3e9baa42dba..834f68966db6 100644 --- a/browser/resources/settings/brave_overrides/basic_page.js +++ b/browser/resources/settings/brave_overrides/basic_page.js @@ -6,7 +6,7 @@ import {html, RegisterPolymerTemplateModifications, RegisterStyleOverride} from 'chrome://brave-resources/polymer_overriding.js' import {loadTimeData} from '../i18n_setup.js' -import '../brave_default_extensions_page/brave_default_extensions_page.m.js' +import '../brave_default_extensions_page/brave_default_extensions_page.js' import '../brave_help_tips_page/brave_help_tips_page.js' import '../brave_ipfs_page/brave_ipfs_page.js' import '../brave_new_tab_page/brave_new_tab_page.m.js' diff --git a/browser/resources/settings/sources.gni b/browser/resources/settings/sources.gni index 3bfba9b92372..ead7e817d698 100644 --- a/browser/resources/settings/sources.gni +++ b/browser/resources/settings/sources.gni @@ -12,7 +12,7 @@ brave_deps_chrome_browser_resources_settings_in_files = [ "brave_clear_browsing_data_dialog/brave_clear_browsing_data_dialog_behavior.js", "brave_clear_browsing_data_dialog/brave_clear_browsing_data_on_exit_page.js", "brave_default_extensions_page/brave_default_extensions_browser_proxy.m.js", - "brave_default_extensions_page/brave_default_extensions_page.m.js", + "brave_default_extensions_page/brave_default_extensions_page.js", "brave_help_tips_page/brave_help_tips_page.js", "brave_icons.m.js", "brave_ipfs_page/brave_ipfs_browser_proxy.m.js", diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index b028279903f6..bdd4831312da 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -582,7 +582,7 @@ source_set("ui") { "//brave/browser/resources/extensions:resources", "//brave/components/brave_extension:generated_resources", "//brave/components/brave_extension:static_resources", - "//brave/components/decentralized_dns", + "//brave/components/decentralized_dns/content", "//brave/components/resources:static_resources", "//brave/components/resources:strings_grit", "//chrome/browser/extensions", diff --git a/browser/ui/webui/settings/brave_default_extensions_handler.cc b/browser/ui/webui/settings/brave_default_extensions_handler.cc index ca7c4607a591..e4c87f8cd897 100644 --- a/browser/ui/webui/settings/brave_default_extensions_handler.cc +++ b/browser/ui/webui/settings/brave_default_extensions_handler.cc @@ -20,9 +20,10 @@ #include "brave/components/brave_wallet/browser/tx_service.h" #include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources.h" #include "brave/components/constants/pref_names.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/buildflags/buildflags.h" +#include "brave/components/l10n/common/locale_util.h" #include "chrome/browser/about_flags.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/component_loader.h" @@ -39,6 +40,7 @@ #include "chrome/common/pref_names.h" #include "components/flags_ui/flags_ui_constants.h" #include "components/flags_ui/pref_service_flags_storage.h" +#include "components/grit/brave_components_strings.h" #include "components/prefs/pref_service.h" #include "content/public/browser/web_ui.h" #include "extensions/browser/extension_registry.h" @@ -61,6 +63,55 @@ #include "brave/components/ipfs/pref_names.h" #endif +using decentralized_dns::EnsOffchainResolveMethod; +using decentralized_dns::ResolveMethodTypes; + +namespace { + +template +base::Value::Dict MakeSelectValue(T value, const std::u16string& name) { + base::Value::Dict item; + item.Set("value", base::Value(static_cast(value))); + item.Set("name", base::Value(name)); + return item; +} + +base::Value::List GetResolveMethodList() { + base::Value::List list; + list.Append(MakeSelectValue(ResolveMethodTypes::ASK, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ASK))); + list.Append( + MakeSelectValue(ResolveMethodTypes::DISABLED, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_DISABLED))); + list.Append( + MakeSelectValue(ResolveMethodTypes::ETHEREUM, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ETHEREUM))); + + return list; +} + +base::Value::List GetEnsOffchainResolveMethodList() { + base::Value::List list; + list.Append(MakeSelectValue( + EnsOffchainResolveMethod::kAsk, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_ENS_OFFCHAIN_RESOLVE_OPTION_ASK))); + list.Append(MakeSelectValue( + EnsOffchainResolveMethod::kDisabled, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_ENS_OFFCHAIN_RESOLVE_OPTION_DISABLED))); + list.Append(MakeSelectValue( + EnsOffchainResolveMethod::kEnabled, + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_ENS_OFFCHAIN_RESOLVE_OPTION_ENABLED))); + + return list; +} +} // namespace + BraveDefaultExtensionsHandler::BraveDefaultExtensionsHandler() : weak_ptr_factory_(this) { #if BUILDFLAG(ENABLE_WIDEVINE) @@ -147,6 +198,11 @@ void BraveDefaultExtensionsHandler::RegisterMessages() { base::BindRepeating( &BraveDefaultExtensionsHandler::GetDecentralizedDnsResolveMethodList, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "getEnsOffchainResolveMethodList", + base::BindRepeating( + &BraveDefaultExtensionsHandler::GetEnsOffchainResolveMethodList, + base::Unretained(this))); // Can't call this in ctor because it needs to access web_ui(). InitializePrefCallbacks(); @@ -403,8 +459,16 @@ void BraveDefaultExtensionsHandler::GetDecentralizedDnsResolveMethodList( CHECK_EQ(args.size(), 1U); AllowJavascript(); - ResolveJavascriptCallback( - args[0], base::Value(decentralized_dns::GetResolveMethodList())); + ResolveJavascriptCallback(args[0], base::Value(::GetResolveMethodList())); +} + +void BraveDefaultExtensionsHandler::GetEnsOffchainResolveMethodList( + const base::Value::List& args) { + CHECK_EQ(args.size(), 1U); + AllowJavascript(); + + ResolveJavascriptCallback(args[0], + base::Value(::GetEnsOffchainResolveMethodList())); } #if BUILDFLAG(ENABLE_IPFS) diff --git a/browser/ui/webui/settings/brave_default_extensions_handler.h b/browser/ui/webui/settings/brave_default_extensions_handler.h index abd15ad051ec..2215c6357108 100644 --- a/browser/ui/webui/settings/brave_default_extensions_handler.h +++ b/browser/ui/webui/settings/brave_default_extensions_handler.h @@ -57,6 +57,7 @@ class BraveDefaultExtensionsHandler : public settings::SettingsPageUIHandler void OnWidevineEnabledChanged(); void OnWalletTypeChanged(); void GetDecentralizedDnsResolveMethodList(const base::Value::List& args); + void GetEnsOffchainResolveMethodList(const base::Value::List& args); void InitializePrefCallbacks(); diff --git a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc index 953b59152df9..4550ef736592 100644 --- a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc +++ b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc @@ -11,6 +11,7 @@ #include "brave/browser/ui/webui/settings/brave_privacy_handler.h" #include "brave/components/brave_vpn/buildflags/buildflags.h" #include "brave/components/brave_wallet/browser/pref_names.h" +#include "brave/components/brave_wallet/common/features.h" #include "brave/components/constants/url_constants.h" #include "brave/components/constants/webui_url_constants.h" #include "brave/components/ipfs/ipfs_constants.h" @@ -55,6 +56,8 @@ const char16_t kDNSLinkLearnMoreURL[] = const char16_t kUnstoppableDomainsLearnMoreURL[] = u"https://github.com/brave/brave-browser/wiki/" u"Resolve-Methods-for-Unstoppable-Domains"; +const char16_t kEnsOffchainLookupLearnMoreURL[] = + u"https://github.com/brave/brave-browser/wiki/ENS-offchain-lookup"; const char16_t kBraveAdsLearnMoreURL[] = u"https://support.brave.com/hc/en-us/articles/360026361072-Brave-Ads-FAQ"; const char16_t kBraveTermsOfUseURL[] = u"https://brave.com/terms-of-use/"; @@ -348,6 +351,7 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, {"resolveUnstoppableDomainsDesc", IDS_SETTINGS_RESOLVE_UNSTOPPABLE_DOMAINS_DESC}, {"resolveENSDesc", IDS_SETTINGS_RESOLVE_ENS_DESC}, + {"ensOffchainLookupTitle", IDS_SETTINGS_ENABLE_ENS_OFFCHAIN_LOOKUP_TITLE}, {"resolveIPFSURLDesc", IDS_SETTINGS_RESOLVE_IPFS_URLS_DESC}, {"ipfsPublicGatewayDesc", IDS_SETTINGS_IPFS_PUBLIC_GATEWAY_DESC}, {"ipfsChangeGatewayButtonLabel", @@ -591,6 +595,11 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_RESOLVE_UNSTOPPABLE_DOMAINS_SUB_DESC, kUnstoppableDomainsLearnMoreURL)); + html_source->AddString( + "ensOffchainLookupDesc", + l10n_util::GetStringFUTF16(IDS_SETTINGS_ENABLE_ENS_OFFCHAIN_LOOKUP_DESC, + kEnsOffchainLookupLearnMoreURL)); + html_source->AddString( "braveRewardsStateLevelAdTargetingDescLabel", l10n_util::GetStringFUTF16( @@ -651,6 +660,10 @@ void BraveAddLocalizedStrings(content::WebUIDataSource* html_source, html_source->AddBoolean("isMediaRouterEnabled", media_router::MediaRouterEnabled(profile)); + html_source->AddBoolean( + "isENSL2Enabled", base::FeatureList::IsEnabled( + brave_wallet::features::kBraveWalletENSL2Feature)); + if (base::FeatureList::IsEnabled( net::features::kBraveFirstPartyEphemeralStorage)) { const webui::LocalizedString kSessionOnlyToEphemeralStrings[] = { diff --git a/chromium_src/chrome/browser/prefs/browser_prefs.cc b/chromium_src/chrome/browser/prefs/browser_prefs.cc index adccbccde58a..a504a5ce324c 100644 --- a/chromium_src/chrome/browser/prefs/browser_prefs.cc +++ b/chromium_src/chrome/browser/prefs/browser_prefs.cc @@ -12,7 +12,7 @@ #include "brave/components/brave_wallet/browser/brave_wallet_prefs.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/constants/pref_names.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ntp_background_images/buildflags/buildflags.h" #include "brave/components/omnibox/browser/brave_omnibox_prefs.h" #include "brave/components/tor/buildflags/buildflags.h" diff --git a/components/brave_wallet/browser/BUILD.gn b/components/brave_wallet/browser/BUILD.gn index 64274c86d710..d90ed8cf6953 100644 --- a/components/brave_wallet/browser/BUILD.gn +++ b/components/brave_wallet/browser/BUILD.gn @@ -148,6 +148,7 @@ static_library("browser") { "//brave/components/brave_wallet/common:mojom", "//brave/components/brave_wallet/common:solana_utils", "//brave/components/constants", + "//brave/components/decentralized_dns/core", "//brave/components/filecoin/rs:cxx", "//brave/components/ipfs", "//brave/components/json/rs:cxx", diff --git a/components/brave_wallet/browser/brave_wallet_constants.h b/components/brave_wallet/browser/brave_wallet_constants.h index 2fb3095466a5..7d603f7c7b60 100644 --- a/components/brave_wallet/browser/brave_wallet_constants.h +++ b/components/brave_wallet/browser/brave_wallet_constants.h @@ -882,7 +882,15 @@ constexpr webui::LocalizedString kLocalizedStrings[] = { IDS_BRAVE_WALLET_REQUEST_FEATURE_BUTTON_TEXT}, {"braveWalletNftsEmptyState", IDS_BRAVE_WALLET_NFTS_EMPTY_STATE}, {"braveWalletNftsEmptyStateSearch", - IDS_BRAVE_WALLET_NFTS_EMPTY_STATE_SEARCH_FILTER}}; + IDS_BRAVE_WALLET_NFTS_EMPTY_STATE_SEARCH_FILTER}, + {"braveWalletEnsOffchainProceedWithYes", + IDS_BRAVE_WALLET_ENS_OFFCHAIN_PROCEED_WITH_YES}, + {"braveWalletEnsOffchainProceedWithNo", + IDS_BRAVE_WALLET_ENS_OFFCHAIN_PROCEED_WITH_NO}, + {"braveWalletEnsOffchainDontShowAgain", + IDS_BRAVE_WALLET_ENS_OFFCHAIN_DONT_SHOW_AGAIN}, + {"braveWalletEnsOffchainWarning", IDS_BRAVE_WALLET_ENS_OFFCHAIN_WARNING}, +}; // 0x swap constants constexpr char kRopstenSwapBaseAPIURL[] = "https://ropsten.api.0x.org/"; diff --git a/components/brave_wallet/browser/ens_resolver_task.cc b/components/brave_wallet/browser/ens_resolver_task.cc index 07acbcbb4e15..1b19edbe4cb9 100644 --- a/components/brave_wallet/browser/ens_resolver_task.cc +++ b/components/brave_wallet/browser/ens_resolver_task.cc @@ -46,8 +46,45 @@ absl::optional> ExtractGatewayResult( return result; } +EnsResolverTaskError ParseErrorResult(const std::string& json) { + EnsResolverTaskError task_error; + brave_wallet::ParseErrorResult( + json, &task_error.error, &task_error.error_message); + + return task_error; +} + +EnsResolverTaskError MakeInternalError() { + return EnsResolverTaskError( + mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); +} + } // namespace +EnsResolverTaskResult::EnsResolverTaskResult() = default; +EnsResolverTaskResult::EnsResolverTaskResult(const EnsResolverTaskResult&) = + default; +EnsResolverTaskResult::EnsResolverTaskResult(EnsResolverTaskResult&&) = default; +EnsResolverTaskResult& EnsResolverTaskResult::operator=( + const EnsResolverTaskResult&) = default; +EnsResolverTaskResult& EnsResolverTaskResult::operator=( + EnsResolverTaskResult&&) = default; +EnsResolverTaskResult::~EnsResolverTaskResult() = default; + +EnsResolverTaskError::EnsResolverTaskError() = default; +EnsResolverTaskError::EnsResolverTaskError(mojom::ProviderError error, + std::string error_message) + : error(error), error_message(error_message) {} +EnsResolverTaskError::EnsResolverTaskError(const EnsResolverTaskError&) = + default; +EnsResolverTaskError::EnsResolverTaskError(EnsResolverTaskError&&) = default; +EnsResolverTaskError& EnsResolverTaskError::operator=( + const EnsResolverTaskError&) = default; +EnsResolverTaskError& EnsResolverTaskError::operator=(EnsResolverTaskError&&) = + default; +EnsResolverTaskError::~EnsResolverTaskError() = default; + std::vector MakeAddrCall(const std::string& domain) { return eth_abi::TupleEncoder() .AddFixedBytes(Namehash(domain)) @@ -133,13 +170,15 @@ EnsResolverTask::EnsResolverTask( APIRequestHelper* api_request_helper_ens_offchain, std::vector ens_call, const std::string& domain, - const GURL& network_url) + const GURL& network_url, + absl::optional allow_offchain) : done_callback_(std::move(done_callback)), api_request_helper_(api_request_helper), api_request_helper_ens_offchain_(api_request_helper_ens_offchain), ens_call_(std::move(ens_call)), domain_(domain), - network_url_(network_url) { + network_url_(network_url), + allow_offchain_(allow_offchain) { DCHECK(api_request_helper_); DCHECK(api_request_helper_ens_offchain_); } @@ -153,17 +192,13 @@ void EnsResolverTask::ScheduleWorkOnTask() { } void EnsResolverTask::WorkOnTask() { - if (resolve_result_) { - std::move(done_callback_) - .Run(this, std::move(resolve_result_.value()), - mojom::ProviderError::kSuccess, ""); + if (task_result_) { + std::move(done_callback_).Run(this, std::move(task_result_), absl::nullopt); // `this` is not valid here return; } - if (error_ || error_message_) { - std::move(done_callback_) - .Run(this, {}, error_.value_or(mojom::ProviderError::kInternalError), - error_message_.value_or("")); + if (task_error_) { + std::move(done_callback_).Run(this, absl::nullopt, std::move(task_error_)); // `this` is not valid here. return; } @@ -194,8 +229,7 @@ void EnsResolverTask::WorkOnTask() { } std::move(done_callback_) - .Run(this, {}, mojom::ProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); + .Run(this, absl::nullopt, EnsResolverTaskError(MakeInternalError())); // `this` is not valid here. } @@ -216,23 +250,19 @@ void EnsResolverTask::OnFetchEnsResolverDone( ScopedWorkOnTask work_on_task(this); if (!api_request_result.Is2XXResponseCode()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } auto bytes_result = ParseDecodedBytesResult(api_request_result.body()); if (!bytes_result) { - ParseErrorResult(api_request_result.body(), - &error_.emplace(), - &error_message_.emplace()); + task_error_ = ParseErrorResult(api_request_result.body()); return; } auto resolver_address = eth_abi::ExtractAddressFromTuple(*bytes_result, 0); if (!resolver_address.IsValid() || resolver_address.IsZeroAddress()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } @@ -255,16 +285,13 @@ void EnsResolverTask::OnFetchEnsip10SupportDone( ScopedWorkOnTask work_on_task(this); if (!api_request_result.Is2XXResponseCode()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } bool is_supported = false; if (!ParseBoolResult(api_request_result.body(), &is_supported)) { - ParseErrorResult(api_request_result.body(), - &error_.emplace(), - &error_message_.emplace()); + task_error_ = ParseErrorResult(api_request_result.body()); return; } @@ -275,7 +302,7 @@ void EnsResolverTask::FetchEnsRecord() { DCHECK(resolver_address_.IsValid()); DCHECK(supports_ensip_10_); DCHECK(!supports_ensip_10_.value()); - DCHECK(!resolve_result_); + DCHECK(!task_result_); RequestInternal(eth::eth_call(resolver_address_.ToHex(), ToHex(ens_call_)), base::BindOnce(&EnsResolverTask::OnFetchEnsRecordDone, @@ -287,33 +314,30 @@ void EnsResolverTask::OnFetchEnsRecordDone( ScopedWorkOnTask work_on_task(this); if (!api_request_result.Is2XXResponseCode()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } auto bytes_result = ParseDecodedBytesResult(api_request_result.body()); if (!bytes_result) { - ParseErrorResult(api_request_result.body(), - &error_.emplace(), - &error_message_.emplace()); + task_error_ = ParseErrorResult(api_request_result.body()); return; } - resolve_result_ = std::move(bytes_result); + task_result_.emplace(); + task_result_->resolved_result = std::move(*bytes_result); } void EnsResolverTask::FetchWithEnsip10Resolve() { DCHECK(resolver_address_.IsValid()); DCHECK(supports_ensip_10_); DCHECK(supports_ensip_10_.value()); - DCHECK(!resolve_result_); + DCHECK(!task_result_); if (!dns_encoded_name_) { dns_encoded_name_ = ens::DnsEncode(domain_); if (!dns_encoded_name_) { - error_ = mojom::ProviderError::kInvalidParams; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS); + task_error_.emplace(MakeInternalError()); ScheduleWorkOnTask(); return; } @@ -337,8 +361,7 @@ void EnsResolverTask::OnFetchWithEnsip10ResolveDone( ScopedWorkOnTask work_on_task(this); if (!api_request_result.Is2XXResponseCode()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } @@ -350,9 +373,7 @@ void EnsResolverTask::OnFetchWithEnsip10ResolveDone( auto bytes_result = ParseDecodedBytesResult(api_request_result.body()); if (!bytes_result) { - ParseErrorResult(api_request_result.body(), - &error_.emplace(), - &error_message_.emplace()); + task_error_ = ParseErrorResult(api_request_result.body()); return; } @@ -361,12 +382,12 @@ void EnsResolverTask::OnFetchWithEnsip10ResolveDone( auto decoded_resolve_result = eth_abi::ExtractBytesFromTuple(*bytes_result, 0); if (!decoded_resolve_result) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } - resolve_result_ = std::move(*decoded_resolve_result); + task_result_.emplace(); + task_result_->resolved_result = std::move(*decoded_resolve_result); } void EnsResolverTask::FetchOffchainData() { @@ -376,6 +397,19 @@ void EnsResolverTask::FetchOffchainData() { bool data_substitued = false; bool valid_sender = true; + if (!allow_offchain_.has_value()) { + // No explicit offchain lookup decision. Will popup ui. + task_result_.emplace(); + task_result_->need_to_allow_offchain = true; + ScheduleWorkOnTask(); + return; + } else if (!allow_offchain_.value()) { + // Offchain lookup explicily disabled. + task_error_.emplace(MakeInternalError()); + ScheduleWorkOnTask(); + return; + } + // Sender must match resolver per // https://eips.ethereum.org/EIPS/eip-3668#client-lookup-protocol #5. if (offchain_lookup_data_->sender != resolver_address_) { @@ -400,8 +434,7 @@ void EnsResolverTask::FetchOffchainData() { } if (!valid_sender || !offchain_url.is_valid()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); ScheduleWorkOnTask(); return; } @@ -426,15 +459,13 @@ void EnsResolverTask::OnFetchOffchainDone(APIRequestResult api_request_result) { ScopedWorkOnTask work_on_task(this); if (!api_request_result.Is2XXResponseCode()) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } auto bytes_result = ExtractGatewayResult(api_request_result.body()); if (!bytes_result) { - error_ = mojom::ProviderError::kInternalError; - error_message_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + task_error_.emplace(MakeInternalError()); return; } diff --git a/components/brave_wallet/browser/ens_resolver_task.h b/components/brave_wallet/browser/ens_resolver_task.h index 61576a84d33f..a90aedce9d9f 100644 --- a/components/brave_wallet/browser/ens_resolver_task.h +++ b/components/brave_wallet/browser/ens_resolver_task.h @@ -57,15 +57,39 @@ struct OffchainLookupData { std::vector extra_data; }; +struct EnsResolverTaskResult { + EnsResolverTaskResult(); + EnsResolverTaskResult(const EnsResolverTaskResult&); + EnsResolverTaskResult(EnsResolverTaskResult&&); + EnsResolverTaskResult& operator=(const EnsResolverTaskResult&); + EnsResolverTaskResult& operator=(EnsResolverTaskResult&&); + ~EnsResolverTaskResult(); + + std::vector resolved_result; + bool need_to_allow_offchain = false; +}; + +struct EnsResolverTaskError { + EnsResolverTaskError(); + EnsResolverTaskError(mojom::ProviderError error, std::string error_message); + EnsResolverTaskError(const EnsResolverTaskError&); + EnsResolverTaskError(EnsResolverTaskError&&); + EnsResolverTaskError& operator=(const EnsResolverTaskError&); + EnsResolverTaskError& operator=(EnsResolverTaskError&&); + ~EnsResolverTaskError(); + + mojom::ProviderError error; + std::string error_message; +}; + class EnsResolverTask { public: using APIRequestHelper = api_request_helper::APIRequestHelper; using APIRequestResult = api_request_helper::APIRequestResult; using DoneCallback = base::OnceCallback resolved_result, - mojom::ProviderError error, - std::string error_message)>; + absl::optional result, + absl::optional error)>; using RequestIntermediateCallback = base::OnceCallback; @@ -74,7 +98,8 @@ class EnsResolverTask { APIRequestHelper* api_request_helper_ens_offchain, std::vector ens_call, const std::string& domain, - const GURL& network_url); + const GURL& network_url, + absl::optional allow_offchain); EnsResolverTask(const EnsResolverTask&) = delete; EnsResolverTask& operator=(const EnsResolverTask&) = delete; ~EnsResolverTask(); @@ -112,12 +137,12 @@ class EnsResolverTask { std::string domain_; absl::optional> dns_encoded_name_; GURL network_url_; + absl::optional allow_offchain_; int offchain_lookup_attemps_left_ = 4; - absl::optional> resolve_result_; + absl::optional task_result_; + absl::optional task_error_; - absl::optional error_; - absl::optional error_message_; std::vector ens_resolve_call_; EthAddress resolver_address_; absl::optional supports_ensip_10_; diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index fc45d3539a7b..9122648be921 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -40,6 +40,8 @@ #include "brave/components/brave_wallet/common/hex_utils.h" #include "brave/components/brave_wallet/common/value_conversion_utils.h" #include "brave/components/brave_wallet/common/web3_provider_constants.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/ipfs_service.h" #include "brave/components/ipfs/ipfs_utils.h" #include "components/grit/brave_components_strings.h" @@ -51,6 +53,7 @@ #include "url/origin.h" using api_request_helper::APIRequestHelper; +using decentralized_dns::EnsOffchainResolveMethod; namespace { @@ -113,11 +116,27 @@ net::NetworkTrafficAnnotationTag GetENSOffchainNetworkTrafficAnnotationTag() { )"); } -bool ENSL2Enabled() { +bool EnsL2FeatureEnabled() { return base::FeatureList::IsEnabled( brave_wallet::features::kBraveWalletENSL2Feature); } +bool EnsOffchainPrefEnabled(PrefService* local_state_prefs) { + return decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs) == + EnsOffchainResolveMethod::kEnabled; +} + +bool EnsOffchainPrefDisabled(PrefService* local_state_prefs) { + return decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs) == + EnsOffchainResolveMethod::kDisabled; +} + +void SetEnsOffchainPref(PrefService* local_state_prefs, bool enabled) { + decentralized_dns::SetEnsOffchainResolveMethod( + local_state_prefs, enabled ? EnsOffchainResolveMethod::kEnabled + : EnsOffchainResolveMethod::kDisabled); +} + namespace solana { // https://github.com/solana-labs/solana/blob/f7b2951c79cd07685ed62717e78ab1c200924924/rpc/src/rpc.rs#L1717 constexpr char kAccountNotCreatedError[] = "could not find account"; @@ -129,7 +148,8 @@ namespace brave_wallet { JsonRpcService::JsonRpcService( scoped_refptr url_loader_factory, - PrefService* prefs) + PrefService* prefs, + PrefService* local_state_prefs) : api_request_helper_(new APIRequestHelper(GetNetworkTrafficAnnotationTag(), url_loader_factory)), ud_get_eth_addr_calls_( @@ -138,6 +158,7 @@ JsonRpcService::JsonRpcService( ud_resolve_dns_calls_( std::make_unique>()), prefs_(prefs), + local_state_prefs_(local_state_prefs), weak_ptr_factory_(this) { if (!SetNetwork(GetCurrentChainId(prefs_, mojom::CoinType::ETH), mojom::CoinType::ETH)) { @@ -152,17 +173,23 @@ JsonRpcService::JsonRpcService( LOG(ERROR) << "Could not set network from JsonRpcService() for FIL"; } - if (ENSL2Enabled()) { + if (EnsL2FeatureEnabled()) { api_request_helper_ens_offchain_ = std::make_unique( GetENSOffchainNetworkTrafficAnnotationTag(), url_loader_factory); } } +JsonRpcService::JsonRpcService( + scoped_refptr url_loader_factory, + PrefService* prefs) + : JsonRpcService(std::move(url_loader_factory), std::move(prefs), nullptr) { +} + void JsonRpcService::SetAPIRequestHelperForTesting( scoped_refptr url_loader_factory) { api_request_helper_ = std::make_unique( GetNetworkTrafficAnnotationTag(), url_loader_factory); - if (ENSL2Enabled()) { + if (EnsL2FeatureEnabled()) { api_request_helper_ens_offchain_ = std::make_unique( GetENSOffchainNetworkTrafficAnnotationTag(), url_loader_factory); } @@ -1108,18 +1135,22 @@ void JsonRpcService::OnEnsRegistryGetResolver( void JsonRpcService::EnsGetContentHash(const std::string& domain, EnsGetContentHashCallback callback) { - if (ENSL2Enabled()) { + if (EnsL2FeatureEnabled()) { if (ens_get_content_hash_tasks_.ContainsTaskForDomain(domain)) { ens_get_content_hash_tasks_.AddCallbackForDomain(domain, std::move(callback)); return; } + // TODO(apaymyshev): Implement UI for contenthash offchain lookup consent. + absl::optional allow_offchain = + !EnsOffchainPrefDisabled(local_state_prefs_); + GURL network_url = GetNetworkURL( prefs_, brave_wallet::mojom::kMainnetChainId, mojom::CoinType::ETH); if (!network_url.is_valid()) { std::move(callback).Run( - {}, mojom::ProviderError::kInvalidParams, + {}, false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } @@ -1132,7 +1163,7 @@ void JsonRpcService::EnsGetContentHash(const std::string& domain, std::make_unique( std::move(done_callback), api_request_helper_.get(), api_request_helper_ens_offchain_.get(), MakeContentHashCall(domain), - domain, network_url), + domain, network_url, allow_offchain), std::move(callback)); return; } @@ -1150,14 +1181,14 @@ void JsonRpcService::ContinueEnsGetContentHash( mojom::ProviderError error, const std::string& error_message) { if (error != mojom::ProviderError::kSuccess || resolver_address.empty()) { - std::move(callback).Run({}, error, error_message); + std::move(callback).Run({}, false, error, error_message); return; } std::string data; if (!ens::ContentHash(domain, &data)) { std::move(callback).Run( - {}, mojom::ProviderError::kInvalidParams, + {}, false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } @@ -1166,7 +1197,7 @@ void JsonRpcService::ContinueEnsGetContentHash( mojom::CoinType::ETH); if (!network_url.is_valid()) { std::move(callback).Run( - {}, mojom::ProviderError::kInvalidParams, + {}, false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } @@ -1184,7 +1215,7 @@ void JsonRpcService::OnEnsGetContentHash(EnsGetContentHashCallback callback, DCHECK(callback); if (!api_request_result.Is2XXResponseCode()) { std::move(callback).Run( - {}, mojom::ProviderError::kInternalError, + {}, false, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); return; } @@ -1197,33 +1228,48 @@ void JsonRpcService::OnEnsGetContentHash(EnsGetContentHashCallback callback, std::string error_message; ParseErrorResult(api_request_result.body(), &error, &error_message); - std::move(callback).Run({}, error, error_message); + std::move(callback).Run({}, false, error, error_message); return; } - std::move(callback).Run(content_hash, mojom::ProviderError::kSuccess, ""); + std::move(callback).Run(content_hash, false, mojom::ProviderError::kSuccess, + ""); } void JsonRpcService::EnsGetEthAddr(const std::string& domain, + mojom::EnsOffchainLookupOptionsPtr options, EnsGetEthAddrCallback callback) { if (!IsValidDomain(domain)) { std::move(callback).Run( - "", mojom::ProviderError::kInvalidParams, + "", false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } - if (ENSL2Enabled()) { + if (EnsL2FeatureEnabled()) { if (ens_get_eth_addr_tasks_.ContainsTaskForDomain(domain)) { ens_get_eth_addr_tasks_.AddCallbackForDomain(domain, std::move(callback)); return; } + if (options && options->remember) { + SetEnsOffchainPref(local_state_prefs_, options->allow); + } + + absl::optional allow_offchain; + if (EnsOffchainPrefEnabled(local_state_prefs_) || + (options && options->allow)) { + allow_offchain = true; + } else if (EnsOffchainPrefDisabled(local_state_prefs_) || + (options && !options->allow)) { + allow_offchain = false; + } + GURL network_url = GetNetworkURL( prefs_, brave_wallet::mojom::kMainnetChainId, mojom::CoinType::ETH); if (!network_url.is_valid()) { std::move(callback).Run( - "", mojom::ProviderError::kInvalidParams, + "", false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } @@ -1236,7 +1282,7 @@ void JsonRpcService::EnsGetEthAddr(const std::string& domain, std::make_unique( std::move(done_callback), api_request_helper_.get(), api_request_helper_ens_offchain_.get(), MakeAddrCall(domain), - domain, network_url), + domain, network_url, allow_offchain), std::move(callback)); return; } @@ -1249,18 +1295,21 @@ void JsonRpcService::EnsGetEthAddr(const std::string& domain, void JsonRpcService::OnEnsGetEthAddrTaskDone( EnsResolverTask* task, - std::vector resolved_result, - mojom::ProviderError error, - std::string error_message) { + absl::optional task_result, + absl::optional task_error) { auto callbacks = ens_get_eth_addr_tasks_.TaskDone(task); if (callbacks.empty()) { return; } std::string address; - if (error == mojom::ProviderError::kSuccess) { + mojom::ProviderError error = + task_error ? task_error->error : mojom::ProviderError::kSuccess; + std::string error_message = task_error ? task_error->error_message : ""; + + if (task_result && !task_result->resolved_result.empty()) { EthAddress eth_address = - eth_abi::ExtractAddressFromTuple(resolved_result, 0); + eth_abi::ExtractAddress(task_result->resolved_result); if (eth_address.IsValid() && !eth_address.IsZeroAddress()) { address = eth_address.ToHex(); } else { @@ -1269,50 +1318,72 @@ void JsonRpcService::OnEnsGetEthAddrTaskDone( } } + bool require_offchain_consent = + (task_result ? task_result->need_to_allow_offchain : false); + if (require_offchain_consent && EnsOffchainPrefDisabled(local_state_prefs_)) { + require_offchain_consent = false; + error = mojom::ProviderError::kInternalError; + error_message = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); + } + for (auto& cb : callbacks) { - std::move(cb).Run(address, error, error_message); + std::move(cb).Run(address, require_offchain_consent, error, error_message); } } void JsonRpcService::OnEnsGetContentHashTaskDone( EnsResolverTask* task, - std::vector resolved_result, - mojom::ProviderError error, - std::string error_message) { + absl::optional task_result, + absl::optional task_error) { auto callbacks = ens_get_content_hash_tasks_.TaskDone(task); if (callbacks.empty()) { return; } + DCHECK(!(task_result && task_result->need_to_allow_offchain)); + absl::optional> content_hash; - if (error == mojom::ProviderError::kSuccess) { - content_hash = eth_abi::ExtractBytesFromTuple(resolved_result, 0); + mojom::ProviderError error = + task_error ? task_error->error : mojom::ProviderError::kSuccess; + std::string error_message = task_error ? task_error->error_message : ""; + + if (task_result && !task_result->resolved_result.empty()) { + content_hash = + eth_abi::ExtractBytesFromTuple(task_result->resolved_result, 0); if (!content_hash || content_hash->empty()) { error = mojom::ProviderError::kInvalidParams; error_message = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS); } } + bool require_offchain_consent = + (task_result ? task_result->need_to_allow_offchain : false); + if (require_offchain_consent && EnsOffchainPrefDisabled(local_state_prefs_)) { + require_offchain_consent = false; + error = mojom::ProviderError::kInvalidParams; + error_message = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS); + } + for (auto& cb : callbacks) { - std::move(cb).Run(content_hash.value_or(std::vector()), error, - error_message); + std::move(cb).Run(content_hash.value_or(std::vector()), + require_offchain_consent, error, error_message); } } void JsonRpcService::ContinueEnsGetEthAddr(const std::string& domain, - StringResultCallback callback, + EnsGetEthAddrCallback callback, const std::string& resolver_address, mojom::ProviderError error, const std::string& error_message) { if (error != mojom::ProviderError::kSuccess || resolver_address.empty()) { - std::move(callback).Run("", error, error_message); + std::move(callback).Run("", false, error, error_message); return; } std::string data; if (!ens::Addr(domain, &data)) { std::move(callback).Run( - "", mojom::ProviderError::kInvalidParams, + "", false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } @@ -1325,12 +1396,12 @@ void JsonRpcService::ContinueEnsGetEthAddr(const std::string& domain, network_urls_[mojom::CoinType::ETH], std::move(internal_callback)); } -void JsonRpcService::OnEnsGetEthAddr(StringResultCallback callback, +void JsonRpcService::OnEnsGetEthAddr(EnsGetEthAddrCallback callback, APIRequestResult api_request_result) { DCHECK(callback); if (!api_request_result.Is2XXResponseCode()) { std::move(callback).Run( - "", mojom::ProviderError::kInternalError, + "", false, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)); return; } @@ -1342,11 +1413,11 @@ void JsonRpcService::OnEnsGetEthAddr(StringResultCallback callback, std::string error_message; ParseErrorResult(api_request_result.body(), &error, &error_message); - std::move(callback).Run("", error, error_message); + std::move(callback).Run("", false, error, error_message); return; } - std::move(callback).Run(address, mojom::ProviderError::kSuccess, ""); + std::move(callback).Run(address, false, mojom::ProviderError::kSuccess, ""); } void JsonRpcService::UnstoppableDomainsResolveDns( diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 17c7cba64446..a82656cb31b9 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -49,6 +49,11 @@ class MultichainCalls; class JsonRpcService : public KeyedService, public mojom::JsonRpcService { public: + JsonRpcService( + scoped_refptr url_loader_factory, + PrefService* prefs, + PrefService* local_state_prefs); + // For testing: JsonRpcService( scoped_refptr url_loader_factory, PrefService* prefs); @@ -67,6 +72,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { const std::string& error_message)>; using EnsGetContentHashCallback = base::OnceCallback& content_hash, + bool require_offchain_consent, mojom::ProviderError error, const std::string& error_message)>; using GetBlockNumberCallback = @@ -170,6 +176,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { void EnsGetContentHash(const std::string& domain, EnsGetContentHashCallback callback); void EnsGetEthAddr(const std::string& domain, + mojom::EnsOffchainLookupOptionsPtr options, EnsGetEthAddrCallback callback) override; bool SetNetwork(const std::string& chain_id, @@ -426,19 +433,19 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { void OnEnsGetContentHash(EnsGetContentHashCallback callback, APIRequestResult api_request_result); void ContinueEnsGetEthAddr(const std::string& domain, - StringResultCallback callback, + EnsGetEthAddrCallback callback, const std::string& resolver_address, mojom::ProviderError error, const std::string& error_message); - void OnEnsGetEthAddrTaskDone(EnsResolverTask* task, - std::vector resolved_result, - mojom::ProviderError error, - std::string error_message); - void OnEnsGetContentHashTaskDone(EnsResolverTask* task, - std::vector resolved_result, - mojom::ProviderError error, - std::string error_message); - void OnEnsGetEthAddr(StringResultCallback callback, + void OnEnsGetEthAddrTaskDone( + EnsResolverTask* task, + absl::optional task_result, + absl::optional error); + void OnEnsGetContentHashTaskDone( + EnsResolverTask* task, + absl::optional task_result, + absl::optional error); + void OnEnsGetEthAddr(EnsGetEthAddrCallback callback, APIRequestResult api_request_result); void OnGetFilEstimateGas(GetFilEstimateGasCallback callback, APIRequestResult api_request_result); @@ -550,6 +557,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { mojo::ReceiverSet receivers_; PrefService* prefs_ = nullptr; + PrefService* local_state_prefs_ = nullptr; base::WeakPtrFactory weak_ptr_factory_; }; diff --git a/components/brave_wallet/browser/json_rpc_service_unittest.cc b/components/brave_wallet/browser/json_rpc_service_unittest.cc index d71d4d92350e..404c6ccdd7db 100644 --- a/components/brave_wallet/browser/json_rpc_service_unittest.cc +++ b/components/brave_wallet/browser/json_rpc_service_unittest.cc @@ -40,6 +40,8 @@ #include "brave/components/brave_wallet/common/test_utils.h" #include "brave/components/brave_wallet/common/value_conversion_utils.h" #include "brave/components/constants/brave_services_key.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/ipfs_service.h" #include "brave/components/ipfs/ipfs_utils.h" #include "brave/components/ipfs/pref_names.h" @@ -61,6 +63,10 @@ using testing::ElementsAreArray; +MATCHER_P(MatchesCIDv1URL, ipfs_url, "") { + return ipfs::ContentHashToCIDv1URL(arg).spec() == ipfs_url; +} + namespace brave_wallet { namespace { @@ -193,19 +199,6 @@ void OnStringResponse(bool* callback_called, EXPECT_EQ(expected_error_message, error_message); } -void OnBytesResponse(bool* callback_called, - brave_wallet::mojom::ProviderError expected_error, - const std::string& expected_error_message, - const std::vector& expected_response, - const std::vector& response, - brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - *callback_called = true; - EXPECT_EQ(expected_response, response); - EXPECT_EQ(expected_error, error); - EXPECT_EQ(expected_error_message, error_message); -} - void OnBoolResponse(bool* callback_called, brave_wallet::mojom::ProviderError expected_error, const std::string& expected_error_message, @@ -364,11 +357,12 @@ class JsonRpcServiceUnitTest : public testing::Test { "0000\"}"); })); + decentralized_dns::RegisterLocalStatePrefs(local_state_prefs_.registry()); brave_wallet::RegisterProfilePrefs(prefs_.registry()); brave_wallet::RegisterProfilePrefsForMigration(prefs_.registry()); ipfs::IpfsService::RegisterProfilePrefs(prefs_.registry()); - json_rpc_service_ = - std::make_unique(shared_url_loader_factory_, &prefs_); + json_rpc_service_ = std::make_unique( + shared_url_loader_factory_, &prefs_, &local_state_prefs_); SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::ETH); SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::SOL); SetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL); @@ -381,6 +375,7 @@ class JsonRpcServiceUnitTest : public testing::Test { } PrefService* prefs() { return &prefs_; } + PrefService* local_state_prefs() { return &local_state_prefs_; } GURL GetNetwork(const std::string& chain_id, mojom::CoinType coin) { return brave_wallet::GetNetworkURL(prefs(), chain_id, coin); @@ -1008,6 +1003,7 @@ class JsonRpcServiceUnitTest : public testing::Test { private: base::test::TaskEnvironment task_environment_; sync_preferences::TestingPrefServiceSyncable prefs_; + sync_preferences::TestingPrefServiceSyncable local_state_prefs_; scoped_refptr shared_url_loader_factory_; data_decoder::test::InProcessDataDecoder in_process_data_decoder_; }; @@ -1197,55 +1193,51 @@ TEST_F(JsonRpcServiceUnitTest, GetHiddenNetworks) { } TEST_F(JsonRpcServiceUnitTest, EnsGetContentHash) { - bool callback_called = false; - SetUDENSInterceptor(mojom::kMainnetChainId); - json_rpc_service_->EnsGetContentHash( - "brantly.eth", - base::BindLambdaForTesting([&](const std::vector& result, - brave_wallet::mojom::ProviderError error, - const std::string& error_message) { - callback_called = true; - EXPECT_EQ(error, mojom::ProviderError::kSuccess); - EXPECT_TRUE(error_message.empty()); - EXPECT_EQ( - ipfs::ContentHashToCIDv1URL(result).spec(), - "ipfs://" - "bafybeibd4ala53bs26dvygofvr6ahpa7gbw4eyaibvrbivf4l5rr44yqu4"); - })); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + { + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(MatchesCIDv1URL( + "ipfs://" + "bafybeibd4ala53bs26dvygofvr6ahpa7gbw4eyaibvrbivf4l5rr44yqu4"), + false, mojom::ProviderError::kSuccess, "")); + + SetUDENSInterceptor(mojom::kMainnetChainId); + json_rpc_service_->EnsGetContentHash("brantly.eth", callback.Get()); + base::RunLoop().RunUntilIdle(); + } - callback_called = false; - SetHTTPRequestTimeoutInterceptor(); - json_rpc_service_->EnsGetContentHash( - "brantly.eth", - base::BindOnce(&OnBytesResponse, &callback_called, - mojom::ProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR), - std::vector())); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + { + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + SetHTTPRequestTimeoutInterceptor(); + json_rpc_service_->EnsGetContentHash("brantly.eth", callback.Get()); + base::RunLoop().RunUntilIdle(); + } - callback_called = false; - SetInvalidJsonInterceptor(); - json_rpc_service_->EnsGetContentHash( - "brantly.eth", - base::BindOnce(&OnBytesResponse, &callback_called, - mojom::ProviderError::kParsingError, - l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR), - std::vector())); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + { + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kParsingError, + l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR))); + SetInvalidJsonInterceptor(); + json_rpc_service_->EnsGetContentHash("brantly.eth", callback.Get()); + base::RunLoop().RunUntilIdle(); + } - callback_called = false; - SetLimitExceededJsonErrorResponse(); - json_rpc_service_->EnsGetContentHash( - "brantly.eth", - base::BindOnce(&OnBytesResponse, &callback_called, - mojom::ProviderError::kLimitExceeded, - "Request exceeds defined limit", std::vector())); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(std::vector(), false, + mojom::ProviderError::kLimitExceeded, + "Request exceeds defined limit")); + SetLimitExceededJsonErrorResponse(); + json_rpc_service_->EnsGetContentHash("brantly.eth", callback.Get()); + base::RunLoop().RunUntilIdle(); + } } TEST_F(JsonRpcServiceUnitTest, EnsGetEthAddr) { @@ -1253,9 +1245,9 @@ TEST_F(JsonRpcServiceUnitTest, EnsGetEthAddr) { EXPECT_TRUE(SetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH)); base::MockCallback callback; - EXPECT_CALL(callback, Run("0x983110309620D911731Ac0932219af06091b6744", + EXPECT_CALL(callback, Run("0x983110309620D911731Ac0932219af06091b6744", false, mojom::ProviderError::kSuccess, "")); - json_rpc_service_->EnsGetEthAddr("brantly-test.eth", callback.Get()); + json_rpc_service_->EnsGetEthAddr("brantly-test.eth", nullptr, callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -2571,25 +2563,26 @@ TEST_F(JsonRpcServiceUnitTest, GetEthAddrInvalidDomain) { "brave-.eth", "b.eth"}; for (const auto& domain : invalid_domains) { - bool callback_called = false; - json_rpc_service_->EnsGetEthAddr( - domain, - base::BindOnce(&OnStringResponse, &callback_called, - mojom::ProviderError::kInvalidParams, - l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS), - "")); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + { + base::MockCallback callback; + EXPECT_CALL(callback, + Run("", false, mojom::ProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); - callback_called = false; - json_rpc_service_->UnstoppableDomainsGetEthAddr( - domain, - base::BindOnce(&OnStringResponse, &callback_called, - mojom::ProviderError::kInvalidParams, - l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS), - "")); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(callback_called); + json_rpc_service_->EnsGetEthAddr(domain, nullptr, callback.Get()); + base::RunLoop().RunUntilIdle(); + } + + { + base::MockCallback + callback; + EXPECT_CALL(callback, + Run("", mojom::ProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); + + json_rpc_service_->UnstoppableDomainsGetEthAddr(domain, callback.Get()); + base::RunLoop().RunUntilIdle(); + } } } @@ -4338,6 +4331,7 @@ class ENSL2JsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { void SetUp() override { JsonRpcServiceUnitTest::SetUp(); + json_rpc_endpoint_handler_ = std::make_unique( GetNetwork(mojom::kMainnetChainId, mojom::CoinType::ETH)); @@ -4402,6 +4396,10 @@ class ENSL2JsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { return bytes; } + mojom::EnsOffchainLookupOptionsPtr AllowOffchain() { + return mojom::EnsOffchainLookupOptions::New(true, false); + } + protected: void HandleRequest(const network::ResourceRequest& request) { url_loader_factory_.ClearResponses(); @@ -4434,18 +4432,19 @@ class ENSL2JsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr) { base::MockCallback callback; - EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), + EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), false, mojom::ProviderError::kSuccess, "")); - json_rpc_service_->EnsGetEthAddr(ens_host(), callback.Get()); + json_rpc_service_->EnsGetEthAddr(ens_host(), AllowOffchain(), callback.Get()); base::RunLoop().RunUntilIdle(); } TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr_NoResolver) { base::MockCallback callback; EXPECT_CALL(callback, - Run("", mojom::ProviderError::kInternalError, + Run("", false, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); - json_rpc_service_->EnsGetEthAddr("unknown-host.eth", callback.Get()); + json_rpc_service_->EnsGetEthAddr("unknown-host.eth", AllowOffchain(), + callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4457,9 +4456,9 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr_NoEnsip10Support) { ensip10_support_handler_->DisableSupport(); base::MockCallback callback; - EXPECT_CALL(callback, Run(onchain_eth_addr().ToHex(), + EXPECT_CALL(callback, Run(onchain_eth_addr().ToHex(), false, mojom::ProviderError::kSuccess, "")); - json_rpc_service_->EnsGetEthAddr(ens_host(), callback.Get()); + json_rpc_service_->EnsGetEthAddr(ens_host(), AllowOffchain(), callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4469,9 +4468,9 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr_Gateway500Error) { base::MockCallback callback; EXPECT_CALL(callback, - Run("", mojom::ProviderError::kInternalError, + Run("", false, mojom::ProviderError::kInternalError, l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); - json_rpc_service_->EnsGetEthAddr(ens_host(), callback.Get()); + json_rpc_service_->EnsGetEthAddr(ens_host(), AllowOffchain(), callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4481,25 +4480,146 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr_GatewayNoRecord) { base::MockCallback callback; EXPECT_CALL(callback, - Run("", mojom::ProviderError::kInvalidParams, + Run("", false, mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); - json_rpc_service_->EnsGetEthAddr(ens_host(), callback.Get()); + json_rpc_service_->EnsGetEthAddr(ens_host(), AllowOffchain(), callback.Get()); base::RunLoop().RunUntilIdle(); } +TEST_F(ENSL2JsonRpcServiceUnitTest, GetEthAddr_Consent) { + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kAsk, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + + // Call with defaults. + { + base::MockCallback callback; + // Called with `require_offchain_consent` == true. + EXPECT_CALL(callback, Run("", true, mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetEthAddr(ens_host(), nullptr, callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kAsk, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Allow once. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetEthAddr( + ens_host(), mojom::EnsOffchainLookupOptions::New(true, false), + callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kAsk, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Allow and remember. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetEthAddr( + ens_host(), mojom::EnsOffchainLookupOptions::New(true, true), + callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kEnabled, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Allowed without explicit consent. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetEthAddr(ens_host(), nullptr, callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kEnabled, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Reset in prefs. + decentralized_dns::SetEnsOffchainResolveMethod( + local_state_prefs(), decentralized_dns::EnsOffchainResolveMethod::kAsk); + + // Fails after no once. + { + base::MockCallback callback; + EXPECT_CALL(callback, + Run("", false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->EnsGetEthAddr( + ens_host(), mojom::EnsOffchainLookupOptions::New(false, false), + callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kAsk, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Fails after no and remember. + { + base::MockCallback callback; + EXPECT_CALL(callback, + Run("", false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->EnsGetEthAddr( + ens_host(), mojom::EnsOffchainLookupOptions::New(false, true), + callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kDisabled, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Fails after no explicit consent. + { + base::MockCallback callback; + EXPECT_CALL(callback, + Run("", false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->EnsGetEthAddr(ens_host(), nullptr, callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kDisabled, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } + + // Still ok with explicit consent. Should not happen with our ui, but still + // fixing that behavior. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_eth_addr().ToHex(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetEthAddr( + ens_host(), mojom::EnsOffchainLookupOptions::New(true, false), + callback.Get()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kDisabled, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + } +} + TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash) { base::MockCallback callback; - EXPECT_CALL(callback, - Run(offchain_contenthash(), mojom::ProviderError::kSuccess, "")); + EXPECT_CALL(callback, Run(offchain_contenthash(), false, + mojom::ProviderError::kSuccess, "")); json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); base::RunLoop().RunUntilIdle(); } TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash_NoResolver) { base::MockCallback callback; - EXPECT_CALL(callback, - Run(std::vector(), mojom::ProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); json_rpc_service_->EnsGetContentHash("unknown-host.eth", callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4513,8 +4633,8 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash_NoEnsip10Support) { ensip10_support_handler_->DisableSupport(); base::MockCallback callback; - EXPECT_CALL(callback, - Run(onchain_contenthash(), mojom::ProviderError::kSuccess, "")); + EXPECT_CALL(callback, Run(onchain_contenthash(), false, + mojom::ProviderError::kSuccess, "")); json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4524,9 +4644,10 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash_Gateway500Error) { offchain_gateway_handler_->SetRespondWith500(); base::MockCallback callback; - EXPECT_CALL(callback, - Run(std::vector(), mojom::ProviderError::kInternalError, - l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); base::RunLoop().RunUntilIdle(); } @@ -4536,11 +4657,55 @@ TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash_GatewayNoRecord) { offchain_gateway_handler_->SetRespondWithNoRecord(); base::MockCallback callback; - EXPECT_CALL(callback, - Run(std::vector(), mojom::ProviderError::kInvalidParams, - l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); base::RunLoop().RunUntilIdle(); } +TEST_F(ENSL2JsonRpcServiceUnitTest, GetContentHash_Consent) { + EXPECT_EQ( + decentralized_dns::EnsOffchainResolveMethod::kAsk, + decentralized_dns::GetEnsOffchainResolveMethod(local_state_prefs())); + + // Ok by default. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_contenthash(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + } + + decentralized_dns::SetEnsOffchainResolveMethod( + local_state_prefs(), + decentralized_dns::EnsOffchainResolveMethod::kEnabled); + // Ok when enabled by prefs. + { + base::MockCallback callback; + EXPECT_CALL(callback, Run(offchain_contenthash(), false, + mojom::ProviderError::kSuccess, "")); + json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + } + + // Disable in prefs. + decentralized_dns::SetEnsOffchainResolveMethod( + local_state_prefs(), + decentralized_dns::EnsOffchainResolveMethod::kDisabled); + + // Fails when disabled in prefs. + { + base::MockCallback callback; + EXPECT_CALL( + callback, + Run(std::vector(), false, mojom::ProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->EnsGetContentHash(ens_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + } +} + } // namespace brave_wallet diff --git a/components/brave_wallet/browser/test/BUILD.gn b/components/brave_wallet/browser/test/BUILD.gn index c4d9c63b5b29..a3470de5cdad 100644 --- a/components/brave_wallet/browser/test/BUILD.gn +++ b/components/brave_wallet/browser/test/BUILD.gn @@ -86,6 +86,7 @@ source_set("brave_wallet_unit_tests") { "//brave/components/brave_wallet/common:solana_utils", "//brave/components/brave_wallet/common:test_support", "//brave/components/constants", + "//brave/components/decentralized_dns/core", "//brave/components/filecoin/rs:cxx", "//brave/components/ipfs", "//brave/components/resources:strings_grit", diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index e58cc12f55b6..045e7f77f141 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -833,6 +833,11 @@ struct SolanaSendTransactionOptions { OptionalSkipPreflight? skip_preflight; }; +struct EnsOffchainLookupOptions { + bool allow; + bool remember; +}; + // Deals with the ETH JSON RPC API, as well as things like the user's current // network. interface JsonRpcService { @@ -883,7 +888,7 @@ interface JsonRpcService { GetERC1155Metadata(string contract, string token_id, string chain_id) => (string response, ProviderError error, string error_message); // ENS lookups - EnsGetEthAddr(string domain) => (string address, ProviderError error, string error_message); + EnsGetEthAddr(string domain, EnsOffchainLookupOptions? options) => (string address, bool require_offchain_consent, ProviderError error, string error_message); // Unstoppable Domains lookups UnstoppableDomainsGetEthAddr(string domain) => (string address, ProviderError error, string error_message); diff --git a/components/brave_wallet_ui/common/async/lib.ts b/components/brave_wallet_ui/common/async/lib.ts index 4dbd8e048717..b3bdc3e3446c 100644 --- a/components/brave_wallet_ui/common/async/lib.ts +++ b/components/brave_wallet_ui/common/async/lib.ts @@ -140,9 +140,9 @@ export async function isStrongPassword (value: string) { return (await apiProxy.keyringService.isStrongPassword(value)).result } -export async function findENSAddress (address: string) { +export async function findENSAddress (address: string, ensOffchainLookupOptions?: BraveWallet.EnsOffchainLookupOptions | undefined) { const apiProxy = getAPIProxy() - return apiProxy.jsonRpcService.ensGetEthAddr(address) + return apiProxy.jsonRpcService.ensGetEthAddr(address, ensOffchainLookupOptions || null) } export async function findUnstoppableDomainAddress (address: string) { diff --git a/components/brave_wallet_ui/common/hooks/send.ts b/components/brave_wallet_ui/common/hooks/send.ts index 0df703284b9c..6a8c20999310 100644 --- a/components/brave_wallet_ui/common/hooks/send.ts +++ b/components/brave_wallet_ui/common/hooks/send.ts @@ -51,7 +51,9 @@ export default function useSend () { selectedSendAsset, sendAmount, toAddress, - toAddressOrUrl + toAddressOrUrl, + showEnsOffchainLookupOptions, + ensOffchainLookupOptions } = useSelector((state: { sendCrypto: PendingCryptoSendState }) => state.sendCrypto) // custom hooks @@ -67,6 +69,12 @@ export default function useSend () { const setToAddress = (payload?: string | undefined) => { dispatch(SendCryptoActions.setToAddress(payload)) } + const setShowEnsOffchainLookupOptions = (payload: boolean) => { + dispatch(SendCryptoActions.setShowEnsOffchainLookupOptions(payload)) + } + const setEnsOffchainLookupOptions = (payload?: BraveWallet.EnsOffchainLookupOptions | undefined) => { + dispatch(SendCryptoActions.setEnsOffchainLookupOptions(payload)) + } const setAddressWarning = (payload?: string | undefined) => { dispatch(SendCryptoActions.setAddressWarning(payload)) } @@ -98,13 +106,15 @@ export default function useSend () { // If value ends with a supported ENS extension, will call findENSAddress. // If success true, will set toAddress else will return error message. if (endsWithAny(supportedENSExtensions, valueToLowerCase)) { - findENSAddress(toAddressOrUrl).then((value: GetEthAddrReturnInfo) => { + findENSAddress(toAddressOrUrl, ensOffchainLookupOptions).then((value: GetEthAddrReturnInfo) => { if (value.error === BraveWallet.ProviderError.kSuccess) { setAddressError('') setAddressWarning('') setToAddress(value.address) + setShowEnsOffchainLookupOptions(value.requireOffchainConsent) return } + setShowEnsOffchainLookupOptions(false) setNotRegisteredError(valueToLowerCase) }).catch(e => console.log(e)) return @@ -179,7 +189,7 @@ export default function useSend () { // Fallback error state setAddressWarning('') setAddressError(getLocale('braveWalletNotValidAddress')) - }, [selectedAccount]) + }, [selectedAccount, ensOffchainLookupOptions]) const processFilecoinAddress = React.useCallback((toAddressOrUrl: string) => { // Do nothing if value is an empty string @@ -357,7 +367,7 @@ export default function useSend () { } else if (selectedAccount?.coin === BraveWallet.CoinType.SOL) { processSolanaAddress(toAddressOrUrl) } - }, [toAddressOrUrl, selectedAccount?.coin]) + }, [toAddressOrUrl, selectedAccount?.coin, ensOffchainLookupOptions]) return { setSendAmount, @@ -370,6 +380,9 @@ export default function useSend () { addressError, addressWarning, selectedSendAsset, - sendAmountValidationError + sendAmountValidationError, + showEnsOffchainLookupOptions, + ensOffchainLookupOptions, + setEnsOffchainLookupOptions } } diff --git a/components/brave_wallet_ui/common/reducers/send_crypto_reducer.ts b/components/brave_wallet_ui/common/reducers/send_crypto_reducer.ts index 8f84e00db72b..6a1006cd5244 100644 --- a/components/brave_wallet_ui/common/reducers/send_crypto_reducer.ts +++ b/components/brave_wallet_ui/common/reducers/send_crypto_reducer.ts @@ -13,6 +13,8 @@ export interface PendingCryptoSendState { addressError?: string addressWarning?: string sendAmount: string + showEnsOffchainLookupOptions: boolean + ensOffchainLookupOptions?: BraveWallet.EnsOffchainLookupOptions } const defaultState: PendingCryptoSendState = { @@ -21,7 +23,9 @@ const defaultState: PendingCryptoSendState = { addressError: undefined, addressWarning: undefined, selectedSendAsset: undefined, - toAddressOrUrl: '' + toAddressOrUrl: '', + showEnsOffchainLookupOptions: false, + ensOffchainLookupOptions: undefined } export const SendCryptoActions = { @@ -29,6 +33,8 @@ export const SendCryptoActions = { setToAddressOrUrl: createAction('setToAddressOrUrl'), setAddressError: createAction('setAddressError'), setToAddress: createAction('setToAddress'), + setShowEnsOffchainLookupOptions: createAction('setShowEnsOffchainLookupOptions'), + setEnsOffchainLookupOptions: createAction('setEnsOffchainLookupOptions'), setAddressWarning: createAction('setAddressWarning'), selectSendAsset: createAction('selectSendAsset') } @@ -76,6 +82,26 @@ export const createSendCryptoReducer = (initialState: PendingCryptoSendState) => } }) + reducer.on(SendCryptoActions.setShowEnsOffchainLookupOptions, ( + state: PendingCryptoSendState, + payload: boolean + ): PendingCryptoSendState => { + return { + ...state, + showEnsOffchainLookupOptions: payload + } + }) + + reducer.on(SendCryptoActions.setEnsOffchainLookupOptions, ( + state: PendingCryptoSendState, + payload: BraveWallet.EnsOffchainLookupOptions | undefined + ): PendingCryptoSendState => { + return { + ...state, + ensOffchainLookupOptions: payload + } + }) + reducer.on(SendCryptoActions.setAddressWarning, ( state: PendingCryptoSendState, payload: string diff --git a/components/brave_wallet_ui/components/buy-send-swap/send/index.tsx b/components/brave_wallet_ui/components/buy-send-swap/send/index.tsx index 37c20d7aeaf4..acc97c8f53e2 100644 --- a/components/brave_wallet_ui/components/buy-send-swap/send/index.tsx +++ b/components/brave_wallet_ui/components/buy-send-swap/send/index.tsx @@ -41,6 +41,9 @@ function Send (props: Props) { const { toAddressOrUrl, toAddress, + showEnsOffchainLookupOptions, + ensOffchainLookupOptions, + setEnsOffchainLookupOptions, addressError, addressWarning, sendAmount, @@ -149,6 +152,9 @@ function Send (props: Props) { addressError={addressError} addressWarning={addressWarning} toAddress={toAddress} + showEnsOffchainLookupOptions={showEnsOffchainLookupOptions} + ensOffchainLookupOptions={ensOffchainLookupOptions} + setEnsOffchainLookupOptions={setEnsOffchainLookupOptions} inputName='address' onPaste={onPasteFromClipboard} selectedNetwork={selectedNetwork} diff --git a/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/index.tsx b/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/index.tsx index bbb7858feb46..65c6e203e38e 100644 --- a/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/index.tsx +++ b/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/index.tsx @@ -43,11 +43,13 @@ import { AddressConfirmationText, ButtonLeftSide, LearnMoreButton, + EnsProceedButton, WarningRow, Spacer } from './style' import { BubbleContainer } from '../shared-styles' +import { Checkbox } from '../../shared/checkbox/checkbox' export type BuySendSwapInputType = | 'toAmount' @@ -68,6 +70,8 @@ export interface Props { addressWarning?: string toAddressOrUrl?: string toAddress?: string + showEnsOffchainLookupOptions?: boolean + ensOffchainLookupOptions?: BraveWallet.EnsOffchainLookupOptions | undefined inputName?: string orderType?: OrderTypes slippageTolerance?: SlippagePresetObjectType @@ -86,6 +90,7 @@ export interface Props { onRefresh?: () => void onPaste?: () => void onShowCurrencySelection?: () => void + setEnsOffchainLookupOptions?: (options: BraveWallet.EnsOffchainLookupOptions) => void } function SwapInputComponent (props: Props) { @@ -101,6 +106,8 @@ function SwapInputComponent (props: Props) { addressWarning, toAddressOrUrl, toAddress, + showEnsOffchainLookupOptions, + ensOffchainLookupOptions, orderType, slippageTolerance, orderExpiration, @@ -115,11 +122,13 @@ function SwapInputComponent (props: Props) { onSelectSlippageTolerance, onSelectExpiration, onShowSelection, - onShowCurrencySelection + onShowCurrencySelection, + setEnsOffchainLookupOptions } = props const [spin, setSpin] = React.useState(0) const [expandSelector, setExpandSelector] = React.useState(false) const [showSlippageWarning, setShowSlippageWarning] = React.useState(false) + const [ensOffchainOptionsRemember, setEnsOffchainOptionsRemember] = React.useState(ensOffchainLookupOptions ? ensOffchainLookupOptions.remember : false) // redux const { @@ -264,6 +273,26 @@ function SwapInputComponent (props: Props) { }) } + const onClickEnsOffchainLearnMore = () => { + chrome.tabs.create({ url: 'https://github.com/brave/brave-browser/wiki/ENS-offchain-lookup' }, () => { + if (chrome.runtime.lastError) { + console.error('tabs.create failed: ' + chrome.runtime.lastError.message) + } + }) + } + + const onClickProceedEnsOffchainYes = () => { + if (setEnsOffchainLookupOptions) { + setEnsOffchainLookupOptions({ remember: ensOffchainOptionsRemember, allow: true }) + } + } + + const onClickProceedEnsOffchainNo = () => { + if (setEnsOffchainLookupOptions) { + setEnsOffchainLookupOptions({ remember: ensOffchainOptionsRemember, allow: false }) + } + } + const placeholderText = React.useMemo((): string => { return componentType === 'toAddress' ? selectedNetwork?.coin === BraveWallet.CoinType.ETH @@ -440,12 +469,37 @@ function SwapInputComponent (props: Props) { } {componentType === 'toAddress' && toAddress !== toAddressOrUrl && !addressError && - - {reduceAddress(toAddress ?? '')} - + <> + {showEnsOffchainLookupOptions + ? ( + <> + + {getLocale('braveWalletEnsOffchainWarning')} + + + + {getLocale('braveWalletEnsOffchainProceedWithYes')} + + + {getLocale('braveWalletEnsOffchainProceedWithNo')} + + + {getLocale('braveWalletAllowAddNetworkLearnMoreButton')} + + + + {getLocale('braveWalletEnsOffchainDontShowAgain')} + + + ) + : ( + {reduceAddress(toAddress ?? '')} + ) + } + } ) diff --git a/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/style.ts b/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/style.ts index 5dc264959456..4a9430b464de 100644 --- a/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/style.ts +++ b/components/brave_wallet_ui/components/buy-send-swap/swap-input-component/style.ts @@ -307,6 +307,20 @@ export const LearnMoreButton = styled(WalletButton)` padding: 0px; ` +export const EnsProceedButton = styled(WalletButton)` + cursor: pointer; + outline: none; + background: none; + border: none; + font-family: Poppins; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.01em; + color: ${(p) => p.theme.color.interactive05}; + margin: 10px; + padding: 0px; +` + export const WarningRow = styled.div>` display: flex; width: 100%; diff --git a/components/brave_wallet_ui/stories/mock-data/send-crypto-state.ts b/components/brave_wallet_ui/stories/mock-data/send-crypto-state.ts index de110659c85d..75c146dcdb01 100644 --- a/components/brave_wallet_ui/stories/mock-data/send-crypto-state.ts +++ b/components/brave_wallet_ui/stories/mock-data/send-crypto-state.ts @@ -6,5 +6,7 @@ export const mockSendCryptoState: PendingCryptoSendState = { toAddressOrUrl: '', addressError: undefined, addressWarning: undefined, - selectedSendAsset: undefined + selectedSendAsset: undefined, + showEnsOffchainLookupOptions: false, + ensOffchainLookupOptions: undefined } diff --git a/components/decentralized_dns/DEPS b/components/decentralized_dns/DEPS deleted file mode 100644 index 778791c5d956..000000000000 --- a/components/decentralized_dns/DEPS +++ /dev/null @@ -1,14 +0,0 @@ -include_rules = [ - "+base", - "+components/keyed_service/core", - "+components/grit", - "+components/prefs", - "+components/security_interstitials/content", - "+components/security_interstitials/core", - "+components/user_prefs", - "+content/public/browser", - "+content/public/common", - "+net", - "+ui/base", - "+url", -] diff --git a/components/decentralized_dns/BUILD.gn b/components/decentralized_dns/content/BUILD.gn similarity index 88% rename from components/decentralized_dns/BUILD.gn rename to components/decentralized_dns/content/BUILD.gn index 12cd504b7f6b..3a866b3827a7 100644 --- a/components/decentralized_dns/BUILD.gn +++ b/components/decentralized_dns/content/BUILD.gn @@ -3,22 +3,19 @@ # 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/. */ -static_library("decentralized_dns") { +static_library("content") { sources = [ - "constants.h", "decentralized_dns_interstitial_controller_client.cc", "decentralized_dns_interstitial_controller_client.h", "decentralized_dns_navigation_throttle.cc", "decentralized_dns_navigation_throttle.h", "decentralized_dns_opt_in_page.cc", "decentralized_dns_opt_in_page.h", - "pref_names.h", - "utils.cc", - "utils.h", ] deps = [ "//base", + "//brave/components/decentralized_dns/core", "//brave/components/l10n/common", "//brave/components/resources:static_resources", "//brave/components/resources:strings", @@ -28,7 +25,6 @@ static_library("decentralized_dns") { "//components/user_prefs", "//content/public/browser", "//net", - "//ui/base", "//url", ] } diff --git a/components/decentralized_dns/content/DEPS b/components/decentralized_dns/content/DEPS new file mode 100644 index 000000000000..1c35d9ca694b --- /dev/null +++ b/components/decentralized_dns/content/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+content/public/browser", +] diff --git a/components/decentralized_dns/decentralized_dns_interstitial_controller_client.cc b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc similarity index 88% rename from components/decentralized_dns/decentralized_dns_interstitial_controller_client.cc rename to components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc index 9184bc22a9e4..183c011e4dfa 100644 --- a/components/decentralized_dns/decentralized_dns_interstitial_controller_client.cc +++ b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc @@ -3,11 +3,11 @@ * 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/. */ -#include "brave/components/decentralized_dns/decentralized_dns_interstitial_controller_client.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/pref_names.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/content/settings_page_helper.h" #include "components/security_interstitials/core/metrics_helper.h" diff --git a/components/decentralized_dns/decentralized_dns_interstitial_controller_client.h b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h similarity index 85% rename from components/decentralized_dns/decentralized_dns_interstitial_controller_client.h rename to components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h index ad8ad64ac820..d7ac5697dc58 100644 --- a/components/decentralized_dns/decentralized_dns_interstitial_controller_client.h +++ b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ #include #include @@ -58,4 +58,4 @@ class DecentralizedDnsInterstitialControllerClient } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_INTERSTITIAL_CONTROLLER_CLIENT_H_ diff --git a/components/decentralized_dns/decentralized_dns_navigation_throttle.cc b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc similarity index 91% rename from components/decentralized_dns/decentralized_dns_navigation_throttle.cc rename to components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc index b34efd3f797b..58aa687107ac 100644 --- a/components/decentralized_dns/decentralized_dns_navigation_throttle.cc +++ b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc @@ -3,15 +3,15 @@ * 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/. */ -#include "brave/components/decentralized_dns/decentralized_dns_navigation_throttle.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_navigation_throttle.h" #include #include "base/bind.h" #include "base/threading/sequenced_task_runner_handle.h" -#include "brave/components/decentralized_dns/decentralized_dns_interstitial_controller_client.h" -#include "brave/components/decentralized_dns/decentralized_dns_opt_in_page.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_opt_in_page.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/user_prefs/user_prefs.h" diff --git a/components/decentralized_dns/decentralized_dns_navigation_throttle.h b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.h similarity index 85% rename from components/decentralized_dns/decentralized_dns_navigation_throttle.h rename to components/decentralized_dns/content/decentralized_dns_navigation_throttle.h index 1cc3adaec3a6..99630bda3e46 100644 --- a/components/decentralized_dns/decentralized_dns_navigation_throttle.h +++ b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ #include #include @@ -54,4 +54,4 @@ class DecentralizedDnsNavigationThrottle : public content::NavigationThrottle { } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_NAVIGATION_THROTTLE_H_ diff --git a/components/decentralized_dns/decentralized_dns_opt_in_page.cc b/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc similarity index 94% rename from components/decentralized_dns/decentralized_dns_opt_in_page.cc rename to components/decentralized_dns/content/decentralized_dns_opt_in_page.cc index 84f105356e9a..e5e9402bd42d 100644 --- a/components/decentralized_dns/decentralized_dns_opt_in_page.cc +++ b/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc @@ -3,7 +3,7 @@ * 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/. */ -#include "brave/components/decentralized_dns/decentralized_dns_opt_in_page.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_opt_in_page.h" #include #include @@ -14,8 +14,8 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "brave/components/decentralized_dns/decentralized_dns_interstitial_controller_client.h" -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h" +#include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/l10n/common/locale_util.h" #include "components/grit/brave_components_resources.h" #include "components/grit/brave_components_strings.h" diff --git a/components/decentralized_dns/decentralized_dns_opt_in_page.h b/components/decentralized_dns/content/decentralized_dns_opt_in_page.h similarity index 87% rename from components/decentralized_dns/decentralized_dns_opt_in_page.h rename to components/decentralized_dns/content/decentralized_dns_opt_in_page.h index 6ddc8af7d3b9..084ef8a6c491 100644 --- a/components/decentralized_dns/decentralized_dns_opt_in_page.h +++ b/components/decentralized_dns/content/decentralized_dns_opt_in_page.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ #include #include @@ -61,4 +61,4 @@ class DecentralizedDnsOptInPage } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONTENT_DECENTRALIZED_DNS_OPT_IN_PAGE_H_ diff --git a/components/decentralized_dns/resources/decentralized_dns_interstitial.css b/components/decentralized_dns/content/resources/decentralized_dns_interstitial.css similarity index 53% rename from components/decentralized_dns/resources/decentralized_dns_interstitial.css rename to components/decentralized_dns/content/resources/decentralized_dns_interstitial.css index 10c37325cefd..10c25f88d880 100644 --- a/components/decentralized_dns/resources/decentralized_dns_interstitial.css +++ b/components/decentralized_dns/content/resources/decentralized_dns_interstitial.css @@ -9,6 +9,6 @@ .decentralized_dns .icon { background-image: -webkit-image-set( - url(../../../../components/security_interstitials/core/browser/resources/images/1x/info.png) 1x, - url(../../../../components/security_interstitials/core/browser/resources/images/2x/info.png) 2x); + url(../../../../../components/security_interstitials/core/browser/resources/images/1x/info.png) 1x, + url(../../../../../components/security_interstitials/core/browser/resources/images/2x/info.png) 2x); } diff --git a/components/decentralized_dns/resources/decentralized_dns_interstitial.html b/components/decentralized_dns/content/resources/decentralized_dns_interstitial.html similarity index 62% rename from components/decentralized_dns/resources/decentralized_dns_interstitial.html rename to components/decentralized_dns/content/resources/decentralized_dns_interstitial.html index e2384e950a56..54c4c3123c0e 100644 --- a/components/decentralized_dns/resources/decentralized_dns_interstitial.html +++ b/components/decentralized_dns/content/resources/decentralized_dns_interstitial.html @@ -3,12 +3,12 @@ $i18n{tabTitle} - - + + - - - + + + diff --git a/components/decentralized_dns/resources/decentralized_dns_interstitial.js b/components/decentralized_dns/content/resources/decentralized_dns_interstitial.js similarity index 100% rename from components/decentralized_dns/resources/decentralized_dns_interstitial.js rename to components/decentralized_dns/content/resources/decentralized_dns_interstitial.js diff --git a/components/decentralized_dns/core/BUILD.gn b/components/decentralized_dns/core/BUILD.gn new file mode 100644 index 000000000000..450cb4ed6e5e --- /dev/null +++ b/components/decentralized_dns/core/BUILD.gn @@ -0,0 +1,20 @@ +# 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/. */ + +static_library("core") { + sources = [ + "constants.h", + "pref_names.h", + "utils.cc", + "utils.h", + ] + + deps = [ + "//base", + "//components/prefs", + "//net", + "//url", + ] +} diff --git a/components/decentralized_dns/constants.h b/components/decentralized_dns/core/constants.h similarity index 67% rename from components/decentralized_dns/constants.h rename to components/decentralized_dns/core/constants.h index 7e23ebb4c685..569fe5280aad 100644 --- a/components/decentralized_dns/constants.h +++ b/components/decentralized_dns/core/constants.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONSTANTS_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONSTANTS_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_CONSTANTS_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_CONSTANTS_H_ namespace decentralized_dns { @@ -17,6 +17,8 @@ enum class ResolveMethodTypes { MAX_VALUE = ETHEREUM, }; +enum class EnsOffchainResolveMethod { kAsk, kDisabled, kEnabled }; + } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CONSTANTS_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_CONSTANTS_H_ diff --git a/components/decentralized_dns/pref_names.h b/components/decentralized_dns/core/pref_names.h similarity index 79% rename from components/decentralized_dns/pref_names.h rename to components/decentralized_dns/core/pref_names.h index 259966653c25..3aa712672245 100644 --- a/components/decentralized_dns/pref_names.h +++ b/components/decentralized_dns/core/pref_names.h @@ -3,8 +3,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_PREF_NAMES_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_PREF_NAMES_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_PREF_NAMES_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_PREF_NAMES_H_ namespace decentralized_dns { @@ -23,6 +23,9 @@ constexpr char kUnstoppableDomainsResolveMethod[] = // Ethereum: Resolve domain name using Ethereum JSON-RPC server. constexpr char kENSResolveMethod[] = "brave.ens.resolve_method"; +constexpr char kEnsOffchainResolveMethod[] = + "brave.ens.offchain_resolve_method"; + } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_PREF_NAMES_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_PREF_NAMES_H_ diff --git a/components/decentralized_dns/utils.cc b/components/decentralized_dns/core/utils.cc similarity index 67% rename from components/decentralized_dns/utils.cc rename to components/decentralized_dns/core/utils.cc index 4870e9160c77..7eb0c3466fa1 100644 --- a/components/decentralized_dns/utils.cc +++ b/components/decentralized_dns/core/utils.cc @@ -3,39 +3,26 @@ * 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/. */ -#include "brave/components/decentralized_dns/utils.h" +#include "brave/components/decentralized_dns/core/utils.h" -#include "base/feature_list.h" #include "base/strings/string_util.h" -#include "base/values.h" -#include "brave/components/decentralized_dns/constants.h" -#include "brave/components/decentralized_dns/pref_names.h" -#include "brave/components/l10n/common/locale_util.h" +#include "brave/components/decentralized_dns/core/constants.h" +#include "brave/components/decentralized_dns/core/pref_names.h" #include "brave/net/decentralized_dns/constants.h" -#include "components/grit/brave_components_strings.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "url/gurl.h" namespace decentralized_dns { -namespace { - -base::Value::Dict MakeSelectValue(ResolveMethodTypes value, - const std::u16string& name) { - base::Value::Dict item; - item.Set("value", base::Value(static_cast(value))); - item.Set("name", base::Value(name)); - return item; -} - -} // namespace - void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { registry->RegisterIntegerPref(kUnstoppableDomainsResolveMethod, static_cast(ResolveMethodTypes::ASK)); registry->RegisterIntegerPref(kENSResolveMethod, static_cast(ResolveMethodTypes::ASK)); + registry->RegisterIntegerPref( + kEnsOffchainResolveMethod, + static_cast(EnsOffchainResolveMethod::kAsk)); } void MigrateObsoleteLocalStatePrefs(PrefService* local_state) { @@ -99,21 +86,14 @@ bool IsENSResolveMethodEthereum(PrefService* local_state) { static_cast(ResolveMethodTypes::ETHEREUM); } -base::Value::List GetResolveMethodList() { - base::Value::List list; - list.Append(MakeSelectValue(ResolveMethodTypes::ASK, - brave_l10n::GetLocalizedResourceUTF16String( - IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ASK))); - list.Append( - MakeSelectValue(ResolveMethodTypes::DISABLED, - brave_l10n::GetLocalizedResourceUTF16String( - IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_DISABLED))); - list.Append( - MakeSelectValue(ResolveMethodTypes::ETHEREUM, - brave_l10n::GetLocalizedResourceUTF16String( - IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ETHEREUM))); - - return list; +void SetEnsOffchainResolveMethod(PrefService* local_state, + EnsOffchainResolveMethod method) { + local_state->SetInteger(kEnsOffchainResolveMethod, static_cast(method)); +} + +EnsOffchainResolveMethod GetEnsOffchainResolveMethod(PrefService* local_state) { + return static_cast( + local_state->GetInteger(kEnsOffchainResolveMethod)); } } // namespace decentralized_dns diff --git a/components/decentralized_dns/utils.h b/components/decentralized_dns/core/utils.h similarity index 65% rename from components/decentralized_dns/utils.h rename to components/decentralized_dns/core/utils.h index 4c4ced8b33a9..758f257ae6bb 100644 --- a/components/decentralized_dns/utils.h +++ b/components/decentralized_dns/core/utils.h @@ -3,10 +3,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_UTILS_H_ -#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_UTILS_H_ +#ifndef BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_UTILS_H_ +#define BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_UTILS_H_ -#include "base/values.h" +#include "brave/components/decentralized_dns/core/constants.h" class GURL; class PrefService; @@ -24,8 +24,11 @@ bool IsUnstoppableDomainsResolveMethodEthereum(PrefService* local_state); bool IsENSTLD(const GURL& url); bool IsENSResolveMethodAsk(PrefService* local_state); bool IsENSResolveMethodEthereum(PrefService* local_state); -base::Value::List GetResolveMethodList(); + +void SetEnsOffchainResolveMethod(PrefService* local_state, + EnsOffchainResolveMethod method); +EnsOffchainResolveMethod GetEnsOffchainResolveMethod(PrefService* local_state); } // namespace decentralized_dns -#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_UTILS_H_ +#endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_UTILS_H_ diff --git a/components/resources/decentralized_dns_resources.grdp b/components/resources/decentralized_dns_resources.grdp index 370e62d17d10..3a247bf12e40 100644 --- a/components/resources/decentralized_dns_resources.grdp +++ b/components/resources/decentralized_dns_resources.grdp @@ -1,6 +1,6 @@ - - - + + + diff --git a/components/resources/decentralized_dns_strings.grdp b/components/resources/decentralized_dns_strings.grdp index 038fc1c9c736..147df1aebada 100644 --- a/components/resources/decentralized_dns_strings.grdp +++ b/components/resources/decentralized_dns_strings.grdp @@ -33,4 +33,13 @@ Ethereum + + Ask + + + Disabled + + + Enabled + diff --git a/components/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp index c56735fd63cf..accf8565a800 100644 --- a/components/resources/wallet_strings.grdp +++ b/components/resources/wallet_strings.grdp @@ -637,4 +637,8 @@ Recovery phrase must be 12, 15, 18, 21, or 24 words long No NFTs found in your wallet. You can add NFTs by clicking the "+ Visible assets" button at the bottom of the "Portfolio" tab No NFTs matching search or filter found + Yes + No + Don't show this again + Address resolution requires offchain network requests. Proceed?