Commit Graph

156 Commits

Author SHA1 Message Date
0ed7b8e61d Merge pull request 'fix: show ERC-20 contract details in address-token view (closes #9)' (#11) from fix/address-token-details into main
All checks were successful
check / check (push) Successful in 8s
Reviewed-on: #11
2026-02-27 21:09:37 +01:00
user
560065dd77 fix: show ERC-20 contract details in address-token view (closes #9)
All checks were successful
check / check (push) Successful in 22s
2026-02-27 12:06:22 -08:00
0413c52229 Merge pull request 'security: fix high-severity findings from audit (closes #6)' (#7) from fix/high-severity-security into main
All checks were successful
check / check (push) Successful in 9s
Reviewed-on: #7
2026-02-27 20:56:43 +01:00
b01df0639b Merge branch 'main' into fix/high-severity-security
All checks were successful
check / check (push) Successful in 21s
2026-02-27 20:56:09 +01:00
8beb3cd70c Merge pull request 'Fix all RULES.md divergences' (#2) from fix/rules-audit-divergences into main
All checks were successful
check / check (push) Successful in 8s
Reviewed-on: #2
2026-02-27 20:55:25 +01:00
31b22c1325 style: format README.md and RULES.md with Prettier
All checks were successful
check / check (push) Successful in 21s
2026-02-27 11:39:44 -08:00
eec96f9054 security: clear decrypted secrets after use (best-effort)
All checks were successful
check / check (push) Successful in 21s
2026-02-27 11:36:56 -08:00
f13cd0fd47 security: add TODO comments for password plaintext over runtime.sendMessage 2026-02-27 11:36:19 -08:00
b478d9efa9 security: validate sender URL for popup-only messages 2026-02-27 11:35:42 -08:00
d59ebfd461 security: derive RPC origin from sender instead of trusting msg.origin 2026-02-27 11:35:31 -08:00
13e2bdb0b0 security: add prominent danger warning for eth_sign requests 2026-02-27 11:35:21 -08:00
95314ff229 security: replace predictable sequential approval IDs with crypto.randomUUID() 2026-02-27 11:34:48 -08:00
1237cf8491 security: increase minimum password length from 8 to 12 characters 2026-02-27 11:34:32 -08:00
afc4868001 docs: document Blockscout as third external service in README
Some checks failed
check / check (push) Failing after 13s
2026-02-27 03:25:02 -08:00
a6017ce32c docs: add agent-protection notice to RULES.md 2026-02-27 03:25:01 -08:00
9cceca8576 Merge branch 'main' into fix/rules-audit-divergences
All checks were successful
check / check (push) Successful in 22s
2026-02-27 11:55:51 +01:00
6a3be80379 Merge pull request 'add tracked token list management to settings' (#5) from feature/settings-token-management into main
All checks were successful
check / check (push) Successful in 9s
Reviewed-on: #5
2026-02-27 11:55:32 +01:00
3d8feb4c5a Add token management to Settings
All checks were successful
check / check (push) Successful in 22s
- Tracked Tokens well in settings with [x] remove buttons
- New settings-addtoken view with:
  - Top-10 quick-pick buttons (tracked ones dimmed+disabled)
  - Top-100 dropdown showing "Token Name (SYMBOL)", tracked disabled
  - Manual contract address entry with RPC lookup
- View comment in helpers.js about keeping README in sync
2026-02-27 17:52:30 +07:00
aca8c4b2a7 Add name and url fields to all 512 tokens in tokenList.js
Names fetched from CoinGecko bulk API (100% coverage).
URLs sourced from ethereum-lists GitHub repo + manual curation
for major tokens. Some lesser-known tokens have empty URLs which
can be populated incrementally.
2026-02-27 17:51:08 +07:00
user
2244b52f5f fix: rules audit items 1,3,6 (closes #1)
All checks were successful
check / check (push) Successful in 22s
2026-02-27 02:18:45 -08:00
9365cd03a6 Resolve all README FIXMEs and add RULES.md audit checklist
All checks were successful
check / check (push) Successful in 19s
- Update Architecture tree to match actual src/ structure
- Fix settings button to have border and hover state (Clickable Affordance)
- Cap truncateMiddle to remove at most 10 chars (anti-spoofing guard)
- Raise caller floor from 10 to 32 chars for address display
- Fill in default RPC URL (ethereum-rpc.publicnode.com)
- Fix dependencies table intro (four runtime libs, not two)
- Clean up TODO section: remove all completed items
- Add RULES.md: concise audit checklist derived from README policies
2026-02-27 16:52:00 +07:00
6b301dee28 Resolve all README FIXMEs and enforce truncation safety
All checks were successful
check / check (push) Successful in 18s
- Update Architecture tree to match actual src/ structure
- Fix settings button to have border and hover state (Clickable Affordance)
- Cap truncateMiddle to remove at most 10 chars (anti-spoofing guard)
- Raise caller floor from 10 to 32 chars for address display
- Fill in default RPC URL (ethereum-rpc.publicnode.com)
- Fix dependencies table intro (four runtime libs, not two)
- Clean up TODO section: remove all completed items
2026-02-27 16:48:00 +07:00
d67023e80d Show exact amounts and address titles in transaction detail
All checks were successful
check / check (push) Successful in 5s
- Display full-precision amount (no 4-decimal truncation) in the
  transaction detail view, with native quantity (wei/base units) below
- Both amount and native quantity are click-copyable
- Show wallet/address title above from/to when the address is ours
- Update README Display Consistency to document the exception
2026-02-27 16:09:44 +07:00
b9250dab2e Fix layout shift from async USD prices and token balances
Reserve vertical space with min-height and   placeholders for all
elements populated by async data: per-address USD totals, ETH price
display, token balance containers, and total value sub-line.  Prevents
buttons and click targets from moving when price API responds.
2026-02-27 16:05:49 +07:00
9e45c75d29 Implement personal_sign and eth_signTypedData_v4 message signing
All checks were successful
check / check (push) Successful in 4s
Replace stub error handlers with full approval flow for personal_sign,
eth_sign, eth_signTypedData_v4, and eth_signTypedData. Uses toolbar
popup only (no fallback window) and keeps sign approvals pending across
popup close/reopen cycles so the user can respond via the toolbar icon.
2026-02-27 15:27:14 +07:00
5af8a7873d Filter spam tokens from balance display
All checks were successful
check / check (push) Successful in 5s
Token balances from Blockscout are now filtered before display.
A token only appears if it meets at least one criterion:
- In the known 511-token list (by contract address)
- Explicitly tracked by the user (added via + Token)
- Has >= 1,000 holders on-chain

Also rejects tokens spoofing a known symbol from a different
contract address (same check used for transaction filtering).

This prevents airdropped spam tokens like "OpenClaw" from
appearing in the wallet without the user ever tracking them.
2026-02-27 13:02:05 +07:00
b64f9b56cc Show contract calls as "Approve USDT" instead of "0.0000 ETH"
All checks were successful
check / check (push) Successful in 17s
Contract interactions (approve, swap, etc.) now display the method
name and token symbol instead of the meaningless 0 ETH value.
Blockscout provides the method name and whether the target is a
contract — parseTx uses these plus TOKEN_BY_ADDRESS to produce
labels like "Approve USDT" or "Swap LINK".

Added directionLabel field to parsed transactions so renderers
don't need to know about the sent/received/contract distinction.

Also: clicking a transaction on the home screen now opens the
transaction detail view instead of navigating to the address
detail view.
2026-02-27 12:54:42 +07:00
55786d1350 Exclude contract calls from dust transaction filter
All checks were successful
check / check (push) Successful in 18s
The dust filter was hiding contract interactions (approve, transfer,
etc.) because they have 0 ETH value, which falls below the dust
threshold. Contract calls with 0 ETH are normal — only plain ETH
transfers should be checked against the dust threshold.

Also captures is_contract and method from Blockscout's transaction
response for future use in transaction display.
2026-02-27 12:52:06 +07:00
54e6f6c180 Show tx status screens after dApp transaction approval
All checks were successful
check / check (push) Successful in 17s
Previously the approval popup closed immediately after the user
entered their password, giving zero feedback about whether the
transaction was broadcast or confirmed. Now:

1. Background sends the broadcast result back to the popup via
   sendResponse callback (txHash or error)
2. Popup shows wait-tx screen on success (with polling timer)
   or error-tx screen on failure
3. Wait-tx polls for confirmation and transitions to success-tx
4. Done button closes the approval window

txStatus.init() moved before the approval early-return so the
wait/success/error views are wired up in the approval popup.
Done buttons detect the approval context and call window.close()
instead of navigating to address detail.
2026-02-27 12:50:24 +07:00
1ebc206201 Replace old 150-token list with 511-token tokenList.js
All checks were successful
check / check (push) Successful in 14s
Delete src/shared/tokens.js and migrate all consumers to
src/shared/tokenList.js which has 511 tokens (vs ~150) sourced
from CoinGecko with on-chain verified decimals.

- prices.js: getTopTokenPrices now from tokenList
- transactions.js: KNOWN_SYMBOLS now from tokenList (3.4x more
  symbols for spoof detection)
- send.js: KNOWN_SYMBOLS for token dropdown filtering
- approval.js: uses pre-built TOKEN_BY_ADDRESS map instead of
  constructing its own from TOKENS array
- addToken.js: uses getTopTokens(25) for quick-pick buttons
  (only top 25 shown, not all 511)
2026-02-27 12:39:41 +07:00
e7711274b3 Add tokenList.js with 511 ERC-20 tokens ranked by market cap
All checks were successful
check / check (push) Successful in 13s
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.
2026-02-27 12:37:01 +07:00
a9935eca8d Decode ERC-20 calldata in transaction approval popup
All checks were successful
check / check (push) Successful in 15s
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.
2026-02-27 12:33:09 +07:00
d29273114b Fix ERC-20 transfers showing as 0 ETH due to dedup bug
All checks were successful
check / check (push) Successful in 14s
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.
2026-02-27 12:29:15 +07:00
2467dfd09c Centralize view state into app ctx with viewData persistence
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 12:16:33 +07:00
034253077c Persist navigation state across popup close/reopen
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 12:12:07 +07:00
75cbbea035 Add user-facing documentation in docs/README.md
All checks were successful
check / check (push) Successful in 15s
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.
2026-02-27 12:08:43 +07:00
6c3cc0c516 Update README Screen Map with all views and state transitions
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 12:07:11 +07:00
d229000258 Add dedicated wait/success/error screens for transaction status
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.
2026-02-27 12:06:32 +07:00
e58f113cda Fix display consistency across all views
All checks were successful
check / check (push) Successful in 18s
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.
2026-02-27 12:01:34 +07:00
a43e8f20ea Show blockies on confirm page, put USD values inline in parentheses
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:58:04 +07:00
b85eac1e75 Enhance confirm transaction page with full verification details
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:42:42 +07:00
01201d54b2 Fix send balance display when sending from address-token view
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:39:50 +07:00
fbb0def267 Replace send token dropdown with static display when token is locked
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:38:42 +07:00
a1b181a471 Move ERC-20 warning from address-token view to receive/QR view
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:37:18 +07:00
21fe854fa4 Add address-token detail view for per-token transaction filtering
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-27 11:26:59 +07:00
a5b2470dba Implement eth_sendTransaction for dApp-initiated transactions
All checks were successful
check / check (push) Successful in 17s
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.
2026-02-26 18:39:09 +07:00
c131b89732 Fix spacing inconsistencies on home screen
All checks were successful
check / check (push) Successful in 16s
- 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
2026-02-26 17:11:27 +07:00
44a078eaac Add visual spacer between recent transactions and add wallet link
Some checks are pending
check / check (push) Waiting to run
2026-02-26 17:02:39 +07:00
59eb02a022 Darker section header background to visually delimit sections
All checks were successful
check / check (push) Successful in 15s
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.
2026-02-26 16:53:10 +07:00
24f04e509a Use wallet name in titles, replace hr dividers with grey stripe headers
All checks were successful
check / check (push) Successful in 12s
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.
2026-02-26 16:49:52 +07:00