Rewrite TODO as 0.1.0 MVP checklist, add screen map
All checks were successful
check / check (push) Successful in 5s

Full screen map with iOS-style stack navigation: Welcome, Home,
AddWallet, ImportKey, AddressDetail, Send, Receive, AddToken,
Settings, Approval. Each screen documents its elements and
transitions. TODO reorganized into Done, Wallet Management,
Sending, Receiving, Display, Tokens, Testing, and Post-MVP.
External Services updated to include CoinDesk price API.
This commit is contained in:
2026-02-25 18:04:28 +07:00
parent 097f90d7f8
commit fc3f0e00c8

275
README.md
View File

@@ -147,34 +147,151 @@ send/receive). Navigation is flat — every view has a "Back" or "Cancel" button
that returns to the previous context. No deep nesting, no tabs, no hamburger that returns to the previous context. No deep nesting, no tabs, no hamburger
menus. menus.
### UI Views ### Screen Map
The popup has the following views, switched via simple show/hide: Navigation uses a stack model (like iOS): each action pushes a screen onto the
stack, and "Back" pops it. The root screen is either Welcome (no wallets) or
Home (has wallets). Screens are listed below with their elements and
transitions.
1. **Welcome**: Shown on first use. Single "Add wallet" button. #### Welcome
2. **Add wallet**: A unified view for both creating and importing recovery
phrase wallets. The recovery phrase text area starts empty. A clickable die - **When**: No wallets exist yet.
button `[die]` generates a random 12-word phrase and fills it in. If the user - **Elements**: "AutistMask" heading, brief intro text, "Add wallet" button.
already has a phrase, they paste it directly. When the die is clicked, a - **Transitions**:
warning box appears reminding the user to write the phrase down. No password - "Add wallet" → pushes **AddWallet**
required — the xpub is derived and stored for read-only access.
3. **Import private key**: Paste a private key. This creates a wallet with a #### Home
single address.
4. **Main**: All wallets listed, each showing its addresses (full, untruncated) - **When**: At least one wallet exists. This is the root screen.
and ETH balance. "+" next to recovery phrase wallets to add another address. - **Elements**:
"+ Add wallet" at the bottom. Settings button in the header. Future: a - Header: "AutistMask", Settings button
sub-heading showing total portfolio value in USD (and eventually other - Total ETH balance across all addresses (large text)
currencies). - Total USD value (small text below ETH total, cached 5 min)
5. **Address detail**: Full address (click to copy), ETH balance, USD value - List of wallets, each showing:
(future), Send/Receive buttons, token list with "+ Add" button. - Wallet name (editable — tap to rename)
6. **Send**: Token selector, recipient address, amount. Cancel returns to - "+" button (HD wallets only) to derive next address
address detail. - List of addresses under that wallet:
7. **Receive**: Full address displayed with "Copy address" button. - Address name (editable — tap to rename, default "Address N")
8. **Add token**: Enter contract address. The extension looks up the token - Full address (untruncated)
name/symbol automatically. - ETH balance + USD value (small text)
9. **Settings**: Network (RPC endpoint URL) with explanatory text. - "+ Add wallet" button at the bottom
10. **Approval**: When a website requests wallet access or a signature, shows - **Transitions**:
the site origin, request details, and Allow/Deny buttons. - Tap address → pushes **AddressDetail**
- "+" on wallet → derives address inline (no screen change)
- "+ Add wallet" → pushes **AddWallet**
- Settings → pushes **Settings**
#### AddWallet
- **When**: User wants to add a new wallet (from Home or Welcome).
- **Elements**:
- "Add Wallet" heading
- Instruction text
- Die button `[die]` (generates random recovery phrase, can be clicked
repeatedly)
- Recovery phrase textarea (empty by default, or filled by die)
- Backup warning box (shown after die is clicked)
- "Add" button, "Back" button
- "Have a private key instead?" link → pushes **ImportKey**
- **Transitions**:
- "Add" (valid phrase) → pops to **Home**
- "Back" → pops to previous (Home or Welcome)
- "Have a private key instead?" → pushes **ImportKey**
#### ImportKey
- **When**: User wants to import a single private key.
- **Elements**:
- "Import Private Key" heading
- Instruction text
- Private key input (password-masked)
- "Import" button, "Back" button
- **Transitions**:
- "Import" (valid key) → pops to **Home**
- "Back" → pops to previous
#### AddressDetail
- **When**: User tapped an address from Home.
- **Elements**:
- Header: wallet name, "Back" button
- Address name (editable — tap to rename)
- ENS name (if resolved, shown above address)
- Full address (tap to copy, "Copied!" feedback)
- ETH balance (large) + USD value (small)
- "Send" button, "Receive" button
- Token list with balances
- "+ Add" token button
- **Transitions**:
- "Send" → pushes **Send**
- "Receive" → pushes **Receive**
- "+ Add" → pushes **AddToken**
- "Back" → pops to **Home**
#### Send
- **When**: User wants to send ETH or a token from this address.
- **Elements**:
- "Send" heading
- Token selector (ETH + any added tokens)
- "To" input (accepts address or ENS name, resolves before sending)
- Amount input
- Fee estimate (shown after entering amount)
- "Send" button, "Cancel" button
- Status area (resolving ENS, confirming, errors)
- **Transitions**:
- "Send" (valid) → prompts for password (to decrypt private key), submits
transaction, shows result, stays on screen
- "Cancel" → pops to **AddressDetail**
#### Receive
- **When**: User wants to receive funds at this address.
- **Elements**:
- "Receive" heading
- Instruction text
- QR code encoding the address
- Full address (displayed, selectable)
- "Copy address" button
- "Back" button
- **Transitions**:
- "Back" → pops to **AddressDetail**
#### AddToken
- **When**: User wants to track an ERC-20 token on this address.
- **Elements**:
- "Add Token" heading
- Instruction text (find contract address on Etherscan)
- Contract address input
- Token info preview (name, symbol — fetched from contract)
- "Add" button, "Cancel" button
- **Transitions**:
- "Add" (valid contract) → pops to **AddressDetail**
- "Cancel" → pops to **AddressDetail**
#### Settings
- **When**: User tapped Settings from Home.
- **Elements**:
- "Settings" heading
- Network section: RPC endpoint URL input, "Save" button, explanatory text
- "Back" button
- **Transitions**:
- "Back" → pops to **Home**
#### Approval (future)
- **When**: A connected website requests wallet access or a transaction
signature. Opened by the background script, not by user navigation.
- **Elements**:
- "A website is requesting access" heading
- Site origin (bold)
- Request type and details (preformatted)
- "Allow" button, "Deny" button
- **Transitions**:
- "Allow" / "Deny" → closes popup (returns result to background script)
### External Services ### External Services
@@ -189,17 +306,22 @@ communicates with external services to function as a wallet:
any endpoint they prefer, including a local node). This is the only external any endpoint they prefer, including a local node). This is the only external
service the extension talks to. service the extension talks to.
- **CoinDesk CADLI price API**: Used to fetch ETH/USD and token/USD prices for
displaying fiat values. The price is cached for 5 minutes to avoid excessive
requests. No API key required. No user data is sent — only a list of token
symbols.
What the extension does NOT do: What the extension does NOT do:
- No analytics or telemetry services - No analytics or telemetry services
- No token list APIs (user adds tokens manually by contract address) - No token list APIs (user adds tokens manually by contract address)
- No price feed APIs (balances are shown in token units, not fiat)
- No phishing/blocklist APIs - No phishing/blocklist APIs
- No Infura/Alchemy dependency (any JSON-RPC endpoint works) - No Infura/Alchemy dependency (any JSON-RPC endpoint works)
- No backend servers operated by the developer - No backend servers operated by the developer
The user's RPC endpoint is the single point of external communication. Users who The user's RPC endpoint and the CoinDesk price API are the only external
want maximum privacy can point it at their own Ethereum node. services. Users who want maximum privacy can point the RPC at their own node
(price fetching can be disabled in a future version).
### Dependencies ### Dependencies
@@ -318,28 +440,81 @@ project owner.
- Browser notifications - Browser notifications
- Transaction history (use Etherscan) - Transaction history (use Etherscan)
## TODO ## TODO — 0.1.0 MVP
- [x] Project scaffolding (Makefile, Dockerfile, CI, manifests) Everything needed for a minimal working wallet that can send and receive ETH.
- [x] Set up Tailwind CSS build pipeline
- [x] Build popup UI views (all 13 views with stub state) ### Done
- [ ] Implement BIP-39 mnemonic generation and validation
- [ ] Implement BIP-32/BIP-44 HD key derivation for Ethereum - [x] Project scaffolding (Makefile, Dockerfile, CI, manifests, esbuild)
- [ ] Implement private key import and address derivation - [x] Tailwind CSS build pipeline
- [ ] Implement encrypted storage for wallet data - [x] Popup UI shell with screen stacking (Welcome, AddWallet, Home,
- [ ] Implement background wallet manager AddressDetail, Send, Receive, Settings)
- [ ] Implement EIP-1193 provider and content script injection - [x] BIP-39 mnemonic generation via ethers.js (die button)
- [ ] Implement ETH balance lookup via RPC - [x] BIP-39 mnemonic validation on import
- [ ] Implement ETH send (transaction construction + signing) - [x] BIP-32/BIP-44 HD key derivation (real addresses from xpub)
- [ ] Implement ERC-20 token management (add by contract, view balance, send) - [x] Private key import (real address via ethers.Wallet)
- [ ] Implement site connection approval flow - [x] Xpub stored unencrypted for read-only address derivation
- [ ] Implement transaction signing approval flow - [x] State persistence to extension storage (survives popup close)
- [ ] Implement message signing (`personal_sign`, `eth_sign`) - [x] Live ETH balance fetching via JSON-RPC (`eth_getBalance`)
- [ ] Add USD value display (price feed TBD) - [x] ENS reverse lookup (address → name) and forward resolution (name → address
- [ ] Add multi-currency fiat display support in Send field)
- [ ] Test on Chrome and Firefox - [x] ETH/USD price fetching via CoinDesk API
- [ ] Write tests for crypto operations - [x] USD value display next to ETH balances
- [ ] Write tests for transaction construction - [x] Full address display everywhere (no truncation)
- [x] Token list module with ~150 ERC-20 tokens ordered by market cap
### Wallet Management
- [ ] Rename wallets (tap wallet name on Home to edit)
- [ ] Rename addresses (tap address name on AddressDetail to edit)
- [ ] Delete wallet (with confirmation)
- [ ] Delete address from HD wallet (with confirmation)
- [ ] Show wallet's recovery phrase (requires password, from Settings or wallet
context menu)
### Sending
- [ ] Encrypt recovery phrase / private key with password via libsodium
(Argon2id + XSalsa20-Poly1305)
- [ ] Password prompt on Send (decrypt private key to construct transaction)
- [ ] Transaction construction via ethers.js (to, value, gasLimit, gasPrice)
- [ ] Gas estimation and fee display before confirming
- [ ] Broadcast transaction via `eth_sendRawTransaction`
- [ ] Transaction status feedback (pending → confirmed / failed)
### Receiving
- [ ] QR code generation for address (text-based or lightweight QR library)
### Display
- [ ] Home screen: total ETH balance summed across all addresses
- [ ] Home screen: total USD value (small text under total ETH)
- [ ] Cache ETH/USD price for 5 minutes (don't re-fetch on every popup open)
- [ ] Per-address USD value in small text under ETH balance everywhere
### Tokens (ERC-20)
- [ ] Add token by contract address (fetch name/symbol/decimals from contract)
- [ ] Display ERC-20 token balances per address
- [ ] Send ERC-20 tokens
### Testing
- [ ] Tests for mnemonic generation and address derivation
- [ ] Tests for xpub derivation and child address generation
- [ ] Tests for token list module (getTopTokenPrices, getTopTokenSymbols)
- [ ] Test on Chrome (Manifest V3)
- [ ] Test on Firefox (Manifest V2)
### Post-MVP
- [ ] EIP-1193 provider injection (window.ethereum) for web3 site connectivity
- [ ] Site connection approval flow
- [ ] Transaction signing approval flow (requests from connected sites)
- [ ] Message signing (`personal_sign`, `eth_sign`)
- [ ] Multi-currency fiat display (EUR, GBP, etc.)
- [ ] Security audit of key management - [ ] Security audit of key management
## License ## License