Skip to content

feat(tron): deduplicate identical requests within 5 seconds - #500

Merged
ulissesferreira merged 1 commit into
mainfrom
feat/tron-client-request-cache
Oct 22, 2026
Merged

ulissesferreira merged 1 commit into
mainfrom
feat/tron-client-request-cache

Conversation

@ulissesferreira

@ulissesferreira ulissesferreira commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Explanation

Rapid keyring calls such as getAccountAssets and getAccountBalances both resolve through fetchAccountAssetsFromTrongrid, which issues the same TronGrid/Tron provider requests per scope. When the two calls arrive in quick succession, every request was sent to the network twice.

This caches the #fetch choke point of TrongridApiClient and TronHttpClient with the shared useCache helper backed by InMemoryCache. An identical request made within 5 seconds reuses the previous response instead of repeating the network call.

Notes:

  • The cache key is built from the cached function's arguments: scope, url, and headers for TronGrid, and network, url, method, headers, body, and allowedStatuses for Tron HTTP. Different arguments never collide, and the 404-allowed transaction-info path stays isolated.
  • Only settled results are cached; rejections are not, so the existing fetch-policy retry behavior is unchanged. Concurrent identical requests are not coalesced: a second request is served from the cache only after the first settles.
  • The cache applies at the client layer, so it covers every caller of these clients, including the fresh asset reads used by the send and stake flows (results may be up to 5 seconds old).
  • All client methods on these paths are read-only, so cached results cannot mask a write.
  • Both clients are singletons in context.ts, so the cache spans the whole keyring flow without any keyring changes.

References

No ticket.

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

@ulissesferreira
ulissesferreira marked this pull request as ready for review October 22, 2026 14:09
@ulissesferreira
ulissesferreira requested review from a team as code owners October 22, 2026 14:09
@ulissesferreira
ulissesferreira force-pushed the feat/tron-client-request-cache branch 2 times, most recently from 323657b to ee7fc1d Compare October 22, 2026 15:10

@stanleyyconsensys stanleyyconsensys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

thx for the change, using inMemory cache should be enough for our case

@stanleyyconsensys stanleyyconsensys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sonarqubecloud

Copy link
Copy Markdown

@ulissesferreira
ulissesferreira added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 0794b14 Oct 22, 2026
56 checks passed
@ulissesferreira
ulissesferreira deleted the feat/tron-client-request-cache branch October 22, 2026 15:23
LabinatorSolutions pushed a commit to LabinatorSolutions/metamask-extension that referenced this pull request Oct 26, 2026
## **Description**

Bumps the preinstalled Solana and Tron wallet Snaps to the latest
published versions:

- `@metamask/solana-wallet-snap`: `^7.1.0` → `^7.2.0`
- `@metamask/tron-wallet-snap`: `^4.2.0` → `^4.3.0`

### `@metamask/solana-wallet-snap` 7.2.0

#### Added

- Route asset reads (`getAccountAssetByID`, `getAccountAssetsByIDs`,
`getAccountAssetsByScope`, `getAccountAssets`) through the Core
AssetsController when the Solana assets migration flag is active,
falling back to the Snap adapter while it is off
([MetaMask#486](MetaMask/internal-snaps#486))

#### Changed

- Retry transient Solana RPC and API read failures with the shared fetch
policy while sending transaction submissions only once
([MetaMask#478](MetaMask/internal-snaps#478))

#### Fixed

- Fix a race condition in the WebSocket connection recovery so resync no
longer skips accounts during re-subscription
([MetaMask#490](MetaMask/internal-snaps#490))
- Accept scan responses that report the `simulation` or `validation`
section as explicit `null` instead of failing response validation

### `@metamask/tron-wallet-snap` 4.3.0

#### Changed

- Cache identical TronGrid and Tron provider requests for 5 seconds, so
rapid keyring calls such as `getAccountAssets` and `getAccountBalances`
reuse the previous result
([MetaMask#500](MetaMask/internal-snaps#500))
- Use the shared `executeWithFetchPolicy`, `fetchWithPolicy`, and
`parseRetryAfter` helpers from `@metamask/snap-networks-utils`, and
apply the shared fetch policy to `TokenApiClient` and the Security
Alerts API client
([MetaMask#492](MetaMask/internal-snaps#492))
- Retry transient TronGrid, Tron provider, price API, and signed
transaction broadcast failures with bounded backoff and per-attempt
timeouts ([MetaMask#472](MetaMask/internal-snaps#472))
- Extend the shared `BaseTransactionScanService` from
`@metamask/snap-networks-utils` in the transaction scan service and
align the Tron security-scan handling with the Blockaid API
documentation
([MetaMask#397](MetaMask/internal-snaps#397))

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A — dependency version bump only.

## **Manual testing steps**

1. Run the extension.
2. Create or import a wallet, then add a Solana account and select the
Solana network.
3. Refresh the asset list and verify balances and token metadata load
without errors.
4. Add a Tron account, select the Tron network, and refresh the asset
list.
5. Send a small Solana and Tron transaction and confirm the confirmation
screen and activity list update correctly.
6. Check the background console for Snap-related errors.

<!--
## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A
-->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/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
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants