# AutistMask AutistMask is a GPL-licensed JavaScript browser extension by [@sneak](https://sneak.berlin) that provides a minimal Ethereum wallet for Chrome and Firefox. It manages HD wallets derived from BIP-39 seed phrases and supports sending and receiving ETH and ERC-20 tokens, as well as web3 site connection and authentication via the EIP-1193 provider API. ## Getting Started ```bash git clone https://git.eeqj.de/sneak/autistmask.git cd autistmask make install make build ``` Load the extension: - **Chrome**: Navigate to `chrome://extensions/`, enable "Developer mode", click "Load unpacked", and select the `dist/chrome/` directory. - **Firefox**: Navigate to `about:debugging#/runtime/this-firefox`, click "Load Temporary Add-on", and select `dist/firefox/manifest.json`. ## Rationale MetaMask has become bloated with swap UIs, portfolio dashboards, analytics, tracking, and advertisements. It is no longer a simple wallet. Most alternatives (Rabby, Rainbow, etc.) only support Chromium browsers, leaving Firefox users without a usable option. AutistMask exists to provide the absolute minimum viable Ethereum wallet experience: manage seed phrases, derive HD addresses, send and receive ETH and ERC-20 tokens, and connect to web3 sites. Nothing else. No swaps (that's what the web is for), no analytics, no tracking, no ads, no portfolio views, no NFT galleries. Just a wallet. ## Design AutistMask is a browser extension targeting both Chrome (Manifest V3) and Firefox (Manifest V2/V3 as supported). The codebase is shared between both targets with platform-specific manifest files and a build step that produces separate output directories. ### Architecture ``` src/ background/ — service worker / background script index.js — extension lifecycle, message routing wallet.js — wallet management (create, import, derive) provider.js — EIP-1193 JSON-RPC provider implementation transaction.js — transaction construction and signing popup/ — popup UI (the main wallet interface) index.html index.js components/ — UI components (account list, send form, etc.) styles/ — CSS (Tailwind) content/ — content script injected into web pages index.js — injects the provider into page context inpage.js — the window.ethereum provider object shared/ — shared utilities crypto.js — BIP-39 mnemonic, HD key derivation, signing storage.js — encrypted storage abstraction constants.js — chain IDs, default RPC endpoints, ERC-20 ABI rpc.js — JSON-RPC client for Ethereum nodes manifest/ chrome.json — Manifest V3 for Chrome firefox.json — Manifest V2/V3 for Firefox ``` ### UI Design Philosophy The UI follows a "Universal Paperclips" aesthetic — a deliberately spartan, almost brutalist approach: - **Monochrome**: Black text on white background. No brand colors, no gradients, no color-coding. Color may be introduced later for specific semantic purposes (e.g. error states) but the baseline is monochrome. - **Text-first**: Every piece of information is presented as text. Balances are numbers. Addresses are hex strings. Status is a sentence. No progress spinners with animations — a text status line is sufficient. - **Monospace font**: All text is rendered in the system monospace font. Ethereum addresses, transaction hashes, and balances are inherently fixed-width data. Rather than mixing proportional and monospace fonts, we use monospace everywhere for visual consistency and alignment. - **Icon fonts only**: Where icons are needed (copy, send, settings, etc.) we use an icon font (no SVGs, no PNGs, no image assets). This keeps the extension size tiny and the build simple. - **No images**: Zero image assets in the entire extension. No logos, no illustrations, no token icons. Token identity is conveyed by symbol text (ETH, USDC, etc.). - **Tailwind CSS**: Utility-first CSS via Tailwind. No custom CSS classes for styling. Tailwind is configured with a minimal monochrome palette. This keeps the styling co-located with the markup and eliminates CSS file management. - **Vanilla JS**: No framework (React, Vue, Svelte, etc.). The popup UI is small enough that vanilla JS with simple view switching is sufficient. A framework would add bundle size, build complexity, and attack surface for no benefit at this scale. - **360x600 popup**: Standard browser extension popup dimensions. The UI is designed for this fixed viewport — no responsive breakpoints needed. ### UI Views The popup has the following views, switched via simple show/hide: 1. **Lock screen**: Password input + unlock button. Shown when the wallet is locked or on first open after browser restart. 2. **Setup / Onboarding**: Shown on first use. Create a new wallet (generates BIP-39 mnemonic, user confirms backup, sets password) or import an existing seed phrase. 3. **Main / Account view**: The default view after unlock. Shows the current account address (truncated, click to copy), ETH balance, list of added ERC-20 tokens with balances, and action buttons (Send, Receive, Settings). 4. **Send**: Form with To address, amount, token selector (ETH or any added ERC-20), and a Send button. Shows gas estimate before confirming. 5. **Receive**: Displays the current account address in full (copyable). That's it. 6. **Settings**: Configure RPC endpoint URL, manage wallets (add/remove seed phrases), derive additional accounts, view/export seed phrase (requires password re-entry), manage added ERC-20 tokens. 7. **Approval popups**: When a connected site requests a transaction signature or message signature, an approval view shows the details and Approve/Reject buttons. ### External Services AutistMask is not a fully self-contained offline tool. It necessarily communicates with external services to function as a wallet: - **Ethereum JSON-RPC endpoint**: The extension needs an Ethereum node to query balances (`eth_getBalance`), read ERC-20 token contracts (`eth_call`), estimate gas (`eth_estimateGas`), fetch nonces (`eth_getTransactionCount`), broadcast transactions (`eth_sendRawTransaction`), and check transaction receipts. The default endpoint is a public RPC (configurable by the user to any endpoint they prefer, including a local node). This is the only external service the extension talks to. What the extension does NOT do: - No analytics or telemetry services - 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 Infura/Alchemy dependency (any JSON-RPC endpoint works) - No backend servers operated by the developer The user's RPC endpoint is the single point of external communication. Users who want maximum privacy can point it at their own Ethereum node. ### Key Decisions - **No framework**: The popup UI is vanilla JS and HTML. The extension is small enough that a framework adds unnecessary complexity and attack surface. - **Encrypted storage**: Seed phrases are encrypted with a user-provided password using AES-256-GCM before being stored in the extension's local storage. The encryption key is derived from the password using PBKDF2 with a high iteration count. - **BIP-39 / BIP-44**: Standard mnemonic generation and HD key derivation (`m/44'/60'/0'/0/n`) for Ethereum address compatibility. - **EIP-1193 provider**: The content script injects a `window.ethereum` object that implements the EIP-1193 provider interface, enabling web3 site connectivity. - **Minimal RPC**: The extension communicates with Ethereum nodes via JSON-RPC. The default endpoint is configurable. No Infura dependency — users can point it at any Ethereum JSON-RPC endpoint. ### Supported Functionality - Create new wallet from generated BIP-39 mnemonic - Import wallet from existing BIP-39 mnemonic - Derive multiple HD addresses per wallet (`m/44'/60'/0'/0/n`) - View ETH balance - View ERC-20 token balances (user adds token by contract address) - Send ETH to an address - Send ERC-20 tokens to an address - Receive ETH/tokens (display address + copy to clipboard) - Connect to web3 sites (EIP-1193 `eth_requestAccounts`) - Sign transactions requested by connected sites - Sign messages (`personal_sign`, `eth_sign`) - Switch between wallets/accounts - Lock/unlock with password - Configurable RPC endpoint ### Non-Goals - Token swaps (use a DEX in the browser) - Portfolio/price tracking (balances shown in token units only, no fiat) - NFT display or management - Multi-chain support (Ethereum mainnet only, for now) - Analytics, telemetry, or tracking of any kind - Advertisements or promotions - Phishing detection (use your brain) - Hardware wallet support (maybe later) - Token list auto-discovery (user adds tokens manually) - Fiat on/off ramps - Browser notifications - Transaction history (use Etherscan) ## TODO - [x] Project scaffolding (Makefile, Dockerfile, CI, manifests) - [ ] Set up Tailwind CSS build pipeline - [ ] Build popup UI views (lock, setup, main, send, receive, settings) - [ ] Implement BIP-39 mnemonic generation and validation - [ ] Implement BIP-32/BIP-44 HD key derivation for Ethereum - [ ] Implement encrypted storage for seed phrases - [ ] Implement background wallet manager - [ ] Implement EIP-1193 provider and content script injection - [ ] Implement ETH balance lookup and send - [ ] Implement ERC-20 token management (add by contract, view balance, send) - [ ] Implement site connection approval flow - [ ] Implement transaction signing approval flow - [ ] Implement message signing (`personal_sign`, `eth_sign`) - [ ] Add configurable RPC endpoint - [ ] Test on Chrome and Firefox - [ ] Write tests for crypto operations - [ ] Write tests for transaction construction - [ ] Security audit of key management ## License GPL-3.0. See [LICENSE](LICENSE). ## Author [@sneak](https://sneak.berlin)