Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Allow to create Mainnet Filecoin accounts #13402

Merged
merged 1 commit into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions browser/brave_wallet/filecoin_keyring_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ TEST(FilecoinKeyring, ImportFilecoinSECP) {
ASSERT_FALSE(input_key.empty());
std::vector<uint8_t> private_key(input_key.begin(), input_key.end());

FilecoinKeyring keyring;
FilecoinKeyring keyring(brave_wallet::mojom::kLocalhostChainId);
auto address =
keyring.ImportFilecoinAccount(private_key, mojom::kFilecoinTestnet,
mojom::FilecoinAddressProtocol::SECP256K1);
Expand All @@ -117,7 +117,7 @@ TEST(FilecoinKeyring, ImportFilecoinBLS) {
ASSERT_TRUE(FilecoinKeyring::DecodeImportPayload(private_key_hex,
&private_key, &protocol));
EXPECT_EQ(protocol, mojom::FilecoinAddressProtocol::BLS);
FilecoinKeyring keyring;
FilecoinKeyring keyring(brave_wallet::mojom::kLocalhostChainId);
std::string address = keyring.ImportFilecoinAccount(
private_key, mojom::kFilecoinTestnet, protocol);
EXPECT_EQ(address,
Expand Down Expand Up @@ -169,7 +169,7 @@ TEST(FilecoinKeyring, fil_private_key_public_key) {
}

TEST(FilecoinKeyring, SignTransaction) {
FilecoinKeyring keyring;
FilecoinKeyring keyring(brave_wallet::mojom::kLocalhostChainId);
EXPECT_FALSE(keyring.SignTransaction(nullptr));

auto transaction = FilTransaction::FromTxData(mojom::FilTxData::New(
Expand Down
159 changes: 159 additions & 0 deletions browser/brave_wallet/keyring_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "base/test/scoped_feature_list.h"
#include "brave/browser/brave_wallet/json_rpc_service_factory.h"
#include "brave/components/brave_wallet/browser/brave_wallet_constants.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/brave_wallet/browser/fil_transaction.h"
#include "brave/components/brave_wallet/browser/filecoin_keyring.h"
#include "brave/components/brave_wallet/browser/hd_keyring.h"
Expand Down Expand Up @@ -549,6 +550,17 @@ class KeyringServiceUnitTest : public testing::Test {
run_loop.Run();
return checksum_address;
}
bool SetNetwork(const std::string& chain_id, mojom::CoinType coin) {
bool result;
base::RunLoop run_loop;
json_rpc_service_->SetNetwork(chain_id, coin,
base::BindLambdaForTesting([&](bool success) {
result = success;
run_loop.Quit();
}));
run_loop.Run();
return result;
}

static bool Lock(KeyringService* service) {
service->Lock();
Expand Down Expand Up @@ -3448,4 +3460,151 @@ TEST_F(KeyringServiceAccountDiscoveryUnitTest, RestoreWalletTwice) {
EXPECT_THAT(requested_addresses, ElementsAreArray(&saved_addresses()[1], 30));
}

TEST_F(KeyringServiceUnitTest, AccountMetasForFilecoinKeyring) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{brave_wallet::features::kBraveWalletFilecoinFeature}, {});

KeyringService service(json_rpc_service(), GetPrefs());
SetNetwork(brave_wallet::mojom::kFilecoinTestnet, mojom::CoinType::FIL);
EXPECT_TRUE(
service.CreateEncryptorForKeyring("brave", mojom::kFilecoinKeyringId));
ASSERT_TRUE(service.CreateKeyringInternal(
brave_wallet::mojom::kFilecoinKeyringId, kMnemonic1, false));
auto* keyring =
service.GetHDKeyringById(brave_wallet::mojom::kFilecoinKeyringId);
keyring->AddAccounts(2);

EXPECT_EQ(GetCurrentChainId(GetPrefs(), mojom::CoinType::FIL),
brave_wallet::mojom::kFilecoinTestnet);
const std::string address1 = keyring->GetAddress(0);
const std::string name1 = "Filecoin Account 1";
const std::string account_path1 = KeyringService::GetAccountPathByIndex(
0, brave_wallet::mojom::kFilecoinKeyringId);
const std::string address2 = keyring->GetAddress(1);
const std::string name2 = "Filecoin Account 2";
const std::string account_path2 = KeyringService::GetAccountPathByIndex(
1, brave_wallet::mojom::kFilecoinKeyringId);

KeyringService::SetAccountMetaForKeyring(GetPrefs(), account_path1, name1,
address1, mojom::kFilecoinKeyringId);
KeyringService::SetAccountMetaForKeyring(GetPrefs(), account_path2, name2,
address2, mojom::kFilecoinKeyringId);

const base::Value* account_metas = KeyringService::GetPrefForKeyring(
GetPrefs(), kAccountMetas, mojom::kFilecoinKeyringId);
ASSERT_NE(account_metas, nullptr);
std::string prefix = GetCurrentFilecoinNetworkPrefix(GetPrefs());
const base::Value* account_metas_for_network = account_metas->FindKey(prefix);
EXPECT_TRUE(account_metas_for_network);

EXPECT_EQ(account_metas_for_network->FindPath(account_path1 + ".account_name")
->GetString(),
name1);
EXPECT_EQ(account_metas_for_network->FindPath(account_path2 + ".account_name")
->GetString(),
name2);
EXPECT_EQ(KeyringService::GetAccountNameForKeyring(GetPrefs(), account_path1,
mojom::kFilecoinKeyringId),
name1);
EXPECT_EQ(KeyringService::GetAccountAddressForKeyring(
GetPrefs(), account_path1, mojom::kFilecoinKeyringId),
address1);
EXPECT_EQ(KeyringService::GetAccountNameForKeyring(GetPrefs(), account_path2,
mojom::kFilecoinKeyringId),
name2);
EXPECT_EQ(KeyringService::GetAccountAddressForKeyring(
GetPrefs(), account_path2, mojom::kFilecoinKeyringId),
address2);
EXPECT_EQ(service.GetAccountMetasNumberForKeyring(mojom::kFilecoinKeyringId),
2u);
EXPECT_EQ(service.GetAccountMetasNumberForKeyring("keyring1"), 0u);

// GetAccountInfosForKeyring should work even if the keyring is locked
service.Lock();
std::vector<mojom::AccountInfoPtr> account_infos =
service.GetAccountInfosForKeyring(mojom::kFilecoinKeyringId);
EXPECT_EQ(account_infos.size(), 2u);
EXPECT_EQ(account_infos[0]->address, address1);
EXPECT_EQ(account_infos[0]->name, name1);
EXPECT_EQ(account_infos[1]->address, address2);
EXPECT_EQ(account_infos[1]->name, name2);
}

TEST_F(KeyringServiceUnitTest, SwitchAccountsOnNetworkChange) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{brave_wallet::features::kBraveWalletFilecoinFeature}, {});

KeyringService service(json_rpc_service(), GetPrefs());
EXPECT_TRUE(
service.CreateEncryptorForKeyring("brave", mojom::kFilecoinKeyringId));

ASSERT_TRUE(service.CreateKeyringInternal(
brave_wallet::mojom::kFilecoinKeyringId, kMnemonic1, false));

auto* keyring =
service.GetHDKeyringById(brave_wallet::mojom::kFilecoinKeyringId);

SetNetwork(brave_wallet::mojom::kFilecoinMainnet, mojom::CoinType::FIL);
base::RunLoop().RunUntilIdle();
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");
EXPECT_EQ(keyring->GetAccountsNumber(), 2u);
const std::string f_address1 = keyring->GetAddress(0);
const std::string f_address2 = keyring->GetAddress(1);
{
std::vector<mojom::AccountInfoPtr> account_infos =
service.GetAccountInfosForKeyring(mojom::kFilecoinKeyringId);
EXPECT_EQ(account_infos.size(), 2u);
EXPECT_EQ(account_infos[0]->address, f_address1);
EXPECT_EQ(account_infos[1]->address, f_address2);
EXPECT_EQ(FilAddress::FromAddress(f_address1).network(),
brave_wallet::mojom::kFilecoinMainnet);
EXPECT_EQ(FilAddress::FromAddress(f_address2).network(),
brave_wallet::mojom::kFilecoinMainnet);
}

SetNetwork(brave_wallet::mojom::kFilecoinTestnet, mojom::CoinType::FIL);
base::RunLoop().RunUntilIdle();
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");

EXPECT_EQ(keyring->GetAccountsNumber(), 2u);
const std::string t_address1 = keyring->GetAddress(0);
const std::string t_address2 = keyring->GetAddress(1);
{
std::vector<mojom::AccountInfoPtr> account_infos =
service.GetAccountInfosForKeyring(mojom::kFilecoinKeyringId);
EXPECT_EQ(account_infos.size(), 2u);
EXPECT_EQ(account_infos[0]->address, t_address1);
EXPECT_EQ(account_infos[1]->address, t_address2);
EXPECT_EQ(FilAddress::FromAddress(t_address1).network(),
brave_wallet::mojom::kFilecoinTestnet);
EXPECT_EQ(FilAddress::FromAddress(t_address2).network(),
brave_wallet::mojom::kFilecoinTestnet);
}
SetNetwork(brave_wallet::mojom::kLocalhostChainId, mojom::CoinType::FIL);
base::RunLoop().RunUntilIdle();
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");
service.AddAccountForKeyring(mojom::kFilecoinKeyringId, "");
EXPECT_EQ(keyring->GetAccountsNumber(), 4u);
const std::string t_address3 = keyring->GetAddress(2);
const std::string t_address4 = keyring->GetAddress(3);
{
std::vector<mojom::AccountInfoPtr> account_infos =
service.GetAccountInfosForKeyring(mojom::kFilecoinKeyringId);
EXPECT_EQ(account_infos.size(), 4u);
EXPECT_EQ(account_infos[0]->address, t_address1);
EXPECT_EQ(account_infos[1]->address, t_address2);
EXPECT_EQ(account_infos[2]->address, t_address3);
EXPECT_EQ(account_infos[3]->address, t_address4);

EXPECT_EQ(FilAddress::FromAddress(t_address3).network(),
brave_wallet::mojom::kFilecoinTestnet);
EXPECT_EQ(FilAddress::FromAddress(t_address4).network(),
brave_wallet::mojom::kFilecoinTestnet);
}
}

} // namespace brave_wallet
7 changes: 7 additions & 0 deletions components/brave_wallet/browser/brave_wallet_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,13 @@ void RemoveCustomNetwork(PrefService* prefs,
});
}

std::string GetCurrentFilecoinNetworkPrefix(PrefService* prefs) {
return (GetCurrentChainId(prefs, mojom::CoinType::FIL) ==
brave_wallet::mojom::kFilecoinMainnet)
? mojom::kFilecoinMainnet
: mojom::kFilecoinTestnet;
}

std::string GetCurrentChainId(PrefService* prefs, mojom::CoinType coin) {
const base::Value* selected_networks =
prefs->GetDictionary(kBraveWalletSelectedNetworks);
Expand Down
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/brave_wallet_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ mojom::NetworkInfoPtr GetChain(PrefService* prefs,
// Get the current chain ID for coin from kBraveWalletSelectedNetworks pref.
std::string GetCurrentChainId(PrefService* prefs, mojom::CoinType coin);

std::string GetCurrentFilecoinNetworkPrefix(PrefService* prefs);

// Returns the first URL to use that:
// 1. Has no variables in it like ${INFURA_API_KEY}
// 2. Is HTTP or HTTPS
Expand Down
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/fil_address_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ TEST(FilAddressUnitTest, From) {
EXPECT_EQ(fil_address.EncodeAsString(), address);
EXPECT_FALSE(fil_address.IsEmpty());
EXPECT_EQ(fil_address.protocol(), mojom::FilecoinAddressProtocol::SECP256K1);
EXPECT_EQ(fil_address.network(), mojom::kFilecoinTestnet);

// Valid secp256k1 address Mainnet
address = "f1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q";
fil_address = FilAddress::FromAddress(address);
EXPECT_EQ(fil_address.EncodeAsString(), address);
EXPECT_FALSE(fil_address.IsEmpty());
EXPECT_EQ(fil_address.protocol(), mojom::FilecoinAddressProtocol::SECP256K1);
EXPECT_EQ(fil_address.network(), mojom::kFilecoinMainnet);

// Valid BLS address Testnet
address =
Expand Down
26 changes: 23 additions & 3 deletions components/brave_wallet/browser/filecoin_keyring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ bool GetBLSPublicKey(const std::vector<uint8_t>& private_key,
}
} // namespace

FilecoinKeyring::FilecoinKeyring() = default;
FilecoinKeyring::FilecoinKeyring(const std::string& chain_id) {
network_prefix_ = (chain_id == brave_wallet::mojom::kFilecoinMainnet)
? mojom::kFilecoinMainnet
: mojom::kFilecoinTestnet;
}

FilecoinKeyring::~FilecoinKeyring() = default;

// static
Expand Down Expand Up @@ -131,14 +136,29 @@ void FilecoinKeyring::RestoreFilecoinAccount(
}
}

void FilecoinKeyring::ChainChangedEvent(const std::string& chain_id,
mojom::CoinType coin) {
if (coin != mojom::CoinType::FIL) {
return;
}
auto* network = (chain_id == brave_wallet::mojom::kFilecoinMainnet)
darkdh marked this conversation as resolved.
Show resolved Hide resolved
? mojom::kFilecoinMainnet
: mojom::kFilecoinTestnet;

if (network_prefix_ != network) {
accounts_.clear();
network_prefix_ = *network;
}
}

std::string FilecoinKeyring::GetAddressInternal(HDKeyBase* hd_key_base) const {
if (!hd_key_base)
return std::string();
HDKey* hd_key = static_cast<HDKey*>(hd_key_base);
// TODO(spylogsster): Get network from settings.

return FilAddress::FromUncompressedPublicKey(
hd_key->GetUncompressedPublicKey(),
mojom::FilecoinAddressProtocol::SECP256K1, mojom::kFilecoinTestnet)
mojom::FilecoinAddressProtocol::SECP256K1, network_prefix_)
.EncodeAsString();
}

Expand Down
19 changes: 17 additions & 2 deletions components/brave_wallet/browser/filecoin_keyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
#include "brave/components/brave_wallet/browser/internal/hd_key.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "brave/components/brave_wallet/common/brave_wallet_types.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace brave_wallet {

class FilTransaction;

class FilecoinKeyring : public HDKeyring {
class FilecoinKeyring : public HDKeyring, public mojom::JsonRpcServiceObserver {
public:
FilecoinKeyring();
explicit FilecoinKeyring(const std::string& chain_id);
~FilecoinKeyring() override;
FilecoinKeyring(const FilecoinKeyring&) = delete;
FilecoinKeyring& operator=(const FilecoinKeyring&) = delete;
Expand All @@ -35,10 +37,23 @@ class FilecoinKeyring : public HDKeyring {
mojom::FilecoinAddressProtocol protocol);
void RestoreFilecoinAccount(const std::vector<uint8_t>& input_key,
const std::string& address);
mojo::PendingRemote<mojom::JsonRpcServiceObserver> GetReceiver() {
return rpc_observer_receiver_.BindNewPipeAndPassRemote();
}
// mojom::JsonRpcServiceObserver
void ChainChangedEvent(const std::string& chain_id,
mojom::CoinType coin) override;
void OnAddEthereumChainRequestCompleted(const std::string& chain_id,
const std::string& error) override {}
void OnIsEip1559Changed(const std::string& chain_id,
bool is_eip1559) override {}

absl::optional<std::string> SignTransaction(const FilTransaction* tx);

private:
std::string GetAddressInternal(HDKeyBase* hd_key_base) const override;
std::string network_prefix_;
mojo::Receiver<mojom::JsonRpcServiceObserver> rpc_observer_receiver_{this};
};

} // namespace brave_wallet
Expand Down
Loading