v0.2.6-pre.007

This commit is contained in:
2026-08-21 10:50:36 +02:00
parent 4c9086e2f0
commit f11f0921b0
25 changed files with 871 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/frontend/ts/main.ts
// version: 6
// version: 7
import "bootstrap";
import DataTable from "datatables.net-bs5";
@@ -7,6 +7,7 @@ import "datatables.net-select-bs5";
import ResizeObserver from "resize-observer-polyfill";
import "simplebar";
import { getCurrentWindow } from "@tauri-apps/api/window";
import type { WalletBalanceDto } from "./bindings/ksp_app_wallet_desk/wallet_balance/WalletBalanceDto.ts";
import type { RuntimeStatusDto } from "./bindings/ksp_app_wallet_desk/dto_common/RuntimeStatusDto.ts";
import type { LockedWalletDto } from "./bindings/ksp_app_wallet_desk/wallet_inventory/LockedWalletDto.ts";
import type { WalletInventoryEntryDto } from "./bindings/ksp_app_wallet_desk/wallet_inventory/WalletInventoryEntryDto.ts";
@@ -169,7 +170,7 @@ function initializeWalletTable(): void {
zeroRecords: "Aucun wallet correspondant.",
},
});
frontendDebug("main", "Wallet inventory DataTable initialized", { phase: "pre.006-wallet-unlock" });
frontendDebug("main", "Wallet inventory DataTable initialized", { phase: "pre.007-wallet-balance" });
}
function renderWalletInventory(entries: WalletInventoryEntryDto[]): void {
@@ -193,6 +194,7 @@ function setText(selector: string, value: string): void {
}
function updateSessionActions(): void {
const refreshBalance = document.querySelector<HTMLButtonElement>("#refreshWalletBalance");
const lock = document.querySelector<HTMLButtonElement>('[data-shell-action="lock"]');
const deselect = document.querySelector<HTMLButtonElement>('[data-shell-action="deselect"]');
if (lock) {
@@ -201,6 +203,9 @@ function updateSessionActions(): void {
if (deselect) {
deselect.disabled = activeSessionState === "no_selection" || activeSessionState === "privileged_operation";
}
if (refreshBalance) {
refreshBalance.disabled = activeSessionState !== "view_open" && activeSessionState !== "owner_open";
}
updateUnlockActions();
}
@@ -255,10 +260,24 @@ function clearUnlockSensitiveInputs(): void {
}
}
function clearBalanceProjection(): void {
setText("#currentWalletBalanceSol", "—");
setText("#detailsBalanceLamports", "—");
setText("#detailsBalanceSol", "—");
setText("#detailsBalanceSlot", "—");
setText("#detailsBalanceApiVersion", "—");
setText("#detailsBalanceTransport", "—");
setText("#balanceStatus", "Unlock VIEW ou OWNER pour interroger getBalance.");
}
function clearAuthorizedProjection(): void {
setText("#currentWalletPubkey", "—");
setText("#currentWalletAlias", "—");
setText("#currentWalletNotes", "—");
setText("#detailsWalletPubkey", "—");
setText("#detailsWalletAlias", "—");
setText("#detailsWalletNotes", "—");
clearBalanceProjection();
clearCreateFormSensitiveInputs();
clearUnlockSensitiveInputs();
}
@@ -325,7 +344,13 @@ function renderAuthorizedWallet(wallet: WalletAuthorizedDto): void {
setText("#currentWalletSecretCandidates", configuredSecretCandidateCount.toString());
setText("#currentWalletPubkey", wallet.pubkey);
setText("#currentWalletAlias", wallet.alias ?? "—");
setText("#currentWalletNotes", wallet.notes.length === 0 ? "—" : wallet.notes.map(note => note.text).join(" · "));
const notesText = wallet.notes.length === 0 ? "—" : wallet.notes.map(note => note.text).join(" · ");
setText("#currentWalletNotes", notesText);
setText("#detailsWalletPubkey", wallet.pubkey);
setText("#detailsWalletAlias", wallet.alias ?? "—");
setText("#detailsWalletNotes", notesText);
clearBalanceProjection();
setText("#balanceStatus", "Session autorisée. Refresh balance appelle getBalance avec la Pubkey détenue par Rust.");
setText("#unlockStatus", `${capabilityLabel} ouvert. Lock pour purger le handle autorisé.`);
updateSessionActions();
frontendDebug("main", "Authorized Wallet session rendered", {
@@ -570,10 +595,61 @@ async function deselectCurrentWallet(): Promise<void> {
}
}
function renderWalletBalance(balance: WalletBalanceDto): void {
if (activeWalletId !== balance.walletId || (activeSessionState !== "view_open" && activeSessionState !== "owner_open")) {
frontendWarn("main", "Stale Wallet balance response ignored", { walletId: balance.walletId });
return;
}
setText("#currentWalletBalanceSol", balance.sol);
setText("#detailsBalanceLamports", balance.lamports);
setText("#detailsBalanceSol", balance.sol);
setText("#detailsBalanceSlot", balance.slot.toString());
setText("#detailsBalanceApiVersion", balance.apiVersion ?? "—");
setText("#detailsBalanceTransport", `${balance.transportProfile} / ${balance.transportRole}`);
setText("#balanceStatus", "Balance réseau actualisée.");
frontendInfo("main", "Wallet balance rendered", { lamports: balance.lamports, slot: balance.slot, walletId: balance.walletId });
}
async function refreshWalletBalance(): Promise<void> {
if (!activeWalletId || (activeSessionState !== "view_open" && activeSessionState !== "owner_open")) {
return;
}
const walletId = activeWalletId;
setText("#balanceStatus", "Interrogation getBalance en cours…");
frontendDebug("main", "Wallet balance refresh requested", { walletId });
try {
const balance = await invokeKsp<WalletBalanceDto>("main", "refresh_wallet_balance");
renderWalletBalance(balance);
} catch {
if (activeWalletId === walletId) {
clearBalanceProjection();
setText("#balanceStatus", "Échec getBalance. Consulter le diagnostic et les logs.");
}
frontendWarn("main", "Wallet balance refresh failed", { walletId });
}
}
function bindBalanceActions(): void {
document.querySelector<HTMLButtonElement>("#refreshWalletBalance")?.addEventListener("click", () => {
void refreshWalletBalance();
});
frontendTrace("main", "Wallet balance action handlers installed");
}
function renderRuntimeStatus(status: RuntimeStatusDto): void {
setText("#runtimeVersion", status.applicationVersion);
setText("#runtimeCompositeProfile", status.activeCompositeProfile);
setText("#runtimeLoggingProfile", status.activeLoggingProfile ?? "fallback transitoire");
setText("#runtimeTransportProfile", status.activeTransportProfile);
setText("#runtimeTransportClusters", status.transportClusters.join(", ") || "—");
setText("#runtimeTransportProviders", status.transportProviders.join(", ") || "—");
setText("#runtimeTransportEndpoints", `${status.transportAvailableEndpointCount}/${status.transportEndpointCount} disponibles`);
setText("#runtimeTransportRole", status.transportRole);
setText("#diagnosticsTransportProfile", status.activeTransportProfile);
setText("#diagnosticsTransportClusters", status.transportClusters.join(", ") || "—");
setText("#diagnosticsTransportProviders", status.transportProviders.join(", ") || "—");
setText("#diagnosticsTransportEndpoints", `${status.transportAvailableEndpointCount}/${status.transportEndpointCount}`);
setText("#diagnosticsTransportRole", status.transportRole);
setText("#runtimeWalletProfile", status.activeWalletProfile);
setText("#runtimeLoggingFallback", status.fallbackLoggingActive ? "oui" : "non");
setText("#runtimeConfigDocuments", status.configDocumentCount.toString());
@@ -582,11 +658,13 @@ function renderRuntimeStatus(status: RuntimeStatusDto): void {
setText("#runtimeEffectiveWalletsDirectory", status.effectiveWalletsDirectory);
setText("#runtimeWalletDirectoryCreated", status.effectiveWalletsDirectoryCreatedOnStartup ? "oui" : "non, déjà présent");
setText("#runtimeShellPhase", status.shellPhase);
setText("#shellStatus", "Config résolue ; création et unlock VIEW/OWNER prêts.");
setText("#shellStatus", "Config/Transport résolus ; VIEW/OWNER et getBalance prêts.");
frontendTrace("main", "Wallet Desk runtime status rendered", {
compositeProfile: status.activeCompositeProfile,
fallbackLoggingActive: status.fallbackLoggingActive,
shellPhase: status.shellPhase,
transportEndpointCount: status.transportEndpointCount,
transportProfile: status.activeTransportProfile,
walletDirectoryCreatedOnStartup: status.effectiveWalletsDirectoryCreatedOnStartup,
walletProfile: status.activeWalletProfile,
});
@@ -629,6 +707,7 @@ async function initializeMain(): Promise<void> {
bindWalletTableSelection();
bindCreateWalletForm();
bindUnlockActions();
bindBalanceActions();
bindShellActions();
clearSelectedWallet();
activateView("dashboard", "startup");