@metamask-previews/account-tree-controller 1.5.0-preview-53e28985 → 1.5.0-preview-31415333

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.
package/CHANGELOG.md CHANGED
@@ -7,14 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Changed
11
-
12
- - Bump `@metamask/base-controller` from `^8.4.1` to `^8.4.2` ([#6917](https://github.com/MetaMask/core/pull/6917))
13
-
14
10
  ## [1.5.0]
15
11
 
16
12
  ### Changed
17
13
 
14
+ - **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6380](https://github.com/MetaMask/core/pull/6380))
15
+ - Previously, `AccountTreeController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`.
18
16
  - Use non-EVM account names for group names ([#6831](https://github.com/MetaMask/core/pull/6831))
19
17
  - EVM accounts still take precedence over non-EVM accounts.
20
18
  - Before accounts get re-aligned, it is possible that a group contains only non-EVM accounts, in which case, the first non-EVM account name will be used for that account group.
@@ -10,12 +10,11 @@ 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_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_backupAndSyncService, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_initialized, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_sortAccountsOfGroup, _AccountTreeController_insertAccount, _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup, _AccountTreeController_getMultichainAccountWallets, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated, _AccountTreeController_handleMultichainAccountWalletStatusChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_registerMessageHandlers, _AccountTreeController_createBackupAndSyncContext;
13
+ var _AccountTreeController_instances, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_backupAndSyncService, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_initialized, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_handleMultichainAccountWalletStatusChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_registerMessageHandlers, _AccountTreeController_createBackupAndSyncContext;
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
- const account_api_2 = require("@metamask/account-api");
18
- const base_controller_1 = require("@metamask/base-controller");
17
+ const next_1 = require("@metamask/base-controller/next");
19
18
  const keyring_api_1 = require("@metamask/keyring-api");
20
19
  const utils_1 = require("@metamask/utils");
21
20
  const analytics_1 = require("./backup-and-sync/analytics/index.cjs");
@@ -30,31 +29,31 @@ const accountTreeControllerMetadata = {
30
29
  accountTree: {
31
30
  includeInStateLogs: true,
32
31
  persist: false,
33
- anonymous: false,
32
+ includeInDebugSnapshot: false,
34
33
  usedInUi: true,
35
34
  },
36
35
  isAccountTreeSyncingInProgress: {
37
36
  includeInStateLogs: false,
38
37
  persist: false,
39
- anonymous: false,
38
+ includeInDebugSnapshot: false,
40
39
  usedInUi: true,
41
40
  },
42
41
  hasAccountTreeSyncingSyncedAtLeastOnce: {
43
42
  includeInStateLogs: true,
44
43
  persist: true,
45
- anonymous: false,
44
+ includeInDebugSnapshot: false,
46
45
  usedInUi: true,
47
46
  },
48
47
  accountGroupsMetadata: {
49
48
  includeInStateLogs: true,
50
49
  persist: true,
51
- anonymous: false,
50
+ includeInDebugSnapshot: false,
52
51
  usedInUi: true,
53
52
  },
54
53
  accountWalletsMetadata: {
55
54
  includeInStateLogs: true,
56
55
  persist: true,
57
- anonymous: false,
56
+ includeInDebugSnapshot: false,
58
57
  usedInUi: true,
59
58
  },
60
59
  };
@@ -76,7 +75,7 @@ function getDefaultAccountTreeControllerState() {
76
75
  };
77
76
  }
78
77
  exports.getDefaultAccountTreeControllerState = getDefaultAccountTreeControllerState;
79
- class AccountTreeController extends base_controller_1.BaseController {
78
+ class AccountTreeController extends next_1.BaseController {
80
79
  /**
81
80
  * Constructor for AccountTreeController.
82
81
  *
@@ -115,11 +114,11 @@ class AccountTreeController extends base_controller_1.BaseController {
115
114
  // Rules to apply to construct the wallets tree.
116
115
  __classPrivateFieldSet(this, _AccountTreeController_rules, [
117
116
  // 1. We group by entropy-source
118
- new entropy_1.EntropyRule(this.messagingSystem),
117
+ new entropy_1.EntropyRule(this.messenger),
119
118
  // 2. We group by Snap ID
120
- new snap_1.SnapRule(this.messagingSystem),
119
+ new snap_1.SnapRule(this.messenger),
121
120
  // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)
122
- new keyring_1.KeyringRule(this.messagingSystem),
121
+ new keyring_1.KeyringRule(this.messenger),
123
122
  ], "f");
124
123
  // Initialize trace function
125
124
  __classPrivateFieldSet(this, _AccountTreeController_trace, config?.trace ?? analytics_1.traceFallback, "f");
@@ -132,25 +131,19 @@ class AccountTreeController extends base_controller_1.BaseController {
132
131
  }, "f");
133
132
  // Initialize the backup and sync service
134
133
  __classPrivateFieldSet(this, _AccountTreeController_backupAndSyncService, new service_1.BackupAndSyncService(__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_createBackupAndSyncContext).call(this)), "f");
135
- this.messagingSystem.subscribe('AccountsController:accountAdded', (account) => {
134
+ this.messenger.subscribe('AccountsController:accountAdded', (account) => {
136
135
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountAdded).call(this, account);
137
136
  });
138
- this.messagingSystem.subscribe('AccountsController:accountRemoved', (accountId) => {
137
+ this.messenger.subscribe('AccountsController:accountRemoved', (accountId) => {
139
138
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountRemoved).call(this, accountId);
140
139
  });
141
- this.messagingSystem.subscribe('AccountsController:selectedAccountChange', (account) => {
140
+ this.messenger.subscribe('AccountsController:selectedAccountChange', (account) => {
142
141
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleSelectedAccountChange).call(this, account);
143
142
  });
144
- this.messagingSystem.subscribe('UserStorageController:stateChange', (userStorageControllerState) => {
143
+ this.messenger.subscribe('UserStorageController:stateChange', (userStorageControllerState) => {
145
144
  __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").handleUserStorageStateChange(userStorageControllerState);
146
145
  });
147
- this.messagingSystem.subscribe('MultichainAccountService:multichainAccountGroupCreated', (group) => {
148
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated).call(this, group);
149
- });
150
- this.messagingSystem.subscribe('MultichainAccountService:multichainAccountGroupUpdated', (group) => {
151
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated).call(this, group);
152
- });
153
- this.messagingSystem.subscribe('MultichainAccountService:walletStatusChange', (walletId, status) => {
146
+ this.messenger.subscribe('MultichainAccountService:walletStatusChange', (walletId, status) => {
154
147
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountWalletStatusChange).call(this, walletId, status);
155
148
  });
156
149
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_registerMessageHandlers).call(this);
@@ -169,7 +162,6 @@ class AccountTreeController extends base_controller_1.BaseController {
169
162
  return;
170
163
  }
171
164
  (0, logger_1.projectLogger)('Initializing...');
172
- // For now, we always re-compute all wallets, we do not re-use the existing state.
173
165
  const wallets = {};
174
166
  // Clear mappings for fresh rebuild.
175
167
  __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").clear();
@@ -177,12 +169,6 @@ class AccountTreeController extends base_controller_1.BaseController {
177
169
  // Keep the current selected group to check if it's still part of the tree
178
170
  // after rebuilding it.
179
171
  const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
180
- // Insert all multichain account wallet/groups.
181
- for (const wallet of __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getMultichainAccountWallets).call(this)) {
182
- for (const group of wallet.getMultichainAccountGroups()) {
183
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup).call(this, wallets, wallet, group);
184
- }
185
- }
186
172
  // There's no guarantee that accounts would be sorted by their import time
187
173
  // with `listMultichainAccounts`. We have to sort them here before constructing
188
174
  // the tree.
@@ -195,9 +181,9 @@ class AccountTreeController extends base_controller_1.BaseController {
195
181
  // won't be enough and we would have to use group properties instead (like group
196
182
  // index or maybe introduce a `importTime` at group level).
197
183
  const accounts = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_listAccounts).call(this).sort((a, b) => a.metadata.importTime - b.metadata.importTime);
198
- // Insert all other kind of accounts (private keys, HW, other Snap accounts, etc.).
184
+ // For now, we always re-compute all wallets, we do not re-use the existing state.
199
185
  for (const account of accounts) {
200
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertAccount).call(this, wallets, account);
186
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, wallets, account);
201
187
  }
202
188
  // Once we have the account tree, we can apply persisted metadata (names + UI states).
203
189
  let previousSelectedAccountGroupStillExists = false;
@@ -246,7 +232,7 @@ class AccountTreeController extends base_controller_1.BaseController {
246
232
  if (previousSelectedAccountGroup !==
247
233
  this.state.accountTree.selectedAccountGroup) {
248
234
  (0, logger_1.projectLogger)(`Selected (initial) group is: [${this.state.accountTree.selectedAccountGroup}]`);
249
- this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
235
+ this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
250
236
  }
251
237
  (0, logger_1.projectLogger)('Initialized!');
252
238
  __classPrivateFieldSet(this, _AccountTreeController_initialized, true, "f");
@@ -307,7 +293,7 @@ class AccountTreeController extends base_controller_1.BaseController {
307
293
  }
308
294
  const accounts = [];
309
295
  for (const id of group.accounts) {
310
- const account = this.messagingSystem.call('AccountsController:getAccount', id);
296
+ const account = this.messenger.call('AccountsController:getAccount', id);
311
297
  // For now, we're filtering undefined account, but I believe
312
298
  // throwing would be more appropriate here.
313
299
  if (account) {
@@ -359,10 +345,10 @@ class AccountTreeController extends base_controller_1.BaseController {
359
345
  state.accountTree.selectedAccountGroup = groupId;
360
346
  });
361
347
  (0, logger_1.projectLogger)(`Selected group is now: [${this.state.accountTree.selectedAccountGroup}]`);
362
- this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
348
+ this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
363
349
  // Update AccountsController - this will trigger selectedAccountChange event,
364
350
  // but our handler is idempotent so it won't cause infinite loop
365
- this.messagingSystem.call('AccountsController:setSelectedAccount', accountToSelect);
351
+ this.messenger.call('AccountsController:setSelectedAccount', accountToSelect);
366
352
  }
367
353
  /**
368
354
  * Resolves name conflicts by adding a suffix to make the name unique.
@@ -610,7 +596,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
610
596
  }, _AccountTreeController_getComputedAccountGroupName = function _AccountTreeController_getComputedAccountGroupName(wallet, group) {
611
597
  let proposedName = ''; // Empty means there's no computed name for this group.
612
598
  for (const id of group.accounts) {
613
- const account = this.messagingSystem.call('AccountsController:getAccount', id);
599
+ const account = this.messenger.call('AccountsController:getAccount', id);
614
600
  if (!account || !account.metadata.name.length) {
615
601
  continue;
616
602
  }
@@ -735,15 +721,10 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
735
721
  if (!__classPrivateFieldGet(this, _AccountTreeController_initialized, "f")) {
736
722
  return;
737
723
  }
738
- if ((0, account_api_1.isBip44Account)(account)) {
739
- // We're skipping BIP-44 accounts since we rely on the `MultichainAccountService` to do
740
- // the grouping of wallets/groups directly.
741
- return;
742
- }
743
724
  // Check if this account is already known by the tree to avoid double-insertion.
744
725
  if (!__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").has(account.id)) {
745
726
  this.update((state) => {
746
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertAccount).call(this, state.accountTree.wallets, account);
727
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
747
728
  const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
748
729
  if (context) {
749
730
  const { walletId, groupId } = context;
@@ -754,7 +735,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
754
735
  }
755
736
  }
756
737
  });
757
- this.messagingSystem.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
738
+ this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
758
739
  }
759
740
  }, _AccountTreeController_handleAccountRemoved = function _AccountTreeController_handleAccountRemoved(accountId) {
760
741
  // We wait for the first `init` to be called to actually build up the tree and
@@ -766,39 +747,33 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
766
747
  const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(accountId);
767
748
  if (context) {
768
749
  const { walletId, groupId } = context;
769
- // If it's in the context, then `group` should be defined.
770
- const group = this.state.accountTree.wallets[walletId]?.groups[groupId];
771
- // We're only considering non-BIP-44 accounts for single account events.
772
- if (group.type !== account_api_2.AccountGroupType.MultichainAccount) {
773
- const index = group.accounts.indexOf(accountId);
774
- if (index !== -1) {
775
- let selectedAccountGroupChanged = false;
776
- const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
777
- this.update((state) => {
778
- const accounts = state.accountTree.wallets[walletId]?.groups[groupId].accounts;
779
- // Effectively remove account from the group and state.
750
+ const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
751
+ let selectedAccountGroupChanged = false;
752
+ this.update((state) => {
753
+ const accounts = state.accountTree.wallets[walletId]?.groups[groupId]?.accounts;
754
+ if (accounts) {
755
+ const index = accounts.indexOf(accountId);
756
+ if (index !== -1) {
780
757
  accounts.splice(index, 1);
781
- // If there's no more account, we have to prune the group and maybe select
782
- // a new account group too.
783
- if (accounts.length === 0) {
784
- // Check if we need to update selectedAccountGroup after removal
785
- if (state.accountTree.selectedAccountGroup === groupId) {
786
- // The currently selected group is now empty, find a new group to select
787
- const newSelectedAccountGroup = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, state.accountTree.wallets);
788
- state.accountTree.selectedAccountGroup =
789
- newSelectedAccountGroup;
790
- selectedAccountGroupChanged =
791
- newSelectedAccountGroup !== previousSelectedAccountGroup;
792
- }
793
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_pruneEmptyGroupAndWallet).call(this, state, walletId, groupId);
758
+ // Check if we need to update selectedAccountGroup after removal
759
+ if (state.accountTree.selectedAccountGroup === groupId &&
760
+ accounts.length === 0) {
761
+ // The currently selected group is now empty, find a new group to select
762
+ const newSelectedAccountGroup = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, state.accountTree.wallets);
763
+ state.accountTree.selectedAccountGroup = newSelectedAccountGroup;
764
+ selectedAccountGroupChanged =
765
+ newSelectedAccountGroup !== previousSelectedAccountGroup;
794
766
  }
795
- });
796
- this.messagingSystem.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
797
- // Emit selectedAccountGroupChange event if the selected group changed
798
- if (selectedAccountGroupChanged) {
799
- this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
767
+ }
768
+ if (accounts.length === 0) {
769
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_pruneEmptyGroupAndWallet).call(this, state, walletId, groupId);
800
770
  }
801
771
  }
772
+ });
773
+ this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
774
+ // Emit selectedAccountGroupChange event if the selected group changed
775
+ if (selectedAccountGroupChanged) {
776
+ this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
802
777
  }
803
778
  // Clear reverse-mapping for that account.
804
779
  __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").delete(accountId);
@@ -815,25 +790,9 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
815
790
  delete state.accountWalletsMetadata[walletId];
816
791
  }
817
792
  return state;
818
- }, _AccountTreeController_sortAccountsOfGroup = function _AccountTreeController_sortAccountsOfGroup(group) {
819
- group.accounts.sort(
820
- /* istanbul ignore next: Comparator branch execution (a===id vs b===id)
821
- * and return attribution vary across engines; final ordering is covered
822
- * by behavior tests. Ignoring the entire comparator avoids flaky line
823
- * coverage without reducing scenario coverage.
824
- */
825
- (a, b) => {
826
- const aSortOrder = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(a)?.sortOrder;
827
- const bSortOrder = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(b)?.sortOrder;
828
- return (aSortOrder ?? group_1.MAX_SORT_ORDER) - (bSortOrder ?? group_1.MAX_SORT_ORDER);
829
- });
830
- }, _AccountTreeController_insertAccount = function _AccountTreeController_insertAccount(wallets, account) {
831
- if ((0, account_api_1.isBip44Account)(account)) {
832
- // We're skipping BIP-44 accounts since we rely on the `MultichainAccountService` to do
833
- // the grouping of wallets/groups directly.
834
- return;
835
- }
836
- const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
793
+ }, _AccountTreeController_insert = function _AccountTreeController_insert(wallets, account) {
794
+ const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).match(account) ??
795
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
837
796
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).match(account); // This one cannot fail.
838
797
  // Update controller's state.
839
798
  const walletId = result.wallet.id;
@@ -852,6 +811,10 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
852
811
  // the union tag `result.wallet.type`.
853
812
  };
854
813
  wallet = wallets[walletId];
814
+ // Trigger atomic sync for new wallet (only for entropy wallets)
815
+ if (wallet.type === account_api_1.AccountWalletType.Entropy) {
816
+ __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleWalletSync(walletId);
817
+ }
855
818
  }
856
819
  const groupId = result.group.id;
857
820
  let group = wallet.groups[groupId];
@@ -874,9 +837,28 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
874
837
  group = wallet.groups[groupId];
875
838
  // Map group ID to its containing wallet ID for efficient direct access
876
839
  __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").set(groupId, walletId);
840
+ // Trigger atomic sync for new group (only for entropy wallets)
841
+ if (wallet.type === account_api_1.AccountWalletType.Entropy) {
842
+ __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleGroupSync(groupId);
843
+ }
877
844
  }
878
845
  else {
879
846
  group.accounts.push(id);
847
+ // We need to do this at every insertion because race conditions can happen
848
+ // during the account creation process where one provider completes before the other.
849
+ // The discovery process in the service can also lead to some accounts being created "out of order".
850
+ const { accounts } = group;
851
+ accounts.sort(
852
+ /* istanbul ignore next: Comparator branch execution (a===id vs b===id)
853
+ * and return attribution vary across engines; final ordering is covered
854
+ * by behavior tests. Ignoring the entire comparator avoids flaky line
855
+ * coverage without reducing scenario coverage.
856
+ */
857
+ (a, b) => {
858
+ const aSortOrder = a === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(a)?.sortOrder;
859
+ const bSortOrder = b === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(b)?.sortOrder;
860
+ return ((aSortOrder ?? group_1.MAX_SORT_ORDER) - (bSortOrder ?? group_1.MAX_SORT_ORDER));
861
+ });
880
862
  }
881
863
  (0, logger_1.projectLogger)(`[${groupId}] Add new account: { id: "${account.id}", type: "${account.type}", address: "${account.address}"`);
882
864
  // Update the reverse mapping for this account.
@@ -885,90 +867,8 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
885
867
  groupId: group.id,
886
868
  sortOrder,
887
869
  });
888
- // We need to do this at every insertion because race conditions can happen
889
- // during the account creation process where one provider completes before the other.
890
- // The discovery process in the service can also lead to some accounts being created "out of order".
891
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_sortAccountsOfGroup).call(this, group);
892
- }, _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup = function _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup(wallets, multichainAccountWallet, multichainAccountGroup) {
893
- const walletId = multichainAccountWallet.id;
894
- const groupId = multichainAccountGroup.id;
895
- let wallet = null;
896
- let group = null;
897
- // Check type, mainly to infer proper wallet object type.
898
- const walletObject = wallets[walletId];
899
- if (walletObject && walletObject.type === account_api_1.AccountWalletType.Entropy) {
900
- wallet = walletObject;
901
- group = wallet.groups[groupId];
902
- }
903
- // We always re-use the account list from the group (if accounts get
904
- // added/removed/re-ordered within the group).
905
- const accounts = multichainAccountGroup.getAccounts();
906
- const accountIds = accounts
907
- // For now, we need this type-cast because `getAccounts` do not have the same
908
- // type-constraint (uses string[] instead of [string; ...string])
909
- .map((account) => account.id);
910
- // Create the group object first, to inject it in the wallet in case this wallet is
911
- // not part of the tree yet.
912
- if (!group) {
913
- group = {
914
- id: multichainAccountGroup.id,
915
- type: multichainAccountGroup.type,
916
- accounts: accountIds,
917
- metadata: {
918
- entropy: {
919
- groupIndex: multichainAccountGroup.groupIndex,
920
- },
921
- name: '',
922
- pinned: false,
923
- hidden: false,
924
- },
925
- };
926
- }
927
- else {
928
- group.accounts = accountIds;
929
- }
930
- if (!wallet) {
931
- wallet = {
932
- id: multichainAccountWallet.id,
933
- type: multichainAccountWallet.type,
934
- status: multichainAccountWallet.status,
935
- groups: {
936
- [group.id]: group,
937
- },
938
- metadata: {
939
- entropy: {
940
- id: multichainAccountWallet.entropySource,
941
- },
942
- name: '', // Will get updated later.
943
- },
944
- };
945
- wallets[walletId] = wallet;
946
- // Trigger atomic sync for new wallet.
947
- __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleWalletSync(walletId);
948
- }
949
- else {
950
- wallet.groups[group.id] = group;
951
- // Trigger atomic sync for new group.
952
- __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleGroupSync(groupId);
953
- }
954
- // Map group ID to its containing wallet ID for efficient direct access
955
- __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").set(groupId, walletId);
956
- // Update the reverse mapping for all accounts account.
957
- for (const account of accounts) {
958
- __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").set(account.id, {
959
- walletId: wallet.id,
960
- groupId: group.id,
961
- sortOrder: group_1.ACCOUNT_TYPE_TO_SORT_ORDER[account.type] ?? group_1.MAX_SORT_ORDER,
962
- });
963
- }
964
- // We need to do this at every insertion because race conditions can happen
965
- // during the account creation process where one provider completes before the other.
966
- // The discovery process in the service can also lead to some accounts being created "out of order".
967
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_sortAccountsOfGroup).call(this, group);
968
- }, _AccountTreeController_getMultichainAccountWallets = function _AccountTreeController_getMultichainAccountWallets() {
969
- return this.messagingSystem.call('MultichainAccountService:getMultichainAccountWallets');
970
870
  }, _AccountTreeController_listAccounts = function _AccountTreeController_listAccounts() {
971
- return this.messagingSystem.call('AccountsController:listMultichainAccounts');
871
+ return this.messenger.call('AccountsController:listMultichainAccounts');
972
872
  }, _AccountTreeController_assertAccountGroupExists = function _AccountTreeController_assertAccountGroupExists(groupId) {
973
873
  const exists = __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").has(groupId);
974
874
  if (!exists) {
@@ -984,7 +884,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
984
884
  throw new Error('Account group name already exists');
985
885
  }
986
886
  }, _AccountTreeController_getDefaultSelectedAccountGroup = function _AccountTreeController_getDefaultSelectedAccountGroup(wallets) {
987
- const selectedAccount = this.messagingSystem.call('AccountsController:getSelectedMultichainAccount');
887
+ const selectedAccount = this.messenger.call('AccountsController:getSelectedMultichainAccount');
988
888
  if (selectedAccount && selectedAccount.id) {
989
889
  const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(selectedAccount.id);
990
890
  if (accountMapping) {
@@ -1010,20 +910,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
1010
910
  this.update((state) => {
1011
911
  state.accountTree.selectedAccountGroup = groupId;
1012
912
  });
1013
- this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
1014
- }, _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated = function _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated(multichainAccountGroup) {
1015
- this.update((state) => {
1016
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup).call(this, state.accountTree.wallets, multichainAccountGroup.wallet, multichainAccountGroup);
1017
- const wallet = state.accountTree.wallets[multichainAccountGroup.wallet.id];
1018
- if (wallet) {
1019
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountWalletMetadata).call(this, state, wallet.id);
1020
- const group = wallet.groups[multichainAccountGroup.id];
1021
- if (group) {
1022
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountGroupMetadata).call(this, state, wallet.id, group.id);
1023
- }
1024
- }
1025
- });
1026
- this.messagingSystem.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
913
+ this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
1027
914
  }, _AccountTreeController_handleMultichainAccountWalletStatusChange = function _AccountTreeController_handleMultichainAccountWalletStatusChange(walletId, walletStatus) {
1028
915
  this.update((state) => {
1029
916
  const wallet = state.accountTree.wallets[walletId];
@@ -1039,7 +926,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
1039
926
  if (group) {
1040
927
  let candidate;
1041
928
  for (const id of group.accounts) {
1042
- const account = this.messagingSystem.call('AccountsController:getAccount', id);
929
+ const account = this.messenger.call('AccountsController:getAccount', id);
1043
930
  if (!candidate) {
1044
931
  candidate = id;
1045
932
  }
@@ -1063,7 +950,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
1063
950
  candidate = group.id;
1064
951
  }
1065
952
  for (const id of group.accounts) {
1066
- const account = this.messagingSystem.call('AccountsController:getAccount', id);
953
+ const account = this.messenger.call('AccountsController:getAccount', id);
1067
954
  if (account && (0, keyring_api_1.isEvmAccountType)(account.type)) {
1068
955
  // EVM accounts have a higher priority, so if we find any, we just
1069
956
  // use that group!
@@ -1074,18 +961,18 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
1074
961
  }
1075
962
  return candidate;
1076
963
  }, _AccountTreeController_registerMessageHandlers = function _AccountTreeController_registerMessageHandlers() {
1077
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:getSelectedAccountGroup`, this.getSelectedAccountGroup.bind(this));
1078
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:setSelectedAccountGroup`, this.setSelectedAccountGroup.bind(this));
1079
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:getAccountsFromSelectedAccountGroup`, this.getAccountsFromSelectedAccountGroup.bind(this));
1080
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:setAccountWalletName`, this.setAccountWalletName.bind(this));
1081
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:setAccountGroupName`, this.setAccountGroupName.bind(this));
1082
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:setAccountGroupPinned`, this.setAccountGroupPinned.bind(this));
1083
- this.messagingSystem.registerActionHandler(`${exports.controllerName}:setAccountGroupHidden`, this.setAccountGroupHidden.bind(this));
964
+ this.messenger.registerActionHandler(`${exports.controllerName}:getSelectedAccountGroup`, this.getSelectedAccountGroup.bind(this));
965
+ this.messenger.registerActionHandler(`${exports.controllerName}:setSelectedAccountGroup`, this.setSelectedAccountGroup.bind(this));
966
+ this.messenger.registerActionHandler(`${exports.controllerName}:getAccountsFromSelectedAccountGroup`, this.getAccountsFromSelectedAccountGroup.bind(this));
967
+ this.messenger.registerActionHandler(`${exports.controllerName}:setAccountWalletName`, this.setAccountWalletName.bind(this));
968
+ this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupName`, this.setAccountGroupName.bind(this));
969
+ this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupPinned`, this.setAccountGroupPinned.bind(this));
970
+ this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupHidden`, this.setAccountGroupHidden.bind(this));
1084
971
  }, _AccountTreeController_createBackupAndSyncContext = function _AccountTreeController_createBackupAndSyncContext() {
1085
972
  return {
1086
973
  ...__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncConfig, "f"),
1087
974
  controller: this,
1088
- messenger: this.messagingSystem,
975
+ messenger: this.messenger,
1089
976
  controllerStateUpdateFn: this.update.bind(this),
1090
977
  traceFn: __classPrivateFieldGet(this, _AccountTreeController_trace, "f").bind(this),
1091
978
  groupIdToWalletId: __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f"),