mirror of
https://github.com/feather-wallet/feather.git
synced 2025-01-10 12:54:46 +00:00
106 lines
3.4 KiB
C++
106 lines
3.4 KiB
C++
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
// SPDX-FileCopyrightText: 2020-2022 The Monero Project
|
||
|
|
||
|
#include "Seed.h"
|
||
|
|
||
|
Seed::Seed(Type type, NetworkType::Type networkType, QString language)
|
||
|
: type(type), networkType(networkType), language(std::move(language))
|
||
|
{
|
||
|
// We only support the creation of Tevador-style seeds for now.
|
||
|
if (this->type != Type::TEVADOR) {
|
||
|
this->errorString = "Unsupported seed type";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// We only support the creation of English language seeds for now.
|
||
|
if (this->language != "English") {
|
||
|
this->errorString = "Unsupported seed language";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->time = std::time(nullptr);
|
||
|
|
||
|
try {
|
||
|
monero_seed seed(this->time, constants::coinName);
|
||
|
|
||
|
std::stringstream buffer;
|
||
|
buffer << seed;
|
||
|
this->mnemonic = QString::fromStdString(buffer.str()).split(" ");
|
||
|
|
||
|
buffer.str(std::string());
|
||
|
buffer << seed.key();
|
||
|
this->spendKey = QString::fromStdString(buffer.str());
|
||
|
}
|
||
|
catch (const std::exception &e) {
|
||
|
this->errorString = QString::fromStdString(e.what());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Basic check against seed library implementation issues
|
||
|
if (m_insecureSeeds.contains(this->spendKey)) {
|
||
|
this->errorString = "Insecure spendkey";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->setRestoreHeight();
|
||
|
}
|
||
|
|
||
|
Seed::Seed(Type type, QStringList mnemonic, NetworkType::Type networkType)
|
||
|
: type(type), mnemonic(std::move(mnemonic)), networkType(networkType)
|
||
|
{
|
||
|
if (m_seedLength[this->type] != this->mnemonic.length()) {
|
||
|
this->errorString = "Invalid seed length";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (this->type == Type::POLYSEED) {
|
||
|
this->errorString = "Unsupported seed type";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (this->type == Type::TEVADOR) {
|
||
|
try {
|
||
|
monero_seed seed(this->mnemonic.join(" ").toStdString(), constants::coinName);
|
||
|
|
||
|
this->time = seed.date();
|
||
|
this->setRestoreHeight();
|
||
|
|
||
|
std::stringstream buffer;
|
||
|
buffer << seed.key();
|
||
|
this->spendKey = QString::fromStdString(buffer.str());
|
||
|
|
||
|
// Tevador style seeds have built-in error correction
|
||
|
// Any word can be replaced with 'xxxx' to recover the original word
|
||
|
this->correction = QString::fromStdString(seed.correction());
|
||
|
if (!this->correction.isEmpty()) {
|
||
|
buffer.str(std::string());
|
||
|
buffer << seed;
|
||
|
int index = this->mnemonic.indexOf("xxxx");
|
||
|
this->mnemonic.replace(index, this->correction);
|
||
|
}
|
||
|
}
|
||
|
catch (const std::exception &e) {
|
||
|
this->errorString = e.what();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Seed::setRestoreHeight(int height) {
|
||
|
auto now = std::time(nullptr);
|
||
|
auto nowClearance = 3600 * 24;
|
||
|
auto currentBlockHeight = appData()->restoreHeights[this->networkType]->dateToHeight(now - nowClearance);
|
||
|
if (height >= currentBlockHeight + nowClearance) {
|
||
|
qWarning() << "unrealistic restore height detected, setting to current blockheight instead: " << currentBlockHeight;
|
||
|
this->restoreHeight = currentBlockHeight;
|
||
|
} else {
|
||
|
this->restoreHeight = height;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Seed::setRestoreHeight() {
|
||
|
// Ignore the embedded restore date, new wallets should sync from the current block height.
|
||
|
this->restoreHeight = appData()->restoreHeights[networkType]->dateToHeight(this->time);
|
||
|
}
|
||
|
|
||
|
Seed::Seed() = default;
|