## Summary
All address rendering now uses a single `renderAddressHtml()` function in helpers.js that produces consistent output everywhere:
- Color dot (deterministic from address)
- Full address with dashed-underline click-to-copy affordance
- Etherscan external link icon
## Changes
Refactored all 9 view files that display addresses to use the shared utility:
- **approval.js** (approve-tx, approve-sign, approve-site): addresses now have click-to-copy with dashed underline affordance
- **confirmTx.js**: from/to addresses and token contract address use shared renderer
- **txStatus.js**: wait/success/error transaction addresses
- **transactionDetail.js**: from/to and decoded calldata addresses
- **home.js**: active address display
- **send.js**: from-address display
- **receive.js**: receive address display
- **addressDetail.js**: address line and export-privkey address
- **addressToken.js**: address line and contract info
## Consolidation
- `EXT_ICON` SVG constant: removed 6 duplicates, now in helpers.js
- `copyableHtml()`: removed duplicate, now in helpers.js
- `etherscanLinkHtml()`: removed duplicates, now in helpers.js
- `attachCopyHandlers()`: removed duplicate, now in helpers.js
- Net: **-193 lines** (174 added, 367 removed)
closes#97
Co-authored-by: user <user@Mac.lan guest wan>
Reviewed-on: #129
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
## Summary
Fixes USD prices still showing on the main view when connected to a testnet (e.g. Sepolia). The root cause was stale mainnet prices lingering in the in-memory price cache after switching networks.
### Root Cause
PR #137 correctly made `refreshPrices()` skip fetching on testnets, but the cached prices from a prior mainnet session remained in the `prices` object. All display functions (`getPrice()`, `getAddressValueUsd()`, etc.) used whatever was cached without checking which network was active.
### Changes
- **`src/shared/prices.js`**
- `refreshPrices()` now clears the price cache when on a testnet instead of silently returning
- New `clearPrices()` function empties the cache and resets the fetch timestamp
- `getPrice()` returns null on testnets (defense-in-depth)
- `getAddressValueUsd()`, `getWalletValueUsd()`, `getTotalValueUsd()` return null on testnets
- **`src/popup/views/settings.js`**
- Network switcher immediately clears prices when switching to a testnet, so the UI updates without waiting for the next refresh cycle
closes#139
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Reviewed-on: #142
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
The approve-tx view (dapp-initiated transaction approval) now shows the estimated USD value next to the ETH amount being transferred, using the existing `getPrice`/`formatUsd` from `shared/prices.js`.
This matches the behavior already present in the manual send confirmation view (`confirmTx.js`).
When ETH price is available, the value line shows e.g. `0.5000 ETH ($1,650.00)`. When price is unavailable, it falls back gracefully to just the ETH amount.
closes#138
Co-authored-by: Jeffrey Paul <sneak@noreply.example.org>
Reviewed-on: #141
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
When viewing the address-token page for our own address with an ERC-20 token, the etherscan link now navigates to the token-specific page (`etherscan.io/token/<contract>?a=<address>`) instead of the plain address page.
Closes#135
Co-authored-by: user <user@Mac.lan guest wan>
Co-authored-by: Jeffrey Paul <sneak@noreply.example.org>
Reviewed-on: #136
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
## Summary
Adds Sepolia testnet support to AutistMask.
### Changes
- **New `src/shared/networks.js`** — centralized network definitions (mainnet + Sepolia) with chain IDs, default RPC/Blockscout endpoints, and block explorer URLs
- **State management** — `networkId` added to persisted state; defaults to mainnet for backward compatibility
- **Settings UI** — network selector dropdown lets users switch between Ethereum Mainnet and Sepolia Testnet
- **Dynamic explorer links** — all hardcoded `etherscan.io` URLs replaced with dynamic links from the current network config (`sepolia.etherscan.io` for Sepolia)
- **Background service** — `wallet_switchEthereumChain` now accepts both mainnet (0x1) and Sepolia (0xaa36a7); broadcasts `chainChanged` to connected dApps
- **Inpage provider** — fetches chain ID on init and updates dynamically via `chainChanged` events (no more hardcoded `0x1`)
- **Blockscout API** — uses `eth-sepolia.blockscout.com/api/v2` for Sepolia
- **Etherscan labels** — phishing/scam checks use the correct explorer per network
- **Price fetching** — skipped on testnets (testnet tokens have no real market value)
- **RPC validation** — checks against the selected network's chain ID, not hardcoded mainnet
- **ethers provider** — `getProvider()` uses the correct ethers `Network` for Sepolia
### API Endpoints Verified
| Service | Mainnet | Sepolia |
|---------|---------|--------|
| Etherscan | etherscan.io | sepolia.etherscan.io |
| Blockscout | eth.blockscout.com/api/v2 | eth-sepolia.blockscout.com/api/v2 |
| RPC | ethereum-rpc.publicnode.com | ethereum-sepolia-rpc.publicnode.com |
| CoinDesk (prices) | ✅ | N/A (skipped on testnet) |
closes#110
Reviewed-on: #137
THIS WAS ONESHOTTED USING OPUS 4. WTAF
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
Add color dot (addressDotHtml), dashed underline styling, and click-to-copy
functionality to the token contract address on the confirm-tx page, matching
the display pattern used in addressToken, txStatus, and other views.
Closes#70
The receive view was using raw textContent and a manually constructed
color dot instead of the shared formatAddressHtml helper used by other
views. This violated the display consistency policy ('Same data
formatted identically across all screens').
Changes:
- Use formatAddressHtml() to render address with color dot, title
(e.g. 'Wallet 1 — Address 1'), and ENS name — matching addressDetail
- Make the address block itself click-to-copy (matching policy:
'Clicking any address copies the full untruncated value')
- Replace separate receive-dot/receive-address spans with a single
receive-address-block element
- Address is still shown in full (no truncation) as appropriate for
the receive view
Closes#58
Carry decoded calldata info (action name, description, token details,
amounts, addresses) from the approval confirmation view through to the
success-tx view. For swap transactions, this now shows the same decoded
details (protocol, action, token symbols, amounts) that appeared on the
signing confirmation screen.
Changes:
- approval.js: store decoded calldata in pendingTxDetails.decoded
- txStatus.js: carry decoded through state.viewData, render in success view
- index.html: add success-tx-decoded container element
The decodeCalldata function in approval.js was embedding the token symbol
into the Amount value string (e.g. '2.0000 USDT'). This value was then
assigned to pendingTxDetails.amount, and txStatus.js would append the
symbol again, producing '2.0000 USDT ETH' (or '2.0000 USDT USDT' when
the token was in TOKEN_BY_ADDRESS).
Fix: decodeCalldata now provides a rawValue field (numeric only) on
Amount details. pendingTxDetails.amount uses rawValue when available,
so txStatus.js can append the correct symbol exactly once.
Affected paths:
- approve() decoded amount (approve calldata)
- transfer() decoded amount (transfer calldata)
- pendingTxDetails.amount assignment
Audited all other amount+symbol display sites:
- txStatus.js showWait/showSuccess/showError: correctly derive symbol
from txInfo.token, no duplication
- confirmTx.js show(): builds symbol independently, amount is raw — OK
- send.js: amount is raw user input — OK
- addressToken.js: uses balanceLine helper — OK
- transactions.js parseTx/parseTokenTransfer: separate value/symbol — OK
Fixes#59
The etherscanLinkHtml helper had added border, px-1, hover:bg-fg,
hover:text-bg, and cursor-pointer classes that no other view uses.
All other views (addressDetail, addressToken, confirmTx, send, receive,
home, txStatus) use only 'inline-flex items-center' on etherscan links.
Removed the extra classes for consistency.
1. Protocol name now has Etherscan link (was appearing clickable but wasn't)
2. Token contract addresses: symbol shown separately, then color dot +
full address + Etherscan link (symbol no longer interposed)
3. Raw data section moved after transaction hash (no longer pushes
useful info off screen)
- Add clickable affordance (border + hover state) to all Etherscan external
links on addresses and transaction hash per clickable affordance policy
- Fix address display when ENS name is present: show color dot and Etherscan
link on the full address line (previously only shown on ENS name line)
- Extract etherscanLinkHtml helper for consistent link styling
Closes#59
Previously, ENS reverse lookups were only performed for the single
counterparty address (from or to depending on direction). This meant
contract interaction targets and the non-counterparty side of
transactions never got ENS names resolved.
Now both from and to addresses are collected for ENS resolution,
ensuring all displayed addresses show their ENS names when available.
Replace the inline confirmation div at the bottom of Settings with a
proper full-screen view (view-delete-wallet-confirm). This fixes the
issue where the confirmation was offscreen on the 360x600 popup.
- New view with back button, title, warning text, password input,
and red-text Confirm Delete button
- Dedicated flash area for password errors
- New deleteWallet.js module with init/show pattern
- Added delete-wallet-confirm to VIEWS array in helpers.js
- Removed old inline confirmation HTML and logic from settings
action.openPopup() is unreliable when called from the background script
during an async message handler — it requires a user gesture context.
tx and sign approvals are triggered programmatically by dApp RPC calls,
not by user clicking the toolbar icon, so openPopup() fails silently.
Use windows.create() directly for tx/sign approvals, matching the
standard extension pattern (used by MetaMask and others). Site-connection
approvals retain openPopup() since they can fall back to the user
clicking the toolbar icon.
Also updates popup window dimensions to 360x600 to match the standard
popup viewport specified in README.
Closes#4
- Delete buttons now use [x] with border, matching token and site
removal patterns in settings
- Wallet names are click-to-rename (inline input), matching the
home view rename UX
- Per-wallet [delete] links in settings wallet list
- Monochrome styling throughout, no red/danger colors
- Password confirmation modal with warning text
- Cleans up site permissions for deleted addresses
- Switches to first remaining wallet or shows welcome if none left
- Remove all red/danger styling, use standard monochrome colors
- Add wallet picker dropdown instead of relying on selectedWallet
- Fix encryptedSecret field name (was wallet.encrypted)
- Populate dropdown when settings view opens
- Confirmation modal uses standard border styling
The approval ID was changed from sequential integers to crypto.randomUUID()
strings for security, but the popup still called parseInt() on it, which
converted the UUID to NaN. This caused every approval lookup to fail,
preventing the confirmation popup from displaying pending tx/sign requests.
- Map known DEX methods (execute, swap, multicall, etc.) to "Swap"
label instead of raw method name like "Execute"
- Remove unused displayData variable in transactionDetail.js
Addresses review feedback on PR #10.
- Preserve contract call metadata (direction, label, method) when token
transfers merge with normal txs in fetchRecentTransactions
- Handle 'contract' direction in counterparty display for home and
address detail list views
- Add decoded calldata display to transaction detail view, fetching
raw input from Blockscout and using decodeCalldata from approval.js
- Show 'Unknown contract call' with raw hex for unrecognized calldata
- Export decodeCalldata from approval.js for reuse
- Remove border, add rounded corners and horizontal margin
- Each attribute on its own line (key: value format)
- Move well below send/receive buttons
- Add project/token URL from tokenlist when available
- Import TOKEN_BY_ADDRESS for URL lookup
- Replace border-b styling with bg-hover + dashed border for visual
distinction from wallet address
- Rename label from "Token Contract" to "Contract Address"
- Addresses feedback on #9
UUID is generated once via crypto.randomUUID(), persisted in
chrome.storage.local, and sent from the content script to the
inpage script via postMessage.