Compare commits
1
Commits
next
...
d9eec62994
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9eec62994 |
@@ -61,20 +61,31 @@ function clearPopupCaches() {
|
|||||||
// (https://git.eeqj.de/sneak/AutistMask/issues/653,
|
// (https://git.eeqj.de/sneak/AutistMask/issues/653,
|
||||||
// https://git.eeqj.de/sneak/AutistMask/issues/692).
|
// https://git.eeqj.de/sneak/AutistMask/issues/692).
|
||||||
//
|
//
|
||||||
|
// When the stored record is on another network, a switch saved elsewhere has
|
||||||
|
// not reached this page yet. This page first takes that switch with
|
||||||
|
// takeStoredNetwork() (state.js), as followStoredSettings() does. The switch to
|
||||||
|
// `newNetworkId` is then made from the stored record's network. So every
|
||||||
|
// network's list of tracked tokens in the stored record is kept
|
||||||
|
// (https://git.eeqj.de/sneak/AutistMask/issues/701). When the stored record is
|
||||||
|
// already on `newNetworkId`, the switch made from there only resets the
|
||||||
|
// balances and caches.
|
||||||
|
//
|
||||||
// Before the switch, `state` takes the tracked tokens that another page stored
|
// Before the switch, `state` takes the tracked tokens that another page stored
|
||||||
// since this page's last save (takeStoredTrackedTokens() in state.js). The
|
// since this page's last save (takeStoredTrackedTokens() in state.js). The
|
||||||
// switch then puts them away under the previous network, the network they were
|
// switch then puts them away under the previous network, the network they were
|
||||||
// added on. When the stored record is on another network, a switch saved
|
// added on.
|
||||||
// elsewhere has not reached this page yet. The stored record's tokens are then
|
|
||||||
// that network's, and none are taken.
|
|
||||||
async function onChainSwitch(newNetworkId) {
|
async function onChainSwitch(newNetworkId) {
|
||||||
const { state, saveState, takeStoredTrackedTokens } = require("./state");
|
const {
|
||||||
|
state,
|
||||||
|
saveState,
|
||||||
|
takeStoredNetwork,
|
||||||
|
takeStoredTrackedTokens,
|
||||||
|
} = require("./state");
|
||||||
let net = null;
|
let net = null;
|
||||||
await saveState((stored) => {
|
await saveState((stored) => {
|
||||||
if (state.networkId === newNetworkId) return false;
|
if (state.networkId === newNetworkId) return false;
|
||||||
if (stored.networkId === state.networkId) {
|
if (stored.networkId !== state.networkId) takeStoredNetwork(stored);
|
||||||
takeStoredTrackedTokens(stored);
|
takeStoredTrackedTokens(stored);
|
||||||
}
|
|
||||||
net = applyChainSwitchFields(state, newNetworkId);
|
net = applyChainSwitchFields(state, newNetworkId);
|
||||||
stored.lastBalanceRefresh = 0;
|
stored.lastBalanceRefresh = 0;
|
||||||
stored.fraudContracts = [];
|
stored.fraudContracts = [];
|
||||||
|
|||||||
+14
-5
@@ -527,6 +527,14 @@ async function saveStateOnce(beforeWrite) {
|
|||||||
merged[key] = current[key];
|
merged[key] = current[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// When the merged record names a network other than this page's, this page
|
||||||
|
// has not yet taken a switch saved elsewhere. This page's `trackedTokens`
|
||||||
|
// is then the list of the network that this page still has. So the merged
|
||||||
|
// record keeps the stored list
|
||||||
|
// (https://git.eeqj.de/sneak/AutistMask/issues/701).
|
||||||
|
if (merged.networkId !== current.networkId) {
|
||||||
|
merged.trackedTokens = fresh.trackedTokens;
|
||||||
|
}
|
||||||
merged.hasWallet = Boolean(merged.wallets && merged.wallets.length > 0);
|
merged.hasWallet = Boolean(merged.wallets && merged.wallets.length > 0);
|
||||||
// Stamped on every write, never merged or diffed: the record that goes to
|
// Stamped on every write, never merged or diffed: the record that goes to
|
||||||
// storage is in THIS build's shape whatever shape it was read in, which is
|
// storage is in THIS build's shape whatever shape it was read in, which is
|
||||||
@@ -608,11 +616,12 @@ function saveState(beforeWrite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Give this page the network switch held by `stored`, a record a save of this
|
// Give this page the network switch held by `stored`, a record a save of this
|
||||||
// page has just read (followStoredSettings() in src/popup/index.js calls this
|
// page has just read (followStoredSettings() in src/popup/index.js and
|
||||||
// from `beforeWrite`), in `state` and in `baseline` alike, as loadState() does
|
// onChainSwitch() in src/shared/chainSwitch.js call this from `beforeWrite`),
|
||||||
// with a whole record. The switch is then not this page's own change, even when
|
// in `state` and in `baseline` alike, as loadState() does with a whole
|
||||||
// that save fails to write: a later switch back to the previous network still
|
// record. The switch is then not this page's own change, even when that save
|
||||||
// differs from `baseline`, and is stored.
|
// fails to write: a later switch back to the previous network still differs
|
||||||
|
// from `baseline`, and is stored.
|
||||||
function takeStoredNetwork(stored) {
|
function takeStoredNetwork(stored) {
|
||||||
copyChainSwitchFields(rawState, stored);
|
copyChainSwitchFields(rawState, stored);
|
||||||
copyChainSwitchFields(baseline, structuredClone(stored));
|
copyChainSwitchFields(baseline, structuredClone(stored));
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ test("a token tracked on Sepolia when another page switched there is not tracked
|
|||||||
...boot.storage.read("autistmask"),
|
...boot.storage.read("autistmask"),
|
||||||
networkId: "sepolia",
|
networkId: "sepolia",
|
||||||
trackedTokens: [SEPOLIA_TOKEN],
|
trackedTokens: [SEPOLIA_TOKEN],
|
||||||
|
networkTrackedTokens: { mainnet: [] },
|
||||||
});
|
});
|
||||||
|
|
||||||
await chooseNetwork(boot, "sepolia");
|
await chooseNetwork(boot, "sepolia");
|
||||||
@@ -267,6 +268,62 @@ test("a token tracked on Sepolia when another page switched there is not tracked
|
|||||||
expect(stored.networkTrackedTokens.mainnet).toEqual([]);
|
expect(stored.networkTrackedTokens.mainnet).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Another popup page saves a switch to Sepolia, where TST is tracked. Before
|
||||||
|
// taking that switch, this page adds a token on Ethereum Mainnet. The add's
|
||||||
|
// save does not write this page's Ethereum Mainnet list as Sepolia's list.
|
||||||
|
test("a token added before this page takes another page's switch leaves Sepolia's tokens tracked", async () => {
|
||||||
|
const boot = await bootOnAddToken("mainnet", {
|
||||||
|
trackedTokens: [MAINNET_TOKEN],
|
||||||
|
networkTrackedTokens: { sepolia: [SEPOLIA_TOKEN] },
|
||||||
|
});
|
||||||
|
expect(boot.pageErrors).toEqual([]);
|
||||||
|
boot.storage.write("autistmask", {
|
||||||
|
...boot.storage.read("autistmask"),
|
||||||
|
networkId: "sepolia",
|
||||||
|
trackedTokens: [SEPOLIA_TOKEN],
|
||||||
|
networkTrackedTokens: {
|
||||||
|
mainnet: [MAINNET_TOKEN],
|
||||||
|
sepolia: [SEPOLIA_TOKEN],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { lookupTokenInfo } = require("../src/shared/balances");
|
||||||
|
lookupTokenInfo.mockResolvedValueOnce({
|
||||||
|
symbol: "NEW",
|
||||||
|
decimals: 18,
|
||||||
|
name: "New Token",
|
||||||
|
});
|
||||||
|
|
||||||
|
boot.node("settings-addtoken-address").value = NEW_TOKEN_ADDRESS;
|
||||||
|
await boot.click("btn-settings-addtoken-manual");
|
||||||
|
|
||||||
|
const stored = boot.storage.read("autistmask");
|
||||||
|
expect(stored.networkId).toBe("sepolia");
|
||||||
|
expect(stored.trackedTokens).toEqual([SEPOLIA_TOKEN]);
|
||||||
|
expect(stored.networkTrackedTokens.mainnet).toEqual([MAINNET_TOKEN]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Another popup page tracks DAI on Ethereum Mainnet and then saves a switch to
|
||||||
|
// Sepolia. That switch puts DAI away under Ethereum Mainnet. This page has not
|
||||||
|
// taken the switch yet. A switch to Sepolia in this page's Settings keeps DAI
|
||||||
|
// on Ethereum Mainnet's list.
|
||||||
|
test("a token another page tracked before its own switch stays tracked on Ethereum Mainnet", async () => {
|
||||||
|
const boot = await bootPopup(unversionedValidProfile());
|
||||||
|
expect(boot.pageErrors).toEqual([]);
|
||||||
|
await boot.click("btn-settings");
|
||||||
|
boot.storage.write("autistmask", {
|
||||||
|
...boot.storage.read("autistmask"),
|
||||||
|
networkId: "sepolia",
|
||||||
|
trackedTokens: [],
|
||||||
|
networkTrackedTokens: { mainnet: [MAINNET_TOKEN] },
|
||||||
|
});
|
||||||
|
|
||||||
|
await chooseNetwork(boot, "sepolia");
|
||||||
|
|
||||||
|
const stored = boot.storage.read("autistmask");
|
||||||
|
expect(stored.networkId).toBe("sepolia");
|
||||||
|
expect(stored.networkTrackedTokens.mainnet).toEqual([MAINNET_TOKEN]);
|
||||||
|
});
|
||||||
|
|
||||||
// Another popup page records a fraud contract on Ethereum Mainnet after this
|
// Another popup page records a fraud contract on Ethereum Mainnet after this
|
||||||
// page's last save. The switch to Sepolia drops that fraud contract, as the
|
// page's last save. The switch to Sepolia drops that fraud contract, as the
|
||||||
// switch drops this page's own.
|
// switch drops this page's own.
|
||||||
|
|||||||
Reference in New Issue
Block a user