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)
94 lines
2.4 KiB
C++
94 lines
2.4 KiB
C++
// ObsidianDragon Wallet - ImGui Edition
|
|
// Copyright 2024-2026 The Hush Developers
|
|
// Released under the GPLv3
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <cstdint>
|
|
|
|
namespace dragonx {
|
|
namespace util {
|
|
|
|
/**
|
|
* @brief PIN-encrypted passphrase vault
|
|
*
|
|
* Stores the wallet passphrase encrypted with a PIN-derived key using
|
|
* libsodium's Argon2id (key derivation) + XSalsa20-Poly1305 (AEAD).
|
|
*
|
|
* File format (vault.dat):
|
|
* [1 byte] version (0x01)
|
|
* [16 bytes] Argon2id salt
|
|
* [24 bytes] XSalsa20 nonce
|
|
* [N bytes] ciphertext (passphrase + 16-byte Poly1305 tag)
|
|
*
|
|
* The PIN is 4-8 digits. Argon2id uses moderate ops/mem limits
|
|
* to resist brute-force on the small PIN space while keeping
|
|
* unlock time under ~1 second.
|
|
*/
|
|
class SecureVault {
|
|
public:
|
|
SecureVault();
|
|
~SecureVault();
|
|
|
|
/**
|
|
* @brief Check if a vault file exists on disk
|
|
*/
|
|
bool hasVault() const;
|
|
|
|
/**
|
|
* @brief Encrypt passphrase with PIN and save to vault.dat
|
|
* @param pin The user's PIN (4-8 digits)
|
|
* @param passphrase The wallet passphrase to protect
|
|
* @return true on success
|
|
*/
|
|
bool store(const std::string& pin, const std::string& passphrase);
|
|
|
|
/**
|
|
* @brief Decrypt passphrase from vault using PIN
|
|
* @param pin The user's PIN
|
|
* @param[out] passphrase The recovered passphrase
|
|
* @return true if PIN was correct and decryption succeeded
|
|
*/
|
|
bool retrieve(const std::string& pin, std::string& passphrase) const;
|
|
|
|
/**
|
|
* @brief Change the PIN (re-encrypt with new PIN)
|
|
* @param oldPin Current PIN
|
|
* @param newPin New PIN
|
|
* @return true if old PIN was valid and re-encryption succeeded
|
|
*/
|
|
bool changePin(const std::string& oldPin, const std::string& newPin);
|
|
|
|
/**
|
|
* @brief Remove the vault file
|
|
* @return true if deleted or didn't exist
|
|
*/
|
|
bool removeVault();
|
|
|
|
/**
|
|
* @brief Validate PIN format (4-8 digits)
|
|
*/
|
|
static bool isValidPin(const std::string& pin);
|
|
|
|
/**
|
|
* @brief Securely zero memory
|
|
*/
|
|
static void secureZero(void* ptr, size_t len);
|
|
|
|
/**
|
|
* @brief Get the vault file path
|
|
*/
|
|
static std::string getVaultPath();
|
|
|
|
private:
|
|
// Derive a 32-byte key from PIN + salt using Argon2id
|
|
bool deriveKey(const std::string& pin,
|
|
const uint8_t* salt, size_t saltLen,
|
|
uint8_t* key, size_t keyLen) const;
|
|
};
|
|
|
|
} // namespace util
|
|
} // namespace dragonx
|