fix: tracked tokens are kept per network, and bundled picks are offered on mainnet only (closes #523)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

A network switch now puts the outgoing network's tracked tokens away in a new
persisted field, networkTrackedTokens, and brings back the incoming network's
list, or an empty one, the way endpoints are already kept per network.
trackedTokens stays the active network's list, so its readers are unchanged,
and the background's switch keeps the lists too because it goes through the
same function. The two add-token screens show their common-token picks, which
come from the bundled list of mainnet contracts, on Ethereum Mainnet only;
adding by contract address works on every network. Settings redraws its
tracked-token list after a switch.

Model: opus-5-5
This commit is contained in:
2026-10-18 23:22:32 +00:00
parent fc042c3191
commit f9318bafec
11 changed files with 241 additions and 49 deletions
+24
View File
@@ -97,6 +97,7 @@ const {
normalizePersisted,
} = require("../src/shared/persistedState");
const { stateProblem } = require("../src/shared/stateSchema");
const { isKnownNetworkId } = require("../src/shared/networks");
const { RESTORABLE_VIEWS } = require("../src/shared/restorableViews");
const {
bootPopup,
@@ -193,6 +194,29 @@ const CONTRACT = [
floorOnly: [[1, 2], [null], [{}], [[TOKEN_ADDRESS]]],
holds: (v) => everyEntry(v, (t) => isRecord(t) && isText(t.address)),
},
{
field: "networkTrackedTokens",
kind: KIND.ENTRIES,
hostile: [42, "notarecord", { sepolia: "notalist" }],
floorOnly: [
[1, 2],
{ sepolia: [1, 2] },
{ mainnet: [null, {}, [TOKEN_ADDRESS]] },
{ notanetwork: [{ address: TOKEN_ADDRESS }] },
JSON.parse('{"__proto__":[{"address":"0xabc"}]}'),
],
// Each list is put straight back onto trackedTokens by
// applyChainSwitchFields() when its network becomes the active one, so
// it is floored the same way; a key that names no network is dropped.
holds: (v) =>
isRecord(v) &&
Object.getPrototypeOf(v) === Object.prototype &&
Object.keys(v).every(
(id) =>
isKnownNetworkId(id) &&
everyEntry(v[id], (t) => isRecord(t) && isText(t.address)),
),
},
{
field: "allowedSites",
kind: KIND.ENTRIES,