Skip to content

Commit

Permalink
SNS support for wallet (#15617)
Browse files Browse the repository at this point in the history
  • Loading branch information
supermassive authored Nov 9, 2022
1 parent c270858 commit a9828ac
Show file tree
Hide file tree
Showing 28 changed files with 2,003 additions and 31 deletions.
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ static_library("browser") {
"nonce_tracker.h",
"password_encryptor.cc",
"password_encryptor.h",
"sns_resolver_task.cc",
"sns_resolver_task.h",
"solana_account_meta.cc",
"solana_account_meta.h",
"solana_block_tracker.cc",
Expand Down
24 changes: 4 additions & 20 deletions components/brave_wallet/browser/brave_wallet_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1054,26 +1054,10 @@ std::vector<mojom::NetworkInfoPtr> GetAllKnownChains(PrefService* prefs,
GURL GetNetworkURL(PrefService* prefs,
const std::string& chain_id,
mojom::CoinType coin) {
if (coin == mojom::CoinType::ETH) {
if (auto custom_chain =
GetCustomChain(prefs, chain_id, mojom::CoinType::ETH)) {
return MaybeAddInfuraProjectId(GetActiveEndpointUrl(*custom_chain));
} else if (auto known_chain =
GetKnownChain(prefs, chain_id, mojom::CoinType::ETH)) {
return MaybeAddInfuraProjectId(GetActiveEndpointUrl(*known_chain));
}
} else if (coin == mojom::CoinType::SOL) {
for (const auto* network : GetKnownSolNetworks()) {
if (base::CompareCaseInsensitiveASCII(network->chain_id, chain_id) == 0) {
return GetActiveEndpointUrl(*network);
}
}
} else if (coin == mojom::CoinType::FIL) {
for (const auto* network : GetKnownFilNetworks()) {
if (base::CompareCaseInsensitiveASCII(network->chain_id, chain_id) == 0) {
return GetActiveEndpointUrl(*network);
}
}
if (auto custom_chain = GetCustomChain(prefs, chain_id, coin)) {
return MaybeAddInfuraProjectId(GetActiveEndpointUrl(*custom_chain));
} else if (auto known_chain = GetKnownChain(prefs, chain_id, coin)) {
return MaybeAddInfuraProjectId(GetActiveEndpointUrl(*known_chain));
}
return GURL();
}
Expand Down
24 changes: 24 additions & 0 deletions components/brave_wallet/browser/brave_wallet_utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,30 @@ TEST(BraveWalletUtilsUnitTest, GetNetworkURLTest) {
GetNetworkURL(&prefs, chain1.chain_id, mojom::CoinType::ETH));
EXPECT_EQ(chain2.rpc_endpoints.front(),
GetNetworkURL(&prefs, chain2.chain_id, mojom::CoinType::ETH));

EXPECT_EQ(GURL("https://mainnet-beta-solana.brave.com/rpc"),
GetNetworkURL(&prefs, mojom::kSolanaMainnet, mojom::CoinType::SOL));
auto custom_sol_network =
GetKnownChain(&prefs, mojom::kSolanaMainnet, mojom::CoinType::SOL);
custom_sol_network->rpc_endpoints.emplace_back("https://test-sol.com");
custom_sol_network->active_rpc_endpoint_index = 1;
UpdateCustomNetworks(&prefs, {NetworkInfoToValue(*custom_sol_network)},
mojom::CoinType::SOL);
EXPECT_EQ(GURL("https://test-sol.com"),
GetNetworkURL(&prefs, mojom::kSolanaMainnet, mojom::CoinType::SOL));

EXPECT_EQ(
GURL("https://api.node.glif.io/rpc/v0"),
GetNetworkURL(&prefs, mojom::kFilecoinMainnet, mojom::CoinType::FIL));
auto custom_fil_network =
GetKnownChain(&prefs, mojom::kFilecoinMainnet, mojom::CoinType::FIL);
custom_fil_network->rpc_endpoints.emplace_back("https://test-fil.com");
custom_fil_network->active_rpc_endpoint_index = 1;
UpdateCustomNetworks(&prefs, {NetworkInfoToValue(*custom_fil_network)},
mojom::CoinType::FIL);
EXPECT_EQ(
GURL("https://test-fil.com"),
GetNetworkURL(&prefs, mojom::kFilecoinMainnet, mojom::CoinType::FIL));
}

TEST(BraveWalletUtilsUnitTest, GetNetworkURLForKnownChains) {
Expand Down
74 changes: 70 additions & 4 deletions components/brave_wallet/browser/json_rpc_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,75 @@ void JsonRpcService::OnEnsGetEthAddrTaskDone(
}
}

void JsonRpcService::SnsGetSolAddr(const std::string& domain,
SnsGetSolAddrCallback callback) {
if (!base::FeatureList::IsEnabled(features::kBraveWalletSnsFeature)) {
std::move(callback).Run(
"", mojom::SolanaProviderError::kInvalidParams,
l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS));
return;
}

if (!IsValidDomain(domain)) {
std::move(callback).Run(
"", mojom::SolanaProviderError::kInvalidParams,
l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS));
return;
}

if (sns_get_sol_addr_tasks_.ContainsTaskForDomain(domain)) {
sns_get_sol_addr_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(
"", 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::OnSnsGetSolAddrTaskDone,
base::Unretained(this));

sns_get_sol_addr_tasks_.AddTask(
std::make_unique<SnsResolverTask>(std::move(done_callback),
api_request_helper_.get(), domain,
network_url),
std::move(callback));
}

void JsonRpcService::OnSnsGetSolAddrTaskDone(
SnsResolverTask* task,
absl::optional<SnsResolverTaskResult> task_result,
absl::optional<SnsResolverTaskError> task_error) {
auto callbacks = sns_get_sol_addr_tasks_.TaskDone(task);
if (callbacks.empty()) {
return;
}

std::string address;
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_address.IsValid()) {
address = task_result->resolved_address.ToBase58();
} else {
error = mojom::SolanaProviderError::kInvalidParams;
error_message = l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS);
}
}

for (auto& cb : callbacks) {
std::move(cb).Run(address, error, error_message);
}
}

void JsonRpcService::OnEnsGetContentHashTaskDone(
EnsResolverTask* task,
absl::optional<EnsResolverTaskResult> task_result,
Expand Down Expand Up @@ -2746,10 +2815,7 @@ void JsonRpcService::GetSolanaAccountInfo(
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
RequestInternal(
solana::getAccountInfo(pubkey), true, network_urls_[mojom::CoinType::SOL],
std::move(internal_callback),
base::BindOnce(&ConvertMultiUint64ToString,
std::vector<std::string>({"/result/value/lamports",
"/result/value/rentEpoch"})));
std::move(internal_callback), solana::ConverterForGetAccountInfo());
}

void JsonRpcService::OnGetSolanaAccountInfo(
Expand Down
9 changes: 9 additions & 0 deletions components/brave_wallet/browser/json_rpc_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "brave/components/api_request_helper/api_request_helper.h"
#include "brave/components/brave_wallet/browser/brave_wallet_constants.h"
#include "brave/components/brave_wallet/browser/ens_resolver_task.h"
#include "brave/components/brave_wallet/browser/sns_resolver_task.h"
#include "brave/components/brave_wallet/browser/solana_transaction.h"
#include "brave/components/brave_wallet/browser/unstoppable_domains_multichain_calls.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
Expand Down Expand Up @@ -176,6 +177,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService {
void EnsGetEthAddr(const std::string& domain,
mojom::EnsOffchainLookupOptionsPtr options,
EnsGetEthAddrCallback callback) override;
void SnsGetSolAddr(const std::string& domain,
SnsGetSolAddrCallback callback) override;

bool SetNetwork(const std::string& chain_id,
mojom::CoinType coin,
Expand Down Expand Up @@ -474,6 +477,10 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService {
EnsResolverTask* task,
absl::optional<EnsResolverTaskResult> task_result,
absl::optional<EnsResolverTaskError> error);
void OnSnsGetSolAddrTaskDone(
SnsResolverTask* task,
absl::optional<SnsResolverTaskResult> task_result,
absl::optional<SnsResolverTaskError> error);
void OnEnsGetEthAddr(EnsGetEthAddrCallback callback,
APIRequestResult api_request_result);
void OnGetFilEstimateGas(GetFilEstimateGasCallback callback,
Expand Down Expand Up @@ -584,6 +591,8 @@ class JsonRpcService : public KeyedService, public mojom::JsonRpcService {
EnsResolverTaskContainer<EnsGetContentHashCallback>
ens_get_content_hash_tasks_;

SnsResolverTaskContainer<SnsGetSolAddrCallback> sns_get_sol_addr_tasks_;

mojo::ReceiverSet<mojom::JsonRpcService> receivers_;
PrefService* prefs_ = nullptr;
PrefService* local_state_prefs_ = nullptr;
Expand Down
28 changes: 28 additions & 0 deletions components/brave_wallet/browser/json_rpc_service_test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include "brave/components/brave_wallet/browser/json_rpc_service_test_utils.h"

#include <utility>

#include "base/json/json_writer.h"
#include "base/strings/stringprintf.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/brave_wallet/common/eth_address.h"
Expand Down Expand Up @@ -62,4 +65,29 @@ std::string MakeJsonRpcErrorResponseWithData(int error,
error, error_message.c_str(), data.c_str());
}

std::string MakeJsonRpcValueResponse(const base::Value& value) {
base::Value::Dict response;
response.Set("jsonrpc", "2.0");
response.Set("id", 1);
base::Value::Dict result;
result.SetByDottedPath("context.slot", 12345);
result.Set("value", value.Clone());
response.Set("result", std::move(result));

std::string response_string;
base::JSONWriter::Write(response, &response_string);
return response_string;
}

std::string MakeJsonRpcResultResponse(const base::Value& value) {
base::Value::Dict response;
response.Set("jsonrpc", "2.0");
response.Set("id", 1);
response.Set("result", value.Clone());

std::string response_string;
base::JSONWriter::Write(response, &response_string);
return response_string;
}

} // namespace brave_wallet
3 changes: 3 additions & 0 deletions components/brave_wallet/browser/json_rpc_service_test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ std::string MakeJsonRpcErrorResponseWithData(int error,
const std::string& error_message,
const std::string& data);

std::string MakeJsonRpcValueResponse(const base::Value& value);
std::string MakeJsonRpcResultResponse(const base::Value& value);

} // namespace brave_wallet

#endif // BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_JSON_RPC_SERVICE_TEST_UTILS_H_
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "brave/components/brave_wallet/browser/json_rpc_service_test_utils.h"

#include <utility>

#include "base/json/json_reader.h"
#include "base/test/values_test_util.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
Expand Down Expand Up @@ -193,4 +195,16 @@ TEST(JsonRpcServiceTestUtils, MakeJsonRpcErrorResponse) {
*value->GetDict().FindStringByDottedPath("error.message"));
}

TEST(JsonRpcServiceTestUtils, MakeJsonRpcValueResponse) {
base::Value::Dict payload;
payload.Set("test", 555);
auto json = MakeJsonRpcValueResponse(base::Value(std::move(payload)));
absl::optional<base::Value> value = base::JSONReader::Read(json);
ASSERT_TRUE(value);
ASSERT_TRUE(value->is_dict());
EXPECT_EQ("2.0", *value->GetDict().FindString("jsonrpc"));
EXPECT_EQ(1, *value->GetDict().FindInt("id"));
EXPECT_EQ(555, *value->GetDict().FindIntByDottedPath("result.value.test"));
}

} // namespace brave_wallet
Loading

0 comments on commit a9828ac

Please sign in to comment.