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:
2026-02-26 02:31:52 -06:00
commit 3aee55b49c
306 changed files with 177789 additions and 0 deletions

116
src/util/bootstrap.h Normal file
View File

@@ -0,0 +1,116 @@
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#pragma once
#include <string>
#include <vector>
#include <mutex>
#include <atomic>
#include <thread>
namespace dragonx {
namespace util {
/**
* @brief Bootstrap downloader + extractor for DRAGONX blockchain data.
*
* Downloads a blockchain snapshot zip from bootstrap.dragonx.is, verifies
* SHA-256 / MD5 checksums, extracts it into the DRAGONX data directory
* (skipping wallet.dat), and cleans old chain data before extraction.
* All work runs on a background thread; progress is queried thread-safely
* from the UI thread.
*/
class Bootstrap {
public:
enum class State {
Idle,
Downloading,
Extracting,
Completed,
Failed
};
struct Progress {
State state = State::Idle;
double downloaded_bytes = 0;
double total_bytes = 0; // 0 if server doesn't send Content-Length
float percent = 0.0f; // 0..100
std::string status_text; // human-readable status
std::string error; // non-empty on failure
};
Bootstrap() = default;
~Bootstrap();
// Non-copyable
Bootstrap(const Bootstrap&) = delete;
Bootstrap& operator=(const Bootstrap&) = delete;
/// Base URL for bootstrap downloads (zip + checksum files).
static constexpr const char* kBaseUrl = "https://bootstrap.dragonx.is";
static constexpr const char* kZipName = "DRAGONX.zip";
/// Start the bootstrap process on a background thread.
/// @param dataDir Path to DRAGONX data dir (e.g. ~/.hush/DRAGONX/)
/// @param url Bootstrap zip URL
void start(const std::string& dataDir,
const std::string& url = "https://bootstrap.dragonx.is/DRAGONX.zip");
/// Cancel an in-progress download/extract.
void cancel();
/// Thread-safe read of current progress.
Progress getProgress() const;
/// Whether the operation is finished (success or failure).
bool isDone() const;
/// Format a byte count as human-readable string (e.g. "1.24 GB")
static std::string formatSize(double bytes);
private:
mutable std::mutex mutex_;
Progress progress_;
std::atomic<bool> cancel_requested_{false};
std::thread worker_;
std::atomic<bool> worker_running_{false};
bool download(const std::string& url, const std::string& destZip);
bool extract(const std::string& zipPath, const std::string& dataDir);
void cleanChainData(const std::string& dataDir);
void setProgress(State state, const std::string& text, double downloaded = 0, double total = 0);
/// Download a small text file (checksum) into a string. Returns empty on failure.
std::string downloadSmallFile(const std::string& url);
/// Compute SHA-256 of a file, return lowercase hex digest.
/// Updates progress with "Verifying SHA-256..." status during computation.
std::string computeSHA256(const std::string& filePath);
/// Compute MD5 of a file, return lowercase hex digest.
/// Updates progress with "Verifying MD5..." status during computation.
std::string computeMD5(const std::string& filePath);
/// Parse the first hex token from a checksum file (handles "<hash> <filename>" format).
static std::string parseChecksumFile(const std::string& content);
/// Verify downloaded zip against remote checksums. Returns true if valid.
bool verifyChecksums(const std::string& zipPath, const std::string& baseUrl);
/// Perform a HEAD request to get remote file size.
/// Returns -1 on failure.
long long getRemoteFileSize(const std::string& url);
/// Byte offset of the partial file when resuming a download.
/// Added to dlnow in progress reports so the bar reflects true total.
double resume_offset_{0};
// libcurl progress callback (static → calls into instance via clientp)
static int progressCallback(void* clientp, long long dltotal, long long dlnow,
long long ultotal, long long ulnow);
};
} // namespace util
} // namespace dragonx