@metamask-previews/account-tree-controller 7.3.0-preview-c7e584108 → 7.3.0-preview-337abd924

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,9 +7,14 @@ 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 `AccountTreeController:accountGroup{Created,Updated,Removed}` events ([#8766](https://github.com/MetaMask/core/pull/8766))
13
+ - None of these events fire during `init`/`reinit`, consumers should bootstrap from `:getState` or `:accountTreeChange`.
14
+
10
15
  ### Changed
11
16
 
12
- - Bump `@metamask/accounts-controller` from `^38.0.0` to `^38.1.0` ([#8755](https://github.com/MetaMask/core/pull/8755))
17
+ - Bump `@metamask/accounts-controller` from `^38.0.0` to `^38.1.1` ([#8755](https://github.com/MetaMask/core/pull/8755), [#8774](https://github.com/MetaMask/core/pull/8774))
13
18
 
14
19
  ## [7.3.0]
15
20
 
@@ -10,7 +10,7 @@ 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_accountOrderCallbacks, _AccountTreeController_initialized, _AccountTreeController_initTreeContext, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountsAdded, _AccountTreeController_handleAccountsRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_setSelectedAccountGroup, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_handleMultichainAccountWalletStatusChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_hasEvmAccount, _AccountTreeController_resolveNameConflict, _AccountTreeController_createBackupAndSyncContext;
13
+ var _AccountTreeController_instances, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_backupAndSyncService, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_accountOrderCallbacks, _AccountTreeController_initialized, _AccountTreeController_initTreeContext, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountsAdded, _AccountTreeController_handleAccountsRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_publishAccountGroupCreated, _AccountTreeController_publishAccountGroupUpdated, _AccountTreeController_publishAccountGroupRemoved, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_setSelectedAccountGroup, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_handleMultichainAccountWalletStatusChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_hasEvmAccount, _AccountTreeController_resolveNameConflict, _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");
@@ -410,6 +410,7 @@ class AccountTreeController extends base_controller_1.BaseController {
410
410
  state.accountTree.wallets[walletId].groups[groupId].metadata.name =
411
411
  finalName;
412
412
  });
413
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupUpdated).call(this, walletId, groupId);
413
414
  // Trigger atomic sync for group rename (only for groups from entropy wallets)
414
415
  if (wallet.type === account_api_1.AccountWalletType.Entropy) {
415
416
  __classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleGroupSync(groupId);
@@ -469,6 +470,9 @@ class AccountTreeController extends base_controller_1.BaseController {
469
470
  pinned;
470
471
  }
471
472
  });
473
+ if (walletId) {
474
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupUpdated).call(this, walletId, groupId);
475
+ }
472
476
  // Trigger atomic sync for group pinning (only for groups from entropy wallets)
473
477
  if (walletId &&
474
478
  this.state.accountTree.wallets[walletId].type ===
@@ -503,6 +507,9 @@ class AccountTreeController extends base_controller_1.BaseController {
503
507
  hidden;
504
508
  }
505
509
  });
510
+ if (walletId) {
511
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupUpdated).call(this, walletId, groupId);
512
+ }
506
513
  // Trigger atomic sync for group hiding (only for groups from entropy wallets)
507
514
  if (walletId &&
508
515
  this.state.accountTree.wallets[walletId].type ===
@@ -786,21 +793,37 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
786
793
  if (newAccounts.length === 0) {
787
794
  return;
788
795
  }
796
+ const createdGroups = new Map();
797
+ const updatedGroups = new Map();
789
798
  this.update((state) => {
790
799
  for (const account of newAccounts) {
791
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
792
- const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
793
- if (context) {
794
- const { walletId, groupId } = context;
795
- const wallet = state.accountTree.wallets[walletId];
796
- if (wallet) {
797
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountWalletMetadata).call(this, state, walletId);
798
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountGroupMetadata).call(this, state, walletId, groupId);
799
- }
800
+ const { walletId, groupId, created } = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
801
+ if (created) {
802
+ createdGroups.set(groupId, walletId);
803
+ }
804
+ else if (!createdGroups.has(groupId)) {
805
+ // ^ We check that the group has not been created in this same batch before adding it to the `updatedGroups`
806
+ // map, to avoid sending both created and updated events for the same group:
807
+ // - Account 1 + Account 2 + Account 3
808
+ // - Account 1 and 3 belong to the same group
809
+ // - Account 1 will create the group
810
+ // - Account 3 will update the group (but we only want to send a created event, not an updated one)
811
+ updatedGroups.set(groupId, walletId);
812
+ }
813
+ const wallet = state.accountTree.wallets[walletId];
814
+ if (wallet) {
815
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountWalletMetadata).call(this, state, walletId);
816
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountGroupMetadata).call(this, state, walletId, groupId);
800
817
  }
801
818
  }
802
819
  });
803
820
  this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
821
+ for (const [groupId, walletId] of createdGroups) {
822
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupCreated).call(this, walletId, groupId);
823
+ }
824
+ for (const [groupId, walletId] of updatedGroups) {
825
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupUpdated).call(this, walletId, groupId);
826
+ }
804
827
  }, _AccountTreeController_handleAccountsRemoved = function _AccountTreeController_handleAccountsRemoved(accountIds) {
805
828
  // We wait for the first `init` to be called to actually build up the tree and
806
829
  // mutate it. We expect the caller to first update the `AccountsController` state
@@ -819,6 +842,8 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
819
842
  return;
820
843
  }
821
844
  const previousSelectedAccountGroup = this.state.selectedAccountGroup;
845
+ const updatedGroups = new Map();
846
+ const removedGroups = new Set();
822
847
  this.update((state) => {
823
848
  for (const { id: accountId, context } of knownAccounts) {
824
849
  const { walletId, groupId } = context;
@@ -834,6 +859,12 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
834
859
  }
835
860
  if (accounts.length === 0) {
836
861
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_pruneEmptyGroupAndWallet).call(this, state, walletId, groupId);
862
+ // If the group gets pruned, we should not consider it as updated.
863
+ updatedGroups.delete(groupId);
864
+ removedGroups.add(groupId);
865
+ }
866
+ else {
867
+ updatedGroups.set(groupId, walletId);
837
868
  }
838
869
  }
839
870
  }
@@ -843,6 +874,12 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
843
874
  __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").delete(id);
844
875
  }
845
876
  this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
877
+ for (const [groupId, walletId] of updatedGroups) {
878
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupUpdated).call(this, walletId, groupId);
879
+ }
880
+ for (const groupId of removedGroups) {
881
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_publishAccountGroupRemoved).call(this, groupId);
882
+ }
846
883
  const newSelectedAccountGroup = this.state.selectedAccountGroup;
847
884
  if (newSelectedAccountGroup !== previousSelectedAccountGroup) {
848
885
  this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, newSelectedAccountGroup, previousSelectedAccountGroup);
@@ -859,6 +896,18 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
859
896
  delete state.accountWalletsMetadata[walletId];
860
897
  }
861
898
  return state;
899
+ }, _AccountTreeController_publishAccountGroupCreated = function _AccountTreeController_publishAccountGroupCreated(walletId, groupId) {
900
+ const group = this.state.accountTree.wallets[walletId]?.groups[groupId];
901
+ if (group) {
902
+ this.messenger.publish(`${exports.controllerName}:accountGroupCreated`, group);
903
+ }
904
+ }, _AccountTreeController_publishAccountGroupUpdated = function _AccountTreeController_publishAccountGroupUpdated(walletId, groupId) {
905
+ const group = this.state.accountTree.wallets[walletId]?.groups[groupId];
906
+ if (group) {
907
+ this.messenger.publish(`${exports.controllerName}:accountGroupUpdated`, group);
908
+ }
909
+ }, _AccountTreeController_publishAccountGroupRemoved = function _AccountTreeController_publishAccountGroupRemoved(groupId) {
910
+ this.messenger.publish(`${exports.controllerName}:accountGroupRemoved`, groupId);
862
911
  }, _AccountTreeController_insert = function _AccountTreeController_insert(wallets, account) {
863
912
  const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).match(account) ??
864
913
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
@@ -889,6 +938,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
889
938
  let group = wallet.groups[groupId];
890
939
  const { type, id } = account;
891
940
  const sortOrder = group_1.ACCOUNT_TYPE_TO_SORT_ORDER[type];
941
+ const created = !group;
892
942
  if (!group) {
893
943
  (0, logger_1.projectLogger)(`[${walletId}] Add new group: [${groupId}]`);
894
944
  wallet.groups[groupId] = {
@@ -936,6 +986,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
936
986
  groupId: group.id,
937
987
  sortOrder,
938
988
  });
989
+ return { walletId: wallet.id, groupId: group.id, created };
939
990
  }, _AccountTreeController_listAccounts = function _AccountTreeController_listAccounts() {
940
991
  return this.messenger.call('AccountsController:listMultichainAccounts');
941
992
  }, _AccountTreeController_assertAccountGroupExists = function _AccountTreeController_assertAccountGroupExists(groupId) {