mirror of
https://github.com/feather-wallet/feather.git
synced 2024-11-16 17:27:38 +00:00
Seed: refactor
This commit is contained in:
parent
f8bc335720
commit
c6264ed3a0
13 changed files with 869 additions and 695 deletions
|
@ -204,7 +204,7 @@ bool WindowManager::autoOpenWallet() {
|
|||
|
||||
// ######################## WALLET CREATION ########################
|
||||
|
||||
void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage,
|
||||
void WindowManager::tryCreateWallet(Seed seed, const QString &path, const QString &password, const QString &seedLanguage,
|
||||
const QString &seedOffset) {
|
||||
if(Utils::fileExists(path)) {
|
||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||
|
@ -218,12 +218,12 @@ void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const
|
|||
}
|
||||
|
||||
Wallet *wallet = nullptr;
|
||||
if (seed.seedType == SeedType::TEVADOR) {
|
||||
if (seed.type == Seed::Type::TEVADOR) {
|
||||
wallet = m_walletManager->createDeterministicWalletFromSpendKey(path, password, seed.language, constants::networkType, seed.spendKey, seed.restoreHeight, constants::kdfRounds, seedOffset);
|
||||
wallet->setCacheAttribute("feather.seed", seed.mnemonic.join(" "));
|
||||
wallet->setCacheAttribute("feather.seedoffset", seedOffset);
|
||||
}
|
||||
if (seed.seedType == SeedType::MONERO) {
|
||||
if (seed.type == Seed::Type::MONERO) {
|
||||
wallet = m_walletManager->recoveryWallet(path, password, seed.mnemonic.join(" "), seedOffset, constants::networkType, seed.restoreHeight, constants::kdfRounds);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ private slots:
|
|||
void onWalletPassphraseNeeded(bool on_device);
|
||||
|
||||
private:
|
||||
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset);
|
||||
void tryCreateWallet(Seed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset);
|
||||
void tryCreateWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||
void tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "utils/os/whonix.h"
|
||||
#include "utils/networking.h"
|
||||
#include "utils/FeatherSeed.h"
|
||||
#include "utils/Seed.h"
|
||||
#include "utils/daemonrpc.h"
|
||||
#include "utils/RestoreHeightLookup.h"
|
||||
#include "utils/nodes.h"
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2022 The Monero Project
|
||||
|
||||
#ifndef FEATHER_FEATHERSEED_H
|
||||
#define FEATHER_FEATHERSEED_H
|
||||
|
||||
#include "libwalletqt/WalletManager.h"
|
||||
#include "libwalletqt/Wallet.h"
|
||||
#include "utils/AppData.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "RestoreHeightLookup.h"
|
||||
|
||||
enum SeedType {
|
||||
MONERO = 0, // 25 word seeds
|
||||
TEVADOR // 14 word seeds
|
||||
};
|
||||
|
||||
struct FeatherSeed {
|
||||
// TODO: this is spaghetti, needs refactor
|
||||
|
||||
NetworkType::Type netType;
|
||||
|
||||
QString coin;
|
||||
QString language;
|
||||
SeedType seedType;
|
||||
|
||||
QStringList mnemonic;
|
||||
QString spendKey;
|
||||
QString correction;
|
||||
|
||||
time_t time;
|
||||
int restoreHeight = 0;
|
||||
|
||||
QString errorString;
|
||||
|
||||
explicit FeatherSeed(NetworkType::Type networkType = NetworkType::MAINNET,
|
||||
const QString &coin = "monero",
|
||||
const QString &language = "English",
|
||||
const QStringList &mnemonic = {})
|
||||
: netType(networkType), coin(coin), language(language), mnemonic(mnemonic)
|
||||
{
|
||||
// Generate a new mnemonic if none was given
|
||||
if (mnemonic.length() == 0) {
|
||||
this->time = std::time(nullptr);
|
||||
monero_seed seed(this->time, coin.toStdString());
|
||||
|
||||
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());
|
||||
|
||||
this->setRestoreHeight();
|
||||
}
|
||||
|
||||
if (mnemonic.length() == 25) {
|
||||
this->seedType = SeedType::MONERO;
|
||||
}
|
||||
else if (mnemonic.length() == 14) {
|
||||
this->seedType = SeedType::TEVADOR;
|
||||
} else {
|
||||
this->errorString = "Mnemonic seed does not match known type";
|
||||
return;
|
||||
}
|
||||
|
||||
if (seedType == SeedType::TEVADOR) {
|
||||
try {
|
||||
monero_seed seed(mnemonic.join(" ").toStdString(), coin.toStdString());
|
||||
|
||||
this->time = seed.date();
|
||||
this->setRestoreHeight();
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << seed.key();
|
||||
this->spendKey = QString::fromStdString(buffer.str());
|
||||
|
||||
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 setRestoreHeight() {
|
||||
if (this->time == 0)
|
||||
this->restoreHeight = 1;
|
||||
|
||||
this->restoreHeight = appData()->restoreHeights[netType]->dateToHeight(this->time);
|
||||
}
|
||||
|
||||
int setRestoreHeight(int height) {
|
||||
auto now = std::time(nullptr);
|
||||
auto nowClearance = 3600 * 24;
|
||||
auto currentBlockHeight = appData()->restoreHeights[netType]->dateToHeight(now - nowClearance);
|
||||
if (height >= currentBlockHeight + nowClearance) {
|
||||
qCritical() << "unrealistic restore height detected, setting to current blockheight instead: " << currentBlockHeight;
|
||||
this->restoreHeight = currentBlockHeight;
|
||||
} else {
|
||||
this->restoreHeight = height;
|
||||
}
|
||||
|
||||
return this->restoreHeight;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //FEATHER_FEATHERSEED_H
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
struct RestoreHeightLookup {
|
||||
NetworkType::Type type;
|
||||
QMap<int, int> data;
|
||||
QMap<time_t, int> data;
|
||||
explicit RestoreHeightLookup(NetworkType::Type type) : type(type) {}
|
||||
|
||||
int dateToHeight(int date) {
|
||||
int dateToHeight(time_t date) {
|
||||
// restore height based on a given timestamp using a lookup
|
||||
// table. If it cannot find the date in the lookup table, it
|
||||
// will calculate the blockheight based off the last known
|
||||
|
@ -28,34 +28,43 @@ struct RestoreHeightLookup {
|
|||
}
|
||||
|
||||
int blockTime = 120;
|
||||
int blocksPerDay = 86400 / blockTime;
|
||||
int blocksPerDay = 720;
|
||||
int blockCalcClearance = blocksPerDay * 5;
|
||||
QList<int> values = this->data.keys();
|
||||
if (date <= values.at(0))
|
||||
return this->data[values.at(0)];
|
||||
|
||||
QList<time_t> values = this->data.keys();
|
||||
|
||||
// If timestamp is before epoch, return genesis height.
|
||||
if (date <= values.at(0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i != values.count(); i++) {
|
||||
if(values[i] > date) {
|
||||
return i - 1 < 0 ? this->data[values[i]] : this->data[values[i-1]] - blockCalcClearance;
|
||||
if (values[i] > date) {
|
||||
if (i == 0) {
|
||||
return 1;
|
||||
}
|
||||
return this->data[values[i-1]] - blockCalcClearance;
|
||||
}
|
||||
}
|
||||
|
||||
// lookup failed, calculate blockheight from last known checkpoint
|
||||
int lastBlockHeightTime = values.at(values.count() - 1);
|
||||
time_t lastBlockHeightTime = values.last();
|
||||
int lastBlockHeight = this->data[lastBlockHeightTime];
|
||||
int deltaTime = date - lastBlockHeightTime;
|
||||
|
||||
time_t deltaTime = date - lastBlockHeightTime;
|
||||
int deltaBlocks = deltaTime / blockTime;
|
||||
|
||||
int blockHeight = (lastBlockHeight + deltaBlocks) - blockCalcClearance;
|
||||
qDebug() << "Calculated blockheight: " << blockHeight << " from epoch " << date;
|
||||
return blockHeight;
|
||||
}
|
||||
|
||||
int heightToTimestamp(int height) {
|
||||
time_t heightToTimestamp(int height) {
|
||||
// @TODO: most likely inefficient, refactor
|
||||
QMap<int, int>::iterator i;
|
||||
int timestamp = 0;
|
||||
QMap<time_t, int>::iterator i;
|
||||
time_t timestamp = 0;
|
||||
int heightData = 1;
|
||||
for (i = this->data.begin(); i != this->data.end(); ++i) {
|
||||
int ts = i.key();
|
||||
time_t ts = i.key();
|
||||
if (i.value() > height)
|
||||
return timestamp;
|
||||
timestamp = ts;
|
||||
|
@ -77,12 +86,14 @@ struct RestoreHeightLookup {
|
|||
static RestoreHeightLookup *fromFile(const QString &fn, NetworkType::Type type) {
|
||||
// initialize this class using a lookup table, e.g `:/assets/restore_heights_monero_mainnet.txt`/
|
||||
auto rtn = new RestoreHeightLookup(type);
|
||||
auto data = Utils::barrayToString(Utils::fileOpen(fn));
|
||||
QMap<int, int> _data;
|
||||
for(const auto &line: data.split('\n')) {
|
||||
if(line.trimmed().isEmpty()) continue;
|
||||
auto data= Utils::barrayToString(Utils::fileOpen(fn));
|
||||
|
||||
for (const auto &line: data.split('\n')) {
|
||||
if (line.trimmed().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
auto spl = line.trimmed().split(':');
|
||||
rtn->data[spl.at(0).toInt()] = spl.at(1).toInt();
|
||||
rtn->data[(time_t)spl.at(0).toInt()] = spl.at(1).toInt();
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
106
src/utils/Seed.cpp
Normal file
106
src/utils/Seed.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
// 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;
|
62
src/utils/Seed.h
Normal file
62
src/utils/Seed.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: 2020-2022 The Monero Project
|
||||
|
||||
#ifndef FEATHER_SEED_H
|
||||
#define FEATHER_SEED_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "libwalletqt/Wallet.h"
|
||||
#include "monero_seed/monero_seed.hpp"
|
||||
#include "utils/AppData.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
struct Seed {
|
||||
enum Type {
|
||||
MONERO = 0, // 25 word seeds
|
||||
TEVADOR, // 14 word seeds
|
||||
POLYSEED, // 16 word seeds
|
||||
};
|
||||
|
||||
NetworkType::Type networkType = NetworkType::MAINNET;
|
||||
|
||||
QString coin;
|
||||
QString language;
|
||||
Type type = Type::TEVADOR;
|
||||
|
||||
QStringList mnemonic;
|
||||
QString spendKey;
|
||||
QString correction;
|
||||
|
||||
time_t time{};
|
||||
int restoreHeight = 0;
|
||||
|
||||
QString errorString;
|
||||
|
||||
explicit Seed();
|
||||
explicit Seed(Type type, NetworkType::Type networkType = NetworkType::MAINNET, QString language = "English");
|
||||
explicit Seed(Type type, QStringList mnemonic, NetworkType::Type networkType = NetworkType::MAINNET);
|
||||
void setRestoreHeight(int height);
|
||||
|
||||
private:
|
||||
void setRestoreHeight();
|
||||
|
||||
QStringList m_insecureSeeds = {
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
};
|
||||
|
||||
QMap<Seed::Type, int> m_seedLength {
|
||||
{Type::MONERO, 25},
|
||||
{Type::TEVADOR, 14},
|
||||
{Type::POLYSEED, 16}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif //FEATHER_SEED_H
|
|
@ -9,7 +9,7 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
#include <monero_seed/wordlist.hpp> // tevador 14 word
|
||||
#include "utils/FeatherSeed.h"
|
||||
#include "utils/Seed.h"
|
||||
#include "constants.h"
|
||||
|
||||
#include <mnemonics/electrum-words.h>
|
||||
|
@ -60,13 +60,13 @@ PageWalletRestoreSeed::PageWalletRestoreSeed(WizardFields *fields, QWidget *pare
|
|||
void PageWalletRestoreSeed::onSeedTypeToggled() {
|
||||
if (ui->radio14->isChecked()) {
|
||||
m_mode = &m_tevador;
|
||||
m_fields->seedType = SeedType::TEVADOR;
|
||||
m_fields->seedType = Seed::Type::TEVADOR;
|
||||
ui->seedEdit->setPlaceholderText("Enter 14 word seed..");
|
||||
ui->group_seedLanguage->hide();
|
||||
}
|
||||
else if (ui->radio25->isChecked()) {
|
||||
m_mode = &m_legacy;
|
||||
m_fields->seedType = SeedType::MONERO;
|
||||
m_fields->seedType = Seed::Type::MONERO;
|
||||
ui->seedEdit->setPlaceholderText("Enter 25 word seed..");
|
||||
ui->group_seedLanguage->show();
|
||||
}
|
||||
|
@ -128,7 +128,8 @@ bool PageWalletRestoreSeed::validatePage() {
|
|||
}
|
||||
}
|
||||
|
||||
auto _seed = FeatherSeed(constants::networkType, QString::fromStdString(constants::coinName), constants::seedLanguage, seedSplit);
|
||||
Seed _seed = Seed(m_mode->length == 14 ? Seed::Type::TEVADOR : Seed::Type::MONERO, seedSplit, constants::networkType);
|
||||
|
||||
if (!_seed.errorString.isEmpty()) {
|
||||
QMessageBox::warning(this, "Invalid seed", QString("Invalid seed:\n\n%1").arg(_seed.errorString));
|
||||
ui->seedEdit->setStyleSheet(errStyle);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "PageWalletSeed.h"
|
||||
#include "ui_PageWalletSeed.h"
|
||||
#include "constants.h"
|
||||
#include "Seed.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
|
@ -15,6 +16,10 @@ PageWalletSeed::PageWalletSeed(WizardFields *fields, QWidget *parent)
|
|||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->frame_invalidSeed->hide();
|
||||
QPixmap warningIcon = QPixmap(":/assets/images/warning.png");
|
||||
ui->warningIcon->setPixmap(warningIcon.scaledToWidth(32, Qt::SmoothTransformation));
|
||||
|
||||
QPixmap pixmap = QPixmap(":/assets/images/seed.png");
|
||||
ui->seedIcon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
|
||||
|
||||
|
@ -48,13 +53,21 @@ void PageWalletSeed::seedRoulette(int count) {
|
|||
}
|
||||
|
||||
void PageWalletSeed::generateSeed() {
|
||||
Seed seed;
|
||||
|
||||
do {
|
||||
FeatherSeed seed = FeatherSeed(constants::networkType, QString::fromStdString(constants::coinName), constants::seedLanguage);
|
||||
seed = Seed(Seed::Type::TEVADOR);
|
||||
m_mnemonic = seed.mnemonic.join(" ");
|
||||
m_restoreHeight = seed.restoreHeight;
|
||||
} while (m_mnemonic.split(" ").length() != 14); // https://github.com/tevador/monero-seed/issues/2
|
||||
|
||||
this->displaySeed(m_mnemonic);
|
||||
|
||||
if (!seed.errorString.isEmpty()) {
|
||||
ui->frame_invalidSeed->show();
|
||||
ui->frame_seedDisplay->hide();
|
||||
m_seedError = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PageWalletSeed::displaySeed(const QString &seed){
|
||||
|
@ -101,4 +114,8 @@ bool PageWalletSeed::validatePage() {
|
|||
m_fields->seed = m_mnemonic;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PageWalletSeed::isComplete() const {
|
||||
return !m_seedError;
|
||||
}
|
|
@ -22,6 +22,7 @@ public:
|
|||
explicit PageWalletSeed(WizardFields *fields, QWidget *parent = nullptr);
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
bool isComplete() const override;
|
||||
int nextId() const override;
|
||||
|
||||
public slots:
|
||||
|
@ -42,6 +43,7 @@ private:
|
|||
QString m_mnemonic;
|
||||
int m_restoreHeight;
|
||||
|
||||
bool m_seedError = false;
|
||||
bool m_roulette = false;
|
||||
int m_rouletteSpin = 15;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -117,15 +117,17 @@ void WalletWizard::onCreateWallet() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto seed = FeatherSeed(constants::networkType, QString::fromStdString(constants::coinName), constants::seedLanguage, m_wizardFields.seed.split(" "));
|
||||
auto seed = Seed(m_wizardFields.seedType, m_wizardFields.seed.split(" "), constants::networkType);
|
||||
|
||||
// If we're connected to the websocket, use the reported height for new wallets to skip initial synchronization.
|
||||
if (m_wizardFields.mode == WizardMode::CreateWallet && currentBlockHeight > 0) {
|
||||
qInfo() << "New wallet, setting restore height to latest blockheight: " << currentBlockHeight;
|
||||
seed.setRestoreHeight(currentBlockHeight);
|
||||
seed.restoreHeight = currentBlockHeight;
|
||||
}
|
||||
|
||||
if (m_wizardFields.mode == WizardMode::RestoreFromSeed && m_wizardFields.seedType == SeedType::MONERO)
|
||||
if (m_wizardFields.mode == WizardMode::RestoreFromSeed && m_wizardFields.seedType == Seed::Type::MONERO) {
|
||||
seed.setRestoreHeight(m_wizardFields.restoreHeight);
|
||||
}
|
||||
|
||||
emit createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedLanguage, m_wizardFields.seedOffsetPassphrase);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ struct WizardFields {
|
|||
QString secretSpendKey;
|
||||
WizardMode mode;
|
||||
int restoreHeight = 0;
|
||||
SeedType seedType;
|
||||
Seed::Type seedType;
|
||||
DeviceType deviceType;
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ signals:
|
|||
|
||||
void createWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||
void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false);
|
||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset = "");
|
||||
void createWallet(Seed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset = "");
|
||||
|
||||
private slots:
|
||||
void onCreateWallet();
|
||||
|
|
Loading…
Reference in a new issue