7#include "bech32/bech32.h"
8#include "bech32/util/strencodings.h"
10#include "crypto/sha256.h"
21 static constexpr auto min_mint_arg_count = 7;
22 if(args.size() < min_mint_arg_count) {
23 std::cerr <<
"Mint requires args <n outputs> <output value>"
28 const auto n_outputs = std::stoull(args[5]);
29 const auto output_val = std::stoul(args[6]);
32 = client.mint(n_outputs,
static_cast<uint32_t
>(output_val));
39 const std::optional<cbdc::transaction::full_tx>& tx,
40 const std::optional<cbdc::sentinel::execute_response>& resp,
42 std::cout <<
"tx_id:" << std::endl
46 for(
const auto& inp : inputs) {
48 std::cout <<
"Data for recipient importinput:" << std::endl
49 << buf.to_hex() << std::endl;
52 if(resp.has_value()) {
53 std::cout <<
"Sentinel responded: "
56 if(resp.value().m_tx_error.has_value()) {
57 std::cout <<
"Validation error: "
59 resp.value().m_tx_error.value())
67 static constexpr auto min_send_arg_count = 7;
68 if(args.size() < min_send_arg_count) {
69 std::cerr <<
"Send requires args <value> <pubkey>" << std::endl;
73 const auto value = std::stoul(args[5]);
74 static constexpr auto address_arg_idx = 6;
76 if(!pubkey.has_value()) {
77 std::cout <<
"Could not decode address" << std::endl;
82 = client.send(
static_cast<uint32_t
>(value), pubkey.value());
84 std::cout <<
"Could not generate valid send tx." << std::endl;
94 static constexpr auto min_fan_arg_count = 8;
95 if(args.size() < min_fan_arg_count) {
96 std::cerr <<
"Fan requires args <count> <value> <pubkey>" << std::endl;
100 const auto value = std::stoul(args[6]);
101 const auto count = std::stoul(args[5]);
103 static constexpr auto address_arg_idx = 7;
105 if(!pubkey.has_value()) {
106 std::cout <<
"Could not decode address" << std::endl;
110 const auto [tx, resp] = client.fan(
static_cast<uint32_t
>(count),
111 static_cast<uint32_t
>(value),
113 if(!tx.has_value()) {
114 std::cout <<
"Could not generate valid send tx." << std::endl;
126 + std::tuple_size<
decltype(addr)>::value);
128 std::copy_n(addr.begin(),
132 auto data = std::vector<uint8_t>();
133 ConvertBits<cbdc::address::bits_per_byte,
134 cbdc::address::bech32_bits_per_symbol,
141 std::cout << bech32::Encode(cbdc::config::bech32_hrp, data) << std::endl;
145 const std::vector<std::string>& args) ->
bool {
146 static constexpr auto input_arg_idx = 5;
148 if(!buffer.has_value()) {
149 std::cout <<
"Invalid input encoding." << std::endl;
154 if(!in.has_value()) {
155 std::cout <<
"Invalid input" << std::endl;
158 client.import_send_input(in.value());
163 const std::vector<std::string>& args) ->
bool {
165 auto success = client.confirm_transaction(tx_id);
167 std::cout <<
"Unknown TXID" << std::endl;
170 std::cout <<
"Confirmed. Balance: "
172 <<
" UTXOs: " << client.utxo_count() << std::endl;
177auto main(
int argc,
char** argv) ->
int {
179 static constexpr auto min_arg_count = 5;
180 if(args.size() < min_arg_count) {
181 std::cerr <<
"Usage: " << args[0]
182 <<
" <config file> <client file> <wallet file> <command>"
183 <<
" <args...>" << std::endl;
188 if(std::holds_alternative<std::string>(cfg_or_err)) {
189 std::cerr <<
"Error loading config file: "
190 << std::get<std::string>(cfg_or_err) << std::endl;
194 auto opts = std::get<cbdc::config::options>(cfg_or_err);
198 const auto wallet_file = args[3];
199 const auto client_file = args[2];
201 auto logger = std::make_shared<cbdc::logging::log>(
202 cbdc::config::defaults::log_level);
204 auto client = std::unique_ptr<cbdc::client>();
205 if(opts.m_twophase_mode) {
206 client = std::make_unique<cbdc::twophase_client>(opts,
211 client = std::make_unique<cbdc::atomizer_client>(opts,
217 if(!client->init()) {
221 const auto command = std::string(args[4]);
222 if(command ==
"mint") {
226 }
else if(command ==
"send") {
230 }
else if(command ==
"fan") {
234 }
else if(command ==
"sync") {
236 }
else if(command ==
"newaddress") {
238 }
else if(command ==
"info") {
239 const auto balance = client->balance();
240 const auto n_txos = client->utxo_count();
242 <<
", UTXOs: " << n_txos
243 <<
", pending TXs: " << client->pending_tx_count()
245 }
else if(command ==
"importinput") {
249 }
else if(command ==
"confirmtx") {
254 std::cerr <<
"Unknown command" << std::endl;
259 static constexpr auto shutdown_delay = std::chrono::milliseconds(100);
260 std::this_thread::sleep_for(shutdown_delay);
static auto from_hex(const std::string &hex) -> std::optional< cbdc::buffer >
Creates a new buffer from the provided hex string.
External client for sending new transactions to the system.
auto new_address() -> pubkey_t
Generates a new wallet address that other clients can use to send money to this client using send.
static auto export_send_inputs(const transaction::full_tx &send_tx, const pubkey_t &payee) -> std::vector< transaction::input >
Extracts the transaction data that recipients need from senders to confirm pending transfers.
@ public_key
Pay-to-Public-Key (P2PK) address data.
static auto print_amount(uint64_t val) -> std::string
Format a value given in currency base units as USD.
auto main(int argc, char **argv) -> int
auto send_command(cbdc::client &client, const std::vector< std::string > &args) -> bool
auto confirmtx_command(cbdc::client &client, const std::vector< std::string > &args) -> bool
auto mint_command(cbdc::client &client, const std::vector< std::string > &args) -> bool
void newaddress_command(cbdc::client &client)
auto importinput_command(cbdc::client &client, const std::vector< std::string > &args) -> bool
auto fan_command(cbdc::client &client, const std::vector< std::string > &args) -> bool
void print_tx_result(const std::optional< cbdc::transaction::full_tx > &tx, const std::optional< cbdc::sentinel::execute_response > &resp, const cbdc::hash_t &pubkey)
Tools for reading options from a configuration file and building application-specific parameter sets ...
auto decode(const std::string &addr_str) -> std::optional< cbdc::hash_t >
auto load_options(const std::string &config_file) -> std::variant< options, std::string >
Loads options from the given config file and check for invariants.
auto get_args(int argc, char **argv) -> std::vector< std::string >
Converts c-args from an executable's main function into a vector of strings.
auto to_string(tx_status status) -> std::string
Return a human-readable string describing a tx_status.
auto to_string(cbdc::transaction::validation::tx_error_code err) -> std::string
auto tx_id(const full_tx &tx) noexcept -> hash_t
Calculates the unique hash of a full transaction.
auto from_buffer(nuraft::buffer &buf) -> std::optional< T >
Deserialize object of given type from a nuraft::buffer.
std::array< unsigned char, cbdc::hash_size > hash_t
SHA256 hash container.
auto hash_from_hex(const std::string &val) -> hash_t
Parses a hexadecimal representation of a hash.
auto to_string(const hash_t &val) -> std::string
Converts a hash to a hexadecimal string.
auto make_buffer(const T &obj) -> std::enable_if_t< std::is_same_v< B, nuraft::ptr< nuraft::buffer > >, nuraft::ptr< nuraft::buffer > >
Serialize object into nuraft::buffer using a cbdc::nuraft_serializer.