Skip to content

Conversation

@Kriys94
Copy link
Contributor

@Kriys94 Kriys94 commented Sep 25, 2025

Follow-up of #6490
PR focusing on merging the core-backend package first

Explanation

What is the current state, and why does it need to change?

Currently, MetaMask relies on polling-based HTTP requests to fetch blockchain data like account balances and transaction updates. This approach has several limitations:

  • Performance inefficiency: Constant polling creates unnecessary network requests and server load
  • User experience delays: Users must wait for the next polling cycle to see updates (typically 20 seconds to 10 minutes)
  • Resource consumption: Mobile devices waste battery on frequent HTTP requests
  • Scalability concerns: As MetaMask grows, polling doesn't scale well for real-time data needs

What is the solution and how does it work?

This PR introduces the @metamask/core-backend package - a new data layer platform that bridges backend services with MetaMask frontend applications through efficient WebSocket-based real-time communication.

The solution provides:

  1. BackendWebSocketService: Low-level WebSocket connection management with automatic reconnection, authentication integration, and intelligent message routing

  2. AccountActivityService: High-level service for real-time account activity monitoring

  3. Intelligent Fallback Strategy: Dynamic coordination with existing HTTP polling controllers - when WebSocket is connected, polling intervals increase from 20s to 10 minutes; when disconnected, polling returns to 20s with immediate balance fetches

Key architectural benefits:

  • Real-time Performance: Instant delivery of transaction and balance updates via WebSocket push notifications
  • Resource Efficiency: Reduces HTTP requests by 95% when WebSocket is active (10min polling vs 20s polling)
  • Multi-chain Support: CAIP-10 address format support for blockchain interoperability
  • Mobile-Optimized: Lifecycle-aware connection management for background/foreground transitions
  • Extensible Design: Platform foundation for future services (price updates, etc.)

Checklist

  • I've updated the test suite for new or updated code as appropriate

    • High test coverage across BackendWebSocketService and AccountActivityService
    • Tests cover WebSocket lifecycle, reconnection scenarios, subscription management, and integration patterns
    • Mobile-specific lifecycle testing included
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate

    • 427-line comprehensive README with architecture diagrams, sequence diagrams, and integration examples
    • Full JSDoc coverage for all public APIs
    • TypeDoc configuration for API documentation generation
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary

    • CHANGELOG.md created following Keep a Changelog format
    • Version 0.0.0 initial release - no breaking changes as this is a new package
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

    • No breaking changes - this is an additive new package
    • Integration examples provided in README for Extension and Mobile consumers
    • Backward compatible - existing polling continues to work alongside WebSocket enhancement

Note

Adds the new @metamask/core-backend package providing a WebSocket client and account activity service, with types, tests, docs, and repo wiring.

  • Packages:
    • packages/core-backend (new):
      • BackendWebSocketService: authenticated WS client with reconnection, request/response, subscriptions, channel callbacks, and connection-state events.
      • AccountActivityService: real-time account activity (transactions/balances), system notifications, selected-account resubscription, and supported-chain fetching/caching.
      • Public types (transactions, balances, messages), logger, exports, README, CHANGELOG, LICENSE, Jest config, TypeDoc, tsconfigs.
      • Comprehensive tests for connection lifecycle, reconnection, subscriptions, message routing, and controller integration.
  • Repo config:
    • Add CODEOWNERS and teams mapping for core-backend.
    • Wire into monorepo build/TypeScript refs (tsconfig*.json) and yarn.lock.

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

@Kriys94 Kriys94 changed the title Feature/core backend platform feat(core-backend): add package Sep 25, 2025
@Kriys94 Kriys94 marked this pull request as ready for review September 25, 2025 12:50
@Kriys94 Kriys94 requested a review from a team as a code owner September 25, 2025 12:50
cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Hello, I see that a new PR was created for this package. I looked through this PR and made some comments as it relates to conventions throughout the rest of this monorepo. Take a look and let me know your thoughts.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@Kriys94 Kriys94 requested a review from a team as a code owner September 30, 2025 13:38
cursor[bot]

This comment was marked as outdated.

@Kriys94 Kriys94 force-pushed the feature/core-backend-platform branch from 5b566ef to 1257213 Compare October 1, 2025 08:30
@Kriys94 Kriys94 requested review from a team as code owners October 1, 2025 08:30
@Kriys94 Kriys94 force-pushed the feature/core-backend-platform branch from a179f5c to 7a73ee0 Compare October 7, 2025 14:27
mcmire
mcmire previously approved these changes Oct 7, 2025
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

I've fully reviewed the API, and it seems to be organized well. I left more comments, but I think they are all nitpicks at this point. LGTM.

@Kriys94 Kriys94 dismissed stale reviews from Prithpal-Sooriya and mcmire via bc80f5a October 7, 2025 20:03
@Kriys94 Kriys94 force-pushed the feature/core-backend-platform branch from 6670c5b to bc80f5a Compare October 7, 2025 20:03
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Looks great!

@Kriys94
Copy link
Contributor Author

Kriys94 commented Oct 8, 2025

@metamaskbot publish-preview

@github-actions
Copy link
Contributor

github-actions bot commented Oct 8, 2025

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "1.4.0-preview-bc80f5a1",
  "@metamask-previews/accounts-controller": "33.1.0-preview-bc80f5a1",
  "@metamask-previews/address-book-controller": "6.1.1-preview-bc80f5a1",
  "@metamask-previews/announcement-controller": "7.0.3-preview-bc80f5a1",
  "@metamask-previews/app-metadata-controller": "1.0.0-preview-bc80f5a1",
  "@metamask-previews/approval-controller": "7.1.3-preview-bc80f5a1",
  "@metamask-previews/assets-controllers": "78.0.0-preview-bc80f5a1",
  "@metamask-previews/base-controller": "8.4.0-preview-bc80f5a1",
  "@metamask-previews/bridge-controller": "48.0.0-preview-bc80f5a1",
  "@metamask-previews/bridge-status-controller": "48.0.0-preview-bc80f5a1",
  "@metamask-previews/build-utils": "3.0.3-preview-bc80f5a1",
  "@metamask-previews/chain-agnostic-permission": "1.1.1-preview-bc80f5a1",
  "@metamask-previews/composable-controller": "11.0.0-preview-bc80f5a1",
  "@metamask-previews/controller-utils": "11.14.0-preview-bc80f5a1",
  "@metamask-previews/core-backend": "0.0.0-preview-bc80f5a1",
  "@metamask-previews/delegation-controller": "0.7.0-preview-bc80f5a1",
  "@metamask-previews/earn-controller": "8.0.0-preview-bc80f5a1",
  "@metamask-previews/eip-5792-middleware": "1.2.0-preview-bc80f5a1",
  "@metamask-previews/eip1193-permission-middleware": "1.0.0-preview-bc80f5a1",
  "@metamask-previews/ens-controller": "17.0.1-preview-bc80f5a1",
  "@metamask-previews/error-reporting-service": "2.2.0-preview-bc80f5a1",
  "@metamask-previews/eth-json-rpc-provider": "5.0.0-preview-bc80f5a1",
  "@metamask-previews/foundryup": "1.0.1-preview-bc80f5a1",
  "@metamask-previews/gas-fee-controller": "24.0.0-preview-bc80f5a1",
  "@metamask-previews/gator-permissions-controller": "0.2.0-preview-bc80f5a1",
  "@metamask-previews/json-rpc-engine": "10.1.0-preview-bc80f5a1",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-bc80f5a1",
  "@metamask-previews/keyring-controller": "23.1.0-preview-bc80f5a1",
  "@metamask-previews/logging-controller": "6.0.4-preview-bc80f5a1",
  "@metamask-previews/message-manager": "13.0.0-preview-bc80f5a1",
  "@metamask-previews/messenger": "0.3.0-preview-bc80f5a1",
  "@metamask-previews/multichain-account-service": "1.6.0-preview-bc80f5a1",
  "@metamask-previews/multichain-api-middleware": "1.2.0-preview-bc80f5a1",
  "@metamask-previews/multichain-network-controller": "1.0.0-preview-bc80f5a1",
  "@metamask-previews/multichain-transactions-controller": "5.0.0-preview-bc80f5a1",
  "@metamask-previews/name-controller": "8.0.3-preview-bc80f5a1",
  "@metamask-previews/network-controller": "24.2.0-preview-bc80f5a1",
  "@metamask-previews/network-enablement-controller": "2.1.0-preview-bc80f5a1",
  "@metamask-previews/notification-services-controller": "18.2.0-preview-bc80f5a1",
  "@metamask-previews/permission-controller": "11.0.6-preview-bc80f5a1",
  "@metamask-previews/permission-log-controller": "4.0.0-preview-bc80f5a1",
  "@metamask-previews/phishing-controller": "14.1.0-preview-bc80f5a1",
  "@metamask-previews/polling-controller": "14.0.0-preview-bc80f5a1",
  "@metamask-previews/preferences-controller": "20.0.1-preview-bc80f5a1",
  "@metamask-previews/profile-sync-controller": "25.1.0-preview-bc80f5a1",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-bc80f5a1",
  "@metamask-previews/remote-feature-flag-controller": "1.7.0-preview-bc80f5a1",
  "@metamask-previews/sample-controllers": "2.0.0-preview-bc80f5a1",
  "@metamask-previews/seedless-onboarding-controller": "4.0.0-preview-bc80f5a1",
  "@metamask-previews/selected-network-controller": "24.0.0-preview-bc80f5a1",
  "@metamask-previews/shield-controller": "0.2.0-preview-bc80f5a1",
  "@metamask-previews/signature-controller": "34.0.0-preview-bc80f5a1",
  "@metamask-previews/subscription-controller": "0.5.0-preview-bc80f5a1",
  "@metamask-previews/token-search-discovery-controller": "3.3.0-preview-bc80f5a1",
  "@metamask-previews/transaction-controller": "60.6.0-preview-bc80f5a1",
  "@metamask-previews/user-operation-controller": "39.0.0-preview-bc80f5a1"
}

@Kriys94 Kriys94 merged commit 8d42386 into main Oct 8, 2025
243 checks passed
@Kriys94 Kriys94 deleted the feature/core-backend-platform branch October 8, 2025 08:23
@Kriys94 Kriys94 mentioned this pull request Oct 8, 2025
5 tasks
Kriys94 added a commit that referenced this pull request Oct 8, 2025
## Release @metamask/core-backend@1.0.0

This PR releases the initial version of the `@metamask/core-backend`
package.

### 📦 Package Overview

`@metamask/core-backend` provides core backend services for MetaMask,
serving as the data layer between Backend services (REST APIs, WebSocket
services) and Frontend applications (Extension, Mobile). This package
enables authenticated real-time data delivery with type-safe controller
integration.

### ✨ What's New in v1.0.0

This is the **initial release** of the package, introducing:

#### Core Services

- **BackendWebSocketService** - WebSocket client providing authenticated
real-time data delivery with:
- Connection management and automatic reconnection with exponential
backoff
  - Message routing and subscription management
  - Authentication integration with `AuthenticationController`
  - Type-safe messenger-based API for controller integration

- **AccountActivityService** - High-level service for monitoring account
activity with:
  - Real-time account activity monitoring via WebSocket subscriptions
- Balance update notifications for integration with
`TokenBalancesController`
  - Chain status change notifications for dynamic polling coordination
  - Account subscription management with automatic cleanup

#### Infrastructure

- **Type definitions** - Comprehensive TypeScript types for
transactions, balances, WebSocket messages, and service configurations
- **Logging infrastructure** - Structured logging with module-specific
loggers for debugging and monitoring

### 📄 Changelog

See
[CHANGELOG.md](https://github.com/MetaMask/core/blob/main/packages/core-backend/CHANGELOG.md)
for full details.

### 🔗 Related PR

- Initial implementation: #6722

### ✅ Release Checklist

- [x] Version bump is correct (1.0.0 for initial release)
- [x] Changelog entries are accurate and comprehensive
- [x] All changes are properly documented
- [x] Package is ready for publication
- [x] No additional changes from `main` need to be incorporated

### 📚 Documentation

- [Package
README](https://github.com/MetaMask/core/blob/main/packages/core-backend/README.md)
- [Architecture
documentation](https://github.com/MetaMask/core/blob/main/packages/core-backend/README.md#architecture--design)

---
@Kriys94 Kriys94 mentioned this pull request Oct 8, 2025
5 tasks
Kriys94 added a commit that referenced this pull request Oct 8, 2025
## Release @metamask/core-backend@1.0.0

This PR releases the initial version of the `@metamask/core-backend`
package.

### 📦 Package Overview

`@metamask/core-backend` provides core backend services for MetaMask,
serving as the data layer between Backend services (REST APIs, WebSocket
services) and Frontend applications (Extension, Mobile). This package
enables authenticated real-time data delivery with type-safe controller
integration.

### ✨ What's New in v1.0.0

This is the **initial release** of the package, introducing:

#### Core Services

- **BackendWebSocketService** - WebSocket client providing authenticated
real-time data delivery with:
- Connection management and automatic reconnection with exponential
backoff
  - Message routing and subscription management
  - Authentication integration with `AuthenticationController`
  - Type-safe messenger-based API for controller integration

- **AccountActivityService** - High-level service for monitoring account
activity with:
  - Real-time account activity monitoring via WebSocket subscriptions
- Balance update notifications for integration with
`TokenBalancesController`
  - Chain status change notifications for dynamic polling coordination
  - Account subscription management with automatic cleanup

#### Infrastructure

- **Type definitions** - Comprehensive TypeScript types for
transactions, balances, WebSocket messages, and service configurations
- **Logging infrastructure** - Structured logging with module-specific
loggers for debugging and monitoring

### 📄 Changelog

See
[CHANGELOG.md](https://github.com/MetaMask/core/blob/main/packages/core-backend/CHANGELOG.md)
for full details.

### 🔗 Related PR

- Initial implementation: #6722

### ✅ Release Checklist

- [x] Version bump is correct (1.0.0 for initial release)
- [x] Changelog entries are accurate and comprehensive
- [x] All changes are properly documented
- [x] Package is ready for publication
- [x] No additional changes from `main` need to be incorporated

### 📚 Documentation

- [Package
README](https://github.com/MetaMask/core/blob/main/packages/core-backend/README.md)
- [Architecture
documentation](https://github.com/MetaMask/core/blob/main/packages/core-backend/README.md#architecture--design)

---

<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Publishes initial @metamask/core-backend v1.0.0 with changelog updates
and bumps monorepo version to 606.0.0.
> 
> - **Releases**:
> - `@metamask/core-backend@1.0.0`: initial release; adds formal
changelog section and release links in
`packages/core-backend/CHANGELOG.md`.
> - **Versioning**:
>   - Monorepo `package.json` version bumped `605.0.0` -> `606.0.0`.
> - `packages/core-backend/package.json` version set `0.0.0` -> `1.0.0`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0d6d6dd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Kriys94 added a commit that referenced this pull request Oct 10, 2025
…lancesController (#6784)

This PR integrates the `TokenBalancesController` with the new
`@metamask/core-backend` package to enable real-time balance updates via
WebSocket connections. This provides users with instant balance updates
without relying solely on periodic polling.

### Context & Dependencies

⚠️ **This PR depends on
[#6722](#6722) being merged
first**, which introduces the `@metamask/core-backend` package with
`BackendWebSocketService` and `AccountActivityService`.

### Current State & Problem

Currently, the `TokenBalancesController` relies exclusively on periodic
REST API polling to detect balance changes. This approach has several
limitations:
- **High latency**: Users must wait for the next polling interval
(default 180s) to see balance updates
- **Increased API load**: Constant polling from all users creates
unnecessary server load
- **Poor UX for time-sensitive operations**: Users don't get immediate
feedback when balances change

### Solution

This PR enhances `TokenBalancesController` to:
- **Subscribe to real-time balance updates** via WebSocket when the
`AccountActivityService` is available
- **Coordinate polling dynamically** based on WebSocket connection
state:
- When WebSocket is connected: Reduce polling to 5-minute backup
intervals
- When WebSocket is disconnected: Resume default 20-second polling
intervals
- **Maintain backward compatibility**: Works identically when
core-backend package is unavailable
- **Provide graceful degradation**: Automatically falls back to polling
if WebSocket fails

### Key Implementation Details

**Integration with AccountActivityService**:
- Subscribes to `AccountActivityService:balanceUpdated` events via
messenger
- Updates token balances immediately when WebSocket notifications arrive
- Processes balance changes without waiting for polling cycles

**Connection State Coordination**:
- Listens to `BackendWebSocketService:connectionStateChanged` events
- Dynamically adjusts polling intervals to reduce API load when
real-time updates are active
- Ensures continuous data flow even during WebSocket reconnection
attempts

## References

- **Depends on**: [#6722 - feat(core-backend): add
package](#6722)
- Foundation for future real-time features (price updates, transaction
monitoring)
- Part of broader MetaMask backend services architecture

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- Enhanced TokenBalancesController tests to 1,225 lines covering
WebSocket integration scenarios
  - Added tests for connection state coordination and fallback behavior
  - Verified graceful degradation when core-backend is unavailable
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
  - Updated JSDoc for new methods and configuration options
  - Documented WebSocket integration behavior
- [x] I've communicated my changes to consumers by updating changelogs
for packages I've changed, highlighting breaking changes as necessary
  - Added CHANGELOG.md entries for `@metamask/assets-controllers`
- [ ] I've prepared draft pull requests for clients and consumer
packages to resolve any breaking changes
- N/A - no breaking changes introduced, backward compatible integration

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Integrates TokenBalancesController with AccountActivityService for
real-time balance updates, adds status-driven polling (with
debounce/jitter) and WS-based token import, updates docs/tests, and
introduces core-backend dependency with BREAKING messenger and interval
changes.
> 
> - **Assets Controllers**:
>   - **TokenBalancesController**:
> - Subscribes to `AccountActivityService:balanceUpdated` and
`statusChanged` for real-time updates and status-driven polling.
> - Adjusts polling dynamically (debounced 5s, jittered) and sets
defaults: `30s` (down) and `5m` when WebSocket is up.
> - Processes ERC20/native updates, updates `AccountTracker`, imports
untracked tokens via `TokenDetectionController:addDetectedTokensViaWs`.
> - Adds utilities (`caipChainIdToHex`, `parseAssetType`), handles
`allIgnoredTokens`, and cleans up timers on destroy.
>   - **TokenDetectionController**:
> - Adds public/action `addDetectedTokensViaWs` to add WS-detected
tokens from cache; minor cleanups.
>   - **BREAKING**:
> - Messenger must allow `AccountActivityService:balanceUpdated`,
`AccountActivityService:statusChanged`, and
`TokenDetectionController:addDetectedTokensViaWs`.
>     - Default polling interval changed to `30s` (was `180s`).
>   - **Docs/Tests**:
> - Adds `docs/real-time-balance-updates-flow.md` and updates README.
> - Extensive new tests for WS flows, utilities, and polling logic;
tweaks Jest coverage threshold.
>   - **Deps/Config**:
> - Adds `@metamask/core-backend` as dependency and peerDependency;
updates tsconfig references and yarn.lock.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5dac77e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

5 participants