// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include #include #include #include namespace dragonx { namespace config { /** * @brief Application settings manager * * Handles loading and saving of user preferences. */ class Settings { public: Settings(); ~Settings(); /** * @brief Load settings from default location * @return true if loaded successfully */ bool load(); /** * @brief Load settings from specific path * @param path Path to settings file * @return true if loaded successfully */ bool load(const std::string& path); /** * @brief Save settings to default location * @return true if saved successfully */ bool save(); /** * @brief Save settings to specific path * @param path Path to settings file * @return true if saved successfully */ bool save(const std::string& path); /** * @brief Get default settings file path */ static std::string getDefaultPath(); // Theme std::string getTheme() const { return theme_; } void setTheme(const std::string& theme) { theme_ = theme; } // Unified skin std::string getSkinId() const { return skin_id_; } void setSkinId(const std::string& id) { skin_id_ = id; } // Privacy bool getSaveZtxs() const { return save_ztxs_; } void setSaveZtxs(bool save) { save_ztxs_ = save; } bool getAutoShield() const { return auto_shield_; } void setAutoShield(bool shield) { auto_shield_ = shield; } bool getUseTor() const { return use_tor_; } void setUseTor(bool tor) { use_tor_ = tor; } // Fees bool getAllowCustomFees() const { return allow_custom_fees_; } void setAllowCustomFees(bool allow) { allow_custom_fees_ = allow; } double getDefaultFee() const { return default_fee_; } void setDefaultFee(double fee) { default_fee_ = fee; } // Price bool getFetchPrices() const { return fetch_prices_; } void setFetchPrices(bool fetch) { fetch_prices_ = fetch; } // Explorer URLs std::string getTxExplorerUrl() const { return tx_explorer_url_; } void setTxExplorerUrl(const std::string& url) { tx_explorer_url_ = url; } std::string getAddressExplorerUrl() const { return address_explorer_url_; } void setAddressExplorerUrl(const std::string& url) { address_explorer_url_ = url; } // Language std::string getLanguage() const { return language_; } void setLanguage(const std::string& lang) { language_ = lang; } // Visual effects bool getAcrylicEnabled() const { return acrylic_enabled_; } void setAcrylicEnabled(bool v) { acrylic_enabled_ = v; } int getAcrylicQuality() const { return acrylic_quality_; } void setAcrylicQuality(int v) { acrylic_quality_ = v; } float getBlurMultiplier() const { return blur_multiplier_; } void setBlurMultiplier(float v) { blur_multiplier_ = v; } bool getReducedTransparency() const { return ui_opacity_ >= 0.99f; } void setReducedTransparency(bool v) { if (v) ui_opacity_ = 1.0f; } float getUIOpacity() const { return ui_opacity_; } void setUIOpacity(float v) { ui_opacity_ = std::max(0.3f, std::min(1.0f, v)); } float getWindowOpacity() const { return window_opacity_; } void setWindowOpacity(float v) { window_opacity_ = std::max(0.3f, std::min(1.0f, v)); } float getNoiseOpacity() const { return noise_opacity_; } void setNoiseOpacity(float v) { noise_opacity_ = v; } // Gradient background mode (use gradient variant of theme background) bool getGradientBackground() const { return gradient_background_; } void setGradientBackground(bool v) { gradient_background_ = v; } // Balance layout (string ID, e.g. "classic", "donut") std::string getBalanceLayout() const { return balance_layout_; } void setBalanceLayout(const std::string& v) { balance_layout_ = v; } // Console scanline effect bool getScanlineEnabled() const { return scanline_enabled_; } void setScanlineEnabled(bool v) { scanline_enabled_ = v; } // Hidden addresses (addresses hidden from the UI by the user) const std::set& getHiddenAddresses() const { return hidden_addresses_; } bool isAddressHidden(const std::string& addr) const { return hidden_addresses_.count(addr) > 0; } void hideAddress(const std::string& addr) { hidden_addresses_.insert(addr); } void unhideAddress(const std::string& addr) { hidden_addresses_.erase(addr); } int getHiddenAddressCount() const { return (int)hidden_addresses_.size(); } // Favorite addresses (pinned to top of address list) const std::set& getFavoriteAddresses() const { return favorite_addresses_; } bool isAddressFavorite(const std::string& addr) const { return favorite_addresses_.count(addr) > 0; } void favoriteAddress(const std::string& addr) { favorite_addresses_.insert(addr); } void unfavoriteAddress(const std::string& addr) { favorite_addresses_.erase(addr); } int getFavoriteAddressCount() const { return (int)favorite_addresses_.size(); } // First-run wizard bool getWizardCompleted() const { return wizard_completed_; } void setWizardCompleted(bool v) { wizard_completed_ = v; } // Security — auto-lock timeout (seconds; 0 = disabled) int getAutoLockTimeout() const { return auto_lock_timeout_; } void setAutoLockTimeout(int seconds) { auto_lock_timeout_ = seconds; } // Security — unlock duration (seconds) for walletpassphrase int getUnlockDuration() const { return unlock_duration_; } void setUnlockDuration(int seconds) { unlock_duration_ = seconds; } // Security — PIN unlock enabled bool getPinEnabled() const { return pin_enabled_; } void setPinEnabled(bool v) { pin_enabled_ = v; } // Daemon — keep running in background when closing the app bool getKeepDaemonRunning() const { return keep_daemon_running_; } void setKeepDaemonRunning(bool v) { keep_daemon_running_ = v; } // Daemon — stop externally-started daemons on exit (default: false) bool getStopExternalDaemon() const { return stop_external_daemon_; } void setStopExternalDaemon(bool v) { stop_external_daemon_ = v; } // Verbose diagnostic logging (connection attempts, daemon state, port owner, etc.) bool getVerboseLogging() const { return verbose_logging_; } void setVerboseLogging(bool v) { verbose_logging_ = v; } // Daemon — debug logging categories const std::set& getDebugCategories() const { return debug_categories_; } void setDebugCategories(const std::set& cats) { debug_categories_ = cats; } bool hasDebugCategory(const std::string& cat) const { return debug_categories_.count(cat) > 0; } void toggleDebugCategory(const std::string& cat) { if (debug_categories_.count(cat)) debug_categories_.erase(cat); else debug_categories_.insert(cat); } // Visual effects — animated theme effects (hue cycling, shimmer, glow, etc.) bool getThemeEffectsEnabled() const { return theme_effects_enabled_; } void setThemeEffectsEnabled(bool v) { theme_effects_enabled_ = v; } // Low-spec mode — disables heavy visual effects for better performance bool getLowSpecMode() const { return low_spec_mode_; } void setLowSpecMode(bool v) { low_spec_mode_ = v; } // Market — last selected exchange + pair std::string getSelectedExchange() const { return selected_exchange_; } void setSelectedExchange(const std::string& v) { selected_exchange_ = v; } std::string getSelectedPair() const { return selected_pair_; } void setSelectedPair(const std::string& v) { selected_pair_ = v; } // Pool mining std::string getPoolUrl() const { return pool_url_; } void setPoolUrl(const std::string& v) { pool_url_ = v; } std::string getPoolAlgo() const { return pool_algo_; } void setPoolAlgo(const std::string& v) { pool_algo_ = v; } std::string getPoolWorker() const { return pool_worker_; } void setPoolWorker(const std::string& v) { pool_worker_ = v; } int getPoolThreads() const { return pool_threads_; } void setPoolThreads(int v) { pool_threads_ = v; } bool getPoolTls() const { return pool_tls_; } void setPoolTls(bool v) { pool_tls_ = v; } bool getPoolHugepages() const { return pool_hugepages_; } void setPoolHugepages(bool v) { pool_hugepages_ = v; } bool getPoolMode() const { return pool_mode_; } void setPoolMode(bool v) { pool_mode_ = v; } // Mine when idle (auto-start mining when system is idle) bool getMineWhenIdle() const { return mine_when_idle_; } void setMineWhenIdle(bool v) { mine_when_idle_ = v; } int getMineIdleDelay() const { return mine_idle_delay_; } void setMineIdleDelay(int seconds) { mine_idle_delay_ = std::max(30, seconds); } // Saved pool URLs (user-managed favorites dropdown) const std::vector& getSavedPoolUrls() const { return saved_pool_urls_; } void addSavedPoolUrl(const std::string& url) { // Don't add duplicates for (const auto& u : saved_pool_urls_) if (u == url) return; saved_pool_urls_.push_back(url); } void removeSavedPoolUrl(const std::string& url) { saved_pool_urls_.erase( std::remove(saved_pool_urls_.begin(), saved_pool_urls_.end(), url), saved_pool_urls_.end()); } // Saved pool worker addresses (user-managed favorites dropdown) const std::vector& getSavedPoolWorkers() const { return saved_pool_workers_; } void addSavedPoolWorker(const std::string& addr) { for (const auto& a : saved_pool_workers_) if (a == addr) return; saved_pool_workers_.push_back(addr); } void removeSavedPoolWorker(const std::string& addr) { saved_pool_workers_.erase( std::remove(saved_pool_workers_.begin(), saved_pool_workers_.end(), addr), saved_pool_workers_.end()); } // Font scale (user accessibility setting, 1.0–1.5) float getFontScale() const { return font_scale_; } void setFontScale(float v) { font_scale_ = std::max(1.0f, std::min(1.5f, v)); } // Window size persistence (logical pixels at 1x scale) int getWindowWidth() const { return window_width_; } int getWindowHeight() const { return window_height_; } void setWindowSize(int w, int h) { window_width_ = w; window_height_ = h; } private: std::string settings_path_; // Settings values std::string theme_ = "dragonx"; std::string skin_id_ = "dragonx"; bool save_ztxs_ = true; bool auto_shield_ = true; bool use_tor_ = false; bool allow_custom_fees_ = false; double default_fee_ = 0.0001; bool fetch_prices_ = true; std::string tx_explorer_url_ = "https://explorer.dragonx.is/tx/"; std::string address_explorer_url_ = "https://explorer.dragonx.is/address/"; std::string language_ = "en"; bool acrylic_enabled_ = true; int acrylic_quality_ = 2; float blur_multiplier_ = 0.10f; float noise_opacity_ = 0.5f; bool gradient_background_ = false; float ui_opacity_ = 0.50f; // Card/sidebar opacity (0.3–1.0, 1.0 = opaque) float window_opacity_ = 0.75f; // Background alpha (0.3–1.0, <1 = desktop visible) std::string balance_layout_ = "classic"; bool scanline_enabled_ = true; std::set hidden_addresses_; std::set favorite_addresses_; bool wizard_completed_ = false; int auto_lock_timeout_ = 900; // 15 minutes int unlock_duration_ = 600; // 10 minutes bool pin_enabled_ = false; bool keep_daemon_running_ = false; bool stop_external_daemon_ = false; bool verbose_logging_ = false; std::set debug_categories_; bool theme_effects_enabled_ = true; bool low_spec_mode_ = false; std::string selected_exchange_ = "TradeOgre"; std::string selected_pair_ = "DRGX/BTC"; // Pool mining std::string pool_url_ = "pool.dragonx.is:3433"; std::string pool_algo_ = "rx/hush"; std::string pool_worker_ = "x"; int pool_threads_ = 0; bool pool_tls_ = false; bool pool_hugepages_ = true; bool pool_mode_ = false; // false=solo, true=pool bool mine_when_idle_ = false; // auto-start mining when system idle int mine_idle_delay_= 120; // seconds of idle before mining starts std::vector saved_pool_urls_; // user-saved pool URL favorites std::vector saved_pool_workers_; // user-saved worker address favorites // Font scale (user accessibility, 1.0–3.0; 1.0 = default) float font_scale_ = 1.0f; // Window size (logical pixels at 1x scale; 0 = use default 1200×775) int window_width_ = 0; int window_height_ = 0; }; } // namespace config } // namespace dragonx