mirror of
https://github.com/wownero/lwsf-wow.git
synced 2026-10-17 07:21:28 +02:00
742 lines
21 KiB
C++
742 lines
21 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 <boost/container/flat_map.hpp>
|
|
#include <boost/container/flat_set.hpp>
|
|
#include <boost/core/demangle.hpp>
|
|
#include <boost/optional/optional.hpp>
|
|
#include <boost/thread/locks.hpp>
|
|
#include <boost/variant.hpp>
|
|
#include <chrono>
|
|
#include <ctime>
|
|
#include <system_error>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
#include "byte_slice.h" // monero/contrib/epee/include
|
|
#include "byte_stream.h" // moneor/contrib/epee/include
|
|
#include "common/expect.h" // monero/src
|
|
#include "crypto/crypto.h" // monero/src
|
|
#include "error.h"
|
|
#include "lwsf_config.h"
|
|
#include "net/http.h"
|
|
#include "ringct/rctTypes.h" // monero/src
|
|
#include "wire/basic_value.h"
|
|
#include "wire/fwd.h"
|
|
#include "wire/json.h"
|
|
#include "wire/msgpack/fwd.h"
|
|
#include "wire/traits.h"
|
|
|
|
namespace lwsf { namespace internal { namespace rpc
|
|
{
|
|
using max_subaddrs = wire::max_element_count<16384>;
|
|
struct daemon_status;
|
|
|
|
template<typename T, typename F>
|
|
struct unpacker
|
|
{
|
|
T* out;
|
|
F f;
|
|
|
|
void operator()(std::error_code error, epee::byte_slice response)
|
|
{
|
|
LWSF_VERIFY(out);
|
|
if (!error)
|
|
{
|
|
error = wire::json::from_bytes({reinterpret_cast<const char*>(response.data()), response.size()}, *out);
|
|
if (error)
|
|
MERROR("Failed to unpack " << boost::core::demangle(typeid(T).name()) << ": " << error.message());
|
|
}
|
|
f(error);
|
|
}
|
|
};
|
|
|
|
|
|
/*! `f` may be buffered in `client` (i.e. NOT in ASIO _yet_), and therefore
|
|
callers need to ensure `f` only has `weak_ptr` to object owning `client`. */
|
|
template<typename T, typename U, typename F>
|
|
void invoke_async(const http::client& client, const T& in, U* out, F f)
|
|
{
|
|
// /daemon_status historically needed to be a post
|
|
if constexpr (!std::is_empty<T>{} || std::is_same<U, daemon_status>{})
|
|
{
|
|
epee::byte_stream sink{};
|
|
std::error_code error = wire::json::to_bytes(sink, in);
|
|
if (error)
|
|
return f(error);
|
|
client.post_async(U::endpoint(), epee::byte_slice{std::move(sink)}, unpacker<U, F>{out, std::move(f)});
|
|
}
|
|
else
|
|
client.get_async(U::endpoint(), unpacker<U, F>{out, std::move(f)});
|
|
}
|
|
|
|
struct empty {};
|
|
WIRE_DECLARE_OBJECT(empty);
|
|
|
|
struct address_meta
|
|
{
|
|
std::uint32_t maj_i;
|
|
std::uint32_t min_i;
|
|
|
|
constexpr address_meta() noexcept
|
|
: maj_i(0), min_i(0)
|
|
{}
|
|
|
|
constexpr address_meta(const std::uint32_t maj, std::uint32_t min) noexcept
|
|
: maj_i(maj), min_i(min)
|
|
{}
|
|
|
|
constexpr address_meta(config::lookahead src) noexcept
|
|
: maj_i(src.major), min_i(src.minor)
|
|
{}
|
|
|
|
constexpr bool is_default() const noexcept { return !maj_i && !min_i; }
|
|
};
|
|
WIRE_DECLARE_OBJECT(address_meta);
|
|
|
|
inline constexpr bool operator<(const address_meta& lhs, const address_meta& rhs) noexcept
|
|
{
|
|
return lhs.maj_i == rhs.maj_i ?
|
|
lhs.min_i < rhs.min_i : lhs.maj_i < rhs.maj_i;
|
|
}
|
|
inline constexpr bool operator==(const address_meta& lhs, const address_meta& rhs) noexcept
|
|
{
|
|
return lhs.maj_i == rhs.maj_i && lhs.min_i == rhs.min_i;
|
|
}
|
|
inline constexpr bool operator!=(const address_meta& lhs, const address_meta& rhs) noexcept
|
|
{
|
|
return lhs.maj_i != rhs.maj_i || lhs.min_i != rhs.min_i;
|
|
}
|
|
|
|
|
|
struct login
|
|
{
|
|
login() = delete;
|
|
|
|
std::string address;
|
|
crypto::secret_key view_key;
|
|
};
|
|
void write_bytes(wire::writer&, const login&);
|
|
|
|
|
|
struct login_request
|
|
{
|
|
login_request() = delete;
|
|
|
|
std::string address;
|
|
crypto::secret_key view_key;
|
|
address_meta lookahead;
|
|
bool create_account;
|
|
bool generated_locally;
|
|
};
|
|
void write_bytes(wire::json_writer&, const login_request&);
|
|
|
|
struct login_response
|
|
{
|
|
login_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/login"; }
|
|
|
|
boost::optional<std::uint64_t> start_height;
|
|
boost::optional<address_meta> lookahead;
|
|
bool new_address;
|
|
};
|
|
void read_bytes(wire::json_reader&, login_response&);
|
|
|
|
|
|
struct daemon_status
|
|
{
|
|
daemon_status() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/daemon_status"; }
|
|
std::uint64_t outgoing_connections_count;
|
|
std::uint64_t incoming_connections_count;
|
|
std::uint64_t height;
|
|
std::uint64_t target_height;
|
|
};
|
|
void read_bytes(wire::json_reader&, daemon_status&);
|
|
|
|
|
|
enum class feed_status : std::uint16_t
|
|
{
|
|
unspecified_error = 0,
|
|
account_not_found,
|
|
bad_address,
|
|
bad_view_key,
|
|
blockchain_reorg,
|
|
daemon_unresponsive,
|
|
parse_error,
|
|
protocol_error,
|
|
queue_error,
|
|
schema_error
|
|
};
|
|
WIRE_AS_INTEGER(feed_status);
|
|
|
|
struct feed
|
|
{
|
|
feed() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/feed"; }
|
|
static constexpr const char* protocol() noexcept { return "lws.feed.v0.msgpack"; }
|
|
};
|
|
void read_bytes(wire::json_reader&, const feed&);
|
|
|
|
struct feed_tx
|
|
{
|
|
struct legacy_id
|
|
{
|
|
legacy_id() = delete;
|
|
std::uint64_t amount;
|
|
std::uint64_t index;
|
|
};
|
|
|
|
struct output_id { legacy_id legacy; };
|
|
|
|
struct receive
|
|
{
|
|
std::uint64_t amount;
|
|
output_id id;
|
|
address_meta recipient;
|
|
std::uint16_t index;
|
|
boost::optional<rct::key> rct;
|
|
crypto::public_key public_key;
|
|
crypto::public_key tx_pub_key;
|
|
|
|
receive() noexcept
|
|
: amount(0), id{}, recipient{}, index(0), rct(), public_key{}, tx_pub_key{}
|
|
{}
|
|
|
|
receive(std::uint64_t amount, const output_id& id, const address_meta& recipient, std::uint16_t index, const boost::optional<rct::key> rct, const crypto::public_key& public_key, const crypto::public_key& tx_pub_key) noexcept
|
|
: amount(amount), id(id), recipient(recipient), index(index), rct(rct), public_key(public_key), tx_pub_key(tx_pub_key)
|
|
{}
|
|
};
|
|
|
|
struct spend
|
|
{
|
|
output_id id;
|
|
crypto::key_image key_image;
|
|
|
|
spend() noexcept
|
|
: id{}, key_image{}
|
|
{}
|
|
};
|
|
|
|
std::vector<receive> receives;
|
|
std::vector<spend> spends;
|
|
std::uint64_t fee;
|
|
std::uint64_t unlock_time;
|
|
std::uint64_t height;
|
|
std::chrono::system_clock::time_point timestamp;
|
|
std::uint32_t mixin;
|
|
std::variant<empty, crypto::hash8, crypto::hash> payment_id;
|
|
crypto::hash hash;
|
|
crypto::hash prefix_hash;
|
|
bool coinbase;
|
|
bool mempool;
|
|
|
|
//! Hack because `boost/std::optional` sort left adjacent
|
|
static constexpr std::uint64_t txpool() noexcept { return std::uint64_t(-1); }
|
|
|
|
feed_tx()
|
|
: receives(),
|
|
spends(),
|
|
unlock_time(0),
|
|
height(),
|
|
timestamp(),
|
|
mixin(),
|
|
payment_id(),
|
|
hash{},
|
|
prefix_hash{},
|
|
coinbase(false),
|
|
mempool(false)
|
|
{}
|
|
|
|
boost::optional<std::uint64_t> get_height() const noexcept
|
|
{ return boost::make_optional(height != txpool(), height); }
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_tx&);
|
|
|
|
inline constexpr bool operator==(const feed_tx::output_id& lhs, const feed_tx::output_id& rhs) noexcept
|
|
{
|
|
return lhs.legacy.index == rhs.legacy.index && lhs.legacy.amount == rhs.legacy.amount;
|
|
}
|
|
inline constexpr bool operator!=(const feed_tx::output_id& lhs, const feed_tx::output_id& rhs) noexcept
|
|
{
|
|
return lhs.legacy.index != rhs.legacy.index || lhs.legacy.amount != rhs.legacy.amount;
|
|
}
|
|
inline constexpr bool operator<(const feed_tx::output_id& lhs, const feed_tx::output_id& rhs) noexcept
|
|
{
|
|
return lhs.legacy.amount == rhs.legacy.amount ?
|
|
lhs.legacy.index < rhs.legacy.index : lhs.legacy.amount < rhs.legacy.amount;
|
|
}
|
|
|
|
struct feed_blocks
|
|
{
|
|
feed_blocks() = delete;
|
|
static constexpr const char* prefix() noexcept { return "blocks:"; }
|
|
|
|
std::vector<feed_tx> transactions;
|
|
std::uint64_t scan_start;
|
|
std::uint64_t scan_end;
|
|
std::uint64_t blockchain_height;
|
|
boost::optional<std::uint64_t> lookahead_fail;
|
|
address_meta lookahead;
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_blocks&);
|
|
|
|
struct feed_error
|
|
{
|
|
feed_error() = delete;
|
|
static constexpr const char* prefix() noexcept { return "error:"; }
|
|
|
|
std::string msg;
|
|
feed_status code;
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_error&);
|
|
|
|
struct feed_login
|
|
{
|
|
feed_login() = delete;
|
|
static constexpr const char* prefix() noexcept { return "login:"; }
|
|
login account;
|
|
};
|
|
void write_bytes(wire::msgpack_writer&, const feed_login&);
|
|
|
|
//! One specific output is sent per-message
|
|
struct feed_mempool
|
|
{
|
|
feed_mempool() = delete;
|
|
static constexpr const char* prefix() noexcept { return "mempool:"; }
|
|
|
|
std::uint64_t amount;
|
|
std::uint64_t fee;
|
|
std::uint64_t unlock_time;
|
|
address_meta recipient;
|
|
std::uint32_t mixin;
|
|
std::variant<empty, crypto::hash8, crypto::hash> payment_id;
|
|
boost::optional<rct::key> rct;
|
|
crypto::hash hash;
|
|
crypto::hash prefix_hash;
|
|
crypto::public_key public_key;
|
|
crypto::public_key tx_pub_key;
|
|
std::uint16_t index;
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_mempool&);
|
|
|
|
struct feed_tx_sync
|
|
{
|
|
feed_tx_sync() = delete;
|
|
static constexpr const char* prefix() noexcept { return "tx_sync:"; }
|
|
|
|
std::vector<feed_tx> transactions;
|
|
std::uint64_t scanned_block_height;
|
|
std::uint64_t start_height;
|
|
std::uint64_t blockchain_height;
|
|
boost::optional<std::uint64_t> lookahead_fail;
|
|
address_meta lookahead;
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_tx_sync&);
|
|
|
|
struct feed_warning
|
|
{
|
|
feed_warning() = delete;
|
|
static constexpr const char* prefix() noexcept { return "warning:"; }
|
|
|
|
std::string msg;
|
|
std::uint64_t height;
|
|
feed_status code;
|
|
};
|
|
void read_bytes(wire::msgpack_reader&, feed_warning&);
|
|
|
|
|
|
enum class uint64_string : std::uint64_t {};
|
|
void write_bytes(wire::json_writer&, uint64_string);
|
|
void read_bytes(wire::json_reader&, uint64_string&);
|
|
|
|
struct transaction_spend
|
|
{
|
|
uint64_string amount;
|
|
boost::optional<address_meta> sender;
|
|
std::uint16_t out_index;
|
|
crypto::key_image key_image;
|
|
crypto::public_key tx_pub_key;
|
|
|
|
transaction_spend() noexcept
|
|
: amount(uint64_string(0)),
|
|
sender(),
|
|
out_index(0),
|
|
key_image{},
|
|
tx_pub_key{}
|
|
{}
|
|
|
|
transaction_spend(const feed_tx::spend& spend, const feed_tx::receive& receive) noexcept
|
|
: amount(uint64_string(receive.amount)),
|
|
sender(receive.recipient),
|
|
out_index(receive.index),
|
|
key_image(spend.key_image),
|
|
tx_pub_key(receive.tx_pub_key)
|
|
{}
|
|
};
|
|
void read_bytes(wire::json_reader&, transaction_spend&);
|
|
|
|
struct transaction
|
|
{
|
|
std::vector<transaction_spend> spent_outputs;
|
|
std::variant<empty, crypto::hash8, crypto::hash> payment_id;
|
|
boost::optional<std::time_t> timestamp;
|
|
boost::optional<uint64_string> fee;
|
|
uint64_string total_received;
|
|
std::uint64_t unlock_time;
|
|
boost::optional<std::uint64_t> height;
|
|
crypto::hash hash;
|
|
bool coinbase;
|
|
bool mempool;
|
|
|
|
transaction()
|
|
: spent_outputs(),
|
|
payment_id(),
|
|
timestamp(),
|
|
fee(),
|
|
total_received(uint64_string(0)),
|
|
unlock_time(0),
|
|
height(),
|
|
hash{},
|
|
coinbase(false),
|
|
mempool(false)
|
|
{}
|
|
|
|
transaction(const feed_tx& src)
|
|
: spent_outputs(),
|
|
payment_id(src.payment_id),
|
|
timestamp(std::chrono::system_clock::to_time_t(src.timestamp)),
|
|
fee(uint64_string(src.fee)),
|
|
total_received(uint64_string(0)),
|
|
unlock_time(src.unlock_time),
|
|
height(src.get_height()),
|
|
hash(src.hash),
|
|
coinbase(src.coinbase),
|
|
mempool(src.mempool)
|
|
{
|
|
std::uint64_t total = 0;
|
|
for (const auto& received : src.receives)
|
|
total += received.amount;
|
|
total_received = uint64_string(total);
|
|
}
|
|
};
|
|
void read_bytes(wire::json_reader&, transaction&);
|
|
|
|
struct get_address_txs
|
|
{
|
|
get_address_txs() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/get_address_txs"; }
|
|
|
|
std::vector<transaction> transactions;
|
|
boost::optional<std::uint64_t> lookahead_fail;
|
|
std::uint64_t scanned_block_height;
|
|
std::uint64_t start_height;
|
|
std::uint64_t blockchain_height;
|
|
address_meta lookahead;
|
|
};
|
|
void read_bytes(wire::json_reader&, get_address_txs&);
|
|
|
|
|
|
struct get_version
|
|
{
|
|
get_version() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/get_version"; }
|
|
|
|
std::uint64_t max_subaddresses;
|
|
};
|
|
void read_bytes(wire::json_reader&, get_version&);
|
|
|
|
|
|
struct random_output
|
|
{
|
|
random_output()
|
|
: global_index(uint64_string(0)), public_key{}, rct{}
|
|
{}
|
|
|
|
uint64_string global_index;
|
|
rct::key public_key;
|
|
rct::key rct;
|
|
};
|
|
void read_bytes(wire::json_reader&, random_output&);
|
|
|
|
struct random_outputs
|
|
{
|
|
random_outputs()
|
|
: outputs(), amount(uint64_string(0))
|
|
{}
|
|
|
|
std::vector<random_output> outputs;
|
|
uint64_string amount;
|
|
};
|
|
void read_bytes(wire::json_reader&, random_outputs&);
|
|
|
|
struct get_random_outs_request
|
|
{
|
|
get_random_outs_request() = delete;
|
|
|
|
std::vector<uint64_string> amounts;
|
|
std::uint32_t count; // mixin
|
|
};
|
|
void write_bytes(wire::json_writer&, const get_random_outs_request&);
|
|
|
|
struct get_random_outs_response
|
|
{
|
|
get_random_outs_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/get_random_outs"; }
|
|
|
|
std::vector<random_outputs> amount_outs;
|
|
};
|
|
void read_bytes(wire::json_reader&, get_random_outs_response&);
|
|
|
|
|
|
struct subaddrs
|
|
{
|
|
subaddrs() noexcept
|
|
: value()
|
|
{}
|
|
|
|
explicit subaddrs(const std::uint32_t last) noexcept
|
|
: value()
|
|
{
|
|
value.insert({0, last});
|
|
}
|
|
|
|
//! \return true if `this` represents a canonical range of values.
|
|
bool is_valid() const noexcept;
|
|
|
|
// Merge `{0, index}` to the set of subaddresses.
|
|
void merge(std::uint32_t index);
|
|
|
|
boost::container::flat_set<std::array<std::uint32_t, 2>, std::less<>> value;
|
|
};
|
|
WIRE_JSON_DECLARE_OBJECT(subaddrs);
|
|
void read_bytes(wire::json_reader&, subaddrs&);
|
|
|
|
struct get_subaddrs
|
|
{
|
|
using mapped_type = std::pair<std::uint32_t, subaddrs>;
|
|
get_subaddrs() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/get_subaddrs"; }
|
|
|
|
boost::container::flat_map<std::uint32_t, subaddrs> all_subaddrs;
|
|
};
|
|
WIRE_JSON_DECLARE_OBJECT(get_subaddrs::mapped_type);
|
|
void read_bytes(wire::json_reader&, get_subaddrs&);
|
|
|
|
|
|
struct ringct
|
|
{
|
|
enum class format : std::uint8_t
|
|
{
|
|
none = 0, //!< Not ringct
|
|
encrypted,
|
|
recompute,
|
|
unencrypted
|
|
};
|
|
|
|
ringct() noexcept
|
|
: mask{}, type(format::none)
|
|
{}
|
|
|
|
ringct(const rct::key& mask, const format type) noexcept
|
|
: mask(mask), type(type)
|
|
{}
|
|
|
|
ringct(const boost::optional<rct::key>& src) noexcept
|
|
: mask(src.value_or(rct::key{})),
|
|
type(bool(src) ? format::unencrypted : format::none)
|
|
{}
|
|
|
|
rct::key mask;
|
|
format type;
|
|
};
|
|
|
|
struct output
|
|
{
|
|
uint64_string amount;
|
|
uint64_string global_index;
|
|
boost::optional<address_meta> recipient;
|
|
std::uint16_t index;
|
|
ringct rct;
|
|
crypto::hash tx_hash;
|
|
crypto::hash tx_prefix_hash;
|
|
crypto::public_key public_key;
|
|
crypto::public_key tx_pub_key;
|
|
|
|
output() noexcept
|
|
: amount(uint64_string(0)),
|
|
global_index(uint64_string(0)),
|
|
recipient(),
|
|
index(0),
|
|
rct{},
|
|
tx_hash{},
|
|
tx_prefix_hash{},
|
|
public_key{},
|
|
tx_pub_key{}
|
|
{}
|
|
|
|
output(const feed_mempool& src) noexcept
|
|
: amount(uint64_string(src.amount)),
|
|
global_index(uint64_string(std::numeric_limits<std::uint64_t>::max())),
|
|
recipient(src.recipient),
|
|
index(src.index),
|
|
rct(src.rct),
|
|
tx_hash(src.hash),
|
|
tx_prefix_hash(src.prefix_hash),
|
|
public_key(src.public_key),
|
|
tx_pub_key(src.tx_pub_key)
|
|
{}
|
|
|
|
output(const feed_tx::receive& src, const feed_tx& tx) noexcept
|
|
: amount(uint64_string(src.amount)),
|
|
global_index(uint64_string(src.id.legacy.index)),
|
|
recipient(src.recipient),
|
|
index(src.index),
|
|
rct(src.rct),
|
|
tx_hash(tx.hash),
|
|
tx_prefix_hash(tx.prefix_hash),
|
|
public_key(src.public_key),
|
|
tx_pub_key(src.tx_pub_key)
|
|
{}
|
|
};
|
|
void read_bytes(wire::json_reader&, output&);
|
|
|
|
struct get_unspent_outs_request
|
|
{
|
|
get_unspent_outs_request() = delete;
|
|
login creds;
|
|
uint64_string amount;
|
|
std::uint32_t mixin;
|
|
bool use_dust;
|
|
};
|
|
void write_bytes(wire::json_writer&, const get_unspent_outs_request&);
|
|
|
|
struct get_unspent_outs_response
|
|
{
|
|
get_unspent_outs_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/get_unspent_outs"; }
|
|
|
|
std::vector<output> outputs;
|
|
std::vector<std::uint64_t> fees;
|
|
std::uint64_t per_byte_fee;
|
|
std::uint64_t fee_mask;
|
|
};
|
|
void read_bytes(wire::json_reader&, get_unspent_outs_response&);
|
|
|
|
|
|
struct import_request
|
|
{
|
|
import_request() = delete;
|
|
login creds;
|
|
std::uint64_t from_height;
|
|
address_meta lookahead;
|
|
};
|
|
void write_bytes(wire::json_writer&, const import_request&);
|
|
|
|
struct import_response
|
|
{
|
|
import_response() = delete;
|
|
import_response(import_response&&) = default;
|
|
import_response(const import_response&) = delete;
|
|
import_response& operator=(import_response&&) = default;
|
|
import_response& operator=(const import_response&) = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/import_wallet_request"; }
|
|
|
|
boost::optional<std::string> payment_address;
|
|
boost::optional<epee::byte_slice> payment_id;
|
|
boost::optional<uint64_string> import_fee;
|
|
boost::optional<address_meta> lookahead;
|
|
std::string status;
|
|
bool new_request;
|
|
bool request_fulfilled;
|
|
};
|
|
void read_bytes(wire::json_reader&, import_response&);
|
|
|
|
|
|
struct provision_subaddrs_request
|
|
{
|
|
provision_subaddrs_request() = delete;
|
|
login creds;
|
|
std::uint32_t maj_i;
|
|
std::uint32_t min_i;
|
|
std::uint32_t n_maj;
|
|
std::uint32_t n_min;
|
|
bool get_all;
|
|
};
|
|
void write_bytes(wire::json_writer&, const provision_subaddrs_request&);
|
|
|
|
struct provision_subaddrs_response
|
|
{
|
|
provision_subaddrs_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/provision_subaddrs"; }
|
|
|
|
boost::container::flat_map<std::uint32_t, subaddrs> new_subaddrs;
|
|
boost::container::flat_map<std::uint32_t, subaddrs> all_subaddrs;
|
|
};
|
|
void read_bytes(wire::json_reader&, provision_subaddrs_response&);
|
|
|
|
|
|
struct submit_raw_tx_request
|
|
{
|
|
submit_raw_tx_request() = delete;
|
|
epee::byte_slice tx;
|
|
};
|
|
void write_bytes(wire::json_writer&, const submit_raw_tx_request&);
|
|
|
|
struct submit_raw_tx_response
|
|
{
|
|
submit_raw_tx_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/submit_raw_tx"; }
|
|
|
|
std::string status;
|
|
};
|
|
void read_bytes(wire::json_reader&, submit_raw_tx_response&);
|
|
|
|
|
|
struct upsert_subaddrs_request
|
|
{
|
|
upsert_subaddrs_request() = delete;
|
|
login creds;
|
|
boost::container::flat_map<std::uint32_t, subaddrs> subaddrs_;
|
|
bool get_all;
|
|
};
|
|
void write_bytes(wire::json_writer&, const upsert_subaddrs_request&);
|
|
|
|
struct upsert_subaddrs_response
|
|
{
|
|
upsert_subaddrs_response() = delete;
|
|
static constexpr const char* endpoint() noexcept { return "/upsert_subaddrs"; }
|
|
};
|
|
void read_bytes(wire::json_reader&, upsert_subaddrs_response&);
|
|
|
|
}}} // lwsf // internal // rpc
|
|
|
|
WIRE_DECLARE_BLOB(lwsf::internal::rpc::ringct);
|
|
|