A network switch 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, as endpoints are kept; the background's switch uses the same function. The two add-token screens offer their common-token picks on Ethereum Mainnet only. After a switch in Settings, Back renders the screen it lands on again, and the stack is cut at the first screen that cannot be rendered from saved state, or at AddressToken for any token but the native one; the cut stack is saved with the switch. ConfirmTx drawn again keeps the network it was reviewed on. A contract lookup that answers after a switch adds nothing. Model: opus-5-5
80 lines
3.5 KiB
JavaScript
80 lines
3.5 KiB
JavaScript
// The field mutations a chain switch performs, applied to a state record
|
|
// handed in rather than to the module-level `state` singleton.
|
|
//
|
|
// Split out of chainSwitch.js so the background can perform a chain switch
|
|
// without the singleton being reachable from its bundle at all. The popup
|
|
// still goes through onChainSwitch() (chainSwitch.js), which applies this to
|
|
// the singleton and saves; the background applies it to the detached record of
|
|
// its own read-modify-write (src/background/state.js).
|
|
//
|
|
// Everything here is synchronous and touches nothing but the object it is
|
|
// given: no storage, no caches, no imports beyond the network table. That is
|
|
// what makes it usable on a record that has been read fresh from storage
|
|
// microseconds earlier and is about to be written back.
|
|
|
|
const { networkById } = require("./networks");
|
|
|
|
// Switch `s` to `newNetworkId` and reset every piece of chain-specific state
|
|
// it carries. Returns the network configuration object for the new chain.
|
|
function applyChainSwitchFields(s, newNetworkId) {
|
|
const net = networkById(newNetworkId);
|
|
|
|
// --- core identity ---
|
|
// Endpoints are remembered per network rather than reset to the
|
|
// defaults, because a user who points the wallet at their own node has
|
|
// no way to get that URL back once it is gone: overwriting it moved
|
|
// every address and every transaction onto a third-party endpoint
|
|
// silently and permanently.
|
|
//
|
|
// s.rpcUrl / s.blockscoutUrl stay the live endpoints of the active
|
|
// network, so nothing that reads them changes. The invariant is that for
|
|
// the ACTIVE network those two fields are authoritative and the map entry
|
|
// may be stale (Settings writes the fields directly); for every other
|
|
// network the map is authoritative. Snapshotting the outgoing network
|
|
// here, before the switch, is what reconciles them.
|
|
if (!s.networkEndpoints) s.networkEndpoints = {};
|
|
s.networkEndpoints[s.networkId] = {
|
|
rpcUrl: s.rpcUrl,
|
|
blockscoutUrl: s.blockscoutUrl,
|
|
};
|
|
const remembered = s.networkEndpoints[net.id] || {};
|
|
|
|
// Tracked tokens are kept per network the same way, because a contract
|
|
// address names a token on one network only. s.trackedTokens stays the
|
|
// active network's list, so nothing that reads it changes: the outgoing
|
|
// list is put away under its network, and the incoming network's list, or
|
|
// an empty one, takes its place.
|
|
if (!s.networkTrackedTokens) s.networkTrackedTokens = {};
|
|
s.networkTrackedTokens[s.networkId] = s.trackedTokens;
|
|
s.trackedTokens = s.networkTrackedTokens[net.id] || [];
|
|
|
|
s.networkId = net.id;
|
|
s.rpcUrl = remembered.rpcUrl || net.defaultRpcUrl;
|
|
s.blockscoutUrl = remembered.blockscoutUrl || net.defaultBlockscoutUrl;
|
|
|
|
// --- balance / refresh state ---
|
|
// Reset last-refresh timestamp so the next polling cycle
|
|
// triggers an immediate balance refresh on the new chain.
|
|
s.lastBalanceRefresh = 0;
|
|
|
|
// Clear per-address balances and token balances so stale data
|
|
// from the previous chain is never displayed while the first
|
|
// refresh on the new chain is in flight.
|
|
for (const wallet of s.wallets || []) {
|
|
for (const addr of wallet.addresses || []) {
|
|
addr.balance = "0";
|
|
addr.tokenBalances = [];
|
|
}
|
|
}
|
|
|
|
// --- chain-specific caches ---
|
|
// Token holder counts and fraud contract lists are
|
|
// chain-specific and must not carry over.
|
|
s.tokenHolderCache = {};
|
|
s.fraudContracts = [];
|
|
|
|
return net;
|
|
}
|
|
|
|
module.exports = { applyChainSwitchFields };
|