From bc52c8ce6f0877cb757905418a5bd06618b35951 Mon Sep 17 00:00:00 2001 From: Max Wittal Date: Fri, 28 Jun 2024 23:11:03 +0700 Subject: [PATCH] account_info_t refactor --- CMakeLists.txt | 1 + include/mmx/ECDSA_Wallet.h | 8 ++++++ include/mmx/Wallet.h | 4 +-- interface/account_info_t.vni | 12 ++++++++ modules/Wallet.vni | 4 +-- src/Farmer.cpp | 33 +++++++++++----------- src/TimeLord.cpp | 14 ++++++---- src/Wallet.cpp | 11 ++++---- src/WebAPI.cpp | 31 ++++++++++++++++++++- src/account_info_t.cpp | 23 ++++++++++++++++ src/mmx.cpp | 15 ++++++---- www/web-gui/public/market.js | 10 +++---- www/web-gui/public/wallet.js | 53 ++++++++++++++---------------------- 13 files changed, 144 insertions(+), 75 deletions(-) create mode 100644 interface/account_info_t.vni create mode 100644 src/account_info_t.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 81c04a441..8f694475e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,7 @@ add_library(mmx_iface SHARED src/wordlist_en.cpp src/mnemonic.cpp src/offer_data_t.cpp + src/account_info_t.cpp ) add_library(mmx_vm SHARED diff --git a/include/mmx/ECDSA_Wallet.h b/include/mmx/ECDSA_Wallet.h index 2a4ee94c6..57a25fcf7 100644 --- a/include/mmx/ECDSA_Wallet.h +++ b/include/mmx/ECDSA_Wallet.h @@ -135,6 +135,14 @@ class ECDSA_Wallet { return farmer_key; } + vnx::optional find_address(const uint32_t index) const + { + if(index >= addresses.size()) { + return nullptr; + } + return addresses[index]; + } + addr_t get_address(const uint32_t index) const { if(index >= addresses.size()) { diff --git a/include/mmx/Wallet.h b/include/mmx/Wallet.h index 7c92e1f82..1283b3aa4 100644 --- a/include/mmx/Wallet.h +++ b/include/mmx/Wallet.h @@ -139,9 +139,9 @@ class Wallet : public WalletBase { std::vector> get_all_farmer_keys() const override; - account_t get_account(const uint32_t& index) const override; + account_info_t get_account(const uint32_t& index) const override; - std::map get_all_accounts() const override; + std::vector get_all_accounts() const override; bool is_locked(const uint32_t& index) const override; diff --git a/interface/account_info_t.vni b/interface/account_info_t.vni new file mode 100644 index 000000000..0ec6ab394 --- /dev/null +++ b/interface/account_info_t.vni @@ -0,0 +1,12 @@ +package mmx; + +struct account_info_t extends account_t { + + optional address; + + uint account; + + + static account_info_t make(uint account, optional address, account_t config); + +} diff --git a/modules/Wallet.vni b/modules/Wallet.vni index 523c54e81..e889a8ace 100644 --- a/modules/Wallet.vni +++ b/modules/Wallet.vni @@ -120,9 +120,9 @@ module Wallet implements vnx.addons.HttpComponent { vector get_all_addresses(int index) const; // (index == -1) -> all wallets - account_t get_account(uint index) const; + account_info_t get_account(uint index) const; - map get_all_accounts() const; + vector get_all_accounts() const; bool is_locked(uint index) const; diff --git a/src/Farmer.cpp b/src/Farmer.cpp index fff20d44c..f220e0763 100644 --- a/src/Farmer.cpp +++ b/src/Farmer.cpp @@ -33,9 +33,10 @@ void Farmer::main() { if(reward_addr) { if(*reward_addr == addr_t()) { - throw std::logic_error("reward_addr == zero"); + reward_addr = nullptr; + } else { + log(INFO) << "Reward address: " << reward_addr->to_string(); } - log(INFO) << "Reward address: " << reward_addr->to_string(); } params = get_params(); @@ -107,22 +108,20 @@ void Farmer::update() if(!reward_addr) { wallet->get_all_accounts( - [this](const std::map& accounts) { - if(accounts.empty()) { - log(WARN) << "Failed to get reward address from wallet: no wallet available"; - return; - } - wallet->get_address(accounts.begin()->first, 0, - [this](const addr_t& address) { - if(!reward_addr) { - log(INFO) << "Reward address: " << address.to_string(); + [this](const std::vector& accounts) { + if(!reward_addr) { + for(const auto& entry : accounts) { + if(entry.address) { + reward_addr = entry.address; + break; } - reward_addr = address; - }, - [this](const vnx::exception& ex) { - log(WARN) << "Failed to get reward address from wallet: " << ex.what(); - }); - + } + if(reward_addr) { + log(INFO) << "Reward address: " << reward_addr->to_string(); + } else { + log(WARN) << "Failed to get reward address from wallet: no wallet available"; + } + } }, [this](const vnx::exception& ex) { log(WARN) << "Failed to get reward address from wallet: " << ex.what(); diff --git a/src/TimeLord.cpp b/src/TimeLord.cpp index dc11ad099..8e1b7a563 100644 --- a/src/TimeLord.cpp +++ b/src/TimeLord.cpp @@ -36,11 +36,15 @@ void TimeLord::main() if(!reward_addr) { try { WalletClient wallet(wallet_server); - const auto accounts = wallet.get_all_accounts(); - if(accounts.empty()) { + for(const auto& entry : wallet.get_all_accounts()) { + if(entry.address) { + reward_addr = entry.address; + break; + } + } + if(!reward_addr) { throw std::logic_error("no wallet available"); } - reward_addr = wallet.get_address(accounts.begin()->first, 0); } catch(const std::exception& ex) { log(WARN) << "Failed to get reward address from wallet: " << ex.what(); @@ -52,7 +56,7 @@ void TimeLord::main() enable_reward = false; } } else { - log(INFO) << "Rewards not enabled"; + log(INFO) << "Reward is disabled"; } { vnx::File file(storage_path + "timelord_sk.dat"); @@ -78,7 +82,7 @@ void TimeLord::main() } } timelord_key = pubkey_t::from_skey(timelord_sk); - log(INFO) << "Our Timelord Key: " << timelord_key; + log(DEBUG) << "Timelord Key: " << timelord_key; } set_timer_millis(10000, std::bind(&TimeLord::print_info, this)); diff --git a/src/Wallet.cpp b/src/Wallet.cpp index aeaaa49b8..b62e3a2d2 100644 --- a/src/Wallet.cpp +++ b/src/Wallet.cpp @@ -822,17 +822,18 @@ std::vector> Wallet::get_all_farmer_keys() const return res; } -account_t Wallet::get_account(const uint32_t& index) const +account_info_t Wallet::get_account(const uint32_t& index) const { - return get_wallet(index)->config; + const auto wallet = get_wallet(index); + return account_info_t::make(index, wallet->find_address(0), wallet->config); } -std::map Wallet::get_all_accounts() const +std::vector Wallet::get_all_accounts() const { - std::map res; + std::vector res; for(size_t i = 0; i < wallets.size(); ++i) { if(auto wallet = wallets[i]) { - res[i] = wallet->config; + res.push_back(account_info_t::make(i, wallet->find_address(0), wallet->config)); } } return res; diff --git a/src/WebAPI.cpp b/src/WebAPI.cpp index 05e1bb3ff..cee534b71 100644 --- a/src/WebAPI.cpp +++ b/src/WebAPI.cpp @@ -683,6 +683,15 @@ vnx::Variant render_value(const T& value, std::shared_ptr c return std::move(visitor.result); } +template +vnx::Variant render_list(const std::vector& list, std::shared_ptr context = nullptr) { + std::vector tmp; + for(const auto& entry : list) { + tmp.push_back(render(entry, context)); + } + return vnx::Variant(tmp); +} + template vnx::Object render_object(const T& value, std::shared_ptr context = nullptr) { return render_value(value, context).to_object(); @@ -1654,6 +1663,26 @@ void WebAPI::http_request_async(std::shared_ptr respond_status(request_id, 404, "wallet/seed?index"); } } + else if(sub_path == "/wallet/accounts") { + wallet->get_all_accounts( + [this, request_id](const std::vector& list) { + respond(request_id, render_list(list)); + }, + std::bind(&WebAPI::respond_ex, this, request_id, std::placeholders::_1)); + } + else if(sub_path == "/wallet/account") { + const auto iter_index = query.find("index"); + if(iter_index != query.end()) { + const uint32_t index = vnx::from_string(iter_index->second); + wallet->get_account(index, + [this, request_id](const account_info_t& info) { + respond(request_id, render(info)); + }, + std::bind(&WebAPI::respond_ex, this, request_id, std::placeholders::_1)); + } else { + respond_status(request_id, 404, "wallet/account?index"); + } + } else if(sub_path == "/wallet/balance") { const auto iter_index = query.find("index"); const auto iter_currency = query.find("currency"); @@ -2551,7 +2580,7 @@ void WebAPI::http_request_async(std::shared_ptr "address/history", "wallet/balance", "wallet/contracts", "wallet/address", "wallet/coins", "wallet/history", "wallet/history/memo", "wallet/send", "wallet/cancel_offer", "wallet/accept_offer", "wallet/offer_withdraw", "wallet/offer_trade", "wallet/swap/liquid", "wallet/swap/trade", "wallet/swap/add_liquid", "wallet/swap/rem_liquid", "wallet/swap/payout", - "wallet/swap/switch_pool", "wallet/swap/rem_all_liquid", + "wallet/swap/switch_pool", "wallet/swap/rem_all_liquid", "wallet/accounts", "wallet/account", "swap/list", "swap/info", "swap/user_info", "swap/trade_estimate", "farmer/info", "farmer/blocks", "farmer/blocks/summary", "farmer/proofs", "node/offers", "node/offer", "node/trade_history", diff --git a/src/account_info_t.cpp b/src/account_info_t.cpp new file mode 100644 index 000000000..4ad6b2828 --- /dev/null +++ b/src/account_info_t.cpp @@ -0,0 +1,23 @@ +/* + * account_info_t.cpp + * + * Created on: Jun 28, 2024 + * Author: mad + */ + +#include + + +namespace mmx { + +account_info_t account_info_t::make(const uint32_t& account, const vnx::optional& address, const account_t& config) +{ + account_info_t out; + static_cast(out) = config; + out.account = account; + out.address = address; + return out; +} + + +} // mmx diff --git a/src/mmx.cpp b/src/mmx.cpp index 0be069e68..d05e93e8a 100644 --- a/src/mmx.cpp +++ b/src/mmx.cpp @@ -327,9 +327,11 @@ int main(int argc, char** argv) } catch(...) { // ignore } - const auto accounts = wallet.get_all_accounts(); - if(index == 0 && !accounts.empty() && accounts.find(index) == accounts.end()) { - index = accounts.begin()->first; + if(index == 0) { + const auto accounts = wallet.get_all_accounts(); + if(!accounts.empty()) { + index = accounts[0].account; + } } } @@ -452,9 +454,10 @@ int main(int argc, char** argv) else if(command == "accounts") { for(const auto& entry : wallet.get_all_accounts()) { - const auto& config = entry.second; - std::cout << "[" << entry.first << "] name = '" << config.name << "', index = " << config.index - << ", num_addresses = " << config.num_addresses << ", key_file = '" << config.key_file << "'" << std::endl; + std::cout << "[" << entry.account << "] name = '" << entry.name << "', index = " << entry.index + << ", passphrase = " << (entry.with_passphrase ? "yes" : "no") + << ", num_addresses = " << entry.num_addresses << ", key_file = " << entry.key_file + << " (" << vnx::to_string(entry.address) << ")" << std::endl; } } else if(command == "keys") diff --git a/www/web-gui/public/market.js b/www/web-gui/public/market.js index 5e0a59fce..b9bd881b0 100644 --- a/www/web-gui/public/market.js +++ b/www/web-gui/public/market.js @@ -18,7 +18,7 @@ Vue.component('market-menu', { methods: { update() { this.loading = true; - fetch('/api/wallet/get_all_accounts') + fetch('/wapi/wallet/accounts') .then(response => response.json()) .then(data => { this.loading = false; @@ -27,7 +27,7 @@ Vue.component('market-menu', { this.wallet = this.wallet_; } else if(data.length > 0) { - this.wallet = data[0][0]; + this.wallet = data[0].account; } }) .catch(error => { @@ -108,10 +108,10 @@ Vue.component('market-menu', { v-model="wallet" :items="wallets" :lablel="$t('market_menu.wallet')" - item-text="[0]" - item-value="[0]"> + item-text="account" + item-value="account"> diff --git a/www/web-gui/public/wallet.js b/www/web-gui/public/wallet.js index 3165d75de..e29ed59e6 100644 --- a/www/web-gui/public/wallet.js +++ b/www/web-gui/public/wallet.js @@ -9,7 +9,7 @@ Vue.component('wallet-summary', { methods: { update() { this.loading = true; - fetch('/api/wallet/get_all_accounts') + fetch('/wapi/wallet/accounts') .then(response => response.json()) .then(data => { this.loading = false; @@ -24,8 +24,8 @@ Vue.component('wallet-summary', {
-
- +
+
{{ $t('wallet_summary.new_wallet') }} @@ -64,25 +64,27 @@ Vue.component('account-header', { info: { name: null, index: null, + address: null, with_passphrase: null }, - address: null, is_locked: null, passphrase_dialog: false } }, + computed: { + address() { + return this.info.address ? this.info.address : "N/A"; + } + }, methods: { update() { if(this.account) { - this.info = this.account + this.info = this.account; } else { - fetch('/api/wallet/get_account?index=' + this.index) + fetch('/wapi/wallet/account?index=' + this.index) .then(response => response.json()) .then(data => this.info = data); } - fetch('/wapi/wallet/address?index=' + this.index) - .then(response => response.json()) - .then(data => this.address = data.length ? data[0] : "N/A"); this.update_lock(); }, update_lock() { @@ -131,7 +133,7 @@ Vue.component('account-header', { {{ $t('account_header.wallet') }} #{{index}} {{ address }} - + mdi-content-copy @@ -1041,7 +1043,7 @@ Vue.component('account-details', { }, methods: { update() { - fetch('/api/wallet/get_account?index=' + this.index) + fetch('/wapi/wallet/account?index=' + this.index) .then(response => response.json()) .then(data => this.account = data); fetch('/wapi/wallet/keys?index=' + this.index) @@ -1176,7 +1178,7 @@ Vue.component('create-account', { }, methods: { update() { - fetch('/api/wallet/get_account?index=' + this.index) + fetch('/wapi/wallet/account?index=' + this.index) .then(response => response.json()) .then(data => this.data = data); }, @@ -1428,22 +1430,9 @@ Vue.component('account-send-form', { }, methods: { update() { - fetch('/api/wallet/get_all_accounts') + fetch('/wapi/wallet/accounts') .then(response => response.json()) - .then(data => { - this.accounts = []; - for(const entry of data) { - const info = entry[1]; - info.account = entry[0]; - fetch('/wapi/wallet/address?limit=1&index=' + entry[0]) - .then(response => response.json()) - .then(data => { - info.address = data[0]; - this.accounts.push(info); - this.accounts.sort((a, b) => a.account - b.account); - }); - } - }); + .then(data => this.accounts = data); if(this.source) { fetch('/wapi/address?id=' + this.source) .then(response => response.json()) @@ -2516,12 +2505,12 @@ Vue.component('wallet-menu', { ], methods: { update() { - fetch('/api/wallet/get_all_accounts') + fetch('/wapi/wallet/accounts') .then(response => response.json()) .then(data => { this.wallets = data; if(this.wallet == null && data.length > 0) { - this.wallet = data[0][0]; + this.wallet = data[0].account; } }); } @@ -2543,10 +2532,10 @@ Vue.component('wallet-menu', { v-model="wallet" :items="wallets" :label="$t('market_menu.wallet')" - item-text="[0]" - item-value="[0]"> + item-text="account" + item-value="account"> `