Files
khadhroony-bot3/kb-app-demo-desktop/frontend/demo_wallet.html
2026-08-10 23:14:17 +02:00

245 lines
16 KiB
HTML

<!-- file: kb-app-demo-desktop/frontend/demo_wallet.html -->
<!-- version: 3 -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<link rel="icon" href="imgs/logo.png">
<link rel="stylesheet" href="sass/main.scss">
<title>Khadhroony Bot3 — Wallets</title>
</head>
<body>
<header class="app-header">
<nav class="navbar navbar-expand-lg h-100 py-0 bg-light text-dark">
<div class="container-fluid px-4 my-0">
<div class="navbar-brand d-flex align-items-center">
<img alt="Logo" src="imgs/logo.png" class="app-logo">
<span class="ps-2 fs-4 fw-bold text-primary font-logo">Bot3 — <span class="badge text-bg-primary">Wallets</span></span>
</div>
</div>
</nav>
</header>
<main class="app-main">
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
<div class="container-fluid px-4 py-4">
<div class="row g-4 justify-content-center">
<div class="col-12 col-xl-7">
<div class="card shadow-sm border-0 h-100">
<div class="card-body">
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
<div>
<h1 class="h3 card-title mb-1">Wallets natifs configurés</h1>
<p class="text-body-secondary mb-0">Inventaire des fichiers <code>.kswallet</code> du profil actif.</p>
</div>
<button id="refreshWalletInventoryButton" class="btn btn-primary" type="button">Rafraîchir</button>
</div>
<dl class="row mb-3">
<dt class="col-sm-3">Profil</dt>
<dd class="col-sm-9"><code id="walletProfile"></code></dd>
<dt class="col-sm-3">Cluster</dt>
<dd class="col-sm-9"><code id="walletCluster"></code></dd>
<dt class="col-sm-3">Statut</dt>
<dd class="col-sm-9"><code id="walletInventoryStatus">Chargement...</code></dd>
<dt class="col-sm-3">Alias sélectionné</dt>
<dd class="col-sm-9"><code id="walletSelectedAlias"></code></dd>
<dt class="col-sm-3">Wallets trouvés</dt>
<dd class="col-sm-9"><code id="walletInventoryCount">0</code></dd>
</dl>
<div class="table-responsive app-table-full-width">
<table class="table table-sm align-middle mb-0" id="walletInventoryTable">
<thead>
<tr>
<th>Alias</th>
<th>Pubkey déclarée</th>
<th>Format</th>
<th>Sélectionné</th>
<th>Action</th>
</tr>
</thead>
<tbody id="walletInventoryTableBody"></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-5">
<div class="card shadow-sm border-0 h-100">
<div class="card-body">
<h2 class="h5 card-title mb-3">Créer un wallet natif</h2>
<p class="text-body-secondary mb-2">Le mot de passe ne traverse jamais Tauri IPC. Cette démo utilise le secret backend <code>KB_SECRET_DEMO_WALLET_PASSWORD</code>.</p>
<div class="mb-3">
<span class="fw-semibold">Secret backend :</span>
<code id="walletCreateSecretStatus" class="ms-1"></code>
</div>
<label for="createWalletAliasInput" class="form-label">Alias</label>
<input id="createWalletAliasInput" class="form-control font-monospace" type="text" autocomplete="off" maxlength="64" placeholder="operator-devnet">
<div class="d-flex flex-wrap gap-2 mt-3">
<button id="createWalletButton" class="btn btn-primary" type="button">Créer</button>
</div>
<div class="mt-3">
<span class="fw-semibold">Statut :</span>
<code id="walletCreateStatus" class="ms-1">En attente</code>
</div>
<p class="small text-body-secondary mb-0 mt-3">La création n'écrit pas automatiquement <code>wallet_alias</code> dans la configuration. Elle ajoute seulement le nouveau conteneur au store du profil actif.</p>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body">
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
<div>
<h2 class="h4 card-title mb-1">Explorateur on-chain</h2>
<p class="text-body-secondary mb-0">Lecture publique du solde SOL, des comptes SPL Token / Token-2022 et de l'historique récent impliquant l'adresse sur le profil RPC sélectionné.</p>
</div>
<button id="loadWalletOnchainButton" class="btn btn-primary" type="button">Charger l'état on-chain</button>
</div>
<div class="row g-3 align-items-end">
<div class="col-12 col-lg-3">
<label for="walletOnchainProfileSelect" class="form-label">Profil RPC</label>
<select id="walletOnchainProfileSelect" class="form-select"></select>
<div class="small text-body-secondary mt-1">Cluster : <code id="walletOnchainCluster"></code></div>
</div>
<div class="col-12 col-lg-7">
<label for="walletAddressInput" class="form-label">Adresse publique</label>
<input id="walletAddressInput" class="form-control font-monospace" type="text" autocomplete="off" placeholder="Pubkey Solana">
</div>
<div class="col-12 col-lg-2">
<label for="walletSignatureLimitInput" class="form-label">Transactions</label>
<input id="walletSignatureLimitInput" class="form-control" type="number" min="1" max="100" value="20">
</div>
</div>
<div class="row g-3 mt-2">
<div class="col-12 col-md-4">
<div class="border rounded p-3 h-100">
<div class="small text-body-secondary">SOL</div>
<div class="fs-4 fw-semibold"><span id="walletSolBalance"></span> SOL</div>
<div class="small"><code id="walletLamportBalance"></code> lamports</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="border rounded p-3 h-100">
<div class="small text-body-secondary">Comptes token</div>
<div class="fs-4 fw-semibold" id="walletTokenCount"></div>
<div class="small" id="walletTokenStatus">En attente</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="border rounded p-3 h-100">
<div class="small text-body-secondary">Transactions récentes</div>
<div class="fs-4 fw-semibold" id="walletTransactionCount"></div>
<div class="small" id="walletTransactionStatus">En attente</div>
</div>
</div>
</div>
<div class="mt-3">
<span class="fw-semibold">Statut global :</span>
<code id="walletOnchainStatus" class="ms-1">En attente</code>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body">
<h2 class="h5 card-title mb-3">Tokens détenus</h2>
<div class="table-responsive app-table-full-width">
<table class="table table-sm align-middle mb-0">
<thead>
<tr>
<th>Programme</th>
<th>Mint</th>
<th>Compte token</th>
<th>Montant</th>
<th>Raw</th>
</tr>
</thead>
<tbody id="walletTokensTableBody"></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body">
<h2 class="h5 card-title mb-3">Transactions impliquant l'adresse</h2>
<div class="table-responsive app-table-full-width">
<table class="table table-sm align-middle mb-0">
<thead>
<tr>
<th>Signature</th>
<th>Slot</th>
<th>Date</th>
<th>Statut</th>
<th>Confirmation</th>
<th>Action</th>
</tr>
</thead>
<tbody id="walletTransactionsTableBody"></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="card shadow-sm border-0">
<div class="card-body">
<h2 class="h5 card-title mb-3">Détail de transaction</h2>
<div id="walletTransactionJson" class="app-config-box app-json-viewer mb-0">{"status":"idle","message":"Sélectionner une transaction."}</div>
</div>
</div>
</div>
<div class="col-12 col-xl-5">
<div class="card shadow-sm border-0 h-100">
<div class="card-body">
<h2 class="h5 card-title mb-3">Inspecter un fichier externe</h2>
<p class="text-body-secondary">Le chemin saisi est transmis au backend uniquement pour cette inspection et n'est pas retourné dans le résultat.</p>
<label for="walletExternalPathInput" class="form-label">Chemin du fichier <code>.kswallet</code></label>
<input id="walletExternalPathInput" class="form-control font-monospace" type="text" autocomplete="off" placeholder="/chemin/vers/operator.kswallet">
<div class="d-flex flex-wrap gap-2 mt-3">
<button id="inspectWalletFileButton" class="btn btn-primary" type="button">Inspecter</button>
<button id="clearWalletInspectionButton" class="btn btn-outline-secondary" type="button">Effacer</button>
</div>
<div class="mt-3">
<span class="fw-semibold">Statut :</span>
<code id="walletInspectionStatus" class="ms-1">En attente</code>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-7">
<div class="card shadow-sm border-0 h-100">
<div class="card-body">
<h2 class="h5 card-title mb-3">Identité inspectée</h2>
<div id="walletInspectionJson" class="app-config-box app-json-viewer mb-0">{"status":"idle","message":"Aucun fichier inspecté."}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<footer class="app-footer bg-dark text-light">
<div class="container h-100 d-flex align-items-center">
<div class="row flex-grow-1 align-items-center">
<div class="col-12 text-center text-small my-1 my-md-0">&copy; 2026 SASEDEV</div>
</div>
</div>
</footer>
<script type="module" src="ts/demo_wallet.ts" defer></script>
</body>
</html>