aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/util.cpp18
-rw-r--r--src/common/util.h3
-rw-r--r--src/simplewallet/simplewallet.cpp17
-rw-r--r--src/wallet/api/wallet.cpp32
-rw-r--r--src/wallet/api/wallet.h6
-rw-r--r--src/wallet/api/wallet2_api.h32
-rw-r--r--src/wallet/api/wallet_manager.cpp20
-rw-r--r--src/wallet/api/wallet_manager.h6
-rw-r--r--src/wallet/wallet2.cpp6
9 files changed, 125 insertions, 15 deletions
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 3f330fa13..329352e94 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -827,4 +827,22 @@ std::string get_nix_version_display_string()
return false;
return true;
}
+
+ boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str)
+ {
+ auto pos = str.find(":");
+ bool r = pos != std::string::npos;
+ uint32_t major;
+ r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos));
+ uint32_t minor;
+ r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1));
+ if (r)
+ {
+ return std::make_pair(major, minor);
+ }
+ else
+ {
+ return {};
+ }
+ }
}
diff --git a/src/common/util.h b/src/common/util.h
index 7caf0e3c5..dc426830b 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -32,6 +32,7 @@
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
+#include <boost/optional.hpp>
#include <system_error>
#include <csignal>
#include <cstdio>
@@ -214,4 +215,6 @@ namespace tools
bool sha256sum(const std::string &filename, crypto::hash &hash);
bool is_hdd(const char *path);
+
+ boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index d0c35dfff..d531c2da2 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -379,21 +379,10 @@ namespace
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str)
{
- auto pos = str.find(":");
- bool r = pos != std::string::npos;
- uint32_t major;
- r = r && epee::string_tools::get_xtype_from_string(major, str.substr(0, pos));
- uint32_t minor;
- r = r && epee::string_tools::get_xtype_from_string(minor, str.substr(pos + 1));
- if (r)
- {
- return std::make_pair(major, minor);
- }
- else
- {
+ auto r = tools::parse_subaddress_lookahead(str);
+ if (!r)
fail_msg_writer() << tr("invalid format for subaddress lookahead; must be <major>:<minor>");
- return {};
- }
+ return r;
}
void handle_transfer_exception(const std::exception_ptr &e, bool trusted_daemon)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 7ade42e11..c7dbd29e4 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -372,6 +372,7 @@ WalletImpl::WalletImpl(NetworkType nettype)
, m_trustedDaemon(false)
, m_wallet2Callback(nullptr)
, m_recoveringFromSeed(false)
+ , m_recoveringFromDevice(false)
, m_synchronized(false)
, m_rebuildWalletCache(false)
, m_is_connected(false)
@@ -419,6 +420,7 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co
clearStatus();
m_recoveringFromSeed = false;
+ m_recoveringFromDevice = false;
bool keys_file_exists;
bool wallet_file_exists;
tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists);
@@ -621,11 +623,28 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
return true;
}
+bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &password, const std::string &device_name)
+{
+ clearStatus();
+ m_recoveringFromSeed = false;
+ m_recoveringFromDevice = true;
+ try
+ {
+ m_wallet->restore(path, password, device_name);
+ LOG_PRINT_L1("Generated new wallet from device: " + device_name);
+ }
+ catch (const std::exception& e) {
+ setStatusError(string(tr("failed to generate new wallet: ")) + e.what());
+ return false;
+ }
+ return true;
+}
bool WalletImpl::open(const std::string &path, const std::string &password)
{
clearStatus();
m_recoveringFromSeed = false;
+ m_recoveringFromDevice = false;
try {
// TODO: handle "deprecated"
// Check if wallet cache exists
@@ -663,6 +682,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
}
m_recoveringFromSeed = true;
+ m_recoveringFromDevice = false;
crypto::secret_key recovery_key;
std::string old_language;
if (!crypto::ElectrumWords::words_to_bytes(seed, recovery_key, old_language)) {
@@ -884,6 +904,16 @@ void WalletImpl::setRecoveringFromSeed(bool recoveringFromSeed)
m_recoveringFromSeed = recoveringFromSeed;
}
+void WalletImpl::setRecoveringFromDevice(bool recoveringFromDevice)
+{
+ m_recoveringFromDevice = recoveringFromDevice;
+}
+
+void WalletImpl::setSubaddressLookahead(uint32_t major, uint32_t minor)
+{
+ m_wallet->set_subaddress_lookahead(major, minor);
+}
+
uint64_t WalletImpl::balance(uint32_t accountIndex) const
{
return m_wallet->balance(accountIndex);
@@ -1996,7 +2026,7 @@ bool WalletImpl::isNewWallet() const
// with the daemon (pull hashes instead of pull blocks).
// If wallet cache is rebuilt, creation height stored in .keys is used.
// Watch only wallet is a copy of an existing wallet.
- return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_rebuildWalletCache) && !watchOnly();
+ return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_recoveringFromDevice || m_rebuildWalletCache) && !watchOnly();
}
bool WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit, bool ssl)
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 813ca4b30..08232cafd 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -76,6 +76,9 @@ public:
const std::string &address_string,
const std::string &viewkey_string,
const std::string &spendkey_string = "");
+ bool recoverFromDevice(const std::string &path,
+ const std::string &password,
+ const std::string &device_name);
bool close(bool store = true);
std::string seed() const;
std::string getSeedLanguage() const;
@@ -115,6 +118,8 @@ public:
void setRefreshFromBlockHeight(uint64_t refresh_from_block_height);
uint64_t getRefreshFromBlockHeight() const { return m_wallet->get_refresh_from_block_height(); };
void setRecoveringFromSeed(bool recoveringFromSeed);
+ void setRecoveringFromDevice(bool recoveringFromDevice) override;
+ void setSubaddressLookahead(uint32_t major, uint32_t minor) override;
bool watchOnly() const;
bool rescanSpent();
NetworkType nettype() const {return static_cast<NetworkType>(m_wallet->nettype());}
@@ -232,6 +237,7 @@ private:
// so it shouldn't be considered as new and pull blocks (slow-refresh)
// instead of pulling hashes (fast-refresh)
std::atomic<bool> m_recoveringFromSeed;
+ std::atomic<bool> m_recoveringFromDevice;
std::atomic<bool> m_synchronized;
std::atomic<bool> m_rebuildWalletCache;
// cache connection status to avoid unnecessary RPC calls
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 5b99bd975..f54255e91 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -509,6 +509,21 @@ struct Wallet
*/
virtual void setRecoveringFromSeed(bool recoveringFromSeed) = 0;
+ /*!
+ * \brief setRecoveringFromDevice - set state to recovering from device
+ *
+ * \param recoveringFromDevice - true/false
+ */
+ virtual void setRecoveringFromDevice(bool recoveringFromDevice) = 0;
+
+ /*!
+ * \brief setSubaddressLookahead - set size of subaddress lookahead
+ *
+ * \param major - size fot the major index
+ * \param minor - size fot the minor index
+ */
+ virtual void setSubaddressLookahead(uint32_t major, uint32_t minor) = 0;
+
/**
* @brief connectToDaemon - connects to the daemon. TODO: check if it can be removed
* @return
@@ -1015,6 +1030,23 @@ struct WalletManager
}
/*!
+ * \brief creates wallet using hardware device.
+ * \param path Name of wallet file to be created
+ * \param password Password of wallet file
+ * \param nettype Network type
+ * \param deviceName Device name
+ * \param restoreHeight restore from start height (0 sets to current height)
+ * \param subaddressLookahead Size of subaddress lookahead (empty sets to some default low value)
+ * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
+ */
+ virtual Wallet * createWalletFromDevice(const std::string &path,
+ const std::string &password,
+ NetworkType nettype,
+ const std::string &deviceName,
+ uint64_t restoreHeight = 0,
+ const std::string &subaddressLookahead = "") = 0;
+
+ /*!
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
* \param wallet previously opened / created wallet instance
* \return None
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index a63716576..99eadc82f 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -114,6 +114,26 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
return wallet;
}
+Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
+ const std::string &password,
+ NetworkType nettype,
+ const std::string &deviceName,
+ uint64_t restoreHeight,
+ const std::string &subaddressLookahead)
+{
+ WalletImpl * wallet = new WalletImpl(nettype);
+ if(restoreHeight > 0){
+ wallet->setRefreshFromBlockHeight(restoreHeight);
+ }
+ auto lookahead = tools::parse_subaddress_lookahead(subaddressLookahead);
+ if (lookahead)
+ {
+ wallet->setSubaddressLookahead(lookahead->first, lookahead->second);
+ }
+ wallet->recoverFromDevice(path, password, deviceName);
+ return wallet;
+}
+
bool WalletManagerImpl::closeWallet(Wallet *wallet, bool store)
{
WalletImpl * wallet_ = dynamic_cast<WalletImpl*>(wallet);
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 26238b658..19aad9ee3 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -64,6 +64,12 @@ public:
const std::string &addressString,
const std::string &viewKeyString,
const std::string &spendKeyString = "");
+ virtual Wallet * createWalletFromDevice(const std::string &path,
+ const std::string &password,
+ NetworkType nettype,
+ const std::string &deviceName,
+ uint64_t restoreHeight = 0,
+ const std::string &subaddressLookahead = "") override;
virtual bool closeWallet(Wallet *wallet, bool store = true);
bool walletExists(const std::string &path);
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key) const;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index bb0953689..16ca04e3f 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -3273,6 +3273,12 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p
cryptonote::block b;
generate_genesis(b);
m_blockchain.push_back(get_block_hash(b));
+ if (m_subaddress_lookahead_major == SUBADDRESS_LOOKAHEAD_MAJOR && m_subaddress_lookahead_minor == SUBADDRESS_LOOKAHEAD_MINOR)
+ {
+ // the default lookahead setting (50:200) is clearly too much for hardware wallet
+ m_subaddress_lookahead_major = 5;
+ m_subaddress_lookahead_minor = 20;
+ }
add_subaddress_account(tr("Primary account"));
if (!wallet_.empty()) {
store();