Files
AutistMask/src/shared/state.js
user cc69c1b2a0
All checks were successful
check / check (push) Successful in 26s
feat: add About well to settings with build info and debug easter egg
Add a new well at the bottom of the settings view that displays:
- License (GPL-3.0)
- Author (sneak)
- Version (from package.json)
- Build date (injected at build time)
- Git commit short hash (linked to Gitea commit URL)

Build-time injection: build.js now reads the git commit hash and version
from package.json, injecting them via esbuild define constants. The
Dockerfile and Makefile pass commit hashes as build args so the info is
available even when .git is excluded from the Docker context.

Easter egg: clicking the version number 10 times reveals a hidden debug
well below the About well, containing a toggle for debug mode. The debug
mode flag is persisted in state and enables verbose console logging via
the runtime debug flag in the logger.

closes #144
2026-03-01 11:33:44 -08:00

157 lines
5.3 KiB
JavaScript

// State management and extension storage persistence.
const { DEFAULT_RPC_URL, DEFAULT_BLOCKSCOUT_URL } = require("./constants");
const { networkById } = require("./networks");
const storageApi =
typeof browser !== "undefined"
? browser.storage.local
: chrome.storage.local;
const DEFAULT_STATE = {
hasWallet: false,
wallets: [],
trackedTokens: [],
networkId: "mainnet",
rpcUrl: DEFAULT_RPC_URL,
blockscoutUrl: DEFAULT_BLOCKSCOUT_URL,
lastBalanceRefresh: 0,
activeAddress: null,
allowedSites: {},
deniedSites: {},
rememberSiteChoice: true,
showZeroBalanceTokens: true,
hideLowHolderTokens: true,
hideFraudContracts: true,
hideDustTransactions: true,
dustThresholdGwei: 100000,
utcTimestamps: false,
fraudContracts: [],
tokenHolderCache: {},
theme: "system",
debugMode: false,
};
const state = {
...DEFAULT_STATE,
currentView: null,
selectedWallet: null,
selectedAddress: null,
selectedToken: null,
viewData: {},
};
// Return the network configuration for the currently selected network.
function currentNetwork() {
return networkById(state.networkId);
}
async function saveState() {
const persisted = {
hasWallet: state.hasWallet,
wallets: state.wallets,
trackedTokens: state.trackedTokens,
networkId: state.networkId,
rpcUrl: state.rpcUrl,
blockscoutUrl: state.blockscoutUrl,
lastBalanceRefresh: state.lastBalanceRefresh,
activeAddress: state.activeAddress,
allowedSites: state.allowedSites,
deniedSites: state.deniedSites,
rememberSiteChoice: state.rememberSiteChoice,
showZeroBalanceTokens: state.showZeroBalanceTokens,
hideLowHolderTokens: state.hideLowHolderTokens,
hideFraudContracts: state.hideFraudContracts,
hideDustTransactions: state.hideDustTransactions,
dustThresholdGwei: state.dustThresholdGwei,
utcTimestamps: state.utcTimestamps,
fraudContracts: state.fraudContracts,
tokenHolderCache: state.tokenHolderCache,
theme: state.theme,
debugMode: state.debugMode,
currentView: state.currentView,
selectedWallet: state.selectedWallet,
selectedAddress: state.selectedAddress,
selectedToken: state.selectedToken,
viewData: state.viewData,
};
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.networkId = saved.networkId || DEFAULT_STATE.networkId;
state.rpcUrl = saved.rpcUrl || DEFAULT_STATE.rpcUrl;
state.blockscoutUrl =
saved.blockscoutUrl || DEFAULT_STATE.blockscoutUrl;
state.lastBalanceRefresh = saved.lastBalanceRefresh || 0;
state.activeAddress = saved.activeAddress || null;
state.allowedSites =
saved.allowedSites && !Array.isArray(saved.allowedSites)
? saved.allowedSites
: {};
state.deniedSites =
saved.deniedSites && !Array.isArray(saved.deniedSites)
? saved.deniedSites
: {};
state.rememberSiteChoice =
saved.rememberSiteChoice !== undefined
? saved.rememberSiteChoice
: true;
state.showZeroBalanceTokens =
saved.showZeroBalanceTokens !== undefined
? saved.showZeroBalanceTokens
: true;
state.hideLowHolderTokens =
saved.hideLowHolderTokens !== undefined
? saved.hideLowHolderTokens
: true;
state.hideFraudContracts =
saved.hideFraudContracts !== undefined
? saved.hideFraudContracts
: true;
state.hideDustTransactions =
saved.hideDustTransactions !== undefined
? saved.hideDustTransactions
: true;
state.dustThresholdGwei =
saved.dustThresholdGwei !== undefined
? saved.dustThresholdGwei
: 100000;
state.utcTimestamps =
saved.utcTimestamps !== undefined ? saved.utcTimestamps : false;
state.fraudContracts = saved.fraudContracts || [];
state.tokenHolderCache = saved.tokenHolderCache || {};
state.theme = saved.theme || "system";
state.debugMode =
saved.debugMode !== undefined ? saved.debugMode : false;
state.currentView = saved.currentView || null;
state.selectedWallet =
saved.selectedWallet !== undefined ? saved.selectedWallet : null;
state.selectedAddress =
saved.selectedAddress !== undefined ? saved.selectedAddress : null;
state.selectedToken = saved.selectedToken || null;
state.viewData = saved.viewData || {};
}
}
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,
currentNetwork,
};