Token auto-discovery, tx history, balance polling, EIP-6963, UI overhaul
All checks were successful
check / check (push) Successful in 14s

Major changes:
- Fetch token balances and tx history from Blockscout API (configurable)
- Remove manual token discovery (discoverTokens) in favor of Blockscout
- HD address gap scanning on mnemonic import
- Duplicate mnemonic detection on wallet add
- EIP-6963 multi-wallet discovery + selectedAddress updates in inpage
- Two-tier balance refresh: 10s while popup open, 60s background
- Fix $0.00 flash before prices load (return null when no prices)
- No-layout-shift: min-height on total value element
- Aligned balance columns (42ch address width, consistent USD column)
- All errors use flash messages instead of off-screen error divs
- Settings gear in global title bar, add-wallet moved to settings pane
- Settings wells with light grey background, configurable Blockscout URL
- Consistent "< Back" buttons top-left on all views
- Address titles (Address 1.1, 1.2, etc.) on main and detail views
- Send view shows current balance of selected asset
- Clickable affordance policy added to README
- Shortened mnemonic backup warning
- Fix broken background script constant imports
This commit is contained in:
2026-02-26 02:13:39 +07:00
parent 2b2137716c
commit 3bd2b58543
27 changed files with 978 additions and 420 deletions

View File

@@ -2,8 +2,12 @@
// Handles EIP-1193 RPC requests from content scripts and proxies
// non-sensitive calls to the configured Ethereum JSON-RPC endpoint.
const CHAIN_ID = "0x1";
const DEFAULT_RPC = "https://eth.llamarpc.com";
const {
ETHEREUM_MAINNET_CHAIN_ID,
DEFAULT_RPC_URL,
} = require("../shared/constants");
const { state, loadState, saveState } = require("../shared/state");
const { refreshBalances } = require("../shared/balances");
const storageApi =
typeof browser !== "undefined"
@@ -17,7 +21,7 @@ const connectedSites = {};
async function getState() {
const result = await storageApi.get("autistmask");
return result.autistmask || { wallets: [], rpcUrl: DEFAULT_RPC };
return result.autistmask || { wallets: [], rpcUrl: DEFAULT_RPC_URL };
}
async function getAccounts() {
@@ -33,7 +37,7 @@ async function getAccounts() {
async function getRpcUrl() {
const state = await getState();
return state.rpcUrl || DEFAULT_RPC;
return state.rpcUrl || DEFAULT_RPC_URL;
}
// Proxy an RPC call to the Ethereum node
@@ -94,7 +98,7 @@ async function handleRpc(method, params, origin) {
}
if (method === "eth_chainId") {
return { result: CHAIN_ID };
return { result: ETHEREUM_MAINNET_CHAIN_ID };
}
if (method === "net_version") {
@@ -103,7 +107,7 @@ async function handleRpc(method, params, origin) {
if (method === "wallet_switchEthereumChain") {
const chainId = params?.[0]?.chainId;
if (chainId === CHAIN_ID) {
if (chainId === ETHEREUM_MAINNET_CHAIN_ID) {
return { result: null };
}
return {
@@ -205,6 +209,24 @@ async function handleRpc(method, params, origin) {
return { error: { message: "Unsupported method: " + method } };
}
// Background balance refresh: every 60 seconds when the popup isn't open.
// When the popup IS open, its 10-second interval keeps lastBalanceRefresh
// fresh, so this naturally skips.
const BACKGROUND_REFRESH_INTERVAL = 60000;
async function backgroundRefresh() {
await loadState();
const now = Date.now();
if (now - (state.lastBalanceRefresh || 0) < BACKGROUND_REFRESH_INTERVAL)
return;
if (state.wallets.length === 0) return;
await refreshBalances(state.wallets, state.rpcUrl, state.blockscoutUrl);
state.lastBalanceRefresh = now;
await saveState();
}
setInterval(backgroundRefresh, BACKGROUND_REFRESH_INTERVAL);
// Listen for messages from content scripts
runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type !== "AUTISTMASK_RPC") return;