// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include #include #include #include namespace dragonx { /** * @brief Represents an address with its balance */ struct AddressInfo { std::string address; double balance = 0.0; std::string type; // "shielded" or "transparent" // For display std::string label; // Derived bool isZAddr() const { return !address.empty() && address[0] == 'z'; } bool isShielded() const { return type == "shielded"; } }; /** * @brief Represents a wallet transaction */ struct TransactionInfo { std::string txid; std::string type; // "send", "receive", "mined" double amount = 0.0; int64_t timestamp = 0; // Unix timestamp int confirmations = 0; std::string address; // destination (send) or source (receive) std::string from_address; // source address for sends std::string memo; // Computed fields std::string getTimeString() const; std::string getTypeDisplay() const; bool isConfirmed() const { return confirmations >= 1; } bool isMature() const { return confirmations >= 100; } }; /** * @brief Represents a connected peer */ struct PeerInfo { int id = 0; std::string addr; std::string subver; std::string services; int version = 0; int64_t conntime = 0; int banscore = 0; double pingtime = 0.0; int64_t bytessent = 0; int64_t bytesrecv = 0; int startingheight = 0; int synced_headers = 0; int synced_blocks = 0; bool inbound = false; // TLS info std::string tls_cipher; bool tls_verified = false; std::string getConnectionTime() const; }; /** * @brief Represents a banned peer */ struct BannedPeer { std::string address; std::string subnet; int64_t banned_until = 0; std::string getBannedUntilString() const; }; /** * @brief Mining statistics */ struct MiningInfo { bool generate = false; int genproclimit = 0; // -1 means max CPUs double localHashrate = 0.0; // Local hashrate (H/s) from getlocalsolps RPC (RandomX) double networkHashrate = 0.0; // Network hashrate (H/s) int blocks = 0; double difficulty = 0.0; std::string chain; double daemon_memory_mb = 0.0; // Daemon process RSS in MB // History for chart std::vector hashrate_history; // Last N samples static constexpr int MAX_HISTORY = 300; // 5 minutes at 1s intervals }; /** * @brief Blockchain synchronization info */ struct SyncInfo { int blocks = 0; int headers = 0; double verification_progress = 0.0; bool syncing = false; std::string best_blockhash; // Rescan state (detected from daemon output) bool rescanning = false; float rescan_progress = 0.0f; // 0.0 - 1.0 std::string rescan_status; // e.g. "Rescanning... 25%" bool isSynced() const { return !syncing && blocks > 0 && blocks >= headers - 2; } }; /** * @brief Market/price information */ struct MarketInfo { double price_usd = 0.0; double price_btc = 0.0; double volume_24h = 0.0; double change_24h = 0.0; double market_cap = 0.0; std::string last_updated; // Price history for chart std::vector price_history; static constexpr int MAX_HISTORY = 24; // 24 hours }; /** * @brief Pool mining state (from xmrig HTTP API) */ struct PoolMiningState { bool pool_mode = false; // UI toggle: solo vs pool bool xmrig_running = false; std::string pool_url; std::string algo; double hashrate_10s = 0; double hashrate_60s = 0; double hashrate_15m = 0; int64_t accepted = 0; int64_t rejected = 0; int64_t uptime_sec = 0; double pool_diff = 0; bool connected = false; // Memory/thread usage (bytes for memory) int64_t memory_used = 0; int threads_active = 0; // Hashrate history for chart (mirrors MiningInfo::hashrate_history) std::vector hashrate_history; static constexpr int MAX_HISTORY = 60; // 5 minutes at ~5s intervals // Recent log lines for the log panel std::vector log_lines; }; /** * @brief Complete wallet state - all data fetched from daemon */ struct WalletState { // Connection bool connected = false; int daemon_version = 0; std::string daemon_subversion; int protocol_version = 0; int p2p_port = 0; int longestchain = 0; int notarized = 0; // Sync status SyncInfo sync; // Balances (named to match UI usage) double privateBalance = 0.0; // shielded balance double transparentBalance = 0.0; double totalBalance = 0.0; double unconfirmedBalance = 0.0; // Aliases for backward compatibility double& shielded_balance = privateBalance; double& transparent_balance = transparentBalance; double& total_balance = totalBalance; double& unconfirmed_balance = unconfirmedBalance; // Addresses - combined list for UI convenience std::vector addresses; // Also keep separate lists for legacy code std::vector z_addresses; std::vector t_addresses; // Transactions std::vector transactions; // Peers std::vector peers; std::vector bannedPeers; // Aliases for banned_peers std::vector& banned_peers = bannedPeers; // Mining MiningInfo mining; // Pool mining (xmrig) PoolMiningState pool_mining; // Market MarketInfo market; // Wallet encryption state (populated from getwalletinfo) bool encrypted = false; // true if wallet has ever been encrypted bool locked = false; // true if encrypted && unlocked_until <= now int64_t unlocked_until = 0; // 0 = locked, >0 = unix timestamp when auto-lock fires bool encryption_state_known = false; // true once first getwalletinfo response processed bool isEncrypted() const { return encrypted; } bool isLocked() const { return encrypted && locked; } bool isUnlocked() const { return encrypted && !locked; } // Timestamps for refresh logic int64_t last_balance_update = 0; int64_t last_tx_update = 0; int64_t last_peer_update = 0; int64_t last_mining_update = 0; // Helper methods int getAddressCount() const { return addresses.size(); } double getBalanceUSD() const { return totalBalance * market.price_usd; } void clear() { connected = false; privateBalance = transparentBalance = totalBalance = 0.0; encrypted = false; locked = false; unlocked_until = 0; encryption_state_known = false; addresses.clear(); z_addresses.clear(); t_addresses.clear(); transactions.clear(); peers.clear(); bannedPeers.clear(); } // Rebuild combined addresses list from z/t lists void rebuildAddressList() { addresses.clear(); addresses.reserve(z_addresses.size() + t_addresses.size()); for (const auto& addr : z_addresses) { addresses.push_back(addr); } for (const auto& addr : t_addresses) { addresses.push_back(addr); } } }; } // namespace dragonx