mirror of
https://github.com/wownero/lwsf-wow.git
synced 2026-10-17 07:21:28 +02:00
Added recover from keys, and more bug fixes
This commit is contained in:
@@ -1375,4 +1375,4 @@ struct WalletManagerFactory
|
||||
static void setLogCategories(const std::string &categories);
|
||||
};
|
||||
|
||||
}
|
||||
} // lwsf
|
||||
|
||||
+14
-7
@@ -447,8 +447,8 @@ namespace lwsf { namespace internal { namespace backend
|
||||
|
||||
void merge_subaddrs(account& self, const epee::span<const rpc::subaddrs> subaddrs)
|
||||
{
|
||||
/* This will purge subaddresses that the server somehow no longer claims
|
||||
as being valid. The existing info per subaddress is moved/preserved. */
|
||||
/* Purge subaccounts that do not have info (label) and are not mentioned
|
||||
by the server. */
|
||||
|
||||
std::map<std::uint32_t, sub_account> subaccounts;
|
||||
subaccounts.swap(self.subaccounts);
|
||||
@@ -456,6 +456,17 @@ namespace lwsf { namespace internal { namespace backend
|
||||
// Never remove special {0,0} account
|
||||
self.subaccounts[0].minor[0] = std::move(subaccounts[0].minor[0]);
|
||||
|
||||
// Keep all subaccounts with a info
|
||||
for (auto& account : subaccounts)
|
||||
{
|
||||
for (auto& subaccount : account.second.minor)
|
||||
{
|
||||
if (subaccount.second.preserve())
|
||||
self.subaccounts[account.first].minor[subaccount.first] = std::move(subaccount.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Keep all subaccounts mentioned by server
|
||||
for (const auto& subaddr : subaddrs)
|
||||
{
|
||||
auto& account = self.subaccounts[subaddr.key];
|
||||
@@ -463,11 +474,7 @@ namespace lwsf { namespace internal { namespace backend
|
||||
for (const auto& minors : subaddr.value)
|
||||
{
|
||||
for (std::uint32_t minor = std::get<0>(minors); minor < std::uint64_t(std::get<1>(minors)) + 1; ++minor)
|
||||
{
|
||||
auto elem = account.minor.try_emplace(minor);
|
||||
if (elem.second && (subaddr.key || minor))
|
||||
elem.first->second = std::move(old.minor[minor]);
|
||||
}
|
||||
account.minor.try_emplace(minor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -77,6 +77,8 @@ namespace lwsf { namespace internal { namespace backend
|
||||
struct subaddress
|
||||
{
|
||||
std::string label;
|
||||
|
||||
bool preserve() const noexcept { return !label.empty(); }
|
||||
};
|
||||
WIRE_DECLARE_OBJECT(subaddress);
|
||||
|
||||
@@ -128,9 +130,9 @@ namespace lwsf { namespace internal { namespace backend
|
||||
receives(),
|
||||
description(),
|
||||
timestamp(),
|
||||
height(),
|
||||
amount(0),
|
||||
fee(0),
|
||||
height(),
|
||||
unlock_time(0),
|
||||
direction(Monero::TransactionInfo::Direction_Out),
|
||||
payment_id(),
|
||||
@@ -154,9 +156,9 @@ namespace lwsf { namespace internal { namespace backend
|
||||
boost::container::flat_map<crypto::public_key, transfer_in, memory> receives; //!< Key is output pub
|
||||
std::string description;
|
||||
std::optional<std::time_t> timestamp;
|
||||
std::optional<std::uint64_t> height;
|
||||
std::uint64_t amount;
|
||||
std::uint64_t fee;
|
||||
std::optional<std::uint64_t> height;
|
||||
std::uint64_t unlock_time;
|
||||
Monero::TransactionInfo::Direction direction;
|
||||
std::variant<rpc::empty, crypto::hash8, crypto::hash> payment_id;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace lwsf { namespace internal
|
||||
std::string transaction_info::description() const
|
||||
{
|
||||
const boost::lock_guard<boost::mutex> lock{wallet_->sync};
|
||||
return data_->description;
|
||||
return data_->description; // this can change outside of refresh func
|
||||
}
|
||||
|
||||
std::set<std::uint32_t> transaction_info::subaddrIndex() const
|
||||
@@ -84,11 +84,16 @@ namespace lwsf { namespace internal
|
||||
std::set<std::uint32_t> out;
|
||||
const std::uint32_t major = subaddrAccount();
|
||||
|
||||
for (const auto& receive : data_->receives)
|
||||
out.insert(receive.second.recipient.min_i);
|
||||
|
||||
for (const auto& spend : data_->spends)
|
||||
out.insert(spend.second.sender.min_i);
|
||||
if (direction() == Direction_In)
|
||||
{
|
||||
for (const auto& receive : data_->receives)
|
||||
out.insert(receive.second.recipient.min_i);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& spend : data_->spends)
|
||||
out.insert(spend.second.sender.min_i);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -585,6 +585,61 @@ namespace lwsf { namespace internal
|
||||
load_wallet(data_->primary, recovery, nettype, false);
|
||||
}
|
||||
|
||||
|
||||
wallet::wallet(from_keys, const Monero::NetworkType nettype, std::string filename, std::string password, const std::uint64_t kdf_rounds, const std::string& address_string, const std::string& view_key, const std::string& spend_key)
|
||||
: data_(std::make_shared<backend::wallet>()),
|
||||
addressbook_(),
|
||||
history_(),
|
||||
subaddresses_(),
|
||||
subaddress_minor_(),
|
||||
filename_(std::move(filename)),
|
||||
password_(std::move(password)),
|
||||
exception_error_(),
|
||||
status_(),
|
||||
thread_(),
|
||||
iterations_(kdf_rounds),
|
||||
mixin_(config::mixin_default),
|
||||
refresh_interval_(config::refresh_interval),
|
||||
refresh_notify_(),
|
||||
error_sync_(),
|
||||
refresh_sync_(),
|
||||
thread_sync_(),
|
||||
thread_state_(state::stop),
|
||||
mandatory_refresh_(false)
|
||||
{
|
||||
if (sodium_init() < 0)
|
||||
throw std::runtime_error{"Failed to initialize libsodium"};
|
||||
|
||||
data_->primary.generated_locally = false;
|
||||
data_->primary.type = nettype;
|
||||
|
||||
if (!epee::from_hex::to_buffer(epee::as_mut_byte_span(unwrap(unwrap(data_->primary.view.sec))), view_key))
|
||||
{
|
||||
exception_error_ = "view_key contained invalid hex";
|
||||
return;
|
||||
}
|
||||
if (!crypto::secret_key_to_public_key(data_->primary.view.sec, data_->primary.view.pub))
|
||||
{
|
||||
exception_error_ = "view_pub could not be computed";
|
||||
return;
|
||||
}
|
||||
|
||||
crypto::secret_key spend_sec;
|
||||
if (!epee::from_hex::to_buffer(epee::as_mut_byte_span(unwrap(unwrap(data_->primary.spend.sec))), spend_key))
|
||||
{
|
||||
exception_error_ = "spend_key contained invalid hex";
|
||||
return;
|
||||
}
|
||||
if (!crypto::secret_key_to_public_key(data_->primary.spend.sec, data_->primary.spend.pub))
|
||||
{
|
||||
exception_error_ = "spend_pub could not be computed";
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_->get_spend_address({0, 0}) != address_string)
|
||||
exception_error_ = "view_key, spend_key, and address_string do not match";
|
||||
}
|
||||
|
||||
wallet::~wallet() { stop_refresh_loop(); }
|
||||
|
||||
std::string wallet::seed(const std::string& seed_offset) const
|
||||
|
||||
+4
-3
@@ -34,9 +34,10 @@
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "cryptonote_basic/account.h" // monero/src
|
||||
#include <system_error>
|
||||
#include "net/http_client.h" // monero/contrib/epee/include
|
||||
#include "wallet/api/wallet2_api.h" // monero/src
|
||||
|
||||
@@ -89,8 +90,8 @@ namespace internal
|
||||
|
||||
wallet(create, Monero::NetworkType nettype, std::string filename, std::string password, std::uint64_t kdf_rounds);
|
||||
wallet(open, Monero::NetworkType nettpe, std::string filename, std::string password, std::uint64_t kdf_rounds);
|
||||
wallet(from_mnemonic, Monero::NetworkType nettype, std::string path, std::string password, std::uint64_t kdf_rounds, const std::string& mnemonic, const std::string& seed_offset);
|
||||
wallet(from_keys, Monero::NetworkType nettype, std::string path, std::string password, std::uint64_t kdf_rounds, const std::string& mnemonic, const std::string& seed_offset);
|
||||
wallet(from_mnemonic, Monero::NetworkType nettype, std::string filename, std::string password, std::uint64_t kdf_rounds, const std::string& mnemonic, const std::string& seed_offset);
|
||||
wallet(from_keys, Monero::NetworkType nettype, std::string filename, std::string password, std::uint64_t kdf_rounds, const std::string& address_string, const std::string& view_key, const std::string& spend_key);
|
||||
|
||||
wallet(const wallet&) = delete;
|
||||
wallet(wallet&&) = delete;
|
||||
|
||||
+15
-9
@@ -28,11 +28,11 @@
|
||||
|
||||
#include "lws_frontend.h"
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include "backend.h"
|
||||
#include "common/dns_utils.h" // monero/src
|
||||
@@ -178,7 +178,11 @@ namespace lwsf
|
||||
const std::string &spendKeyString,
|
||||
uint64_t kdf_rounds) override
|
||||
{
|
||||
//! \TODO Complete
|
||||
auto out = std::make_unique<wallet>(
|
||||
wallet::from_keys{}, nettype, path, password, kdf_rounds, addressString, viewKeyString, spendKeyString
|
||||
);
|
||||
out->setRefreshFromBlockHeight(restoreHeight);
|
||||
return out.release();
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -201,7 +205,7 @@ namespace lwsf
|
||||
const std::string &viewKeyString,
|
||||
const std::string &spendKeyString) override
|
||||
{
|
||||
//! \TODO Complete
|
||||
return createWalletFromKeys(path, "", language, nettype, restoreHeight, addressString, viewKeyString, spendKeyString, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -252,7 +256,7 @@ namespace lwsf
|
||||
*/
|
||||
bool walletExists(const std::string &path) override
|
||||
{
|
||||
return lwsf::internal::wallet::is_wallet_file(path);
|
||||
return wallet::is_wallet_file(path);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -269,7 +273,7 @@ namespace lwsf
|
||||
*/
|
||||
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool, uint64_t) const override
|
||||
{
|
||||
lwsf::internal::wallet::verify_password(keys_file_name, password);
|
||||
return wallet::verify_password(keys_file_name, password);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -294,7 +298,7 @@ namespace lwsf
|
||||
*/
|
||||
std::vector<std::string> findWallets(const std::string &path) override
|
||||
{
|
||||
return lwsf::internal::wallet::find(path);
|
||||
return wallet::find(path);
|
||||
}
|
||||
|
||||
std::string errorString() const override { return error_; }
|
||||
@@ -355,21 +359,23 @@ namespace lwsf
|
||||
|
||||
std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const override
|
||||
{
|
||||
const boost::string_ref prefix{"oa1:xmr "};
|
||||
static constexpr const std::string_view prefix{"oa1:xmr "};
|
||||
std::string real_address =
|
||||
tools::DNSResolver::instance().get_dns_format_from_oa_address(address);
|
||||
|
||||
bool dnssec_available = false;
|
||||
std::vector<std::string> records =
|
||||
tools::DNSResolver::instance().get_txt_record(real_address, dnssec_available, dnssec_valid);
|
||||
for (boost::string_ref record : records)
|
||||
for (std::string_view record : records)
|
||||
{
|
||||
if (record.starts_with(prefix))
|
||||
if (record.substr(0, prefix.size()) == prefix)
|
||||
{
|
||||
record = record.substr(prefix.size());
|
||||
return std::string{record.data(), record.size()};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//! checks for an update and returns version, hash and url
|
||||
|
||||
Reference in New Issue
Block a user