Skip to content

Commit 8257977

Browse files
authored
feat: add new ConnectivityController (#7623)
## Explanation This PR introduces a new `@metamask/connectivity-controller` package that provides a centralized way to track and manage device internet connectivity status across MetaMask clients (extension and mobile). **What is the current state of things and why does it need to change?** - Have a single source of truth for connectivity state - Share connectivity status across controllers and UI components - Test connectivity-related functionality in isolation - Maintain consistent behavior across platforms **What is the solution your changes offer and how does it work?** The `ConnectivityController` is a platform-agnostic controller that: - Stores the current connectivity status (`online` or `offline`) in its state - Uses a service injection pattern where platform-specific `ConnectivityService` implementations are injected at construction time - Subscribes to connectivity changes from the service and automatically updates its state - Emits `stateChange` events when connectivity status changes, allowing other controllers and UI components to react accordingly The controller is designed to work with different service implementations: - **Mobile**: `NetInfoConnectivityService` using `@react-native-community/netinfo` - **Extension (same context)**: `BrowserConnectivityService` using browser APIs **Are there any changes whose purpose might not be obvious to those unfamiliar with the domain?** - The `connectivityStatus` field in state is prefixed with "connectivity" to avoid conflicts when state is flattened in Redux - The state is configured with `persist: false` since connectivity status is ephemeral and should not be restored from storage ## References Fixes: https://consensyssoftware.atlassian.net/browse/WPC-210 <!-- Add any relevant issues, related PRs, or documentation links here --> ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduce a new, platform-agnostic controller to track device connectivity with adapter-driven status updates. > > - New package `@metamask/connectivity-controller` exposing `ConnectivityController`, `CONNECTIVITY_STATUSES`, and `ConnectivityAdapter` interface > - Controller initializes from adapter `getStatus()` and updates state on `onConnectivityChange`, with non-persistent `connectivityStatus` metadata > - Comprehensive tests for initialization and status change handling; 100% coverage config > - Added package docs (README, CHANGELOG, LICENSE) and build/test configs (tsconfig, typedoc, jest) > - Monorepo integration: README package list/graph, `CODEOWNERS`, `teams.json`, tsconfig references, and `yarn.lock` entry > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 16c51b5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent e7deea3 commit 8257977

18 files changed

+680
-0
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
/packages/base-controller @MetaMask/core-platform
6969
/packages/build-utils @MetaMask/core-platform
7070
/packages/composable-controller @MetaMask/core-platform
71+
/packages/connectivity-controller @MetaMask/core-platform
7172
/packages/controller-utils @MetaMask/core-platform
7273
/packages/error-reporting-service @MetaMask/core-platform
7374
/packages/eth-json-rpc-middleware @MetaMask/core-platform

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Each package in this repository has its own README where you can find installati
3636
- [`@metamask/chain-agnostic-permission`](packages/chain-agnostic-permission)
3737
- [`@metamask/claims-controller`](packages/claims-controller)
3838
- [`@metamask/composable-controller`](packages/composable-controller)
39+
- [`@metamask/connectivity-controller`](packages/connectivity-controller)
3940
- [`@metamask/controller-utils`](packages/controller-utils)
4041
- [`@metamask/core-backend`](packages/core-backend)
4142
- [`@metamask/delegation-controller`](packages/delegation-controller)
@@ -111,6 +112,7 @@ linkStyle default opacity:0.5
111112
chain_agnostic_permission(["@metamask/chain-agnostic-permission"]);
112113
claims_controller(["@metamask/claims-controller"]);
113114
composable_controller(["@metamask/composable-controller"]);
115+
connectivity_controller(["@metamask/connectivity-controller"]);
114116
controller_utils(["@metamask/controller-utils"]);
115117
core_backend(["@metamask/core-backend"]);
116118
delegation_controller(["@metamask/delegation-controller"]);
@@ -231,6 +233,8 @@ linkStyle default opacity:0.5
231233
composable_controller --> base_controller;
232234
composable_controller --> messenger;
233235
composable_controller --> json_rpc_engine;
236+
connectivity_controller --> base_controller;
237+
connectivity_controller --> messenger;
234238
core_backend --> accounts_controller;
235239
core_backend --> controller_utils;
236240
core_backend --> keyring_controller;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
12+
- Initial release ([#7623](https://github.com/MetaMask/core/pull/7623))
13+
14+
[Unreleased]: https://github.com/MetaMask/core/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
MIT License
2+
3+
Copyright (c) 2026 MetaMask
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# `@metamask/connectivity-controller`
2+
3+
ConnectivityController stores the device's internet connectivity status.
4+
5+
## Installation
6+
7+
`yarn add @metamask/connectivity-controller`
8+
9+
or
10+
11+
`npm install @metamask/connectivity-controller`
12+
13+
## Contributing
14+
15+
This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* For a detailed explanation regarding each configuration property and type check, visit:
3+
* https://jestjs.io/docs/configuration
4+
*/
5+
6+
const merge = require('deepmerge');
7+
const path = require('path');
8+
9+
const baseConfig = require('../../jest.config.packages');
10+
11+
const displayName = path.basename(__dirname);
12+
13+
module.exports = merge(baseConfig, {
14+
// The display name when running multiple projects
15+
displayName,
16+
17+
// An object that configures minimum threshold enforcement for coverage results
18+
coverageThreshold: {
19+
global: {
20+
branches: 100,
21+
functions: 100,
22+
lines: 100,
23+
statements: 100,
24+
},
25+
},
26+
});
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"name": "@metamask/connectivity-controller",
3+
"version": "0.0.0",
4+
"description": "ConnectivityController stores the device's internet connectivity status",
5+
"keywords": [
6+
"MetaMask",
7+
"Ethereum"
8+
],
9+
"homepage": "https://github.com/MetaMask/core/tree/main/packages/connectivity-controller#readme",
10+
"bugs": {
11+
"url": "https://github.com/MetaMask/core/issues"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/MetaMask/core.git"
16+
},
17+
"license": "MIT",
18+
"sideEffects": false,
19+
"exports": {
20+
".": {
21+
"import": {
22+
"types": "./dist/index.d.mts",
23+
"default": "./dist/index.mjs"
24+
},
25+
"require": {
26+
"types": "./dist/index.d.cts",
27+
"default": "./dist/index.cjs"
28+
}
29+
},
30+
"./package.json": "./package.json"
31+
},
32+
"main": "./dist/index.cjs",
33+
"types": "./dist/index.d.cts",
34+
"files": [
35+
"dist/"
36+
],
37+
"scripts": {
38+
"build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
39+
"build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
40+
"build:docs": "typedoc",
41+
"changelog:update": "../../scripts/update-changelog.sh @metamask/connectivity-controller",
42+
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/connectivity-controller",
43+
"publish:preview": "yarn npm publish --tag preview",
44+
"since-latest-release": "../../scripts/since-latest-release.sh",
45+
"test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
46+
"test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
47+
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
48+
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
49+
},
50+
"dependencies": {
51+
"@metamask/base-controller": "^9.0.0",
52+
"@metamask/messenger": "^0.3.0"
53+
},
54+
"devDependencies": {
55+
"@metamask/auto-changelog": "^3.4.4",
56+
"@ts-bridge/cli": "^0.6.4",
57+
"@types/jest": "^27.4.1",
58+
"deepmerge": "^4.2.2",
59+
"jest": "^27.5.1",
60+
"ts-jest": "^27.1.4",
61+
"typedoc": "^0.24.8",
62+
"typedoc-plugin-missing-exports": "^2.0.0",
63+
"typescript": "~5.3.3"
64+
},
65+
"engines": {
66+
"node": "^18.18 || >=20"
67+
},
68+
"publishConfig": {
69+
"access": "public",
70+
"registry": "https://registry.npmjs.org/"
71+
}
72+
}

0 commit comments

Comments
 (0)