diff --git a/assets/config/cfg.json b/assets/config/cfg.json index 8ac884ef9d..55e9f57757 100644 --- a/assets/config/cfg.json +++ b/assets/config/cfg.json @@ -1,6 +1,7 @@ { "notification_enabled": true, "spamfilter_enabled": false, + "use_static_rpcpass": false, "current_currency": "USD", "current_fiat": "USD", "current_currency_sign": "$", diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml index 1f202693c8..d01600f8d6 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml @@ -125,9 +125,10 @@ DexListView delegate: DexRectangle // Order Line { property bool _isCoinEnabled: Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled + property bool _isAboveMinVal: parseFloat(price_fiat) > parseFloat(_bestOrderFiatFilterField.textField.text) || _bestOrderFiatFilterField.textField.text === "" property bool _hideDisabled: hide_disabled_coins_checkbox.checked - visible: _isCoinEnabled ? true : _hideDisabled ? false : true - height: _isCoinEnabled ? _rowHeight : _hideDisabled ? 0 : _rowHeight + visible: !_isAboveMinVal ? false : _isCoinEnabled ? true : _hideDisabled ? false : true + height: !_isAboveMinVal ? 0 : _isCoinEnabled ? _rowHeight : _hideDisabled ? 0 : _rowHeight width: _rowWidth radius: mouse_area.containsMouse ? 3 : 0 border.width: 0 @@ -204,6 +205,7 @@ DexListView { Layout.preferredWidth: _fiatVolumeColumnSize horizontalAlignment: Text.AlignRight + // TODO: Adjust fiat to left/right sign based on region text_value: parseFloat(price_fiat).toFixed(2)+Constants.API.app.settings_pg.current_fiat_sign opacity: !_isCoinEnabled? .3 : 1 } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml index 25063fed09..ebea341ac2 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml @@ -791,10 +791,9 @@ ClipRRect // Trade Card SearchField { - id: _bestOrderSearchField Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 206 + Layout.preferredWidth: 160 Layout.preferredHeight: 35 Layout.leftMargin: 20 Layout.topMargin: 10 @@ -804,6 +803,26 @@ ClipRRect // Trade Card textField.placeholderText: qsTr("Search coins") } + Item { + Layout.fillWidth: true + } + + SearchField + { + id: _bestOrderFiatFilterField + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: 160 + Layout.preferredHeight: 35 + Layout.leftMargin: 20 + Layout.topMargin: 10 + textField.placeholderText: qsTr("Min Value") + textField.validator: RegExpValidator + { + regExp: /[0-9]+/ + } + Component.onDestruction: textField.text = "" + } + Item { Layout.fillWidth: true } @@ -819,7 +838,7 @@ ClipRRect // Trade Card label.wrapMode: Label.NoWrap label.font.pixelSize: 14 - text: qsTr("Show only enabled coins") + text: qsTr("Hide disabled coins") textColor: Dex.CurrentTheme.foregroundColor2 } } diff --git a/atomic_defi_design/Dex/Screens/Startup/Login.qml b/atomic_defi_design/Dex/Screens/Startup/Login.qml index 211c816aa6..d27c32af19 100644 --- a/atomic_defi_design/Dex/Screens/Startup/Login.qml +++ b/atomic_defi_design/Dex/Screens/Startup/Login.qml @@ -26,7 +26,7 @@ SetupPage function onClickedLogin(password) { - if (API.app.wallet_mgr.login(password, walletName)) + if (API.app.wallet_mgr.login(password, walletName, API.app.settings_pg.static_rpcpass_enabled)) { console.info("Success: Login"); app.currentWalletName = walletName; diff --git a/atomic_defi_design/Dex/Settings/SettingModal.qml b/atomic_defi_design/Dex/Settings/SettingModal.qml index 98778cada9..45692cd07d 100644 --- a/atomic_defi_design/Dex/Settings/SettingModal.qml +++ b/atomic_defi_design/Dex/Settings/SettingModal.qml @@ -617,6 +617,31 @@ Qaterial.Dialog onClicked: camouflage_password_modal.open() } + // Spam filter toggle + RowLayout + { + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + height: 50 + + DexLabel + { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + font: DexTypo.subtitle1 + text: qsTr("Reuse static RPC password") + } + + Item { Layout.fillWidth: true } + + DexSwitch + { + Layout.alignment: Qt.AlignVCenter + Component.onCompleted: checked = API.app.settings_pg.static_rpcpass_enabled + onCheckedChanged: API.app.settings_pg.static_rpcpass_enabled = checked + } + } + } } diff --git a/src/core/atomicdex/config/app.cfg.cpp b/src/core/atomicdex/config/app.cfg.cpp index ba9fb02313..9790276baa 100644 --- a/src/core/atomicdex/config/app.cfg.cpp +++ b/src/core/atomicdex/config/app.cfg.cpp @@ -50,6 +50,7 @@ namespace config_json_data["available_signs"] = config.available_currency_signs; config_json_data["notification_enabled"] = config.notification_enabled; config_json_data["spamfilter_enabled"] = config.spamfilter_enabled; + config_json_data["static_rpcpass_enabled"] = config.static_rpcpass_enabled; file.close(); @@ -83,6 +84,15 @@ namespace atomic_dex { config.spamfilter_enabled = true; } + + if (j.contains("static_rpcpass_enabled")) + { + j.at("static_rpcpass_enabled").get_to(config.static_rpcpass_enabled); + } + else + { + config.static_rpcpass_enabled = false; + } } void @@ -105,6 +115,16 @@ namespace atomic_dex } } + void + change_static_rpcpass_status(cfg& config, bool is_enabled) + { + if (config.static_rpcpass_enabled != is_enabled) + { + config.static_rpcpass_enabled = is_enabled; + upgrade_cfg(config); + } + } + cfg load_cfg() { diff --git a/src/core/atomicdex/config/app.cfg.hpp b/src/core/atomicdex/config/app.cfg.hpp index 41b954d4dc..ba52c13d1a 100644 --- a/src/core/atomicdex/config/app.cfg.hpp +++ b/src/core/atomicdex/config/app.cfg.hpp @@ -33,6 +33,7 @@ namespace atomic_dex std::vector possible_currencies; bool notification_enabled; bool spamfilter_enabled{false}; + bool static_rpcpass_enabled{false}; }; void from_json(const nlohmann::json& j, cfg& config); @@ -40,6 +41,7 @@ namespace atomic_dex void change_fiat(cfg& config, const std::string& new_fiat); void change_notification_status(cfg& config, bool is_enabled); void change_spamfilter_status(cfg& config, bool is_enabled); + void change_static_rpcpass_status(cfg& config, bool is_enabled); [[nodiscard]] bool is_this_currency_a_fiat(const cfg& config, const std::string& currency); cfg load_cfg(); std::string retrieve_sign_from_ticker(const cfg& config, const std::string& currency); diff --git a/src/core/atomicdex/managers/qt.wallet.manager.cpp b/src/core/atomicdex/managers/qt.wallet.manager.cpp index 2bc6e4b22e..b1758179e7 100644 --- a/src/core/atomicdex/managers/qt.wallet.manager.cpp +++ b/src/core/atomicdex/managers/qt.wallet.manager.cpp @@ -15,6 +15,7 @@ ******************************************************************************/ //! Qt +#include #include #include @@ -71,6 +72,7 @@ namespace atomic_dex { using namespace std::string_literals; const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); + const std::filesystem::path rpcpass_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".rpcpass"s); const std::filesystem::path wallet_object_path = utils::get_atomic_dex_export_folder() / (wallet_name.toStdString() + ".wallet.json"s); const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name.toStdString() + ".json"s; const std::filesystem::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; @@ -85,6 +87,9 @@ namespace atomic_dex // Encrypt seed atomic_dex::encrypt(seed_path, seed.toStdString().data(), key.data()); + // Encrypt rpcpass + std::string rpcpass = atomic_dex::gen_random_password(); + atomic_dex::encrypt(rpcpass_path, rpcpass.data(), key.data()); // sodium_memzero(&seed, seed.size()); sodium_memzero(key.data(), key.size()); @@ -153,6 +158,7 @@ namespace atomic_dex { using namespace std::string_literals; return std::filesystem::remove(utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s)); + return std::filesystem::remove(utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".rpcpass"s)); } bool @@ -171,6 +177,8 @@ namespace atomic_dex using namespace std::string_literals; const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); + const std::filesystem::path rpcpass_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".rpcpass"s); + auto rpcpass = atomic_dex::decrypt(rpcpass_path, key.data(), ec); if (ec == dextop_error::corrupted_file_or_wrong_password) { SPDLOG_WARN("{}", ec.message()); @@ -268,7 +276,7 @@ namespace atomic_dex } bool - qt_wallet_manager::login(const QString& password, const QString& wallet_name) + qt_wallet_manager::login(const QString& password, const QString& wallet_name, bool use_static_rpcpass) { SPDLOG_INFO("qt_wallet_manager::login"); if (not load_wallet_cfg(wallet_name.toStdString())) @@ -296,7 +304,6 @@ namespace atomic_dex else { using namespace std::string_literals; - const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name.toStdString() + ".json"s; const std::filesystem::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; bool valid_json = false; @@ -320,6 +327,21 @@ namespace atomic_dex const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); + + const std::filesystem::path rpcpass_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".rpcpass"s); + //! We need to create a new rpcpass if it doesn't exist for existing logins + std::string rpcpass = atomic_dex::gen_random_password(); + if (not std::filesystem::exists(rpcpass_path) || not use_static_rpcpass) + { + atomic_dex::encrypt(rpcpass_path, rpcpass.data(), key.data()); + // sodium_memzero(&seed, seed.size()); + sodium_memzero(key.data(), key.size()); + } + else + { + rpcpass = atomic_dex::decrypt(rpcpass_path, key.data(), ec); + } + if (ec == dextop_error::corrupted_file_or_wrong_password) { SPDLOG_WARN("{}", ec.message()); @@ -330,7 +352,7 @@ namespace atomic_dex this->set_wallet_default_name(wallet_name); this->set_status("initializing_mm2"); auto& mm2_system = m_system_manager.get_system(); - mm2_system.spawn_mm2_instance(get_default_wallet_name().toStdString(), seed, with_pin_cfg); + mm2_system.spawn_mm2_instance(get_default_wallet_name().toStdString(), seed, with_pin_cfg, rpcpass); this->dispatcher_.trigger(); set_log_status(true); diff --git a/src/core/atomicdex/managers/qt.wallet.manager.hpp b/src/core/atomicdex/managers/qt.wallet.manager.hpp index 5540335742..4ad11710e3 100644 --- a/src/core/atomicdex/managers/qt.wallet.manager.hpp +++ b/src/core/atomicdex/managers/qt.wallet.manager.hpp @@ -66,7 +66,7 @@ namespace atomic_dex static QString get_default_wallet_name() ; ///< Static version //! Q_INVOKABLE (QML API) - Q_INVOKABLE bool login(const QString& password, const QString& wallet_name); + Q_INVOKABLE bool login(const QString& password, const QString& wallet_name, bool use_static_rpcpass = false); Q_INVOKABLE bool create(const QString& password, const QString& seed, const QString& wallet_name); Q_INVOKABLE static QStringList get_wallets(const QString& wallet_name = "") ; Q_INVOKABLE static bool delete_wallet(const QString& wallet_name) ; diff --git a/src/core/atomicdex/pages/qt.settings.page.cpp b/src/core/atomicdex/pages/qt.settings.page.cpp index eff63c2949..9c94beb432 100644 --- a/src/core/atomicdex/pages/qt.settings.page.cpp +++ b/src/core/atomicdex/pages/qt.settings.page.cpp @@ -178,6 +178,20 @@ namespace atomic_dex emit onLangChanged(); } + bool atomic_dex::settings_page::is_static_rpcpass_enabled() const + { + return m_config.static_rpcpass_enabled; + } + + void settings_page::set_static_rpcpass_enabled(bool is_enabled) + { + if (m_config.static_rpcpass_enabled != is_enabled) + { + change_static_rpcpass_status(m_config, is_enabled); + emit onStaticRpcPassEnabledChanged(); + } + } + bool atomic_dex::settings_page::is_spamfilter_enabled() const { return m_config.spamfilter_enabled; @@ -624,6 +638,8 @@ namespace atomic_dex using namespace std::string_literals; const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); + const std::filesystem::path rpcpass_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".rpcpass"s); + auto rpcpass = atomic_dex::decrypt(rpcpass_path, key.data(), ec); if (ec == dextop_error::corrupted_file_or_wrong_password) { SPDLOG_ERROR("cannot decrypt the seed with the derived password: {}", ec.message()); diff --git a/src/core/atomicdex/pages/qt.settings.page.hpp b/src/core/atomicdex/pages/qt.settings.page.hpp index bd2bbaf947..2032da6bb7 100644 --- a/src/core/atomicdex/pages/qt.settings.page.hpp +++ b/src/core/atomicdex/pages/qt.settings.page.hpp @@ -46,6 +46,7 @@ namespace atomic_dex Q_PROPERTY(QString current_fiat READ get_current_fiat WRITE set_current_fiat NOTIFY onFiatChanged) Q_PROPERTY(bool notification_enabled READ is_notification_enabled WRITE set_notification_enabled NOTIFY onNotificationEnabledChanged) Q_PROPERTY(bool spamfilter_enabled READ is_spamfilter_enabled WRITE set_spamfilter_enabled NOTIFY onSpamFilterEnabledChanged) + Q_PROPERTY(bool static_rpcpass_enabled READ is_static_rpcpass_enabled WRITE set_static_rpcpass_enabled NOTIFY onStaticRpcPassEnabledChanged) Q_PROPERTY(QVariant custom_token_data READ get_custom_token_data WRITE set_custom_token_data NOTIFY customTokenDataChanged) Q_PROPERTY(bool fetching_custom_token_data_busy READ is_fetching_custom_token_data_busy WRITE set_fetching_custom_token_data_busy NOTIFY customTokenDataStatusChanged) Q_PROPERTY(bool fetching_priv_keys_busy READ is_fetching_priv_key_busy WRITE set_fetching_priv_key_busy NOTIFY privKeyStatusChanged) @@ -85,6 +86,8 @@ namespace atomic_dex void set_pirate_sync_date(int new_timestamp); [[nodiscard]] bool is_notification_enabled() const; void set_notification_enabled(bool is_enabled); + [[nodiscard]] bool is_static_rpcpass_enabled() const; + void set_static_rpcpass_enabled(bool is_enabled); [[nodiscard]] bool is_spamfilter_enabled() const; void set_spamfilter_enabled(bool is_enabled); void set_current_currency(const QString& current_currency); @@ -133,6 +136,7 @@ namespace atomic_dex void onFiatChanged(); void onNotificationEnabledChanged(); void onSpamFilterEnabledChanged(); + void onStaticRpcPassEnabledChanged(); void customTokenDataChanged(); void customTokenDataStatusChanged(); void privKeyStatusChanged(); diff --git a/src/core/atomicdex/services/mm2/mm2.service.cpp b/src/core/atomicdex/services/mm2/mm2.service.cpp index 7855b72fbf..92738cc754 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.cpp +++ b/src/core/atomicdex/services/mm2/mm2.service.cpp @@ -1907,7 +1907,7 @@ namespace atomic_dex } } - void mm2_service::spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg) + void mm2_service::spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg, std::string rpcpass) { this->m_balance_factor = utils::determine_balance_factor(with_pin_cfg); SPDLOG_DEBUG("balance factor is: {}", m_balance_factor); @@ -1916,7 +1916,10 @@ namespace atomic_dex this->dispatcher_.trigger(this->retrieve_coins_informations()); this->dispatcher_.trigger(); this->dispatcher_.trigger(); - mm2_config cfg{.passphrase = std::move(passphrase), .rpc_password = atomic_dex::gen_random_password()}; + mm2_config cfg{ + .passphrase = std::move(passphrase), + .rpc_password = std::move(rpcpass) == "" ? std::move(atomic_dex::gen_random_password()) : std::move(rpcpass) + }; mm2::set_system_manager(m_system_manager); mm2::set_rpc_password(cfg.rpc_password); json json_cfg; diff --git a/src/core/atomicdex/services/mm2/mm2.service.hpp b/src/core/atomicdex/services/mm2/mm2.service.hpp index a10b20de19..60d479c845 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.hpp +++ b/src/core/atomicdex/services/mm2/mm2.service.hpp @@ -156,7 +156,7 @@ namespace atomic_dex void on_gui_leave_trading(const gui_leave_trading& evt); //! Spawn mm2 instance with given seed - void spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg = false); + void spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg = false, std::string rpcpassword = ""); //! Refresh the current info (internally call process_balance and process_tx) void fetch_infos_thread(bool is_a_fresh = true, bool only_tx = false);