Support all seed languages for 25 word seeds

This commit is contained in:
tobtoht 2021-09-05 15:22:06 +02:00
parent 1d691d1eb1
commit 2ce6a80fba
9 changed files with 55 additions and 1646 deletions

View file

@ -212,7 +212,7 @@ bool WindowManager::autoOpenWallet() {
// ######################## WALLET CREATION ########################
void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password,
void WindowManager::tryCreateWallet(FeatherSeed 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);

View file

@ -45,7 +45,7 @@ private slots:
void onWalletPassphraseNeeded(bool on_device);
private:
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset);
void tryCreateWallet(FeatherSeed 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);

View file

@ -119,7 +119,6 @@
<file>assets/images/xmrig.ico</file>
<file>assets/images/xmrig.svg</file>
<file>assets/images/zoom.png</file>
<file>assets/mnemonic_25_english.txt</file>
<file>assets/restore_heights_monero_mainnet.txt</file>
<file>assets/restore_heights_monero_stagenet.txt</file>
</qresource>

File diff suppressed because it is too large Load diff

View file

@ -12,13 +12,27 @@
#include "utils/FeatherSeed.h"
#include "constants.h"
#include <mnemonics/electrum-words.h>
PageWalletRestoreSeed::PageWalletRestoreSeed(WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageWalletRestoreSeed)
, m_fields(fields)
{
ui->setupUi(this);
ui->label_errorString->hide();
std::vector<const Language::Base*> wordlists = crypto::ElectrumWords::get_language_list();
for (const auto& wordlist: wordlists) {
QStringList words_qt;
std::vector<std::string> words_std = wordlist->get_word_list();
for (const auto& word: words_std) {
words_qt += QString::fromStdString(word);
}
QString language = QString::fromStdString(wordlist->get_english_language_name());
ui->combo_seedLanguage->addItem(language);
m_wordlists[language] = words_qt;
}
QStringList bip39English;
for (int i = 0; i != 2048; i++)
@ -27,26 +41,18 @@ PageWalletRestoreSeed::PageWalletRestoreSeed(WizardFields *fields, QWidget *pare
// (illegible word with a known location). This can be tested by replacing a word with xxxx
bip39English << "xxxx";
QByteArray data = Utils::fileOpen(":/assets/mnemonic_25_english.txt");
QStringList moneroEnglish;
for (const auto &seed_word: data.split('\n'))
moneroEnglish << seed_word;
m_tevador.length = 14;
m_tevador.setWords(bip39English);
m_legacy.length = 25;
m_legacy.setWords(moneroEnglish);
m_legacy.setWords(m_wordlists["English"]);
ui->combo_seedLanguage->setCurrentText("English");
ui->seedEdit->setAcceptRichText(false);
ui->seedEdit->setMaximumHeight(150);
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QGuiApplication::restoreOverrideCursor();
#endif
connect(ui->seedBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &PageWalletRestoreSeed::onSeedTypeToggled);
connect(ui->combo_seedLanguage, &QComboBox::currentTextChanged, this, &PageWalletRestoreSeed::onSeedLanguageChanged);
this->onSeedTypeToggled();
}
@ -56,11 +62,13 @@ void PageWalletRestoreSeed::onSeedTypeToggled() {
m_mode = &m_tevador;
m_fields->seedType = SeedType::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;
ui->seedEdit->setPlaceholderText("Enter 25 word seed..");
ui->group_seedLanguage->show();
}
ui->label_errorString->hide();
@ -69,6 +77,11 @@ void PageWalletRestoreSeed::onSeedTypeToggled() {
ui->seedEdit->setText("");
}
void PageWalletRestoreSeed::onSeedLanguageChanged(const QString &language) {
m_legacy.setWords(m_wordlists[language]);
m_fields->seedLanguage = language;
}
int PageWalletRestoreSeed::nextId() const {
if (m_mode == &m_legacy) {
return WalletWizard::Page_SetRestoreHeight;
@ -100,8 +113,14 @@ bool PageWalletRestoreSeed::validatePage() {
return false;
}
// libwallet will accept e.g. "brötchen" or "BRÖTCHEN" instead of "Brötchen"
QStringList lowercaseWords;
for (const auto &word : m_mode->words) {
lowercaseWords << word.toLower();
}
for (const auto &word : seedSplit) {
if (!m_mode->words.contains(word)) {
if (!lowercaseWords.contains(word.toLower())) {
ui->label_errorString->show();
ui->label_errorString->setText(QString("Mnemonic seed contains an unknown word: %1").arg(word));
ui->seedEdit->setStyleSheet(errStyle);

View file

@ -32,8 +32,8 @@ private:
seedType()
{
completer.setModel(&completerModel);
completer.setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer.setCaseSensitivity(Qt::CaseInsensitive);
completer.setModelSorting(QCompleter::CaseSensitivelySortedModel);
completer.setCaseSensitivity(Qt::CaseSensitive);
completer.setWrapAround(false);
}
@ -49,6 +49,7 @@ private:
};
void onSeedTypeToggled();
void onSeedLanguageChanged(const QString &language);
Ui::PageWalletRestoreSeed *ui;
WizardFields *m_fields;
@ -57,6 +58,8 @@ private:
seedType m_legacy;
seedType *m_mode;
QMap<QString, QStringList> m_wordlists;
};
#endif

View file

@ -46,6 +46,18 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="group_seedLanguage">
<property name="title">
<string>Select seed language:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="combo_seedLanguage"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="TextEdit" name="seedEdit">
<property name="acceptRichText">

View file

@ -127,5 +127,5 @@ void WalletWizard::onCreateWallet() {
if (m_wizardFields.mode == WizardMode::RestoreFromSeed && m_wizardFields.seedType == SeedType::MONERO)
seed.setRestoreHeight(m_wizardFields.restoreHeight);
emit createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedOffsetPassphrase);
emit createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedLanguage, m_wizardFields.seedOffsetPassphrase);
}

View file

@ -12,6 +12,7 @@
#include "model/WalletKeysFilesModel.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/config.h"
#include "constants.h"
enum WizardMode {
CreateWallet = 0,
@ -32,6 +33,7 @@ struct WizardFields {
QString walletDir;
QString seed;
QString seedOffsetPassphrase;
QString seedLanguage = constants::seedLanguage;
QString password;
QString modeText;
QString address;
@ -72,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 &seedOffset = "");
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedLanguage, const QString &seedOffset = "");
private slots:
void onCreateWallet();