Files
AutistMask/src/popup/index.html
sneak f2e22cadf2
All checks were successful
check / check (push) Successful in 14s
Encrypt secrets with libsodium, password required to send
vault.js: Argon2id key derivation + XSalsa20-Poly1305 encryption
via libsodium-wrappers-sumo. No raw crypto primitives.

Wallet creation now requires a password. The mnemonic or private
key is encrypted before storage — only the ciphertext blob
(salt, nonce, ciphertext) is persisted. The plaintext secret
is never stored.

Sending requires the password to decrypt the secret, derive
the signing key, and construct the transaction. Wrong password
is caught and reported.
2026-02-25 18:23:09 +07:00

478 lines
20 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AutistMask</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body class="bg-bg text-fg font-mono text-sm">
<div id="app" class="p-2">
<!-- ============ WELCOME / FIRST USE ============ -->
<div id="view-welcome" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Welcome to AutistMask
</h1>
<p class="mb-3">To get started, add a wallet.</p>
<button
id="btn-welcome-add"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Add wallet
</button>
</div>
<!-- ============ ADD WALLET (unified create/import) ============ -->
<div id="view-add-wallet" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Add Wallet
</h1>
<p class="mb-2">
Enter your 12 or 24 word recovery phrase below, or click the
button to roll the die for a new one.
</p>
<div class="mb-1 flex justify-end">
<button
id="btn-generate-phrase"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer text-xs"
title="Generate a random recovery phrase"
>
[&#9856;]
</button>
</div>
<div class="mb-2">
<textarea
id="wallet-mnemonic"
rows="3"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg resize-y"
placeholder="word word word ..."
></textarea>
</div>
<div
id="add-wallet-phrase-warning"
class="text-xs mb-2 border border-border border-dashed p-2 hidden"
>
These words are your recovery phrase. Write them down on
paper and keep them somewhere safe. Anyone with these words
can access your funds. If you lose them, your wallet cannot
be recovered.
</div>
<div class="mb-2" id="add-wallet-password-section">
<label class="block mb-1">Choose a password</label>
<p class="text-xs text-muted mb-1">
This password encrypts your recovery phrase on this
device. You will need it to send funds.
</p>
<input
type="password"
id="add-wallet-password"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
</div>
<div class="mb-2" id="add-wallet-password-confirm-section">
<label class="block mb-1">Confirm password</label>
<input
type="password"
id="add-wallet-password-confirm"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
</div>
<div class="flex gap-2">
<button
id="btn-add-wallet-confirm"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Add
</button>
<button
id="btn-add-wallet-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Back
</button>
</div>
<div
id="add-wallet-error"
class="mt-2 border border-border border-dashed p-1 hidden"
></div>
<div class="mt-3 text-xs text-muted">
Have a private key instead?
<button
id="btn-add-wallet-import-key"
class="underline cursor-pointer bg-transparent border-none text-fg text-xs font-mono p-0"
>
Import private key
</button>
</div>
</div>
<!-- ============ IMPORT PRIVATE KEY ============ -->
<div id="view-import-key" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Import Private Key
</h1>
<p class="mb-2">
Paste your private key below. This wallet will have a single
address.
</p>
<div class="mb-2">
<input
type="password"
id="import-private-key"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
placeholder="0x..."
/>
</div>
<div class="mb-2" id="import-key-password-section">
<label class="block mb-1">Choose a password</label>
<p class="text-xs text-muted mb-1">
This password encrypts your private key on this device.
You will need it to send funds.
</p>
<input
type="password"
id="import-key-password"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
</div>
<div class="mb-2" id="import-key-password-confirm-section">
<label class="block mb-1">Confirm password</label>
<input
type="password"
id="import-key-password-confirm"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
</div>
<div class="flex gap-2">
<button
id="btn-import-key-confirm"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Import
</button>
<button
id="btn-import-key-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Back
</button>
</div>
<div
id="import-key-error"
class="mt-2 border border-border border-dashed p-1 hidden"
></div>
</div>
<!-- ============ MAIN VIEW: ALL WALLETS & ADDRESSES ============ -->
<div id="view-main" class="view hidden">
<div
class="flex justify-between items-center border-b border-border pb-1 mb-2"
>
<h1 class="font-bold">AutistMask</h1>
<button
id="btn-settings"
class="border border-border px-1 hover:bg-fg hover:text-bg cursor-pointer"
title="Settings"
>
Settings
</button>
</div>
<!-- wallet list -->
<div id="wallet-list"></div>
<!-- add wallet button -->
<div class="mt-3 border-t border-border pt-2">
<button
id="btn-main-add-wallet"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
+ Add wallet
</button>
</div>
</div>
<!-- ============ ADDRESS DETAIL VIEW ============ -->
<div id="view-address" class="view hidden">
<div
class="flex justify-between items-center border-b border-border pb-1 mb-2"
>
<h1 class="font-bold" id="address-title">Address</h1>
<button
id="btn-address-back"
class="border border-border px-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Back
</button>
</div>
<div id="address-ens" class="font-bold mb-1 hidden"></div>
<div
id="address-full"
class="text-xs break-all mb-1 cursor-pointer"
title="Click to copy"
></div>
<div
class="text-xs text-muted mb-3"
id="address-copied-msg"
></div>
<!-- balance -->
<div class="border-b border-border-light pb-2 mb-2">
<div class="text-base font-bold">
<span id="address-eth-balance">0.0000</span> ETH
</div>
<div
class="text-xs text-muted"
id="address-usd-value"
></div>
</div>
<!-- actions -->
<div class="flex gap-2 mb-3">
<button
id="btn-send"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer flex-1"
>
Send
</button>
<button
id="btn-receive"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer flex-1"
>
Receive
</button>
</div>
<!-- tokens -->
<div>
<div
class="flex justify-between items-center border-b border-border pb-1 mb-1"
>
<h2 class="font-bold">Tokens</h2>
<button
id="btn-add-token"
class="border border-border px-1 hover:bg-fg hover:text-bg cursor-pointer text-xs"
>
+ Add
</button>
</div>
<div id="token-list">
<div class="text-muted text-xs py-1">
No tokens added yet. Use "+ Add" to track a token.
</div>
</div>
</div>
</div>
<!-- ============ SEND ============ -->
<div id="view-send" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">Send</h1>
<div class="mb-2">
<label class="block mb-1">What to send</label>
<select
id="send-token"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
>
<option value="ETH">ETH</option>
</select>
</div>
<div class="mb-2">
<label class="block mb-1">To</label>
<input
type="text"
id="send-to"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
placeholder="Address (0x...) or ENS name"
/>
</div>
<div class="mb-2">
<label class="block mb-1">Amount</label>
<input
type="text"
id="send-amount"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
placeholder="0.0"
/>
</div>
<div
id="send-fee-estimate"
class="text-xs text-muted mb-2 hidden"
></div>
<div class="mb-2">
<label class="block mb-1">Password</label>
<p class="text-xs text-muted mb-1">
Required to authorize the transaction.
</p>
<input
type="password"
id="send-password"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
</div>
<div class="flex gap-2">
<button
id="btn-send-confirm"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Send
</button>
<button
id="btn-send-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Cancel
</button>
</div>
<div
id="send-status"
class="mt-2 border border-border p-1 hidden"
></div>
</div>
<!-- ============ RECEIVE ============ -->
<div id="view-receive" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Receive
</h1>
<p class="mb-2">
Share this address with the sender. Make sure you only use
this address to receive Ethereum tokens.
</p>
<div class="flex justify-center mb-3">
<canvas id="receive-qr"></canvas>
</div>
<div
id="receive-address"
class="border border-border p-2 break-all select-all mb-3"
></div>
<div class="flex gap-2">
<button
id="btn-receive-copy"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Copy address
</button>
<button
id="btn-receive-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Back
</button>
</div>
</div>
<!-- ============ ADD TOKEN ============ -->
<div id="view-add-token" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Add Token
</h1>
<p class="mb-2">
Enter the contract address of the token you want to track.
You can find this on the token's page on Etherscan.
</p>
<div class="mb-2">
<label class="block mb-1">Contract address</label>
<input
type="text"
id="add-token-address"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
placeholder="0x..."
/>
</div>
<div
id="add-token-info"
class="text-xs text-muted mb-2 hidden"
></div>
<div class="flex gap-2">
<button
id="btn-add-token-confirm"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Add
</button>
<button
id="btn-add-token-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Cancel
</button>
</div>
<div
id="add-token-error"
class="mt-2 border border-border border-dashed p-1 hidden"
></div>
</div>
<!-- ============ SETTINGS ============ -->
<div id="view-settings" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
Settings
</h1>
<h2 class="font-bold mb-1">Network</h2>
<p class="text-xs text-muted mb-1">
The server used to talk to the Ethereum network. Change this
if you run your own node or prefer a different provider.
</p>
<div class="mb-3">
<input
type="text"
id="settings-rpc"
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
/>
<button
id="btn-save-rpc"
class="border border-border px-2 py-1 mt-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Save
</button>
</div>
<div class="border-t border-border pt-2">
<button
id="btn-settings-back"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Back
</button>
</div>
</div>
<!-- ============ APPROVAL ============ -->
<div id="view-approve" class="view hidden">
<h1 class="font-bold border-b border-border pb-1 mb-3">
A website is requesting access
</h1>
<div class="mb-2">
<div class="text-xs text-muted mb-1">
From:
<span id="approve-origin" class="font-bold"></span>
</div>
<div class="font-bold mb-1" id="approve-type"></div>
</div>
<pre
id="approve-details"
class="border border-border p-2 text-xs overflow-auto mb-3 max-h-64"
></pre>
<div class="flex gap-2">
<button
id="btn-approve"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Allow
</button>
<button
id="btn-reject"
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
>
Deny
</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>