From cc18926ebab0c117b88a08da19bac14021fa4c2d Mon Sep 17 00:00:00 2001
From: xiphon <xiphon@protonmail.com>
Date: Tue, 11 Feb 2020 23:27:30 +0000
Subject: [PATCH] wallet2_api: wallet recovery - seed offset passphrase support

---
 src/wallet/api/wallet.cpp         | 6 +++++-
 src/wallet/api/wallet.h           | 2 +-
 src/wallet/api/wallet2_api.h      | 4 +++-
 src/wallet/api/wallet_manager.cpp | 5 +++--
 src/wallet/api/wallet_manager.h   | 3 ++-
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 6200c7a1f..00ed2ff65 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -725,7 +725,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &seed)
     return recover(path, "", seed);
 }
 
-bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed)
+bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/)
 {
     clearStatus();
     m_errorString.clear();
@@ -743,6 +743,10 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
         setStatusError(tr("Electrum-style word list failed verification"));
         return false;
     }
+    if (!seed_offset.empty())
+    {
+        recovery_key = cryptonote::decrypt_key(recovery_key, seed_offset);
+    }
 
     if (old_language == crypto::ElectrumWords::old_language_name)
         old_language = Language::English().get_language_name();
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 331bf4b38..5417427d5 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -60,7 +60,7 @@ public:
                             const std::string &language) const override;
     bool open(const std::string &path, const std::string &password);
     bool recover(const std::string &path,const std::string &password,
-                            const std::string &seed);
+                            const std::string &seed, const std::string &seed_offset = {});
     bool recoverFromKeysWithPassword(const std::string &path,
                             const std::string &password,
                             const std::string &language,
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index e543a115b..024732a06 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1085,10 +1085,12 @@ struct WalletManager
      * \param  nettype        Network type
      * \param  restoreHeight  restore from start height
      * \param  kdf_rounds     Number of rounds for key derivation function
+     * \param  seed_offset    Seed offset passphrase (optional)
      * \return                Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
      */
     virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
-                                    NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1) = 0;
+                                    NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1,
+                                    const std::string &seed_offset = {}) = 0;
     Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
                                     bool testnet = false, uint64_t restoreHeight = 0)           // deprecated
     {
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index d589dcc75..44a184304 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -93,13 +93,14 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path,
                                                 const std::string &mnemonic,
                                                 NetworkType nettype,
                                                 uint64_t restoreHeight,
-                                                uint64_t kdf_rounds)
+                                                uint64_t kdf_rounds,
+                                                const std::string &seed_offset/* = {}*/)
 {
     WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
     if(restoreHeight > 0){
         wallet->setRefreshFromBlockHeight(restoreHeight);
     }
-    wallet->recover(path, password, mnemonic);
+    wallet->recover(path, password, mnemonic, seed_offset);
     return wallet;
 }
 
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 537fc5ba6..0595b8327 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -46,7 +46,8 @@ public:
                                        const std::string &mnemonic,
                                        NetworkType nettype,
                                        uint64_t restoreHeight,
-                                       uint64_t kdf_rounds = 1) override;
+                                       uint64_t kdf_rounds = 1,
+                                       const std::string &seed_offset = {}) override;
     virtual Wallet * createWalletFromKeys(const std::string &path,
                                              const std::string &password,
                                              const std::string &language,