488 lines
42 KiB
HTML
488 lines
42 KiB
HTML
<!doctype html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Wallet Desk — Dashboard</title>
|
||
</head>
|
||
<body>
|
||
<header class="app-header bg-dark text-white shadow-sm">
|
||
<div class="container-fluid h-100 d-flex align-items-center gap-3 px-4">
|
||
<img class="app-logo" src="./imgs/logo.png" alt="KSP">
|
||
<div class="d-flex flex-column me-auto">
|
||
<span class="fw-semibold">Wallet Desk — <span id="headerViewTitle">Dashboard</span></span>
|
||
<small id="shellStatus" class="text-white-50 app-shell-status">Initialisation du shell…</small>
|
||
</div>
|
||
<button class="btn btn-outline-light btn-sm" type="button" data-shell-action="deselect" disabled>
|
||
<i class="fa-solid fa-xmark me-2" aria-hidden="true"></i>Deselect
|
||
</button>
|
||
<button class="btn btn-outline-light btn-sm" type="button" data-shell-action="lock" disabled>
|
||
<i class="fa-solid fa-lock me-2" aria-hidden="true"></i>Lock
|
||
</button>
|
||
</div>
|
||
</header>
|
||
<main class="app-main container-fluid p-0">
|
||
<div class="row g-0 h-100">
|
||
<aside class="col-auto app-sidebar border-end bg-body-tertiary">
|
||
<div class="app-sidebar-scroll h-100" data-simplebar>
|
||
<nav class="nav nav-pills flex-column gap-1 p-3" aria-label="Navigation Wallet Desk">
|
||
<button class="nav-link text-start active" type="button" data-view="dashboard"><i class="fa-solid fa-gauge-high me-2" aria-hidden="true"></i>Dashboard</button>
|
||
<button class="nav-link text-start" type="button" data-view="wallets"><i class="fa-solid fa-wallet me-2" aria-hidden="true"></i>Wallets</button>
|
||
<button class="nav-link text-start" type="button" data-view="create-import"><i class="fa-solid fa-circle-plus me-2" aria-hidden="true"></i>Create / Import</button>
|
||
<button class="nav-link text-start" type="button" data-view="details"><i class="fa-solid fa-id-card me-2" aria-hidden="true"></i>Details</button>
|
||
<button class="nav-link text-start" type="button" data-view="security"><i class="fa-solid fa-shield-halved me-2" aria-hidden="true"></i>Security</button>
|
||
<button class="nav-link text-start" type="button" data-view="diagnostics"><i class="fa-solid fa-stethoscope me-2" aria-hidden="true"></i>Diagnostics</button>
|
||
</nav>
|
||
</div>
|
||
</aside>
|
||
<section class="col app-content h-100" data-simplebar>
|
||
<div class="p-4">
|
||
<div class="d-flex align-items-center justify-content-between mb-4">
|
||
<div>
|
||
<h1 id="viewTitle" class="h3 mb-1">Dashboard</h1>
|
||
<p class="text-body-secondary mb-0">Identité autorisée et balance SOL via le Transport HTTP composite sont actives.</p>
|
||
</div>
|
||
<span class="badge text-bg-secondary">0.2.6-pre.013</span>
|
||
</div>
|
||
<section data-view-panel="dashboard">
|
||
<div class="row g-3">
|
||
<div class="col-xl-8">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Runtime</div>
|
||
<div class="card-body">
|
||
<dl class="row mb-0 app-runtime-list">
|
||
<dt class="col-sm-5">Version</dt><dd id="runtimeVersion" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Phase</dt><dd id="runtimeShellPhase" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Documents Config enregistrés</dt><dd id="runtimeConfigDocuments" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Profil composite</dt><dd id="runtimeCompositeProfile" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Profil Logging</dt><dd id="runtimeLoggingProfile" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Profil Transport</dt><dd id="runtimeTransportProfile" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Cluster Transport</dt><dd id="runtimeTransportClusters" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Provider Transport</dt><dd id="runtimeTransportProviders" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Endpoints Transport</dt><dd id="runtimeTransportEndpoints" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Rôle Transport</dt><dd id="runtimeTransportRole" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Profil Wallet</dt><dd id="runtimeWalletProfile" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Fallback Logging</dt><dd id="runtimeLoggingFallback" class="col-sm-7">—</dd>
|
||
<dt class="col-sm-5">Racine Wallet</dt><dd id="runtimeWalletsDirectory" class="col-sm-7 text-break">—</dd>
|
||
<dt class="col-sm-5">Sous-répertoire Wallet</dt><dd id="runtimeWalletsSubdirectory" class="col-sm-7 text-break">—</dd>
|
||
<dt class="col-sm-5">Répertoire effectif</dt><dd id="runtimeEffectiveWalletsDirectory" class="col-sm-7 text-break">—</dd>
|
||
<dt class="col-sm-5">Créé au démarrage</dt><dd id="runtimeWalletDirectoryCreated" class="col-sm-7">—</dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-xl-4">
|
||
<div class="card shadow-sm h-100">
|
||
<div class="card-header fw-semibold">Wallet courant</div>
|
||
<div class="card-body text-center">
|
||
<i id="currentWalletIcon" class="fa-solid fa-lock fa-2x mb-3 text-body-secondary" aria-hidden="true"></i>
|
||
<p id="currentWalletFilename" class="fw-semibold mb-2">Aucun wallet sélectionné.</p>
|
||
<dl class="row small text-start mb-0">
|
||
<dt class="col-5">État</dt><dd id="currentWalletState" class="col-7">—</dd>
|
||
<dt class="col-5">Format</dt><dd id="currentWalletFormat" class="col-7">—</dd>
|
||
<dt class="col-5">VIEW</dt><dd id="currentWalletView" class="col-7">—</dd>
|
||
<dt class="col-5">Secrets Config</dt><dd id="currentWalletSecretCandidates" class="col-7">0</dd>
|
||
<dt class="col-5">Pubkey</dt><dd id="currentWalletPubkey" class="col-7 text-break">—</dd>
|
||
<dt class="col-5">Alias</dt><dd id="currentWalletAlias" class="col-7 text-break">—</dd>
|
||
<dt class="col-5">Notes</dt><dd id="currentWalletNotes" class="col-7 text-break">—</dd>
|
||
<dt class="col-5">Balance SOL</dt><dd id="currentWalletBalanceSol" class="col-7">—</dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section data-view-panel="wallets" hidden>
|
||
<div class="card shadow-sm">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<div class="d-flex align-items-center gap-3">
|
||
<span class="fw-semibold">Wallets disponibles</span>
|
||
<small class="text-body-secondary"><i class="fa-solid fa-lock me-1" aria-hidden="true"></i>verrouillé · <i class="fa-solid fa-lock-open me-1" aria-hidden="true"></i>ouvert</small>
|
||
</div>
|
||
<button class="btn btn-outline-primary btn-sm" type="button" data-shell-action="refresh-wallets">
|
||
<i class="fa-solid fa-rotate me-2" aria-hidden="true"></i>Refresh
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<table id="walletInventoryTable" class="table table-striped table-hover align-middle w-100">
|
||
<thead><tr><th>État</th><th>Filename</th><th>Format</th><th>VIEW</th><th>Inspection</th></tr></thead>
|
||
<tbody id="walletInventoryBody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section data-view-panel="create-import" hidden>
|
||
<div class="row g-3">
|
||
<div class="col-xl-8">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Créer un wallet natif KSP</div>
|
||
<div class="card-body">
|
||
<form id="createWalletForm" autocomplete="off">
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="createWalletFilename">Filename</label>
|
||
<input id="createWalletFilename" class="form-control" type="text" value="wallet-01.kspwallet" required spellcheck="false">
|
||
<div class="form-text">Un seul filename sous le répertoire Wallet effectif, suffixe exact .kspwallet.</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="createWalletAlias">Alias interne optionnel</label>
|
||
<input id="createWalletAlias" class="form-control" type="text" autocomplete="off">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="createWalletOwnerPassword">OWNER password</label>
|
||
<input id="createWalletOwnerPassword" class="form-control" type="password" autocomplete="new-password" required>
|
||
</div>
|
||
<div class="col-md-6 d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input id="createWalletEnableView" class="form-check-input" type="checkbox">
|
||
<label class="form-check-label" for="createWalletEnableView">Créer aussi une capability VIEW</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="createWalletViewPassword">VIEW password</label>
|
||
<input id="createWalletViewPassword" class="form-control" type="password" autocomplete="new-password" disabled>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label" for="createWalletInitialNote">Note initiale optionnelle</label>
|
||
<textarea id="createWalletInitialNote" class="form-control" rows="3" autocomplete="off"></textarea>
|
||
</div>
|
||
<div class="col-12 d-flex align-items-center gap-3">
|
||
<button id="createWalletSubmit" class="btn btn-primary" type="submit">
|
||
<i class="fa-solid fa-circle-plus me-2" aria-hidden="true"></i>Create wallet
|
||
</button>
|
||
<span id="createWalletStatus" class="text-body-secondary" role="status">Prêt.</span>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-xl-4">
|
||
<div class="alert alert-info mb-0">
|
||
<i class="fa-solid fa-shield-halved me-2" aria-hidden="true"></i>
|
||
Les passwords sont envoyés uniquement du frontend vers Rust pour l'opération courante. Ils ne sont jamais renvoyés par Rust ni journalisés.
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Importer un keypair Solana vers un wallet KSP</div>
|
||
<div class="card-body">
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-md-5">
|
||
<label class="form-label" for="importTransferFormat">Format source</label>
|
||
<select id="importTransferFormat" class="form-select">
|
||
<option value="solana_cli_json">Solana CLI JSON</option>
|
||
<option value="solana_keypair_base58">Keypair Base58 complet</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-7 d-flex align-items-end">
|
||
<button id="inspectImportSource" class="btn btn-outline-primary" type="button">
|
||
<i class="fa-solid fa-folder-open me-2" aria-hidden="true"></i>Choisir et inspecter la source
|
||
</button>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="alert alert-secondary mb-0">
|
||
<div><strong>Source :</strong> <span id="importSourceName">—</span></div>
|
||
<div><strong>Format :</strong> <span id="importSourceFormat">—</span></div>
|
||
<div><strong>Pubkey inspectée :</strong> <span id="importSourcePubkey" class="text-break">—</span></div>
|
||
<div class="small text-body-secondary mt-2">Le chemin et le contenu secret restent exclusivement côté Rust. Le frontend ne reçoit que cette projection publique.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<form id="importWalletForm" autocomplete="off">
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="importWalletFilename">Destination .kspwallet</label>
|
||
<input id="importWalletFilename" class="form-control" type="text" value="imported-01.kspwallet" required spellcheck="false">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="importWalletAlias">Alias interne optionnel</label>
|
||
<input id="importWalletAlias" class="form-control" type="text" autocomplete="off">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="importWalletOwnerPassword">Nouveau OWNER password</label>
|
||
<input id="importWalletOwnerPassword" class="form-control" type="password" autocomplete="new-password" required>
|
||
</div>
|
||
<div class="col-md-6 d-flex align-items-end">
|
||
<div class="form-check mb-2">
|
||
<input id="importWalletEnableView" class="form-check-input" type="checkbox">
|
||
<label class="form-check-label" for="importWalletEnableView">Créer aussi une capability VIEW</label>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="importWalletViewPassword">Nouveau VIEW password</label>
|
||
<input id="importWalletViewPassword" class="form-control" type="password" autocomplete="new-password" disabled>
|
||
</div>
|
||
<div class="col-12">
|
||
<label class="form-label" for="importWalletInitialNote">Note initiale optionnelle</label>
|
||
<textarea id="importWalletInitialNote" class="form-control" rows="3" autocomplete="off"></textarea>
|
||
</div>
|
||
<div class="col-12 d-flex align-items-center gap-3">
|
||
<button id="importWalletSubmit" class="btn btn-primary" type="submit" disabled>
|
||
<i class="fa-solid fa-file-import me-2" aria-hidden="true"></i>Import wallet
|
||
</button>
|
||
<span id="importWalletStatus" class="text-body-secondary" role="status">Choisir une source.</span>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section data-view-panel="details" hidden>
|
||
<div class="card shadow-sm">
|
||
<div class="card-header d-flex align-items-center justify-content-between">
|
||
<span class="fw-semibold">Détails autorisés et balance réseau</span>
|
||
<button id="refreshWalletBalance" class="btn btn-outline-primary btn-sm" type="button" disabled>
|
||
<i class="fa-solid fa-coins me-2" aria-hidden="true"></i>Refresh balance
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<dl class="row mb-3">
|
||
<dt class="col-md-4">Pubkey</dt><dd id="detailsWalletPubkey" class="col-md-8 text-break">—</dd>
|
||
<dt class="col-md-4">Alias</dt><dd id="detailsWalletAlias" class="col-md-8 text-break">—</dd>
|
||
<dt class="col-md-4">Notes</dt><dd id="detailsWalletNotes" class="col-md-8 text-break">—</dd>
|
||
<dt class="col-md-4">Lamports</dt><dd id="detailsBalanceLamports" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">SOL</dt><dd id="detailsBalanceSol" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">RPC slot</dt><dd id="detailsBalanceSlot" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">RPC api_version</dt><dd id="detailsBalanceApiVersion" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">Transport</dt><dd id="detailsBalanceTransport" class="col-md-8">—</dd>
|
||
</dl>
|
||
<div id="balanceStatus" class="alert alert-secondary mb-0" role="status">Unlock VIEW ou OWNER pour interroger getBalance.</div>
|
||
</div>
|
||
</div>
|
||
<div class="card shadow-sm mt-3">
|
||
<div class="card-header fw-semibold">Administration metadata OWNER</div>
|
||
<div class="card-body">
|
||
<p class="text-body-secondary">Alias et notes sont protégés dans le wallet. Les contrôles restent désactivés tant qu’une session OWNER n’est pas ouverte.</p>
|
||
<div class="row g-3">
|
||
<div class="col-lg-6">
|
||
<label class="form-label" for="ownerWalletAlias">Alias interne</label>
|
||
<div class="input-group">
|
||
<input id="ownerWalletAlias" class="form-control" type="text" autocomplete="off" data-owner-metadata-control disabled>
|
||
<button id="saveOwnerAlias" class="btn btn-outline-primary" type="button" data-owner-metadata-control disabled>Save</button>
|
||
<button id="clearOwnerAlias" class="btn btn-outline-secondary" type="button" data-owner-metadata-control disabled>Clear</button>
|
||
</div>
|
||
<div class="form-text">Limite V1 : 256 octets UTF-8. La validation autoritative reste dans ksp-wallet-lib.</div>
|
||
</div>
|
||
<div class="col-lg-6">
|
||
<label class="form-label" for="ownerNewNote">Nouvelle note</label>
|
||
<div class="input-group">
|
||
<textarea id="ownerNewNote" class="form-control" rows="2" autocomplete="off" data-owner-metadata-control disabled></textarea>
|
||
<button id="addOwnerNote" class="btn btn-outline-primary" type="button" data-owner-metadata-control disabled>Add note</button>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<span class="fw-semibold">Notes autorisées</span>
|
||
<small class="text-body-secondary">64 notes maximum en V1</small>
|
||
</div>
|
||
<div id="ownerNotesList" class="vstack gap-2"><span class="text-body-secondary">Ouvrir OWNER pour administrer les notes.</span></div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div id="ownerMetadataStatus" class="alert alert-secondary mb-0" role="status">Session OWNER requise.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section data-view-panel="security" hidden>
|
||
<div class="row g-3">
|
||
<div class="col-xl-7">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Unlock manuel du wallet sélectionné</div>
|
||
<div class="card-body">
|
||
<p class="text-body-secondary">Chaque tentative Argon2 est explicite et peut prendre plusieurs secondes. Le password est envoyé uniquement frontend → Rust puis purgé.</p>
|
||
<div class="row g-3">
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="unlockWalletViewPassword">VIEW password</label>
|
||
<div class="input-group">
|
||
<input id="unlockWalletViewPassword" class="form-control" type="password" autocomplete="current-password">
|
||
<button id="unlockViewManual" class="btn btn-outline-primary" type="button" disabled>Unlock VIEW</button>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label class="form-label" for="unlockWalletOwnerPassword">OWNER password</label>
|
||
<div class="input-group">
|
||
<input id="unlockWalletOwnerPassword" class="form-control" type="password" autocomplete="current-password">
|
||
<button id="unlockOwnerManual" class="btn btn-outline-danger" type="button" disabled>Unlock OWNER</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-xl-5">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Secrets configurés</div>
|
||
<div class="card-body">
|
||
<p class="mb-2">Candidats effectifs : <strong id="unlockSecretCandidateCount">0</strong></p>
|
||
<p class="small text-body-secondary">Les noms, suffixes et valeurs des secrets Wallet configurés restent exclusivement côté Rust/Config. Cette action tente les candidats uniquement sur demande.</p>
|
||
<div class="d-grid gap-2">
|
||
<button id="unlockViewConfigured" class="btn btn-outline-primary" type="button" disabled>Unlock VIEW avec secret configuré</button>
|
||
<button id="unlockOwnerConfigured" class="btn btn-outline-danger" type="button" disabled>Unlock OWNER avec secret configuré</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="card shadow-sm">
|
||
<div class="card-header fw-semibold">Rotation credentials OWNER / VIEW</div>
|
||
<div class="card-body">
|
||
<p class="small text-body-secondary">OWNER peut administrer OWNER et VIEW sans ancien password VIEW. Une session VIEW peut self-rotate son propre password VIEW. Les rotations modifient le fichier Wallet sans changer automatiquement les secrets Config.</p>
|
||
<div class="row g-3">
|
||
<div class="col-lg-6">
|
||
<label class="form-label" for="rotateOwnerPassword">Nouveau OWNER password</label>
|
||
<input id="rotateOwnerPassword" class="form-control mb-2" type="password" autocomplete="new-password" data-owner-rotation-control disabled>
|
||
<label class="form-label" for="rotateOwnerPasswordConfirm">Confirmer OWNER password</label>
|
||
<div class="input-group">
|
||
<input id="rotateOwnerPasswordConfirm" class="form-control" type="password" autocomplete="new-password" data-owner-rotation-control disabled>
|
||
<button id="rotateOwnerPasswordSubmit" class="btn btn-outline-danger" type="button" data-owner-rotation-control disabled>Rotate OWNER</button>
|
||
</div>
|
||
</div>
|
||
<div class="col-lg-6">
|
||
<label class="form-label" for="rotateViewPassword">Nouveau VIEW password</label>
|
||
<input id="rotateViewPassword" class="form-control mb-2" type="password" autocomplete="new-password" data-view-rotation-control disabled>
|
||
<label class="form-label" for="rotateViewPasswordConfirm">Confirmer VIEW password</label>
|
||
<div class="input-group">
|
||
<input id="rotateViewPasswordConfirm" class="form-control" type="password" autocomplete="new-password" data-view-rotation-control disabled>
|
||
<button id="rotateViewPasswordSubmit" class="btn btn-outline-primary" type="button" data-view-rotation-control disabled>Rotate VIEW</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="rotationStatus" class="alert alert-secondary mt-3 mb-0" role="status">Session VIEW ou OWNER requise pour une rotation VIEW ; OWNER requis pour une rotation OWNER.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="card shadow-sm border-warning">
|
||
<div class="card-header fw-semibold">Administration forte VIEW — OWNER uniquement</div>
|
||
<div class="card-body">
|
||
<p class="small text-body-secondary">Ces opérations changent l’autorité VIEW courante, pas seulement son password. Disable retire VIEW et rekey les metadata ; Recreate génère une nouvelle metadata key, un nouveau slot VIEW et un nouveau password. La keypair Solana, l’OWNER, l’alias et les notes restent inchangés.</p>
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-lg-4">
|
||
<button id="disableWalletView" class="btn btn-outline-danger w-100" type="button" disabled>Strong disable VIEW</button>
|
||
</div>
|
||
<div class="col-lg-4">
|
||
<label class="form-label" for="recreateViewPassword">Nouveau VIEW password</label>
|
||
<input id="recreateViewPassword" class="form-control" type="password" autocomplete="new-password" data-view-security-recreate-control disabled>
|
||
</div>
|
||
<div class="col-lg-4">
|
||
<label class="form-label" for="recreateViewPasswordConfirm">Confirmer VIEW password</label>
|
||
<div class="input-group">
|
||
<input id="recreateViewPasswordConfirm" class="form-control" type="password" autocomplete="new-password" data-view-security-recreate-control disabled>
|
||
<button id="recreateWalletView" class="btn btn-outline-warning" type="button" data-view-security-recreate-control disabled>Strong recreate</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="viewSecurityStatus" class="alert alert-secondary mt-3 mb-0" role="status">Session OWNER requise pour administrer fortement VIEW.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div class="card shadow-sm border-danger-subtle">
|
||
<div class="card-header fw-semibold">Export keypair Solana — OWNER uniquement</div>
|
||
<div class="card-body">
|
||
<p class="small text-body-secondary">L’export produit un fichier secret non chiffré contenant la keypair Solana complète. Le contenu et le chemin complet restent exclusivement côté Rust ; le frontend choisit seulement le format puis confirme l’opération.</p>
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-lg-6">
|
||
<label class="form-label" for="walletExportFormat">Format d’export</label>
|
||
<select id="walletExportFormat" class="form-select" data-owner-export-control disabled>
|
||
<option value="solana_cli_json">Solana CLI JSON</option>
|
||
<option value="solana_keypair_base58">Keypair Base58 complet</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-lg-6 d-grid">
|
||
<button id="exportWalletKeypair" class="btn btn-outline-danger" type="button" data-owner-export-control disabled>Export secret keypair file</button>
|
||
</div>
|
||
</div>
|
||
<div id="walletExportStatus" class="alert alert-secondary mt-3 mb-0" role="status">Session OWNER requise. Aucun export texte ou clipboard n’est disponible.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-12">
|
||
<div id="unlockStatus" class="alert alert-secondary mb-0" role="status">Sélectionner un wallet verrouillé.</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section data-view-panel="diagnostics" hidden>
|
||
<div class="card shadow-sm"><div class="card-header fw-semibold">Diagnostics Transport sûrs</div><div class="card-body"><dl class="row mb-0">
|
||
<dt class="col-md-4">Profil</dt><dd id="diagnosticsTransportProfile" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">Clusters</dt><dd id="diagnosticsTransportClusters" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">Providers</dt><dd id="diagnosticsTransportProviders" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">Endpoints disponibles</dt><dd id="diagnosticsTransportEndpoints" class="col-md-8">—</dd>
|
||
<dt class="col-md-4">Rôle balance</dt><dd id="diagnosticsTransportRole" class="col-md-8">—</dd>
|
||
</dl></div></div>
|
||
</section>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</main>
|
||
<div class="modal fade" id="deleteWalletNoteModal" tabindex="-1" aria-labelledby="deleteWalletNoteModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 class="modal-title fs-5" id="deleteWalletNoteModalLabel">Supprimer la note protégée ?</h2>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">Cette mutation OWNER est définitive pour la note sélectionnée. Le contenu protégé n’est pas recopié dans la confirmation.</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||
<button id="confirmDeleteWalletNote" type="button" class="btn btn-danger">Delete note</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal fade" id="disableWalletViewModal" tabindex="-1" aria-labelledby="disableWalletViewModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 class="modal-title fs-5" id="disableWalletViewModalLabel">Strong disable VIEW ?</h2>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">Le slot VIEW courant sera supprimé et les metadata seront rekeyées. Le password VIEW actuel ne pourra plus ouvrir l’état courant. Les copies historiques du fichier restent hors de la garantie de révocation.</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||
<button id="confirmDisableWalletView" type="button" class="btn btn-danger">Disable VIEW</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal fade" id="recreateWalletViewModal" tabindex="-1" aria-labelledby="recreateWalletViewModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 class="modal-title fs-5" id="recreateWalletViewModalLabel">Strong recreate VIEW ?</h2>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">Une nouvelle metadata key et un nouveau slot VIEW seront créés. Tout credential VIEW courant sera remplacé. Le nouveau password n’est jamais recopié dans cette confirmation.</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||
<button id="confirmRecreateWalletView" type="button" class="btn btn-warning">Recreate VIEW</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal fade" id="exportWalletKeypairModal" tabindex="-1" aria-labelledby="exportWalletKeypairModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 class="modal-title fs-5" id="exportWalletKeypairModalLabel">Exporter la keypair Solana ?</h2>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">Cette opération OWNER crée un fichier secret non chiffré contenant les 64 octets de la keypair Solana. Le fichier doit être protégé comme une clé privée. Un fichier existant ne sera jamais écrasé par Wallet.</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||
<button id="confirmExportWalletKeypair" type="button" class="btn btn-danger">Choose destination and export</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<footer class="app-footer bg-dark text-white-50 d-flex align-items-center px-4">
|
||
<span>KSP Wallet Desk · integration / compliance pre.013</span>
|
||
</footer>
|
||
<script type="module" src="./ts/main.ts"></script>
|
||
</body>
|
||
</html>
|