Persist wallet state to extension storage
All checks were successful
check / check (push) Successful in 12s
All checks were successful
check / check (push) Successful in 12s
State (wallets, RPC URL, setup flag) is saved to browser.storage.local / chrome.storage.local after every mutation and loaded on popup open. In DEBUG mode, the lock screen is skipped since encryption is not yet implemented.
This commit is contained in:
@@ -28,21 +28,52 @@ function showView(name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- mock state (will be replaced by background messaging) --
|
// Browser-agnostic storage API
|
||||||
|
const storage =
|
||||||
|
typeof browser !== "undefined"
|
||||||
|
? browser.storage.local
|
||||||
|
: chrome.storage.local;
|
||||||
|
|
||||||
// A wallet is either { type: "hd", name, mnemonic, addresses: [...] }
|
// A wallet is either { type: "hd", name, mnemonic, addresses: [...] }
|
||||||
// or { type: "key", name, privateKey, addresses: [single] }.
|
// or { type: "key", name, privateKey, addresses: [single] }.
|
||||||
// Each address is { address, balance, tokens: [...] }.
|
// Each address is { address, balance, tokens: [...] }.
|
||||||
const state = {
|
const DEFAULT_STATE = {
|
||||||
locked: true,
|
|
||||||
hasWallet: false,
|
hasWallet: false,
|
||||||
password: null,
|
|
||||||
wallets: [],
|
wallets: [],
|
||||||
selectedWallet: null,
|
|
||||||
selectedAddress: null,
|
|
||||||
rpcUrl: "https://eth.llamarpc.com",
|
rpcUrl: "https://eth.llamarpc.com",
|
||||||
isFirstSetup: true,
|
isFirstSetup: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Transient state (not persisted)
|
||||||
|
const state = {
|
||||||
|
...DEFAULT_STATE,
|
||||||
|
locked: true,
|
||||||
|
password: null,
|
||||||
|
selectedWallet: null,
|
||||||
|
selectedAddress: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function saveState() {
|
||||||
|
const persisted = {
|
||||||
|
hasWallet: state.hasWallet,
|
||||||
|
wallets: state.wallets,
|
||||||
|
rpcUrl: state.rpcUrl,
|
||||||
|
isFirstSetup: state.isFirstSetup,
|
||||||
|
};
|
||||||
|
await storage.set({ autistmask: persisted });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadState() {
|
||||||
|
const result = await storage.get("autistmask");
|
||||||
|
if (result.autistmask) {
|
||||||
|
const saved = result.autistmask;
|
||||||
|
state.hasWallet = saved.hasWallet;
|
||||||
|
state.wallets = saved.wallets || [];
|
||||||
|
state.rpcUrl = saved.rpcUrl || DEFAULT_STATE.rpcUrl;
|
||||||
|
state.isFirstSetup = saved.isFirstSetup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -- helpers --
|
// -- helpers --
|
||||||
function $(id) {
|
function $(id) {
|
||||||
return document.getElementById(id);
|
return document.getElementById(id);
|
||||||
@@ -121,11 +152,12 @@ function renderWalletList() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
container.querySelectorAll(".btn-add-address").forEach((btn) => {
|
container.querySelectorAll(".btn-add-address").forEach((btn) => {
|
||||||
btn.addEventListener("click", (e) => {
|
btn.addEventListener("click", async (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const wi = parseInt(btn.dataset.wallet, 10);
|
const wi = parseInt(btn.dataset.wallet, 10);
|
||||||
// TODO: derive next address from seed via background
|
// TODO: derive next address from seed via background
|
||||||
state.wallets[wi].addresses.push(makeStubAddress());
|
state.wallets[wi].addresses.push(makeStubAddress());
|
||||||
|
await saveState();
|
||||||
renderWalletList();
|
renderWalletList();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -180,10 +212,11 @@ function currentAddress() {
|
|||||||
return state.wallets[state.selectedWallet].addresses[state.selectedAddress];
|
return state.wallets[state.selectedWallet].addresses[state.selectedAddress];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWalletAndGoToMain(wallet) {
|
async function addWalletAndGoToMain(wallet) {
|
||||||
state.wallets.push(wallet);
|
state.wallets.push(wallet);
|
||||||
state.hasWallet = true;
|
state.hasWallet = true;
|
||||||
state.isFirstSetup = false;
|
state.isFirstSetup = false;
|
||||||
|
await saveState();
|
||||||
renderWalletList();
|
renderWalletList();
|
||||||
showView("main");
|
showView("main");
|
||||||
}
|
}
|
||||||
@@ -243,7 +276,7 @@ function backFromWalletAdd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -- init --
|
// -- init --
|
||||||
function init() {
|
async function init() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
const banner = document.createElement("div");
|
const banner = document.createElement("div");
|
||||||
banner.textContent = "DEBUG / INSECURE";
|
banner.textContent = "DEBUG / INSECURE";
|
||||||
@@ -252,6 +285,13 @@ function init() {
|
|||||||
document.body.prepend(banner);
|
document.body.prepend(banner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await loadState();
|
||||||
|
|
||||||
|
// In DEBUG mode, skip the lock screen (no encryption yet)
|
||||||
|
if (DEBUG && state.hasWallet) {
|
||||||
|
state.locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!state.hasWallet) {
|
if (!state.hasWallet) {
|
||||||
showView("welcome");
|
showView("welcome");
|
||||||
} else if (state.locked) {
|
} else if (state.locked) {
|
||||||
@@ -443,7 +483,7 @@ function init() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// -- Add Token --
|
// -- Add Token --
|
||||||
$("btn-add-token-confirm").addEventListener("click", () => {
|
$("btn-add-token-confirm").addEventListener("click", async () => {
|
||||||
const contractAddr = $("add-token-address").value.trim();
|
const contractAddr = $("add-token-address").value.trim();
|
||||||
if (!contractAddr || !contractAddr.startsWith("0x")) {
|
if (!contractAddr || !contractAddr.startsWith("0x")) {
|
||||||
showError(
|
showError(
|
||||||
@@ -462,6 +502,7 @@ function init() {
|
|||||||
decimals: 18,
|
decimals: 18,
|
||||||
balance: "0",
|
balance: "0",
|
||||||
});
|
});
|
||||||
|
await saveState();
|
||||||
}
|
}
|
||||||
showAddressDetail();
|
showAddressDetail();
|
||||||
});
|
});
|
||||||
@@ -471,9 +512,9 @@ function init() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// -- Settings --
|
// -- Settings --
|
||||||
$("btn-save-rpc").addEventListener("click", () => {
|
$("btn-save-rpc").addEventListener("click", async () => {
|
||||||
state.rpcUrl = $("settings-rpc").value.trim();
|
state.rpcUrl = $("settings-rpc").value.trim();
|
||||||
// TODO: persist via background
|
await saveState();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("btn-settings-back").addEventListener("click", () => {
|
$("btn-settings-back").addEventListener("click", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user