Expands the confirm-tx warning system with three new warning types, all using the existing `visibility:hidden/visible` pattern from PR #98 (no animations, no layout shift).
## Changes
1. **Scam address list expanded** (7 → 652 addresses): Sourced from [MyEtherWallet/ethereum-lists](https://github.com/MyEtherWallet/ethereum-lists) darklist (MIT license). Checked synchronously before sending.
2. **Contract address warning**: When the recipient is a smart contract (detected via `getCode`), shows a warning that sending directly to a contract may result in permanent loss of funds.
3. **Null/burn address warning**: Detects known burn addresses (`0x0000...0000`, `0x...dead`, `0x...deadbeef`) and warns that funds are permanently destroyed.
4. **No-history warning** (existing from #98): Unchanged, still shows for EOAs with zero transaction history.
All warnings use reserved-space `visibility:hidden/visible` elements — no layout shift, no animations.
closes#114
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Co-authored-by: user <user@Mac.lan guest wan>
Co-authored-by: clawbot <clawbot@eeqj.de>
Reviewed-on: #118
Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
Co-committed-by: clawbot <sneak+clawbot@sneak.cloud>
- Always display a Type field as the first item under the Transaction
heading, identifying the transaction as: Native ETH Transfer, ERC-20
Token Transfer, Swap, Token Approval, Contract Call, or Contract Creation
- Show token contract address with identicon for ERC-20 transfers
- Fetch and display on-chain details from Blockscout: block number,
nonce, transaction fee, gas price, and gas used
- All new fields are click-copyable with Etherscan links where applicable
closes#95
- Change dark mode --color-well from #0a0a0a to #111111 for visible
contrast against #000000 background
- Add explicit text-fg class to balance display element to ensure
white text in dark mode
All isoDate() functions now output proper ISO 8601 format with timezone
offset (e.g. 2026-02-28T15:30:00-08:00) instead of bare datetime strings.
Also uses 'T' separator per ISO 8601.
closes#116
Add theme preference (light/dark/system) stored in extension state.
System mode follows prefers-color-scheme and listens for changes.
Dark mode inverts the monochrome palette (white-on-black).
Theme selector added to Display section in settings.
Closes#125
Replace display:none (hidden class) with visibility:hidden/visible for all
error, warning, and status message elements across the extension UI. This
prevents layout shift when messages appear or disappear.
Changes:
- helpers.js: showError/hideError now use visibility instead of hidden class
- index.html: all error/status divs use visibility:hidden + min-height
- confirmTx.js: warnings, errors, fee section use visibility
- approval.js: tx-error, sign-error, danger-warning use visibility
- addressDetail.js: export-privkey-flash uses visibility
- deleteWallet.js: delete-wallet-flash uses visibility
- addWallet.js: phrase-warning uses visibility
- receive.js: erc20-warning uses visibility
- addToken.js: add-token-info uses visibility
- settingsAddToken.js: settings-addtoken-info uses visibility
Remove all CSS transitions, max-height changes, and opacity animations.
The warning container always reserves its space with visibility:hidden
and switches to visibility:visible when needed. No layout shift ever.
Instead of permanently reserving space with visibility:hidden, the warning
container now uses max-height + opacity transitions. Space is reserved during
the async check, then smoothly collapses to 0 if the warning isn't needed.
This reclaims ~40px of popup viewport in the common case.
- Active tab: solid border on top/sides, bottom border matches background
(connects to content area), bold text
- Inactive tabs: dashed borders in border-light color, muted text,
transparent bottom border
- Inactive hover: invert (bg-fg text-bg) for clear clickability signal
- All three tabs behave identically on hover
Tabs are not buttons (they change UI state, not application state).
All tabs now use underline style with identical hover behavior:
- Active: bold text + solid bottom border
- Inactive: muted text + transparent bottom border
- Hover (all tabs): text brightens to fg + bottom border appears
This ensures all tabs clearly indicate clickability on hover,
including the currently active one.
Per README clickable affordance policy: all tabs now use visible
border, padding, and hover:bg-fg hover:text-bg (invert to
white-on-black). Active tab is inverted (bg-fg text-bg). All
three tabs behave identically on hover regardless of active state.
Merge all three wallet import methods (recovery phrase, private key,
extended key/xprv) into one tabbed add-wallet view with a mode selector.
This fixes the blank import-xprv render (it was missing from the VIEWS
array) and the broken back-button navigation from the separate import
views.
- Add tab selector: Recovery Phrase | Private Key | Extended Key (xprv)
- Share password fields across all modes
- Remove separate import-key and import-xprv views and modules
- Add duplicate wallet detection for private key imports
- All tabs follow affordance policy (visible border + hover state)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the ability to import an existing HD wallet using an extended
private key (xprv) instead of a mnemonic phrase.
- New 'xprv' wallet type with full HD derivation and address scanning
- New importXprv view with password encryption
- Updated getSignerForAddress to handle xprv wallet type
- Added xprv link to the add-wallet view
- Allow adding derived addresses for xprv wallets
Closes#20
- Reserve space for the warning upfront using visibility:hidden instead
of display:none, preventing layout shift per README policy
- Move warning HTML to index.html as a static element rather than
injecting dynamically
- Skip warning for contract addresses (check getCode first) since
getTransactionCount only returns outgoing tx nonce
- Collapse reserved space when warning is not needed (address has
history, is a contract, or on RPC error)
Replace the modal overlay password dialog in the confirm-tx view with
an inline password field, matching the pattern used by approve-tx and
approve-sign views for consistency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add min-h-[1.25rem] and border styling to approve-tx-error and
approve-sign-error divs to prevent layout shift, matching the pattern
used by modal-password-error in confirm-tx view.
Replace direct DOM classList manipulation with showError()/hideError()
helpers from helpers.js for consistency.
Closes#84
- Validate Ethereum addresses (0x + 40 hex chars) and ENS names
- EIP-55 checksum validation for mixed-case addresses
- Block sending to zero address (0x0000...0000)
- Warn when sending to own address (allow but show warning)
- Inline error messages with reserved space (no layout shift)
- Disable Review button while address is invalid
Closes#67
- Replace dashed border with light red well (bg-danger-well) and rounded corners
- Remove redundant 'Click to copy.' paragraph
- Add --color-danger-well theme token
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
Add blockie identicon, wallet/address title, and color dot with full
address display to the export-privkey view, matching the pattern used
by AddressDetail and other views. Address is click-to-copy.
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
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)
- Menu items now use text-xs font-light for smaller, lighter type
that's clearly distinct from the pushbuttons in the action row
- The ··· button stays visually inverted (bg-fg text-bg) while the
dropdown menu is open, reverting when closed
- Menu items styled as plain text rows with subtle hover background,
no borders or button-like appearance
Use bg-hover token for grey mouseover instead of full fg/bg
inversion. Add py-1 padding to dropdown container and px-4 to
items for proper list appearance with margin around items.
Replace the muted text link at the bottom of AddressDetail with a
'···' overflow/more button in the action button row. Clicking it
opens a dropdown with 'Export Private Key' as an option. Clicking
outside closes the dropdown. The pattern is reusable for future
secondary actions.
- Moved 'Export private key' from prominent button row to a small
muted text link at the bottom of the address detail view
- Added 'export-privkey' to the VIEWS array in helpers.js — this was
the cause of the blank view (showView toggled all known views but
didn't know about export-privkey, so it was never unhidden)
Adds an 'Export Private Key' button to the address detail view.
Clicking it opens a password confirmation screen; after verification,
the derived private key is displayed in a copyable field with a
security warning. The key is cleared when navigating away.
Closes#19
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
- Restructured calldata section to use same well layout as approval view:
Action label + bold name + structured details
- Always show raw data section below decoded well
- Unknown contract calls show method name in well instead of inline
- 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
- 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