Skip to content

feat: MUSD-943 money-account-balance-service optimizations#9100

Merged
Matt561 merged 11 commits into
mainfrom
feat/musd-943-money-account-balance-fetching-optimizations
Jun 12, 2026
Merged

feat: MUSD-943 money-account-balance-service optimizations#9100
Matt561 merged 11 commits into
mainfrom
feat/musd-943-money-account-balance-fetching-optimizations

Conversation

@Matt561

@Matt561 Matt561 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Explanation

The Money account balance service currently makes multiple sequential RPC calls to fetch a user's Money account balance (mUSD wallet balance + vault share value).

This PR addresses both issues:

  • Multicall batching: A new getMoneyAccountBalance method fetches the mUSD wallet balance and the vmUSD (Veda vault tokens) in a single multicall. Previously, we needed 3 RPC calls each time we fetched the balance (getUnderlyingToken, getMusdBalance, getVmusdBalance).

  • Configurable stale time: The balance cache staleTime is now driven by a remote feature flag (moneyAccountBalanceStaletime). The default balance staleTime was bumped from 30s to 60s.

  • Underlying token from config: The vault config now accepts an optional underlyingToken address. When present, the service uses it directly instead of making an extra Accountant.base() on-chain read on every mUSD balance fetch. Falls back to the on-chain read when absent (backwards compatible with existing flag payloads).

  • Rename mUSDSHFvd → vmUSD: The vault share token is called vmUSD everywhere else, so the public API now reflects that (getMusdSHFvdBalancegetVmusdBalance, etc.). This is a breaking change.

References

  • MUSD-943

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
Breaking public API renames require consumer updates; balance and vault config changes affect on-chain reads and caching behavior, though defaults and fallbacks limit rollout risk.

Overview
Adds getMoneyAccountBalance, which batches mUSD balanceOf and Lens balanceOfInAssets in one Multicall3 aggregate3 call and returns musdBalance, vmusdValueInMusd, and totalBalance.

Breaking: Renames the vault-share API from musdSHFvd / getMusdSHFvdBalance to vmUSD / getVmusdBalance (including messenger action types).

Vault config may include optional underlyingToken so mUSD reads skip Accountant.base() when set; behavior stays backward compatible when omitted.

On-chain balance cache staleTime defaults to 60s (was 30s) and can be overridden at runtime via the moneyAccountBalanceStaletime remote feature flag (init + RemoteFeatureFlagController:stateChange, with validation and fallback).

Reviewed by Cursor Bugbot for commit d6a3b01. Bugbot is set up for automated code reviews on this repo. Configure here.

@Matt561

Matt561 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.2-preview-1b0db3500
@metamask-previews/accounts-controller@39.0.1-preview-1b0db3500
@metamask-previews/address-book-controller@7.1.2-preview-1b0db3500
@metamask-previews/ai-controllers@0.7.0-preview-1b0db3500
@metamask-previews/analytics-controller@1.1.1-preview-1b0db3500
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-1b0db3500
@metamask-previews/announcement-controller@8.1.0-preview-1b0db3500
@metamask-previews/app-metadata-controller@2.0.1-preview-1b0db3500
@metamask-previews/approval-controller@9.0.2-preview-1b0db3500
@metamask-previews/assets-controller@9.0.1-preview-1b0db3500
@metamask-previews/assets-controllers@109.0.0-preview-1b0db3500
@metamask-previews/authenticated-user-storage@2.0.0-preview-1b0db3500
@metamask-previews/base-controller@9.1.0-preview-1b0db3500
@metamask-previews/base-data-service@0.1.3-preview-1b0db3500
@metamask-previews/bridge-controller@75.1.1-preview-1b0db3500
@metamask-previews/bridge-status-controller@72.1.0-preview-1b0db3500
@metamask-previews/build-utils@3.0.4-preview-1b0db3500
@metamask-previews/chain-agnostic-permission@1.6.1-preview-1b0db3500
@metamask-previews/chomp-api-service@3.1.0-preview-1b0db3500
@metamask-previews/claims-controller@0.5.3-preview-1b0db3500
@metamask-previews/client-controller@1.0.1-preview-1b0db3500
@metamask-previews/compliance-controller@2.1.0-preview-1b0db3500
@metamask-previews/composable-controller@12.0.1-preview-1b0db3500
@metamask-previews/config-registry-controller@0.4.1-preview-1b0db3500
@metamask-previews/connectivity-controller@0.2.0-preview-1b0db3500
@metamask-previews/controller-utils@12.2.0-preview-1b0db3500
@metamask-previews/core-backend@6.3.3-preview-1b0db3500
@metamask-previews/delegation-controller@3.0.2-preview-1b0db3500
@metamask-previews/earn-controller@12.2.0-preview-1b0db3500
@metamask-previews/eip-5792-middleware@3.0.4-preview-1b0db3500
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-1b0db3500
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-1b0db3500
@metamask-previews/ens-controller@19.1.3-preview-1b0db3500
@metamask-previews/eth-block-tracker@15.0.1-preview-1b0db3500
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-1b0db3500
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-1b0db3500
@metamask-previews/foundryup@1.0.1-preview-1b0db3500
@metamask-previews/gas-fee-controller@26.2.2-preview-1b0db3500
@metamask-previews/gator-permissions-controller@4.2.0-preview-1b0db3500
@metamask-previews/geolocation-controller@0.1.3-preview-1b0db3500
@metamask-previews/json-rpc-engine@10.5.0-preview-1b0db3500
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-1b0db3500
@metamask-previews/keyring-controller@27.0.0-preview-1b0db3500
@metamask-previews/logging-controller@8.0.2-preview-1b0db3500
@metamask-previews/message-manager@14.1.2-preview-1b0db3500
@metamask-previews/messenger@1.2.0-preview-1b0db3500
@metamask-previews/messenger-cli@0.2.0-preview-1b0db3500
@metamask-previews/money-account-balance-service@1.0.2-preview-1b0db3500
@metamask-previews/money-account-controller@0.3.3-preview-1b0db3500
@metamask-previews/money-account-upgrade-controller@2.0.5-preview-1b0db3500
@metamask-previews/multichain-account-service@10.0.3-preview-1b0db3500
@metamask-previews/multichain-api-middleware@3.1.3-preview-1b0db3500
@metamask-previews/multichain-network-controller@3.1.3-preview-1b0db3500
@metamask-previews/multichain-transactions-controller@7.1.1-preview-1b0db3500
@metamask-previews/name-controller@9.1.2-preview-1b0db3500
@metamask-previews/network-controller@32.0.0-preview-1b0db3500
@metamask-previews/network-enablement-controller@5.3.0-preview-1b0db3500
@metamask-previews/notification-services-controller@24.1.3-preview-1b0db3500
@metamask-previews/passkey-controller@2.0.1-preview-1b0db3500
@metamask-previews/permission-controller@13.1.1-preview-1b0db3500
@metamask-previews/permission-log-controller@5.1.0-preview-1b0db3500
@metamask-previews/perps-controller@8.1.0-preview-1b0db3500
@metamask-previews/phishing-controller@17.2.0-preview-1b0db3500
@metamask-previews/polling-controller@16.0.6-preview-1b0db3500
@metamask-previews/preferences-controller@23.1.0-preview-1b0db3500
@metamask-previews/profile-metrics-controller@3.2.0-preview-1b0db3500
@metamask-previews/profile-sync-controller@28.1.1-preview-1b0db3500
@metamask-previews/ramps-controller@14.1.1-preview-1b0db3500
@metamask-previews/rate-limit-controller@7.0.1-preview-1b0db3500
@metamask-previews/react-data-query@0.2.1-preview-1b0db3500
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-1b0db3500
@metamask-previews/sample-controllers@5.0.1-preview-1b0db3500
@metamask-previews/seedless-onboarding-controller@10.0.2-preview-1b0db3500
@metamask-previews/selected-network-controller@26.1.3-preview-1b0db3500
@metamask-previews/shield-controller@5.1.2-preview-1b0db3500
@metamask-previews/signature-controller@39.2.5-preview-1b0db3500
@metamask-previews/snap-account-service@0.3.1-preview-1b0db3500
@metamask-previews/social-controllers@2.2.1-preview-1b0db3500
@metamask-previews/storage-service@1.0.2-preview-1b0db3500
@metamask-previews/subscription-controller@6.2.0-preview-1b0db3500
@metamask-previews/transaction-controller@68.0.0-preview-1b0db3500
@metamask-previews/transaction-pay-controller@23.5.1-preview-1b0db3500
@metamask-previews/user-operation-controller@41.2.4-preview-1b0db3500
@metamask-previews/wallet@3.0.0-preview-1b0db3500
@metamask-previews/wallet-cli@0.0.0-preview-1b0db3500

@Matt561 Matt561 marked this pull request as ready for review June 11, 2026 20:38
@Matt561 Matt561 requested review from a team as code owners June 11, 2026 20:38
@Matt561 Matt561 temporarily deployed to default-branch June 11, 2026 20:38 — with GitHub Actions Inactive
Jwhiles
Jwhiles previously approved these changes Jun 12, 2026

@Jwhiles Jwhiles 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.

Suggested a couple of minor tweaks - but generally happy to merge

* is stored in `RemoteFeatureFlagController` state's `remoteFeatureFlags` map.
* Falls back to {@link DEFAULT_BALANCE_STALE_TIME} when absent or malformed.
*/
export const MONEY_ACCOUNT_BALANCE_STALETIME_FEATURE_FLAG_KEY =

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.

I'm not sure it makes sense to store the feature flags in the core library. To me it feels more like a client concern, and in general most of feature flags seem to be defined in the clients - so defining some of them in core seems to make the situation more confusing.

I understand that VAULT_CONFIG_FEATURE_FLAG_KEY is already defined in this package, so I’m happy to approve - but IMO we should move away from this pattern

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.

Also, the changelog says it's moneyAccountBalanceStaleTime - note the capital T. Would be good to get them matching ;)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I've fixed the typo in the changelog!

As discussed, we'll open a separate PR if we decide to move feature flags to the client.

};
}

function mockMoneyAccountBalanceMulticall({

@Jwhiles Jwhiles Jun 12, 2026

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.

This mocks out basically everything in getMoneyAccountBalance - and I think it takes away a bit of the value of the test.

For example, I think it would be nice to have at least one test actually exercise the decode/encode paths - cos at the moment we only know they work from manual testing.

@Matt561 Matt561 force-pushed the feat/musd-943-money-account-balance-fetching-optimizations branch from 8f1bdd7 to d6a3b01 Compare June 12, 2026 17:11
@Matt561 Matt561 requested a review from Jwhiles June 12, 2026 17:17
@Matt561 Matt561 added this pull request to the merge queue Jun 12, 2026
Merged via the queue into main with commit 1166390 Jun 12, 2026
376 checks passed
@Matt561 Matt561 deleted the feat/musd-943-money-account-balance-fetching-optimizations branch June 12, 2026 18:35
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.

2 participants