// AutistMask popup entry point. // Loads state, initializes views, triggers first render. const { state, saveState, loadState } = require("../shared/state"); const { setRuntimeDebug } = require("../shared/log"); const { refreshPrices } = require("../shared/prices"); const { refreshBalances } = require("../shared/balances"); const { $, showView, updateDebugBanner, setBackRenderer, pushCurrentView, goBack, } = require("./views/helpers"); const { applyTheme } = require("./theme"); // Renders a view the popup lands on without having navigated to it forward: // on restore here, and on Back. Only the views that can be fully re-rendered // from persisted state (RESTORABLE_VIEWS, src/popup/restorableViews.js) go // through it; anything else falls back to the nearest restorable parent. const { renderView, makeBackRenderer } = require("./viewRouter"); const home = require("./views/home"); const welcome = require("./views/welcome"); const addWallet = require("./views/addWallet"); const addressDetail = require("./views/addressDetail"); const addressToken = require("./views/addressToken"); const send = require("./views/send"); const confirmTx = require("./views/confirmTx"); const txStatus = require("./views/txStatus"); const transactionDetail = require("./views/transactionDetail"); const receive = require("./views/receive"); const addToken = require("./views/addToken"); const settings = require("./views/settings"); const settingsAddToken = require("./views/settingsAddToken"); const deleteAddress = require("./views/deleteAddress"); const approval = require("./views/approval"); function renderWalletList() { home.render(ctx); } let refreshInFlight = false; async function doRefreshAndRender() { if (refreshInFlight) return; refreshInFlight = true; try { await Promise.all([ refreshPrices(), refreshBalances( state.wallets, state.rpcUrl, state.blockscoutUrl, state.trackedTokens, ), ]); state.lastBalanceRefresh = Date.now(); await saveState(); renderWalletList(); } finally { refreshInFlight = false; } } const ctx = { renderWalletList, doRefreshAndRender, showAddWalletView: () => { pushCurrentView(); addWallet.show(); }, showAddressDetail: () => { pushCurrentView(); addressDetail.show(); }, showAddressToken: () => { pushCurrentView(); addressToken.show(); }, showAddTokenView: () => { pushCurrentView(); addToken.show(); }, showConfirmTx: (txInfo) => { pushCurrentView(); confirmTx.show(txInfo); }, showReceive: () => { pushCurrentView(); receive.show(); }, showTransactionDetail: (tx) => { pushCurrentView(); transactionDetail.show(tx); }, showSettingsView: () => { pushCurrentView(); settings.show(); }, showSettingsAddTokenView: () => { pushCurrentView(); settingsAddToken.show(); }, showDeleteAddress: (walletIdx, addrIdx) => { pushCurrentView(); deleteAddress.show(walletIdx, addrIdx); }, }; // The view modules the router renders through, keyed as it expects them. const viewModules = { main: { show: () => fallbackView() }, addressDetail, addressToken, receive, settings, settingsAddToken, confirmTx, transactionDetail, txStatus, }; function restoreView() { if (!renderView(state.currentView, state, viewModules)) { fallbackView(); } } function fallbackView() { renderWalletList(); showView("main"); } async function init() { await loadState(); applyTheme(state.theme); // Sync runtime debug flag from persisted state before first render setRuntimeDebug(state.debugMode); // Create the debug/testnet banner if needed (uses runtime debug state) updateDebugBanner(); // Auto-default active address if ( state.activeAddress === null && state.wallets.length > 0 && state.wallets[0].addresses.length > 0 ) { state.activeAddress = state.wallets[0].addresses[0].address; await saveState(); } // Always init approval and txStatus — they may run in the approval popup window approval.init(ctx); txStatus.init(ctx); // Check for approval mode const params = new URLSearchParams(window.location.search); const approvalId = params.get("approval"); if (approvalId) { approval.show(approvalId); showView("approve-site"); return; } $("btn-settings").addEventListener("click", () => { if ( !document .getElementById("view-settings") .classList.contains("hidden") ) { goBack(); return; } pushCurrentView(); settings.show(); }); setBackRenderer(makeBackRenderer(state, viewModules)); welcome.init(ctx); addWallet.init(ctx); home.init(ctx); addressDetail.init(ctx); addressToken.init(ctx); send.init(ctx); confirmTx.init(ctx); transactionDetail.init(ctx); receive.init(ctx); addToken.init(ctx); settings.init(ctx); settingsAddToken.init(ctx); deleteAddress.init(ctx); if (!state.hasWallet) { showView("welcome"); } else { renderWalletList(); restoreView(); doRefreshAndRender(); setInterval(doRefreshAndRender, 10000); } } document.addEventListener("DOMContentLoaded", init);