New module with top Ethereum mainnet ERC-20 tokens sourced from
CoinGecko API (market cap ranking) with decimals verified on-chain
via eth_call to each contract. Addresses are EIP-55 checksummed.
Exports:
- TOKENS: full array ordered by market cap
- TOKEN_BY_ADDRESS: Map of lowercase address -> token info
- KNOWN_SYMBOLS: Map of uppercase symbol -> legitimate address
- getTopTokens(n): return first n tokens
This module is not yet integrated into the existing token.js — it
exists alongside it for now as a data source ready for integration.
The tx approval screen now decodes known ERC-20 function calls
(approve, transfer) and shows them in plain language instead of
raw hex. For the Uniswap approve example, the user now sees:
Action: Token Approval
Approve spending of your USDT
Token: USDT (with full contract address + etherscan link)
Spender: (full address + etherscan link)
Amount: Unlimited
Known tokens from the built-in list show their symbol. Unknown
tokens show the contract address. Max uint256 approvals are
labeled "Unlimited". The raw data is still shown below in a
scrollable area for verification.
Also labels the "To" field as "Contract" since dApp transactions
are always contract calls, and shows the token symbol above the
contract address when recognized.
When sending an ERC-20 token, Blockscout returns the same tx hash
from both the /transactions endpoint (as a 0 ETH contract call) and
the /token-transfers endpoint (as the actual token transfer with
amount and symbol). The old dedup logic kept the 0 ETH version and
skipped the token transfer.
Now token transfers replace normal transactions with the same hash,
since the token transfer has the real amount, symbol, and contract
address.
Creates a centralized transactionDetail.js view module, replacing
the duplicated showTxDetail/copyableHtml/blockieHtml/txDetailAddressHtml
code that was in both addressDetail.js and addressToken.js (~120 lines
removed). Transaction data is stored in state.viewData and persisted,
so the transaction detail view survives popup close/reopen.
Adds viewData to persisted state. Each view that needs data for
restore stores it in state.viewData before rendering. The ctx object
now has showTransactionDetail() alongside all other show methods.
Restorable views expanded to include: transaction (via viewData.tx),
success-tx (via viewData.hash/blockNumber), error-tx (via
viewData.message). txStatus.js split into show (sets data) + render
(reads data) for each screen, enabling restore.
Non-restorable views (send, confirm-tx, wait-tx, add-wallet,
import-key, add-token) fall back to the nearest parent since they
involve active form state or network polling.
The current view, selected wallet, selected address, and selected
token are now saved to extension storage. When the popup reopens,
it restores to the last visited view instead of always returning
to the home screen.
Restorable views: main, address detail, address-token, receive,
settings. Non-restorable views (send, confirm, tx status, forms)
fall back to the nearest parent. Stored indices are validated
against current wallet data to handle stale references.
Also refactors receive view setup into a centralized receive.show()
function, eliminating duplicate QR/address/warning code from
addressDetail.js, addressToken.js, and home.js. Adds settings.show()
to centralize settings field population.
Covers rationale, hard guidelines (always/never), external service
details (RPC, Blockscout, CoinDesk APIs with what data is sent),
encryption model, installation, wallet management, sending/receiving,
web3 site connections, scam protection, settings, and FAQ.
Written for a technical cryptocurrency user who is not a programmer.
Complete rewrite of the Screen Map section documenting all 17 views:
Welcome, Home, AddWallet, ImportKey, AddressDetail, AddressToken,
Send, ConfirmTx, WaitTx, SuccessTx, ErrorTx, Receive,
TransactionDetail, AddToken, Settings, SiteApproval, TxApproval.
Each view documents its elements (with display details like blockies,
color dots, etherscan links, formatting) and all state transitions
with their destination screens and conditions.
After broadcast, the user is taken to a full-screen wait view showing
the amount, recipient, tx hash (copyable + etherscan link), and a
count-up timer. The view polls every 10 seconds for confirmation.
On confirmation: navigates to success screen showing block number,
tx hash, and a Done button that returns to the address view.
On 60-second timeout or error: navigates to error screen with the
failure message, tx hash (if available), and Done button.
Replaces the previous inline confirm-status div that was crammed
onto the confirmation page.
Receive view: address now shows color dot and etherscan link,
matching every other address display in the app.
Send view "From": address now includes etherscan link alongside
the existing color dot.
Send view "What to send" (ERC-20 from token view): shows token
symbol as bold heading, then full contract address below with
color dot, copy-on-click, and etherscan link.
Approval views: tx approval From/To addresses now show color
dots and etherscan links instead of bare text. Site approval
address adds etherscan link. Tx approval value uses 4 decimal
places consistent with all other amount displays.
Home tx list: row padding changed from py-1 to py-2, matching
addressDetail and addressToken transaction lists.
From and To addresses now render with 48px blockie identicons,
color dots, and etherscan links — matching the transaction detail
view pattern. USD estimates for amount, balance, and network fee
are shown in parentheses after the value on the same line, not on
a separate line below.
The confirmation page now shows:
- Transaction type (Native ETH transfer vs ERC-20 token transfer)
- Full ERC-20 token contract address with etherscan link
- Token symbol throughout (not raw contract address)
- Current balance of the token being sent, with USD value
- Estimated network fee in ETH and USD (fetched async)
- USD value for ERC-20 token amounts (not just ETH)
- Insufficient balance errors for ERC-20 tokens
Also implements actual ERC-20 token transfers via the token contract's
transfer() function, rather than only supporting native ETH sends.
Read token from state.selectedToken when set, falling back to the
select element. This ensures the correct token balance is shown even
when the select dropdown is hidden or its value didn't take because
the token was filtered out by renderSendTokenSelect.
When sending from the address-token view, show the token symbol as
plain text instead of a disabled dropdown. ERC-20 tokens include an
etherscan link to the contract address. The dropdown is restored when
navigating back or entering send from other views.
The warning about only sending ERC-20 tokens on the Ethereum network
belongs on the receive page where the QR code is shown, not on the
token detail view. Non-token receive flows hide the warning.
Clicking a token balance on the address detail view navigates to a
focused view showing only that token's transactions. Send pre-selects
and locks the token dropdown, Receive shows an ERC-20 warning for
non-ETH tokens, and all back buttons return to the correct parent view.
Show a confirmation popup with tx details (from, to, value, data) and
password prompt when a dApp calls eth_sendTransaction. Sign and broadcast
the transaction in the background, returning the tx hash to the dApp.
- Remove mb-1 from Recent Transactions header (wallet headers have
no bottom margin, so this should match)
- Remove mb-3 wrapper from wallet sections (section header bg
provides the visual break, extra margin created uneven gaps)
- Change tx row padding from py-2 to py-1 to match address rows
Add --color-section (#dddddd) distinct from --color-well (#f5f5f5).
Section headers on the home screen use bg-section so they stand out
as visual dividers rather than blending with the price well.
Address titles now use wallet name instead of wallet index (e.g.
"Wallet 1 — Address 2" instead of "Address 1.2"). This applies to
the address detail page title, the home address labels, and the
addressTitle() helper used on confirmation pages.
Section dividers on the home screen are now full-width grey
background stripes instead of horizontal rules, visually breaking
the page into wallet sections and a recent transactions section.
Wallet and Recent Transactions headings now use border-border-light
for their bottom rule. Thick 2px black horizontal rules separate
wallet sections from each other and from the transactions section,
with generous vertical spacing.
Fetch transactions for every address across all wallets in parallel,
merge and deduplicate by hash, apply anti-poisoning filters, sort by
block number, and display the top 25 below the wallet list. Clicking
a transaction navigates to the address detail page for the relevant
address. Shows "Loading..." placeholder to prevent layout shift.
Blockies now appear above the from/to addresses on a separate line,
with color dots restored inline next to the address text. Increased
spacing between transaction detail fields from mb-2 to mb-3.
Show a 48px pixelated blockie (same style as Etherscan) centered
above the wallet title on the address detail page. Uses
ethereum-blockies-base64 which generates a base64 PNG from the
address. Replaces the previously added @metamask/jazzicon.
The "Scanning for addresses..." flash had a 30-second timeout and was
never cleared on completion. Now shows "Found N addresses." when
multiple are found, or briefly shows "Ready." for single-address
wallets.
Remove border and padding from the info button, use dashed underline
text style instead. This saves enough horizontal space that the full
address no longer wraps.
Both elements now have min-height and placeholder content so they
reserve vertical space before API data arrives, preventing layout
jumps when prices load. This follows the No Layout Shift policy
in the README.
Clicking an address row now makes it the active address (bold title,
updates headline and active address display, broadcasts to dapps).
The [info] button on each row opens the address detail page. This
replaces the previous [ ]/ACTIVE toggle.
The address now sits on its own line with no other elements beside it,
followed by an etherscan external link icon. The USD total value moves
to a separate line below.
Headline shows active address ETH balance with ETH-only USD value
in parentheses. Small "Total:" subtitle below includes ETH + token
values. A centered well between Send/Receive buttons and the wallet
list displays the current ETH price in USD.
Replace [select] with [ ] to avoid wrapping the full address line.
ACTIVE label stays as-is for discoverability. Show the currently
active address (full, untruncated, with color dot) above the Send
and Receive buttons on the home screen.
Each address now shows: title on its own line, full untruncated
address with ACTIVE/select marker on the next line, USD total
right-aligned on the next line, then token balances below. The
wallet rename input now fills the available width.
Click the wallet name on the home screen to edit it inline. The name
turns into a text input; press Enter or click away to save, Escape
to cancel. The dashed underline on the name indicates it is editable.
Add debugFetch wrapper in log.js that logs method, URL, and body on
request, and status code on response. Replace all fetch() calls
across balances, transactions, tokens, background RPC proxy, and
settings validation with debugFetch.
Add showZeroBalanceTokens setting (default: on). When enabled,
balanceLinesForAddress merges state.trackedTokens with the address's
tokenBalances, showing 0.0000 lines for tracked tokens that have no
balance on that address. This gives users visibility into all tokens
they're watching across all addresses.
From address, to address, and tx hash are now clickable to copy.
Each also has a small box-arrow icon linking to the corresponding
etherscan page. ENS names and full addresses are both copyable.
Add more vertical spacing between checkboxes in the Token Spam
Protection well. Change the gwei threshold from a number input
(with spinner arrows) to a plain text input with numeric keyboard
hint.