From 18cb28cd6f4f463bc76fdce0eae56b1e412fcefd Mon Sep 17 00:00:00 2001 From: Anton Paymyshev Date: Thu, 3 Nov 2022 17:04:49 +0700 Subject: [PATCH 1/2] SNS domain resolving --- ...ButtonGroupENSResolveMethodPreference.java | 4 +- ...oppableDomainsResolveMethodPreference.java | 4 +- ...on_group_ens_resolve_method_preference.xml | 4 +- ...able_domains_resolve_method_preference.xml | 4 +- app/brave_settings_strings.grdp | 9 +- ...zed_dns_navigation_throttle_browsertest.cc | 52 +++++- .../decentralized_dns/test/utils_unittest.cc | 8 +- .../api/settings_private/brave_prefs_util.cc | 2 + .../content_browser_client_helper_unittest.cc | 8 +- ...centralized_dns_network_delegate_helper.cc | 29 +++ ...ecentralized_dns_network_delegate_helper.h | 7 + ...ed_dns_network_delegate_helper_unittest.cc | 38 +++- .../brave_default_extensions_browser_proxy.ts | 5 + .../brave_default_extensions_page.html | 12 +- .../brave_default_extensions_page.ts | 20 +-- .../android/strings/android_brave_strings.grd | 4 +- .../brave_default_extensions_handler.cc | 4 +- ...ave_settings_localized_strings_provider.cc | 5 + .../net/base/lookup_string_in_fixed_set.cc | 4 + .../brave_wallet/browser/json_rpc_service.cc | 71 +++++++- .../brave_wallet/browser/json_rpc_service.h | 12 ++ .../browser/json_rpc_service_unittest.cc | 82 +++++++++ .../brave_wallet/browser/sns_resolver_task.cc | 166 ++++++++++++++++-- .../brave_wallet/browser/sns_resolver_task.h | 17 +- components/decentralized_dns/content/BUILD.gn | 1 + ...ized_dns_interstitial_controller_client.cc | 18 +- .../decentralized_dns_navigation_throttle.cc | 7 +- .../content/decentralized_dns_opt_in_page.cc | 48 +++-- .../ens_offchain_lookup_opt_in_page.cc | 11 +- components/decentralized_dns/core/constants.h | 4 +- .../decentralized_dns/core/pref_names.h | 11 +- components/decentralized_dns/core/utils.cc | 28 ++- components/decentralized_dns/core/utils.h | 4 + .../resources/decentralized_dns_strings.grdp | 25 ++- net/decentralized_dns/constants.h | 2 + 35 files changed, 631 insertions(+), 99 deletions(-) diff --git a/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupENSResolveMethodPreference.java b/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupENSResolveMethodPreference.java index cb428f3d0409..187c4b3c0084 100644 --- a/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupENSResolveMethodPreference.java +++ b/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupENSResolveMethodPreference.java @@ -54,9 +54,9 @@ public void onBindViewHolder(PreferenceViewHolder holder) { mButtons.set(ResolveMethodTypes.DISABLED, (RadioButtonWithDescription) holder.findViewById( R.id.ens_resolve_method_disabled_radio_button)); - mButtons.set(ResolveMethodTypes.ETHEREUM, + mButtons.set(ResolveMethodTypes.ENABLED, (RadioButtonWithDescription) holder.findViewById( - R.id.ens_resolve_method_ethereum_radio_button)); + R.id.ens_resolve_method_enabled_radio_button)); mSettingRadioButton = mButtons.get(mSetting); mSettingRadioButton.setChecked(true); diff --git a/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupUnstoppableDomainsResolveMethodPreference.java b/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupUnstoppableDomainsResolveMethodPreference.java index ca99fbe5c13c..fb8ff9aeb28a 100644 --- a/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupUnstoppableDomainsResolveMethodPreference.java +++ b/android/java/org/chromium/chrome/browser/decentralized_dns/settings/RadioButtonGroupUnstoppableDomainsResolveMethodPreference.java @@ -56,9 +56,9 @@ public void onBindViewHolder(PreferenceViewHolder holder) { mButtons.set(ResolveMethodTypes.DISABLED, (RadioButtonWithDescription) holder.findViewById( R.id.unstoppable_domains_resolve_method_disabled_radio_button)); - mButtons.set(ResolveMethodTypes.ETHEREUM, + mButtons.set(ResolveMethodTypes.ENABLED, (RadioButtonWithDescription) holder.findViewById( - R.id.unstoppable_domains_resolve_method_ethereum_radio_button)); + R.id.unstoppable_domains_resolve_method_enabled_radio_button)); mSettingRadioButton = mButtons.get(mSetting); mSettingRadioButton.setChecked(true); diff --git a/android/java/res/layout/radio_button_group_ens_resolve_method_preference.xml b/android/java/res/layout/radio_button_group_ens_resolve_method_preference.xml index e353800da79a..3de4efe6190c 100644 --- a/android/java/res/layout/radio_button_group_ens_resolve_method_preference.xml +++ b/android/java/res/layout/radio_button_group_ens_resolve_method_preference.xml @@ -30,11 +30,11 @@ app:primaryText="@string/resolve_method_disabled" /> + app:primaryText="@string/resolve_method_enabled" /> diff --git a/android/java/res/layout/radio_button_group_unstoppable_domains_resolve_method_preference.xml b/android/java/res/layout/radio_button_group_unstoppable_domains_resolve_method_preference.xml index d9579491bf1e..e7d0df8cdd58 100644 --- a/android/java/res/layout/radio_button_group_unstoppable_domains_resolve_method_preference.xml +++ b/android/java/res/layout/radio_button_group_unstoppable_domains_resolve_method_preference.xml @@ -30,11 +30,11 @@ app:primaryText="@string/resolve_method_disabled" /> + app:primaryText="@string/resolve_method_enabled" /> diff --git a/app/brave_settings_strings.grdp b/app/brave_settings_strings.grdp index 87e65a7a292a..aa1105132762 100644 --- a/app/brave_settings_strings.grdp +++ b/app/brave_settings_strings.grdp @@ -706,17 +706,20 @@ Media router enables cast feature in the browser. - Method to resolve Unstoppable Domains + Resolve Unstoppable Domains domain names - <a target="_blank" href="$1">Learn More</a> about Ethereum privacy considerations. + <a target="_blank" href="$1">Learn More</a> about Unstoppable Domains privacy considerations. - Method to resolve Ethereum Name Service (ENS) + Resolve Ethereum Name Service (ENS) domain names Allow ENS offchain lookup. + + Resolve Solana Name Service (SNS) domain names + <a target="_blank" href="$1">Learn More</a> about ENS offchain lookup privacy considerations. 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 558829363624..4a7ac72c1966 100644 --- a/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc +++ b/browser/decentralized_dns/test/decentralized_dns_navigation_throttle_browsertest.cc @@ -84,6 +84,10 @@ class DecentralizedDnsNavigationThrottleBrowserTest ~DecentralizedDnsNavigationThrottleBrowserTest() override = default; PrefService* local_state() { return g_browser_process->local_state(); } + + private: + base::test::ScopedFeatureList scoped_feature{ + brave_wallet::features::kBraveWalletSnsFeature}; }; IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, @@ -103,7 +107,7 @@ IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, SendInterstitialCommandSync( browser(), security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); - EXPECT_EQ(static_cast(ResolveMethodTypes::ETHEREUM), + EXPECT_EQ(static_cast(ResolveMethodTypes::ENABLED), local_state()->GetInteger(kUnstoppableDomainsResolveMethod)); } @@ -144,7 +148,7 @@ IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, SendInterstitialCommandSync( browser(), security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); - EXPECT_EQ(static_cast(ResolveMethodTypes::ETHEREUM), + EXPECT_EQ(static_cast(ResolveMethodTypes::ENABLED), local_state()->GetInteger(kENSResolveMethod)); } @@ -194,7 +198,7 @@ class EnsL2OffchanLookupNavigationThrottleBrowserTest IN_PROC_BROWSER_TEST_F(EnsL2OffchanLookupNavigationThrottleBrowserTest, ShowENSOffchainLookupInterstitialAndProceed) { local_state()->SetInteger(kENSResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); SetEnsResolverResult(EnsResolverTaskResult({}, true), absl::nullopt); EnsResolverTask::GetWorkOnTaskForTesting() = @@ -227,7 +231,7 @@ IN_PROC_BROWSER_TEST_F(EnsL2OffchanLookupNavigationThrottleBrowserTest, IN_PROC_BROWSER_TEST_F(EnsL2OffchanLookupNavigationThrottleBrowserTest, ShowENSOffchainLookupInterstitialAndDontProceed) { local_state()->SetInteger(kENSResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); SetEnsResolverResult(EnsResolverTaskResult({}, true), absl::nullopt); EnsResolverTask::GetWorkOnTaskForTesting() = @@ -257,4 +261,44 @@ IN_PROC_BROWSER_TEST_F(EnsL2OffchanLookupNavigationThrottleBrowserTest, GetEnsOffchainResolveMethod(local_state())); } +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowSnsInterstitialAndProceed) { + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("http://test.sol"))); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetPrimaryMainFrame())); + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kSnsResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::ENABLED), + local_state()->GetInteger(kSnsResolveMethod)); +} + +IN_PROC_BROWSER_TEST_F(DecentralizedDnsNavigationThrottleBrowserTest, + ShowSnsInterstitialAndReject) { + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("http://test.sol"))); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + EXPECT_TRUE(WaitForRenderFrameReady(web_contents->GetPrimaryMainFrame())); + EXPECT_EQ(DecentralizedDnsOptInPage::kTypeForTesting, + GetInterstitialType(web_contents)); + + EXPECT_EQ(static_cast(ResolveMethodTypes::ASK), + local_state()->GetInteger(kSnsResolveMethod)); + SendInterstitialCommandSync( + browser(), + security_interstitials::SecurityInterstitialCommand::CMD_DONT_PROCEED); + EXPECT_EQ(static_cast(ResolveMethodTypes::DISABLED), + local_state()->GetInteger(kSnsResolveMethod)); +} + } // namespace decentralized_dns diff --git a/browser/decentralized_dns/test/utils_unittest.cc b/browser/decentralized_dns/test/utils_unittest.cc index d5faac550243..0a1a9a7c0080 100644 --- a/browser/decentralized_dns/test/utils_unittest.cc +++ b/browser/decentralized_dns/test/utils_unittest.cc @@ -38,7 +38,7 @@ TEST_F(UtilsUnitTest, IsUnstoppableDomainsResolveMethodAsk) { EXPECT_TRUE(IsUnstoppableDomainsResolveMethodAsk(local_state())); local_state()->SetInteger(kUnstoppableDomainsResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_FALSE(IsUnstoppableDomainsResolveMethodAsk(local_state())); } @@ -46,7 +46,7 @@ TEST_F(UtilsUnitTest, IsUnstoppableDomainsResolveMethodEthereum) { EXPECT_FALSE(IsUnstoppableDomainsResolveMethodEthereum(local_state())); local_state()->SetInteger(kUnstoppableDomainsResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_TRUE(IsUnstoppableDomainsResolveMethodEthereum(local_state())); } @@ -61,7 +61,7 @@ TEST_F(UtilsUnitTest, IsENSResolveMethodAsk) { EXPECT_TRUE(IsENSResolveMethodAsk(local_state())); local_state()->SetInteger(kENSResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_FALSE(IsENSResolveMethodAsk(local_state())); } @@ -69,7 +69,7 @@ TEST_F(UtilsUnitTest, IsENSResolveMethodEthereum) { EXPECT_FALSE(IsENSResolveMethodEthereum(local_state())); local_state()->SetInteger(kENSResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_TRUE(IsENSResolveMethodEthereum(local_state())); } diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index c4b0710f80e1..f249871ebc47 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -321,6 +321,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetAllowlistedKeys() { settings_api::PrefType::PREF_TYPE_NUMBER; (*s_brave_allowlist)[decentralized_dns::kEnsOffchainResolveMethod] = settings_api::PrefType::PREF_TYPE_NUMBER; + (*s_brave_allowlist)[decentralized_dns::kSnsResolveMethod] = + settings_api::PrefType::PREF_TYPE_NUMBER; // Media router pref (*s_brave_allowlist)[kEnableMediaRouterOnRestart] = diff --git a/browser/ipfs/content_browser_client_helper_unittest.cc b/browser/ipfs/content_browser_client_helper_unittest.cc index 4417f543ef3d..6ee47dff7451 100644 --- a/browser/ipfs/content_browser_client_helper_unittest.cc +++ b/browser/ipfs/content_browser_client_helper_unittest.cc @@ -197,7 +197,7 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLRewriteENS) { ASSERT_FALSE(HandleIPFSURLRewrite(&ens_uri, browser_context())); local_state()->SetInteger( decentralized_dns::kENSResolveMethod, - static_cast(decentralized_dns::ResolveMethodTypes::ETHEREUM)); + static_cast(decentralized_dns::ResolveMethodTypes::ENABLED)); EXPECT_TRUE(decentralized_dns::IsENSResolveMethodEthereum(local_state())); ASSERT_TRUE(HandleIPFSURLRewrite(&ens_uri, browser_context())); } @@ -317,7 +317,7 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLRewriteCrypto) { profile()->GetPrefs()->SetInteger( kIPFSResolveMethod, static_cast(IPFSResolveMethodTypes::IPFS_LOCAL)); ASSERT_TRUE( - ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ETHEREUM)); + ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ENABLED)); ASSERT_FALSE( ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::DISABLED)); @@ -325,7 +325,7 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLRewriteCrypto) { kIPFSResolveMethod, static_cast(IPFSResolveMethodTypes::IPFS_GATEWAY)); ASSERT_FALSE( - ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ETHEREUM)); + ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ENABLED)); ASSERT_FALSE( ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::DISABLED)); @@ -333,7 +333,7 @@ TEST_F(ContentBrowserClientHelperUnitTest, HandleIPFSURLRewriteCrypto) { kIPFSResolveMethod, static_cast(IPFSResolveMethodTypes::IPFS_DISABLED)); ASSERT_FALSE( - ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ETHEREUM)); + ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::ENABLED)); ASSERT_FALSE( ResolveUnstoppableURL(decentralized_dns::ResolveMethodTypes::DISABLED)); } diff --git a/browser/net/decentralized_dns_network_delegate_helper.cc b/browser/net/decentralized_dns_network_delegate_helper.cc index 38c325776a38..db55495d2861 100644 --- a/browser/net/decentralized_dns_network_delegate_helper.cc +++ b/browser/net/decentralized_dns_network_delegate_helper.cc @@ -8,9 +8,11 @@ #include #include +#include "base/feature_list.h" #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/brave_wallet/common/features.h" #include "brave/components/decentralized_dns/core/constants.h" #include "brave/components/decentralized_dns/core/utils.h" #include "brave/components/ipfs/ipfs_utils.h" @@ -57,6 +59,18 @@ int OnBeforeURLRequest_DecentralizedDnsPreRedirectWork( return net::ERR_IO_PENDING; } + if (base::FeatureList::IsEnabled( + brave_wallet::features::kBraveWalletSnsFeature) && + IsSnsTLD(ctx->request_url) && + IsSnsResolveMethodEnabled(g_browser_process->local_state())) { + json_rpc_service->SnsResolveHost( + ctx->request_url.host(), + base::BindOnce(&OnBeforeURLRequest_SnsRedirectWork, next_callback, + ctx)); + + return net::ERR_IO_PENDING; + } + return net::OK; } @@ -88,6 +102,21 @@ void OnBeforeURLRequest_EnsRedirectWork( next_callback.Run(); } +void OnBeforeURLRequest_SnsRedirectWork( + const brave::ResponseCallback& next_callback, + std::shared_ptr ctx, + const GURL& url, + brave_wallet::mojom::SolanaProviderError error, + const std::string& error_message) { + if (error == brave_wallet::mojom::SolanaProviderError::kSuccess && + url.is_valid()) { + ctx->new_url_spec = url.spec(); + } + + if (!next_callback.is_null()) + next_callback.Run(); +} + void OnBeforeURLRequest_UnstoppableDomainsRedirectWork( const brave::ResponseCallback& next_callback, std::shared_ptr ctx, diff --git a/browser/net/decentralized_dns_network_delegate_helper.h b/browser/net/decentralized_dns_network_delegate_helper.h index 8ebf2e51dd39..a9d12f8bce79 100644 --- a/browser/net/decentralized_dns_network_delegate_helper.h +++ b/browser/net/decentralized_dns_network_delegate_helper.h @@ -37,6 +37,13 @@ void OnBeforeURLRequest_EnsRedirectWork( brave_wallet::mojom::ProviderError error, const std::string& error_message); +void OnBeforeURLRequest_SnsRedirectWork( + const brave::ResponseCallback& next_callback, + std::shared_ptr ctx, + const GURL& url, + brave_wallet::mojom::SolanaProviderError error, + const std::string& error_message); + } // namespace decentralized_dns #endif // BRAVE_BROWSER_NET_DECENTRALIZED_DNS_NETWORK_DELEGATE_HELPER_H_ diff --git a/browser/net/decentralized_dns_network_delegate_helper_unittest.cc b/browser/net/decentralized_dns_network_delegate_helper_unittest.cc index 3c4b50515d77..cb6146e1320c 100644 --- a/browser/net/decentralized_dns_network_delegate_helper_unittest.cc +++ b/browser/net/decentralized_dns_network_delegate_helper_unittest.cc @@ -94,7 +94,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, EXPECT_TRUE(brave_request_info->new_url_spec.empty()); local_state()->SetInteger(kUnstoppableDomainsResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_TRUE(IsUnstoppableDomainsResolveMethodEthereum(local_state())); // No redirect for OTR context. @@ -127,7 +127,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, EXPECT_TRUE(brave_request_info->new_url_spec.empty()); local_state()->SetInteger(kENSResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); EXPECT_TRUE(IsENSResolveMethodEthereum(local_state())); brave_request_info->request_url = GURL("http://brave.eth"); rc = OnBeforeURLRequest_DecentralizedDnsPreRedirectWork(base::DoNothing(), @@ -139,7 +139,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, TEST_F(DecentralizedDnsNetworkDelegateHelperTest, DecentralizedDnsPreRedirectTLDs) { local_state()->SetInteger(kUnstoppableDomainsResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); struct TestCase { const char* url; bool is_valid; @@ -172,7 +172,7 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, TEST_F(DecentralizedDnsNetworkDelegateHelperTest, UnstoppableDomainsRedirectWork) { local_state()->SetInteger(kUnstoppableDomainsResolveMethod, - static_cast(ResolveMethodTypes::ETHEREUM)); + static_cast(ResolveMethodTypes::ENABLED)); GURL url("http://brave.crypto"); auto brave_request_info = std::make_shared(url); @@ -298,4 +298,34 @@ TEST_F(DecentralizedDnsNetworkDelegateHelperTest, net::ERR_ENS_OFFCHAIN_LOOKUP_NOT_SELECTED); } +TEST_F(DecentralizedDnsNetworkDelegateHelperTest, SnsRedirectWork) { + GURL url("http://test.sol"); + auto brave_request_info = std::make_shared(url); + + // No redirect for failed requests. + OnBeforeURLRequest_SnsRedirectWork( + base::DoNothing(), brave_request_info, {}, + brave_wallet::mojom::SolanaProviderError::kInternalError, "todo"); + EXPECT_TRUE(brave_request_info->new_url_spec.empty()); + + OnBeforeURLRequest_SnsRedirectWork( + base::DoNothing(), brave_request_info, {}, + brave_wallet::mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(brave_request_info->new_url_spec.empty()); + + // No redirect for invalid url. + OnBeforeURLRequest_SnsRedirectWork( + base::DoNothing(), brave_request_info, GURL("invalid"), + brave_wallet::mojom::SolanaProviderError::kSuccess, ""); + EXPECT_TRUE(brave_request_info->new_url_spec.empty()); + + // Redirect for valid url. + OnBeforeURLRequest_SnsRedirectWork( + base::DoNothing(), brave_request_info, GURL("https://brave.com"), + brave_wallet::mojom::SolanaProviderError::kSuccess, ""); + EXPECT_EQ(brave_request_info->new_url_spec, GURL("https://brave.com")); + + EXPECT_FALSE(brave_request_info->pending_error.has_value()); +} + } // namespace decentralized_dns diff --git a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.ts b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.ts index 18b79894c431..e510d087e8d4 100644 --- a/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.ts +++ b/browser/resources/settings/brave_default_extensions_page/brave_default_extensions_browser_proxy.ts @@ -18,6 +18,7 @@ export interface BraveDefaultExtensionsBrowserProxy { getDecentralizedDnsResolveMethodList(): Promise // TODO(petemill): Define type getEnsOffchainResolveMethodList(): Promise // TODO(petemill): Define type isENSL2Enabled(): boolean + isSnsEnabled(): boolean } export class BraveDefaultExtensionsBrowserProxyImpl implements BraveDefaultExtensionsBrowserProxy { @@ -65,6 +66,10 @@ export class BraveDefaultExtensionsBrowserProxyImpl implements BraveDefaultExten return loadTimeData.getBoolean('isENSL2Enabled') } + isSnsEnabled() { + return loadTimeData.getBoolean('isSnsEnabled') + } + static getInstance(): BraveDefaultExtensionsBrowserProxy { return instance || (instance = new 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 fdd35a41c373..2ab37329190f 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 @@ -91,14 +91,14 @@ + menu-options="[[resolveMethod_]]">
$i18n{resolveENSDesc}
+ menu-options="[[resolveMethod_]]">
+ { this.showRestartToast_ = needsRestart }) @@ -76,10 +79,7 @@ export class SettingBraveDefaultExtensionsPageElement extends SettingBraveDefaul this.showRestartToast_ = show }) this.browserProxy_.getDecentralizedDnsResolveMethodList().then(list => { - this.unstoppableDomainsResolveMethod_ = list - }) - this.browserProxy_.getDecentralizedDnsResolveMethodList().then(list => { - this.ensResolveMethod_ = list + this.resolveMethod_ = list }) this.browserProxy_.getEnsOffchainResolveMethodList().then(list => { this.ensOffchainResolveMethod_ = list diff --git a/browser/ui/android/strings/android_brave_strings.grd b/browser/ui/android/strings/android_brave_strings.grd index 1c5ae7dd5886..bff8d2fe127c 100644 --- a/browser/ui/android/strings/android_brave_strings.grd +++ b/browser/ui/android/strings/android_brave_strings.grd @@ -383,8 +383,8 @@ This file contains all "about" strings. It is set to NOT be translated, in tran Disabled - - Ethereum + + Enabled Today’s top stories in a completely private feed, just for you. diff --git a/browser/ui/webui/settings/brave_default_extensions_handler.cc b/browser/ui/webui/settings/brave_default_extensions_handler.cc index 21c31b17256f..138261ed8138 100644 --- a/browser/ui/webui/settings/brave_default_extensions_handler.cc +++ b/browser/ui/webui/settings/brave_default_extensions_handler.cc @@ -86,9 +86,9 @@ base::Value::List GetResolveMethodList() { brave_l10n::GetLocalizedResourceUTF16String( IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_DISABLED))); list.Append( - MakeSelectValue(ResolveMethodTypes::ETHEREUM, + MakeSelectValue(ResolveMethodTypes::ENABLED, brave_l10n::GetLocalizedResourceUTF16String( - IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ETHEREUM))); + IDS_DECENTRALIZED_DNS_RESOLVE_OPTION_ENABLED))); return list; } 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 ce017aa6c6ac..38fd18522106 100644 --- a/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc +++ b/browser/ui/webui/settings/brave_settings_localized_strings_provider.cc @@ -363,6 +363,7 @@ void BraveAddCommonStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_RESOLVE_UNSTOPPABLE_DOMAINS_DESC}, {"resolveENSDesc", IDS_SETTINGS_RESOLVE_ENS_DESC}, {"ensOffchainLookupTitle", IDS_SETTINGS_ENABLE_ENS_OFFCHAIN_LOOKUP_TITLE}, + {"resolveSnsDesc", IDS_SETTINGS_RESOLVE_SNS_DESC}, {"resolveIPFSURLDesc", IDS_SETTINGS_RESOLVE_IPFS_URLS_DESC}, {"ipfsPublicGatewayDesc", IDS_SETTINGS_IPFS_PUBLIC_GATEWAY_DESC}, {"ipfsNftPublicGatewayDesc", IDS_SETTINGS_IPFS_PUBLIC_NFT_GATEWAY_DESC}, @@ -679,6 +680,10 @@ void BraveAddLocalizedStrings(content::WebUIDataSource* html_source, "isENSL2Enabled", base::FeatureList::IsEnabled( brave_wallet::features::kBraveWalletENSL2Feature)); + html_source->AddBoolean("isSnsEnabled", + base::FeatureList::IsEnabled( + brave_wallet::features::kBraveWalletSnsFeature)); + if (base::FeatureList::IsEnabled( net::features::kBraveFirstPartyEphemeralStorage)) { const webui::LocalizedString kSessionOnlyToEphemeralStrings[] = { diff --git a/chromium_src/net/base/lookup_string_in_fixed_set.cc b/chromium_src/net/base/lookup_string_in_fixed_set.cc index bc98e965213f..87c3c175c95c 100644 --- a/chromium_src/net/base/lookup_string_in_fixed_set.cc +++ b/chromium_src/net/base/lookup_string_in_fixed_set.cc @@ -56,6 +56,10 @@ int LookupSuffixInReversedSet(const unsigned char* graph, *suffix_length = strlen(decentralized_dns::kEthDomain) - 1; return kDafsaFound; } + if (base::EndsWith(host, decentralized_dns::kSolDomain)) { + *suffix_length = strlen(decentralized_dns::kSolDomain) - 1; + return kDafsaFound; + } if (include_private && base::EndsWith(host, decentralized_dns::kDNSForEthDomain)) { diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index 6410b17387fc..bb01a5c023d8 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -1397,7 +1397,7 @@ void JsonRpcService::SnsGetSolAddr(const std::string& domain, sns_get_sol_addr_tasks_.AddTask( std::make_unique(std::move(done_callback), api_request_helper_.get(), domain, - network_url), + network_url, true), std::move(callback)); } @@ -1429,6 +1429,75 @@ void JsonRpcService::OnSnsGetSolAddrTaskDone( } } +void JsonRpcService::SnsResolveHost(const std::string& domain, + SnsResolveHostCallback callback) { + if (!base::FeatureList::IsEnabled(features::kBraveWalletSnsFeature)) { + std::move(callback).Run( + GURL(), mojom::SolanaProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + return; + } + + if (!IsValidDomain(domain)) { + std::move(callback).Run( + GURL(), mojom::SolanaProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + return; + } + + if (sns_resolve_host_tasks_.ContainsTaskForDomain(domain)) { + sns_resolve_host_tasks_.AddCallbackForDomain(domain, std::move(callback)); + return; + } + + GURL network_url = GetNetworkURL(prefs_, brave_wallet::mojom::kSolanaMainnet, + mojom::CoinType::SOL); + if (!network_url.is_valid()) { + std::move(callback).Run( + GURL(), mojom::SolanaProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + return; + } + + // JsonRpcService owns EnsResolverTask instance, so Unretained is safe here. + auto done_callback = base::BindOnce(&JsonRpcService::OnSnsResolveHostTaskDone, + base::Unretained(this)); + + sns_resolve_host_tasks_.AddTask( + std::make_unique(std::move(done_callback), + api_request_helper_.get(), domain, + network_url, false), + std::move(callback)); +} + +void JsonRpcService::OnSnsResolveHostTaskDone( + SnsResolverTask* task, + absl::optional task_result, + absl::optional task_error) { + auto callbacks = sns_resolve_host_tasks_.TaskDone(task); + if (callbacks.empty()) { + return; + } + + GURL url; + mojom::SolanaProviderError error = + task_error ? task_error->error : mojom::SolanaProviderError::kSuccess; + std::string error_message = task_error ? task_error->error_message : ""; + + if (task_result) { + if (task_result->resolved_url.is_valid()) { + url = task_result->resolved_url; + } else { + error = mojom::SolanaProviderError::kInvalidParams; + error_message = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS); + } + } + + for (auto& cb : callbacks) { + std::move(cb).Run(url, error, error_message); + } +} + void JsonRpcService::OnEnsGetContentHashTaskDone( EnsResolverTask* task, absl::optional task_result, diff --git a/components/brave_wallet/browser/json_rpc_service.h b/components/brave_wallet/browser/json_rpc_service.h index 5204a3f1d0f2..ecfae3a96144 100644 --- a/components/brave_wallet/browser/json_rpc_service.h +++ b/components/brave_wallet/browser/json_rpc_service.h @@ -180,6 +180,13 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { void SnsGetSolAddr(const std::string& domain, SnsGetSolAddrCallback callback) override; + using SnsResolveHostCallback = + base::OnceCallback; + void SnsResolveHost(const std::string& domain, + SnsResolveHostCallback callback); + bool SetNetwork(const std::string& chain_id, mojom::CoinType coin, bool silent = false); @@ -481,6 +488,10 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { SnsResolverTask* task, absl::optional task_result, absl::optional error); + void OnSnsResolveHostTaskDone( + SnsResolverTask* task, + absl::optional task_result, + absl::optional error); void OnEnsGetEthAddr(EnsGetEthAddrCallback callback, APIRequestResult api_request_result); void OnGetFilEstimateGas(GetFilEstimateGasCallback callback, @@ -592,6 +603,7 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService { ens_get_content_hash_tasks_; SnsResolverTaskContainer sns_get_sol_addr_tasks_; + SnsResolverTaskContainer sns_resolve_host_tasks_; mojo::ReceiverSet receivers_; PrefService* prefs_ = nullptr; diff --git a/components/brave_wallet/browser/json_rpc_service_unittest.cc b/components/brave_wallet/browser/json_rpc_service_unittest.cc index 810c5a82e991..73df7f295619 100644 --- a/components/brave_wallet/browser/json_rpc_service_unittest.cc +++ b/components/brave_wallet/browser/json_rpc_service_unittest.cc @@ -471,6 +471,11 @@ class GetAccountInfoHandler : public SolRpcCallHandler { return result; } + static std::vector MakeTextRecordPayloadData( + const std::string& text) { + return std::vector(text.begin(), text.end()); + } + absl::optional HandleCall( const base::Value::Dict& dict) override { if (fail_with_timeout_) @@ -5705,6 +5710,20 @@ class SnsJsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { SolRecordAddress(), GetRecordKeyAddress("SOL"), domain_owner_private_key_))); + url_record_address_handler_ = std::make_unique( + GetRecordKeyAddress("url"), SolanaAddress::ZeroAddress(), + GetAccountInfoHandler::MakeNameRegistryStateData( + DomainOwnerAddress(), + GetAccountInfoHandler::MakeTextRecordPayloadData( + url_value().spec()))); + + ipfs_record_address_handler_ = std::make_unique( + GetRecordKeyAddress("IPFS"), SolanaAddress::ZeroAddress(), + GetAccountInfoHandler::MakeNameRegistryStateData( + DomainOwnerAddress(), + GetAccountInfoHandler::MakeTextRecordPayloadData( + ipfs_value().spec()))); + default_handler_ = std::make_unique(); json_rpc_endpoint_handler_->AddSolRpcCallHandler( @@ -5717,6 +5736,11 @@ class SnsJsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { json_rpc_endpoint_handler_->AddSolRpcCallHandler( sol_record_address_handler_.get()); + json_rpc_endpoint_handler_->AddSolRpcCallHandler( + url_record_address_handler_.get()); + json_rpc_endpoint_handler_->AddSolRpcCallHandler( + ipfs_record_address_handler_.get()); + json_rpc_endpoint_handler_->AddSolRpcCallHandler(default_handler_.get()); url_loader_factory_.SetInterceptor(base::BindRepeating( @@ -5754,6 +5778,12 @@ class SnsJsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { "RecPwner11111111111111111111111111111111111"); } + GURL url_value() const { return GURL("https://brave.com"); } + GURL ipfs_value() const { + return GURL( + "ipfs://bafybeibd4ala53bs26dvygofvr6ahpa7gbw4eyaibvrbivf4l5rr44yqu4"); + } + std::string sns_host() const { return "sub.test.sol"; } protected: @@ -5777,6 +5807,8 @@ class SnsJsonRpcServiceUnitTest : public JsonRpcServiceUnitTest { std::unique_ptr get_program_accounts_handler_; std::unique_ptr domain_address_handler_; std::unique_ptr sol_record_address_handler_; + std::unique_ptr url_record_address_handler_; + std::unique_ptr ipfs_record_address_handler_; std::unique_ptr default_handler_; std::unique_ptr json_rpc_endpoint_handler_; @@ -5896,4 +5928,54 @@ TEST_F(SnsJsonRpcServiceUnitTest, GetWalletAddr_SolRecordOwner) { testing::Mock::VerifyAndClearExpectations(&callback); } +TEST_F(SnsJsonRpcServiceUnitTest, ResolveHost_UrlValue) { + base::MockCallback callback; + EXPECT_CALL(callback, + Run(url_value(), mojom::SolanaProviderError::kSuccess, "")); + json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&callback); + + // HTTP error for url record account. Fail resolution. + url_record_address_handler_->FailWithTimeout(); + EXPECT_CALL(callback, + Run(GURL(), mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&callback); + url_record_address_handler_->FailWithTimeout(false); +} + +TEST_F(SnsJsonRpcServiceUnitTest, ResolveHost_IpfsValue) { + url_record_address_handler_->Disable(); + + // No url record. Will return ipfs record. + base::MockCallback callback; + EXPECT_CALL(callback, + Run(ipfs_value(), mojom::SolanaProviderError::kSuccess, "")); + json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&callback); + + // HTTP error for ipfs record account. Fail resolution. + ipfs_record_address_handler_->FailWithTimeout(); + EXPECT_CALL(callback, + Run(GURL(), mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); + json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&callback); + ipfs_record_address_handler_->FailWithTimeout(false); + + // No ipfs record account. Fail resolution. + ipfs_record_address_handler_->Disable(); + EXPECT_CALL(callback, + Run(GURL(), mojom::SolanaProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); + json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); + base::RunLoop().RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(&callback); +} + } // namespace brave_wallet diff --git a/components/brave_wallet/browser/sns_resolver_task.cc b/components/brave_wallet/browser/sns_resolver_task.cc index d73d409bebd7..596d3aaa3b3f 100644 --- a/components/brave_wallet/browser/sns_resolver_task.cc +++ b/components/brave_wallet/browser/sns_resolver_task.cc @@ -376,11 +376,13 @@ class ScopedWorkOnSnsTask { SnsResolverTask::SnsResolverTask(DoneCallback done_callback, APIRequestHelper* api_request_helper, const std::string& domain, - const GURL& network_url) + const GURL& network_url, + bool resolve_address) : done_callback_(std::move(done_callback)), api_request_helper_(api_request_helper), domain_(domain), - network_url_(network_url) { + network_url_(network_url), + resolve_address_(resolve_address) { DCHECK(api_request_helper_); } @@ -433,6 +435,14 @@ void SnsResolverTask::WorkOnTask() { } } + if (resolve_address_) { + WorkOnWalletAddressTask(); + } else { + WorkOnDomainResolveTask(); + } +} + +void SnsResolverTask::WorkOnWalletAddressTask() { // Check if there is an nft token associated with domain. if (!nft_owner_check_done_) { if (!nft_mint_address_) { @@ -462,10 +472,26 @@ void SnsResolverTask::WorkOnTask() { return; } - if (!sol_record_name_registry_state_) { - FetchSolRecordRegistryState(); + FetchSolRecordRegistryState(); +} + +void SnsResolverTask::WorkOnDomainResolveTask() { + if (!url_record_check_done_) { + FetchUrlRecordRegistryState(); return; } + + FetchIpfsRecordRegistryState(); +} + +void SnsResolverTask::SetAddressResult(SolanaAddress address) { + task_result_.emplace(); + task_result_->resolved_address = std::move(address); +} + +void SnsResolverTask::SetUrlResult(GURL url) { + task_result_.emplace(); + task_result_->resolved_url = std::move(url); } void SnsResolverTask::SetError(SnsResolverTaskError error) { @@ -588,8 +614,6 @@ void SnsResolverTask::OnFetchDomainRegistryState( } void SnsResolverTask::FetchSolRecordRegistryState() { - DCHECK(!sol_record_name_registry_state_); - auto sol_record_address = GetDomainKey("SOL." + domain_, true); if (!sol_record_address) { // Put the domain owner as a fallback result and use it if there is no SOL @@ -626,25 +650,143 @@ void SnsResolverTask::OnFetchSolRecordRegistryState( if (!account_info) { // No such account, use owner address. - task_result_.emplace(domain_name_registry_state_->owner); + SetAddressResult(domain_name_registry_state_->owner); return; } - sol_record_name_registry_state_ = + auto sol_record_name_registry_state = FromBase64(account_info->data); - if (!sol_record_name_registry_state_) { + if (!sol_record_name_registry_state) { SetError(MakeInternalError()); return; } if (auto sol_record_payload_address = ParseAndVerifySolRecordData( - base::make_span(sol_record_name_registry_state_->data), + base::make_span(sol_record_name_registry_state->data), sol_record_address_, domain_name_registry_state_->owner)) { - task_result_.emplace(*sol_record_payload_address); + SetAddressResult(*sol_record_payload_address); } else { // No valid address for SOL record, use owner address. - task_result_.emplace(domain_name_registry_state_->owner); + SetAddressResult(domain_name_registry_state_->owner); + } +} + +void SnsResolverTask::FetchUrlRecordRegistryState() { + auto url_record_address = GetDomainKey("url." + domain_, true); + if (!url_record_address) { + SetError(MakeInternalError()); + ScheduleWorkOnTask(); + return; + } + + auto internal_callback = + base::BindOnce(&SnsResolverTask::OnFetchUrlRecordRegistryState, + weak_ptr_factory_.GetWeakPtr()); + RequestInternal(solana::getAccountInfo(url_record_address->ToBase58()), + std::move(internal_callback), + solana::ConverterForGetAccountInfo()); +} + +void SnsResolverTask::OnFetchUrlRecordRegistryState( + APIRequestResult api_request_result) { + ScopedWorkOnSnsTask work_on_task(this); + + if (!api_request_result.Is2XXResponseCode()) { + SetError(MakeInternalError()); + return; + } + + absl::optional account_info; + if (!solana::ParseGetAccountInfo(api_request_result.body(), &account_info)) { + SetError(MakeInternalError()); + return; + } + + if (!account_info) { + // No url record account, will proceed with ipfs record. + url_record_check_done_ = true; + return; + } + + auto url_record_name_registry_state = + FromBase64(account_info->data); + if (!url_record_name_registry_state) { + SetError(MakeInternalError()); + return; + } + + // Trim possible zeros. + std::string url_string( + std::string(url_record_name_registry_state->data.begin(), + url_record_name_registry_state->data.end()) + .c_str()); + + GURL url(url_string); + if (!url.is_valid()) { + SetError(MakeInvalidParamsError()); + return; + } + + SetUrlResult(std::move(url)); +} + +void SnsResolverTask::FetchIpfsRecordRegistryState() { + auto ipfs_record_address = GetDomainKey("IPFS." + domain_, true); + if (!ipfs_record_address) { + SetError(MakeInternalError()); + ScheduleWorkOnTask(); + return; } + + auto internal_callback = + base::BindOnce(&SnsResolverTask::OnFetchIpfsRecordRegistryState, + weak_ptr_factory_.GetWeakPtr()); + RequestInternal(solana::getAccountInfo(ipfs_record_address->ToBase58()), + std::move(internal_callback), + solana::ConverterForGetAccountInfo()); +} + +void SnsResolverTask::OnFetchIpfsRecordRegistryState( + APIRequestResult api_request_result) { + ScopedWorkOnSnsTask work_on_task(this); + + if (!api_request_result.Is2XXResponseCode()) { + SetError(MakeInternalError()); + return; + } + + absl::optional account_info; + if (!solana::ParseGetAccountInfo(api_request_result.body(), &account_info)) { + SetError(MakeInternalError()); + return; + } + + if (!account_info) { + // No ipfs record account, resolve as error. + SetError(MakeInvalidParamsError()); + return; + } + + auto ipfs_record_name_registry_state = + FromBase64(account_info->data); + if (!ipfs_record_name_registry_state) { + SetError(MakeInternalError()); + return; + } + + // Trim possible zeros. + std::string url_string( + std::string(ipfs_record_name_registry_state->data.begin(), + ipfs_record_name_registry_state->data.end()) + .c_str()); + + GURL url(url_string); + if (!url.is_valid()) { + SetError(MakeInvalidParamsError()); + return; + } + + SetUrlResult(std::move(url)); } void SnsResolverTask::RequestInternal( diff --git a/components/brave_wallet/browser/sns_resolver_task.h b/components/brave_wallet/browser/sns_resolver_task.h index f142fe1a046a..13bd7a5598db 100644 --- a/components/brave_wallet/browser/sns_resolver_task.h +++ b/components/brave_wallet/browser/sns_resolver_task.h @@ -58,6 +58,7 @@ struct SnsResolverTaskResult { ~SnsResolverTaskResult() = default; SolanaAddress resolved_address; + GURL resolved_url; }; struct SnsResolverTaskError { @@ -91,7 +92,8 @@ class SnsResolverTask { SnsResolverTask(DoneCallback done_callback, APIRequestHelper* api_request_helper, const std::string& domain, - const GURL& network_url); + const GURL& network_url, + bool resolve_address); SnsResolverTask(const SnsResolverTask&) = delete; SnsResolverTask& operator=(const SnsResolverTask&) = delete; ~SnsResolverTask(); @@ -113,13 +115,22 @@ class SnsResolverTask { void FetchSolRecordRegistryState(); void OnFetchSolRecordRegistryState(APIRequestResult api_request_result); + void FetchUrlRecordRegistryState(); + void OnFetchUrlRecordRegistryState(APIRequestResult api_request_result); + void FetchIpfsRecordRegistryState(); + void OnFetchIpfsRecordRegistryState(APIRequestResult api_request_result); + private: template friend class SnsResolverTaskContainer; friend class ScopedWorkOnSnsTask; void ScheduleWorkOnTask(); void WorkOnTask(); + void WorkOnWalletAddressTask(); + void WorkOnDomainResolveTask(); + void SetAddressResult(SolanaAddress address); + void SetUrlResult(GURL url); void SetError(SnsResolverTaskError error); void NftOwnerDone(absl::optional nft_owner); @@ -132,6 +143,7 @@ class SnsResolverTask { raw_ptr api_request_helper_; std::string domain_; GURL network_url_; + bool resolve_address_ = false; absl::optional domain_address_; @@ -141,7 +153,8 @@ class SnsResolverTask { absl::optional domain_name_registry_state_; SolanaAddress sol_record_address_; - absl::optional sol_record_name_registry_state_; + + bool url_record_check_done_ = false; absl::optional task_result_; absl::optional task_error_; diff --git a/components/decentralized_dns/content/BUILD.gn b/components/decentralized_dns/content/BUILD.gn index 95295b533fd1..58b02d4677d9 100644 --- a/components/decentralized_dns/content/BUILD.gn +++ b/components/decentralized_dns/content/BUILD.gn @@ -19,6 +19,7 @@ static_library("content") { deps = [ "//base", + "//brave/components/brave_wallet/common:common", "//brave/components/decentralized_dns/core", "//brave/components/l10n/common", "//brave/components/resources:static_resources", diff --git a/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc index 183c011e4dfa..a309885ad60f 100644 --- a/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc +++ b/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.cc @@ -5,6 +5,7 @@ #include "brave/components/decentralized_dns/content/decentralized_dns_interstitial_controller_client.h" +#include "base/notreached.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" @@ -44,7 +45,7 @@ DecentralizedDnsInterstitialControllerClient:: local_state_(local_state) {} void DecentralizedDnsInterstitialControllerClient::Proceed() { - SetResolveMethodAndReload(ResolveMethodTypes::ETHEREUM); + SetResolveMethodAndReload(ResolveMethodTypes::ENABLED); } void DecentralizedDnsInterstitialControllerClient::DontProceed() { @@ -54,9 +55,18 @@ void DecentralizedDnsInterstitialControllerClient::DontProceed() { void DecentralizedDnsInterstitialControllerClient::SetResolveMethodAndReload( ResolveMethodTypes type) { DCHECK(local_state_); - auto* pref_name = IsUnstoppableDomainsTLD(request_url_) - ? kUnstoppableDomainsResolveMethod - : kENSResolveMethod; + const char* pref_name = nullptr; + if (IsUnstoppableDomainsTLD(request_url_)) { + pref_name = kUnstoppableDomainsResolveMethod; + } else if (IsENSTLD(request_url_)) { + pref_name = kENSResolveMethod; + } else if (IsSnsTLD(request_url_)) { + pref_name = kSnsResolveMethod; + } else { + NOTREACHED(); + return; + } + local_state_->SetInteger(pref_name, static_cast(type)); web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE, true); diff --git a/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc index 4c97cb6c8b7e..148b37b2d4dc 100644 --- a/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc +++ b/components/decentralized_dns/content/decentralized_dns_navigation_throttle.cc @@ -8,7 +8,9 @@ #include #include "base/bind.h" +#include "base/features.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "brave/components/brave_wallet/common/features.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/content/ens_offchain_lookup_interstitial_controller_client.h" @@ -59,7 +61,10 @@ DecentralizedDnsNavigationThrottle::WillStartRequest() { GURL url = navigation_handle()->GetURL(); if ((IsUnstoppableDomainsTLD(url) && IsUnstoppableDomainsResolveMethodAsk(local_state_)) || - (IsENSTLD(url) && IsENSResolveMethodAsk(local_state_))) { + (IsENSTLD(url) && IsENSResolveMethodAsk(local_state_)) || + (base::FeatureList::IsEnabled( + brave_wallet::features::kBraveWalletSnsFeature) && + IsSnsTLD(url) && IsSnsResolveMethodAsk(local_state_))) { base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&DecentralizedDnsNavigationThrottle::ShowInterstitial, diff --git a/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc b/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc index 1b90b23fe65d..32fe35cf5be6 100644 --- a/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc +++ b/components/decentralized_dns/content/decentralized_dns_opt_in_page.cc @@ -67,18 +67,13 @@ void DecentralizedDnsOptInPage::CommandReceived(const std::string& command) { void DecentralizedDnsOptInPage::PopulateInterstitialStrings( base::Value::Dict& load_time_data) { - const std::vector message_params = { - u"", + const std::vector infura_links = { + u"https://consensys.net/terms-of-use/", + u"https://consensys.net/privacy-policy/"}; - u"", - - u"", - - u"", - }; + const std::vector coinbase_links = { + u"https://www.coinbase.com/legal/cloud/terms-of-service/", + u"https://www.coinbase.com/legal/privacy/"}; if (IsUnstoppableDomainsTLD(request_url_)) { load_time_data.Set("tabTitle", brave_l10n::GetLocalizedResourceUTF16String( @@ -91,8 +86,8 @@ void DecentralizedDnsOptInPage::PopulateInterstitialStrings( base::ReplaceStringPlaceholders( brave_l10n::GetLocalizedResourceUTF16String( IDS_UNSTOPPABLE_DOMAINS_OPT_IN_PRIMARY_PARAGRAPH), - message_params, nullptr)); - } else { + infura_links, nullptr)); + } else if (IsENSTLD(request_url_)) { load_time_data.Set("tabTitle", brave_l10n::GetLocalizedResourceUTF16String( IDS_ENS_OPT_IN_TITLE)); load_time_data.Set("heading", brave_l10n::GetLocalizedResourceUTF16String( @@ -101,12 +96,31 @@ void DecentralizedDnsOptInPage::PopulateInterstitialStrings( base::ReplaceStringPlaceholders( brave_l10n::GetLocalizedResourceUTF16String( IDS_ENS_OPT_IN_PRIMARY_PARAGRAPH), - message_params, nullptr)); + infura_links, nullptr)); + } else if (IsSnsTLD(request_url_)) { + load_time_data.Set("tabTitle", brave_l10n::GetLocalizedResourceUTF16String( + IDS_SNS_OPT_IN_TITLE)); + load_time_data.Set("heading", brave_l10n::GetLocalizedResourceUTF16String( + IDS_SNS_OPT_IN_HEADING)); + load_time_data.Set("primaryParagraph", + base::ReplaceStringPlaceholders( + brave_l10n::GetLocalizedResourceUTF16String( + IDS_SNS_OPT_IN_PRIMARY_PARAGRAPH), + coinbase_links, nullptr)); + } else { + NOTREACHED(); } - load_time_data.Set("primaryButtonText", - brave_l10n::GetLocalizedResourceUTF16String( - IDS_DECENTRALIZED_DNS_OPT_IN_PRIMARY_BUTTON)); + if (IsSnsTLD(request_url_)) { + load_time_data.Set( + "primaryButtonText", + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_OPT_IN_PRIMARY_COINBASE_BUTTON)); + } else { + load_time_data.Set("primaryButtonText", + brave_l10n::GetLocalizedResourceUTF16String( + IDS_DECENTRALIZED_DNS_OPT_IN_PRIMARY_INFURA_BUTTON)); + } load_time_data.Set("dontProceedButtonText", brave_l10n::GetLocalizedResourceUTF16String( IDS_DECENTRALIZED_DNS_OPT_IN_DONT_PROCEED_BUTTON)); diff --git a/components/decentralized_dns/content/ens_offchain_lookup_opt_in_page.cc b/components/decentralized_dns/content/ens_offchain_lookup_opt_in_page.cc index c409f5122713..528ffbda887b 100644 --- a/components/decentralized_dns/content/ens_offchain_lookup_opt_in_page.cc +++ b/components/decentralized_dns/content/ens_offchain_lookup_opt_in_page.cc @@ -67,13 +67,8 @@ void EnsOffchainLookupOptInPage::CommandReceived(const std::string& command) { void EnsOffchainLookupOptInPage::PopulateInterstitialStrings( base::Value::Dict& load_time_data) { - const std::vector message_params = { - u"", - - u"", - }; + std::u16string learn_more_link = + u"https://github.com/brave/brave-browser/wiki/ENS-offchain-lookup"; load_time_data.Set("tabTitle", brave_l10n::GetLocalizedResourceUTF16String( IDS_ENS_OFFCHAIN_LOOKUP_OPT_IN_TITLE)); @@ -83,7 +78,7 @@ void EnsOffchainLookupOptInPage::PopulateInterstitialStrings( base::ReplaceStringPlaceholders( brave_l10n::GetLocalizedResourceUTF16String( IDS_ENS_OFFCHAIN_LOOKUP_OPT_IN_PRIMARY_PARAGRAPH), - message_params, nullptr)); + {learn_more_link}, nullptr)); load_time_data.Set("primaryButtonText", brave_l10n::GetLocalizedResourceUTF16String( diff --git a/components/decentralized_dns/core/constants.h b/components/decentralized_dns/core/constants.h index 569fe5280aad..fa594106306d 100644 --- a/components/decentralized_dns/core/constants.h +++ b/components/decentralized_dns/core/constants.h @@ -13,8 +13,8 @@ enum class ResolveMethodTypes { ASK, DISABLED, DEPRECATED_DNS_OVER_HTTPS, - ETHEREUM, - MAX_VALUE = ETHEREUM, + ENABLED, + MAX_VALUE = ENABLED, }; enum class EnsOffchainResolveMethod { kAsk, kDisabled, kEnabled }; diff --git a/components/decentralized_dns/core/pref_names.h b/components/decentralized_dns/core/pref_names.h index 3aa712672245..7a91429db1c7 100644 --- a/components/decentralized_dns/core/pref_names.h +++ b/components/decentralized_dns/core/pref_names.h @@ -12,7 +12,7 @@ namespace decentralized_dns { // domains, between: // Disabled: Disable all unstoppable domains resolution. // Ask: Ask users if they want to enable support of unstoppable domains. -// Ethereum: Resolve domain name using Ethereum JSON-RPC server. +// Enabled: Resolve domain name using Ethereum JSON-RPC server. constexpr char kUnstoppableDomainsResolveMethod[] = "brave.unstoppable_domains.resolve_method"; @@ -20,12 +20,19 @@ constexpr char kUnstoppableDomainsResolveMethod[] = // between: // Disabled: Disable all ENS domains resolution. // Ask: Ask users if they want to enable support of ENS. -// Ethereum: Resolve domain name using Ethereum JSON-RPC server. +// Enabled: Resolve domain name using Ethereum JSON-RPC server. constexpr char kENSResolveMethod[] = "brave.ens.resolve_method"; constexpr char kEnsOffchainResolveMethod[] = "brave.ens.offchain_resolve_method"; +// Used to determine which method should be used to resolve SNS domains, +// between: +// Disabled: Disable all SNS domains resolution. +// Ask: Ask users if they want to enable support of SNS. +// Enabled: Resolve domain name using Solana JSON-RPC server. +constexpr char kSnsResolveMethod[] = "brave.sns.resolve_method"; + } // namespace decentralized_dns #endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_PREF_NAMES_H_ diff --git a/components/decentralized_dns/core/utils.cc b/components/decentralized_dns/core/utils.cc index 7eb0c3466fa1..b41d180230eb 100644 --- a/components/decentralized_dns/core/utils.cc +++ b/components/decentralized_dns/core/utils.cc @@ -23,6 +23,8 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { registry->RegisterIntegerPref( kEnsOffchainResolveMethod, static_cast(EnsOffchainResolveMethod::kAsk)); + registry->RegisterIntegerPref(kSnsResolveMethod, + static_cast(ResolveMethodTypes::ASK)); } void MigrateObsoleteLocalStatePrefs(PrefService* local_state) { @@ -61,7 +63,7 @@ bool IsUnstoppableDomainsResolveMethodEthereum(PrefService* local_state) { } return local_state->GetInteger(kUnstoppableDomainsResolveMethod) == - static_cast(ResolveMethodTypes::ETHEREUM); + static_cast(ResolveMethodTypes::ENABLED); } bool IsENSTLD(const GURL& url) { @@ -83,7 +85,7 @@ bool IsENSResolveMethodEthereum(PrefService* local_state) { } return local_state->GetInteger(kENSResolveMethod) == - static_cast(ResolveMethodTypes::ETHEREUM); + static_cast(ResolveMethodTypes::ENABLED); } void SetEnsOffchainResolveMethod(PrefService* local_state, @@ -96,4 +98,26 @@ EnsOffchainResolveMethod GetEnsOffchainResolveMethod(PrefService* local_state) { local_state->GetInteger(kEnsOffchainResolveMethod)); } +bool IsSnsTLD(const GURL& url) { + return base::EndsWith(url.host_piece(), kSolDomain); +} + +bool IsSnsResolveMethodAsk(PrefService* local_state) { + if (!local_state) { + return false; // Treat it as disabled. + } + + return local_state->GetInteger(kSnsResolveMethod) == + static_cast(ResolveMethodTypes::ASK); +} + +bool IsSnsResolveMethodEnabled(PrefService* local_state) { + if (!local_state) { + return false; // Treat it as disabled. + } + + return local_state->GetInteger(kSnsResolveMethod) == + static_cast(ResolveMethodTypes::ENABLED); +} + } // namespace decentralized_dns diff --git a/components/decentralized_dns/core/utils.h b/components/decentralized_dns/core/utils.h index 758f257ae6bb..a0deaa9b77a6 100644 --- a/components/decentralized_dns/core/utils.h +++ b/components/decentralized_dns/core/utils.h @@ -29,6 +29,10 @@ void SetEnsOffchainResolveMethod(PrefService* local_state, EnsOffchainResolveMethod method); EnsOffchainResolveMethod GetEnsOffchainResolveMethod(PrefService* local_state); +bool IsSnsTLD(const GURL& url); +bool IsSnsResolveMethodAsk(PrefService* local_state); +bool IsSnsResolveMethodEnabled(PrefService* local_state); + } // namespace decentralized_dns #endif // BRAVE_COMPONENTS_DECENTRALIZED_DNS_CORE_UTILS_H_ diff --git a/components/resources/decentralized_dns_strings.grdp b/components/resources/decentralized_dns_strings.grdp index 4a1ae9e4427f..241d36a548b9 100644 --- a/components/resources/decentralized_dns_strings.grdp +++ b/components/resources/decentralized_dns_strings.grdp @@ -7,7 +7,7 @@ Enable support of Unstoppable Domains in Brave? - Brave will be using Infura to issue Ethereum JSON-RPC calls to the smart contract from Unstoppable Domains to resolve .crypto (and also .x, .coin, .nft, .dao, .wallet, .blockchain, .bitcoin, .zil) domain name lookup requests. If you enable this, Infura will see those specific domains that you're trying to visit but they will not be able to see other domains. See Infura's $1terms of use$2 and $3privacy policy$4. + Brave will be using Infura to issue Ethereum JSON-RPC calls to the smart contract from Unstoppable Domains to resolve .crypto (and also .x, .coin, .nft, .dao, .wallet, .blockchain, .bitcoin, .zil) domain name lookup requests. If you enable this, Infura will see those specific domains that you're trying to visit but they will not be able to see other domains. See Infura's <a target="_blank" href="$1">terms of use</a> and <a target="_blank" href="$2">privacy policy</a>. Ethereum Name Service @@ -16,7 +16,7 @@ Enable support of Ethereum Name Service (ENS) in Brave? - Brave will be using Infura to issue Ethereum JSON-RPC calls to the smart contract from Ethereum Name Service to resolve .eth domain name lookup requests. If you enable this, Infura will see the .eth domain that you're trying to visit but they will not be able to see other domains. See Infura's $1terms of use$2 and $3privacy policy$4. + Brave will be using Infura to issue Ethereum JSON-RPC calls to the smart contract from Ethereum Name Service to resolve .eth domain name lookup requests. If you enable this, Infura will see the .eth domain that you're trying to visit but they will not be able to see other domains. See Infura's <a target="_blank" href="$1">terms of use</a> and <a target="_blank" href="$2">privacy policy</a>. Ethereum Name Service Offchain Lookup @@ -25,7 +25,7 @@ Enable support of Ethereum Name Service (ENS) offchain lookup in Brave? - Brave will be using offchain gateways to resolve .eth domain name lookup requests. If you enable this, third party gateways will see the .eth domain that you're trying to visit but they will not be able to see other domains. $1Learn more$2. + Brave will be using offchain gateways to resolve .eth domain name lookup requests. If you enable this, third party gateways will see the .eth domain that you're trying to visit but they will not be able to see other domains. <a target="_blank" href="$1">Learn more</a>. Proceed with offchain lookup @@ -33,9 +33,24 @@ Disable + + Solana Name Service + + + Enable support of Solana Name Service (SNS) in Brave? + + + Brave will be using Coinbase Cloud to issue Solana JSON-RPC calls to the program from Solana Name Service to resolve .sol domain name lookup requests. If you enable this, Coinbase Cloud will see the .sol domain that you're trying to visit but they will not be able to see other domains. See Coinbase Cloud's <a target="_blank" href="$1">terms of use</a> and <a target="_blank" href="$2">privacy policy</a>. + Proceed using Infura server + + Proceed using Infura server + + + Proceed using Coinbase Cloud server + Disable @@ -45,8 +60,8 @@ Disabled - - Ethereum + + Enabled Ask diff --git a/net/decentralized_dns/constants.h b/net/decentralized_dns/constants.h index aa18fa5fb31d..41a7eb1a57e5 100644 --- a/net/decentralized_dns/constants.h +++ b/net/decentralized_dns/constants.h @@ -15,6 +15,8 @@ constexpr const char* kUnstoppableDomains[] = { constexpr char kEthDomain[] = ".eth"; constexpr char kDNSForEthDomain[] = ".eth.link"; +constexpr char kSolDomain[] = ".sol"; + } // namespace decentralized_dns #endif // BRAVE_NET_DECENTRALIZED_DNS_CONSTANTS_H_ From 91d2a5920940315f8cb1df0c9c5686cba117dab6 Mon Sep 17 00:00:00 2001 From: Anton Paymyshev Date: Tue, 15 Nov 2022 10:24:22 +0700 Subject: [PATCH 2/2] fix review --- .../brave_wallet/browser/json_rpc_service.cc | 4 ++-- .../browser/json_rpc_service_unittest.cc | 4 ++-- .../brave_wallet/browser/sns_resolver_task.cc | 16 +++++++++------- components/decentralized_dns/content/BUILD.gn | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/components/brave_wallet/browser/json_rpc_service.cc b/components/brave_wallet/browser/json_rpc_service.cc index bb01a5c023d8..6926b54c3b9a 100644 --- a/components/brave_wallet/browser/json_rpc_service.cc +++ b/components/brave_wallet/browser/json_rpc_service.cc @@ -1488,8 +1488,8 @@ void JsonRpcService::OnSnsResolveHostTaskDone( if (task_result->resolved_url.is_valid()) { url = task_result->resolved_url; } else { - error = mojom::SolanaProviderError::kInvalidParams; - error_message = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS); + error = mojom::SolanaProviderError::kInternalError; + error_message = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR); } } diff --git a/components/brave_wallet/browser/json_rpc_service_unittest.cc b/components/brave_wallet/browser/json_rpc_service_unittest.cc index 73df7f295619..57be6847d031 100644 --- a/components/brave_wallet/browser/json_rpc_service_unittest.cc +++ b/components/brave_wallet/browser/json_rpc_service_unittest.cc @@ -5971,8 +5971,8 @@ TEST_F(SnsJsonRpcServiceUnitTest, ResolveHost_IpfsValue) { // No ipfs record account. Fail resolution. ipfs_record_address_handler_->Disable(); EXPECT_CALL(callback, - Run(GURL(), mojom::SolanaProviderError::kInvalidParams, - l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS))); + Run(GURL(), mojom::SolanaProviderError::kInternalError, + l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR))); json_rpc_service_->SnsResolveHost(sns_host(), callback.Get()); base::RunLoop().RunUntilIdle(); testing::Mock::VerifyAndClearExpectations(&callback); diff --git a/components/brave_wallet/browser/sns_resolver_task.cc b/components/brave_wallet/browser/sns_resolver_task.cc index 596d3aaa3b3f..50cff6fb0c6e 100644 --- a/components/brave_wallet/browser/sns_resolver_task.cc +++ b/components/brave_wallet/browser/sns_resolver_task.cc @@ -698,7 +698,7 @@ void SnsResolverTask::OnFetchUrlRecordRegistryState( absl::optional account_info; if (!solana::ParseGetAccountInfo(api_request_result.body(), &account_info)) { - SetError(MakeInternalError()); + SetError(ParseErrorResult(api_request_result.body())); return; } @@ -715,7 +715,8 @@ void SnsResolverTask::OnFetchUrlRecordRegistryState( return; } - // Trim possible zeros. + // https://bonfida.github.io/solana-name-service-guide/registry.html + // Parse NameRegistry data as a string trimming possible zeros at the end. std::string url_string( std::string(url_record_name_registry_state->data.begin(), url_record_name_registry_state->data.end()) @@ -723,7 +724,7 @@ void SnsResolverTask::OnFetchUrlRecordRegistryState( GURL url(url_string); if (!url.is_valid()) { - SetError(MakeInvalidParamsError()); + SetError(MakeInternalError()); return; } @@ -757,13 +758,13 @@ void SnsResolverTask::OnFetchIpfsRecordRegistryState( absl::optional account_info; if (!solana::ParseGetAccountInfo(api_request_result.body(), &account_info)) { - SetError(MakeInternalError()); + SetError(ParseErrorResult(api_request_result.body())); return; } if (!account_info) { // No ipfs record account, resolve as error. - SetError(MakeInvalidParamsError()); + SetError(MakeInternalError()); return; } @@ -774,7 +775,8 @@ void SnsResolverTask::OnFetchIpfsRecordRegistryState( return; } - // Trim possible zeros. + // https://bonfida.github.io/solana-name-service-guide/registry.html + // Parse NameRegistry data as a string trimming possible zeros at the end. std::string url_string( std::string(ipfs_record_name_registry_state->data.begin(), ipfs_record_name_registry_state->data.end()) @@ -782,7 +784,7 @@ void SnsResolverTask::OnFetchIpfsRecordRegistryState( GURL url(url_string); if (!url.is_valid()) { - SetError(MakeInvalidParamsError()); + SetError(MakeInternalError()); return; } diff --git a/components/decentralized_dns/content/BUILD.gn b/components/decentralized_dns/content/BUILD.gn index 58b02d4677d9..164f51f460fb 100644 --- a/components/decentralized_dns/content/BUILD.gn +++ b/components/decentralized_dns/content/BUILD.gn @@ -19,7 +19,7 @@ static_library("content") { deps = [ "//base", - "//brave/components/brave_wallet/common:common", + "//brave/components/brave_wallet/common", "//brave/components/decentralized_dns/core", "//brave/components/l10n/common", "//brave/components/resources:static_resources",