From ad28016bf3cfd11242dc14472389f7a006c73dcf Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 11 Oct 2023 16:47:59 +0200 Subject: [PATCH 12/15] Add recoverDeterministicWalletFromSpendKey This function is used by Cake Wallet to enable polyseed (dart implementation) support. Sourced from the following commit: https://github.com/cake-tech/monero/commit/cb6fb5ab218878702ed151c0e3d5d68eb2732788 Co-authored-by: Godwin Asuquo --- src/wallet/api/wallet.cpp | 29 +++++++++++++++++++++++++++++ src/wallet/api/wallet.h | 4 ++++ src/wallet/api/wallet2_api.h | 19 +++++++++++++++++++ src/wallet/api/wallet_manager.cpp | 16 ++++++++++++++++ src/wallet/api/wallet_manager.h | 7 +++++++ 5 files changed, 75 insertions(+) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index e69910e69..e650e6044 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -824,6 +824,35 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c return status() == Status_Ok; } +bool WalletImpl::recoverDeterministicWalletFromSpendKey(const std::string &path, const std::string &password, const std::string &language, const std::string &spendkey_string) +{ + clearStatus(); + m_errorString.clear(); + + m_recoveringFromSeed = true; + m_recoveringFromDevice = false; + + // parse spend key + crypto::secret_key spendkey; + if (!spendkey_string.empty()) { + cryptonote::blobdata spendkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key)) + { + setStatusError(tr("failed to parse secret spend key")); + return false; + } + spendkey = *reinterpret_cast(spendkey_data.data()); + } + + try { + m_wallet->generate(path, password, spendkey, true, false); + setSeedLanguage(language); + } catch (const std::exception &e) { + setStatusCritical(e.what()); + } + return status() == Status_Ok; +} + bool WalletImpl::close(bool store) { diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index a82f270e4..9e1fbb40b 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -77,6 +77,10 @@ public: const std::string &address_string, const std::string &viewkey_string, const std::string &spendkey_string = ""); + bool recoverDeterministicWalletFromSpendKey(const std::string &path, + const std::string &password, + const std::string &language, + const std::string &spendkey_string); bool recoverFromDevice(const std::string &path, const std::string &password, const std::string &device_name); diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index f421fdc05..c8d6bb179 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -1323,6 +1323,25 @@ struct WalletManager return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); } + /*! + * \brief recover deterministic wallet from spend key. + * \param path Name of wallet file to be created + * \param password Password of wallet file + * \param language language + * \param nettype Network type + * \param restoreHeight restore from start height + * \param spendKeyString spend key + * \param kdf_rounds Number of rounds for key derivation function + * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) + */ + virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path, + const std::string &password, + const std::string &language, + NetworkType nettype, + uint64_t restoreHeight, + const std::string &spendKeyString, + uint64_t kdf_rounds = 1) = 0; + /*! * \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index da2056d8a..c200f52ae 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -127,6 +127,22 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, return wallet; } +Wallet *WalletManagerImpl::createDeterministicWalletFromSpendKey(const std::string &path, + const std::string &password, + const std::string &language, + NetworkType nettype, + uint64_t restoreHeight, + const std::string &spendkey_string, + uint64_t kdf_rounds) +{ + WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + if(restoreHeight > 0){ + wallet->setRefreshFromBlockHeight(restoreHeight); + } + wallet->recoverDeterministicWalletFromSpendKey(path, password, language, spendkey_string); + return wallet; +} + Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, const std::string &password, NetworkType nettype, diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index 28fcd36c9..be3ff8184 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -67,6 +67,13 @@ public: const std::string &addressString, const std::string &viewKeyString, const std::string &spendKeyString = "") override; + virtual Wallet * createDeterministicWalletFromSpendKey(const std::string &path, + const std::string &password, + const std::string &language, + NetworkType nettype, + uint64_t restoreHeight, + const std::string &spendkey_string, + uint64_t kdf_rounds) override; virtual Wallet * createWalletFromDevice(const std::string &path, const std::string &password, NetworkType nettype, -- 2.48.0