71 lines
2.5 KiB
JavaScript
71 lines
2.5 KiB
JavaScript
// Wallet deletion state transition, kept out of the view so the selection
|
|
// and broadcast rules are testable without a DOM.
|
|
|
|
// Remove wallet `walletIdx` from `state` and repair the derived state.
|
|
//
|
|
// Rules:
|
|
// - `hasWallet` tracks whether any wallet remains.
|
|
// - Site permissions are dropped for every address of the deleted wallet.
|
|
// - `selectedWallet` follows the splice: it is decremented when a wallet
|
|
// before it was removed, and falls back to the first remaining wallet's
|
|
// first address only when the selection itself was deleted.
|
|
// - `activeAddress` is only moved when it belonged to the deleted wallet;
|
|
// the fallback is the first remaining wallet's first address, or null
|
|
// when no wallet remains.
|
|
//
|
|
// Returns whether `activeAddress` changed, so the caller can broadcast it.
|
|
function removeWalletFromState(state, walletIdx) {
|
|
const wallet = state.wallets[walletIdx];
|
|
const addresses = (wallet.addresses || []).map((a) => a.address);
|
|
const previousActive = state.activeAddress;
|
|
const activeWasDeleted =
|
|
previousActive !== null &&
|
|
previousActive !== undefined &&
|
|
addresses.some(
|
|
(a) => a.toLowerCase() === String(previousActive).toLowerCase(),
|
|
);
|
|
|
|
state.wallets.splice(walletIdx, 1);
|
|
|
|
for (const addr of addresses) {
|
|
delete state.allowedSites[addr];
|
|
delete state.deniedSites[addr];
|
|
}
|
|
|
|
state.hasWallet = state.wallets.length > 0;
|
|
|
|
const fallbackAddress = state.hasWallet
|
|
? state.wallets[0].addresses[0]?.address || null
|
|
: null;
|
|
|
|
if (!state.hasWallet) {
|
|
state.selectedWallet = null;
|
|
state.selectedAddress = null;
|
|
} else if (state.selectedWallet === walletIdx) {
|
|
state.selectedWallet = 0;
|
|
state.selectedAddress = 0;
|
|
} else if (
|
|
typeof state.selectedWallet === "number" &&
|
|
state.selectedWallet > walletIdx
|
|
) {
|
|
state.selectedWallet -= 1;
|
|
}
|
|
|
|
if (activeWasDeleted || !state.hasWallet) {
|
|
state.activeAddress = fallbackAddress;
|
|
}
|
|
|
|
return { activeAddressChanged: state.activeAddress !== previousActive };
|
|
}
|
|
|
|
// Tell the background the active address changed, so it re-emits
|
|
// accountsChanged to connected sites. Same call shape as the address
|
|
// switch in the home view.
|
|
function broadcastActiveChanged() {
|
|
const runtime =
|
|
typeof browser !== "undefined" ? browser.runtime : chrome.runtime;
|
|
runtime.sendMessage({ type: "AUTISTMASK_ACTIVE_CHANGED" });
|
|
}
|
|
|
|
module.exports = { removeWalletFromState, broadcastActiveChanged };
|