[CodeHealth] [Polkadot] [Wallet] update PolkadotKeyring to eschew upserting keypairs (#35006)
Resolves brave/brave-browser#53959 This PR alters the behavior of the PolkadotKeyring to no longer insert keypairs on every function call if they don't exist in the secondary_keys_ container. To this end, many of the methods have been updated to return std::optional<>-wrapped values. This aligns the PolkadotKeyring with the other existing Keyrings we have in Wallet.
This commit is contained in:
@@ -3178,8 +3178,7 @@ KeyringService::GetPolkadotPubKey(const mojom::AccountIdPtr& account_id) {
|
||||
CHECK(account_id);
|
||||
|
||||
if (auto* keyring = GetKeyring<PolkadotKeyring>(account_id->keyring_id)) {
|
||||
auto key = keyring->GetPublicKey(account_id->account_index);
|
||||
return {key};
|
||||
return keyring->GetPublicKey(account_id->account_index);
|
||||
}
|
||||
if (auto* keyring =
|
||||
GetKeyring<PolkadotImportKeyring>(account_id->keyring_id)) {
|
||||
|
||||
@@ -62,11 +62,13 @@ TEST(PolkadotImportKeyringTest, AddAccountAndGetAddress) {
|
||||
auto import_keyring =
|
||||
MakePolkadotImportKeyring(mojom::KeyringId::kPolkadotImport);
|
||||
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(
|
||||
import_keyring.AddAccount(0, hd_keyring.GetPkcs8KeyForTesting(0)));
|
||||
EXPECT_EQ(import_keyring.GetAccountAddress(0).value(), kMainnetAddress0);
|
||||
EXPECT_EQ(import_keyring.GetAddress(0, 0u).value(), kMainnetAddress0);
|
||||
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(1));
|
||||
ASSERT_TRUE(
|
||||
import_keyring.AddAccount(1, hd_keyring.GetPkcs8KeyForTesting(1)));
|
||||
EXPECT_EQ(import_keyring.GetAccountAddress(1).value(), kMainnetAddress1);
|
||||
@@ -79,11 +81,13 @@ TEST(PolkadotImportKeyringTest, AddAccountAndGetAddress) {
|
||||
auto import_keyring =
|
||||
MakePolkadotImportKeyring(mojom::KeyringId::kPolkadotImportTestnet);
|
||||
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(
|
||||
import_keyring.AddAccount(0, hd_keyring.GetPkcs8KeyForTesting(0)));
|
||||
EXPECT_EQ(import_keyring.GetAccountAddress(0).value(), kTestnetAddress0);
|
||||
EXPECT_EQ(import_keyring.GetAddress(0, 42u).value(), kTestnetAddress0);
|
||||
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(1));
|
||||
EXPECT_TRUE(
|
||||
import_keyring.AddAccount(1, hd_keyring.GetPkcs8KeyForTesting(1)));
|
||||
EXPECT_EQ(import_keyring.GetAccountAddress(1).value(), kTestnetAddress1);
|
||||
@@ -93,6 +97,7 @@ TEST(PolkadotImportKeyringTest, AddAccountAndGetAddress) {
|
||||
|
||||
TEST(PolkadotImportKeyringTest, AddAccountFails) {
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
auto pkcs8 = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
|
||||
auto keyring = MakePolkadotImportKeyring(mojom::KeyringId::kPolkadotImport);
|
||||
@@ -105,6 +110,7 @@ TEST(PolkadotImportKeyringTest, AddAccountFails) {
|
||||
|
||||
TEST(PolkadotImportKeyringTest, RemoveAccount) {
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
auto pkcs8 = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
|
||||
auto keyring = MakePolkadotImportKeyring(mojom::KeyringId::kPolkadotImport);
|
||||
@@ -119,6 +125,7 @@ TEST(PolkadotImportKeyringTest, RemoveAccount) {
|
||||
|
||||
TEST(PolkadotImportKeyringTest, GetPublicKey) {
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
auto pkcs8 = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
|
||||
auto import_keyring =
|
||||
@@ -135,6 +142,7 @@ TEST(PolkadotImportKeyringTest, GetPublicKey) {
|
||||
|
||||
TEST(PolkadotImportKeyringTest, SignMessage) {
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
auto pkcs8 = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
|
||||
auto import_keyring =
|
||||
@@ -151,13 +159,14 @@ TEST(PolkadotImportKeyringTest, SignMessage) {
|
||||
|
||||
TEST(PolkadotImportKeyringTest, EncodePrivateKeyForExportRoundtrip) {
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
auto pkcs8 = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
|
||||
auto import_keyring =
|
||||
MakePolkadotImportKeyring(mojom::KeyringId::kPolkadotImport);
|
||||
ASSERT_TRUE(import_keyring.AddAccount(0, pkcs8));
|
||||
|
||||
constexpr char kPassword[] = "export_password_123";
|
||||
static constexpr char kPassword[] = "export_password_123";
|
||||
auto encoded = import_keyring.EncodePrivateKeyForExport(0, kPassword);
|
||||
ASSERT_TRUE(encoded.has_value());
|
||||
|
||||
@@ -187,6 +196,10 @@ TEST(PolkadotImportKeyringTest, AddAccount_OfacSanctionedAddress) {
|
||||
CHECK(registry);
|
||||
|
||||
auto hd_keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(hd_keyring.AddNewHDAccount(1));
|
||||
|
||||
auto pkcs8_key = hd_keyring.GetPkcs8KeyForTesting(0);
|
||||
auto pkcs8_key1 = hd_keyring.GetPkcs8KeyForTesting(1);
|
||||
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
|
||||
#include "brave/components/brave_wallet/browser/polkadot/polkadot_keyring.h"
|
||||
|
||||
#include "base/base64.h"
|
||||
#include "base/check_is_test.h"
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/containers/span_writer.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "brave/components/brave_wallet/browser/internal/hd_key.h"
|
||||
#include "brave/components/brave_wallet/browser/polkadot/polkadot_utils.h"
|
||||
#include "brave/components/brave_wallet/browser/scrypt_utils.h"
|
||||
#include "brave/components/brave_wallet/common/common_utils.h"
|
||||
@@ -59,60 +56,88 @@ bool PolkadotKeyring::IsTestnet() const {
|
||||
return keyring_id_ == mojom::KeyringId::kPolkadotTestnet;
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSr25519PublicKeySize> PolkadotKeyring::GetPublicKey(
|
||||
uint32_t account_index) {
|
||||
auto const& keypair = EnsureKeyPair(account_index);
|
||||
return keypair.GetPublicKey();
|
||||
std::optional<std::array<uint8_t, kSr25519PublicKeySize>>
|
||||
PolkadotKeyring::GetPublicKey(uint32_t account_index) {
|
||||
const auto* keypair = GetKeypair(account_index);
|
||||
if (!keypair) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return keypair->GetPublicKey();
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSr25519Pkcs8Size>
|
||||
PolkadotKeyring::GetPkcs8KeyForTesting( // IN-TEST
|
||||
uint32_t account_index) {
|
||||
CHECK_IS_TEST();
|
||||
return EnsureKeyPair(account_index).GetExportKeyPkcs8();
|
||||
const auto* keypair = GetKeypair(account_index);
|
||||
// This is a test, so we can require correct inputs unconditionally.
|
||||
CHECK(keypair);
|
||||
return keypair->GetExportKeyPkcs8();
|
||||
}
|
||||
|
||||
std::string PolkadotKeyring::GetAddress(uint32_t account_index,
|
||||
uint16_t prefix) {
|
||||
auto& keypair = EnsureKeyPair(account_index);
|
||||
std::optional<std::string> PolkadotKeyring::GetAddress(uint32_t account_index,
|
||||
uint16_t prefix) {
|
||||
auto* keypair = GetKeypair(account_index);
|
||||
if (!keypair) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Ss58Address addr;
|
||||
addr.prefix = prefix;
|
||||
addr.public_key = keypair.GetPublicKey();
|
||||
return addr.Encode().value();
|
||||
addr.public_key = keypair->GetPublicKey();
|
||||
return addr.Encode();
|
||||
}
|
||||
|
||||
std::array<uint8_t, kSr25519SignatureSize> PolkadotKeyring::SignMessage(
|
||||
base::span<const uint8_t> message,
|
||||
uint32_t account_index) {
|
||||
auto const& keypair = EnsureKeyPair(account_index);
|
||||
return keypair.SignMessage(message);
|
||||
std::optional<std::array<uint8_t, kSr25519SignatureSize>>
|
||||
PolkadotKeyring::SignMessage(base::span<const uint8_t> message,
|
||||
uint32_t account_index) {
|
||||
auto const* keypair = GetKeypair(account_index);
|
||||
if (!keypair) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return keypair->SignMessage(message);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool PolkadotKeyring::VerifyMessage(
|
||||
base::span<const uint8_t, kSr25519SignatureSize> signature,
|
||||
base::span<const uint8_t> message,
|
||||
uint32_t account_index) {
|
||||
auto const& keypair = EnsureKeyPair(account_index);
|
||||
return keypair.VerifyMessage(signature, message);
|
||||
}
|
||||
|
||||
HDKeySr25519& PolkadotKeyring::EnsureKeyPair(uint32_t account_index) {
|
||||
auto pos = secondary_keys_.find(account_index);
|
||||
if (pos == secondary_keys_.end()) {
|
||||
auto [it, inserted] = secondary_keys_.emplace(
|
||||
account_index,
|
||||
root_account_key_.DeriveHard(base::byte_span_from_ref(account_index)));
|
||||
pos = it;
|
||||
const auto* keypair = GetKeypair(account_index);
|
||||
if (!keypair) {
|
||||
return false;
|
||||
}
|
||||
return pos->second;
|
||||
|
||||
return keypair->VerifyMessage(signature, message);
|
||||
}
|
||||
|
||||
std::optional<std::string> PolkadotKeyring::AddNewHDAccount(uint32_t index) {
|
||||
auto addr = GetAddress(index, IsTestnet() ? kWestendPrefix : kPolkadotPrefix);
|
||||
if (!is_address_allowed_.Run(addr)) {
|
||||
HDKeySr25519* PolkadotKeyring::GetKeypair(uint32_t account_index) {
|
||||
return base::FindOrNull(secondary_keys_, account_index);
|
||||
}
|
||||
|
||||
std::optional<std::string> PolkadotKeyring::AddNewHDAccount(
|
||||
uint32_t account_index) {
|
||||
if (secondary_keys_.contains(account_index)) {
|
||||
// Account already exists.
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto keypair =
|
||||
root_account_key_.DeriveHard(base::byte_span_from_ref(account_index));
|
||||
|
||||
Ss58Address ss58_addr;
|
||||
ss58_addr.prefix = IsTestnet() ? kWestendPrefix : kPolkadotPrefix;
|
||||
base::span(ss58_addr.public_key)
|
||||
.copy_from_nonoverlapping(keypair.GetPublicKey());
|
||||
|
||||
const auto addr = ss58_addr.Encode();
|
||||
if (!addr || !is_address_allowed_.Run(*addr)) {
|
||||
// We either failed to ss58-encode the public key or it was present in our
|
||||
// block-list. Either way, reject keypair creation.
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
secondary_keys_.emplace(account_index, std::move(keypair));
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -134,8 +159,13 @@ void PolkadotKeyring::SetSignatureRngForTesting() {
|
||||
std::optional<std::string> PolkadotKeyring::EncodePrivateKeyForExport(
|
||||
uint32_t account_index,
|
||||
std::string_view password) {
|
||||
auto* keypair = GetKeypair(account_index);
|
||||
if (!keypair) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return PolkadotKeyring::EncodePrivateKeyForExport(
|
||||
EnsureKeyPair(account_index), password, rand_salt_bytes_for_testing_,
|
||||
*keypair, password, rand_salt_bytes_for_testing_,
|
||||
rand_nonce_bytes_for_testing_);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,20 +29,25 @@ class PolkadotKeyring {
|
||||
// which is the SS58-encoded public key for this particular derivation. Many
|
||||
// parachains use their own ss58 prefix, which the caller can supply.
|
||||
// Unified addressing uses 0 as the default prefix.
|
||||
std::string GetAddress(uint32_t account_index, uint16_t prefix);
|
||||
// Returns nullopt if account_index has not been added via AddNewHDAccount().
|
||||
std::optional<std::string> GetAddress(uint32_t account_index,
|
||||
uint16_t prefix);
|
||||
|
||||
// Get the public key associated with the account denoted by
|
||||
// `//<network>//<account_index>`.
|
||||
std::array<uint8_t, kSr25519PublicKeySize> GetPublicKey(
|
||||
// Returns nullopt if account_index has not been added via AddNewHDAccount().
|
||||
std::optional<std::array<uint8_t, kSr25519PublicKeySize>> GetPublicKey(
|
||||
uint32_t account_index);
|
||||
|
||||
// Use the derived account `account_index` to sign the provided message.
|
||||
std::array<uint8_t, kSr25519SignatureSize> SignMessage(
|
||||
// Returns nullopt if account_index has not been added via AddNewHDAccount().
|
||||
std::optional<std::array<uint8_t, kSr25519SignatureSize>> SignMessage(
|
||||
base::span<const uint8_t> message,
|
||||
uint32_t account_index);
|
||||
|
||||
// Verify that the provided signature is associated with the given message,
|
||||
// for the account denoted by `account_index`.
|
||||
// Returns false if account_index has not been added via AddNewHDAccount().
|
||||
[[nodiscard]] bool VerifyMessage(
|
||||
base::span<const uint8_t, kSr25519SignatureSize> signature,
|
||||
base::span<const uint8_t> message,
|
||||
@@ -54,11 +59,12 @@ class PolkadotKeyring {
|
||||
|
||||
mojom::KeyringId keyring_id() const { return keyring_id_; }
|
||||
|
||||
std::optional<std::string> AddNewHDAccount(uint32_t index);
|
||||
std::optional<std::string> AddNewHDAccount(uint32_t account_index);
|
||||
|
||||
// Encodes the private key for export in JSON format.
|
||||
// Returns a JSON string with encoded key, encoding metadata, and address.
|
||||
// The seed is encrypted using xsalsa20-poly1305 with a password-derived key.
|
||||
// Returns nullopt if account_index has not been added via AddNewHDAccount().
|
||||
std::optional<std::string> EncodePrivateKeyForExport(
|
||||
uint32_t account_index,
|
||||
std::string_view password);
|
||||
@@ -86,7 +92,7 @@ class PolkadotKeyring {
|
||||
void SetSignatureRngForTesting();
|
||||
|
||||
private:
|
||||
HDKeySr25519& EnsureKeyPair(uint32_t account_index);
|
||||
HDKeySr25519* GetKeypair(uint32_t account_index);
|
||||
|
||||
HDKeySr25519 root_account_key_;
|
||||
mojom::KeyringId keyring_id_;
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/test/bind.h"
|
||||
@@ -120,6 +118,8 @@ TEST(PolkadotKeyring, GetAddress) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
EXPECT_EQ(keyring.GetAddress(0, 0u),
|
||||
"14YLzDFZTwnkcJkFij4Km7g5LdkLqKHy47xYGPN6HsLJpfnb");
|
||||
@@ -140,6 +140,8 @@ TEST(PolkadotKeyring, GetAddress) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotTestnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
EXPECT_EQ(keyring.GetAddress(0, 42u),
|
||||
"5HGiBcFgEBMgT6GEuo9SA98sBnGgwHtPKDXiUukT6aqCrKEx");
|
||||
@@ -225,12 +227,14 @@ TEST(PolkadotKeyring, GetPublicKey) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto pubkey = keyring.GetPublicKey(0);
|
||||
ASSERT_TRUE(pubkey.has_value());
|
||||
|
||||
constexpr char const* kPublicKey =
|
||||
"9C9C968EBB31417A36BEC0908ECD9EB6E847B44821E521DDA9ADD8C418EF7C30";
|
||||
EXPECT_EQ(base::HexEncode(pubkey), kPublicKey);
|
||||
EXPECT_EQ(base::HexEncode(*pubkey), kPublicKey);
|
||||
}
|
||||
|
||||
// Testnet.
|
||||
@@ -242,12 +246,14 @@ TEST(PolkadotKeyring, GetPublicKey) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotTestnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto pubkey = keyring.GetPublicKey(0);
|
||||
ASSERT_TRUE(pubkey.has_value());
|
||||
|
||||
constexpr char const* kPublicKey =
|
||||
"E655361D12F3CCCA5F128187CF3F5EEA052BE722746E392C8B498D0D18723470";
|
||||
EXPECT_EQ(base::HexEncode(pubkey), kPublicKey);
|
||||
EXPECT_EQ(base::HexEncode(*pubkey), kPublicKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,12 +266,19 @@ TEST(PolkadotKeyring, SignAndVerifyMessage) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
auto signature = keyring.SignMessage(message, 0);
|
||||
auto verified = keyring.VerifyMessage(signature, message, 0);
|
||||
ASSERT_TRUE(signature);
|
||||
|
||||
auto verified = keyring.VerifyMessage(*signature, message, 0);
|
||||
EXPECT_TRUE(verified);
|
||||
|
||||
verified = keyring.VerifyMessage(signature, message, 1);
|
||||
verified = keyring.VerifyMessage(*signature, message, 1);
|
||||
EXPECT_FALSE(verified);
|
||||
|
||||
verified = keyring.VerifyMessage(*signature, message, 1234);
|
||||
EXPECT_FALSE(verified);
|
||||
}
|
||||
|
||||
@@ -275,12 +288,19 @@ TEST(PolkadotKeyring, SignAndVerifyMessage) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotTestnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
auto signature = keyring.SignMessage(message, 0);
|
||||
auto verified = keyring.VerifyMessage(signature, message, 0);
|
||||
ASSERT_TRUE(signature);
|
||||
|
||||
auto verified = keyring.VerifyMessage(*signature, message, 0);
|
||||
EXPECT_TRUE(verified);
|
||||
|
||||
verified = keyring.VerifyMessage(signature, message, 1);
|
||||
verified = keyring.VerifyMessage(*signature, message, 1);
|
||||
EXPECT_FALSE(verified);
|
||||
|
||||
verified = keyring.VerifyMessage(*signature, message, 1234);
|
||||
EXPECT_FALSE(verified);
|
||||
}
|
||||
}
|
||||
@@ -297,6 +317,8 @@ TEST(PolkadotKeyring, VerifyMessage) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotTestnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
std::string signature_hex =
|
||||
"4C62835B705663D221F45A70E493C2B48FEEE5B541D3071727139A44A71F1E46E5F536"
|
||||
@@ -339,6 +361,8 @@ TEST(PolkadotKeyring, VerifyMessage) {
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
// Test with first mainnet signature vector
|
||||
std::string signature_hex =
|
||||
@@ -381,9 +405,12 @@ TEST(PolkadotKeyring, AddNewHDAccount_OfacSanctionedAddress) {
|
||||
CHECK(registry);
|
||||
|
||||
auto seed = bip39::MnemonicToEntropyToSeed(kDevPhrase).value();
|
||||
PolkadotKeyring keyring(base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindRepeating(IsAddressAllowed));
|
||||
PolkadotKeyring keyring(
|
||||
base::span(seed).first<kPolkadotSeedSize>(),
|
||||
mojom::KeyringId::kPolkadotMainnet,
|
||||
base::BindLambdaForTesting([=](const std::string& address) {
|
||||
return !registry->IsOfacAddress(address);
|
||||
}));
|
||||
|
||||
// Add an account to get its address.
|
||||
auto address = keyring.AddNewHDAccount(0);
|
||||
@@ -416,6 +443,10 @@ TEST(PolkadotKeyring, AddNewHDAccount_OfacSanctionedAddress) {
|
||||
|
||||
// Clear OFAC list
|
||||
registry->UpdateOfacAddressesList({});
|
||||
|
||||
// Prove that we didn't leave any remnant phantom keypairs.
|
||||
result2 = keyring2.AddNewHDAccount(0);
|
||||
EXPECT_TRUE(result2);
|
||||
}
|
||||
|
||||
} // namespace brave_wallet
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "brave/components/brave_wallet/browser/internal/hd_key_sr25519.h"
|
||||
#include "brave/components/brave_wallet/browser/polkadot/polkadot_keyring.h"
|
||||
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
|
||||
#include "brave/components/brave_wallet/common/brave_wallet_constants.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace brave_wallet {
|
||||
@@ -125,9 +124,12 @@ TEST(PolkadotUtils, Uint128MojomConversions) {
|
||||
// format).
|
||||
|
||||
TEST(PolkadotUtils, EncodePrivateKeyForExport) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
std::array<uint8_t, kScryptSaltSize> salt_bytes;
|
||||
salt_bytes.fill(1);
|
||||
std::array<uint8_t, kSecretboxNonceSize> nonce_bytes;
|
||||
@@ -137,8 +139,10 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport) {
|
||||
// Test account 0
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(0);
|
||||
std::string address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
auto private_key_0 = EncodePrivateKeyForExport(pkcs8, address, kPassword,
|
||||
auto address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
auto private_key_0 = EncodePrivateKeyForExport(pkcs8, *address, kPassword,
|
||||
salt_bytes, nonce_bytes);
|
||||
auto json_value =
|
||||
base::test::ParseJsonDict(*private_key_0, base::JSON_PARSE_RFC);
|
||||
@@ -153,8 +157,10 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport) {
|
||||
// Test account 1
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(1);
|
||||
std::string address = keyring.GetAddress(1, kSubstratePrefix);
|
||||
auto private_key_1 = EncodePrivateKeyForExport(pkcs8, address, kPassword,
|
||||
auto address = keyring.GetAddress(1, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
auto private_key_1 = EncodePrivateKeyForExport(pkcs8, *address, kPassword,
|
||||
salt_bytes, nonce_bytes);
|
||||
auto json_value_1 =
|
||||
base::test::ParseJsonDict(*private_key_1, base::JSON_PARSE_RFC);
|
||||
@@ -169,16 +175,21 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport) {
|
||||
// Empty password (should fail)
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(0);
|
||||
std::string address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
EXPECT_FALSE(
|
||||
EncodePrivateKeyForExport(pkcs8, address, "", salt_bytes, nonce_bytes));
|
||||
auto address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
EXPECT_FALSE(EncodePrivateKeyForExport(pkcs8, *address, "", salt_bytes,
|
||||
nonce_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, EncodePrivateKeyForExport_Testnet) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotTestnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
std::array<uint8_t, kScryptSaltSize> salt_bytes;
|
||||
salt_bytes.fill(1);
|
||||
std::array<uint8_t, kSecretboxNonceSize> nonce_bytes;
|
||||
@@ -188,8 +199,10 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport_Testnet) {
|
||||
// Test account 0
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(0);
|
||||
std::string address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
auto private_key_0 = EncodePrivateKeyForExport(pkcs8, address, kPassword,
|
||||
auto address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
auto private_key_0 = EncodePrivateKeyForExport(pkcs8, *address, kPassword,
|
||||
salt_bytes, nonce_bytes);
|
||||
auto json_value =
|
||||
base::test::ParseJsonDict(*private_key_0, base::JSON_PARSE_RFC);
|
||||
@@ -204,8 +217,10 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport_Testnet) {
|
||||
// Test account 1
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(1);
|
||||
std::string address = keyring.GetAddress(1, kSubstratePrefix);
|
||||
auto private_key_1 = EncodePrivateKeyForExport(pkcs8, address, kPassword,
|
||||
auto address = keyring.GetAddress(1, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
auto private_key_1 = EncodePrivateKeyForExport(pkcs8, *address, kPassword,
|
||||
salt_bytes, nonce_bytes);
|
||||
auto json_value_1 =
|
||||
base::test::ParseJsonDict(*private_key_1, base::JSON_PARSE_RFC);
|
||||
@@ -220,16 +235,20 @@ TEST(PolkadotUtils, EncodePrivateKeyForExport_Testnet) {
|
||||
// Empty password (should fail)
|
||||
{
|
||||
auto pkcs8 = keyring.GetPkcs8KeyForTesting(0);
|
||||
std::string address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
EXPECT_FALSE(
|
||||
EncodePrivateKeyForExport(pkcs8, address, "", salt_bytes, nonce_bytes));
|
||||
auto address = keyring.GetAddress(0, kSubstratePrefix);
|
||||
ASSERT_TRUE(address.has_value());
|
||||
|
||||
EXPECT_FALSE(EncodePrivateKeyForExport(pkcs8, *address, "", salt_bytes,
|
||||
nonce_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_Roundtrip) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(1));
|
||||
|
||||
// Account 0: encode then decode
|
||||
{
|
||||
@@ -267,10 +286,11 @@ TEST(PolkadotUtils, DecodePrivateKeyFromExport_Roundtrip) {
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_WrongPassword) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
const std::string kWrongPassword = "wrong_password";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
static constexpr char kWrongPassword[] = "wrong_password";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto encoded_json = keyring.EncodePrivateKeyForExport(0, kPassword);
|
||||
ASSERT_TRUE(encoded_json.has_value());
|
||||
@@ -280,9 +300,10 @@ TEST(PolkadotUtils, DecodePrivateKeyFromExport_WrongPassword) {
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_EmptyPassword) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotMainnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto encoded_json = keyring.EncodePrivateKeyForExport(0, kPassword);
|
||||
ASSERT_TRUE(encoded_json.has_value());
|
||||
@@ -291,7 +312,7 @@ TEST(PolkadotUtils, DecodePrivateKeyFromExport_EmptyPassword) {
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_InvalidJSON) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
EXPECT_FALSE(
|
||||
DecodePrivateKeyFromExport("{ invalid json }", kPassword).has_value());
|
||||
@@ -303,9 +324,10 @@ TEST(PolkadotUtils, DecodePrivateKeyFromExport_InvalidJSON) {
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_Testnet) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotTestnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto encoded_json = keyring.EncodePrivateKeyForExport(0, kPassword);
|
||||
ASSERT_TRUE(encoded_json.has_value());
|
||||
@@ -317,9 +339,10 @@ TEST(PolkadotUtils, DecodePrivateKeyFromExport_Testnet) {
|
||||
}
|
||||
|
||||
TEST(PolkadotUtils, DecodePrivateKeyFromExport_MissingParts) {
|
||||
const std::string kPassword = "test_password_123";
|
||||
static constexpr char kPassword[] = "test_password_123";
|
||||
|
||||
auto keyring = MakePolkadotKeyring(mojom::KeyringId::kPolkadotTestnet);
|
||||
ASSERT_TRUE(keyring.AddNewHDAccount(0));
|
||||
|
||||
auto valid_json = keyring.EncodePrivateKeyForExport(0, kPassword);
|
||||
ASSERT_TRUE(valid_json.has_value());
|
||||
|
||||
Reference in New Issue
Block a user