Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/monero_util.cpp 4 : : \copyright 2022-2025 J. Bakosi, 5 : : All rights reserved. See the LICENSE file for details. 6 : : \brief Piac monero wallet interaction functionality 7 : : */ 8 : : // ***************************************************************************** 9 : : 10 : : #include "string_util.hpp" 11 : : #include "crypto_util.hpp" 12 : : #include "monero_util.hpp" 13 : : 14 : : void 15 : 0 : piac::WalletListener::on_sync_progress( uint64_t height, 16 : : uint64_t start_height, 17 : : uint64_t end_height, 18 : : double percent_done, 19 : : const std::string& message ) 20 : : { 21 : 0 : m_height = height; 22 : 0 : m_start_height = start_height; 23 : 0 : m_end_height = end_height; 24 : 0 : m_percent_done = percent_done; 25 : 0 : m_message = message; 26 : 0 : } 27 : : 28 : : void 29 : 43 : piac::send_cmd( std::string cmd, 30 : : zmqpp::context& ctx, 31 : : const std::string& host, 32 : : const std::string& rpc_server_public_key, 33 : : const zmqpp::curve::keypair& client_keys, 34 : : const std::unique_ptr< monero_wallet_full >& wallet ) 35 : : // ***************************************************************************** 36 : : // Send a command to piac daemon 37 : : //! \param[in] cmd Command to send to piac daemon 38 : : //! \param[in,out] ctx ZeroMQ socket context to use 39 : : //! \param[in] host Hostname or IP + port of piac daemon to send cmd to 40 : : //! \param[in] rpc_server_public_key CurveZMQ server public key to use 41 : : //! \param[in] client_keys CurveMQ client keypair to use 42 : : //! \param[in] wallet Monero wallet to use as author / user id 43 : : // ***************************************************************************** 44 : : { 45 [ + - ]: 43 : trim( cmd ); 46 [ + - ][ + - ]: 43 : MDEBUG( cmd ); [ + - ][ + - ] 47 : : 48 : : // append author if cmd contains "db add/rm" 49 : 43 : auto npos = std::string::npos; 50 [ + + ][ + + ]: 81 : if ( cmd.find("db") != npos && [ + + ] 51 [ + + ]: 38 : (cmd.find("add") != npos || cmd.find("rm") != npos) ) 52 : : { 53 [ - + ]: 9 : if (not wallet) { 54 : : std::cout << "Need active user id (wallet) to add to db. " 55 [ - - ]: 0 : "See 'new' or 'user'.\n"; 56 : 0 : return; 57 : : } 58 [ + - ][ + - ]: 9 : cmd += " AUTH:" + piac::sha256( wallet->get_primary_address() ); [ + - ][ + - ] 59 : : } 60 : : 61 : : // send message to daemon with command 62 [ + - ]: 86 : auto reply = pirate_send( cmd, ctx, host, rpc_server_public_key, client_keys ); 63 [ + - ][ + - ]: 43 : std::cout << reply << '\n'; 64 : : } 65 : : 66 : : void 67 : 15 : piac::start_syncing( const std::string& msg, 68 : : monero_wallet_full* wallet, 69 : : WalletListener& listener ) 70 : : // ***************************************************************************** 71 : : // Start wallet sync the background 72 : : //! \param[in] msg Info message to print before starting to sync 73 : : //! \param[in,out] wallet Pointer to monero wallet object from monero-cpp 74 : : //! \param[in,out] listener Wallet listener object up to initialize used to 75 : : //! interact with the background sync 76 : : // ***************************************************************************** 77 : : { 78 [ - + ]: 15 : assert( wallet ); 79 : 15 : std::cout << msg; 80 [ + + ]: 15 : if (wallet->is_connected_to_daemon()) { 81 : 1 : std::cout << ", starting background sync, check progress with 'balance'\n"; 82 : 1 : wallet->add_listener( listener ); 83 : 1 : wallet->start_syncing( /* sync period in ms = */ 10000 ); 84 : : } else { 85 : 14 : std::cout << ", no connection to monero daemon\n"; 86 : : } 87 : 15 : } 88 : : 89 : : [[nodiscard]] std::unique_ptr< monero_wallet_full > 90 : 1 : piac::create_wallet( const std::string& monerod_host, WalletListener& listener ) 91 : : // ***************************************************************************** 92 : : // Create a new monero wallet 93 : : //! \param[in] monerod_host Hostname + port of a monero daemon to connect to 94 : : //! \param[in,out] listener Wallet listener object up to initialize used to 95 : : //! interact with the background sync 96 : : //! \return Smart pointer to monero wallet object 97 : : // ***************************************************************************** 98 : : { 99 [ + - ][ + - ]: 1 : MDEBUG( "new" ); [ + - ][ + - ] 100 : 2 : monero::monero_wallet_config wallet_config; 101 [ + - ]: 1 : wallet_config.m_network_type = monero_network_type::STAGENET; 102 [ + - ]: 1 : wallet_config.m_server_uri = monerod_host; 103 [ + - ]: 1 : auto wallet = monero_wallet_full::create_wallet( wallet_config ); 104 [ + - ][ + - ]: 1 : start_syncing( "Created new user/wallet", wallet, listener ); 105 : 1 : std::cout << "Mnemonic seed: " << wallet->get_mnemonic() << '\n' << 106 : : "This is your monero wallet mnemonic seed that identifies you within\n" 107 : : "piac. You can use it to create your ads or pay for a product. This seed\n" 108 : : "can be restored within your favorite monero wallet software and you can\n" 109 : : "use this wallet just like any other monero wallet. Save this seed and\n" 110 [ + - ][ + - ]: 1 : "keep it secret.\n"; [ + - ][ + - ] [ + - ] 111 : 2 : return std::unique_ptr< monero_wallet_full >( wallet ); 112 : : } 113 : : 114 : : void 115 : 2 : piac::show_wallet_keys( const std::unique_ptr< monero_wallet_full >& wallet ) 116 : : // ***************************************************************************** 117 : : // Query and print currently active wallet keys 118 : : //! \param[in] wallet Smart pointer to monero wallet object 119 : : // ***************************************************************************** 120 : : { 121 [ + - ][ + - ]: 2 : MDEBUG( "keys" ); [ + - ] 122 [ + + ]: 2 : if (not wallet) { 123 : 1 : std::cout << "Need active user id (wallet). See 'new' or 'user'.\n"; 124 : 1 : return; 125 : : } 126 [ + - ][ + - ]: 1 : std::cout << "Mnemonic seed: " << wallet->get_mnemonic() << '\n'; 127 [ + - ][ + - ]: 1 : std::cout << "Primary address: " << wallet->get_primary_address() << '\n'; 128 [ + - ][ + - ]: 1 : std::cout << "Secret view key: " << wallet->get_private_view_key() << '\n'; 129 [ + - ][ + - ]: 1 : std::cout << "Public view key: " << wallet->get_public_view_key() << '\n'; 130 [ + - ][ + - ]: 1 : std::cout << "Secret spend key: " << wallet->get_private_spend_key() << '\n'; 131 [ + - ][ + - ]: 1 : std::cout << "Public spend key: " << wallet->get_public_spend_key() << '\n'; 132 : : } 133 : : 134 : : void 135 : 1 : piac::show_wallet_balance( const std::unique_ptr< monero_wallet_full >& wallet, 136 : : const WalletListener& listener ) 137 : : // ***************************************************************************** 138 : : // Query and print currently active wallet balance 139 : : //! \param[in] wallet Smart pointer to monero wallet object 140 : : //! \param[in] listener Wallet listener object interacting with background sync 141 : : // ***************************************************************************** 142 : : { 143 [ + - ][ + - ]: 1 : MDEBUG( "balance" ); [ + - ] 144 [ - + ]: 1 : if (not wallet) { 145 : 0 : std::cout << "Need active user id (wallet). See 'new' or 'user'.\n"; 146 : 0 : return; 147 : : } 148 : 1 : std::cout << "Balance = " << std::fixed << std::setprecision( 6 ) 149 : 1 : << static_cast< double >( wallet->get_balance() ) / 1.0e+12 150 : 1 : << " XMR\n"; 151 : 1 : std::cout << "Wallet sync start height: " << listener.start_height() << '\n'; 152 : 1 : std::cout << "Wallet sync height: " << listener.height() << '\n'; 153 : 1 : std::cout << "Wallet sync end height: " << listener.end_height() << '\n'; 154 : 1 : std::cout << "Wallet sync at: " << std::fixed << std::setprecision( 2 ) 155 : 1 : << listener.percent_done() * 100.0 << "%\n"; 156 : : } 157 : : 158 : : [[nodiscard]] 159 : : std::unique_ptr< monero_wallet_full > 160 : 14 : piac::switch_user( const std::string& mnemonic, 161 : : const std::string& monerod_host, 162 : : WalletListener& listener ) 163 : : // ***************************************************************************** 164 : : // Change currently currently active user id / monero wallet 165 : : //! \param[in] mnemonic Monero mnemonic to use 166 : : //! \param[in] monerod_host Hostname + port of a monero daemon to connect to 167 : : //! \param[in,out] listener Wallet listener object up to initialize used to 168 : : //! interact with the background sync 169 : : // ***************************************************************************** 170 : : { 171 [ + - ][ + - ]: 14 : MDEBUG( "user" ); [ + - ][ + - ] 172 [ - + ]: 14 : assert( not mnemonic.empty() ); 173 : 28 : monero::monero_wallet_config wallet_config; 174 [ + - ]: 14 : wallet_config.m_mnemonic = mnemonic; 175 [ + - ]: 14 : wallet_config.m_network_type = monero_network_type::STAGENET; 176 [ + - ]: 14 : wallet_config.m_server_uri = monerod_host; 177 [ + - ]: 14 : auto wallet = monero_wallet_full::create_wallet( wallet_config ); 178 [ + - ][ + - ]: 14 : start_syncing( "Switched to new user/wallet", wallet, listener ); 179 : 28 : return std::unique_ptr< monero_wallet_full >( wallet ); 180 : : } 181 : : 182 : : void 183 : 2 : piac::show_user( const std::unique_ptr< monero_wallet_full >& wallet ) 184 : : // ***************************************************************************** 185 : : // Show user id /monero wallet mnemonic 186 : : //! \param[in] wallet Smart pointer to monero wallet object 187 : : // ***************************************************************************** 188 : : { 189 [ + - ][ + - ]: 2 : MDEBUG( "user" ); [ + - ] 190 [ + - ]: 2 : if (not wallet) { 191 : 2 : std::cout << "No active user id (wallet). See 'new' or 'user'.\n"; 192 : 2 : return; 193 : : } 194 [ - - ][ - - ]: 0 : std::cout << "Mnemonic seed: " << wallet->get_mnemonic() << '\n'; 195 : : }