ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency. Built with Dear ImGui, SDL3, and OpenGL3/DX11. Features: - Send/receive shielded and transparent transactions - Autoshield with merged transaction display - Built-in CPU mining (xmrig) - Peer management and network monitoring - Wallet encryption with PIN lock - QR code generation for receive addresses - Transaction history with pagination - Console for direct RPC commands - Cross-platform (Linux, Windows)
This commit is contained in:
267
src/data/wallet_state.h
Normal file
267
src/data/wallet_state.h
Normal file
@@ -0,0 +1,267 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
|
||||
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<double> 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;
|
||||
|
||||
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<double> 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<double> hashrate_history;
|
||||
static constexpr int MAX_HISTORY = 60; // 5 minutes at ~5s intervals
|
||||
|
||||
// Recent log lines for the log panel
|
||||
std::vector<std::string> 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<AddressInfo> addresses;
|
||||
|
||||
// Also keep separate lists for legacy code
|
||||
std::vector<AddressInfo> z_addresses;
|
||||
std::vector<AddressInfo> t_addresses;
|
||||
|
||||
// Transactions
|
||||
std::vector<TransactionInfo> transactions;
|
||||
|
||||
// Peers
|
||||
std::vector<PeerInfo> peers;
|
||||
std::vector<BannedPeer> bannedPeers;
|
||||
|
||||
// Aliases for banned_peers
|
||||
std::vector<BannedPeer>& 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
|
||||
Reference in New Issue
Block a user