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

179
src/ui/widgets/qr_code.cpp Normal file
View File

@@ -0,0 +1,179 @@
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#include "qr_code.h"
#include "../schema/ui_schema.h"
#include "imgui.h"
#include "../../../libs/qrcode/QrCode.hpp"
#ifdef DRAGONX_USE_DX11
#include <d3d11.h>
#else
#include <SDL3/SDL_opengl.h>
#endif
#include <cstdint>
#include <vector>
#include "../../util/logger.h"
#ifdef DRAGONX_USE_DX11
// Forward-declared helper to get D3D11 device from ImGui backend state
static ID3D11Device* GetImGuiD3D11Device()
{
// ImGui_ImplDX11 stores the device in its backend data
// Access through the render state stored during init
ImGuiIO& io = ImGui::GetIO();
if (!io.BackendRendererUserData) return nullptr;
// The first field in ImGui_ImplDX11_Data is the device pointer
return *reinterpret_cast<ID3D11Device**>(io.BackendRendererUserData);
}
#endif
namespace dragonx {
namespace ui {
uintptr_t GenerateQRTexture(const char* data, int* out_width, int* out_height)
{
if (!data || !data[0]) {
return 0;
}
try {
// Generate QR code
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(
data, qrcodegen::QrCode::Ecc::MEDIUM);
const auto& S = schema::UI();
int qr_size = qr.getSize();
auto qrE = S.drawElement("components.qr-code", "module-scale");
int scale = qrE.size >= 0 ? (int)qrE.size : 4;
auto qrB = S.drawElement("components.qr-code", "border-modules");
int border = qrB.size >= 0 ? (int)qrB.size : 2;
int img_size = (qr_size + border * 2) * scale;
// Create pixel data (RGBA)
std::vector<unsigned char> pixels(img_size * img_size * 4);
for (int y = 0; y < img_size; y++) {
for (int x = 0; x < img_size; x++) {
int qx = x / scale - border;
int qy = y / scale - border;
bool is_black = false;
if (qx >= 0 && qx < qr_size && qy >= 0 && qy < qr_size) {
is_black = qr.getModule(qx, qy);
}
int idx = (y * img_size + x) * 4;
unsigned char color = is_black ? 0 : 255;
pixels[idx + 0] = color; // R
pixels[idx + 1] = color; // G
pixels[idx + 2] = color; // B
pixels[idx + 3] = 255; // A
}
}
#ifdef DRAGONX_USE_DX11
// Create D3D11 texture + shader resource view
ID3D11Device* device = GetImGuiD3D11Device();
if (!device) return 0;
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = img_size;
desc.Height = img_size;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA initData = {};
initData.pSysMem = pixels.data();
initData.SysMemPitch = img_size * 4;
ID3D11Texture2D* texture = nullptr;
HRESULT hr = device->CreateTexture2D(&desc, &initData, &texture);
if (FAILED(hr) || !texture) return 0;
ID3D11ShaderResourceView* srv = nullptr;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = desc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
hr = device->CreateShaderResourceView(texture, &srvDesc, &srv);
texture->Release();
if (FAILED(hr) || !srv) return 0;
if (out_width) *out_width = img_size;
if (out_height) *out_height = img_size;
// Return SRV pointer as uintptr_t (cast to ImTextureID when rendering)
return (uintptr_t)srv;
#else
// Create OpenGL texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_size, img_size, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
if (out_width) *out_width = img_size;
if (out_height) *out_height = img_size;
return texture;
#endif
} catch (const std::exception& e) {
DEBUG_LOGF("QR generation failed: %s\n", e.what());
return 0;
}
}
void FreeQRTexture(uintptr_t texture_id)
{
if (texture_id) {
#ifdef DRAGONX_USE_DX11
ID3D11ShaderResourceView* srv = (ID3D11ShaderResourceView*)texture_id;
srv->Release();
#else
GLuint tex = texture_id;
glDeleteTextures(1, &tex);
#endif
}
}
void RenderQRCode(uintptr_t texture_id, float size)
{
if (texture_id) {
ImGui::Image((ImTextureID)texture_id, ImVec2(size, size));
} else {
// Draw placeholder
ImVec2 cursor = ImGui::GetCursorScreenPos();
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRectFilled(
cursor,
ImVec2(cursor.x + size, cursor.y + size),
IM_COL32(200, 200, 200, 255)
);
draw_list->AddRect(
cursor,
ImVec2(cursor.x + size, cursor.y + size),
IM_COL32(100, 100, 100, 255)
);
ImGui::Dummy(ImVec2(size, size));
}
}
} // namespace ui
} // namespace dragonx

39
src/ui/widgets/qr_code.h Normal file
View File

@@ -0,0 +1,39 @@
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#pragma once
#include <cstdint>
namespace dragonx {
namespace ui {
/**
* @brief QR Code rendering utilities
*/
/**
* @brief Generate a texture containing a QR code
* @param data The data to encode in the QR code
* @param out_width Output: width of the texture
* @param out_height Output: height of the texture
* @return Texture handle (OpenGL texture ID or DX11 SRV pointer), or 0 on failure
*/
uintptr_t GenerateQRTexture(const char* data, int* out_width, int* out_height);
/**
* @brief Free a QR texture
* @param texture_id Texture handle returned by GenerateQRTexture
*/
void FreeQRTexture(uintptr_t texture_id);
/**
* @brief Render a QR code using ImGui
* @param texture_id Texture handle from GenerateQRTexture
* @param size Display size (width and height)
*/
void RenderQRCode(uintptr_t texture_id, float size);
} // namespace ui
} // namespace dragonx