diff options
Diffstat (limited to 'src/wallet/api/wallet.cpp')
-rw-r--r-- | src/wallet/api/wallet.cpp | 88 |
1 files changed, 66 insertions, 22 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 908e2db2e..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); @@ -554,18 +556,26 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, } // parse view secret key + bool has_viewkey = true; + crypto::secret_key viewkey; if (viewkey_string.empty()) { - setStatusError(tr("No view key supplied, cancelled")); - return false; + if(has_spendkey) { + has_viewkey = false; + } + else { + setStatusError(tr("Neither view key nor spend key supplied, cancelled")); + return false; + } } - cryptonote::blobdata viewkey_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) - { - setStatusError(tr("failed to parse secret view key")); - return false; + if(has_viewkey) { + cryptonote::blobdata viewkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) + { + setStatusError(tr("failed to parse secret view key")); + return false; + } + viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); } - crypto::secret_key viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); - // check the spend and view keys match the given address crypto::public_key pkey; if(has_spendkey) { @@ -578,26 +588,32 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, return false; } } - if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - setStatusError(tr("failed to verify secret view key")); - return false; - } - if (info.address.m_view_public_key != pkey) { - setStatusError(tr("view key does not match address")); - return false; + if(has_viewkey) { + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + setStatusError(tr("failed to verify secret view key")); + return false; + } + if (info.address.m_view_public_key != pkey) { + setStatusError(tr("view key does not match address")); + return false; + } } try { - if (has_spendkey) { + if (has_spendkey && has_viewkey) { m_wallet->generate(path, password, info.address, spendkey, viewkey); - setSeedLanguage(language); - LOG_PRINT_L1("Generated new wallet from keys with seed language: " + language); + LOG_PRINT_L1("Generated new wallet from spend key and view key"); } - else { + if(!has_spendkey && has_viewkey) { m_wallet->generate(path, password, info.address, viewkey); LOG_PRINT_L1("Generated new view only wallet from keys"); } + if(has_spendkey && !has_viewkey) { + m_wallet->generate(path, password, spendkey, true, false, false); + setSeedLanguage(language); + LOG_PRINT_L1("Generated deterministic wallet from spend key with seed language: " + language); + } } catch (const std::exception& e) { @@ -607,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 @@ -649,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)) { @@ -870,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); @@ -1896,7 +1940,7 @@ void WalletImpl::refreshThreadFunc() // if auto refresh enabled, we wait for the "m_refreshIntervalSeconds" interval. // if not - we wait forever if (m_refreshIntervalMillis > 0) { - boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis); + boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis.load()); m_refreshCV.timed_wait(lock, wait_for_ms); } else { m_refreshCV.wait(lock); @@ -1982,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) |