@metamask-previews/network-connection-banner-controller 0.1.0-preview-bd4161b27 → 0.1.0-preview-6fc64deac

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +11 -19
  2. package/dist/NetworkConnectionBannerController-method-action-types.cjs.map +1 -1
  3. package/dist/NetworkConnectionBannerController-method-action-types.d.cts +4 -26
  4. package/dist/NetworkConnectionBannerController-method-action-types.d.cts.map +1 -1
  5. package/dist/NetworkConnectionBannerController-method-action-types.d.mts +4 -26
  6. package/dist/NetworkConnectionBannerController-method-action-types.d.mts.map +1 -1
  7. package/dist/NetworkConnectionBannerController-method-action-types.mjs.map +1 -1
  8. package/dist/NetworkConnectionBannerController.cjs +108 -86
  9. package/dist/NetworkConnectionBannerController.cjs.map +1 -1
  10. package/dist/NetworkConnectionBannerController.d.cts +26 -39
  11. package/dist/NetworkConnectionBannerController.d.cts.map +1 -1
  12. package/dist/NetworkConnectionBannerController.d.mts +26 -39
  13. package/dist/NetworkConnectionBannerController.d.mts.map +1 -1
  14. package/dist/NetworkConnectionBannerController.mjs +109 -87
  15. package/dist/NetworkConnectionBannerController.mjs.map +1 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +1 -1
  18. package/dist/index.d.cts.map +1 -1
  19. package/dist/index.d.mts +1 -1
  20. package/dist/index.d.mts.map +1 -1
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/url-utils.cjs +1 -52
  23. package/dist/url-utils.cjs.map +1 -1
  24. package/dist/url-utils.d.cts +0 -23
  25. package/dist/url-utils.d.cts.map +1 -1
  26. package/dist/url-utils.d.mts +0 -23
  27. package/dist/url-utils.d.mts.map +1 -1
  28. package/dist/url-utils.mjs +0 -53
  29. package/dist/url-utils.mjs.map +1 -1
  30. package/package.json +3 -3
package/README.md CHANGED
@@ -1,30 +1,22 @@
1
1
  # `@metamask/network-connection-banner-controller`
2
2
 
3
3
  NetworkConnectionBannerController decides when and how to surface the network
4
- connection banner based on RPC endpoint health. It encapsulates the rule, the
5
- 5s/30s timer state machine, and the eTLD+1 grouping used to decide when a
6
- wider provider outage is in play.
4
+ connection banner based on RPC endpoint health. It encapsulates the rule and
5
+ the 5s/30s timer state machine.
7
6
 
8
7
  ## Lifecycle
9
8
 
10
9
  The controller stays dormant after construction so the 5s / 30s escalation
11
10
  timers do not run before a user is actually looking at the wallet (e.g. while
12
- the app is still on the lock screen). The UI that renders the banner is
13
- responsible for driving the lifecycle:
14
-
15
- ```typescript
16
- // When the wallet UI that shows the banner becomes active
17
- // (e.g. the home surface mounts after unlock):
18
- networkConnectionBannerController.start();
19
-
20
- // When it goes away:
21
- networkConnectionBannerController.stop();
22
- ```
23
-
24
- Both methods are idempotent. `start` runs the initial evaluation immediately
25
- and enables reactions to upstream state changes. `stop` cancels any pending
26
- timers and resets the banner state to `available`. Upstream state changes are
27
- ignored while stopped.
11
+ the app is still on the lock screen). It manages its own lifecycle by
12
+ subscribing to `ClientController:stateChanged` and
13
+ `KeyringController:unlock` / `KeyringController:lock`: evaluation runs only
14
+ while the client UI is open on an unlocked wallet. When either condition
15
+ stops holding, pending timers are cancelled and the banner state resets to
16
+ `available`; upstream state changes are ignored until both hold again.
17
+
18
+ Clients need no lifecycle wiring beyond keeping `ClientController`'s
19
+ `isUiOpen` up to date (via `ClientController:setUiOpen`).
28
20
 
29
21
  ## Installation
30
22
 
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkConnectionBannerController-method-action-types.cjs","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NetworkConnectionBannerController } from './NetworkConnectionBannerController';\n\n/**\n * Look for a failed network, if any, and populate the initial state of the\n * banner. Reacts to upstream state changes from this point on.\n *\n * Call this when the wallet UI that consumes the banner becomes active\n * (typically when the wallet is unlocked and the home surface mounts) so\n * timers do not run while the user is not looking at the wallet. Should\n * be called after `NetworkController`, `NetworkEnablementController`, and\n * `ConnectivityController` have been initialized. Idempotent.\n */\nexport type NetworkConnectionBannerControllerStartAction = {\n type: `NetworkConnectionBannerController:start`;\n handler: NetworkConnectionBannerController['start'];\n};\n\n/**\n * Stops evaluating network connection state. Clears any pending banner\n * timers and resets state to `available`. Call this when the UI\n * consuming the banner is no longer active. Idempotent.\n */\nexport type NetworkConnectionBannerControllerStopAction = {\n type: `NetworkConnectionBannerController:stop`;\n handler: NetworkConnectionBannerController['stop'];\n};\n\n/**\n * Clears the banner state such that the banner will be hidden.\n */\nexport type NetworkConnectionBannerControllerDismissBannerAction = {\n type: `NetworkConnectionBannerController:dismissBanner`;\n handler: NetworkConnectionBannerController['dismissBanner'];\n};\n\n/**\n * Switches the chain's default RPC endpoint to its Infura endpoint,\n * causing the banner to clear once the network becomes available again.\n *\n * @param chainId - The chain whose default RPC endpoint should be switched.\n * @throws If the chain configuration cannot be found, or if it has no\n * Infura endpoint to switch to, or if the default is already Infura.\n */\nexport type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction =\n {\n type: `NetworkConnectionBannerController:switchToDefaultInfuraRpcEndpoint`;\n handler: NetworkConnectionBannerController['switchToDefaultInfuraRpcEndpoint'];\n };\n\n/**\n * Union of all NetworkConnectionBannerController action types.\n */\nexport type NetworkConnectionBannerControllerMethodActions =\n | NetworkConnectionBannerControllerStartAction\n | NetworkConnectionBannerControllerStopAction\n | NetworkConnectionBannerControllerDismissBannerAction\n | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;\n"]}
1
+ {"version":3,"file":"NetworkConnectionBannerController-method-action-types.cjs","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NetworkConnectionBannerController } from './NetworkConnectionBannerController';\n\n/**\n * Clears the banner state such that the banner will be hidden.\n */\nexport type NetworkConnectionBannerControllerDismissBannerAction = {\n type: `NetworkConnectionBannerController:dismissBanner`;\n handler: NetworkConnectionBannerController['dismissBanner'];\n};\n\n/**\n * Switches the chain's default RPC endpoint to its Infura endpoint and\n * makes it the active network, causing the banner to clear once the\n * network becomes available again.\n *\n * @param chainId - The chain whose default RPC endpoint should be switched.\n * @throws If the chain configuration cannot be found, or if it has no\n * Infura endpoint to switch to, or if the default is already Infura.\n */\nexport type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction =\n {\n type: `NetworkConnectionBannerController:switchToDefaultInfuraRpcEndpoint`;\n handler: NetworkConnectionBannerController['switchToDefaultInfuraRpcEndpoint'];\n };\n\n/**\n * Union of all NetworkConnectionBannerController action types.\n */\nexport type NetworkConnectionBannerControllerMethodActions =\n | NetworkConnectionBannerControllerDismissBannerAction\n | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;\n"]}
@@ -3,29 +3,6 @@
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { NetworkConnectionBannerController } from "./NetworkConnectionBannerController.cjs";
6
- /**
7
- * Look for a failed network, if any, and populate the initial state of the
8
- * banner. Reacts to upstream state changes from this point on.
9
- *
10
- * Call this when the wallet UI that consumes the banner becomes active
11
- * (typically when the wallet is unlocked and the home surface mounts) so
12
- * timers do not run while the user is not looking at the wallet. Should
13
- * be called after `NetworkController`, `NetworkEnablementController`, and
14
- * `ConnectivityController` have been initialized. Idempotent.
15
- */
16
- export type NetworkConnectionBannerControllerStartAction = {
17
- type: `NetworkConnectionBannerController:start`;
18
- handler: NetworkConnectionBannerController['start'];
19
- };
20
- /**
21
- * Stops evaluating network connection state. Clears any pending banner
22
- * timers and resets state to `available`. Call this when the UI
23
- * consuming the banner is no longer active. Idempotent.
24
- */
25
- export type NetworkConnectionBannerControllerStopAction = {
26
- type: `NetworkConnectionBannerController:stop`;
27
- handler: NetworkConnectionBannerController['stop'];
28
- };
29
6
  /**
30
7
  * Clears the banner state such that the banner will be hidden.
31
8
  */
@@ -34,8 +11,9 @@ export type NetworkConnectionBannerControllerDismissBannerAction = {
34
11
  handler: NetworkConnectionBannerController['dismissBanner'];
35
12
  };
36
13
  /**
37
- * Switches the chain's default RPC endpoint to its Infura endpoint,
38
- * causing the banner to clear once the network becomes available again.
14
+ * Switches the chain's default RPC endpoint to its Infura endpoint and
15
+ * makes it the active network, causing the banner to clear once the
16
+ * network becomes available again.
39
17
  *
40
18
  * @param chainId - The chain whose default RPC endpoint should be switched.
41
19
  * @throws If the chain configuration cannot be found, or if it has no
@@ -48,5 +26,5 @@ export type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAct
48
26
  /**
49
27
  * Union of all NetworkConnectionBannerController action types.
50
28
  */
51
- export type NetworkConnectionBannerControllerMethodActions = NetworkConnectionBannerControllerStartAction | NetworkConnectionBannerControllerStopAction | NetworkConnectionBannerControllerDismissBannerAction | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;
29
+ export type NetworkConnectionBannerControllerMethodActions = NetworkConnectionBannerControllerDismissBannerAction | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;
52
30
  //# sourceMappingURL=NetworkConnectionBannerController-method-action-types.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkConnectionBannerController-method-action-types.d.cts","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iCAAiC,EAAE,gDAA4C;AAE7F;;;;;;;;;GASG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,iCAAiC,CAAC,OAAO,CAAC,CAAC;CACrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,iCAAiC,CAAC,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,iCAAiC,CAAC,eAAe,CAAC,CAAC;CAC7D,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,uEAAuE,GACjF;IACE,IAAI,EAAE,oEAAoE,CAAC;IAC3E,OAAO,EAAE,iCAAiC,CAAC,kCAAkC,CAAC,CAAC;CAChF,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,8CAA8C,GACtD,4CAA4C,GAC5C,2CAA2C,GAC3C,oDAAoD,GACpD,uEAAuE,CAAC"}
1
+ {"version":3,"file":"NetworkConnectionBannerController-method-action-types.d.cts","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iCAAiC,EAAE,gDAA4C;AAE7F;;GAEG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,iCAAiC,CAAC,eAAe,CAAC,CAAC;CAC7D,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,uEAAuE,GACjF;IACE,IAAI,EAAE,oEAAoE,CAAC;IAC3E,OAAO,EAAE,iCAAiC,CAAC,kCAAkC,CAAC,CAAC;CAChF,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,8CAA8C,GACtD,oDAAoD,GACpD,uEAAuE,CAAC"}
@@ -3,29 +3,6 @@
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { NetworkConnectionBannerController } from "./NetworkConnectionBannerController.mjs";
6
- /**
7
- * Look for a failed network, if any, and populate the initial state of the
8
- * banner. Reacts to upstream state changes from this point on.
9
- *
10
- * Call this when the wallet UI that consumes the banner becomes active
11
- * (typically when the wallet is unlocked and the home surface mounts) so
12
- * timers do not run while the user is not looking at the wallet. Should
13
- * be called after `NetworkController`, `NetworkEnablementController`, and
14
- * `ConnectivityController` have been initialized. Idempotent.
15
- */
16
- export type NetworkConnectionBannerControllerStartAction = {
17
- type: `NetworkConnectionBannerController:start`;
18
- handler: NetworkConnectionBannerController['start'];
19
- };
20
- /**
21
- * Stops evaluating network connection state. Clears any pending banner
22
- * timers and resets state to `available`. Call this when the UI
23
- * consuming the banner is no longer active. Idempotent.
24
- */
25
- export type NetworkConnectionBannerControllerStopAction = {
26
- type: `NetworkConnectionBannerController:stop`;
27
- handler: NetworkConnectionBannerController['stop'];
28
- };
29
6
  /**
30
7
  * Clears the banner state such that the banner will be hidden.
31
8
  */
@@ -34,8 +11,9 @@ export type NetworkConnectionBannerControllerDismissBannerAction = {
34
11
  handler: NetworkConnectionBannerController['dismissBanner'];
35
12
  };
36
13
  /**
37
- * Switches the chain's default RPC endpoint to its Infura endpoint,
38
- * causing the banner to clear once the network becomes available again.
14
+ * Switches the chain's default RPC endpoint to its Infura endpoint and
15
+ * makes it the active network, causing the banner to clear once the
16
+ * network becomes available again.
39
17
  *
40
18
  * @param chainId - The chain whose default RPC endpoint should be switched.
41
19
  * @throws If the chain configuration cannot be found, or if it has no
@@ -48,5 +26,5 @@ export type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAct
48
26
  /**
49
27
  * Union of all NetworkConnectionBannerController action types.
50
28
  */
51
- export type NetworkConnectionBannerControllerMethodActions = NetworkConnectionBannerControllerStartAction | NetworkConnectionBannerControllerStopAction | NetworkConnectionBannerControllerDismissBannerAction | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;
29
+ export type NetworkConnectionBannerControllerMethodActions = NetworkConnectionBannerControllerDismissBannerAction | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;
52
30
  //# sourceMappingURL=NetworkConnectionBannerController-method-action-types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkConnectionBannerController-method-action-types.d.mts","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iCAAiC,EAAE,gDAA4C;AAE7F;;;;;;;;;GASG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,iCAAiC,CAAC,OAAO,CAAC,CAAC;CACrD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,iCAAiC,CAAC,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,iCAAiC,CAAC,eAAe,CAAC,CAAC;CAC7D,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,uEAAuE,GACjF;IACE,IAAI,EAAE,oEAAoE,CAAC;IAC3E,OAAO,EAAE,iCAAiC,CAAC,kCAAkC,CAAC,CAAC;CAChF,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,8CAA8C,GACtD,4CAA4C,GAC5C,2CAA2C,GAC3C,oDAAoD,GACpD,uEAAuE,CAAC"}
1
+ {"version":3,"file":"NetworkConnectionBannerController-method-action-types.d.mts","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iCAAiC,EAAE,gDAA4C;AAE7F;;GAEG;AACH,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,iDAAiD,CAAC;IACxD,OAAO,EAAE,iCAAiC,CAAC,eAAe,CAAC,CAAC;CAC7D,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,uEAAuE,GACjF;IACE,IAAI,EAAE,oEAAoE,CAAC;IAC3E,OAAO,EAAE,iCAAiC,CAAC,kCAAkC,CAAC,CAAC;CAChF,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,8CAA8C,GACtD,oDAAoD,GACpD,uEAAuE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkConnectionBannerController-method-action-types.mjs","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NetworkConnectionBannerController } from './NetworkConnectionBannerController';\n\n/**\n * Look for a failed network, if any, and populate the initial state of the\n * banner. Reacts to upstream state changes from this point on.\n *\n * Call this when the wallet UI that consumes the banner becomes active\n * (typically when the wallet is unlocked and the home surface mounts) so\n * timers do not run while the user is not looking at the wallet. Should\n * be called after `NetworkController`, `NetworkEnablementController`, and\n * `ConnectivityController` have been initialized. Idempotent.\n */\nexport type NetworkConnectionBannerControllerStartAction = {\n type: `NetworkConnectionBannerController:start`;\n handler: NetworkConnectionBannerController['start'];\n};\n\n/**\n * Stops evaluating network connection state. Clears any pending banner\n * timers and resets state to `available`. Call this when the UI\n * consuming the banner is no longer active. Idempotent.\n */\nexport type NetworkConnectionBannerControllerStopAction = {\n type: `NetworkConnectionBannerController:stop`;\n handler: NetworkConnectionBannerController['stop'];\n};\n\n/**\n * Clears the banner state such that the banner will be hidden.\n */\nexport type NetworkConnectionBannerControllerDismissBannerAction = {\n type: `NetworkConnectionBannerController:dismissBanner`;\n handler: NetworkConnectionBannerController['dismissBanner'];\n};\n\n/**\n * Switches the chain's default RPC endpoint to its Infura endpoint,\n * causing the banner to clear once the network becomes available again.\n *\n * @param chainId - The chain whose default RPC endpoint should be switched.\n * @throws If the chain configuration cannot be found, or if it has no\n * Infura endpoint to switch to, or if the default is already Infura.\n */\nexport type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction =\n {\n type: `NetworkConnectionBannerController:switchToDefaultInfuraRpcEndpoint`;\n handler: NetworkConnectionBannerController['switchToDefaultInfuraRpcEndpoint'];\n };\n\n/**\n * Union of all NetworkConnectionBannerController action types.\n */\nexport type NetworkConnectionBannerControllerMethodActions =\n | NetworkConnectionBannerControllerStartAction\n | NetworkConnectionBannerControllerStopAction\n | NetworkConnectionBannerControllerDismissBannerAction\n | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;\n"]}
1
+ {"version":3,"file":"NetworkConnectionBannerController-method-action-types.mjs","sourceRoot":"","sources":["../src/NetworkConnectionBannerController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NetworkConnectionBannerController } from './NetworkConnectionBannerController';\n\n/**\n * Clears the banner state such that the banner will be hidden.\n */\nexport type NetworkConnectionBannerControllerDismissBannerAction = {\n type: `NetworkConnectionBannerController:dismissBanner`;\n handler: NetworkConnectionBannerController['dismissBanner'];\n};\n\n/**\n * Switches the chain's default RPC endpoint to its Infura endpoint and\n * makes it the active network, causing the banner to clear once the\n * network becomes available again.\n *\n * @param chainId - The chain whose default RPC endpoint should be switched.\n * @throws If the chain configuration cannot be found, or if it has no\n * Infura endpoint to switch to, or if the default is already Infura.\n */\nexport type NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction =\n {\n type: `NetworkConnectionBannerController:switchToDefaultInfuraRpcEndpoint`;\n handler: NetworkConnectionBannerController['switchToDefaultInfuraRpcEndpoint'];\n };\n\n/**\n * Union of all NetworkConnectionBannerController action types.\n */\nexport type NetworkConnectionBannerControllerMethodActions =\n | NetworkConnectionBannerControllerDismissBannerAction\n | NetworkConnectionBannerControllerSwitchToDefaultInfuraRpcEndpointAction;\n"]}
@@ -10,10 +10,11 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
11
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
12
  };
13
- var _NetworkConnectionBannerController_instances, _NetworkConnectionBannerController_degradedTimer, _NetworkConnectionBannerController_unavailableTimer, _NetworkConnectionBannerController_pendingNetworkClientId, _NetworkConnectionBannerController_isStarted, _NetworkConnectionBannerController_refreshState, _NetworkConnectionBannerController_resetBanner, _NetworkConnectionBannerController_clearTimers, _NetworkConnectionBannerController_findFailedNetwork, _NetworkConnectionBannerController_getEnabledEvmChainIds, _NetworkConnectionBannerController_collectNetworksWithMetadata, _NetworkConnectionBannerController_buildFailedNetwork, _NetworkConnectionBannerController_pickBannerNetwork;
13
+ var _NetworkConnectionBannerController_instances, _NetworkConnectionBannerController_degradedTimer, _NetworkConnectionBannerController_unavailableTimer, _NetworkConnectionBannerController_pendingNetworkClientId, _NetworkConnectionBannerController_isStarted, _NetworkConnectionBannerController_isUiOpen, _NetworkConnectionBannerController_isUnlocked, _NetworkConnectionBannerController_updateLifecycle, _NetworkConnectionBannerController_start, _NetworkConnectionBannerController_stop, _NetworkConnectionBannerController_refreshState, _NetworkConnectionBannerController_resetBanner, _NetworkConnectionBannerController_clearTimers, _NetworkConnectionBannerController_findFailedNetwork, _NetworkConnectionBannerController_getEnabledEvmChainIds, _NetworkConnectionBannerController_collectEnabledNetworks, _NetworkConnectionBannerController_buildFailedNetwork, _NetworkConnectionBannerController_pickFailedNetworkToDisplay;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.NetworkConnectionBannerController = exports.getDefaultNetworkConnectionBannerControllerState = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
17
+ const client_controller_1 = require("@metamask/client-controller");
17
18
  const connectivity_controller_1 = require("@metamask/connectivity-controller");
18
19
  const network_controller_1 = require("@metamask/network-controller");
19
20
  const network_enablement_controller_1 = require("@metamask/network-enablement-controller");
@@ -107,31 +108,29 @@ const DEGRADED_BANNER_TIMEOUT = 5000;
107
108
  */
108
109
  const UNAVAILABLE_BANNER_TIMEOUT = 30000;
109
110
  const MESSENGER_EXPOSED_METHODS = [
110
- 'start',
111
- 'stop',
112
111
  'dismissBanner',
113
112
  'switchToDefaultInfuraRpcEndpoint',
114
113
  ];
115
114
  /**
116
115
  * NetworkConnectionBannerController decides whether the network connection
117
116
  * banner should be shown for the user, and which failing network it should
118
- * describe. It encapsulates the rule, the 5s / 30s timer escalation, and the
119
- * eTLD+1 grouping used to decide when a wider provider outage is in play.
117
+ * describe. It encapsulates the rule and the 5s / 30s timer escalation.
120
118
  *
121
119
  * The banner shows when:
122
120
  *
123
- * - The first failing network's default RPC is a custom (non-Infura) endpoint
124
- * users always want to be informed about errors with RPCs they've chosen.
125
- * - Failed RPCs span more than one registrable domain (likely client-side).
126
- * - Every enabled EVM network with known connectivity status is failing
127
- * (escape hatch for single-network setups so they still get a signal).
121
+ * - A failing network's default RPC is a custom (non-Infura) endpoint
122
+ * users always want to be informed about errors with RPCs they've chosen.
123
+ * - Every enabled EVM network is reporting a failed connectivity status
124
+ * (escape hatch so Infura-only setups still get a signal).
128
125
  *
129
- * A wide single-provider outage (e.g. every `*.infura.io` network goes down at
130
- * once) collapses to one domain and is suppressed, except in the all-down
131
- * single-network case. When a custom failure is present, it's surfaced first
132
- * so the "Switch to MetaMask default RPC" CTA targets the network the user
133
- * can act on.
126
+ * A partial Infura outage alongside healthy peers is suppressed since it
127
+ * usually resolves on its own and the user cannot act on it. When a custom
128
+ * failure is present, it's surfaced first so the "Switch to MetaMask default
129
+ * RPC" CTA targets the network the user can act on.
134
130
  *
131
+ * The controller manages its own lifecycle: it evaluates RPC health (and
132
+ * runs the escalation timers) only while the client UI is open
133
+ * (`ClientController`) and the wallet is unlocked (`KeyringController`).
135
134
  * Clients only need to render the banner from the controller's state and wire
136
135
  * click handlers to {@link dismissBanner} or {@link switchToDefaultInfuraRpcEndpoint}.
137
136
  */
@@ -154,44 +153,45 @@ class NetworkConnectionBannerController extends base_controller_1.BaseController
154
153
  _NetworkConnectionBannerController_unavailableTimer.set(this, void 0);
155
154
  _NetworkConnectionBannerController_pendingNetworkClientId.set(this, void 0);
156
155
  _NetworkConnectionBannerController_isStarted.set(this, false);
156
+ /** Whether the client UI is open. Combined with {@link #isUnlocked}. */
157
+ _NetworkConnectionBannerController_isUiOpen.set(this, false);
158
+ /** Whether the keyring is unlocked. Combined with {@link #isUiOpen}. */
159
+ _NetworkConnectionBannerController_isUnlocked.set(this, false);
157
160
  // Upstream controllers still expose :stateChange; switch to :stateChanged
158
161
  // once those packages migrate their event types.
159
162
  /* eslint-disable no-restricted-syntax -- awaiting upstream :stateChanged migration */
160
- this.messenger.subscribe('NetworkController:stateChange', (networkControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, { networkControllerState }), selectNetworkControllerFields);
161
- this.messenger.subscribe('NetworkEnablementController:stateChange', (networkEnablementControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, { networkEnablementControllerState }), selectNetworkEnablementControllerFields);
162
- this.messenger.subscribe('ConnectivityController:stateChange', (connectivityControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, { connectivityControllerState }), selectConnectivityControllerFields);
163
+ this.messenger.subscribe('NetworkController:stateChange', (networkControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, {
164
+ networkControllerState,
165
+ networkEnablementControllerState: this.messenger.call('NetworkEnablementController:getState'),
166
+ connectivityControllerState: this.messenger.call('ConnectivityController:getState'),
167
+ }), selectNetworkControllerFields);
168
+ this.messenger.subscribe('NetworkEnablementController:stateChange', (networkEnablementControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, {
169
+ networkControllerState: this.messenger.call('NetworkController:getState'),
170
+ networkEnablementControllerState,
171
+ connectivityControllerState: this.messenger.call('ConnectivityController:getState'),
172
+ }), selectNetworkEnablementControllerFields);
173
+ this.messenger.subscribe('ConnectivityController:stateChange', (connectivityControllerState) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, {
174
+ networkControllerState: this.messenger.call('NetworkController:getState'),
175
+ networkEnablementControllerState: this.messenger.call('NetworkEnablementController:getState'),
176
+ connectivityControllerState,
177
+ }), selectConnectivityControllerFields);
163
178
  /* eslint-enable no-restricted-syntax */
179
+ // Lifecycle: evaluate RPC health (and run the banner escalation timers)
180
+ // only while the client UI is open on an unlocked wallet.
181
+ this.messenger.subscribe('ClientController:stateChanged', (isUiOpen) => {
182
+ __classPrivateFieldSet(this, _NetworkConnectionBannerController_isUiOpen, isUiOpen, "f");
183
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_updateLifecycle).call(this);
184
+ }, client_controller_1.clientControllerSelectors.selectIsUiOpen);
185
+ this.messenger.subscribe('KeyringController:unlock', () => {
186
+ __classPrivateFieldSet(this, _NetworkConnectionBannerController_isUnlocked, true, "f");
187
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_updateLifecycle).call(this);
188
+ });
189
+ this.messenger.subscribe('KeyringController:lock', () => {
190
+ __classPrivateFieldSet(this, _NetworkConnectionBannerController_isUnlocked, false, "f");
191
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_updateLifecycle).call(this);
192
+ });
164
193
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
165
194
  }
166
- /**
167
- * Look for a failed network, if any, and populate the initial state of the
168
- * banner. Reacts to upstream state changes from this point on.
169
- *
170
- * Call this when the wallet UI that consumes the banner becomes active
171
- * (typically when the wallet is unlocked and the home surface mounts) so
172
- * timers do not run while the user is not looking at the wallet. Should
173
- * be called after `NetworkController`, `NetworkEnablementController`, and
174
- * `ConnectivityController` have been initialized. Idempotent.
175
- */
176
- start() {
177
- if (__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
178
- return;
179
- }
180
- __classPrivateFieldSet(this, _NetworkConnectionBannerController_isStarted, true, "f");
181
- __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this);
182
- }
183
- /**
184
- * Stops evaluating network connection state. Clears any pending banner
185
- * timers and resets state to `available`. Call this when the UI
186
- * consuming the banner is no longer active. Idempotent.
187
- */
188
- stop() {
189
- if (!__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
190
- return;
191
- }
192
- __classPrivateFieldSet(this, _NetworkConnectionBannerController_isStarted, false, "f");
193
- __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_resetBanner).call(this);
194
- }
195
195
  /**
196
196
  * Clears the banner state such that the banner will be hidden.
197
197
  */
@@ -199,8 +199,9 @@ class NetworkConnectionBannerController extends base_controller_1.BaseController
199
199
  __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_resetBanner).call(this);
200
200
  }
201
201
  /**
202
- * Switches the chain's default RPC endpoint to its Infura endpoint,
203
- * causing the banner to clear once the network becomes available again.
202
+ * Switches the chain's default RPC endpoint to its Infura endpoint and
203
+ * makes it the active network, causing the banner to clear once the
204
+ * network becomes available again.
204
205
  *
205
206
  * @param chainId - The chain whose default RPC endpoint should be switched.
206
207
  * @throws If the chain configuration cannot be found, or if it has no
@@ -222,25 +223,50 @@ class NetworkConnectionBannerController extends base_controller_1.BaseController
222
223
  await this.messenger.call('NetworkController:updateNetwork', chainId, {
223
224
  ...networkConfiguration,
224
225
  defaultRpcEndpointIndex: infuraEndpointIndex,
225
- }, { replacementSelectedRpcEndpointIndex: infuraEndpointIndex });
226
+ });
227
+ // Move the active connection onto the Infura endpoint too, so the user
228
+ // is no longer connected to the failing endpoint.
229
+ const infuraNetworkClientId = networkConfiguration.rpcEndpoints[infuraEndpointIndex].networkClientId;
230
+ const { selectedNetworkClientId } = this.messenger.call('NetworkController:getState');
231
+ if (infuraNetworkClientId !== selectedNetworkClientId) {
232
+ await this.messenger.call('NetworkController:setActiveNetwork', infuraNetworkClientId);
233
+ }
226
234
  }
227
235
  }
228
236
  exports.NetworkConnectionBannerController = NetworkConnectionBannerController;
229
- _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnectionBannerController_unavailableTimer = new WeakMap(), _NetworkConnectionBannerController_pendingNetworkClientId = new WeakMap(), _NetworkConnectionBannerController_isStarted = new WeakMap(), _NetworkConnectionBannerController_instances = new WeakSet(), _NetworkConnectionBannerController_refreshState = function _NetworkConnectionBannerController_refreshState({ networkControllerState, networkEnablementControllerState, connectivityControllerState, } = {}) {
237
+ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnectionBannerController_unavailableTimer = new WeakMap(), _NetworkConnectionBannerController_pendingNetworkClientId = new WeakMap(), _NetworkConnectionBannerController_isStarted = new WeakMap(), _NetworkConnectionBannerController_isUiOpen = new WeakMap(), _NetworkConnectionBannerController_isUnlocked = new WeakMap(), _NetworkConnectionBannerController_instances = new WeakSet(), _NetworkConnectionBannerController_updateLifecycle = function _NetworkConnectionBannerController_updateLifecycle() {
238
+ if (__classPrivateFieldGet(this, _NetworkConnectionBannerController_isUiOpen, "f") && __classPrivateFieldGet(this, _NetworkConnectionBannerController_isUnlocked, "f")) {
239
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_start).call(this);
240
+ }
241
+ else {
242
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_stop).call(this);
243
+ }
244
+ }, _NetworkConnectionBannerController_start = function _NetworkConnectionBannerController_start() {
245
+ if (__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
246
+ return;
247
+ }
248
+ __classPrivateFieldSet(this, _NetworkConnectionBannerController_isStarted, true, "f");
249
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_refreshState).call(this, {
250
+ networkControllerState: this.messenger.call('NetworkController:getState'),
251
+ networkEnablementControllerState: this.messenger.call('NetworkEnablementController:getState'),
252
+ connectivityControllerState: this.messenger.call('ConnectivityController:getState'),
253
+ });
254
+ }, _NetworkConnectionBannerController_stop = function _NetworkConnectionBannerController_stop() {
255
+ if (!__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
256
+ return;
257
+ }
258
+ __classPrivateFieldSet(this, _NetworkConnectionBannerController_isStarted, false, "f");
259
+ __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_resetBanner).call(this);
260
+ }, _NetworkConnectionBannerController_refreshState = function _NetworkConnectionBannerController_refreshState({ networkControllerState, networkEnablementControllerState, connectivityControllerState, }) {
230
261
  if (!__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
231
262
  return;
232
263
  }
233
- const { connectivityStatus } = connectivityControllerState ??
234
- this.messenger.call('ConnectivityController:getState');
235
- if (connectivityStatus === connectivity_controller_1.CONNECTIVITY_STATUSES.Offline) {
264
+ if (connectivityControllerState.connectivityStatus ===
265
+ connectivity_controller_1.CONNECTIVITY_STATUSES.Offline) {
236
266
  __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_resetBanner).call(this);
237
267
  return;
238
268
  }
239
- const networkState = networkControllerState ??
240
- this.messenger.call('NetworkController:getState');
241
- const enablementState = networkEnablementControllerState ??
242
- this.messenger.call('NetworkEnablementController:getState');
243
- const failedNetwork = __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_findFailedNetwork).call(this, networkState, enablementState);
269
+ const failedNetwork = __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_findFailedNetwork).call(this, networkControllerState, networkEnablementControllerState);
244
270
  if (!failedNetwork) {
245
271
  __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_resetBanner).call(this);
246
272
  return;
@@ -249,10 +275,16 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
249
275
  this.state.networkConnectionBannerNetwork?.networkClientId ===
250
276
  failedNetwork.networkClientId) {
251
277
  this.update((state) => {
278
+ // Even if the network client ID has not changed, save the current
279
+ // version of the failed network to state in case the user has updated
280
+ // its RPC URL.
252
281
  state.networkConnectionBannerNetwork = failedNetwork;
253
282
  });
254
283
  return;
255
284
  }
285
+ // A degraded timer is already counting down for this same network.
286
+ // Repeated `stateChange` events must not clear and restart it, or a
287
+ // steady stream of updates could postpone the banner indefinitely.
256
288
  if (__classPrivateFieldGet(this, _NetworkConnectionBannerController_pendingNetworkClientId, "f") === failedNetwork.networkClientId) {
257
289
  return;
258
290
  }
@@ -261,15 +293,15 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
261
293
  state.networkConnectionBannerStatus = 'available';
262
294
  state.networkConnectionBannerNetwork = null;
263
295
  });
264
- // A synchronous listener on our `stateChanged` event above may have
265
- // called `stop()` re-entrantly. Bail before scheduling anything.
296
+ // If `stop` is called before scheduling timers, bail early.
266
297
  if (!__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
267
298
  return;
268
299
  }
269
- // Capture the failing network at schedule time. We trust the messenger
270
- // contract: if the failure resolves or the target changes during the
271
- // wait, our upstream subscriptions will have cancelled or replaced this
272
- // timer via `#clearTimers` before it fires.
300
+ // Remember which network the pending timer is for (see the guard above)
301
+ // and capture the failing network at schedule time. If the failure
302
+ // resolves or a different network becomes the banner target while we
303
+ // wait, the subscription handlers re-enter this method and cancel or
304
+ // replace the timer before it fires.
273
305
  __classPrivateFieldSet(this, _NetworkConnectionBannerController_pendingNetworkClientId, failedNetwork.networkClientId, "f");
274
306
  __classPrivateFieldSet(this, _NetworkConnectionBannerController_degradedTimer, setTimeout(() => {
275
307
  __classPrivateFieldSet(this, _NetworkConnectionBannerController_degradedTimer, undefined, "f");
@@ -278,8 +310,7 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
278
310
  state.networkConnectionBannerStatus = 'degraded';
279
311
  state.networkConnectionBannerNetwork = failedNetwork;
280
312
  });
281
- // A synchronous listener on our `stateChanged` event above may have
282
- // called `stop()` re-entrantly. Bail before scheduling the escalation.
313
+ // If `stop` is called before scheduling timers, bail early.
283
314
  if (!__classPrivateFieldGet(this, _NetworkConnectionBannerController_isStarted, "f")) {
284
315
  return;
285
316
  }
@@ -311,16 +342,17 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
311
342
  __classPrivateFieldSet(this, _NetworkConnectionBannerController_unavailableTimer, undefined, "f");
312
343
  }
313
344
  }, _NetworkConnectionBannerController_findFailedNetwork = function _NetworkConnectionBannerController_findFailedNetwork(networkState, enablementState) {
314
- const networksWithMetadata = __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_collectNetworksWithMetadata).call(this, networkState, enablementState);
315
- const failedNetworks = networksWithMetadata
316
- .filter(({ metadata }) => metadata.status !== network_controller_1.NetworkStatus.Available)
345
+ const enabledNetworks = __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_collectEnabledNetworks).call(this, networkState, enablementState);
346
+ // Networks whose connectivity has not been looked up yet are not failed.
347
+ const failedNetworks = enabledNetworks
348
+ .filter(({ metadata }) => metadata !== undefined && metadata.status !== network_controller_1.NetworkStatus.Available)
317
349
  .map((network) => __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_buildFailedNetwork).call(this, network));
318
- return __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_pickBannerNetwork).call(this, failedNetworks, networksWithMetadata.length);
350
+ return __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_pickFailedNetworkToDisplay).call(this, failedNetworks, enabledNetworks.length);
319
351
  }, _NetworkConnectionBannerController_getEnabledEvmChainIds = function _NetworkConnectionBannerController_getEnabledEvmChainIds(enabledNetworkMap) {
320
352
  return Object.entries(enabledNetworkMap[utils_1.KnownCaipNamespace.Eip155] ?? {})
321
353
  .filter(([, enabled]) => enabled)
322
354
  .map(([chainId]) => chainId);
323
- }, _NetworkConnectionBannerController_collectNetworksWithMetadata = function _NetworkConnectionBannerController_collectNetworksWithMetadata({ networkConfigurationsByChainId, networksMetadata, }, { enabledNetworkMap, }) {
355
+ }, _NetworkConnectionBannerController_collectEnabledNetworks = function _NetworkConnectionBannerController_collectEnabledNetworks({ networkConfigurationsByChainId, networksMetadata, }, { enabledNetworkMap, }) {
324
356
  return __classPrivateFieldGet(this, _NetworkConnectionBannerController_instances, "m", _NetworkConnectionBannerController_getEnabledEvmChainIds).call(this, enabledNetworkMap).flatMap((chainId) => {
325
357
  const networkConfiguration = networkConfigurationsByChainId[chainId];
326
358
  if (!networkConfiguration) {
@@ -331,10 +363,6 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
331
363
  if (!defaultRpcEndpoint) {
332
364
  return [];
333
365
  }
334
- const metadata = networksMetadata[defaultRpcEndpoint.networkClientId];
335
- if (!metadata) {
336
- return [];
337
- }
338
366
  return [
339
367
  {
340
368
  chainId,
@@ -342,7 +370,7 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
342
370
  rpcEndpoints,
343
371
  defaultRpcEndpointIndex,
344
372
  defaultRpcEndpoint,
345
- metadata,
373
+ metadata: networksMetadata[defaultRpcEndpoint.networkClientId],
346
374
  },
347
375
  ];
348
376
  });
@@ -363,20 +391,14 @@ _NetworkConnectionBannerController_degradedTimer = new WeakMap(), _NetworkConnec
363
391
  rpcUrl: defaultRpcEndpoint.url,
364
392
  isInfuraEndpoint,
365
393
  switchableInfuraNetworkClientId,
366
- domain: (0, url_utils_1.getDomain)(defaultRpcEndpoint.url),
367
394
  };
368
- }, _NetworkConnectionBannerController_pickBannerNetwork = function _NetworkConnectionBannerController_pickBannerNetwork(failedNetworks, totalNetworksWithMetadata) {
395
+ }, _NetworkConnectionBannerController_pickFailedNetworkToDisplay = function _NetworkConnectionBannerController_pickFailedNetworkToDisplay(failedNetworks, totalEnabledNetworks) {
369
396
  if (failedNetworks.length === 0) {
370
397
  return null;
371
398
  }
372
399
  const firstCustomFailed = failedNetworks.find((entry) => !entry.isInfuraEndpoint);
373
- const distinctDomains = new Set(failedNetworks
374
- .map((entry) => entry.domain)
375
- .filter((domain) => domain !== null)).size;
376
- const areAllKnownNetworksFailed = failedNetworks.length === totalNetworksWithMetadata;
377
- if (!firstCustomFailed &&
378
- distinctDomains <= 1 &&
379
- !areAllKnownNetworksFailed) {
400
+ const areAllEnabledNetworksFailed = failedNetworks.length === totalEnabledNetworks;
401
+ if (!firstCustomFailed && !areAllEnabledNetworksFailed) {
380
402
  return null;
381
403
  }
382
404
  return firstCustomFailed ?? failedNetworks[0];