Refactor popup into shared modules, wire up real ERC-20 tokens
All checks were successful
check / check (push) Successful in 13s

Split popup/index.js (784 lines) into focused modules:
- shared/state.js: state management, storage persistence
- shared/wallet.js: mnemonic gen, HD derivation, signing
- shared/prices.js: price cache (5min TTL), USD formatting,
  value aggregation (address → wallet → total)
- shared/balances.js: ETH + ERC-20 balance cache (60s TTL),
  ENS lookup, token contract metadata lookup
- shared/vault.js: unchanged (libsodium encryption)
- shared/tokens.js: unchanged (token list + CoinDesk client)
- popup/index.js: view switching and event wiring only

Token tracking is now app-wide: trackedTokens stored in state,
balances fetched for all tracked tokens across all addresses.
Add Token now calls the real contract to read name/symbol/decimals.
Total portfolio value shown in 2x type on Home screen.
This commit is contained in:
2026-02-25 18:48:44 +07:00
parent 2a8c051377
commit f50a2a0389
5 changed files with 494 additions and 333 deletions

49
src/shared/state.js Normal file
View File

@@ -0,0 +1,49 @@
// State management and extension storage persistence.
const storageApi =
typeof browser !== "undefined"
? browser.storage.local
: chrome.storage.local;
const DEFAULT_STATE = {
hasWallet: false,
wallets: [],
trackedTokens: [],
rpcUrl: "https://eth.llamarpc.com",
};
const state = {
...DEFAULT_STATE,
selectedWallet: null,
selectedAddress: null,
};
async function saveState() {
const persisted = {
hasWallet: state.hasWallet,
wallets: state.wallets,
trackedTokens: state.trackedTokens,
rpcUrl: state.rpcUrl,
};
await storageApi.set({ autistmask: persisted });
}
async function loadState() {
const result = await storageApi.get("autistmask");
if (result.autistmask) {
const saved = result.autistmask;
state.hasWallet = saved.hasWallet;
state.wallets = saved.wallets || [];
state.trackedTokens = saved.trackedTokens || [];
state.rpcUrl = saved.rpcUrl || DEFAULT_STATE.rpcUrl;
}
}
function currentAddress() {
if (state.selectedWallet === null || state.selectedAddress === null) {
return null;
}
return state.wallets[state.selectedWallet].addresses[state.selectedAddress];
}
module.exports = { state, saveState, loadState, currentAddress };