#ifndef FEATHER_FEATHERSEED_H #define FEATHER_FEATHERSEED_H #include "libwalletqt/WalletManager.h" #include "libwalletqt/Wallet.h" #include #include "RestoreHeightLookup.h" enum SeedType { MONERO = 0, // 25 word seeds TEVADOR // 14 word seeds }; struct FeatherSeed { QString coin; QString language; SeedType seedType; QStringList mnemonic; QString spendKey; QString correction; time_t time; int restoreHeight = 0; RestoreHeightLookup *lookup = nullptr; QString errorString; explicit FeatherSeed(RestoreHeightLookup *lookup, const QString &coin = "monero", const QString &language = "English", const QStringList &mnemonic = {}) : lookup(lookup), coin(coin), language(language), mnemonic(mnemonic) { // Generate a new mnemonic if none was given if (this->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 (this->mnemonic.length() == 25) { this->seedType = SeedType::MONERO; } else if (this->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(this->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; } } } int setRestoreHeight() { if (this->lookup == nullptr) return 1; if (this->time == 0) return 1; this->restoreHeight = this->lookup->dateToRestoreHeight(this->time); return this->restoreHeight; } int setRestoreHeight(int height) { auto now = std::time(nullptr); auto nowClearance = 3600 * 24; auto currentBlockHeight = this->lookup->dateToRestoreHeight(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