theseus/bundled-addons/aegis/panel.html
Local Dev 992c02ea89 feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:

- Vault lifecycle from the wallet gate. The locked / not-yet-created states
  now show a master-password form (with optional BIP39 mnemonic on setup)
  instead of redirecting users to Settings › Passwords. New
  api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
  the existing "vault-derive" capability. api.openSettings(section) also
  added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
  path or a WIF; the cashaddr is derived in the add-on, the signer material
  goes to a separate wallet-imports.enc via api.vault.imports {list, add,
  remove, signer}. Argus password-vault gains createImports / unlockImports /
  saveImports with its own KDF salt so the imports key is disjoint from the
  passwords key. lib/chain-bch-imported.js is a single-address Electrum
  adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
  in add-on storage. Fiat lines under balances, in the wallet picker, and a
  portfolio total when 2+ wallets are open. Settings tab is now reachable
  while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
  @wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
  on the right side of LGPL §4d. Sign requests go through approvalModal and
  are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
  bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
  taking the whole add-on down.
2026-09-09 10:33:21 +02:00

420 lines
25 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Aegis Wallet</title>
<!-- Aegis brand mark from aegis.x/brand/favicon.svg — kept byte-close so
the sidebar-tab icon reads as the identity a user just downloaded from. -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A//www.w3.org/2000/svg'%20viewBox%3D'0%200%2032%2032'%20fill%3D'none'%3E%3Cpolygon%20points%3D'16%2C2%2028%2C9%2028%2C23%2016%2C30%204%2C23%204%2C9'%20fill%3D'%230a0a0d'%20stroke%3D'%23D6FF3D'%20stroke-width%3D'1.6'%20stroke-linejoin%3D'round'/%3E%3Ccircle%20cx%3D'16'%20cy%3D'16'%20r%3D'4.5'%20fill%3D'none'%20stroke%3D'%23D6FF3D'%20stroke-width%3D'1.4'/%3E%3Ccircle%20cx%3D'16'%20cy%3D'16'%20r%3D'1.6'%20fill%3D'%23D6FF3D'/%3E%3C/svg%3E">
<style>
:root { color-scheme: light dark;
--bg:#0e131c; --panel:#141a24; --card:#0f1621; --line:rgba(255,255,255,.09);
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d; --danger:#f6768a; --ok:#5ad38a;
--bch:#0ac18e; --trx:#ff060a; --trxNile:#4d9dff; }
@media (prefers-color-scheme: light) {
:root { --bg:#f8faff; --panel:#ffffff; --card:#f1f4fa; --line:rgba(0,0,0,.10);
--ink:#1a1f2b; --mut:#5c6577; --dim:#8a93a5;
/* Darker acid on light backgrounds — ~7:1 contrast on white. */
--acid: #0AC18E; }
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); color: var(--ink);
font: 13.5px/1.5 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
display: flex; flex-direction: column; }
header { padding: 10px 14px 10px; border-bottom: 1px solid var(--line); background: var(--panel); position: relative; }
.picker { display: flex; align-items: center; justify-content: space-between; gap: 8px; cursor: pointer; user-select: none; }
.picker .t { display: flex; align-items: center; gap: 7px; font-weight: 600; min-width: 0; }
.picker .t .badge { font-size: 15px; line-height: 1; }
.picker .t .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker .caret { color: var(--mut); font-size: 10px; }
.picker:hover { color: var(--acid); }
.net { display: flex; align-items: center; gap: 6px; color: var(--dim); font-size: 11.5px; white-space: nowrap; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dim); }
.dot.on { background: var(--ok); } .dot.busy { background: #e0b341; }
.bal { margin-top: 8px; font-variant-numeric: tabular-nums; }
.bal .big { font-size: 22px; font-weight: 650; letter-spacing: .2px; }
.bal .big small { font-size: 13px; color: var(--mut); font-weight: 500; margin-left: 4px; }
.bal .sub { color: var(--dim); font-size: 11.5px; display: flex; justify-content: space-between; gap: 8px; }
.bal .sub .netlbl { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#drop { position: absolute; left: 10px; right: 10px; top: 100%; background: var(--panel); border: 1px solid var(--line);
border-radius: 10px; box-shadow: 0 8px 26px rgba(0,0,0,.3); z-index: 20; padding: 4px; margin-top: 4px; max-height: 60vh; overflow-y: auto; }
#drop[hidden] { display: none; }
#drop .row, #drop .coinrow { display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 7px; cursor: pointer; }
#drop .row:hover, #drop .coinrow:hover { background: rgba(255,255,255,.05); }
#drop .row .m, #drop .coinrow .m { flex: 1; min-width: 0; }
#drop .row .m .l, #drop .coinrow .m .l { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#drop .row .m .s, #drop .coinrow .m .s { color: var(--dim); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#drop .row .v { color: var(--mut); font-size: 12px; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
#drop .row .v .fs { color: var(--dim); font-size: 11px; margin-top: 2px; }
#drop .row.on { background: rgb(from var(--acid) r g b / .10); }
#drop .coinrow .caret { color: var(--dim); font-size: 11px; }
#drop hr { border: 0; border-top: 1px solid var(--line); margin: 6px 0; }
#drop .addhdr { padding: 5px 8px 3px; color: var(--dim); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
#drop .netgroup { padding: 2px 4px 6px 40px; }
#drop .netgroup[hidden] { display: none; }
#drop .netchoice { padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 12.5px; color: var(--mut); }
#drop .netchoice:hover { background: rgba(255,255,255,.06); color: var(--ink); }
.ttag { display: inline-block; font-size: 9.5px; letter-spacing: .06em; padding: 1px 5px; border-radius: 3px;
background: rgba(224,179,65,.18); color: #e0b341; font-weight: 700; vertical-align: middle; margin-left: 2px; }
#hNet { color: var(--dim); font-size: 11px; margin-left: 4px; font-weight: 500; }
.fiat { color: var(--dim); font-size: 12.5px; margin-left: 10px; font-weight: 500; letter-spacing: .2px; }
.portfolio { margin-top: 6px; color: var(--mut); font-size: 11.5px; }
.portfolio b { color: var(--ink); font-weight: 600; }
.portfolio[hidden] { display: none; }
.picker-actions { display: flex; align-items: center; gap: 6px; }
.chip { background: transparent; border: 1px solid var(--line); color: var(--mut); border-radius: 6px;
padding: 0 8px; height: 22px; cursor: pointer; font: inherit; font-size: 13.5px; line-height: 1;
display: inline-flex; align-items: center; justify-content: center; }
.chip:hover { border-color: var(--acid); color: var(--acid); }
nav { display: flex; border-bottom: 1px solid var(--line); background: var(--panel); }
nav button { flex: 1; padding: 9px 0 8px; border: 0; background: transparent; color: var(--mut); cursor: pointer;
font: inherit; font-size: 12.5px; border-bottom: 2px solid transparent; }
nav button.on { color: var(--acid); border-bottom-color: var(--acid); }
nav button:hover { color: var(--ink); }
main { flex: 1; overflow: auto; padding: 14px; }
section[hidden] { display: none; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 12px; }
.mono { font: 12.5px/1.45 ui-monospace, "Cascadia Code", Consolas, monospace; word-break: break-all; }
.lbl { color: var(--dim); font-size: 11.5px; margin-bottom: 4px; }
.btn { padding: 7px 12px; border-radius: 7px; border: 1px solid var(--line); background: var(--panel); color: var(--ink);
cursor: pointer; font: inherit; font-size: 12.5px; }
.btn:hover { border-color: rgb(from var(--acid) r g b / .4); }
.btn.primary { background: var(--acid); color: #0b0e14; border-color: transparent; font-weight: 650; }
.btn.primary:disabled { opacity: .45; cursor: default; }
.btn.danger { color: var(--danger); }
.btn.sm { padding: 4px 9px; font-size: 12px; }
.actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.qrwrap { display: grid; place-items: center; padding: 12px; background: #fff; border-radius: 10px; margin-bottom: 12px; }
canvas { image-rendering: pixelated; }
input[type=text], input[type=number], input[type=password], textarea { width: 100%; padding: 7px 9px; border-radius: 7px; background: var(--panel);
border: 1px solid var(--line); color: var(--ink); font: inherit; font-size: 13px; outline: none; }
input:focus, textarea:focus { border-color: rgb(from var(--acid) r g b / .5); }
textarea { resize: vertical; min-height: 96px; font: 12px/1.45 ui-monospace, Consolas, monospace; }
.field { margin-bottom: 12px; }
.hint { color: var(--dim); font-size: 11.5px; margin-top: 4px; }
.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 12.5px; color: var(--ink); }
.switch input { accent-color: var(--brand, #d6ff3d); width: 15px; height: 15px; margin: 0; }
.amt { display: flex; gap: 6px; }
.amt input { flex: 1; }
.unit { display: flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
.unit button { border: 0; background: var(--panel); color: var(--mut); padding: 0 10px; cursor: pointer; font: inherit; font-size: 12px; }
.unit button.on { background: rgb(from var(--acid) r g b / .14); color: var(--acid); }
.fee { display: flex; align-items: center; gap: 10px; }
.fee input[type=range] { flex: 1; accent-color: var(--acid); }
.fee .v { color: var(--mut); font-size: 12px; min-width: 70px; text-align: right; font-variant-numeric: tabular-nums; }
.summary { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; font-size: 12.5px; margin-top: 10px; }
.summary .k { color: var(--dim); } .summary .v { text-align: right; font-variant-numeric: tabular-nums; }
.msg { margin-top: 10px; font-size: 12.5px; padding: 8px 10px; border-radius: 7px; }
.msg.err { background: rgba(246,118,138,.12); color: var(--danger); }
.msg.ok { background: rgba(90,211,138,.12); color: var(--ok); }
.msg a { color: inherit; }
.tx { display: grid; grid-template-columns: 22px 1fr auto; gap: 2px 10px; padding: 9px 4px; border-bottom: 1px solid var(--line); cursor: pointer; }
.tx:hover { background: rgba(255,255,255,.03); }
.tx .ic { font-size: 15px; line-height: 1.3; }
.tx .ic.in { color: var(--ok); } .tx .ic.out { color: var(--danger); }
.tx .what { font-size: 12.5px; }
.tx .when { color: var(--dim); font-size: 11.5px; grid-column: 2; }
.tx .amt2 { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12.5px; }
.tx .amt2.in { color: var(--ok); }
.tx .conf { grid-column: 3; text-align: right; color: var(--dim); font-size: 11px; }
.tx .conf.pending { color: #e0b341; }
.empty { color: var(--dim); text-align: center; padding: 30px 10px; font-size: 12.5px; }
.gate { padding: 40px 18px; text-align: center; color: var(--mut); }
.gate .big { font-size: 28px; margin-bottom: 8px; }
.gate b { color: var(--ink); }
.kv { margin-top: 10px; }
.kv .lbl { margin-top: 8px; }
a.link { color: var(--acid); text-decoration: none; cursor: pointer; }
</style>
</head>
<body>
<header>
<div class="picker" id="pickerBtn">
<div class="t">
<span class="badge" id="hBadge"></span>
<span class="lbl" id="hLabel">Aegis Wallet</span>
<span id="hNet"></span>
</div>
<div class="picker-actions">
<button type="button" id="hAddWallet" class="chip" title="Add a new wallet"></button>
<span class="caret"></span>
</div>
</div>
<div id="drop" hidden></div>
<div class="bal">
<div class="big">
<span id="balMain"></span><small id="balTicker"></small>
<span id="balFiat" class="fiat" hidden></span>
</div>
<div class="sub">
<span class="netlbl" id="netlbl">connecting…</span>
<span class="net"><span class="dot" id="dot"></span></span>
</div>
<div id="portfolio" class="portfolio" hidden></div>
</div>
</header>
<nav>
<button data-tab="receive" class="on">Receive</button>
<button data-tab="send">Send</button>
<button data-tab="history">History</button>
<button data-tab="settings">Settings</button>
</nav>
<main>
<div id="gate" class="gate" hidden></div>
<div id="tabs">
<section id="tab-receive">
<div class="qrwrap"><canvas id="qr" width="200" height="200"></canvas></div>
<div class="card">
<div class="lbl">Receiving address <span id="addrMeta"></span></div>
<div class="mono" id="addr"></div>
<div class="actions">
<button class="btn sm" id="copyAddr">Copy</button>
<button class="btn sm" id="nextAddr" hidden>Next unused address</button>
<button class="btn sm" id="viewAddr">Explorer</button>
<button class="btn sm" id="openFaucet" hidden>Faucet</button>
</div>
</div>
<div class="card" id="tokensCard" hidden style="margin-top:12px">
<div class="lbl">Tokens</div>
<div id="tokensList" class="kv"></div>
<div class="hint">SPL tokens held by this wallet. Send by picking one under the Send tab's Asset dropdown.</div>
</div>
</section>
<section id="tab-send" hidden>
<div class="field" id="sendAssetField" hidden>
<div class="lbl">Asset</div>
<select id="sendAsset"></select>
<div class="hint">Pick the native coin or an SPL token in this wallet.</div>
</div>
<div class="field">
<div class="lbl">Recipient</div>
<input type="text" id="sendTo" spellcheck="false" autocomplete="off" placeholder="…">
<div class="hint" id="sendToHint"></div>
</div>
<div class="field">
<div class="lbl">Amount</div>
<div class="amt">
<input type="text" id="sendAmt" inputmode="decimal" autocomplete="off" placeholder="0.00">
<div class="unit" id="unitPicker"></div>
<button class="btn sm" id="sendMax" type="button">Max</button>
</div>
</div>
<div class="field" id="feeField">
<div class="lbl">Fee</div>
<div class="fee"><input type="range" id="feeRate" min="1" max="5" step="1" value="1"><span class="v" id="feeLbl">1 sat/B</span></div>
</div>
<div class="card">
<div class="summary">
<div class="k">Amount</div><div class="v" id="sumAmt"></div>
<div class="k">Network fee</div><div class="v" id="sumFee"></div>
<div class="k">Total</div><div class="v" id="sumTotal"></div>
</div>
</div>
<div class="actions"><button class="btn primary" id="sendBtn" disabled>Send</button></div>
<div class="msg" id="sendMsg" hidden></div>
</section>
<section id="tab-history" hidden>
<div id="txlist"></div>
</section>
<section id="tab-settings" hidden>
<div class="card" id="walletManage" style="margin-bottom:14px">
<div class="lbl">This wallet</div>
<div class="field" style="margin-top:6px;margin-bottom:8px">
<input type="text" id="renameLabel" placeholder="Wallet name">
</div>
<div class="actions">
<button class="btn sm" id="renameBtn">Rename</button>
<button class="btn sm danger" id="removeBtn">Remove wallet</button>
</div>
<div class="hint" id="removeHint"></div>
</div>
<div id="bchSettings" hidden>
<div class="field">
<div class="lbl">Derivation path (account)</div>
<input type="text" id="setPath" spellcheck="false" placeholder="m/44'/145'/0'">
<div class="hint">Changing this switches to a different set of addresses under the same wallet seed.</div>
</div>
<div class="field" id="bchServersRow">
<div class="lbl">Electrum servers (shared across BCH mainnet wallets, one per line)</div>
<textarea id="setServers" spellcheck="false"></textarea>
<div class="hint" id="serverHint"></div>
</div>
<div class="actions">
<button class="btn primary" id="applySettings">Apply</button>
<button class="btn" id="resetServers">Reset servers</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="purpose"></span>. The same vault seed on another machine recreates this wallet.</div>
<div class="kv" id="recovery"></div>
<div class="actions">
<button class="btn" id="showXpub">Show account xpub</button>
<button class="btn danger" id="showXprv">Show account private key</button>
</div>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">WizardConnect</div>
<div class="hint" style="margin-bottom:8px">
Pair this BCH wallet with a dapp that speaks the WizardConnect protocol
(Cauldron, Moria, or any site built on the SDK). Paste the <span class="mono">wiz://</span>
URI the dapp shows in its Connect dialog. Aegis signs every transaction only after you approve it.
</div>
<div class="field" style="margin-top:8px">
<input type="text" id="wcUri" spellcheck="false" placeholder="wiz://?p=…&amp;s=…">
</div>
<div class="actions">
<button class="btn primary" id="wcConnectBtn">Connect</button>
</div>
<div class="msg" id="wcMsg" hidden></div>
<div class="kv" id="wcSites" style="margin-top:8px"></div>
</div>
</div>
<div id="trxSettings" hidden>
<div class="card">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="trxPurpose"></span>. Import into TronLink with the derivation path <span class="mono">m/44'/195'/0'/0/0</span> from the same vault seed.</div>
</div>
</div>
<div id="scSettings" hidden>
<div class="field">
<div class="lbl">walletd URL</div>
<input type="text" id="setWalletdUrl" spellcheck="false" placeholder="https://your-walletd.example/api">
<div class="hint">Any public or self-hosted <span class="mono">go.sia.tech/walletd</span> in "full" index mode. The URL is per-wallet, so different Sia sub-accounts can point at different nodes. It is not shared with anyone else.</div>
</div>
<div class="actions">
<button class="btn primary" id="applyWalletdUrl">Apply</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="scPurpose"></span>. Address scheme: walletd <span class="mono">KeyFromSeed(seed, index)</span>.</div>
<div class="kv" id="scRecovery"></div>
<div class="actions">
<button class="btn danger" id="showScSeed">Reveal wallet seed</button>
</div>
</div>
</div>
<div id="dgbSettings" hidden>
<div class="field">
<div class="lbl">Address family</div>
<select id="setDgbFamily"></select>
<div class="hint">Picks the BIP purpose that shapes your DGB addresses. Switching rebuilds the wallet against a different set of addresses under the same seed — old funds don't move; they still live under the family they were received on.</div>
</div>
<div class="field">
<div class="lbl">Derivation path (account)</div>
<input type="text" id="setDgbPath" spellcheck="false" placeholder="m/84'/20'/0'">
<div class="hint">Auto-filled from the family above. Edit only if you need a non-default account.</div>
</div>
<div class="actions">
<button class="btn primary" id="applyDgbPath">Apply</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="dgbPurpose"></span>. Any BIP39 tool set to <span class="mono">DGB</span> (coin type 20) at the same purpose can reproduce this wallet.</div>
<div class="kv" id="dgbRecovery"></div>
<div class="actions">
<button class="btn" id="showDgbXpub">Show account xpub</button>
<button class="btn danger" id="showDgbXprv">Show account private key</button>
</div>
</div>
</div>
<div id="btcSettings" hidden>
<div class="field">
<div class="lbl">Address family</div>
<select id="setBtcFamily"></select>
<div class="hint">Picks the BIP purpose that shapes your Bitcoin addresses. Switching rebuilds the wallet against a different set of addresses under the same seed — old funds don't move; they still live under the family they were received on.</div>
</div>
<div class="field">
<div class="lbl">Derivation path (account)</div>
<input type="text" id="setBtcPath" spellcheck="false" placeholder="m/84'/0'/0'">
<div class="hint">Auto-filled from the family above. Edit only if you need a non-default account.</div>
</div>
<div class="actions">
<button class="btn primary" id="applyBtcPath">Apply</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="btcPurpose"></span>. Any BIP39 tool at coin type 0 (mainnet) / 1 (testnet) and the same purpose can reproduce this wallet.</div>
<div class="kv" id="btcRecovery"></div>
<div class="actions">
<button class="btn" id="showBtcXpub">Show account xpub</button>
<button class="btn danger" id="showBtcXprv">Show account private key</button>
</div>
</div>
</div>
<div id="ethSettings" hidden>
<div class="field">
<div class="lbl">RPC URL</div>
<input type="text" id="setEthRpcUrl" spellcheck="false" placeholder="https://cloudflare-eth.com">
<div class="hint">JSON-RPC endpoint Aegis reads balances and broadcasts from. Any provider works — public gateways (Cloudflare, PublicNode), Alchemy, Infura, or your own node. Stored per-wallet; not shared.</div>
</div>
<div class="actions">
<button class="btn primary" id="applyEthRpc">Apply</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="ethPurpose"></span>. Import into MetaMask / any Ethereum wallet using the derivation path <span class="mono">m/44'/60'/0'/0/0</span> from the same vault seed.</div>
<div class="kv" id="ethRecovery"></div>
<div class="actions">
<button class="btn danger" id="showEthKey">Reveal private key</button>
</div>
</div>
</div>
<div id="solSettings" hidden>
<div class="field">
<div class="lbl">RPC URL</div>
<input type="text" id="setSolRpcUrl" spellcheck="false" placeholder="https://api.mainnet-beta.solana.com">
<div class="hint">JSON-RPC endpoint. The public Solana RPCs are heavily rate-limited — for real use point Aegis at Helius / QuickNode / your own node.</div>
</div>
<div class="actions">
<button class="btn primary" id="applySolRpc">Apply</button>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Recovery info</div>
<div class="hint">Keys come from your Theseus password vault under <span class="mono" id="solPurpose"></span>. Import into Phantom / Solflare with the derivation path <span class="mono">m/44'/501'/0'/0'</span> from the same vault seed.</div>
<div class="kv" id="solRecovery"></div>
<div class="actions">
<button class="btn danger" id="showSolKey">Reveal wallet seed</button>
</div>
</div>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Fiat prices</div>
<div class="hint" style="margin-bottom:10px">
Off by default. When enabled, Aegis fetches USD prices for the seven supported coins from
<span class="mono">api.coingecko.com</span> every 5 minutes while the panel is open.
One HTTP request per interval, no keys and no address data — but CoinGecko can see your IP,
which is a signal that a wallet is open on this machine.
</div>
<div class="actions" style="align-items:center;gap:12px">
<label class="switch">
<input type="checkbox" id="pricesToggle">
<span>Enable USD prices</span>
</label>
<button class="btn sm" id="refreshPrices" hidden>Refresh now</button>
<span class="hint" id="pricesStatus" style="margin-left:auto"></span>
</div>
</div>
<div class="card" style="margin-top:16px">
<div class="lbl">Connected sites</div>
<div class="hint">Sites allowed to see your address, allowances for silent BCH payments, and Tron dapps you've connected. Message signing always asks.</div>
<div id="sites" class="kv"></div>
</div>
<div class="msg err" id="settingsMsg" hidden></div>
</section>
</div>
</main>
<script src="qr.js"></script>
<script src="panel.js"></script>
</body>
</html>