@metamask-previews/account-tree-controller 0.10.0-preview-541d905c → 0.10.0-preview-b2b44c46

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 (192) hide show
  1. package/CHANGELOG.md +0 -17
  2. package/dist/AccountTreeController.cjs +3 -81
  3. package/dist/AccountTreeController.cjs.map +1 -1
  4. package/dist/AccountTreeController.d.cts +3 -19
  5. package/dist/AccountTreeController.d.cts.map +1 -1
  6. package/dist/AccountTreeController.d.mts +3 -19
  7. package/dist/AccountTreeController.d.mts.map +1 -1
  8. package/dist/AccountTreeController.mjs +3 -81
  9. package/dist/AccountTreeController.mjs.map +1 -1
  10. package/dist/types.cjs.map +1 -1
  11. package/dist/types.d.cts +1 -14
  12. package/dist/types.d.cts.map +1 -1
  13. package/dist/types.d.mts +1 -14
  14. package/dist/types.d.mts.map +1 -1
  15. package/dist/types.mjs.map +1 -1
  16. package/package.json +1 -6
  17. package/dist/backup-and-sync/analytics/index.cjs +0 -19
  18. package/dist/backup-and-sync/analytics/index.cjs.map +0 -1
  19. package/dist/backup-and-sync/analytics/index.d.cts +0 -3
  20. package/dist/backup-and-sync/analytics/index.d.cts.map +0 -1
  21. package/dist/backup-and-sync/analytics/index.d.mts +0 -3
  22. package/dist/backup-and-sync/analytics/index.d.mts.map +0 -1
  23. package/dist/backup-and-sync/analytics/index.mjs +0 -3
  24. package/dist/backup-and-sync/analytics/index.mjs.map +0 -1
  25. package/dist/backup-and-sync/analytics/segment.cjs +0 -32
  26. package/dist/backup-and-sync/analytics/segment.cjs.map +0 -1
  27. package/dist/backup-and-sync/analytics/segment.d.cts +0 -34
  28. package/dist/backup-and-sync/analytics/segment.d.cts.map +0 -1
  29. package/dist/backup-and-sync/analytics/segment.d.mts +0 -34
  30. package/dist/backup-and-sync/analytics/segment.d.mts.map +0 -1
  31. package/dist/backup-and-sync/analytics/segment.mjs +0 -28
  32. package/dist/backup-and-sync/analytics/segment.mjs.map +0 -1
  33. package/dist/backup-and-sync/analytics/traces.cjs +0 -24
  34. package/dist/backup-and-sync/analytics/traces.cjs.map +0 -1
  35. package/dist/backup-and-sync/analytics/traces.d.cts +0 -16
  36. package/dist/backup-and-sync/analytics/traces.d.cts.map +0 -1
  37. package/dist/backup-and-sync/analytics/traces.d.mts +0 -16
  38. package/dist/backup-and-sync/analytics/traces.d.mts.map +0 -1
  39. package/dist/backup-and-sync/analytics/traces.mjs +0 -20
  40. package/dist/backup-and-sync/analytics/traces.mjs.map +0 -1
  41. package/dist/backup-and-sync/authentication/index.cjs +0 -18
  42. package/dist/backup-and-sync/authentication/index.cjs.map +0 -1
  43. package/dist/backup-and-sync/authentication/index.d.cts +0 -2
  44. package/dist/backup-and-sync/authentication/index.d.cts.map +0 -1
  45. package/dist/backup-and-sync/authentication/index.d.mts +0 -2
  46. package/dist/backup-and-sync/authentication/index.d.mts.map +0 -1
  47. package/dist/backup-and-sync/authentication/index.mjs +0 -2
  48. package/dist/backup-and-sync/authentication/index.mjs.map +0 -1
  49. package/dist/backup-and-sync/authentication/utils.cjs +0 -16
  50. package/dist/backup-and-sync/authentication/utils.cjs.map +0 -1
  51. package/dist/backup-and-sync/authentication/utils.d.cts +0 -10
  52. package/dist/backup-and-sync/authentication/utils.d.cts.map +0 -1
  53. package/dist/backup-and-sync/authentication/utils.d.mts +0 -10
  54. package/dist/backup-and-sync/authentication/utils.d.mts.map +0 -1
  55. package/dist/backup-and-sync/authentication/utils.mjs +0 -12
  56. package/dist/backup-and-sync/authentication/utils.mjs.map +0 -1
  57. package/dist/backup-and-sync/service/atomic-sync-queue.cjs +0 -121
  58. package/dist/backup-and-sync/service/atomic-sync-queue.cjs.map +0 -1
  59. package/dist/backup-and-sync/service/atomic-sync-queue.d.cts +0 -39
  60. package/dist/backup-and-sync/service/atomic-sync-queue.d.cts.map +0 -1
  61. package/dist/backup-and-sync/service/atomic-sync-queue.d.mts +0 -39
  62. package/dist/backup-and-sync/service/atomic-sync-queue.d.mts.map +0 -1
  63. package/dist/backup-and-sync/service/atomic-sync-queue.mjs +0 -117
  64. package/dist/backup-and-sync/service/atomic-sync-queue.mjs.map +0 -1
  65. package/dist/backup-and-sync/service/index.cjs +0 -300
  66. package/dist/backup-and-sync/service/index.cjs.map +0 -1
  67. package/dist/backup-and-sync/service/index.d.cts +0 -58
  68. package/dist/backup-and-sync/service/index.d.cts.map +0 -1
  69. package/dist/backup-and-sync/service/index.d.mts +0 -58
  70. package/dist/backup-and-sync/service/index.d.mts.map +0 -1
  71. package/dist/backup-and-sync/service/index.mjs +0 -296
  72. package/dist/backup-and-sync/service/index.mjs.map +0 -1
  73. package/dist/backup-and-sync/syncing/group.cjs +0 -179
  74. package/dist/backup-and-sync/syncing/group.cjs.map +0 -1
  75. package/dist/backup-and-sync/syncing/group.d.cts +0 -33
  76. package/dist/backup-and-sync/syncing/group.d.cts.map +0 -1
  77. package/dist/backup-and-sync/syncing/group.d.mts +0 -33
  78. package/dist/backup-and-sync/syncing/group.d.mts.map +0 -1
  79. package/dist/backup-and-sync/syncing/group.mjs +0 -173
  80. package/dist/backup-and-sync/syncing/group.mjs.map +0 -1
  81. package/dist/backup-and-sync/syncing/index.cjs +0 -21
  82. package/dist/backup-and-sync/syncing/index.cjs.map +0 -1
  83. package/dist/backup-and-sync/syncing/index.d.cts +0 -5
  84. package/dist/backup-and-sync/syncing/index.d.cts.map +0 -1
  85. package/dist/backup-and-sync/syncing/index.d.mts +0 -5
  86. package/dist/backup-and-sync/syncing/index.d.mts.map +0 -1
  87. package/dist/backup-and-sync/syncing/index.mjs +0 -5
  88. package/dist/backup-and-sync/syncing/index.mjs.map +0 -1
  89. package/dist/backup-and-sync/syncing/legacy.cjs +0 -39
  90. package/dist/backup-and-sync/syncing/legacy.cjs.map +0 -1
  91. package/dist/backup-and-sync/syncing/legacy.d.cts +0 -17
  92. package/dist/backup-and-sync/syncing/legacy.d.cts.map +0 -1
  93. package/dist/backup-and-sync/syncing/legacy.d.mts +0 -17
  94. package/dist/backup-and-sync/syncing/legacy.d.mts.map +0 -1
  95. package/dist/backup-and-sync/syncing/legacy.mjs +0 -34
  96. package/dist/backup-and-sync/syncing/legacy.mjs.map +0 -1
  97. package/dist/backup-and-sync/syncing/metadata.cjs +0 -51
  98. package/dist/backup-and-sync/syncing/metadata.cjs.map +0 -1
  99. package/dist/backup-and-sync/syncing/metadata.d.cts +0 -38
  100. package/dist/backup-and-sync/syncing/metadata.d.cts.map +0 -1
  101. package/dist/backup-and-sync/syncing/metadata.d.mts +0 -38
  102. package/dist/backup-and-sync/syncing/metadata.d.mts.map +0 -1
  103. package/dist/backup-and-sync/syncing/metadata.mjs +0 -47
  104. package/dist/backup-and-sync/syncing/metadata.mjs.map +0 -1
  105. package/dist/backup-and-sync/syncing/wallet.cjs +0 -67
  106. package/dist/backup-and-sync/syncing/wallet.cjs.map +0 -1
  107. package/dist/backup-and-sync/syncing/wallet.d.cts +0 -22
  108. package/dist/backup-and-sync/syncing/wallet.d.cts.map +0 -1
  109. package/dist/backup-and-sync/syncing/wallet.d.mts +0 -22
  110. package/dist/backup-and-sync/syncing/wallet.d.mts.map +0 -1
  111. package/dist/backup-and-sync/syncing/wallet.mjs +0 -62
  112. package/dist/backup-and-sync/syncing/wallet.mjs.map +0 -1
  113. package/dist/backup-and-sync/types.cjs +0 -31
  114. package/dist/backup-and-sync/types.cjs.map +0 -1
  115. package/dist/backup-and-sync/types.d.cts +0 -99
  116. package/dist/backup-and-sync/types.d.cts.map +0 -1
  117. package/dist/backup-and-sync/types.d.mts +0 -99
  118. package/dist/backup-and-sync/types.d.mts.map +0 -1
  119. package/dist/backup-and-sync/types.mjs +0 -28
  120. package/dist/backup-and-sync/types.mjs.map +0 -1
  121. package/dist/backup-and-sync/user-storage/constants.cjs +0 -7
  122. package/dist/backup-and-sync/user-storage/constants.cjs.map +0 -1
  123. package/dist/backup-and-sync/user-storage/constants.d.cts +0 -4
  124. package/dist/backup-and-sync/user-storage/constants.d.cts.map +0 -1
  125. package/dist/backup-and-sync/user-storage/constants.d.mts +0 -4
  126. package/dist/backup-and-sync/user-storage/constants.d.mts.map +0 -1
  127. package/dist/backup-and-sync/user-storage/constants.mjs +0 -4
  128. package/dist/backup-and-sync/user-storage/constants.mjs.map +0 -1
  129. package/dist/backup-and-sync/user-storage/format-utils.cjs +0 -82
  130. package/dist/backup-and-sync/user-storage/format-utils.cjs.map +0 -1
  131. package/dist/backup-and-sync/user-storage/format-utils.d.cts +0 -45
  132. package/dist/backup-and-sync/user-storage/format-utils.d.cts.map +0 -1
  133. package/dist/backup-and-sync/user-storage/format-utils.d.mts +0 -45
  134. package/dist/backup-and-sync/user-storage/format-utils.d.mts.map +0 -1
  135. package/dist/backup-and-sync/user-storage/format-utils.mjs +0 -75
  136. package/dist/backup-and-sync/user-storage/format-utils.mjs.map +0 -1
  137. package/dist/backup-and-sync/user-storage/index.cjs +0 -21
  138. package/dist/backup-and-sync/user-storage/index.cjs.map +0 -1
  139. package/dist/backup-and-sync/user-storage/index.d.cts +0 -5
  140. package/dist/backup-and-sync/user-storage/index.d.cts.map +0 -1
  141. package/dist/backup-and-sync/user-storage/index.d.mts +0 -5
  142. package/dist/backup-and-sync/user-storage/index.d.mts.map +0 -1
  143. package/dist/backup-and-sync/user-storage/index.mjs +0 -5
  144. package/dist/backup-and-sync/user-storage/index.mjs.map +0 -1
  145. package/dist/backup-and-sync/user-storage/network-operations.cjs +0 -153
  146. package/dist/backup-and-sync/user-storage/network-operations.cjs.map +0 -1
  147. package/dist/backup-and-sync/user-storage/network-operations.d.cts +0 -68
  148. package/dist/backup-and-sync/user-storage/network-operations.d.cts.map +0 -1
  149. package/dist/backup-and-sync/user-storage/network-operations.d.mts +0 -68
  150. package/dist/backup-and-sync/user-storage/network-operations.d.mts.map +0 -1
  151. package/dist/backup-and-sync/user-storage/network-operations.mjs +0 -143
  152. package/dist/backup-and-sync/user-storage/network-operations.mjs.map +0 -1
  153. package/dist/backup-and-sync/user-storage/network-utils.cjs +0 -32
  154. package/dist/backup-and-sync/user-storage/network-utils.cjs.map +0 -1
  155. package/dist/backup-and-sync/user-storage/network-utils.d.cts +0 -10
  156. package/dist/backup-and-sync/user-storage/network-utils.d.cts.map +0 -1
  157. package/dist/backup-and-sync/user-storage/network-utils.d.mts +0 -10
  158. package/dist/backup-and-sync/user-storage/network-utils.d.mts.map +0 -1
  159. package/dist/backup-and-sync/user-storage/network-utils.mjs +0 -28
  160. package/dist/backup-and-sync/user-storage/network-utils.mjs.map +0 -1
  161. package/dist/backup-and-sync/user-storage/validation.cjs +0 -50
  162. package/dist/backup-and-sync/user-storage/validation.cjs.map +0 -1
  163. package/dist/backup-and-sync/user-storage/validation.d.cts +0 -16
  164. package/dist/backup-and-sync/user-storage/validation.d.cts.map +0 -1
  165. package/dist/backup-and-sync/user-storage/validation.d.mts +0 -16
  166. package/dist/backup-and-sync/user-storage/validation.d.mts.map +0 -1
  167. package/dist/backup-and-sync/user-storage/validation.mjs +0 -45
  168. package/dist/backup-and-sync/user-storage/validation.mjs.map +0 -1
  169. package/dist/backup-and-sync/utils/contextual-logger.cjs +0 -15
  170. package/dist/backup-and-sync/utils/contextual-logger.cjs.map +0 -1
  171. package/dist/backup-and-sync/utils/contextual-logger.d.cts +0 -11
  172. package/dist/backup-and-sync/utils/contextual-logger.d.cts.map +0 -1
  173. package/dist/backup-and-sync/utils/contextual-logger.d.mts +0 -11
  174. package/dist/backup-and-sync/utils/contextual-logger.d.mts.map +0 -1
  175. package/dist/backup-and-sync/utils/contextual-logger.mjs +0 -12
  176. package/dist/backup-and-sync/utils/contextual-logger.mjs.map +0 -1
  177. package/dist/backup-and-sync/utils/controller.cjs +0 -71
  178. package/dist/backup-and-sync/utils/controller.cjs.map +0 -1
  179. package/dist/backup-and-sync/utils/controller.d.cts +0 -48
  180. package/dist/backup-and-sync/utils/controller.d.cts.map +0 -1
  181. package/dist/backup-and-sync/utils/controller.d.mts +0 -48
  182. package/dist/backup-and-sync/utils/controller.d.mts.map +0 -1
  183. package/dist/backup-and-sync/utils/controller.mjs +0 -64
  184. package/dist/backup-and-sync/utils/controller.mjs.map +0 -1
  185. package/dist/backup-and-sync/utils/index.cjs +0 -19
  186. package/dist/backup-and-sync/utils/index.cjs.map +0 -1
  187. package/dist/backup-and-sync/utils/index.d.cts +0 -3
  188. package/dist/backup-and-sync/utils/index.d.cts.map +0 -1
  189. package/dist/backup-and-sync/utils/index.d.mts +0 -3
  190. package/dist/backup-and-sync/utils/index.d.mts.map +0 -1
  191. package/dist/backup-and-sync/utils/index.mjs +0 -3
  192. package/dist/backup-and-sync/utils/index.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,23 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
11
-
12
- - Add backup and sync capabilities ([#6344](https://github.com/MetaMask/core/pull/6344))
13
- - New `syncWithUserStorage()` method for manual sync triggers, replacing `UserStorageController:syncInternalAccountsWithUserStorage` usage in clients
14
- - `BackupAndSyncService` with full and atomic sync operations for account tree data persistence
15
- - Bidirectional metadata synchronization for wallets and groups with user storage
16
- - Automatic sync triggers on metadata changes (rename, pin/hide operations) with superstruct validation
17
- - New `isBackupAndSyncInProgress` state property to track sync status
18
- - Analytics event tracking and performance tracing for sync operations
19
- - Rollback mechanism for failed sync operations with state snapshot/restore capabilities
20
- - Support for entropy-based wallets with multichain account syncing
21
- - Legacy account syncing compatibility for seamless migration
22
- - Optional configuration through new `AccountTreeControllerConfig.backupAndSync` options
23
- - Add new dependencies for sync functionality
24
- - `@metamask/superstruct` for data validation
25
- - `@metamask/profile-sync-controller` and `@metamask/multichain-account-service` peer dependencies
26
-
27
10
  ### Changed
28
11
 
29
12
  - Bump `@metamask/base-controller` from `^8.1.0` to `^8.2.0` ([#6355](https://github.com/MetaMask/core/pull/6355))
@@ -10,14 +10,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _AccountTreeController_instances, _AccountTreeController_serviceStartTime, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_syncingService, _AccountTreeController_newGroupsMap, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_disableMultichainAccountSyncing, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_handleAccountRenamed, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_registerMessageHandlers, _AccountTreeController_createBackupAndSyncContext;
13
+ var _AccountTreeController_instances, _AccountTreeController_serviceStartTime, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_newGroupsMap, _AccountTreeController_rules, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_handleAccountRenamed, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_registerMessageHandlers;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.AccountTreeController = exports.getDefaultAccountTreeControllerState = exports.controllerName = void 0;
16
16
  const account_api_1 = require("@metamask/account-api");
17
17
  const base_controller_1 = require("@metamask/base-controller");
18
18
  const keyring_api_1 = require("@metamask/keyring-api");
19
- const analytics_1 = require("./backup-and-sync/analytics/index.cjs");
20
- const service_1 = require("./backup-and-sync/service/index.cjs");
21
19
  const entropy_1 = require("./rules/entropy.cjs");
22
20
  const keyring_1 = require("./rules/keyring.cjs");
23
21
  const snap_1 = require("./rules/snap.cjs");
@@ -27,14 +25,6 @@ const accountTreeControllerMetadata = {
27
25
  persist: false,
28
26
  anonymous: false,
29
27
  },
30
- isAccountTreeSyncingInProgress: {
31
- persist: false,
32
- anonymous: false,
33
- },
34
- hasAccountTreeSyncingSyncedAtLeastOnce: {
35
- persist: true,
36
- anonymous: false,
37
- },
38
28
  accountGroupsMetadata: {
39
29
  persist: true,
40
30
  anonymous: false,
@@ -55,8 +45,6 @@ function getDefaultAccountTreeControllerState() {
55
45
  wallets: {},
56
46
  selectedAccountGroup: '',
57
47
  },
58
- isAccountTreeSyncingInProgress: false,
59
- hasAccountTreeSyncingSyncedAtLeastOnce: false,
60
48
  accountGroupsMetadata: {},
61
49
  accountWalletsMetadata: {},
62
50
  };
@@ -70,9 +58,8 @@ class AccountTreeController extends base_controller_1.BaseController {
70
58
  * @param options - The controller options.
71
59
  * @param options.messenger - The messenger object.
72
60
  * @param options.state - Initial state to set on this controller
73
- * @param options.config - Optional configuration for the controller.
74
61
  */
75
- constructor({ messenger, state, config, }) {
62
+ constructor({ messenger, state, }) {
76
63
  super({
77
64
  messenger,
78
65
  name: exports.controllerName,
@@ -86,33 +73,12 @@ class AccountTreeController extends base_controller_1.BaseController {
86
73
  _AccountTreeController_serviceStartTime.set(this, Date.now());
87
74
  _AccountTreeController_accountIdToContext.set(this, void 0);
88
75
  _AccountTreeController_groupIdToWalletId.set(this, void 0);
89
- /**
90
- * Service responsible for all backup and sync operations.
91
- */
92
- _AccountTreeController_syncingService.set(this, void 0);
93
76
  _AccountTreeController_newGroupsMap.set(this, void 0);
94
77
  _AccountTreeController_rules.set(this, void 0);
95
- _AccountTreeController_trace.set(this, void 0);
96
- _AccountTreeController_backupAndSyncConfig.set(this, void 0);
97
- // Temporary: ensures we can release updates to AccountTreeController without
98
- // breaking changes while we transition to the new multichain syncing approach.
99
- _AccountTreeController_disableMultichainAccountSyncing.set(this, false);
100
78
  // Reverse map to allow fast node access from an account ID.
101
79
  __classPrivateFieldSet(this, _AccountTreeController_accountIdToContext, new Map(), "f");
102
80
  // Reverse map to allow fast wallet node access from a group ID.
103
81
  __classPrivateFieldSet(this, _AccountTreeController_groupIdToWalletId, new Map(), "f");
104
- // Initialize trace function before syncing service
105
- __classPrivateFieldSet(this, _AccountTreeController_trace, config?.trace ?? analytics_1.traceFallback, "f");
106
- // Initialize backup and sync config before syncing service
107
- __classPrivateFieldSet(this, _AccountTreeController_backupAndSyncConfig, {
108
- emitBackupAndSyncEvent: (event) => {
109
- const formattedEvent = (0, analytics_1.formatAnalyticsEvent)(event);
110
- return config?.backupAndSync?.onBackupAndSyncEvent?.(formattedEvent);
111
- },
112
- enableDebugLogging: config?.backupAndSync?.enableDebugLogging ?? false,
113
- }, "f");
114
- // Initialize the syncing service
115
- __classPrivateFieldSet(this, _AccountTreeController_syncingService, new service_1.BackupAndSyncService(__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_createBackupAndSyncContext).call(this)), "f");
116
82
  // Temporary map to track which groups contain new accounts (for naming optimization)
117
83
  __classPrivateFieldSet(this, _AccountTreeController_newGroupsMap, new WeakMap(), "f");
118
84
  // Rules to apply to construct the wallets tree.
@@ -295,8 +261,6 @@ class AccountTreeController extends base_controller_1.BaseController {
295
261
  name;
296
262
  }
297
263
  });
298
- // Trigger atomic sync for group rename
299
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleGroupSync(groupId);
300
264
  }
301
265
  /**
302
266
  * Sets a custom name for an account wallet.
@@ -319,8 +283,6 @@ class AccountTreeController extends base_controller_1.BaseController {
319
283
  // Update tree node directly
320
284
  state.accountTree.wallets[walletId].metadata.name = name;
321
285
  });
322
- // Trigger atomic sync for wallet rename
323
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleWalletSync(walletId);
324
286
  }
325
287
  /**
326
288
  * Toggles the pinned state of an account group.
@@ -347,8 +309,6 @@ class AccountTreeController extends base_controller_1.BaseController {
347
309
  pinned;
348
310
  }
349
311
  });
350
- // Trigger atomic sync for group pinning
351
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleGroupSync(groupId);
352
312
  }
353
313
  /**
354
314
  * Toggles the hidden state of an account group.
@@ -375,29 +335,10 @@ class AccountTreeController extends base_controller_1.BaseController {
375
335
  hidden;
376
336
  }
377
337
  });
378
- // Trigger atomic sync for group hiding
379
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleGroupSync(groupId);
380
- }
381
- /**
382
- * Clears all persisted metadata and syncing state.
383
- *
384
- * This will reset the account groups and wallets metadata, as well as
385
- * the syncing state. This should be used when we want to
386
- * completely reset the controller's state.
387
- */
388
- clearPersistedMetadataAndSyncingState() {
389
- this.update((state) => {
390
- state.accountGroupsMetadata = {};
391
- state.accountWalletsMetadata = {};
392
- state.hasAccountTreeSyncingSyncedAtLeastOnce = false;
393
- });
394
- }
395
- async syncWithUserStorage() {
396
- return __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").performFullSync();
397
338
  }
398
339
  }
399
340
  exports.AccountTreeController = AccountTreeController;
400
- _AccountTreeController_serviceStartTime = new WeakMap(), _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_groupIdToWalletId = new WeakMap(), _AccountTreeController_syncingService = new WeakMap(), _AccountTreeController_newGroupsMap = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_trace = new WeakMap(), _AccountTreeController_backupAndSyncConfig = new WeakMap(), _AccountTreeController_disableMultichainAccountSyncing = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getEntropyRule = function _AccountTreeController_getEntropyRule() {
341
+ _AccountTreeController_serviceStartTime = new WeakMap(), _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_groupIdToWalletId = new WeakMap(), _AccountTreeController_newGroupsMap = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getEntropyRule = function _AccountTreeController_getEntropyRule() {
401
342
  return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[0];
402
343
  }, _AccountTreeController_getSnapRule = function _AccountTreeController_getSnapRule() {
403
344
  return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[1];
@@ -571,10 +512,6 @@ _AccountTreeController_serviceStartTime = new WeakMap(), _AccountTreeController_
571
512
  // the union tag `result.wallet.type`.
572
513
  };
573
514
  wallet = wallets[walletId];
574
- // Trigger atomic sync for new wallet (only for entropy wallets)
575
- if (wallet.type === account_api_1.AccountWalletType.Entropy) {
576
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleWalletSync(walletId);
577
- }
578
515
  }
579
516
  const groupId = result.group.id;
580
517
  let group = wallet.groups[groupId];
@@ -597,10 +534,6 @@ _AccountTreeController_serviceStartTime = new WeakMap(), _AccountTreeController_
597
534
  __classPrivateFieldGet(this, _AccountTreeController_newGroupsMap, "f").set(group, isNewAccount);
598
535
  // Map group ID to its containing wallet ID for efficient direct access
599
536
  __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").set(groupId, walletId);
600
- // Trigger atomic sync for new group (only for entropy wallets)
601
- if (wallet.type === account_api_1.AccountWalletType.Entropy) {
602
- __classPrivateFieldGet(this, _AccountTreeController_syncingService, "f").enqueueSingleGroupSync(groupId);
603
- }
604
537
  }
605
538
  else {
606
539
  // If adding to existing group, update the "new" status if this account is new
@@ -699,16 +632,5 @@ _AccountTreeController_serviceStartTime = new WeakMap(), _AccountTreeController_
699
632
  this.messagingSystem.registerActionHandler(`${exports.controllerName}:getSelectedAccountGroup`, this.getSelectedAccountGroup.bind(this));
700
633
  this.messagingSystem.registerActionHandler(`${exports.controllerName}:setSelectedAccountGroup`, this.setSelectedAccountGroup.bind(this));
701
634
  this.messagingSystem.registerActionHandler(`${exports.controllerName}:getAccountsFromSelectedAccountGroup`, this.getAccountsFromSelectedAccountGroup.bind(this));
702
- }, _AccountTreeController_createBackupAndSyncContext = function _AccountTreeController_createBackupAndSyncContext() {
703
- return {
704
- controller: this,
705
- messenger: this.messagingSystem,
706
- controllerStateUpdateFn: this.update.bind(this),
707
- traceFn: __classPrivateFieldGet(this, _AccountTreeController_trace, "f").bind(this),
708
- emitAnalyticsEventFn: __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncConfig, "f").emitBackupAndSyncEvent.bind(this),
709
- enableDebugLogging: __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncConfig, "f").enableDebugLogging,
710
- disableMultichainAccountSyncing: __classPrivateFieldGet(this, _AccountTreeController_disableMultichainAccountSyncing, "f"),
711
- groupIdToWalletId: __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f"),
712
- };
713
635
  };
714
636
  //# sourceMappingURL=AccountTreeController.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountGroupId,\n AccountWalletId,\n AccountGroupType,\n AccountSelector,\n} from '@metamask/account-api';\nimport { AccountWalletType, select } from '@metamask/account-api';\nimport { type AccountId } from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { BackupAndSyncEmitAnalyticsEventParams } from './backup-and-sync/analytics';\nimport {\n formatAnalyticsEvent,\n traceFallback,\n} from './backup-and-sync/analytics';\nimport { BackupAndSyncService } from './backup-and-sync/service';\nimport type { BackupAndSyncContext } from './backup-and-sync/types';\nimport type { AccountGroupObject } from './group';\nimport type { Rule } from './rule';\nimport { EntropyRule } from './rules/entropy';\nimport { KeyringRule } from './rules/keyring';\nimport { SnapRule } from './rules/snap';\nimport type {\n AccountTreeControllerConfig,\n AccountTreeControllerMessenger,\n AccountTreeControllerState,\n} from './types';\nimport type { AccountWalletObject, AccountWalletObjectOf } from './wallet';\n\nexport const controllerName = 'AccountTreeController';\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n isAccountTreeSyncingInProgress: {\n persist: false,\n anonymous: false,\n },\n hasAccountTreeSyncingSyncedAtLeastOnce: {\n persist: true,\n anonymous: false,\n },\n accountGroupsMetadata: {\n persist: true,\n anonymous: false,\n },\n accountWalletsMetadata: {\n persist: true,\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n selectedAccountGroup: '',\n },\n isAccountTreeSyncingInProgress: false,\n hasAccountTreeSyncingSyncedAtLeastOnce: false,\n accountGroupsMetadata: {},\n accountWalletsMetadata: {},\n };\n}\n\n/**\n * Context for an account.\n */\nexport type AccountContext = {\n /**\n * Wallet ID associated to that account.\n */\n walletId: AccountWalletObject['id'];\n\n /**\n * Account group ID associated to that account.\n */\n groupId: AccountGroupObject['id'];\n};\n\nconst DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX = /^Account ([0-9]+)$/u;\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #serviceStartTime = Date.now();\n\n readonly #accountIdToContext: Map<AccountId, AccountContext>;\n\n readonly #groupIdToWalletId: Map<AccountGroupId, AccountWalletId>;\n\n /**\n * Service responsible for all backup and sync operations.\n */\n readonly #syncingService: BackupAndSyncService;\n\n readonly #newGroupsMap: WeakMap<AccountGroupObject, boolean>;\n\n readonly #rules: [EntropyRule, SnapRule, KeyringRule];\n\n readonly #trace: TraceCallback;\n\n readonly #backupAndSyncConfig: {\n emitBackupAndSyncEvent: (\n event: BackupAndSyncEmitAnalyticsEventParams,\n ) => void;\n enableDebugLogging: boolean;\n };\n\n // Temporary: ensures we can release updates to AccountTreeController without\n // breaking changes while we transition to the new multichain syncing approach.\n readonly #disableMultichainAccountSyncing: boolean = false;\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n * @param options.config - Optional configuration for the controller.\n */\n\n constructor({\n messenger,\n state,\n config,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n config?: AccountTreeControllerConfig;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#accountIdToContext = new Map();\n\n // Reverse map to allow fast wallet node access from a group ID.\n this.#groupIdToWalletId = new Map();\n\n // Initialize trace function before syncing service\n this.#trace = config?.trace ?? traceFallback;\n\n // Initialize backup and sync config before syncing service\n this.#backupAndSyncConfig = {\n emitBackupAndSyncEvent: (\n event: BackupAndSyncEmitAnalyticsEventParams,\n ) => {\n const formattedEvent = formatAnalyticsEvent(event);\n return config?.backupAndSync?.onBackupAndSyncEvent?.(formattedEvent);\n },\n enableDebugLogging: config?.backupAndSync?.enableDebugLogging ?? false,\n };\n\n // Initialize the syncing service\n this.#syncingService = new BackupAndSyncService(\n this.#createBackupAndSyncContext(),\n );\n // Temporary map to track which groups contain new accounts (for naming optimization)\n this.#newGroupsMap = new WeakMap();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n new EntropyRule(this.messagingSystem),\n // 2. We group by Snap ID\n new SnapRule(this.messagingSystem),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n new KeyringRule(this.messagingSystem),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n (account) => {\n this.#handleSelectedAccountChange(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRenamed',\n (account) => {\n this.#handleAccountRenamed(account);\n },\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Initialize the controller's state.\n *\n * It constructs the initial state of the account tree (tree nodes, nodes\n * names, metadata, etc..) and will automatically update the controller's\n * state with it.\n */\n init() {\n const wallets: AccountTreeControllerState['accountTree']['wallets'] = {};\n\n // Clear mappings for fresh rebuild\n this.#accountIdToContext.clear();\n this.#groupIdToWalletId.clear();\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n // Once we have the account tree, we can apply persisted metadata (names + UI states).\n for (const wallet of Object.values(wallets)) {\n this.#applyAccountWalletMetadata(wallet);\n\n for (const group of Object.values(wallet.groups)) {\n this.#applyAccountGroupMetadata(wallet, group);\n }\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n\n if (state.accountTree.selectedAccountGroup === '') {\n // No group is selected yet, re-sync with the AccountsController.\n state.accountTree.selectedAccountGroup =\n this.#getDefaultSelectedAccountGroup(wallets);\n }\n });\n }\n\n /**\n * Rule for entropy-base wallets.\n *\n * @returns The rule for entropy-based wallets.\n */\n #getEntropyRule(): EntropyRule {\n return this.#rules[0];\n }\n\n /**\n * Rule for Snap-base wallets.\n *\n * @returns The rule for snap-based wallets.\n */\n #getSnapRule(): SnapRule {\n return this.#rules[1];\n }\n\n /**\n * Rule for keyring-base wallets.\n *\n * This rule acts as a fallback and never fails since all accounts\n * comes from a keyring anyway.\n *\n * @returns The fallback rule for every accounts that did not match\n * any other rules.\n */\n #getKeyringRule(): KeyringRule {\n return this.#rules[2];\n }\n\n /**\n * Applies wallet metadata updates (name) by checking the persistent state\n * first, and then fallbacks to default values (based on the wallet's\n * type).\n *\n * @param wallet Account wallet object to update.\n */\n #applyAccountWalletMetadata(wallet: AccountWalletObject) {\n const persistedMetadata = this.state.accountWalletsMetadata[wallet.id];\n\n // Apply persisted name if available (including empty strings)\n if (persistedMetadata?.name !== undefined) {\n wallet.metadata.name = persistedMetadata.name.value;\n } else if (!wallet.metadata.name) {\n // Generate default name if none exists\n if (wallet.type === AccountWalletType.Entropy) {\n wallet.metadata.name =\n this.#getEntropyRule().getDefaultAccountWalletName(wallet);\n } else if (wallet.type === AccountWalletType.Snap) {\n wallet.metadata.name =\n this.#getSnapRule().getDefaultAccountWalletName(wallet);\n } else {\n wallet.metadata.name =\n this.#getKeyringRule().getDefaultAccountWalletName(wallet);\n }\n }\n }\n\n /**\n * Gets the appropriate rule instance for a given wallet type.\n *\n * @param wallet - The wallet object to get the rule for.\n * @returns The rule instance that handles the wallet's type.\n */\n #getRuleForWallet<WalletType extends AccountWalletType>(\n wallet: AccountWalletObjectOf<WalletType>,\n ): Rule<WalletType, AccountGroupType> {\n switch (wallet.type) {\n case AccountWalletType.Entropy:\n return this.#getEntropyRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n case AccountWalletType.Snap:\n return this.#getSnapRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n default:\n return this.#getKeyringRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n }\n }\n\n /**\n * Applies group metadata updates (name, pinned, hidden flags) by checking\n * the persistent state first, and then fallbacks to default values (based\n * on the wallet's\n * type).\n *\n * @param wallet Account wallet object of the account group to update.\n * @param group Account group object to update.\n */\n #applyAccountGroupMetadata(\n wallet: AccountWalletObject,\n group: AccountGroupObject,\n ) {\n const persistedMetadata = this.state.accountGroupsMetadata[group.id];\n\n // Apply persisted name if available (including empty strings)\n if (persistedMetadata?.name !== undefined) {\n group.metadata.name = persistedMetadata.name.value;\n } else if (!group.metadata.name) {\n // Get the appropriate rule for this wallet type\n const rule = this.#getRuleForWallet(wallet);\n const typedWallet = wallet as AccountWalletObjectOf<typeof wallet.type>;\n const typedGroup = typedWallet.groups[group.id] as AccountGroupObject;\n\n // Calculate group index based on position within sorted group IDs\n // We sort to ensure consistent ordering across all wallet types:\n // - Entropy: group IDs like \"entropy:abc/0\", \"entropy:abc/1\" sort to logical order\n // - Snap/Keyring: group IDs like \"keyring:ledger/0xABC\" get consistent alphabetical order\n const sortedGroupIds = Object.keys(wallet.groups).sort();\n let groupIndex = sortedGroupIds.indexOf(group.id);\n\n // Defensive fallback: if group.id is not found in sortedGroupIds (should never happen\n // in normal operation since we iterate over wallet.groups), use index 0 to prevent\n // passing -1 to getDefaultAccountGroupName which would result in \"Account 0\"\n /* istanbul ignore next */\n if (groupIndex === -1) {\n groupIndex = 0;\n }\n\n // For new groups, use default naming. For existing groups, try computed name first\n const isNewGroup = this.#newGroupsMap.get(group) || false;\n group.metadata.name = isNewGroup\n ? rule.getDefaultAccountGroupName(groupIndex)\n : rule.getComputedAccountGroupName(typedGroup) ||\n rule.getDefaultAccountGroupName(groupIndex);\n\n // Clear the flag after use to prevent stale state across rebuilds\n if (isNewGroup) {\n this.#newGroupsMap.delete(group);\n }\n }\n\n // Apply persisted UI states\n if (persistedMetadata?.pinned?.value !== undefined) {\n group.metadata.pinned = persistedMetadata.pinned.value;\n }\n if (persistedMetadata?.hidden?.value !== undefined) {\n group.metadata.hidden = persistedMetadata.hidden.value;\n }\n }\n\n /**\n * Gets the account wallet object from its ID.\n *\n * @param walletId - Account wallet ID.\n * @returns The account wallet object if found, undefined otherwise.\n */\n getAccountWalletObject(\n walletId: AccountWalletId,\n ): AccountWalletObject | undefined {\n const wallet = this.state.accountTree.wallets[walletId];\n if (!wallet) {\n return undefined;\n }\n\n return wallet;\n }\n\n /**\n * Gets all account wallet objects.\n *\n * @returns All account wallet objects.\n */\n getAccountWalletObjects(): AccountWalletObject[] {\n return Object.values(this.state.accountTree.wallets);\n }\n\n /**\n * Gets all underlying accounts from the currently selected account\n * group.\n *\n * It also support account selector, which allows to filter specific\n * accounts given some criterias (account type, address, scopes, etc...).\n *\n * @param selector - Optional account selector.\n * @returns Underlying accounts for the currently selected account (filtered\n * by the selector if provided).\n */\n getAccountsFromSelectedAccountGroup(\n selector?: AccountSelector<InternalAccount>,\n ) {\n const groupId = this.getSelectedAccountGroup();\n if (!groupId) {\n return [];\n }\n\n const group = this.getAccountGroupObject(groupId);\n // We should never reach this part, so we cannot cover it either.\n /* istanbul ignore next */\n if (!group) {\n return [];\n }\n\n const accounts: InternalAccount[] = [];\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n // For now, we're filtering undefined account, but I believe\n // throwing would be more appropriate here.\n if (account) {\n accounts.push(account);\n }\n }\n\n return selector ? select(accounts, selector) : accounts;\n }\n\n /**\n * Gets the account group object from its ID.\n *\n * @param groupId - Account group ID.\n * @returns The account group object if found, undefined otherwise.\n */\n getAccountGroupObject(\n groupId: AccountGroupId,\n ): AccountGroupObject | undefined {\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (!walletId) {\n return undefined;\n }\n\n const wallet = this.getAccountWalletObject(walletId);\n return wallet?.groups[groupId];\n }\n\n /**\n * Handles \"AccountsController:accountAdded\" event to insert\n * new accounts into the tree.\n *\n * @param account - New account.\n */\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n\n const context = this.#accountIdToContext.get(account.id);\n if (context) {\n const { walletId, groupId } = context;\n\n const wallet = state.accountTree.wallets[walletId];\n if (wallet) {\n this.#applyAccountWalletMetadata(wallet);\n\n const group = wallet.groups[groupId];\n if (group) {\n this.#applyAccountGroupMetadata(wallet, group);\n }\n }\n }\n });\n }\n\n /**\n * Handles \"AccountsController:accountRemoved\" event to remove\n * given account from the tree.\n *\n * @param accountId - Removed account ID.\n */\n #handleAccountRemoved(accountId: AccountId) {\n const context = this.#accountIdToContext.get(accountId);\n\n if (context) {\n const { walletId, groupId } = context;\n\n this.update((state) => {\n const accounts =\n state.accountTree.wallets[walletId]?.groups[groupId]?.accounts;\n\n if (accounts) {\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n\n // Check if we need to update selectedAccountGroup after removal\n if (\n state.accountTree.selectedAccountGroup === groupId &&\n accounts.length === 0\n ) {\n // The currently selected group is now empty, find a new group to select\n state.accountTree.selectedAccountGroup =\n this.#getDefaultAccountGroupId(state.accountTree.wallets);\n }\n }\n if (accounts.length === 0) {\n this.#pruneEmptyGroupAndWallet(state, walletId, groupId);\n }\n }\n });\n\n // Clear reverse-mapping for that account.\n this.#accountIdToContext.delete(accountId);\n }\n }\n\n /**\n * Handles \"AccountsController:accountRenamed\" event to rename\n * the associated account group which contains the account being\n * renamed.\n *\n * NOTE: This is mainly useful for legacy backup & sync v1.\n *\n * @param account - Account being renamed.\n */\n #handleAccountRenamed(account: InternalAccount) {\n // We only consider HD and simple EVM accounts for the moment as they have\n // an higher priority over others when it comes to naming.\n // (Similar logic than `EntropyRule.getDefaultAccountGroupName`).\n // TODO: Rename other kind of accounts, but we need to compute their \"default name\" with custom prefixes.\n if (!isEvmAccountType(account.type)) {\n return;\n }\n\n const context = this.#accountIdToContext.get(account.id);\n\n if (context) {\n const { walletId, groupId } = context;\n\n const wallet = this.state.accountTree.wallets[walletId];\n if (wallet) {\n const group = wallet.groups[groupId];\n if (group) {\n // We both use the same naming conventions for HD and simple accounts,\n // so we can use the same regex to check if the name is a default one.\n const isAccountNameDefault =\n DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX.test(account.metadata.name);\n const isGroupNameDefault = DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX.test(\n group.metadata.name,\n );\n\n if (isGroupNameDefault && !isAccountNameDefault) {\n this.setAccountGroupName(groupId, account.metadata.name);\n }\n }\n }\n }\n }\n\n /**\n * Helper method to prune a group if it holds no accounts and additionally\n * prune the wallet if it holds no groups. This action should take place\n * after a singular account removal.\n *\n * NOTE: This method should only be used for a group that we know to be empty.\n *\n * @param state - The AccountTreeController state to prune.\n * @param walletId - The wallet ID to prune, the wallet should be the parent of the associated group that holds the removed account.\n * @param groupId - The group ID to prune, the group should be the parent of the associated account that was removed.\n * @returns The updated state.\n */\n #pruneEmptyGroupAndWallet(\n state: AccountTreeControllerState,\n walletId: AccountWalletId,\n groupId: AccountGroupId,\n ) {\n const { wallets } = state.accountTree;\n\n delete wallets[walletId].groups[groupId];\n this.#groupIdToWalletId.delete(groupId);\n\n if (Object.keys(wallets[walletId].groups).length === 0) {\n delete wallets[walletId];\n }\n return state;\n }\n\n /**\n * Insert an account inside an account tree.\n *\n * We go over multiple rules to try to \"match\" the account following\n * specific criterias. If a rule \"matches\" an account, then this\n * account get added into its proper account wallet and account group.\n *\n * @param wallets - Account tree.\n * @param account - The account to be inserted.\n */\n #insert(\n wallets: AccountTreeControllerState['accountTree']['wallets'],\n account: InternalAccount,\n ) {\n const result =\n this.#getEntropyRule().match(account) ??\n this.#getSnapRule().match(account) ??\n this.#getKeyringRule().match(account); // This one cannot fail.\n\n // Determine if this account is new (created after service start)\n const isNewAccount = account.metadata.importTime > this.#serviceStartTime;\n\n // Update controller's state.\n const walletId = result.wallet.id;\n let wallet = wallets[walletId];\n if (!wallet) {\n wallets[walletId] = {\n ...result.wallet,\n groups: {},\n metadata: {\n name: '', // Will get updated later.\n ...result.wallet.metadata,\n },\n // We do need to type-cast since we're not narrowing `result` with\n // the union tag `result.wallet.type`.\n } as AccountWalletObject;\n wallet = wallets[walletId];\n\n // Trigger atomic sync for new wallet (only for entropy wallets)\n if (wallet.type === AccountWalletType.Entropy) {\n this.#syncingService.enqueueSingleWalletSync(walletId);\n }\n }\n\n const groupId = result.group.id;\n let group = wallet.groups[groupId];\n if (!group) {\n wallet.groups[groupId] = {\n ...result.group,\n // Type-wise, we are guaranteed to always have at least 1 account.\n accounts: [account.id],\n metadata: {\n name: '',\n ...{ pinned: false, hidden: false }, // Default UI states\n ...result.group.metadata, // Allow rules to override defaults\n },\n // We do need to type-cast since we're not narrowing `result` with\n // the union tag `result.group.type`.\n } as AccountGroupObject;\n group = wallet.groups[groupId];\n\n // Store whether this is a new group (has new accounts) for naming logic\n // We use a WeakMap to avoid polluting the group object with temporary data\n this.#newGroupsMap.set(group, isNewAccount);\n\n // Map group ID to its containing wallet ID for efficient direct access\n this.#groupIdToWalletId.set(groupId, walletId);\n\n // Trigger atomic sync for new group (only for entropy wallets)\n if (wallet.type === AccountWalletType.Entropy) {\n this.#syncingService.enqueueSingleGroupSync(groupId);\n }\n } else {\n // If adding to existing group, update the \"new\" status if this account is new\n if (isNewAccount) {\n this.#newGroupsMap.set(group, true);\n }\n group.accounts.push(account.id);\n }\n\n // Update the reverse mapping for this account.\n this.#accountIdToContext.set(account.id, {\n walletId: wallet.id,\n groupId: group.id,\n });\n }\n\n /**\n * List all internal accounts.\n *\n * @returns The list of all internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Asserts that a group exists in the current account tree.\n *\n * @param groupId - The account group ID to validate.\n * @throws Error if the group does not exist.\n */\n #assertAccountGroupExists(groupId: AccountGroupId): void {\n const exists = this.#groupIdToWalletId.has(groupId);\n if (!exists) {\n throw new Error(`Account group with ID \"${groupId}\" not found in tree`);\n }\n }\n\n /**\n * Asserts that a wallet exists in the current account tree.\n *\n * @param walletId - The account wallet ID to validate.\n * @throws Error if the wallet does not exist.\n */\n #assertAccountWalletExists(walletId: AccountWalletId): void {\n const exists = Boolean(this.state.accountTree.wallets[walletId]);\n if (!exists) {\n throw new Error(`Account wallet with ID \"${walletId}\" not found in tree`);\n }\n }\n\n /**\n * Gets the currently selected account group ID.\n *\n * @returns The selected account group ID or empty string if none selected.\n */\n getSelectedAccountGroup(): AccountGroupId | '' {\n return this.state.accountTree.selectedAccountGroup;\n }\n\n /**\n * Sets the selected account group and updates the AccountsController selectedAccount accordingly.\n *\n * @param groupId - The account group ID to select.\n */\n setSelectedAccountGroup(groupId: AccountGroupId): void {\n const currentSelectedGroup = this.state.accountTree.selectedAccountGroup;\n\n // Idempotent check - if the same group is already selected, do nothing\n if (currentSelectedGroup === groupId) {\n return;\n }\n\n // Find the first account in this group to select\n const accountToSelect = this.#getDefaultAccountFromAccountGroupId(groupId);\n if (!accountToSelect) {\n throw new Error(`No accounts found in group: ${groupId}`);\n }\n\n // Update our state first\n this.update((state) => {\n state.accountTree.selectedAccountGroup = groupId;\n });\n\n // Update AccountsController - this will trigger selectedAccountChange event,\n // but our handler is idempotent so it won't cause infinite loop\n this.messagingSystem.call(\n 'AccountsController:setSelectedAccount',\n accountToSelect,\n );\n }\n\n /**\n * Initializes the selectedAccountGroup based on the currently selected account from AccountsController.\n *\n * @param wallets - Wallets object to use for fallback logic\n * @returns The default selected account group ID or empty string if none selected.\n */\n #getDefaultSelectedAccountGroup(wallets: {\n [walletId: AccountWalletId]: AccountWalletObject;\n }): AccountGroupId | '' {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n if (selectedAccount && selectedAccount.id) {\n const accountMapping = this.#accountIdToContext.get(selectedAccount.id);\n if (accountMapping) {\n const { groupId } = accountMapping;\n\n return groupId;\n }\n }\n\n // Default to the default group in case of errors.\n return this.#getDefaultAccountGroupId(wallets);\n }\n\n /**\n * Handles selected account change from AccountsController.\n * Updates selectedAccountGroup to match the selected account.\n *\n * @param account - The newly selected account.\n */\n #handleSelectedAccountChange(account: InternalAccount): void {\n const accountMapping = this.#accountIdToContext.get(account.id);\n if (!accountMapping) {\n // Account not in tree yet, might be during initialization\n return;\n }\n\n const { groupId } = accountMapping;\n const currentSelectedGroup = this.state.accountTree.selectedAccountGroup;\n\n // Idempotent check - if the same group is already selected, do nothing\n if (currentSelectedGroup === groupId) {\n return;\n }\n\n // Update selectedAccountGroup to match the selected account\n this.update((state) => {\n state.accountTree.selectedAccountGroup = groupId;\n });\n }\n\n /**\n * Gets account group.\n *\n * @param groupId - The account group ID.\n * @returns The account group or undefined if not found.\n */\n #getAccountGroup(groupId: AccountGroupId): AccountGroupObject | undefined {\n const found = Object.values(this.state.accountTree.wallets).find(\n (wallet) => wallet.groups[groupId] !== undefined,\n );\n\n return found?.groups[groupId];\n }\n\n /**\n * Gets the default account for specified group.\n *\n * @param groupId - The account group ID.\n * @returns The first account ID in the group, or undefined if no accounts found.\n */\n #getDefaultAccountFromAccountGroupId(\n groupId: AccountGroupId,\n ): AccountId | undefined {\n const group = this.#getAccountGroup(groupId);\n\n if (group) {\n let candidate;\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n if (!candidate) {\n candidate = id;\n }\n if (account && isEvmAccountType(account.type)) {\n // EVM accounts have a higher priority, so if we find any, we just\n // use that account!\n return account.id;\n }\n }\n\n return candidate;\n }\n\n return undefined;\n }\n\n /**\n * Gets the default group id, which is either, the first non-empty group that contains an EVM account or\n * just the first non-empty group with any accounts.\n *\n * @param wallets - The wallets object to search.\n * @returns The ID of the first non-empty group, or an empty string if no groups are found.\n */\n #getDefaultAccountGroupId(wallets: {\n [walletId: AccountWalletId]: AccountWalletObject;\n }): AccountGroupId | '' {\n let candidate: AccountGroupId | '' = '';\n\n for (const wallet of Object.values(wallets)) {\n for (const group of Object.values(wallet.groups)) {\n // We only update the candidate with the first non-empty group, but still\n // try to find a group that contains an EVM account (the `candidate` is\n // our fallback).\n if (candidate === '' && group.accounts.length > 0) {\n candidate = group.id;\n }\n\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n if (account && isEvmAccountType(account.type)) {\n // EVM accounts have a higher priority, so if we find any, we just\n // use that group!\n return group.id;\n }\n }\n }\n }\n return candidate;\n }\n\n /**\n * Sets a custom name for an account group.\n *\n * @param groupId - The account group ID.\n * @param name - The custom name to set.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupName(groupId: AccountGroupId, name: string): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].name = {\n value: name,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.name =\n name;\n }\n });\n\n // Trigger atomic sync for group rename\n this.#syncingService.enqueueSingleGroupSync(groupId);\n }\n\n /**\n * Sets a custom name for an account wallet.\n *\n * @param walletId - The account wallet ID.\n * @param name - The custom name to set.\n * @throws If the account wallet ID is not found in the current tree.\n */\n setAccountWalletName(walletId: AccountWalletId, name: string): void {\n // Validate that the wallet exists in the current tree\n this.#assertAccountWalletExists(walletId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountWalletsMetadata[walletId] ??= {};\n state.accountWalletsMetadata[walletId].name = {\n value: name,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly\n state.accountTree.wallets[walletId].metadata.name = name;\n });\n\n // Trigger atomic sync for wallet rename\n this.#syncingService.enqueueSingleWalletSync(walletId);\n }\n\n /**\n * Toggles the pinned state of an account group.\n *\n * @param groupId - The account group ID.\n * @param pinned - Whether the group should be pinned.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupPinned(groupId: AccountGroupId, pinned: boolean): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].pinned = {\n value: pinned,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.pinned =\n pinned;\n }\n });\n\n // Trigger atomic sync for group pinning\n this.#syncingService.enqueueSingleGroupSync(groupId);\n }\n\n /**\n * Toggles the hidden state of an account group.\n *\n * @param groupId - The account group ID.\n * @param hidden - Whether the group should be hidden.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupHidden(groupId: AccountGroupId, hidden: boolean): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].hidden = {\n value: hidden,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.hidden =\n hidden;\n }\n });\n\n // Trigger atomic sync for group hiding\n this.#syncingService.enqueueSingleGroupSync(groupId);\n }\n\n /**\n * Clears all persisted metadata and syncing state.\n *\n * This will reset the account groups and wallets metadata, as well as\n * the syncing state. This should be used when we want to\n * completely reset the controller's state.\n */\n clearPersistedMetadataAndSyncingState(): void {\n this.update((state) => {\n state.accountGroupsMetadata = {};\n state.accountWalletsMetadata = {};\n state.hasAccountTreeSyncingSyncedAtLeastOnce = false;\n });\n }\n\n /**\n * Registers message handlers for the AccountTreeController.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccountGroup`,\n this.getSelectedAccountGroup.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccountGroup`,\n this.setSelectedAccountGroup.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountsFromSelectedAccountGroup`,\n this.getAccountsFromSelectedAccountGroup.bind(this),\n );\n }\n\n async syncWithUserStorage(): Promise<void> {\n return this.#syncingService.performFullSync();\n }\n\n /**\n * Creates an backup and sync context for sync operations.\n * Used by the syncing service.\n *\n * @returns The backup and sync context.\n */\n #createBackupAndSyncContext(): BackupAndSyncContext {\n return {\n controller: this,\n messenger: this.messagingSystem,\n controllerStateUpdateFn: this.update.bind(this),\n traceFn: this.#trace.bind(this),\n emitAnalyticsEventFn:\n this.#backupAndSyncConfig.emitBackupAndSyncEvent.bind(this),\n enableDebugLogging: this.#backupAndSyncConfig.enableDebugLogging,\n disableMultichainAccountSyncing: this.#disableMultichainAccountSyncing,\n groupIdToWalletId: this.#groupIdToWalletId,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountGroupId,\n AccountWalletId,\n AccountGroupType,\n AccountSelector,\n} from '@metamask/account-api';\nimport { AccountWalletType, select } from '@metamask/account-api';\nimport { type AccountId } from '@metamask/accounts-controller';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { isEvmAccountType } from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountGroupObject } from './group';\nimport type { Rule } from './rule';\nimport { EntropyRule } from './rules/entropy';\nimport { KeyringRule } from './rules/keyring';\nimport { SnapRule } from './rules/snap';\nimport type {\n AccountTreeControllerMessenger,\n AccountTreeControllerState,\n} from './types';\nimport type { AccountWalletObject, AccountWalletObjectOf } from './wallet';\n\nexport const controllerName = 'AccountTreeController';\n\nconst accountTreeControllerMetadata: StateMetadata<AccountTreeControllerState> =\n {\n accountTree: {\n persist: false, // We do re-recompute this state everytime.\n anonymous: false,\n },\n accountGroupsMetadata: {\n persist: true,\n anonymous: false,\n },\n accountWalletsMetadata: {\n persist: true,\n anonymous: false,\n },\n };\n\n/**\n * Gets default state of the `AccountTreeController`.\n *\n * @returns The default state of the `AccountTreeController`.\n */\nexport function getDefaultAccountTreeControllerState(): AccountTreeControllerState {\n return {\n accountTree: {\n wallets: {},\n selectedAccountGroup: '',\n },\n accountGroupsMetadata: {},\n accountWalletsMetadata: {},\n };\n}\n\n/**\n * Context for an account.\n */\nexport type AccountContext = {\n /**\n * Wallet ID associated to that account.\n */\n walletId: AccountWalletObject['id'];\n\n /**\n * Account group ID associated to that account.\n */\n groupId: AccountGroupObject['id'];\n};\n\nconst DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX = /^Account ([0-9]+)$/u;\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #serviceStartTime = Date.now();\n\n readonly #accountIdToContext: Map<AccountId, AccountContext>;\n\n readonly #groupIdToWalletId: Map<AccountGroupId, AccountWalletId>;\n\n readonly #newGroupsMap: WeakMap<AccountGroupObject, boolean>;\n\n readonly #rules: [EntropyRule, SnapRule, KeyringRule];\n\n /**\n * Constructor for AccountTreeController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n */\n\n constructor({\n messenger,\n state,\n }: {\n messenger: AccountTreeControllerMessenger;\n state?: Partial<AccountTreeControllerState>;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountTreeControllerMetadata,\n state: {\n ...getDefaultAccountTreeControllerState(),\n ...state,\n },\n });\n\n // Reverse map to allow fast node access from an account ID.\n this.#accountIdToContext = new Map();\n\n // Reverse map to allow fast wallet node access from a group ID.\n this.#groupIdToWalletId = new Map();\n\n // Temporary map to track which groups contain new accounts (for naming optimization)\n this.#newGroupsMap = new WeakMap();\n\n // Rules to apply to construct the wallets tree.\n this.#rules = [\n // 1. We group by entropy-source\n new EntropyRule(this.messagingSystem),\n // 2. We group by Snap ID\n new SnapRule(this.messagingSystem),\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n new KeyringRule(this.messagingSystem),\n ];\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountAdded',\n (account) => {\n this.#handleAccountAdded(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRemoved',\n (accountId) => {\n this.#handleAccountRemoved(accountId);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n (account) => {\n this.#handleSelectedAccountChange(account);\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:accountRenamed',\n (account) => {\n this.#handleAccountRenamed(account);\n },\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Initialize the controller's state.\n *\n * It constructs the initial state of the account tree (tree nodes, nodes\n * names, metadata, etc..) and will automatically update the controller's\n * state with it.\n */\n init() {\n const wallets: AccountTreeControllerState['accountTree']['wallets'] = {};\n\n // Clear mappings for fresh rebuild\n this.#accountIdToContext.clear();\n this.#groupIdToWalletId.clear();\n\n // For now, we always re-compute all wallets, we do not re-use the existing state.\n for (const account of this.#listAccounts()) {\n this.#insert(wallets, account);\n }\n\n // Once we have the account tree, we can apply persisted metadata (names + UI states).\n for (const wallet of Object.values(wallets)) {\n this.#applyAccountWalletMetadata(wallet);\n\n for (const group of Object.values(wallet.groups)) {\n this.#applyAccountGroupMetadata(wallet, group);\n }\n }\n\n this.update((state) => {\n state.accountTree.wallets = wallets;\n\n if (state.accountTree.selectedAccountGroup === '') {\n // No group is selected yet, re-sync with the AccountsController.\n state.accountTree.selectedAccountGroup =\n this.#getDefaultSelectedAccountGroup(wallets);\n }\n });\n }\n\n /**\n * Rule for entropy-base wallets.\n *\n * @returns The rule for entropy-based wallets.\n */\n #getEntropyRule(): EntropyRule {\n return this.#rules[0];\n }\n\n /**\n * Rule for Snap-base wallets.\n *\n * @returns The rule for snap-based wallets.\n */\n #getSnapRule(): SnapRule {\n return this.#rules[1];\n }\n\n /**\n * Rule for keyring-base wallets.\n *\n * This rule acts as a fallback and never fails since all accounts\n * comes from a keyring anyway.\n *\n * @returns The fallback rule for every accounts that did not match\n * any other rules.\n */\n #getKeyringRule(): KeyringRule {\n return this.#rules[2];\n }\n\n /**\n * Applies wallet metadata updates (name) by checking the persistent state\n * first, and then fallbacks to default values (based on the wallet's\n * type).\n *\n * @param wallet Account wallet object to update.\n */\n #applyAccountWalletMetadata(wallet: AccountWalletObject) {\n const persistedMetadata = this.state.accountWalletsMetadata[wallet.id];\n\n // Apply persisted name if available (including empty strings)\n if (persistedMetadata?.name !== undefined) {\n wallet.metadata.name = persistedMetadata.name.value;\n } else if (!wallet.metadata.name) {\n // Generate default name if none exists\n if (wallet.type === AccountWalletType.Entropy) {\n wallet.metadata.name =\n this.#getEntropyRule().getDefaultAccountWalletName(wallet);\n } else if (wallet.type === AccountWalletType.Snap) {\n wallet.metadata.name =\n this.#getSnapRule().getDefaultAccountWalletName(wallet);\n } else {\n wallet.metadata.name =\n this.#getKeyringRule().getDefaultAccountWalletName(wallet);\n }\n }\n }\n\n /**\n * Gets the appropriate rule instance for a given wallet type.\n *\n * @param wallet - The wallet object to get the rule for.\n * @returns The rule instance that handles the wallet's type.\n */\n #getRuleForWallet<WalletType extends AccountWalletType>(\n wallet: AccountWalletObjectOf<WalletType>,\n ): Rule<WalletType, AccountGroupType> {\n switch (wallet.type) {\n case AccountWalletType.Entropy:\n return this.#getEntropyRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n case AccountWalletType.Snap:\n return this.#getSnapRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n default:\n return this.#getKeyringRule() as unknown as Rule<\n WalletType,\n AccountGroupType\n >;\n }\n }\n\n /**\n * Applies group metadata updates (name, pinned, hidden flags) by checking\n * the persistent state first, and then fallbacks to default values (based\n * on the wallet's\n * type).\n *\n * @param wallet Account wallet object of the account group to update.\n * @param group Account group object to update.\n */\n #applyAccountGroupMetadata(\n wallet: AccountWalletObject,\n group: AccountGroupObject,\n ) {\n const persistedMetadata = this.state.accountGroupsMetadata[group.id];\n\n // Apply persisted name if available (including empty strings)\n if (persistedMetadata?.name !== undefined) {\n group.metadata.name = persistedMetadata.name.value;\n } else if (!group.metadata.name) {\n // Get the appropriate rule for this wallet type\n const rule = this.#getRuleForWallet(wallet);\n const typedWallet = wallet as AccountWalletObjectOf<typeof wallet.type>;\n const typedGroup = typedWallet.groups[group.id] as AccountGroupObject;\n\n // Calculate group index based on position within sorted group IDs\n // We sort to ensure consistent ordering across all wallet types:\n // - Entropy: group IDs like \"entropy:abc/0\", \"entropy:abc/1\" sort to logical order\n // - Snap/Keyring: group IDs like \"keyring:ledger/0xABC\" get consistent alphabetical order\n const sortedGroupIds = Object.keys(wallet.groups).sort();\n let groupIndex = sortedGroupIds.indexOf(group.id);\n\n // Defensive fallback: if group.id is not found in sortedGroupIds (should never happen\n // in normal operation since we iterate over wallet.groups), use index 0 to prevent\n // passing -1 to getDefaultAccountGroupName which would result in \"Account 0\"\n /* istanbul ignore next */\n if (groupIndex === -1) {\n groupIndex = 0;\n }\n\n // For new groups, use default naming. For existing groups, try computed name first\n const isNewGroup = this.#newGroupsMap.get(group) || false;\n group.metadata.name = isNewGroup\n ? rule.getDefaultAccountGroupName(groupIndex)\n : rule.getComputedAccountGroupName(typedGroup) ||\n rule.getDefaultAccountGroupName(groupIndex);\n\n // Clear the flag after use to prevent stale state across rebuilds\n if (isNewGroup) {\n this.#newGroupsMap.delete(group);\n }\n }\n\n // Apply persisted UI states\n if (persistedMetadata?.pinned?.value !== undefined) {\n group.metadata.pinned = persistedMetadata.pinned.value;\n }\n if (persistedMetadata?.hidden?.value !== undefined) {\n group.metadata.hidden = persistedMetadata.hidden.value;\n }\n }\n\n /**\n * Gets the account wallet object from its ID.\n *\n * @param walletId - Account wallet ID.\n * @returns The account wallet object if found, undefined otherwise.\n */\n getAccountWalletObject(\n walletId: AccountWalletId,\n ): AccountWalletObject | undefined {\n const wallet = this.state.accountTree.wallets[walletId];\n if (!wallet) {\n return undefined;\n }\n\n return wallet;\n }\n\n /**\n * Gets all account wallet objects.\n *\n * @returns All account wallet objects.\n */\n getAccountWalletObjects(): AccountWalletObject[] {\n return Object.values(this.state.accountTree.wallets);\n }\n\n /**\n * Gets all underlying accounts from the currently selected account\n * group.\n *\n * It also support account selector, which allows to filter specific\n * accounts given some criterias (account type, address, scopes, etc...).\n *\n * @param selector - Optional account selector.\n * @returns Underlying accounts for the currently selected account (filtered\n * by the selector if provided).\n */\n getAccountsFromSelectedAccountGroup(\n selector?: AccountSelector<InternalAccount>,\n ) {\n const groupId = this.getSelectedAccountGroup();\n if (!groupId) {\n return [];\n }\n\n const group = this.getAccountGroupObject(groupId);\n // We should never reach this part, so we cannot cover it either.\n /* istanbul ignore next */\n if (!group) {\n return [];\n }\n\n const accounts: InternalAccount[] = [];\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n // For now, we're filtering undefined account, but I believe\n // throwing would be more appropriate here.\n if (account) {\n accounts.push(account);\n }\n }\n\n return selector ? select(accounts, selector) : accounts;\n }\n\n /**\n * Gets the account group object from its ID.\n *\n * @param groupId - Account group ID.\n * @returns The account group object if found, undefined otherwise.\n */\n getAccountGroupObject(\n groupId: AccountGroupId,\n ): AccountGroupObject | undefined {\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (!walletId) {\n return undefined;\n }\n\n const wallet = this.getAccountWalletObject(walletId);\n return wallet?.groups[groupId];\n }\n\n /**\n * Handles \"AccountsController:accountAdded\" event to insert\n * new accounts into the tree.\n *\n * @param account - New account.\n */\n #handleAccountAdded(account: InternalAccount) {\n this.update((state) => {\n this.#insert(state.accountTree.wallets, account);\n\n const context = this.#accountIdToContext.get(account.id);\n if (context) {\n const { walletId, groupId } = context;\n\n const wallet = state.accountTree.wallets[walletId];\n if (wallet) {\n this.#applyAccountWalletMetadata(wallet);\n\n const group = wallet.groups[groupId];\n if (group) {\n this.#applyAccountGroupMetadata(wallet, group);\n }\n }\n }\n });\n }\n\n /**\n * Handles \"AccountsController:accountRemoved\" event to remove\n * given account from the tree.\n *\n * @param accountId - Removed account ID.\n */\n #handleAccountRemoved(accountId: AccountId) {\n const context = this.#accountIdToContext.get(accountId);\n\n if (context) {\n const { walletId, groupId } = context;\n\n this.update((state) => {\n const accounts =\n state.accountTree.wallets[walletId]?.groups[groupId]?.accounts;\n\n if (accounts) {\n const index = accounts.indexOf(accountId);\n if (index !== -1) {\n accounts.splice(index, 1);\n\n // Check if we need to update selectedAccountGroup after removal\n if (\n state.accountTree.selectedAccountGroup === groupId &&\n accounts.length === 0\n ) {\n // The currently selected group is now empty, find a new group to select\n state.accountTree.selectedAccountGroup =\n this.#getDefaultAccountGroupId(state.accountTree.wallets);\n }\n }\n if (accounts.length === 0) {\n this.#pruneEmptyGroupAndWallet(state, walletId, groupId);\n }\n }\n });\n\n // Clear reverse-mapping for that account.\n this.#accountIdToContext.delete(accountId);\n }\n }\n\n /**\n * Handles \"AccountsController:accountRenamed\" event to rename\n * the associated account group which contains the account being\n * renamed.\n *\n * NOTE: This is mainly useful for legacy backup & sync v1.\n *\n * @param account - Account being renamed.\n */\n #handleAccountRenamed(account: InternalAccount) {\n // We only consider HD and simple EVM accounts for the moment as they have\n // an higher priority over others when it comes to naming.\n // (Similar logic than `EntropyRule.getDefaultAccountGroupName`).\n // TODO: Rename other kind of accounts, but we need to compute their \"default name\" with custom prefixes.\n if (!isEvmAccountType(account.type)) {\n return;\n }\n\n const context = this.#accountIdToContext.get(account.id);\n\n if (context) {\n const { walletId, groupId } = context;\n\n const wallet = this.state.accountTree.wallets[walletId];\n if (wallet) {\n const group = wallet.groups[groupId];\n if (group) {\n // We both use the same naming conventions for HD and simple accounts,\n // so we can use the same regex to check if the name is a default one.\n const isAccountNameDefault =\n DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX.test(account.metadata.name);\n const isGroupNameDefault = DEFAULT_HD_SIMPLE_ACCOUNT_NAME_REGEX.test(\n group.metadata.name,\n );\n\n if (isGroupNameDefault && !isAccountNameDefault) {\n this.setAccountGroupName(groupId, account.metadata.name);\n }\n }\n }\n }\n }\n\n /**\n * Helper method to prune a group if it holds no accounts and additionally\n * prune the wallet if it holds no groups. This action should take place\n * after a singular account removal.\n *\n * NOTE: This method should only be used for a group that we know to be empty.\n *\n * @param state - The AccountTreeController state to prune.\n * @param walletId - The wallet ID to prune, the wallet should be the parent of the associated group that holds the removed account.\n * @param groupId - The group ID to prune, the group should be the parent of the associated account that was removed.\n * @returns The updated state.\n */\n #pruneEmptyGroupAndWallet(\n state: AccountTreeControllerState,\n walletId: AccountWalletId,\n groupId: AccountGroupId,\n ) {\n const { wallets } = state.accountTree;\n\n delete wallets[walletId].groups[groupId];\n this.#groupIdToWalletId.delete(groupId);\n\n if (Object.keys(wallets[walletId].groups).length === 0) {\n delete wallets[walletId];\n }\n return state;\n }\n\n /**\n * Insert an account inside an account tree.\n *\n * We go over multiple rules to try to \"match\" the account following\n * specific criterias. If a rule \"matches\" an account, then this\n * account get added into its proper account wallet and account group.\n *\n * @param wallets - Account tree.\n * @param account - The account to be inserted.\n */\n #insert(\n wallets: AccountTreeControllerState['accountTree']['wallets'],\n account: InternalAccount,\n ) {\n const result =\n this.#getEntropyRule().match(account) ??\n this.#getSnapRule().match(account) ??\n this.#getKeyringRule().match(account); // This one cannot fail.\n\n // Determine if this account is new (created after service start)\n const isNewAccount = account.metadata.importTime > this.#serviceStartTime;\n\n // Update controller's state.\n const walletId = result.wallet.id;\n let wallet = wallets[walletId];\n if (!wallet) {\n wallets[walletId] = {\n ...result.wallet,\n groups: {},\n metadata: {\n name: '', // Will get updated later.\n ...result.wallet.metadata,\n },\n // We do need to type-cast since we're not narrowing `result` with\n // the union tag `result.wallet.type`.\n } as AccountWalletObject;\n wallet = wallets[walletId];\n }\n\n const groupId = result.group.id;\n let group = wallet.groups[groupId];\n if (!group) {\n wallet.groups[groupId] = {\n ...result.group,\n // Type-wise, we are guaranteed to always have at least 1 account.\n accounts: [account.id],\n metadata: {\n name: '',\n ...{ pinned: false, hidden: false }, // Default UI states\n ...result.group.metadata, // Allow rules to override defaults\n },\n // We do need to type-cast since we're not narrowing `result` with\n // the union tag `result.group.type`.\n } as AccountGroupObject;\n group = wallet.groups[groupId];\n\n // Store whether this is a new group (has new accounts) for naming logic\n // We use a WeakMap to avoid polluting the group object with temporary data\n this.#newGroupsMap.set(group, isNewAccount);\n\n // Map group ID to its containing wallet ID for efficient direct access\n this.#groupIdToWalletId.set(groupId, walletId);\n } else {\n // If adding to existing group, update the \"new\" status if this account is new\n if (isNewAccount) {\n this.#newGroupsMap.set(group, true);\n }\n group.accounts.push(account.id);\n }\n\n // Update the reverse mapping for this account.\n this.#accountIdToContext.set(account.id, {\n walletId: wallet.id,\n groupId: group.id,\n });\n }\n\n /**\n * List all internal accounts.\n *\n * @returns The list of all internal accounts.\n */\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\n );\n }\n\n /**\n * Asserts that a group exists in the current account tree.\n *\n * @param groupId - The account group ID to validate.\n * @throws Error if the group does not exist.\n */\n #assertAccountGroupExists(groupId: AccountGroupId): void {\n const exists = this.#groupIdToWalletId.has(groupId);\n if (!exists) {\n throw new Error(`Account group with ID \"${groupId}\" not found in tree`);\n }\n }\n\n /**\n * Asserts that a wallet exists in the current account tree.\n *\n * @param walletId - The account wallet ID to validate.\n * @throws Error if the wallet does not exist.\n */\n #assertAccountWalletExists(walletId: AccountWalletId): void {\n const exists = Boolean(this.state.accountTree.wallets[walletId]);\n if (!exists) {\n throw new Error(`Account wallet with ID \"${walletId}\" not found in tree`);\n }\n }\n\n /**\n * Gets the currently selected account group ID.\n *\n * @returns The selected account group ID or empty string if none selected.\n */\n getSelectedAccountGroup(): AccountGroupId | '' {\n return this.state.accountTree.selectedAccountGroup;\n }\n\n /**\n * Sets the selected account group and updates the AccountsController selectedAccount accordingly.\n *\n * @param groupId - The account group ID to select.\n */\n setSelectedAccountGroup(groupId: AccountGroupId): void {\n const currentSelectedGroup = this.state.accountTree.selectedAccountGroup;\n\n // Idempotent check - if the same group is already selected, do nothing\n if (currentSelectedGroup === groupId) {\n return;\n }\n\n // Find the first account in this group to select\n const accountToSelect = this.#getDefaultAccountFromAccountGroupId(groupId);\n if (!accountToSelect) {\n throw new Error(`No accounts found in group: ${groupId}`);\n }\n\n // Update our state first\n this.update((state) => {\n state.accountTree.selectedAccountGroup = groupId;\n });\n\n // Update AccountsController - this will trigger selectedAccountChange event,\n // but our handler is idempotent so it won't cause infinite loop\n this.messagingSystem.call(\n 'AccountsController:setSelectedAccount',\n accountToSelect,\n );\n }\n\n /**\n * Initializes the selectedAccountGroup based on the currently selected account from AccountsController.\n *\n * @param wallets - Wallets object to use for fallback logic\n * @returns The default selected account group ID or empty string if none selected.\n */\n #getDefaultSelectedAccountGroup(wallets: {\n [walletId: AccountWalletId]: AccountWalletObject;\n }): AccountGroupId | '' {\n const selectedAccount = this.messagingSystem.call(\n 'AccountsController:getSelectedAccount',\n );\n if (selectedAccount && selectedAccount.id) {\n const accountMapping = this.#accountIdToContext.get(selectedAccount.id);\n if (accountMapping) {\n const { groupId } = accountMapping;\n\n return groupId;\n }\n }\n\n // Default to the default group in case of errors.\n return this.#getDefaultAccountGroupId(wallets);\n }\n\n /**\n * Handles selected account change from AccountsController.\n * Updates selectedAccountGroup to match the selected account.\n *\n * @param account - The newly selected account.\n */\n #handleSelectedAccountChange(account: InternalAccount): void {\n const accountMapping = this.#accountIdToContext.get(account.id);\n if (!accountMapping) {\n // Account not in tree yet, might be during initialization\n return;\n }\n\n const { groupId } = accountMapping;\n const currentSelectedGroup = this.state.accountTree.selectedAccountGroup;\n\n // Idempotent check - if the same group is already selected, do nothing\n if (currentSelectedGroup === groupId) {\n return;\n }\n\n // Update selectedAccountGroup to match the selected account\n this.update((state) => {\n state.accountTree.selectedAccountGroup = groupId;\n });\n }\n\n /**\n * Gets account group.\n *\n * @param groupId - The account group ID.\n * @returns The account group or undefined if not found.\n */\n #getAccountGroup(groupId: AccountGroupId): AccountGroupObject | undefined {\n const found = Object.values(this.state.accountTree.wallets).find(\n (wallet) => wallet.groups[groupId] !== undefined,\n );\n\n return found?.groups[groupId];\n }\n\n /**\n * Gets the default account for specified group.\n *\n * @param groupId - The account group ID.\n * @returns The first account ID in the group, or undefined if no accounts found.\n */\n #getDefaultAccountFromAccountGroupId(\n groupId: AccountGroupId,\n ): AccountId | undefined {\n const group = this.#getAccountGroup(groupId);\n\n if (group) {\n let candidate;\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n if (!candidate) {\n candidate = id;\n }\n if (account && isEvmAccountType(account.type)) {\n // EVM accounts have a higher priority, so if we find any, we just\n // use that account!\n return account.id;\n }\n }\n\n return candidate;\n }\n\n return undefined;\n }\n\n /**\n * Gets the default group id, which is either, the first non-empty group that contains an EVM account or\n * just the first non-empty group with any accounts.\n *\n * @param wallets - The wallets object to search.\n * @returns The ID of the first non-empty group, or an empty string if no groups are found.\n */\n #getDefaultAccountGroupId(wallets: {\n [walletId: AccountWalletId]: AccountWalletObject;\n }): AccountGroupId | '' {\n let candidate: AccountGroupId | '' = '';\n\n for (const wallet of Object.values(wallets)) {\n for (const group of Object.values(wallet.groups)) {\n // We only update the candidate with the first non-empty group, but still\n // try to find a group that contains an EVM account (the `candidate` is\n // our fallback).\n if (candidate === '' && group.accounts.length > 0) {\n candidate = group.id;\n }\n\n for (const id of group.accounts) {\n const account = this.messagingSystem.call(\n 'AccountsController:getAccount',\n id,\n );\n\n if (account && isEvmAccountType(account.type)) {\n // EVM accounts have a higher priority, so if we find any, we just\n // use that group!\n return group.id;\n }\n }\n }\n }\n return candidate;\n }\n\n /**\n * Sets a custom name for an account group.\n *\n * @param groupId - The account group ID.\n * @param name - The custom name to set.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupName(groupId: AccountGroupId, name: string): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].name = {\n value: name,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.name =\n name;\n }\n });\n }\n\n /**\n * Sets a custom name for an account wallet.\n *\n * @param walletId - The account wallet ID.\n * @param name - The custom name to set.\n * @throws If the account wallet ID is not found in the current tree.\n */\n setAccountWalletName(walletId: AccountWalletId, name: string): void {\n // Validate that the wallet exists in the current tree\n this.#assertAccountWalletExists(walletId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountWalletsMetadata[walletId] ??= {};\n state.accountWalletsMetadata[walletId].name = {\n value: name,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly\n state.accountTree.wallets[walletId].metadata.name = name;\n });\n }\n\n /**\n * Toggles the pinned state of an account group.\n *\n * @param groupId - The account group ID.\n * @param pinned - Whether the group should be pinned.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupPinned(groupId: AccountGroupId, pinned: boolean): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].pinned = {\n value: pinned,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.pinned =\n pinned;\n }\n });\n }\n\n /**\n * Toggles the hidden state of an account group.\n *\n * @param groupId - The account group ID.\n * @param hidden - Whether the group should be hidden.\n * @throws If the account group ID is not found in the current tree.\n */\n setAccountGroupHidden(groupId: AccountGroupId, hidden: boolean): void {\n // Validate that the group exists in the current tree\n this.#assertAccountGroupExists(groupId);\n\n this.update((state) => {\n // Update persistent metadata\n state.accountGroupsMetadata[groupId] ??= {};\n state.accountGroupsMetadata[groupId].hidden = {\n value: hidden,\n lastUpdatedAt: Date.now(),\n };\n\n // Update tree node directly using efficient mapping\n const walletId = this.#groupIdToWalletId.get(groupId);\n if (walletId) {\n state.accountTree.wallets[walletId].groups[groupId].metadata.hidden =\n hidden;\n }\n });\n }\n\n /**\n * Registers message handlers for the AccountTreeController.\n */\n #registerMessageHandlers(): void {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccountGroup`,\n this.getSelectedAccountGroup.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccountGroup`,\n this.setSelectedAccountGroup.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountsFromSelectedAccountGroup`,\n this.getAccountsFromSelectedAccountGroup.bind(this),\n );\n }\n}\n"]}
@@ -2,7 +2,7 @@ import type { AccountGroupId, AccountWalletId, AccountSelector } from "@metamask
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { InternalAccount } from "@metamask/keyring-internal-api";
4
4
  import type { AccountGroupObject } from "./group.cjs";
5
- import type { AccountTreeControllerConfig, AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.cjs";
5
+ import type { AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.cjs";
6
6
  import type { AccountWalletObject } from "./wallet.cjs";
7
7
  export declare const controllerName = "AccountTreeController";
8
8
  /**
@@ -32,12 +32,10 @@ export declare class AccountTreeController extends BaseController<typeof control
32
32
  * @param options - The controller options.
33
33
  * @param options.messenger - The messenger object.
34
34
  * @param options.state - Initial state to set on this controller
35
- * @param options.config - Optional configuration for the controller.
36
35
  */
37
- constructor({ messenger, state, config, }: {
36
+ constructor({ messenger, state, }: {
38
37
  messenger: AccountTreeControllerMessenger;
39
38
  state?: Partial<AccountTreeControllerState>;
40
- config?: AccountTreeControllerConfig;
41
39
  });
42
40
  /**
43
41
  * Initialize the controller's state.
@@ -81,12 +79,7 @@ export declare class AccountTreeController extends BaseController<typeof control
81
79
  derivationPath: string;
82
80
  groupIndex: number;
83
81
  } | {
84
- type: "private-key"; /**
85
- * Gets account group.
86
- *
87
- * @param groupId - The account group ID.
88
- * @returns The account group or undefined if not found.
89
- */
82
+ type: "private-key";
90
83
  } | undefined;
91
84
  exportable?: boolean | undefined;
92
85
  };
@@ -159,14 +152,5 @@ export declare class AccountTreeController extends BaseController<typeof control
159
152
  * @throws If the account group ID is not found in the current tree.
160
153
  */
161
154
  setAccountGroupHidden(groupId: AccountGroupId, hidden: boolean): void;
162
- /**
163
- * Clears all persisted metadata and syncing state.
164
- *
165
- * This will reset the account groups and wallets metadata, as well as
166
- * the syncing state. This should be used when we want to
167
- * completely reset the controller's state.
168
- */
169
- clearPersistedMetadataAndSyncingState(): void;
170
- syncWithUserStorage(): Promise<void>;
171
155
  }
172
156
  //# sourceMappingURL=AccountTreeController.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,eAAe,EAChB,8BAA8B;AAI/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAStE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAKlD,OAAO,KAAK,EACV,2BAA2B,EAC3B,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAyB,qBAAiB;AAE3E,eAAO,MAAM,cAAc,0BAA0B,CAAC;AA0BtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAWjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAIF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IA6BC;;;;;;;OAOG;gBAES,EACV,SAAS,EACT,KAAK,EACL,MAAM,GACP,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAC5C,MAAM,CAAC,EAAE,2BAA2B,CAAC;KACtC;IA+ED;;;;;;OAMG;IACH,IAAI;IAoLJ;;;;;OAKG;IACH,sBAAsB,CACpB,QAAQ,EAAE,eAAe,GACxB,mBAAmB,GAAG,SAAS;IASlC;;;;OAIG;IACH,uBAAuB,IAAI,mBAAmB,EAAE;IAIhD;;;;;;;;;;OAUG;IACH,mCAAmC,CACjC,QAAQ,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC;;;;;;;;;;qCAsZ7C;;;;;mBAKG;;;;;;;;;;;;;;;;;;;;;;IA5XH;;;;;OAKG;IACH,qBAAqB,CACnB,OAAO,EAAE,cAAc,GACtB,kBAAkB,GAAG,SAAS;IAkRjC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAsKtD;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBhE;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAoBnE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAwBrE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAwBrE;;;;;;OAMG;IACH,qCAAqC,IAAI,IAAI;IA4BvC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB3C"}
1
+ {"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,eAAe,EAChB,8BAA8B;AAI/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAKlD,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAyB,qBAAiB;AAE3E,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAkBtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CASjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAIF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAWC;;;;;;OAMG;gBAES,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IA6DD;;;;;;OAMG;IACH,IAAI;IAoLJ;;;;;OAKG;IACH,sBAAsB,CACpB,QAAQ,EAAE,eAAe,GACxB,mBAAmB,GAAG,SAAS;IASlC;;;;OAIG;IACH,uBAAuB,IAAI,mBAAmB,EAAE;IAIhD;;;;;;;;;;OAUG;IACH,mCAAmC,CACjC,QAAQ,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+B7C;;;;;OAKG;IACH,qBAAqB,CACnB,OAAO,EAAE,cAAc,GACtB,kBAAkB,GAAG,SAAS;IAwQjC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAsKtD;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAqBhE;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAiBnE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAqBrE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;CAwCtE"}
@@ -2,7 +2,7 @@ import type { AccountGroupId, AccountWalletId, AccountSelector } from "@metamask
2
2
  import { BaseController } from "@metamask/base-controller";
3
3
  import type { InternalAccount } from "@metamask/keyring-internal-api";
4
4
  import type { AccountGroupObject } from "./group.mjs";
5
- import type { AccountTreeControllerConfig, AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.mjs";
5
+ import type { AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.mjs";
6
6
  import type { AccountWalletObject } from "./wallet.mjs";
7
7
  export declare const controllerName = "AccountTreeController";
8
8
  /**
@@ -32,12 +32,10 @@ export declare class AccountTreeController extends BaseController<typeof control
32
32
  * @param options - The controller options.
33
33
  * @param options.messenger - The messenger object.
34
34
  * @param options.state - Initial state to set on this controller
35
- * @param options.config - Optional configuration for the controller.
36
35
  */
37
- constructor({ messenger, state, config, }: {
36
+ constructor({ messenger, state, }: {
38
37
  messenger: AccountTreeControllerMessenger;
39
38
  state?: Partial<AccountTreeControllerState>;
40
- config?: AccountTreeControllerConfig;
41
39
  });
42
40
  /**
43
41
  * Initialize the controller's state.
@@ -81,12 +79,7 @@ export declare class AccountTreeController extends BaseController<typeof control
81
79
  derivationPath: string;
82
80
  groupIndex: number;
83
81
  } | {
84
- type: "private-key"; /**
85
- * Gets account group.
86
- *
87
- * @param groupId - The account group ID.
88
- * @returns The account group or undefined if not found.
89
- */
82
+ type: "private-key";
90
83
  } | undefined;
91
84
  exportable?: boolean | undefined;
92
85
  };
@@ -159,14 +152,5 @@ export declare class AccountTreeController extends BaseController<typeof control
159
152
  * @throws If the account group ID is not found in the current tree.
160
153
  */
161
154
  setAccountGroupHidden(groupId: AccountGroupId, hidden: boolean): void;
162
- /**
163
- * Clears all persisted metadata and syncing state.
164
- *
165
- * This will reset the account groups and wallets metadata, as well as
166
- * the syncing state. This should be used when we want to
167
- * completely reset the controller's state.
168
- */
169
- clearPersistedMetadataAndSyncingState(): void;
170
- syncWithUserStorage(): Promise<void>;
171
155
  }
172
156
  //# sourceMappingURL=AccountTreeController.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,eAAe,EAChB,8BAA8B;AAI/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAStE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAKlD,OAAO,KAAK,EACV,2BAA2B,EAC3B,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAyB,qBAAiB;AAE3E,eAAO,MAAM,cAAc,0BAA0B,CAAC;AA0BtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAWjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAIF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IA6BC;;;;;;;OAOG;gBAES,EACV,SAAS,EACT,KAAK,EACL,MAAM,GACP,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAC5C,MAAM,CAAC,EAAE,2BAA2B,CAAC;KACtC;IA+ED;;;;;;OAMG;IACH,IAAI;IAoLJ;;;;;OAKG;IACH,sBAAsB,CACpB,QAAQ,EAAE,eAAe,GACxB,mBAAmB,GAAG,SAAS;IASlC;;;;OAIG;IACH,uBAAuB,IAAI,mBAAmB,EAAE;IAIhD;;;;;;;;;;OAUG;IACH,mCAAmC,CACjC,QAAQ,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC;;;;;;;;;;qCAsZ7C;;;;;mBAKG;;;;;;;;;;;;;;;;;;;;;;IA5XH;;;;;OAKG;IACH,qBAAqB,CACnB,OAAO,EAAE,cAAc,GACtB,kBAAkB,GAAG,SAAS;IAkRjC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAsKtD;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBhE;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAoBnE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAwBrE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAwBrE;;;;;;OAMG;IACH,qCAAqC,IAAI,IAAI;IA4BvC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB3C"}
1
+ {"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEf,eAAe,EAChB,8BAA8B;AAI/B,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAKlD,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAyB,qBAAiB;AAE3E,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAkBtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CASjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAIF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAWC;;;;;;OAMG;gBAES,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IA6DD;;;;;;OAMG;IACH,IAAI;IAoLJ;;;;;OAKG;IACH,sBAAsB,CACpB,QAAQ,EAAE,eAAe,GACxB,mBAAmB,GAAG,SAAS;IASlC;;;;OAIG;IACH,uBAAuB,IAAI,mBAAmB,EAAE;IAIhD;;;;;;;;;;OAUG;IACH,mCAAmC,CACjC,QAAQ,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+B7C;;;;;OAKG;IACH,qBAAqB,CACnB,OAAO,EAAE,cAAc,GACtB,kBAAkB,GAAG,SAAS;IAwQjC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAsKtD;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAqBhE;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAiBnE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAqBrE;;;;;;OAMG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;CAwCtE"}