MetaMask / MetaMask/metamask-mobile
RemoteFeatureFlagController does not toggle disabled state on runtime Basic Functionality changes
- Dominant language
- TypeScript
- Stars
- 3k
- Forks
- 1.7k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
## What is this about?
`RemoteFeatureFlagController` only evaluates `selectBasicFunctionalityEnabled` **once, at initialization**, to set its initial `disabled` state. It does not react to runtime changes of the Basic Functionality toggle, so it never calls `enable()` / `disable()` after startup.
This is **pre-existing behaviour** (it predates the `@metamask/wallet` adoption in #31917 — the old `remote-feature-flag-controller-init.ts` had the same one-shot read) and was intentionally preserved by that migration to keep it behaviour-preserving. Filing as a follow-up.
The MetaMask Extension implementation subscribes to the toggle and flips the controller's `disabled` state accordingly. Mobile should match that.
## Current behaviour
- Initial `disabled` value is set from `selectBasicFunctionalityEnabled(store.getState())` when the controller's instance options are built:
- `app/core/Engine/wallet-init/instance-options/remote-feature-flag-controller.ts` (`disabled` field)
- Startup fetch gate in `app/core/Engine/Engine.ts` (~line 840)
- The only reactor to the toggle is the `basicFunctionalityToggle` saga (`app/store/sagas/index.ts`), which just swaps the global XHR override (`restoreXMLHttpRequest` / `overrideXMLHttpRequest`). It never calls `RemoteFeatureFlagController.enable()` / `disable()`.
### Secondary issue: the XHR override doesn't catch RFFC either
Even the XHR override path wouldn't block remote feature flag fetches: `AppConstants.BASIC_FUNCTIONALITY_BLOCK_LIST` still references the stale host `config-api.metamask.io/featureFlags`, whereas the real endpoint is `client-config.api.cx.metamask.io` (`AppConstants.FEATURE_FLAGS_API.BASE_URL`).
Net effect: toggling Basic Functionality off at runtime currently neither disables the controller nor blocks its requests.
## Expected behaviour
When the Basic Functionality toggle changes at runtime:
1. Call `RemoteFeatureFlagController.disable()` when basic functionality is turned off, and `enable()` (followed by `updateRemoteFeatureFlags()`) when it is turned back on — matching the Extension implementation.
2. Update `BASIC_FUNCTIONALITY_BLOCK_LIST` so the feature-flags host (`client-config.api.cx.metamask.io`) is actually covered, removing the stale `config-api.metamask.io/featureFlags` entry.
## References
- PR: #31917
- Reviewer comment by @FrederikBolding on the RFFC startup gate in `Engine.ts`.
Contributor guide
Research direction
Start with app/core/Engine/wallet-init/instance-options/remote-feature-flag-controller.ts and the basicFunctionalityToggle saga in app/store/sagas/index.ts, then compare the Extension implementation referenced in the issue. Verify the startup gate in app/core/Engine/Engine.ts and the feature-flags entry in AppConstants.BASIC_FUNCTIONALITY_BLOCK_LIST. Done means runtime toggles call disable or enable/updateFeatureFlags and the current feature-flags host is covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 64/100