Two recurring jobs are scheduled with setInterval inside the Chrome MV3
service worker, which is terminated after roughly 30 seconds idle. Neither
survives:
src/background/index.js:614 — setInterval(backgroundRefresh, 60000), the
60-second balance refresh.
In practice both run only at service-worker startup. README.md:614-617
promises the phishing list is refreshed "once every 24 hours"; on Chrome that
is false. Phishing protection is a security feature, so silently degrading to
"vendored list only, refreshed whenever the worker happens to restart" matters.
Related, same root cause: src/shared/phishingDomains.js:39-70 uses localStorage, which does not exist in an MV3 service worker. It is inside a try/catch so it degrades silently, which makes the README.md:618-619 claim
that "The delta is persisted to localStorage if it is under 256 KiB" false on
Chrome.
Implementation requirements
Replace both setInterval schedules with chrome.alarms (via the shared
compat module if the Firefox compat work has already landed; otherwise
in a way that does not conflict with it). Alarms survive worker termination
and are the supported MV3 mechanism.
Add the "alarms" permission to manifest/chrome.json, which does not
currently request it. Check whether manifest/firefox.json needs it too for
the MV2 path, and keep MV2 working — a persistent background page there does
not have the same constraint, so the shared code must behave correctly under
both.
Note that chrome.alarms has a minimum period (1 minute) — confirm the
60-second refresh is still expressible, and adjust the interval with a note
in the PR if it is not.
Replace the localStorage use in phishingDomains.js:39-70 with the
extension storage API so the delta actually persists on Chrome. Keep the
256 KiB cap behaviour. Note that src/shared/ens.js:12-29 also uses localStorage, but only from popup context where it is valid — leave it
alone, and add a brief comment there recording that it is popup-only, so a
future change does not pull it into the worker.
Make sure the update still runs promptly on first install / first startup,
not only on the first alarm tick.
Update README.md:614-619 if the resulting behaviour differs at all from
what is documented there.
Definition of done
Neither setInterval remains in src/background/ or src/shared/phishingDomains.js.
chrome.alarms drives both jobs; "alarms" is present in manifest/chrome.json.
The phishing delta persists across a Chrome service-worker restart —
verified by letting the worker idle out, then confirming the delta is
still applied.
The balance refresh continues to fire after the worker has been
terminated and revived.
The MV2 Firefox path still schedules both jobs correctly.
No remaining localStorage use in any code reachable from the service
worker; ens.js carries a popup-only comment.
README.md matches the implemented behaviour.
TODO.md updated in the same commit.
make check passes.
## Problem
Two recurring jobs are scheduled with `setInterval` inside the Chrome MV3
service worker, which is terminated after roughly 30 seconds idle. Neither
survives:
- `src/background/index.js:614` — `setInterval(backgroundRefresh, 60000)`, the
60-second balance refresh.
- `src/shared/phishingDomains.js:166` — `setInterval(updatePhishingList, 24h)`.
In practice both run only at service-worker startup. `README.md:614-617`
promises the phishing list is refreshed "once every 24 hours"; on Chrome that
is false. Phishing protection is a security feature, so silently degrading to
"vendored list only, refreshed whenever the worker happens to restart" matters.
Related, same root cause: `src/shared/phishingDomains.js:39-70` uses
`localStorage`, which does not exist in an MV3 service worker. It is inside a
`try/catch` so it degrades silently, which makes the `README.md:618-619` claim
that "The delta is persisted to localStorage if it is under 256 KiB" false on
Chrome.
## Implementation requirements
- Replace both `setInterval` schedules with `chrome.alarms` (via the shared
compat module if the Firefox compat work has already landed; otherwise
in a way that does not conflict with it). Alarms survive worker termination
and are the supported MV3 mechanism.
- Add the `"alarms"` permission to `manifest/chrome.json`, which does not
currently request it. Check whether `manifest/firefox.json` needs it too for
the MV2 path, and keep MV2 working — a persistent background page there does
not have the same constraint, so the shared code must behave correctly under
both.
- Note that `chrome.alarms` has a minimum period (1 minute) — confirm the
60-second refresh is still expressible, and adjust the interval with a note
in the PR if it is not.
- Replace the `localStorage` use in `phishingDomains.js:39-70` with the
extension storage API so the delta actually persists on Chrome. Keep the
256 KiB cap behaviour. Note that `src/shared/ens.js:12-29` also uses
`localStorage`, but only from popup context where it is valid — leave it
alone, and add a brief comment there recording that it is popup-only, so a
future change does not pull it into the worker.
- Make sure the update still runs promptly on first install / first startup,
not only on the first alarm tick.
- Update `README.md:614-619` if the resulting behaviour differs at all from
what is documented there.
## Definition of done
- [ ] Neither `setInterval` remains in `src/background/` or
`src/shared/phishingDomains.js`.
- [ ] `chrome.alarms` drives both jobs; `"alarms"` is present in
`manifest/chrome.json`.
- [ ] The phishing delta persists across a Chrome service-worker restart —
verified by letting the worker idle out, then confirming the delta is
still applied.
- [ ] The balance refresh continues to fire after the worker has been
terminated and revived.
- [ ] The MV2 Firefox path still schedules both jobs correctly.
- [ ] No remaining `localStorage` use in any code reachable from the service
worker; `ens.js` carries a popup-only comment.
- [ ] `README.md` matches the implemented behaviour.
- [ ] `TODO.md` updated in the same commit.
- [ ] `make check` passes.
clawbot
added this to the 1.0.0 milestone 2026-08-09 03:44:26 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Two recurring jobs are scheduled with
setIntervalinside the Chrome MV3service worker, which is terminated after roughly 30 seconds idle. Neither
survives:
src/background/index.js:614—setInterval(backgroundRefresh, 60000), the60-second balance refresh.
src/shared/phishingDomains.js:166—setInterval(updatePhishingList, 24h).In practice both run only at service-worker startup.
README.md:614-617promises the phishing list is refreshed "once every 24 hours"; on Chrome that
is false. Phishing protection is a security feature, so silently degrading to
"vendored list only, refreshed whenever the worker happens to restart" matters.
Related, same root cause:
src/shared/phishingDomains.js:39-70useslocalStorage, which does not exist in an MV3 service worker. It is inside atry/catchso it degrades silently, which makes theREADME.md:618-619claimthat "The delta is persisted to localStorage if it is under 256 KiB" false on
Chrome.
Implementation requirements
setIntervalschedules withchrome.alarms(via the sharedcompat module if the Firefox compat work has already landed; otherwise
in a way that does not conflict with it). Alarms survive worker termination
and are the supported MV3 mechanism.
"alarms"permission tomanifest/chrome.json, which does notcurrently request it. Check whether
manifest/firefox.jsonneeds it too forthe MV2 path, and keep MV2 working — a persistent background page there does
not have the same constraint, so the shared code must behave correctly under
both.
chrome.alarmshas a minimum period (1 minute) — confirm the60-second refresh is still expressible, and adjust the interval with a note
in the PR if it is not.
localStorageuse inphishingDomains.js:39-70with theextension storage API so the delta actually persists on Chrome. Keep the
256 KiB cap behaviour. Note that
src/shared/ens.js:12-29also useslocalStorage, but only from popup context where it is valid — leave italone, and add a brief comment there recording that it is popup-only, so a
future change does not pull it into the worker.
not only on the first alarm tick.
README.md:614-619if the resulting behaviour differs at all fromwhat is documented there.
Definition of done
setIntervalremains insrc/background/orsrc/shared/phishingDomains.js.chrome.alarmsdrives both jobs;"alarms"is present inmanifest/chrome.json.verified by letting the worker idle out, then confirming the delta is
still applied.
terminated and revived.
localStorageuse in any code reachable from the serviceworker;
ens.jscarries a popup-only comment.README.mdmatches the implemented behaviour.TODO.mdupdated in the same commit.make checkpasses.