mirror of
https://github.com/wownero/lwsf-wow.git
synced 2026-10-17 07:21:28 +02:00
238 lines
7.1 KiB
C++
238 lines
7.1 KiB
C++
// Copyright (c) 2024, The Monero Project
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification, are
|
|
// permitted provided that the following conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
// conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
// of conditions and the following disclaimer in the documentation and/or other
|
|
// materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
// used to endorse or promote products derived from this software without specific
|
|
// prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <boost/container/flat_map.hpp>
|
|
#include <boost/thread/mutex.hpp>
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <filesystem>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <unordered_map>
|
|
#include <type_traits>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include "byte_slice.h" // monero/contrib/epee/include
|
|
#include "common/expect.h" // moneor/src
|
|
#include "crypto/crypto.h" // monero/src
|
|
#include "crypto/hash.h" // monero/src
|
|
#include "cryptonote_config.h" // monero/src
|
|
#include "net/http_client.h" // monero/contrib/epee/include
|
|
#include "ringct/rctTypes.h" // monero/src
|
|
#include "rpc.h"
|
|
#include "wallet/api/wallet2_api.h" // monero/src
|
|
#include "wire/fwd.h"
|
|
|
|
namespace lwsf { namespace internal { namespace backend
|
|
{
|
|
struct memory
|
|
{
|
|
template<typename T>
|
|
bool operator()(const T& lhs, const T& rhs) const noexcept
|
|
{
|
|
static_assert(std::is_pod<T>::value);
|
|
return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(T)) < 0;
|
|
}
|
|
};
|
|
|
|
struct address_book_entry
|
|
{
|
|
std::string address;
|
|
std::string payment_id;
|
|
std::string description;
|
|
};
|
|
WIRE_DECLARE_OBJECT(address_book_entry);
|
|
|
|
struct subaddress
|
|
{
|
|
std::string label;
|
|
|
|
bool preserve() const noexcept { return !label.empty(); }
|
|
};
|
|
WIRE_DECLARE_OBJECT(subaddress);
|
|
|
|
struct sub_account
|
|
{
|
|
boost::container::flat_map<std::uint32_t, subaddress> minor;
|
|
};
|
|
WIRE_DECLARE_OBJECT(sub_account);
|
|
|
|
struct transfer_out
|
|
{
|
|
std::string address;
|
|
std::uint64_t amount;
|
|
rpc::address_meta sender;
|
|
std::optional<crypto::secret_key> secret;
|
|
crypto::public_key tx_pub;
|
|
crypto::public_key output_pub;
|
|
|
|
transfer_out()
|
|
: address(), amount(0), sender{}, secret(), tx_pub{}, output_pub{}
|
|
{}
|
|
};
|
|
WIRE_DECLARE_OBJECT(transfer_out);
|
|
|
|
struct transfer_in
|
|
{
|
|
std::uint64_t global_index;
|
|
std::uint64_t amount;
|
|
rpc::address_meta recipient;
|
|
std::uint16_t index;
|
|
std::optional<rct::key> rct_mask;
|
|
crypto::public_key tx_pub;
|
|
|
|
transfer_in()
|
|
: global_index(0),
|
|
amount(0),
|
|
recipient{},
|
|
index(0),
|
|
rct_mask(),
|
|
tx_pub{}
|
|
{}
|
|
};
|
|
WIRE_DECLARE_OBJECT(transfer_in);
|
|
|
|
struct transaction
|
|
{
|
|
transaction()
|
|
: spends(),
|
|
receives(),
|
|
description(),
|
|
timestamp(),
|
|
height(),
|
|
amount(0),
|
|
fee(0),
|
|
unlock_time(0),
|
|
direction(Monero::TransactionInfo::Direction_Out),
|
|
payment_id(),
|
|
id{},
|
|
prefix{},
|
|
coinbase(false),
|
|
failed(false)
|
|
{}
|
|
|
|
transaction(transaction&&) = default;
|
|
transaction(const transaction&) = default;
|
|
transaction& operator=(transaction&&) = default;
|
|
transaction& operator=(const transaction&) = default;
|
|
|
|
bool is_unlocked(std::uint64_t chain_height, Monero::NetworkType type) const;
|
|
|
|
/*! flat_map is used here for faster copies/merging. A single allocation
|
|
is needed in the copy (done every refresh interval), instead of an
|
|
allocation per key. */
|
|
boost::container::flat_map<crypto::key_image, transfer_out, memory> spends;
|
|
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::uint64_t unlock_time;
|
|
Monero::TransactionInfo::Direction direction;
|
|
std::variant<rpc::empty, crypto::hash8, crypto::hash> payment_id;
|
|
crypto::hash id;
|
|
crypto::hash prefix;
|
|
bool coinbase;
|
|
bool failed;
|
|
};
|
|
WIRE_DECLARE_OBJECT(transaction);
|
|
|
|
struct keypair
|
|
{
|
|
keypair() = delete;
|
|
crypto::secret_key sec;
|
|
crypto::public_key pub;
|
|
};
|
|
WIRE_DECLARE_OBJECT(keypair);
|
|
|
|
struct account
|
|
{
|
|
account() = delete;
|
|
|
|
std::string address; //!> not serialized, recovered on read_bytes
|
|
std::string language;
|
|
std::vector<address_book_entry> addressbook;
|
|
std::map<std::uint32_t, sub_account> subaccounts;
|
|
std::unordered_map<crypto::hash, std::shared_ptr<transaction>> txes;
|
|
std::unordered_map<std::string, std::string> attributes;
|
|
std::uint64_t scan_height;
|
|
std::uint64_t restore_height;
|
|
Monero::NetworkType type;
|
|
keypair view;
|
|
keypair spend;
|
|
bool generated_locally;
|
|
};
|
|
WIRE_DECLARE_OBJECT(account);
|
|
|
|
struct wallet
|
|
{
|
|
Monero::WalletListener* listener;
|
|
rpc::http_client client;
|
|
account primary;
|
|
std::atomic<std::chrono::steady_clock::time_point::duration::rep> last_sync;
|
|
std::uint64_t blockchain_height;
|
|
std::uint64_t per_byte_fee;
|
|
std::uint64_t fee_mask;
|
|
mutable boost::mutex sync;
|
|
boost::mutex sync_listener;
|
|
boost::mutex sync_refresh;
|
|
bool passed_login;
|
|
|
|
wallet();
|
|
|
|
cryptonote::network_type get_net_type() const;
|
|
crypto::public_key get_spend_public(const rpc::address_meta& index) const;
|
|
std::string get_spend_address(const rpc::address_meta& index) const;
|
|
|
|
//! Serializate `this` wallet to msgpack. Locks contents.
|
|
expect<epee::byte_slice> to_bytes() const;
|
|
|
|
//! De-serialize `this` from msgpack. Locks+replaces contents.
|
|
std::error_code from_bytes(epee::byte_slice source);
|
|
|
|
//! Attempt
|
|
std::error_code login();
|
|
|
|
//! Refreshes txes information. Strong exception guarantee. Locks contents.
|
|
std::error_code refresh(bool mandatory = false);
|
|
|
|
std::error_code add_subaccount(std::string label);
|
|
|
|
std::error_code restore_height(const std::uint64_t height);
|
|
|
|
std::error_code send_tx(epee::byte_slice tx_bytes);
|
|
};
|
|
}}} // lwsf // internal // backend
|