const { $, showView, showFlash, escapeHtml } = require("./helpers"); const { state, saveState } = require("../../shared/state"); const { ETHEREUM_MAINNET_CHAIN_ID } = require("../../shared/constants"); const { log, debugFetch } = require("../../shared/log"); const runtime = typeof browser !== "undefined" ? browser.runtime : chrome.runtime; function renderSiteList(containerId, siteMap, stateKey) { const container = $(containerId); const hostnames = [...new Set(Object.values(siteMap).flat())]; if (hostnames.length === 0) { container.innerHTML = '

None

'; return; } let html = ""; hostnames.forEach((hostname) => { html += `
`; html += `${hostname}`; html += ``; html += `
`; }); container.innerHTML = html; container.querySelectorAll(".btn-remove-site").forEach((btn) => { btn.addEventListener("click", async () => { const key = btn.dataset.key; const host = btn.dataset.hostname; for (const addr of Object.keys(state[key])) { state[key][addr] = state[key][addr].filter((h) => h !== host); if (state[key][addr].length === 0) { delete state[key][addr]; } } await saveState(); runtime.sendMessage({ type: "AUTISTMASK_REMOVE_SITE" }); renderSiteList(containerId, state[key], key); }); }); } function renderTrackedTokens() { const container = $("settings-tracked-tokens"); if (state.trackedTokens.length === 0) { container.innerHTML = '

None

'; return; } let html = ""; state.trackedTokens.forEach((token, idx) => { const label = token.name ? escapeHtml(token.name) + " (" + escapeHtml(token.symbol) + ")" : escapeHtml(token.symbol); html += `
`; html += `${label}`; html += ``; html += `
`; }); container.innerHTML = html; container.querySelectorAll(".btn-remove-token").forEach((btn) => { btn.addEventListener("click", async () => { const idx = parseInt(btn.dataset.idx, 10); state.trackedTokens.splice(idx, 1); await saveState(); renderTrackedTokens(); }); }); } function show() { $("settings-rpc").value = state.rpcUrl; $("settings-blockscout").value = state.blockscoutUrl; renderTrackedTokens(); renderSiteLists(); showView("settings"); } function renderSiteLists() { renderSiteList( "settings-allowed-sites", state.allowedSites, "allowedSites", ); renderSiteList("settings-denied-sites", state.deniedSites, "deniedSites"); } function init(ctx) { $("btn-save-rpc").addEventListener("click", async () => { const url = $("settings-rpc").value.trim(); if (!url) { showFlash("Please enter an RPC URL."); return; } showFlash("Testing endpoint..."); try { const resp = await debugFetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_chainId", params: [], }), }); const json = await resp.json(); if (json.error) { log.errorf("RPC validation error:", json.error); showFlash("Endpoint returned error: " + json.error.message); return; } if (json.result !== ETHEREUM_MAINNET_CHAIN_ID) { showFlash( "Wrong network (expected mainnet, got chain " + json.result + ").", ); return; } } catch (e) { log.errorf("RPC validation fetch failed:", e.message); showFlash("Could not reach endpoint."); return; } state.rpcUrl = url; await saveState(); showFlash("Saved."); }); $("btn-save-blockscout").addEventListener("click", async () => { const url = $("settings-blockscout").value.trim(); if (!url) { showFlash("Please enter a Blockscout API URL."); return; } showFlash("Testing endpoint..."); try { const resp = await debugFetch(url + "/stats"); if (!resp.ok) { showFlash("Endpoint returned HTTP " + resp.status + "."); return; } } catch (e) { log.errorf("Blockscout validation failed:", e.message); showFlash("Could not reach endpoint."); return; } state.blockscoutUrl = url; await saveState(); showFlash("Saved."); }); $("settings-show-zero-balances").checked = state.showZeroBalanceTokens; $("settings-show-zero-balances").addEventListener("change", async () => { state.showZeroBalanceTokens = $("settings-show-zero-balances").checked; await saveState(); }); $("settings-hide-low-holders").checked = state.hideLowHolderTokens; $("settings-hide-low-holders").addEventListener("change", async () => { state.hideLowHolderTokens = $("settings-hide-low-holders").checked; await saveState(); }); $("settings-hide-fraud-contracts").checked = state.hideFraudContracts; $("settings-hide-fraud-contracts").addEventListener("change", async () => { state.hideFraudContracts = $("settings-hide-fraud-contracts").checked; await saveState(); }); $("settings-hide-dust").checked = state.hideDustTransactions; $("settings-hide-dust").addEventListener("change", async () => { state.hideDustTransactions = $("settings-hide-dust").checked; await saveState(); }); $("settings-dust-threshold").value = state.dustThresholdGwei; $("settings-dust-threshold").addEventListener("change", async () => { const val = parseInt($("settings-dust-threshold").value, 10); if (!isNaN(val) && val >= 0) { state.dustThresholdGwei = val; await saveState(); } }); $("btn-main-add-wallet").addEventListener("click", ctx.showAddWalletView); $("btn-settings-add-token").addEventListener( "click", ctx.showSettingsAddTokenView, ); $("btn-settings-back").addEventListener("click", () => { ctx.renderWalletList(); showView("main"); }); } module.exports = { init, show, renderSiteLists };