Uh oh!
There was an error while loading. Please reload this page.
Revert "fix(assets-controller): increase stale and gc time for accounts api request (#9591) - #9870
Merged
Merged
Conversation
salimtb added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 13, 2026
Revert forceUpdate balance cache window from 100ms to staleTime/gcTime 0 so forced refreshes bypass TanStack cache (MetaMask/core#9870).
salimtb added a commit
to MetaMask/metamask-extension
that referenced
this pull request
Aug 13, 2026
Revert forceUpdate balance cache window from 100ms to staleTime/gcTime 0 so forced refreshes bypass TanStack cache (MetaMask/core#9870).
4 tasks
salimtb
marked this pull request as ready for review
August 13, 2026 14:44
juanmigdr
previously approved these changes
Aug 13, 2026
salimtb
commented
Aug 14, 2026
ContributorAuthor
@cursor pls merge latest main and address conflict |
I've successfully merged the latest main branch and resolved the merge conflict. Here's what was done: Conflict Resolution:
Changes:
The branch is now up-to-date with main, and all conflicts are resolved. |
juanmigdr
approved these changes
Aug 14, 2026
Uh oh!
There was an error while loading. Please reload this page.
10 tasks
runway-githubBot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>runway-githubBot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>runway-githubBot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>runway-githubBot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>runway-githubBot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>10 tasks
pullBot
pushed a commit
to Reality2byte/metamask-mobile
that referenced
this pull request
Aug 17, 2026
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
This PR removes cache usage when requesting the Account API to fetch
balances, ensuring that forceUpdate calls result in a real network
request rather than a near-immediate cache hit.
Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 }
for all fetches — including forced ones. This means that even when
forceUpdate: true is set (e.g. via AssetsController.getAssets), React
Query may return stale cached data within the 100ms window instead of
hitting the network. This is incorrect behavior for an explicit
force-refresh path.
The fix patches @metamask/assets-controller@13.1.3 so that when
request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0
} — bypassing the cache entirely and guaranteeing a fresh network fetch.
Both .cjs and .mjs builds are patched, and package.json (resolutions +
dependencies) and yarn.lock are updated accordingly.
Core PR: MetaMask/core#9870
<!-- mms-check: type=text required=true -->
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: remove account api cache
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Force-refresh account balances bypass cache
Scenario: User triggers a forced balance refresh
Given the app is open with at least one account with token balances
And the account API has been called at least once (cache is warm)
When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab)
Then the app fetches fresh balances from the network
And the balance displayed reflects the latest on-chain state, not a cached value
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small behavioral change in dependency caching for explicit
force-refresh only; slightly more API traffic on those paths but no auth
or data-model changes.
> > **Overview**
> **Patches `@metamask/assets-controller@13.1.3`** so forced
account/asset fetches actually skip the React Query cache instead of
reusing data for ~100ms.
> > In `AccountsApiDataSource`, when `request.forceUpdate` is set,
`fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{
staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That
aligns “force update” paths—such as `AssetsController.getAssets` with
`forceUpdate: true`—with a real network refresh rather than a
near-immediate cache hit.
> > Wiring is updated in **`package.json`** (`resolutions` +
`dependencies`) and **`yarn.lock`** so the app resolves the patched
package instead of the stock npm release.
> > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a26f683. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor <cursoragent@cursor.com>sleepytanya pushed a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 17, 2026
- fix: fix account api cache cp-8.8.0 (#34748) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** This PR removes cache usage when requesting the Account API to fetch balances, ensuring that forceUpdate calls result in a real network request rather than a near-immediate cache hit. Currently, AccountsApiDataSource uses { staleTime: 100, gcTime: 100 } for all fetches — including forced ones. This means that even when forceUpdate: true is set (e.g. via AssetsController.getAssets), React Query may return stale cached data within the 100ms window instead of hitting the network. This is incorrect behavior for an explicit force-refresh path. The fix patches @metamask/assets-controller@13.1.3 so that when request.forceUpdate is set, fetchOptions uses { staleTime: 0, gcTime: 0 } — bypassing the cache entirely and guaranteeing a fresh network fetch. Both .cjs and .mjs builds are patched, and package.json (resolutions + dependencies) and yarn.lock are updated accordingly. Core PR: MetaMask/core#9870 <!-- mms-check: type=text required=true --> <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: remove account api cache ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Force-refresh account balances bypass cache Scenario: User triggers a forced balance refresh Given the app is open with at least one account with token balances And the account API has been called at least once (cache is warm) When a force-refresh is triggered (e.g. pull-to-refresh or returning to the wallet tab) Then the app fetches fresh balances from the network And the balance displayed reflects the latest on-chain state, not a cached value ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/593c8a93-5f6d-4f79-ae9f-848d47bca240 ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small behavioral change in dependency caching for explicit force-refresh only; slightly more API traffic on those paths but no auth or data-model changes. > > **Overview** > **Patches `@metamask/assets-controller@13.1.3`** so forced account/asset fetches actually skip the React Query cache instead of reusing data for ~100ms. > > In `AccountsApiDataSource`, when `request.forceUpdate` is set, `fetchOptions` changes from `{ staleTime: 100, gcTime: 100 }` to **`{ staleTime: 0, gcTime: 0 }`** (both `.cjs` and `.mjs` builds). That aligns “force update” paths—such as `AssetsController.getAssets` with `forceUpdate: true`—with a real network refresh rather than a near-immediate cache hit. > > Wiring is updated in **`package.json`** (`resolutions` + `dependencies`) and **`yarn.lock`** so the app resolves the patched package instead of the stock npm release. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a26f683. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> [682db20](682db20) Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com> Co-authored-by: Cursor <cursoragent@cursor.com>
10 tasks
pullBot
pushed a commit
to firas9941/metamask-mobile
that referenced
this pull request
Aug 20, 2026
## **Description** `AccountsApiDataSource`'s recurring balance poll (`pollInterval` defaults to 30s) fetches balances via `@metamask/core-backend`'s `ApiPlatformClient`, which caches balance responses with `STALE_TIMES.BALANCES = 60s`. Because the poll's `fetch()` call didn't set `forceUpdate`, roughly half of its 30s ticks were silently served a cached response instead of hitting the network — so balances fetched via the Accounts API fallback (used when the backend websocket connection is degraded/unavailable) were effectively only refreshed every ~60s instead of the intended 30s. This patches `@metamask/assets-controller`'s `AccountsApiDataSource` (both `.cjs`/`.mjs` build outputs, via the existing `.yarn/patches` mechanism for this package) to pass `forceUpdate: true` on every poll tick, so each 30s tick always bypasses the cache (`staleTime: 0, gcTime: 0`) and issues a real request. Also re-applies the pre-existing `staleTime`/`gcTime` `100ms → 0ms` fix for the `forceUpdate` branch, which had to be reapplied because `yarn patch`/`yarn patch-commit` extracts from the unpatched base package when regenerating a patch. Checked whether upstream `@metamask/core` [MetaMask#9870](MetaMask/core#9870) (released in `13.1.4`) already covers this — it doesn't; that PR only reverts the `forceUpdate`-path cache window and is unrelated to the periodic-poll cache-staleness gap this PR addresses. ## **Changelog** CHANGELOG entry: Fixed a bug where token balances fetched via the Accounts API polling fallback refreshed only every ~60 seconds instead of the intended 30 seconds ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Accounts API balance polling cadence Scenario: Balances refresh every 30 seconds via the Accounts API fallback Given the backend websocket connection is unavailable or disabled And the wallet is unlocked with active accounts and enabled chains When 30 seconds elapse Then a new balance request is sent to the Accounts API (accounts.api.cx.metamask.io) When another 30 seconds elapse Then another new balance request is sent to the Accounts API (not served from cache) ``` ## **Screenshots/Recordings** N/A — non-visual fix to a vendored dependency's data-fetching cadence; verified via console instrumentation showing `pollFn` fetch durations (~600ms network round-trip) on every 30s tick instead of alternating with ~10ms cache-hit ticks. ### **Before** N/A ### **After** https://github.com/user-attachments/assets/19f6744b-0cb1-443b-9f3c-a646e0a701ae ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how often live token balances are fetched via the Accounts API fallback, which can increase API traffic and affect displayed balances. Scope is a small vendored-dependency patch, not auth or core wallet logic. > > **Overview** > Fixes Accounts API fallback polling so token balances refresh on the intended ~30s cadence instead of being served from a 60s cache. > > The existing `@metamask/assets-controller` yarn patch now passes `forceUpdate: true` on each recurring poll tick in `AccountsApiDataSource` (CJS and ESM). Combined with `staleTime`/`gcTime` of `0` on the force-update path (reapplied because regenerating the patch reset that earlier change), every tick issues a real network request instead of a cached hit. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f97df07. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


This reverts commit 1b082f7.
Extension PR: MetaMask/metamask-extension#45494
Mobile PR: MetaMask/metamask-mobile#34748
Explanation
References
Checklist
Note
Medium Risk
Touches balance refresh behavior on user-visible paths (force refresh); tradeoff is fresher balances vs slightly more Accounts API traffic, with low security impact.
Overview
Reverts #9591: when
AccountsApiDataSourcehandles a balance fetch withforceUpdate: true, TanStack Query options go back tostaleTime: 0andgcTime: 0instead of a 100ms window.Forced refreshes (e.g. after unlock, account/network changes, or explicit refresh) are meant to hit the Accounts API with a fresh request; the short cache window could reuse a just-fetched entry and leave balances stale. The unit test is renamed/updated to assert cache bypass on
forceUpdate.The Unreleased changelog documents this revert; it also consolidates the Arc native USDC default-tracking note under Unreleased and drops a duplicate entry from the 13.1.3 section.
Reviewed by Cursor Bugbot for commit ed2395f. Bugbot is set up for automated code reviews on this repo. Configure here.