Skip to content

Conversation

@Kriys94
Copy link
Contributor

@Kriys94 Kriys94 commented Jan 28, 2026

Explanation

This PR simplifies and cleans up SnapDataSource by:

  1. Dynamic snap discovery via PermissionController: Instead of hardcoded snap registry entries, SnapDataSource now dynamically discovers installed snaps that have the endowment:keyring permission and extracts their supported chain IDs from permission caveats. This makes the data source more flexible and extensible for future snaps.

  2. Simplified fetch routing: Changed from complex chain-based routing to account-based routing using account.metadata.snap.id. This aligns with how MultichainBalancesController handles snap accounts and is more direct since each account already knows which snap it belongs to.

  3. Added KeyringClient: Replaced manual SnapController:handleRequest calls with KeyringClient from @metamask/keyring-snap-client, which provides cleaner typed methods (listAccountAssets, getAccountBalances). This follows the same pattern used in MultichainBalancesController.

  4. Removed unused/redundant code:

    • Removed DEFAULT_SNAP_POLL_INTERVAL constant (never used)
    • Removed #groupChainsBySnapId method (no longer needed with account-based routing)
    • Removed #fetchFromSnapById method (inlined into fetch)
    • Removed #accountSupportsChain method (unused after simplification)
    • Removed redundant chain filtering in fetch (already done by middleware/subscribe callers)
    • Removed unused InternalAccount import
  5. Used proper types: Replaced inline type Record<string, { amount: string; unit: string }> with GetAccountBalancesResponse and Balance from @metamask/keyring-api.

Dependencies added:

  • @metamask/keyring-api: For Balance and CaipAssetType types
  • @metamask/keyring-snap-client: For KeyringClient to make typed snap calls

References

  • Related to the SnapDataSource dynamic snap discovery refactoring
  • Pattern aligned with MultichainBalancesController and MultichainAssetsController implementations

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

Note

Medium Risk
Refactors snap balance fetching and active-chain selection to be driven by PermissionController/SnapController rather than hardcoded registries, which could affect which chains/accounts are considered snap-backed. Also changes the snap call path to KeyringClient, so any mismatch in snap permissions or account metadata could lead to missing balances until rediscovery occurs.

Overview
SnapDataSource is refactored from a hardcoded Solana/Bitcoin/Tron registry to dynamic snap discovery. It now queries SnapController:getRunnableSnaps and PermissionController:getPermissions (using endowment:keyring plus endowment:assets chainIds caveat) to build activeChains and a chainToSnap map, and re-runs discovery on PermissionController:stateChange.

Balance fetching is simplified to be account-driven. fetch now skips non-snap accounts, routes calls by account.metadata.snap.id, and uses a cached KeyringClient (via SnapController:handleRequest) instead of provider wallet_invokeSnap/wallet_getSnaps; balance update events are filtered against discovered chains.

Integration/export surface is updated. initDataSources no longer accepts a snapProvider and the Snap messenger delegates the new Snap/Permission controller actions/events; public exports drop the old registry/constants and add KEYRING_PERMISSION/getChainIdsCaveat. Dependencies/tsconfig are updated to include keyring/snaps/permission packages.

Written by Cursor Bugbot for commit ad81bb1. This will update automatically on new commits. Configure here.

@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch 2 times, most recently from 7238184 to 58befda Compare January 29, 2026 10:34
@Kriys94 Kriys94 marked this pull request as ready for review January 29, 2026 10:41
@Kriys94 Kriys94 requested review from a team as code owners January 29, 2026 10:41
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 58befda to edad4fe Compare January 29, 2026 10:43
Comment on lines +509 to +534
const snapSupportsRequestedChains = request.chainIds.some(
(chainId) => this.state.chainToSnap[chainId] === snapId,
);
Copy link
Member

Choose a reason for hiding this comment

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

I don't fully understand how this is supposed to work. What if the chainToSnap mapping isn't already populated? Are the inputs BIP-44 account groups or individual accounts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

chainToSnap is populated at the initialization of MetaMask, much before that we are fetching assets. So What if the chainToSnap mapping isn't already populated? is unlikely to say impossible.

Are the inputs BIP-44 account groups or individual accounts?
request.accounts is the selected account group

@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from edad4fe to b6be0e0 Compare January 29, 2026 13:10
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch 3 times, most recently from bbc3ea1 to 92d01fb Compare January 29, 2026 14:45
Copy link
Contributor

@Prithpal-Sooriya Prithpal-Sooriya left a comment

Choose a reason for hiding this comment

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

Approving on first pass. This data source is completely new and not in production (we have time to refine).

Lets have the snaps team to review before merging. Maybe a short loom/recording to walkthrough changes?

const configuredNetworks =
options.configuredNetworks ?? ALL_DEFAULT_NETWORKS;

super(SNAP_DATA_SOURCE_NAME, {
Copy link
Member

Choose a reason for hiding this comment

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

Not necessarily Snaps-related, but I think you should loop in @mcmire to look at the DataSource architecture. We should ensure that this pattern is aligned with the approach we generally want for data services.

Copy link
Contributor

Choose a reason for hiding this comment

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

@FrederikBolding: Thanks for the mention, @Kriys94 messaged me privately about the DataSource code in AssetsController code. I'm looking through it now to understand how it all fits together. @Kriys94: I'll let you know when I have something to share.

Copy link
Contributor Author

@Kriys94 Kriys94 Jan 30, 2026

Choose a reason for hiding this comment

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

I have a diagram about what we are trying to build https://consensyssoftware.atlassian.net/wiki/spaces/PRDC/pages/400284352527/Architecture+proposal+34+AssetsController+the+cross-network-asset-type+controller#High-Level-Architecture

Here we call "data source" a piece of logic that extends the AssetsController and implements a specific interface to work with external services (Backend REST APIs, Snap, RPC). The code is related to the business logic, here assets balance, price and metadata.

For @mcmire and this ticket https://consensyssoftware.atlassian.net/browse/WPC-26, I think it refers more to a new service/client I just implemented in core-backend https://github.com/MetaMask/core/tree/main/packages/core-backend#http-api . The code in core-backend is agnostic form business logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In any case, feel free to comment on the overall code :) It's not released yet so making a braking change is easy :)

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 82d66c0 to 1d3ed84 Compare January 30, 2026 19:04
@Kriys94 Kriys94 force-pushed the fix/CleanSnapDataSource branch from 1d3ed84 to ad81bb1 Compare January 30, 2026 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants