@metamask-previews/account-tree-controller 0.7.0-preview-0910ff0 → 0.7.0-preview-98faf75a

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 (90) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/AccountTreeController.cjs +128 -78
  3. package/dist/AccountTreeController.cjs.map +1 -1
  4. package/dist/AccountTreeController.d.cts +5 -3
  5. package/dist/AccountTreeController.d.cts.map +1 -1
  6. package/dist/AccountTreeController.d.mts +5 -3
  7. package/dist/AccountTreeController.d.mts.map +1 -1
  8. package/dist/AccountTreeController.mjs +127 -77
  9. package/dist/AccountTreeController.mjs.map +1 -1
  10. package/dist/{AccountTreeGroup.cjs → group.cjs} +5 -4
  11. package/dist/group.cjs.map +1 -0
  12. package/dist/group.d.cts +79 -0
  13. package/dist/group.d.cts.map +1 -0
  14. package/dist/group.d.mts +79 -0
  15. package/dist/group.d.mts.map +1 -0
  16. package/dist/{AccountTreeGroup.mjs → group.mjs} +5 -4
  17. package/dist/group.mjs.map +1 -0
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +3 -3
  20. package/dist/index.d.cts.map +1 -1
  21. package/dist/index.d.mts +3 -3
  22. package/dist/index.d.mts.map +1 -1
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/rule.cjs +22 -0
  25. package/dist/rule.cjs.map +1 -0
  26. package/dist/rule.d.cts +69 -0
  27. package/dist/rule.d.cts.map +1 -0
  28. package/dist/rule.d.mts +69 -0
  29. package/dist/rule.d.mts.map +1 -0
  30. package/dist/rule.mjs +18 -0
  31. package/dist/rule.mjs.map +1 -0
  32. package/dist/rules/entropy.cjs +37 -31
  33. package/dist/rules/entropy.cjs.map +1 -1
  34. package/dist/rules/entropy.d.cts +10 -9
  35. package/dist/rules/entropy.d.cts.map +1 -1
  36. package/dist/rules/entropy.d.mts +10 -9
  37. package/dist/rules/entropy.d.mts.map +1 -1
  38. package/dist/rules/entropy.mjs +38 -32
  39. package/dist/rules/entropy.mjs.map +1 -1
  40. package/dist/rules/keyring.cjs +23 -26
  41. package/dist/rules/keyring.cjs.map +1 -1
  42. package/dist/rules/keyring.d.cts +9 -10
  43. package/dist/rules/keyring.d.cts.map +1 -1
  44. package/dist/rules/keyring.d.mts +9 -10
  45. package/dist/rules/keyring.d.mts.map +1 -1
  46. package/dist/rules/keyring.mjs +24 -27
  47. package/dist/rules/keyring.mjs.map +1 -1
  48. package/dist/rules/snap.cjs +35 -31
  49. package/dist/rules/snap.cjs.map +1 -1
  50. package/dist/rules/snap.d.cts +8 -19
  51. package/dist/rules/snap.d.cts.map +1 -1
  52. package/dist/rules/snap.d.mts +8 -19
  53. package/dist/rules/snap.d.mts.map +1 -1
  54. package/dist/rules/snap.mjs +36 -32
  55. package/dist/rules/snap.mjs.map +1 -1
  56. package/dist/types.cjs.map +1 -1
  57. package/dist/types.d.cts +3 -55
  58. package/dist/types.d.cts.map +1 -1
  59. package/dist/types.d.mts +3 -55
  60. package/dist/types.d.mts.map +1 -1
  61. package/dist/types.mjs.map +1 -1
  62. package/dist/{AccountTreeWallet.cjs → wallet.cjs} +5 -5
  63. package/dist/wallet.cjs.map +1 -0
  64. package/dist/wallet.d.cts +127 -0
  65. package/dist/wallet.d.cts.map +1 -0
  66. package/dist/wallet.d.mts +127 -0
  67. package/dist/wallet.d.mts.map +1 -0
  68. package/dist/{AccountTreeWallet.mjs → wallet.mjs} +4 -4
  69. package/dist/wallet.mjs.map +1 -0
  70. package/package.json +3 -3
  71. package/dist/AccountTreeGroup.cjs.map +0 -1
  72. package/dist/AccountTreeGroup.d.cts +0 -24
  73. package/dist/AccountTreeGroup.d.cts.map +0 -1
  74. package/dist/AccountTreeGroup.d.mts +0 -24
  75. package/dist/AccountTreeGroup.d.mts.map +0 -1
  76. package/dist/AccountTreeGroup.mjs.map +0 -1
  77. package/dist/AccountTreeRule.cjs +0 -37
  78. package/dist/AccountTreeRule.cjs.map +0 -1
  79. package/dist/AccountTreeRule.d.cts +0 -53
  80. package/dist/AccountTreeRule.d.cts.map +0 -1
  81. package/dist/AccountTreeRule.d.mts +0 -53
  82. package/dist/AccountTreeRule.d.mts.map +0 -1
  83. package/dist/AccountTreeRule.mjs +0 -33
  84. package/dist/AccountTreeRule.mjs.map +0 -1
  85. package/dist/AccountTreeWallet.cjs.map +0 -1
  86. package/dist/AccountTreeWallet.d.cts +0 -43
  87. package/dist/AccountTreeWallet.d.cts.map +0 -1
  88. package/dist/AccountTreeWallet.d.mts +0 -43
  89. package/dist/AccountTreeWallet.d.mts.map +0 -1
  90. package/dist/AccountTreeWallet.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@ 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 `group.type` tag ([#6214](https://github.com/MetaMask/core/pull/6214))
13
+ - This `type` can be used as a tag to strongly-type (tagged-union) the `AccountGroupObject`.
14
+ - Add `group.metadata` metadata object ([#6214](https://github.com/MetaMask/core/pull/6214))
15
+ - Given the `group.type` you will now have access to specific metadata information (e.g. `groupIndex` for multichain account groups)
16
+
17
+ ### Changed
18
+
19
+ - **BREAKING:** Bump peer dependency `@metamask/account-api` from `^0.3.0` to `^0.7.0` ([#6214](https://github.com/MetaMask/core/pull/6214)), ([#6216](https://github.com/MetaMask/core/pull/6216)), ([#6222](https://github.com/MetaMask/core/pull/6222))
20
+ - **BREAKING:** Move `wallet.metadata.type` tag to `wallet` node ([#6214](https://github.com/MetaMask/core/pull/6214))
21
+ - This `type` can be used as a tag to strongly-type (tagged-union) the `AccountWalletObject`.
22
+ - Defaults to the EVM account from a group when using `setSelectedAccountGroup` ([#6208](https://github.com/MetaMask/core/pull/6208))
23
+ - In case no EVM accounts are found in a group (which should not be possible), it will defaults to the first account of that group.
24
+
10
25
  ## [0.7.0]
11
26
 
12
27
  ### Added
@@ -10,15 +10,16 @@ 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_rules, _AccountTreeController_categoryToRule, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_renameAccountWalletIfNeeded, _AccountTreeController_renameAccountGroupIfNeeded, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_getFirstAccountInGroup, _AccountTreeController_findFirstNonEmptyGroup, _AccountTreeController_registerMessageHandlers;
13
+ var _AccountTreeController_instances, _AccountTreeController_accountIdToContext, _AccountTreeController_rules, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_renameAccountWalletIfNeeded, _AccountTreeController_renameAccountGroupIfNeeded, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_insert, _AccountTreeController_listAccounts, _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
- const AccountTreeWallet_1 = require("./AccountTreeWallet.cjs");
18
+ const keyring_api_1 = require("@metamask/keyring-api");
19
19
  const entropy_1 = require("./rules/entropy.cjs");
20
20
  const keyring_1 = require("./rules/keyring.cjs");
21
21
  const snap_1 = require("./rules/snap.cjs");
22
+ const wallet_1 = require("./wallet.cjs");
22
23
  exports.controllerName = 'AccountTreeController';
23
24
  const accountTreeControllerMetadata = {
24
25
  accountTree: {
@@ -61,22 +62,16 @@ class AccountTreeController extends base_controller_1.BaseController {
61
62
  _AccountTreeController_instances.add(this);
62
63
  _AccountTreeController_accountIdToContext.set(this, void 0);
63
64
  _AccountTreeController_rules.set(this, void 0);
64
- _AccountTreeController_categoryToRule.set(this, void 0);
65
65
  // Reverse map to allow fast node access from an account ID.
66
66
  __classPrivateFieldSet(this, _AccountTreeController_accountIdToContext, new Map(), "f");
67
67
  // Rules to apply to construct the wallets tree.
68
- __classPrivateFieldSet(this, _AccountTreeController_categoryToRule, {
69
- [account_api_1.AccountWalletCategory.Entropy]: new entropy_1.EntropyRule(this.messagingSystem),
70
- [account_api_1.AccountWalletCategory.Snap]: new snap_1.SnapRule(this.messagingSystem),
71
- [account_api_1.AccountWalletCategory.Keyring]: new keyring_1.KeyringRule(this.messagingSystem),
72
- }, "f");
73
68
  __classPrivateFieldSet(this, _AccountTreeController_rules, [
74
69
  // 1. We group by entropy-source
75
- __classPrivateFieldGet(this, _AccountTreeController_categoryToRule, "f")[account_api_1.AccountWalletCategory.Entropy],
70
+ new entropy_1.EntropyRule(this.messagingSystem),
76
71
  // 2. We group by Snap ID
77
- __classPrivateFieldGet(this, _AccountTreeController_categoryToRule, "f")[account_api_1.AccountWalletCategory.Snap],
72
+ new snap_1.SnapRule(this.messagingSystem),
78
73
  // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)
79
- __classPrivateFieldGet(this, _AccountTreeController_categoryToRule, "f")[account_api_1.AccountWalletCategory.Keyring],
74
+ new keyring_1.KeyringRule(this.messagingSystem),
80
75
  ], "f");
81
76
  this.messagingSystem.subscribe('AccountsController:accountAdded', (account) => {
82
77
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountAdded).call(this, account);
@@ -116,11 +111,11 @@ class AccountTreeController extends base_controller_1.BaseController {
116
111
  if (!wallet) {
117
112
  return undefined;
118
113
  }
119
- return new AccountTreeWallet_1.AccountTreeWallet({ messenger: this.messagingSystem, wallet });
114
+ return new wallet_1.AccountTreeWallet({ messenger: this.messagingSystem, wallet });
120
115
  }
121
116
  getAccountWallets() {
122
117
  return Object.values(this.state.accountTree.wallets).map((wallet) => {
123
- return new AccountTreeWallet_1.AccountTreeWallet({ messenger: this.messagingSystem, wallet });
118
+ return new wallet_1.AccountTreeWallet({ messenger: this.messagingSystem, wallet });
124
119
  });
125
120
  }
126
121
  /**
@@ -143,7 +138,7 @@ class AccountTreeController extends base_controller_1.BaseController {
143
138
  return;
144
139
  }
145
140
  // Find the first account in this group to select
146
- const accountToSelect = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getFirstAccountInGroup).call(this, groupId);
141
+ const accountToSelect = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountFromAccountGroupId).call(this, groupId);
147
142
  if (!accountToSelect) {
148
143
  throw new Error(`No accounts found in group: ${groupId}`);
149
144
  }
@@ -157,29 +152,47 @@ class AccountTreeController extends base_controller_1.BaseController {
157
152
  }
158
153
  }
159
154
  exports.AccountTreeController = AccountTreeController;
160
- _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_categoryToRule = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getDefaultSelectedAccountGroup = function _AccountTreeController_getDefaultSelectedAccountGroup(wallets) {
161
- const selectedAccount = this.messagingSystem.call('AccountsController:getSelectedAccount');
162
- if (selectedAccount && selectedAccount.id) {
163
- const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(selectedAccount.id);
164
- if (accountMapping) {
165
- const { groupId } = accountMapping;
166
- return groupId;
167
- }
168
- }
169
- // Default to the first non-empty group in case of errors.
170
- return __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_findFirstNonEmptyGroup).call(this, wallets);
155
+ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getEntropyRule = function _AccountTreeController_getEntropyRule() {
156
+ return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[0];
157
+ }, _AccountTreeController_getSnapRule = function _AccountTreeController_getSnapRule() {
158
+ return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[1];
159
+ }, _AccountTreeController_getKeyringRule = function _AccountTreeController_getKeyringRule() {
160
+ return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[2];
171
161
  }, _AccountTreeController_renameAccountWalletIfNeeded = function _AccountTreeController_renameAccountWalletIfNeeded(wallet) {
172
162
  if (wallet.metadata.name) {
173
163
  return;
174
164
  }
175
- const rule = __classPrivateFieldGet(this, _AccountTreeController_categoryToRule, "f")[wallet.metadata.type];
176
- wallet.metadata.name = rule.getDefaultAccountWalletName(wallet);
165
+ if (wallet.type === account_api_1.AccountWalletType.Entropy) {
166
+ wallet.metadata.name =
167
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).getDefaultAccountWalletName(wallet);
168
+ }
169
+ else if (wallet.type === account_api_1.AccountWalletType.Snap) {
170
+ wallet.metadata.name =
171
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).getDefaultAccountWalletName(wallet);
172
+ }
173
+ else {
174
+ wallet.metadata.name =
175
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).getDefaultAccountWalletName(wallet);
176
+ }
177
177
  }, _AccountTreeController_renameAccountGroupIfNeeded = function _AccountTreeController_renameAccountGroupIfNeeded(wallet, group) {
178
178
  if (group.metadata.name) {
179
179
  return;
180
180
  }
181
- const rule = __classPrivateFieldGet(this, _AccountTreeController_categoryToRule, "f")[wallet.metadata.type];
182
- group.metadata.name = rule.getDefaultAccountGroupName(group);
181
+ if (wallet.type === account_api_1.AccountWalletType.Entropy) {
182
+ group.metadata.name = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).getDefaultAccountGroupName(
183
+ // Get the group from the wallet, to get the proper type inference.
184
+ wallet.groups[group.id]);
185
+ }
186
+ else if (wallet.type === account_api_1.AccountWalletType.Snap) {
187
+ group.metadata.name = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).getDefaultAccountGroupName(
188
+ // Same here.
189
+ wallet.groups[group.id]);
190
+ }
191
+ else {
192
+ group.metadata.name = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).getDefaultAccountGroupName(
193
+ // Same here.
194
+ wallet.groups[group.id]);
195
+ }
183
196
  }, _AccountTreeController_handleAccountAdded = function _AccountTreeController_handleAccountAdded(account) {
184
197
  this.update((state) => {
185
198
  __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
@@ -211,7 +224,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
211
224
  accounts.length === 0) {
212
225
  // The currently selected group is now empty, find a new group to select
213
226
  state.accountTree.selectedAccountGroup =
214
- __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_findFirstNonEmptyGroup).call(this, state.accountTree.wallets);
227
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, state.accountTree.wallets);
215
228
  }
216
229
  }
217
230
  }
@@ -220,48 +233,62 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
220
233
  __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").delete(accountId);
221
234
  }
222
235
  }, _AccountTreeController_insert = function _AccountTreeController_insert(wallets, account) {
223
- for (const rule of __classPrivateFieldGet(this, _AccountTreeController_rules, "f")) {
224
- const result = rule.match(account);
225
- if (!result) {
226
- // No match for that rule, we go to the next one.
227
- continue;
228
- }
229
- // Update controller's state.
230
- const walletId = result.wallet.id;
231
- let wallet = wallets[walletId];
232
- if (!wallet) {
233
- wallets[walletId] = {
234
- id: walletId,
235
- groups: {},
236
- metadata: {
237
- name: '',
238
- ...result.wallet.metadata,
239
- },
240
- };
241
- wallet = wallets[walletId];
242
- }
243
- const groupId = result.group.id;
244
- let group = wallet.groups[groupId];
245
- if (!group) {
246
- wallet.groups[groupId] = {
247
- id: groupId,
248
- accounts: [],
249
- metadata: {
250
- name: '', // Will get updated later.
251
- },
252
- };
253
- group = wallet.groups[groupId];
254
- }
236
+ const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).match(account) ??
237
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
238
+ __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).match(account); // This one cannot fail.
239
+ // Update controller's state.
240
+ const walletId = result.wallet.id;
241
+ let wallet = wallets[walletId];
242
+ if (!wallet) {
243
+ wallets[walletId] = {
244
+ ...result.wallet,
245
+ groups: {},
246
+ metadata: {
247
+ name: '',
248
+ ...result.wallet.metadata,
249
+ },
250
+ // We do need to type-cast since we're not narrowing `result` with
251
+ // the union tag `result.wallet.type`.
252
+ };
253
+ wallet = wallets[walletId];
254
+ }
255
+ const groupId = result.group.id;
256
+ let group = wallet.groups[groupId];
257
+ if (!group) {
258
+ wallet.groups[groupId] = {
259
+ ...result.group,
260
+ // Type-wise, we are guaranteed to always have at least 1 account.
261
+ accounts: [account.id],
262
+ metadata: {
263
+ name: '',
264
+ ...result.group.metadata,
265
+ },
266
+ // We do need to type-cast since we're not narrowing `result` with
267
+ // the union tag `result.group.type`.
268
+ };
269
+ group = wallet.groups[groupId];
270
+ }
271
+ else {
255
272
  group.accounts.push(account.id);
256
- // Update the reverse mapping for this account.
257
- __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").set(account.id, {
258
- walletId: wallet.id,
259
- groupId: group.id,
260
- });
261
- return;
262
273
  }
274
+ // Update the reverse mapping for this account.
275
+ __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").set(account.id, {
276
+ walletId: wallet.id,
277
+ groupId: group.id,
278
+ });
263
279
  }, _AccountTreeController_listAccounts = function _AccountTreeController_listAccounts() {
264
280
  return this.messagingSystem.call('AccountsController:listMultichainAccounts');
281
+ }, _AccountTreeController_getDefaultSelectedAccountGroup = function _AccountTreeController_getDefaultSelectedAccountGroup(wallets) {
282
+ const selectedAccount = this.messagingSystem.call('AccountsController:getSelectedAccount');
283
+ if (selectedAccount && selectedAccount.id) {
284
+ const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(selectedAccount.id);
285
+ if (accountMapping) {
286
+ const { groupId } = accountMapping;
287
+ return groupId;
288
+ }
289
+ }
290
+ // Default to the default group in case of errors.
291
+ return __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, wallets);
265
292
  }, _AccountTreeController_handleSelectedAccountChange = function _AccountTreeController_handleSelectedAccountChange(account) {
266
293
  const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
267
294
  if (!accountMapping) {
@@ -278,25 +305,48 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
278
305
  this.update((state) => {
279
306
  state.accountTree.selectedAccountGroup = groupId;
280
307
  });
281
- }, _AccountTreeController_getFirstAccountInGroup = function _AccountTreeController_getFirstAccountInGroup(groupId) {
282
- for (const wallet of Object.values(this.state.accountTree.wallets)) {
283
- if (wallet.groups[groupId]) {
284
- const group = wallet.groups[groupId];
285
- if (group && group.accounts.length > 0) {
286
- return group.accounts[0];
308
+ }, _AccountTreeController_getAccountGroup = function _AccountTreeController_getAccountGroup(groupId) {
309
+ const found = Object.values(this.state.accountTree.wallets).find((wallet) => wallet.groups[groupId] !== undefined);
310
+ return found?.groups[groupId];
311
+ }, _AccountTreeController_getDefaultAccountFromAccountGroupId = function _AccountTreeController_getDefaultAccountFromAccountGroupId(groupId) {
312
+ const group = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getAccountGroup).call(this, groupId);
313
+ if (group) {
314
+ let candidate;
315
+ for (const id of group.accounts) {
316
+ const account = this.messagingSystem.call('AccountsController:getAccount', id);
317
+ if (!candidate) {
318
+ candidate = id;
319
+ }
320
+ if (account && (0, keyring_api_1.isEvmAccountType)(account.type)) {
321
+ // EVM accounts have a higher priority, so if we find any, we just
322
+ // use that account!
323
+ return account.id;
287
324
  }
288
325
  }
326
+ return candidate;
289
327
  }
290
328
  return undefined;
291
- }, _AccountTreeController_findFirstNonEmptyGroup = function _AccountTreeController_findFirstNonEmptyGroup(wallets) {
329
+ }, _AccountTreeController_getDefaultAccountGroupId = function _AccountTreeController_getDefaultAccountGroupId(wallets) {
330
+ let candidate = '';
292
331
  for (const wallet of Object.values(wallets)) {
293
332
  for (const group of Object.values(wallet.groups)) {
294
- if (group.accounts.length > 0) {
295
- return group.id;
333
+ // We only update the candidate with the first non-empty group, but still
334
+ // try to find a group that contains an EVM account (the `candidate` is
335
+ // our fallback).
336
+ if (candidate === '' && group.accounts.length > 0) {
337
+ candidate = group.id;
338
+ }
339
+ for (const id of group.accounts) {
340
+ const account = this.messagingSystem.call('AccountsController:getAccount', id);
341
+ if (account && (0, keyring_api_1.isEvmAccountType)(account.type)) {
342
+ // EVM accounts have a higher priority, so if we find any, we just
343
+ // use that group!
344
+ return group.id;
345
+ }
296
346
  }
297
347
  }
298
348
  }
299
- return '';
349
+ return candidate;
300
350
  }, _AccountTreeController_registerMessageHandlers = function _AccountTreeController_registerMessageHandlers() {
301
351
  this.messagingSystem.registerActionHandler(`${exports.controllerName}:getSelectedAccountGroup`, this.getSelectedAccountGroup.bind(this));
302
352
  this.messagingSystem.registerActionHandler(`${exports.controllerName}:setSelectedAccountGroup`, this.setSelectedAccountGroup.bind(this));
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId, AccountWalletId } from '@metamask/account-api';\nimport { AccountWalletCategory } 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 { InternalAccount } from '@metamask/keyring-internal-api';\n\nimport type { AccountTreeRule } from './AccountTreeRule';\nimport { AccountTreeWallet } from './AccountTreeWallet';\nimport { EntropyRule } from './rules/entropy';\nimport { KeyringRule } from './rules/keyring';\nimport { SnapRule } from './rules/snap';\nimport type {\n AccountGroupObject,\n AccountTreeControllerMessenger,\n AccountTreeControllerState,\n AccountWalletObject,\n} from './types';\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 };\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 };\n}\n\n/**\n * Context for an account.\n */\nexport type AccountContext = {\n /**\n * Wallet ID associated to that account.\n */\n walletId: AccountWalletId;\n\n /**\n * Account group ID associated to that account.\n */\n groupId: AccountGroupId;\n};\n\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #accountIdToContext: Map<AccountId, AccountContext>;\n\n readonly #rules: AccountTreeRule[];\n\n readonly #categoryToRule: Record<AccountWalletCategory, AccountTreeRule>;\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 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 // Rules to apply to construct the wallets tree.\n this.#categoryToRule = {\n [AccountWalletCategory.Entropy]: new EntropyRule(this.messagingSystem),\n [AccountWalletCategory.Snap]: new SnapRule(this.messagingSystem),\n [AccountWalletCategory.Keyring]: new KeyringRule(this.messagingSystem),\n } as const;\n this.#rules = [\n // 1. We group by entropy-source\n this.#categoryToRule[AccountWalletCategory.Entropy],\n // 2. We group by Snap ID\n this.#categoryToRule[AccountWalletCategory.Snap],\n // 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)\n this.#categoryToRule[AccountWalletCategory.Keyring],\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.#registerMessageHandlers();\n }\n\n init() {\n const wallets: AccountTreeControllerState['accountTree']['wallets'] = {};\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 compute the name.\n for (const wallet of Object.values(wallets)) {\n this.#renameAccountWalletIfNeeded(wallet);\n\n for (const group of Object.values(wallet.groups)) {\n this.#renameAccountGroupIfNeeded(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 * 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 first non-empty group in case of errors.\n return this.#findFirstNonEmptyGroup(wallets);\n }\n\n #renameAccountWalletIfNeeded(wallet: AccountWalletObject) {\n if (wallet.metadata.name) {\n return;\n }\n\n const rule = this.#categoryToRule[wallet.metadata.type];\n wallet.metadata.name = rule.getDefaultAccountWalletName(wallet);\n }\n\n #renameAccountGroupIfNeeded(\n wallet: AccountWalletObject,\n group: AccountGroupObject,\n ) {\n if (group.metadata.name) {\n return;\n }\n\n const rule = this.#categoryToRule[wallet.metadata.type];\n group.metadata.name = rule.getDefaultAccountGroupName(group);\n }\n\n getAccountWallet(walletId: AccountWalletId): AccountTreeWallet | undefined {\n const wallet = this.state.accountTree.wallets[walletId];\n if (!wallet) {\n return undefined;\n }\n\n return new AccountTreeWallet({ messenger: this.messagingSystem, wallet });\n }\n\n getAccountWallets(): AccountTreeWallet[] {\n return Object.values(this.state.accountTree.wallets).map((wallet) => {\n return new AccountTreeWallet({ messenger: this.messagingSystem, wallet });\n });\n }\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.#renameAccountWalletIfNeeded(wallet);\n\n const group = wallet.groups[groupId];\n if (group) {\n this.#renameAccountGroupIfNeeded(wallet, group);\n }\n }\n }\n });\n }\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.#findFirstNonEmptyGroup(state.accountTree.wallets);\n }\n }\n }\n });\n\n // Clear reverse-mapping for that account.\n this.#accountIdToContext.delete(accountId);\n }\n }\n\n #insert(\n wallets: AccountTreeControllerState['accountTree']['wallets'],\n account: InternalAccount,\n ) {\n for (const rule of this.#rules) {\n const result = rule.match(account);\n\n if (!result) {\n // No match for that rule, we go to the next one.\n continue;\n }\n\n // Update controller's state.\n const walletId = result.wallet.id;\n let wallet = wallets[walletId];\n if (!wallet) {\n wallets[walletId] = {\n id: walletId,\n groups: {},\n metadata: {\n name: '', // Will get updated later.\n ...result.wallet.metadata,\n },\n };\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 id: groupId,\n accounts: [],\n metadata: {\n name: '', // Will get updated later.\n },\n };\n group = wallet.groups[groupId];\n }\n\n group.accounts.push(account.id);\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 return;\n }\n }\n\n #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\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.#getFirstAccountInGroup(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 * 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 the first account ID in the 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 #getFirstAccountInGroup(groupId: AccountGroupId): AccountId | undefined {\n for (const wallet of Object.values(this.state.accountTree.wallets)) {\n if (wallet.groups[groupId]) {\n const group = wallet.groups[groupId];\n if (group && group.accounts.length > 0) {\n return group.accounts[0];\n }\n }\n }\n return undefined;\n }\n\n /**\n * Finds the first non-empty group in the given wallets object.\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 #findFirstNonEmptyGroup(wallets: {\n [walletId: AccountWalletId]: AccountWalletObject;\n }): AccountGroupId | '' {\n for (const wallet of Object.values(wallets)) {\n for (const group of Object.values(wallet.groups)) {\n if (group.accounts.length > 0) {\n return group.id;\n }\n }\n }\n return '';\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}\n"]}
1
+ {"version":3,"file":"AccountTreeController.cjs","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountGroupId, AccountWalletId } from '@metamask/account-api';\nimport { AccountWalletType } 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 { 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 } from './wallet';\nimport { AccountTreeWallet } 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 };\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 };\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\nexport class AccountTreeController extends BaseController<\n typeof controllerName,\n AccountTreeControllerState,\n AccountTreeControllerMessenger\n> {\n readonly #accountIdToContext: Map<AccountId, AccountContext>;\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 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 // 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.#registerMessageHandlers();\n }\n\n init() {\n const wallets: AccountTreeControllerState['accountTree']['wallets'] = {};\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 compute the name.\n for (const wallet of Object.values(wallets)) {\n this.#renameAccountWalletIfNeeded(wallet);\n\n for (const group of Object.values(wallet.groups)) {\n this.#renameAccountGroupIfNeeded(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 #getEntropyRule(): EntropyRule {\n return this.#rules[0];\n }\n\n #getSnapRule(): SnapRule {\n return this.#rules[1];\n }\n\n #getKeyringRule(): KeyringRule {\n return this.#rules[2];\n }\n\n #renameAccountWalletIfNeeded(wallet: AccountWalletObject) {\n if (wallet.metadata.name) {\n return;\n }\n\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 #renameAccountGroupIfNeeded(\n wallet: AccountWalletObject,\n group: AccountGroupObject,\n ) {\n if (group.metadata.name) {\n return;\n }\n\n if (wallet.type === AccountWalletType.Entropy) {\n group.metadata.name = this.#getEntropyRule().getDefaultAccountGroupName(\n // Get the group from the wallet, to get the proper type inference.\n wallet.groups[group.id],\n );\n } else if (wallet.type === AccountWalletType.Snap) {\n group.metadata.name = this.#getSnapRule().getDefaultAccountGroupName(\n // Same here.\n wallet.groups[group.id],\n );\n } else {\n group.metadata.name = this.#getKeyringRule().getDefaultAccountGroupName(\n // Same here.\n wallet.groups[group.id],\n );\n }\n }\n\n getAccountWallet(walletId: AccountWalletId): AccountTreeWallet | undefined {\n const wallet = this.state.accountTree.wallets[walletId];\n if (!wallet) {\n return undefined;\n }\n\n return new AccountTreeWallet({ messenger: this.messagingSystem, wallet });\n }\n\n getAccountWallets(): AccountTreeWallet[] {\n return Object.values(this.state.accountTree.wallets).map((wallet) => {\n return new AccountTreeWallet({ messenger: this.messagingSystem, wallet });\n });\n }\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.#renameAccountWalletIfNeeded(wallet);\n\n const group = wallet.groups[groupId];\n if (group) {\n this.#renameAccountGroupIfNeeded(wallet, group);\n }\n }\n }\n });\n }\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 }\n });\n\n // Clear reverse-mapping for that account.\n this.#accountIdToContext.delete(accountId);\n }\n }\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 // 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 ...result.group.metadata,\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 } else {\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 #listAccounts(): InternalAccount[] {\n return this.messagingSystem.call(\n 'AccountsController:listMultichainAccounts',\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 * 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}\n"]}
@@ -1,7 +1,9 @@
1
1
  import type { AccountGroupId, AccountWalletId } from "@metamask/account-api";
2
2
  import { BaseController } from "@metamask/base-controller";
3
- import { AccountTreeWallet } from "./AccountTreeWallet.cjs";
3
+ import type { AccountGroupObject } from "./group.cjs";
4
4
  import type { AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.cjs";
5
+ import type { AccountWalletObject } from "./wallet.cjs";
6
+ import { AccountTreeWallet } from "./wallet.cjs";
5
7
  export declare const controllerName = "AccountTreeController";
6
8
  /**
7
9
  * Gets default state of the `AccountTreeController`.
@@ -16,11 +18,11 @@ export type AccountContext = {
16
18
  /**
17
19
  * Wallet ID associated to that account.
18
20
  */
19
- walletId: AccountWalletId;
21
+ walletId: AccountWalletObject['id'];
20
22
  /**
21
23
  * Account group ID associated to that account.
22
24
  */
23
- groupId: AccountGroupId;
25
+ groupId: AccountGroupObject['id'];
24
26
  };
25
27
  export declare class AccountTreeController extends BaseController<typeof controllerName, AccountTreeControllerState, AccountTreeControllerMessenger> {
26
28
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAI7E,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAI3D,OAAO,EAAE,iBAAiB,EAAE,gCAA4B;AAIxD,OAAO,KAAK,EAEV,8BAA8B,EAC9B,0BAA0B,EAE3B,oBAAgB;AAEjB,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAUtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAOjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,eAAe,CAAC;IAE1B;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC;CACzB,CAAC;AAEF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAOC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IAqDD,IAAI;IA0EJ,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,GAAG,SAAS;IAS1E,iBAAiB,IAAI,iBAAiB,EAAE;IAsHxC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAyGvD"}
1
+ {"version":3,"file":"AccountTreeController.d.cts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAI7E,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAI3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAIlD,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAiB;AACpD,OAAO,EAAE,iBAAiB,EAAE,qBAAiB;AAE7C,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAUtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAOjF;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;AAEF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAKC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IAgDD,IAAI;IAmFJ,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,GAAG,SAAS;IAS1E,iBAAiB,IAAI,iBAAiB,EAAE;IAsHxC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAoLvD"}
@@ -1,7 +1,9 @@
1
1
  import type { AccountGroupId, AccountWalletId } from "@metamask/account-api";
2
2
  import { BaseController } from "@metamask/base-controller";
3
- import { AccountTreeWallet } from "./AccountTreeWallet.mjs";
3
+ import type { AccountGroupObject } from "./group.mjs";
4
4
  import type { AccountTreeControllerMessenger, AccountTreeControllerState } from "./types.mjs";
5
+ import type { AccountWalletObject } from "./wallet.mjs";
6
+ import { AccountTreeWallet } from "./wallet.mjs";
5
7
  export declare const controllerName = "AccountTreeController";
6
8
  /**
7
9
  * Gets default state of the `AccountTreeController`.
@@ -16,11 +18,11 @@ export type AccountContext = {
16
18
  /**
17
19
  * Wallet ID associated to that account.
18
20
  */
19
- walletId: AccountWalletId;
21
+ walletId: AccountWalletObject['id'];
20
22
  /**
21
23
  * Account group ID associated to that account.
22
24
  */
23
- groupId: AccountGroupId;
25
+ groupId: AccountGroupObject['id'];
24
26
  };
25
27
  export declare class AccountTreeController extends BaseController<typeof controllerName, AccountTreeControllerState, AccountTreeControllerMessenger> {
26
28
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAI7E,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAI3D,OAAO,EAAE,iBAAiB,EAAE,gCAA4B;AAIxD,OAAO,KAAK,EAEV,8BAA8B,EAC9B,0BAA0B,EAE3B,oBAAgB;AAEjB,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAUtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAOjF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,QAAQ,EAAE,eAAe,CAAC;IAE1B;;OAEG;IACH,OAAO,EAAE,cAAc,CAAC;CACzB,CAAC;AAEF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAOC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IAqDD,IAAI;IA0EJ,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,GAAG,SAAS;IAS1E,iBAAiB,IAAI,iBAAiB,EAAE;IAsHxC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAyGvD"}
1
+ {"version":3,"file":"AccountTreeController.d.mts","sourceRoot":"","sources":["../src/AccountTreeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAI7E,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAI3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAgB;AAIlD,OAAO,KAAK,EACV,8BAA8B,EAC9B,0BAA0B,EAC3B,oBAAgB;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAiB;AACpD,OAAO,EAAE,iBAAiB,EAAE,qBAAiB;AAE7C,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAUtD;;;;GAIG;AACH,wBAAgB,oCAAoC,IAAI,0BAA0B,CAOjF;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;AAEF,qBAAa,qBAAsB,SAAQ,cAAc,CACvD,OAAO,cAAc,EACrB,0BAA0B,EAC1B,8BAA8B,CAC/B;;IAKC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,8BAA8B,CAAC;QAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;KAC7C;IAgDD,IAAI;IAmFJ,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,GAAG,SAAS;IAS1E,iBAAiB,IAAI,iBAAiB,EAAE;IAsHxC;;;;OAIG;IACH,uBAAuB,IAAI,cAAc,GAAG,EAAE;IAI9C;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CAoLvD"}