[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:
Christian Mazakas
2026-04-02 08:54:50 -07:00
committed by GitHub
parent 78c4993d19
commit d4ab9239f0
6 changed files with 180 additions and 78 deletions
@@ -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());