@metamask-previews/accounts-controller 21.0.0-preview-a7b445fc → 21.0.0-preview-d2b96e95

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.
@@ -4,7 +4,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  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");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var _AccountsController_instances, _AccountsController_generateInternalAccountForNonSnapAccount, _AccountsController_listSnapAccounts, _AccountsController_listNormalAccounts, _AccountsController_handleOnKeyringStateChange, _AccountsController_handleOnSnapStateChange, _AccountsController_getAccountsByKeyringType, _AccountsController_getLastSelectedAccount, _AccountsController_isAccountCompatibleWithChain, _AccountsController_getLastSelectedIndex, _AccountsController_handleNewAccountAdded, _AccountsController_publishAccountChangeEvent, _AccountsController_handleAccountRemoved, _AccountsController_populateExistingMetadata, _AccountsController_registerMessageHandlers;
7
+ var _AccountsController_instances, _AccountsController_generateInternalAccountForNonSnapAccount, _AccountsController_getSnapKeyring, _AccountsController_getKeyringForAccount, _AccountsController_getAccountAddresses, _AccountsController_getAccountMetadataOrDefaults, _AccountsController_listAccountsFromSnapKeyring, _AccountsController_listAccountsFromOtherKeyrings, _AccountsController_handleOnKeyringStateChange, _AccountsController_handleOnSnapStateChange, _AccountsController_getAccountsByKeyringType, _AccountsController_getLastSelectedAccount, _AccountsController_isAccountCompatibleWithChain, _AccountsController_getLastSelectedIndex, _AccountsController_handleNewAccountAdded, _AccountsController_publishAccountChangeEvent, _AccountsController_handleAccountRemoved, _AccountsController_registerMessageHandlers;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.AccountsController = exports.EMPTY_ACCOUNT = void 0;
10
10
  const base_controller_1 = require("@metamask/base-controller");
@@ -239,37 +239,66 @@ class AccountsController extends base_controller_1.BaseController {
239
239
  * @returns A Promise that resolves when the accounts have been updated.
240
240
  */
241
241
  async updateAccounts() {
242
- const snapAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listSnapAccounts).call(this);
243
- const normalAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listNormalAccounts).call(this);
244
- // keyring type map.
245
- const keyringTypes = new Map();
246
- const previousAccounts = this.state.internalAccounts.accounts;
247
- const accounts = [
248
- ...normalAccounts,
249
- ...snapAccounts,
250
- ].reduce((internalAccountMap, internalAccount) => {
251
- const keyringTypeName = (0, utils_2.keyringTypeToName)(internalAccount.metadata.keyring.type);
252
- const keyringAccountIndex = keyringTypes.get(keyringTypeName) ?? 0;
253
- if (keyringAccountIndex) {
254
- keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);
242
+ // We are re-creating the list of internal accounts based on the accounts from
243
+ // each keyrings, following those rules:
244
+ //
245
+ // - If the account already exists on this controller state, we only update
246
+ // metadata. This allows to automatically "migrate" new metadata for existing
247
+ // accounts.
248
+ //
249
+ // - Else, we create the associated internal account for that new account. This
250
+ // can happen when the Snap keyring adds a new account. The Snap keyring will
251
+ // create a new account and will automatically "persists" by calling this
252
+ // function explicitly to create its associated internal account.
253
+ //
254
+ // FIXME: This logic is kinda tricky and could be replaced with the new
255
+ // incoming notification system that the Snap keyring will use.
256
+ const snapAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listAccountsFromSnapKeyring).call(this);
257
+ const normalAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listAccountsFromOtherKeyrings).call(this);
258
+ // Keep track of unnamed account to rename them after.
259
+ const namedAccounts = [];
260
+ const unnamedAccounts = [];
261
+ // Compute the updated list of internal accounts:
262
+ const accounts = {};
263
+ for (const keyringInternalAccount of [...normalAccounts, ...snapAccounts]) {
264
+ const { id } = keyringInternalAccount;
265
+ const internalAccount = this.state.internalAccounts.accounts[id];
266
+ if (internalAccount) {
267
+ // The account already exist, we're just updating the metadata.
268
+ const { metadata } = internalAccount;
269
+ accounts[id] = {
270
+ ...internalAccount,
271
+ metadata: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, metadata.keyring.type, metadata),
272
+ };
255
273
  }
256
274
  else {
257
- keyringTypes.set(keyringTypeName, 1);
275
+ // The account does not exist yet on this controller. We create a new
276
+ // internal account now using the internal account created from
277
+ // the keyring account.
278
+ const { metadata } = keyringInternalAccount;
279
+ accounts[id] = {
280
+ ...keyringInternalAccount,
281
+ metadata: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, metadata.keyring.type, metadata),
282
+ };
258
283
  }
259
- const existingAccount = previousAccounts[internalAccount.id];
260
- internalAccountMap[internalAccount.id] = {
261
- ...internalAccount,
262
- metadata: {
263
- ...internalAccount.metadata,
264
- name: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'name') ??
265
- `${keyringTypeName} ${keyringAccountIndex + 1}`,
266
- importTime: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'importTime') ??
267
- Date.now(),
268
- lastSelected: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'lastSelected') ?? 0,
269
- },
270
- };
271
- return internalAccountMap;
272
- }, {});
284
+ // If the account has no name yet, we mark it and we'll rename it afterward once
285
+ // we have re-created the full state.
286
+ if (accounts[id].metadata.name === '') {
287
+ unnamedAccounts.push(accounts[id]);
288
+ }
289
+ else {
290
+ // It's important to track named accounts too since the
291
+ // `getNextAvailableAccountname` will use the highest index possible
292
+ // based on account's names.
293
+ namedAccounts.push(accounts[id]);
294
+ }
295
+ }
296
+ // Now, we can rename each accounts according to our naming rule.
297
+ for (const account of unnamedAccounts) {
298
+ accounts[account.id].metadata.name = this.getNextAvailableAccountName(account.metadata.keyring.type, namedAccounts);
299
+ // It has a name now, we need to re-use it when naming other accounts.
300
+ namedAccounts.push(accounts[account.id]);
301
+ }
273
302
  this.update((currentState) => {
274
303
  currentState.internalAccounts.accounts = accounts;
275
304
  if (!currentState.internalAccounts.accounts[currentState.internalAccounts.selectedAccount]) {
@@ -330,9 +359,15 @@ class AccountsController extends base_controller_1.BaseController {
330
359
  }
331
360
  }
332
361
  exports.AccountsController = AccountsController;
333
- _AccountsController_instances = new WeakSet(), _AccountsController_generateInternalAccountForNonSnapAccount = function _AccountsController_generateInternalAccountForNonSnapAccount(address, type) {
362
+ _AccountsController_instances = new WeakSet(), _AccountsController_generateInternalAccountForNonSnapAccount = function _AccountsController_generateInternalAccountForNonSnapAccount(address, keyringType) {
363
+ // Non-Snap accounts computes their account ID based on their address (in a
364
+ // deterministic way).
365
+ const id = (0, utils_2.getUUIDFromAddressOfNormalAccount)(address);
366
+ // If the account does not exist yet, metadata will use all default values.
367
+ const account = this.getAccount(id);
368
+ const metadata = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, keyringType, account?.metadata);
334
369
  return {
335
- id: (0, utils_2.getUUIDFromAddressOfNormalAccount)(address),
370
+ id,
336
371
  address,
337
372
  options: {},
338
373
  methods: [
@@ -343,31 +378,64 @@ _AccountsController_instances = new WeakSet(), _AccountsController_generateInter
343
378
  keyring_api_1.EthMethod.SignTypedDataV3,
344
379
  keyring_api_1.EthMethod.SignTypedDataV4,
345
380
  ],
346
- scopes: [keyring_api_1.EthScopes.Namespace],
381
+ // Normal accounts are all EOA.
347
382
  type: keyring_api_1.EthAccountType.Eoa,
383
+ // And EOA accounts are compatible on every EVM chains, so use the namespace here.
384
+ scopes: [keyring_api_1.EthScopes.Namespace],
348
385
  metadata: {
349
- name: '',
350
- importTime: Date.now(),
386
+ ...metadata,
351
387
  keyring: {
352
- type,
388
+ type: keyringType,
353
389
  },
354
390
  },
355
391
  };
356
- }, _AccountsController_listSnapAccounts =
392
+ }, _AccountsController_getSnapKeyring = function _AccountsController_getSnapKeyring() {
393
+ const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', eth_snap_keyring_1.SnapKeyring.type);
394
+ return snapKeyring;
395
+ }, _AccountsController_getKeyringForAccount =
357
396
  /**
358
- * Returns a list of internal accounts created using the SnapKeyring.
397
+ * Gets the keyring associated to an account's address.
398
+ *
399
+ * @param address - Account's address.
400
+ * @returns A promise that resolves to the associated keyring.
401
+ */
402
+ async function _AccountsController_getKeyringForAccount(address) {
403
+ const keyring = await this.messagingSystem.call('KeyringController:getKeyringForAccount', address);
404
+ return keyring;
405
+ }, _AccountsController_getAccountAddresses =
406
+ /**
407
+ * Gets the address of all accounts.
408
+ *
409
+ * @returns A promise that resolves to the list of account addresses.
410
+ */
411
+ async function _AccountsController_getAccountAddresses() {
412
+ return await this.messagingSystem.call('KeyringController:getAccounts');
413
+ }, _AccountsController_getAccountMetadataOrDefaults = function _AccountsController_getAccountMetadataOrDefaults(keyringType, metadata) {
414
+ return {
415
+ // Expand the account's metadata first, and then adds default if they are not
416
+ // defined.
417
+ ...metadata,
418
+ name: metadata?.name ?? '',
419
+ keyring: {
420
+ type: keyringType,
421
+ },
422
+ importTime: metadata?.importTime ?? Date.now(),
423
+ lastSelected: metadata?.lastSelected ?? 0, // This means the account has never been selected yet.
424
+ };
425
+ }, _AccountsController_listAccountsFromSnapKeyring =
426
+ /**
427
+ * Returns a list of internal accounts created using the Snap keyring.
359
428
  *
360
429
  * @returns A promise that resolves to an array of InternalAccount objects.
361
430
  */
362
- async function _AccountsController_listSnapAccounts() {
363
- const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', eth_snap_keyring_1.SnapKeyring.type);
364
- // snap keyring is not available until the first account is created in the keyring controller
431
+ async function _AccountsController_listAccountsFromSnapKeyring() {
432
+ const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
433
+ // Snap keyring is not available until the first account is created in the keyring controller
365
434
  if (!snapKeyring) {
366
435
  return [];
367
436
  }
368
- const snapAccounts = snapKeyring.listAccounts();
369
- return snapAccounts;
370
- }, _AccountsController_listNormalAccounts =
437
+ return snapKeyring.listAccounts();
438
+ }, _AccountsController_listAccountsFromOtherKeyrings =
371
439
  /**
372
440
  * Returns a list of normal accounts.
373
441
  * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.
@@ -375,42 +443,17 @@ async function _AccountsController_listSnapAccounts() {
375
443
  *
376
444
  * @returns A Promise that resolves to an array of InternalAccount objects.
377
445
  */
378
- async function _AccountsController_listNormalAccounts() {
379
- const addresses = await this.messagingSystem.call('KeyringController:getAccounts');
446
+ async function _AccountsController_listAccountsFromOtherKeyrings() {
380
447
  const internalAccounts = [];
381
- for (const address of addresses) {
382
- const keyring = await this.messagingSystem.call('KeyringController:getKeyringForAccount', address);
383
- const keyringType = keyring.type;
384
- if (!(0, utils_2.isNormalKeyringType)(keyringType)) {
385
- // We only consider "normal accounts" here, so keep looping
448
+ for (const address of await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountAddresses).call(this)) {
449
+ const keyring = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getKeyringForAccount).call(this, address);
450
+ if (!(0, utils_2.isNormalKeyringType)(keyring.type)) {
451
+ // We only consider "normal accounts" here, so keep looping.
386
452
  continue;
387
453
  }
388
- const id = (0, utils_2.getUUIDFromAddressOfNormalAccount)(address);
389
- const nameLastUpdatedAt = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'nameLastUpdatedAt');
390
- internalAccounts.push({
391
- id,
392
- address,
393
- options: {},
394
- methods: [
395
- keyring_api_1.EthMethod.PersonalSign,
396
- keyring_api_1.EthMethod.Sign,
397
- keyring_api_1.EthMethod.SignTransaction,
398
- keyring_api_1.EthMethod.SignTypedDataV1,
399
- keyring_api_1.EthMethod.SignTypedDataV3,
400
- keyring_api_1.EthMethod.SignTypedDataV4,
401
- ],
402
- scopes: [keyring_api_1.EthScopes.Namespace],
403
- type: keyring_api_1.EthAccountType.Eoa,
404
- metadata: {
405
- name: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'name') ?? '',
406
- ...(nameLastUpdatedAt && { nameLastUpdatedAt }),
407
- importTime: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'importTime') ?? Date.now(),
408
- lastSelected: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'lastSelected') ?? 0,
409
- keyring: {
410
- type: keyring.type,
411
- },
412
- },
413
- });
454
+ internalAccounts.push(__classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_generateInternalAccountForNonSnapAccount).call(this, address,
455
+ // The keyring type can either be "Simple" or "HD" here.
456
+ keyring.type));
414
457
  }
415
458
  return internalAccounts;
416
459
  }, _AccountsController_handleOnKeyringStateChange = function _AccountsController_handleOnKeyringStateChange(keyringState) {
@@ -454,8 +497,8 @@ async function _AccountsController_listNormalAccounts() {
454
497
  });
455
498
  const addedAccounts = [];
456
499
  const deletedAccounts = [];
457
- // snap account ids are random uuid while normal accounts
458
- // are determininistic based on the address
500
+ // Snap account IDs are random UUIDs while normal accounts
501
+ // are determininistic based on the address.
459
502
  // ^NOTE: This will be removed when normal accounts also implement internal accounts
460
503
  // finding all the normal accounts that were added
461
504
  for (const account of updatedNormalKeyringAddresses) {
@@ -561,7 +604,7 @@ async function _AccountsController_listNormalAccounts() {
561
604
  newAccount = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_generateInternalAccountForNonSnapAccount).call(this, account.address, account.type);
562
605
  }
563
606
  else {
564
- const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', eth_snap_keyring_1.SnapKeyring.type);
607
+ const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
565
608
  newAccount = snapKeyring.getAccountByAddress(account.address);
566
609
  // The snap deleted the account before the keyring controller could add it
567
610
  if (!newAccount) {
@@ -592,9 +635,6 @@ async function _AccountsController_listNormalAccounts() {
592
635
  delete accountsState[accountId];
593
636
  this.messagingSystem.publish('AccountsController:accountRemoved', accountId);
594
637
  return accountsState;
595
- }, _AccountsController_populateExistingMetadata = function _AccountsController_populateExistingMetadata(accountId, metadataKey, account) {
596
- const internalAccount = account ?? this.getAccount(accountId);
597
- return internalAccount ? internalAccount.metadata[metadataKey] : undefined;
598
638
  }, _AccountsController_registerMessageHandlers = function _AccountsController_registerMessageHandlers() {
599
639
  this.messagingSystem.registerActionHandler(`${controllerName}:setSelectedAccount`, this.setSelectedAccount.bind(this));
600
640
  this.messagingSystem.registerActionHandler(`${controllerName}:listAccounts`, this.listAccounts.bind(this));
@@ -1 +1 @@
1
- {"version":3,"file":"AccountsController.cjs","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":";;;;;;;;;AAKA,+DAA2D;AAC3D,iEAAyD;AACzD,uDAK+B;AAC/B,qEAA4D;AAgB5D,2CAKyB;AAGzB,uCAIiB;AAEjB,MAAM,cAAc,GAAG,oBAAoB,CAAC;AA+I5C,MAAM,0BAA0B,GAAG;IACjC,gBAAgB,EAAE;QAChB,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,KAAK;KACjB;CACF,CAAC;AAEF,MAAM,YAAY,GAA4B;IAC5C,gBAAgB,EAAE;QAChB,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,EAAE;KACpB;CACF,CAAC;AAEW,QAAA,aAAa,GAAG;IAC3B,EAAE,EAAE,EAAE;IACN,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,4BAAc,CAAC,GAAG;IACxB,MAAM,EAAE,CAAC,uBAAS,CAAC,SAAS,CAAC;IAC7B,QAAQ,EAAE;QACR,IAAI,EAAE,EAAE;QACR,OAAO,EAAE;YACP,IAAI,EAAE,EAAE;SACT;QACD,UAAU,EAAE,CAAC;KACd;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAa,kBAAmB,SAAQ,gCAIvC;IACC;;;;;;OAMG;IACH,YAAY,EACV,SAAS,EACT,KAAK,GAIN;QACC,KAAK,CAAC;YACJ,SAAS;YACT,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,0BAA0B;YACpC,KAAK,EAAE;gBACL,GAAG,YAAY;gBACf,GAAG,KAAK;aACT;SACF,CAAC,CAAC;;QAEH,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,4BAA4B,EAC5B,CAAC,cAAc,EAAE,EAAE,CAAC,uBAAA,IAAI,kFAAyB,MAA7B,IAAI,EAA0B,cAAc,CAAC,CAClE,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,SAAS,CAC5B,+BAA+B,EAC/B,CAAC,YAAY,EAAE,EAAE,CAAC,uBAAA,IAAI,qFAA4B,MAAhC,IAAI,EAA6B,YAAY,CAAC,CACjE,CAAC;QAEF,uBAAA,IAAI,kFAAyB,MAA7B,IAAI,CAA2B,CAAC;IAClC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACrE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,8BAAgB,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,OAAqB;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,QAAQ,CAAC;SACjB;QAED,IAAI,CAAC,IAAA,qBAAa,EAAC,OAAO,CAAC,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;SAChE;QAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACjC,uBAAA,IAAI,uFAA8B,MAAlC,IAAI,EAA+B,OAAO,EAAE,OAAO,CAAC,CACrD,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,gBAAgB,CAAC,SAAiB;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,MAAM,IAAI,KAAK,CAAC,eAAe,SAAS,aAAa,CAAC,CAAC;SACxD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,kBAAkB;QAChB,wEAAwE;QACxE,uFAAuF;QACvF,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,KAAK,EAAE,EAAE;YACtD,OAAO,qBAAa,CAAC;SACtB;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAC3C,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,CAC5C,CAAC;QACF,IAAI,IAAA,8BAAgB,EAAC,eAAe,CAAC,IAAI,CAAC,EAAE;YAC1C,OAAO,eAAe,CAAC;SACxB;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAErC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACpB,6BAA6B;YAC7B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;SACpC;QAED,yFAAyF;QACzF,oEAAoE;QACpE,OAAO,uBAAA,IAAI,iFAAwB,MAA5B,IAAI,EAAyB,QAAQ,CAAE,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,4BAA4B,CAC1B,OAAqB;QAErB,wEAAwE;QACxE,uFAAuF;QACvF,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,KAAK,EAAE,EAAE;YACtD,OAAO,qBAAa,CAAC;SACtB;QAED,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;SAC3E;QAED,IAAI,CAAC,IAAA,qBAAa,EAAC,OAAO,CAAC,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAiB,EAAE,CAAC,CAAC;SAClE;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,MAAM,CACzE,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,uFAA8B,MAAlC,IAAI,EAA+B,OAAO,EAAE,OAAO,CAAC,CAClE,CAAC;QAEF,OAAO,uBAAA,IAAI,iFAAwB,MAA5B,IAAI,EAAyB,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,mBAAmB,CAAC,OAAe;QACjC,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,CACvC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CACrE,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,SAAiB;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAEjD,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;YAC3D,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,YAAY;gBACtE,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,gBAAgB,CAAC,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,uBAAA,IAAI,oFAA2B,MAA/B,IAAI,EAA4B,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,SAAiB,EAAE,WAAmB;QACnD,0EAA0E;QAC1E,mCAAmC;QACnC,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE;YACpC,IAAI,EAAE,WAAW;YACjB,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE;SAC9B,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,qBAAqB,CACnB,SAAiB,EACjB,QAA8C;QAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAEjD,IACE,QAAQ,CAAC,IAAI;YACb,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,CAChC,CAAC,eAAe,EAAE,EAAE,CAClB,eAAe,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;gBAC/C,eAAe,CAAC,EAAE,KAAK,SAAS,CACnC,EACD;YACA,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;YAC3D,MAAM,eAAe,GAAG;gBACtB,GAAG,OAAO;gBACV,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE;aAC/C,CAAC;YACF,4HAA4H;YAC5H,oDAAoD;YACpD,yGAAyG;YACzG,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,eAAe,CAAC;YAEpE,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACjB,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,mCAAmC,EACnC,eAAe,CAChB,CAAC;aACH;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc;QAClB,MAAM,YAAY,GAAG,MAAM,uBAAA,IAAI,2EAAkB,MAAtB,IAAI,CAAoB,CAAC;QACpD,MAAM,cAAc,GAAG,MAAM,uBAAA,IAAI,6EAAoB,MAAxB,IAAI,CAAsB,CAAC;QAExD,oBAAoB;QACpB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAE9D,MAAM,QAAQ,GAAoC;YAChD,GAAG,cAAc;YACjB,GAAG,YAAY;SAChB,CAAC,MAAM,CAAC,CAAC,kBAAkB,EAAE,eAAe,EAAE,EAAE;YAC/C,MAAM,eAAe,GAAG,IAAA,yBAAiB,EACvC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CACtC,CAAC;YACF,MAAM,mBAAmB,GAAG,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YACnE,IAAI,mBAAmB,EAAE;gBACvB,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,mBAAmB,GAAG,CAAC,CAAC,CAAC;aAC5D;iBAAM;gBACL,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;aACtC;YAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;YAE7D,kBAAkB,CAAC,eAAe,CAAC,EAAE,CAAC,GAAG;gBACvC,GAAG,eAAe;gBAElB,QAAQ,EAAE;oBACR,GAAG,eAAe,CAAC,QAAQ;oBAC3B,IAAI,EACF,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC;wBAC3D,GAAG,eAAe,IAAI,mBAAmB,GAAG,CAAC,EAAE;oBACjD,UAAU,EACR,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,eAAe,EAAE,EAAE,EAAE,YAAY,CAAC;wBACjE,IAAI,CAAC,GAAG,EAAE;oBACZ,YAAY,EACV,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EACF,eAAe,EAAE,EAAE,EACnB,cAAc,CACf,IAAI,CAAC;iBACT;aACF,CAAC;YAEF,OAAO,kBAAkB,CAAC;QAC5B,CAAC,EAAE,EAAqC,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;YAC3D,YAAY,CAAC,gBAAgB,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAElD,IACE,CAAC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CACrC,YAAY,CAAC,gBAAgB,CAAC,eAAe,CAC9C,EACD;gBACA,MAAM,mBAAmB,GAAG,uBAAA,IAAI,iFAAwB,MAA5B,IAAI,EAC9B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CACxB,CAAC;gBAEF,IAAI,mBAAmB,EAAE;oBACvB,YAAY,CAAC,gBAAgB,CAAC,eAAe;wBAC3C,mBAAmB,CAAC,EAAE,CAAC;oBACzB,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CACpC,mBAAmB,CAAC,EAAE,CACvB,CAAC,QAAQ,CAAC,YAAY,GAAG,uBAAA,IAAI,+EAAsB,MAA1B,IAAI,CAAwB,CAAC;oBACvD,uBAAA,IAAI,oFAA2B,MAA/B,IAAI,EAA4B,mBAAmB,CAAC,CAAC;iBACtD;qBAAM;oBACL,gDAAgD;oBAChD,YAAY,CAAC,gBAAgB,CAAC,eAAe,GAAG,EAAE,CAAC;iBACpD;aACF;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,MAA+B;QACxC,IAAI,MAAM,CAAC,gBAAgB,EAAE;YAC3B,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;gBAC3D,YAAY,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;YAC1D,CAAC,CAAC,CAAC;SACJ;IACH,CAAC;IA8VD;;;;;OAKG;IACH,2BAA2B,CACzB,cAAsB,iCAAY,CAAC,EAAE,EACrC,QAA4B;QAE5B,MAAM,WAAW,GAAG,IAAA,yBAAiB,EAAC,WAAW,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAC1B,WAAW,EACX,QAAQ,CACT,CAAC;QACF,MAAM,kCAAkC,GAAG,eAAe,CAAC,MAAM,CAC/D,CAAC,uBAAuB,EAAE,eAAe,EAAE,EAAE;YAC3C,8DAA8D;YAC9D,kCAAkC;YAClC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,CAC5D,eAAe,CAAC,QAAQ,CAAC,IAAI,CAC9B,CAAC;YAEF,IAAI,KAAK,EAAE;gBACT,uCAAuC;gBACvC,qFAAqF;gBACrF,8CAA8C;gBAC9C,8CAA8C;gBAC9C,MAAM,oBAAoB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpD,OAAO,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAAE,oBAAoB,CAAC,CAAC;aAChE;YAED,OAAO,uBAAuB,CAAC;QACjC,CAAC,EACD,CAAC,CACF,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,eAAe,CAAC,MAAM,GAAG,CAAC;QAC1B,wCAAwC;QACxC,qEAAqE;QACrE,kCAAkC,GAAG,CAAC,CACvC,CAAC;QAEF,OAAO,GAAG,WAAW,IAAI,KAAK,EAAE,CAAC;IACnC,CAAC;CAyMF;AAt6BD,gDAs6BC;oLA3kBG,OAAe,EACf,IAAY;IAEZ,OAAO;QACL,EAAE,EAAE,IAAA,yCAAiC,EAAC,OAAO,CAAC;QAC9C,OAAO;QACP,OAAO,EAAE,EAAE;QACX,OAAO,EAAE;YACP,uBAAS,CAAC,YAAY;YACtB,uBAAS,CAAC,IAAI;YACd,uBAAS,CAAC,eAAe;YACzB,uBAAS,CAAC,eAAe;YACzB,uBAAS,CAAC,eAAe;YACzB,uBAAS,CAAC,eAAe;SAC1B;QACD,MAAM,EAAE,CAAC,uBAAS,CAAC,SAAS,CAAC;QAC7B,IAAI,EAAE,4BAAc,CAAC,GAAG;QACxB,QAAQ,EAAE;YACR,IAAI,EAAE,EAAE;YACR,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,OAAO,EAAE;gBACP,IAAI;aACL;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,qCAAqC,EACrC,8BAAW,CAAC,IAAI,CACjB,CAAC;IACF,6FAA6F;IAC7F,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,EAAE,CAAC;KACX;IAED,MAAM,YAAY,GAAI,WAA2B,CAAC,YAAY,EAAE,CAAC;IAEjE,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,KAAK;IACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAC/C,+BAA+B,CAChC,CAAC;IACF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAC/C,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE;QAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,wCAAwC,EACxC,OAAO,CACR,CAAC;QAEF,MAAM,WAAW,GAAI,OAAyB,CAAC,IAAI,CAAC;QACpD,IAAI,CAAC,IAAA,2BAAmB,EAAC,WAA2B,CAAC,EAAE;YACrD,2DAA2D;YAC3D,SAAS;SACV;QAED,MAAM,EAAE,GAAG,IAAA,yCAAiC,EAAC,OAAO,CAAC,CAAC;QAEtD,MAAM,iBAAiB,GAAG,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAC5B,EAAE,EACF,mBAAmB,CACpB,CAAC;QAEF,gBAAgB,CAAC,IAAI,CAAC;YACpB,EAAE;YACF,OAAO;YACP,OAAO,EAAE,EAAE;YACX,OAAO,EAAE;gBACP,uBAAS,CAAC,YAAY;gBACtB,uBAAS,CAAC,IAAI;gBACd,uBAAS,CAAC,eAAe;gBACzB,uBAAS,CAAC,eAAe;gBACzB,uBAAS,CAAC,eAAe;gBACzB,uBAAS,CAAC,eAAe;aAC1B;YACD,MAAM,EAAE,CAAC,uBAAS,CAAC,SAAS,CAAC;YAC7B,IAAI,EAAE,4BAAc,CAAC,GAAG;YACxB,QAAQ,EAAE;gBACR,IAAI,EAAE,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE;gBACtD,GAAG,CAAC,iBAAiB,IAAI,EAAE,iBAAiB,EAAE,CAAC;gBAC/C,UAAU,EACR,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,EAAE,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE;gBAChE,YAAY,EAAE,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B,EAAE,EAAE,cAAc,CAAC,IAAI,CAAC;gBACrE,OAAO,EAAE;oBACP,IAAI,EAAG,OAAyB,CAAC,IAAI;iBACtC;aACF;SACF,CAAC,CAAC;KACJ;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC,2GAO2B,YAAoC;IAC9D,4CAA4C;IAC5C,0EAA0E;IAE1E,iGAAiG;IACjG,qDAAqD;IACrD,4HAA4H;IAC5H,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;QAC/D,MAAM,6BAA6B,GAAkC,EAAE,CAAC;QACxE,MAAM,2BAA2B,GAAkC,EAAE,CAAC;QAEtE,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE;YAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,IAAI,EAAE;gBACtC,2BAA2B,CAAC,IAAI,CAC9B,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;oBAClC,OAAO;wBACL,OAAO;wBACP,IAAI,EAAE,OAAO,CAAC,IAAI;qBACnB,CAAC;gBACJ,CAAC,CAAC,CACH,CAAC;aACH;iBAAM;gBACL,6BAA6B,CAAC,IAAI,CAChC,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;oBAClC,OAAO;wBACL,OAAO;wBACP,IAAI,EAAE,OAAO,CAAC,IAAI;qBACnB,CAAC;gBACJ,CAAC,CAAC,CACH,CAAC;aACH;SACF;QAED,MAAM,EAAE,8BAA8B,EAAE,4BAA4B,EAAE,GACpE,IAAI,CAAC,sBAAsB,EAAE,CAAC,MAAM,CAClC,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE;YACvB,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,IAAI,EAAE;gBACvD,WAAW,CAAC,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aACxD;iBAAM;gBACL,WAAW,CAAC,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC1D;YACD,OAAO,WAAW,CAAC;QACrB,CAAC,EACD;YACE,8BAA8B,EAAE,EAAuB;YACvD,4BAA4B,EAAE,EAAuB;SACtD,CACF,CAAC;QAEJ,MAAM,aAAa,GAAkC,EAAE,CAAC;QACxD,MAAM,eAAe,GAAsB,EAAE,CAAC;QAE9C,yDAAyD;QACzD,2CAA2C;QAE3C,oFAAoF;QACpF,kDAAkD;QAClD,KAAK,MAAM,OAAO,IAAI,6BAA6B,EAAE;YACnD,IACE,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CACnC,IAAA,yCAAiC,EAAC,OAAO,CAAC,OAAO,CAAC,CACnD,EACD;gBACA,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC7B;SACF;QAED,gDAAgD;QAChD,KAAK,MAAM,OAAO,IAAI,2BAA2B,EAAE;YACjD,IACE,CAAC,4BAA4B,CAAC,IAAI,CAChC,CAAC,eAAgC,EAAE,EAAE,CACnC,eAAe,CAAC,OAAO,CAAC,WAAW,EAAE;gBACrC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAChC,EACD;gBACA,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC7B;SACF;QAED,oDAAoD;QACpD,KAAK,MAAM,OAAO,IAAI,8BAA8B,EAAE;YACpD,IACE,CAAC,6BAA6B,CAAC,IAAI,CACjC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACd,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAC1D,EACD;gBACA,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC/B;SACF;QAED,kDAAkD;QAClD,KAAK,MAAM,OAAO,IAAI,4BAA4B,EAAE;YAClD,IACE,CAAC,2BAA2B,CAAC,IAAI,CAC/B,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACd,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAC1D,EACD;gBACA,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC/B;SACF;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;YAC3D,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC9B,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE;oBACrC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,GAAG,uBAAA,IAAI,+EAAsB,MAA1B,IAAI,EAC3C,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EACtC,OAAO,CAAC,EAAE,CACX,CAAC;iBACH;aACF;YAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC5B,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE;oBACnC,YAAY,CAAC,gBAAgB,CAAC,QAAQ;wBACpC,uBAAA,IAAI,gFAAuB,MAA3B,IAAI,EACF,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EACtC,OAAO,CACR,CAAC;iBACL;aACF;YAED,sEAAsE;YACtE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CACpC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CACvC,CAAC;YAEF,6CAA6C;YAC7C,IACE,CAAC,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CACrC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,eAAe,CAC5C,EACD;gBACA,MAAM,mBAAmB,GACvB,uBAAA,IAAI,iFAAwB,MAA5B,IAAI,EAAyB,gBAAgB,CAAC,CAAC;gBAEjD,IAAI,mBAAmB,EAAE;oBACvB,YAAY,CAAC,gBAAgB,CAAC,eAAe;wBAC3C,mBAAmB,CAAC,EAAE,CAAC;oBACzB,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CACpC,mBAAmB,CAAC,EAAE,CACvB,CAAC,QAAQ,CAAC,YAAY,GAAG,uBAAA,IAAI,+EAAsB,MAA1B,IAAI,CAAwB,CAAC;oBACvD,uBAAA,IAAI,oFAA2B,MAA/B,IAAI,EAA4B,mBAAmB,CAAC,CAAC;iBACtD;qBAAM;oBACL,gDAAgD;oBAChD,YAAY,CAAC,gBAAgB,CAAC,eAAe,GAAG,EAAE,CAAC;iBACpD;aACF;QACH,CAAC,CAAC,CAAC;KACJ;AACH,CAAC,qGAOwB,SAA8B;IACrD,wCAAwC;IACxC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,MAAM,CACnD,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CACnC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,CAAC,YAA4C,EAAE,EAAE;QAC3D,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,cAAc,GAClB,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrD,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE;gBAChC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/C,MAAM,UAAU,GAAS,KAAK,CAAC,MAAgB,CAAC,CAAC;gBACjD,IAAI,UAAU,EAAE;oBACd,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO;wBAClC,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;iBAC7C;aACF;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,uGAQyB,WAAmB,EAAE,QAA4B;IACzE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC,MAAM,CACvD,CAAC,eAAe,EAAE,EAAE;QAClB,0FAA0F;QAC1F,oCAAoC;QACpC,IACE,WAAW,KAAK,iCAAY,CAAC,EAAE;YAC/B,WAAW,KAAK,iCAAY,CAAC,MAAM,EACnC;YACA,OAAO,CACL,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,EAAE;gBACzD,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,MAAM,CAC9D,CAAC;SACH;QAED,OAAO,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC;IAC/D,CAAC,CACF,CAAC;AACJ,CAAC,mGASC,QAA2B;IAE3B,MAAM,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAC7D,kCAAkC;QAClC,OAAO,CACL,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,IAAI,CAAC,CAAC;YACrC,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,IAAI,CAAC,CAAC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC;AACzB,CAAC,+GAyDC,OAAwB,EACxB,OAAoB;IAEpB,oDAAoD;IACpD,yEAAyE;IACzE,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAA,wBAAgB,EAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC;AACtE,CAAC;IAQC,kEAAkE;IAClE,iEAAiE;IACjE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AACpB,CAAC,iGAWC,aAAsE,EACtE,OAAoC;IAEpC,IAAI,UAA2B,CAAC;IAChC,IAAI,OAAO,CAAC,IAAI,KAAK,iCAAY,CAAC,IAAI,EAAE;QACtC,UAAU,GAAG,uBAAA,IAAI,mGAA0C,MAA9C,IAAI,EACf,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,IAAI,CACb,CAAC;KACH;SAAM;QACL,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAC7C,qCAAqC,EACrC,8BAAW,CAAC,IAAI,CACjB,CAAC;QAEF,UAAU,GAAI,WAA2B,CAAC,mBAAmB,CAC3D,OAAO,CAAC,OAAO,CACG,CAAC;QAErB,0EAA0E;QAC1E,IAAI,CAAC,UAAU,EAAE;YACf,OAAO,aAAa,CAAC;SACtB;KACF;IAED,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAE/D,yDAAyD;IACzD,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAClD,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAChC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAC7B,CAAC;IAEF,MAAM,6BAA6B,GAAG;QACpC,GAAG,UAAU;QACb,QAAQ,EAAE;YACR,GAAG,UAAU,CAAC,QAAQ;YACtB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC,uBAAA,IAAI,+EAAsB,MAA1B,IAAI,CAAwB,CAAC,CAAC,CAAC,CAAC;SAChE;KACF,CAAC;IACF,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,6BAA6B,CAAC;IAE7D,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,iCAAiC,EACjC,6BAA6B,CAC9B,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC,yGAE0B,OAAwB;IACjD,IAAI,IAAA,8BAAgB,EAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAClC,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,6CAA6C,EAC7C,OAAO,CACR,CAAC;KACH;IACD,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,0CAA0C,EAC1C,OAAO,CACR,CAAC;AACJ,CAAC,+FASC,aAAsE,EACtE,SAAiB;IAEjB,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;IAEhC,IAAI,CAAC,eAAe,CAAC,OAAO,CAC1B,mCAAmC,EACnC,SAAS,CACV,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC,uGAYC,SAAiB,EACjB,WAAc,EACd,OAAyB;IAEzB,MAAM,eAAe,GAAG,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC9D,OAAO,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;IAOC,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,qBAAqB,EACtC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CACnC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,eAAe,EAChC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAC7B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,yBAAyB,EAC1C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CACvC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,iBAAiB,EAClC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,iBAAiB,EAClC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,qBAAqB,EACtC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CACnC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,+BAA+B,EAChD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAC7C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,sBAAsB,EACvC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CACpC,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,GAAG,cAAc,8BAA8B,EAC/C,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5C,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,+BAA+B,EAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAC3B,CAAC;IAEF,IAAI,CAAC,eAAe,CAAC,qBAAqB,CACxC,0CAA0C,EAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CACtC,CAAC;AACJ,CAAC","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n EthAccountType,\n EthMethod,\n EthScopes,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n KeyringControllerState,\n KeyringControllerGetKeyringForAccountAction,\n KeyringControllerGetKeyringsByTypeAction,\n KeyringControllerGetAccountsAction,\n KeyringControllerStateChangeEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n SnapControllerState,\n SnapStateChange,\n} from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { Snap } from '@metamask/snaps-utils';\nimport type { CaipChainId } from '@metamask/utils';\nimport {\n type Keyring,\n type Json,\n isCaipChainId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n getUUIDFromAddressOfNormalAccount,\n isNormalKeyringType,\n keyringTypeToName,\n} from './utils';\n\nconst controllerName = 'AccountsController';\n\nexport type AccountId = string;\n\nexport type AccountsControllerState = {\n internalAccounts: {\n accounts: Record<AccountId, InternalAccount>;\n selectedAccount: string; // id of the selected account\n };\n};\n\nexport type AccountsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSetSelectedAccountAction = {\n type: `${typeof controllerName}:setSelectedAccount`;\n handler: AccountsController['setSelectedAccount'];\n};\n\nexport type AccountsControllerSetAccountNameAction = {\n type: `${typeof controllerName}:setAccountName`;\n handler: AccountsController['setAccountName'];\n};\n\nexport type AccountsControllerListAccountsAction = {\n type: `${typeof controllerName}:listAccounts`;\n handler: AccountsController['listAccounts'];\n};\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `${typeof controllerName}:listMultichainAccounts`;\n handler: AccountsController['listMultichainAccounts'];\n};\n\nexport type AccountsControllerUpdateAccountsAction = {\n type: `${typeof controllerName}:updateAccounts`;\n handler: AccountsController['updateAccounts'];\n};\n\nexport type AccountsControllerGetSelectedAccountAction = {\n type: `${typeof controllerName}:getSelectedAccount`;\n handler: AccountsController['getSelectedAccount'];\n};\n\nexport type AccountsControllerGetSelectedMultichainAccountAction = {\n type: `${typeof controllerName}:getSelectedMultichainAccount`;\n handler: AccountsController['getSelectedMultichainAccount'];\n};\n\nexport type AccountsControllerGetAccountByAddressAction = {\n type: `${typeof controllerName}:getAccountByAddress`;\n handler: AccountsController['getAccountByAddress'];\n};\n\nexport type AccountsControllerGetNextAvailableAccountNameAction = {\n type: `${typeof controllerName}:getNextAvailableAccountName`;\n handler: AccountsController['getNextAvailableAccountName'];\n};\n\nexport type AccountsControllerGetAccountAction = {\n type: `${typeof controllerName}:getAccount`;\n handler: AccountsController['getAccount'];\n};\n\nexport type AccountsControllerUpdateAccountMetadataAction = {\n type: `${typeof controllerName}:updateAccountMetadata`;\n handler: AccountsController['updateAccountMetadata'];\n};\n\nexport type AllowedActions =\n | KeyringControllerGetKeyringForAccountAction\n | KeyringControllerGetKeyringsByTypeAction\n | KeyringControllerGetAccountsAction;\n\nexport type AccountsControllerActions =\n | AccountsControllerGetStateAction\n | AccountsControllerSetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerSetAccountNameAction\n | AccountsControllerUpdateAccountsAction\n | AccountsControllerGetAccountByAddressAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetNextAvailableAccountNameAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetSelectedMultichainAccountAction\n | AccountsControllerUpdateAccountMetadataAction;\n\nexport type AccountsControllerChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSelectedAccountChangeEvent = {\n type: `${typeof controllerName}:selectedAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerSelectedEvmAccountChangeEvent = {\n type: `${typeof controllerName}:selectedEvmAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountAddedEvent = {\n type: `${typeof controllerName}:accountAdded`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountRemovedEvent = {\n type: `${typeof controllerName}:accountRemoved`;\n payload: [AccountId];\n};\n\nexport type AccountsControllerAccountRenamedEvent = {\n type: `${typeof controllerName}:accountRenamed`;\n payload: [InternalAccount];\n};\n\nexport type AllowedEvents = SnapStateChange | KeyringControllerStateChangeEvent;\n\nexport type AccountsControllerEvents =\n | AccountsControllerChangeEvent\n | AccountsControllerSelectedAccountChangeEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountRenamedEvent;\n\nexport type AccountsControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AccountsControllerActions | AllowedActions,\n AccountsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype AddressAndKeyringTypeObject = {\n address: string;\n type: string;\n};\n\nconst accountsControllerMetadata = {\n internalAccounts: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst defaultState: AccountsControllerState = {\n internalAccounts: {\n accounts: {},\n selectedAccount: '',\n },\n};\n\nexport const EMPTY_ACCOUNT = {\n id: '',\n address: '',\n options: {},\n methods: [],\n type: EthAccountType.Eoa,\n scopes: [EthScopes.Namespace],\n metadata: {\n name: '',\n keyring: {\n type: '',\n },\n importTime: 0,\n },\n};\n\n/**\n * Controller that manages internal accounts.\n * The accounts controller is responsible for creating and managing internal accounts.\n * It also provides convenience methods for accessing and updating the internal accounts.\n * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.\n * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.\n *\n */\nexport class AccountsController extends BaseController<\n typeof controllerName,\n AccountsControllerState,\n AccountsControllerMessenger\n> {\n /**\n * Constructor for AccountsController.\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: AccountsControllerMessenger;\n state: AccountsControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountsControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.messagingSystem.subscribe(\n 'SnapController:stateChange',\n (snapStateState) => this.#handleOnSnapStateChange(snapStateState),\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:stateChange',\n (keyringState) => this.#handleOnKeyringStateChange(keyringState),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Returns the internal account object for the given account ID, if it exists.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object, or undefined if the account does not exist.\n */\n getAccount(accountId: string): InternalAccount | undefined {\n return this.state.internalAccounts.accounts[accountId];\n }\n\n /**\n * Returns an array of all evm internal accounts.\n *\n * @returns An array of InternalAccount objects.\n */\n listAccounts(): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n return accounts.filter((account) => isEvmAccountType(account.type));\n }\n\n /**\n * Returns an array of all internal accounts.\n *\n * @param chainId - The chain ID.\n * @returns An array of InternalAccount objects.\n */\n listMultichainAccounts(chainId?: CaipChainId): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n if (!chainId) {\n return accounts;\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${String(chainId)}`);\n }\n\n return accounts.filter((account) =>\n this.#isAccountCompatibleWithChain(account, chainId),\n );\n }\n\n /**\n * Returns the internal account object for the given account ID.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object.\n * @throws An error if the account ID is not found.\n */\n getAccountExpect(accountId: string): InternalAccount {\n const account = this.getAccount(accountId);\n if (account === undefined) {\n throw new Error(`Account Id \"${accountId}\" not found`);\n }\n return account;\n }\n\n /**\n * Returns the last selected EVM account.\n *\n * @returns The selected internal account.\n */\n getSelectedAccount(): InternalAccount {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n const selectedAccount = this.getAccountExpect(\n this.state.internalAccounts.selectedAccount,\n );\n if (isEvmAccountType(selectedAccount.type)) {\n return selectedAccount;\n }\n\n const accounts = this.listAccounts();\n\n if (!accounts.length) {\n // ! Should never reach this.\n throw new Error('No EVM accounts');\n }\n\n // This will never be undefined because we have already checked if accounts.length is > 0\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#getLastSelectedAccount(accounts)!;\n }\n\n /**\n * __WARNING The return value may be undefined if there isn't an account for that chain id.__\n *\n * Retrieves the last selected account by chain ID.\n *\n * @param chainId - The chain ID to filter the accounts.\n * @returns The last selected account compatible with the specified chain ID or undefined.\n */\n getSelectedMultichainAccount(\n chainId?: CaipChainId,\n ): InternalAccount | undefined {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n if (!chainId) {\n return this.getAccountExpect(this.state.internalAccounts.selectedAccount);\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${chainId as string}`);\n }\n\n const accounts = Object.values(this.state.internalAccounts.accounts).filter(\n (account) => this.#isAccountCompatibleWithChain(account, chainId),\n );\n\n return this.#getLastSelectedAccount(accounts);\n }\n\n /**\n * Returns the account with the specified address.\n * ! This method will only return the first account that matches the address\n * @param address - The address of the account to retrieve.\n * @returns The account with the specified address, or undefined if not found.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n return this.listMultichainAccounts().find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n );\n }\n\n /**\n * Sets the selected account by its ID.\n *\n * @param accountId - The ID of the account to be selected.\n */\n setSelectedAccount(accountId: string): void {\n const account = this.getAccountExpect(accountId);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts[account.id].metadata.lastSelected =\n Date.now();\n currentState.internalAccounts.selectedAccount = account.id;\n });\n\n this.#publishAccountChangeEvent(account);\n }\n\n /**\n * Sets the name of the account with the given ID.\n *\n * @param accountId - The ID of the account to set the name for.\n * @param accountName - The new name for the account.\n * @throws An error if an account with the same name already exists.\n */\n setAccountName(accountId: string, accountName: string): void {\n // This will check for name uniqueness and fire the `accountRenamed` event\n // if the account has been renamed.\n this.updateAccountMetadata(accountId, {\n name: accountName,\n nameLastUpdatedAt: Date.now(),\n });\n }\n\n /**\n * Updates the metadata of the account with the given ID.\n *\n * @param accountId - The ID of the account for which the metadata will be updated.\n * @param metadata - The new metadata for the account.\n */\n updateAccountMetadata(\n accountId: string,\n metadata: Partial<InternalAccount['metadata']>,\n ): void {\n const account = this.getAccountExpect(accountId);\n\n if (\n metadata.name &&\n this.listMultichainAccounts().find(\n (internalAccount) =>\n internalAccount.metadata.name === metadata.name &&\n internalAccount.id !== accountId,\n )\n ) {\n throw new Error('Account name already exists');\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n const internalAccount = {\n ...account,\n metadata: { ...account.metadata, ...metadata },\n };\n // Do not remove this comment - This error is flaky: Comment out or restore the `ts-expect-error` directive below as needed.\n // See: https://github.com/MetaMask/utils/issues/168\n // // @ts-expect-error Known issue - `Json` causes recursive error in immer `Draft`/`WritableDraft` types\n currentState.internalAccounts.accounts[accountId] = internalAccount;\n\n if (metadata.name) {\n this.messagingSystem.publish(\n 'AccountsController:accountRenamed',\n internalAccount,\n );\n }\n });\n }\n\n /**\n * Updates the internal accounts list by retrieving normal and snap accounts,\n * removing duplicates, and updating the metadata of each account.\n *\n * @returns A Promise that resolves when the accounts have been updated.\n */\n async updateAccounts(): Promise<void> {\n const snapAccounts = await this.#listSnapAccounts();\n const normalAccounts = await this.#listNormalAccounts();\n\n // keyring type map.\n const keyringTypes = new Map<string, number>();\n const previousAccounts = this.state.internalAccounts.accounts;\n\n const accounts: Record<string, InternalAccount> = [\n ...normalAccounts,\n ...snapAccounts,\n ].reduce((internalAccountMap, internalAccount) => {\n const keyringTypeName = keyringTypeToName(\n internalAccount.metadata.keyring.type,\n );\n const keyringAccountIndex = keyringTypes.get(keyringTypeName) ?? 0;\n if (keyringAccountIndex) {\n keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);\n } else {\n keyringTypes.set(keyringTypeName, 1);\n }\n\n const existingAccount = previousAccounts[internalAccount.id];\n\n internalAccountMap[internalAccount.id] = {\n ...internalAccount,\n\n metadata: {\n ...internalAccount.metadata,\n name:\n this.#populateExistingMetadata(existingAccount?.id, 'name') ??\n `${keyringTypeName} ${keyringAccountIndex + 1}`,\n importTime:\n this.#populateExistingMetadata(existingAccount?.id, 'importTime') ??\n Date.now(),\n lastSelected:\n this.#populateExistingMetadata(\n existingAccount?.id,\n 'lastSelected',\n ) ?? 0,\n },\n };\n\n return internalAccountMap;\n }, {} as Record<string, InternalAccount>);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts = accounts;\n\n if (\n !currentState.internalAccounts.accounts[\n currentState.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount = this.#getLastSelectedAccount(\n Object.values(accounts),\n );\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n\n /**\n * Loads the backup state of the accounts controller.\n *\n * @param backup - The backup state to load.\n */\n loadBackup(backup: AccountsControllerState): void {\n if (backup.internalAccounts) {\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts = backup.internalAccounts;\n });\n }\n }\n\n /**\n * Generates an internal account for a non-Snap account.\n * @param address - The address of the account.\n * @param type - The type of the account.\n * @returns The generated internal account.\n */\n #generateInternalAccountForNonSnapAccount(\n address: string,\n type: string,\n ): InternalAccount {\n return {\n id: getUUIDFromAddressOfNormalAccount(address),\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n scopes: [EthScopes.Namespace],\n type: EthAccountType.Eoa,\n metadata: {\n name: '',\n importTime: Date.now(),\n keyring: {\n type,\n },\n },\n };\n }\n\n /**\n * Returns a list of internal accounts created using the SnapKeyring.\n *\n * @returns A promise that resolves to an array of InternalAccount objects.\n */\n async #listSnapAccounts(): Promise<InternalAccount[]> {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n // snap keyring is not available until the first account is created in the keyring controller\n if (!snapKeyring) {\n return [];\n }\n\n const snapAccounts = (snapKeyring as SnapKeyring).listAccounts();\n\n return snapAccounts;\n }\n\n /**\n * Returns a list of normal accounts.\n * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.\n * Once all keyrings implement the InternalAccount interface, this method can be removed and getAccounts can be used instead.\n *\n * @returns A Promise that resolves to an array of InternalAccount objects.\n */\n async #listNormalAccounts(): Promise<InternalAccount[]> {\n const addresses = await this.messagingSystem.call(\n 'KeyringController:getAccounts',\n );\n const internalAccounts: InternalAccount[] = [];\n for (const address of addresses) {\n const keyring = await this.messagingSystem.call(\n 'KeyringController:getKeyringForAccount',\n address,\n );\n\n const keyringType = (keyring as Keyring<Json>).type;\n if (!isNormalKeyringType(keyringType as KeyringTypes)) {\n // We only consider \"normal accounts\" here, so keep looping\n continue;\n }\n\n const id = getUUIDFromAddressOfNormalAccount(address);\n\n const nameLastUpdatedAt = this.#populateExistingMetadata(\n id,\n 'nameLastUpdatedAt',\n );\n\n internalAccounts.push({\n id,\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n scopes: [EthScopes.Namespace],\n type: EthAccountType.Eoa,\n metadata: {\n name: this.#populateExistingMetadata(id, 'name') ?? '',\n ...(nameLastUpdatedAt && { nameLastUpdatedAt }),\n importTime:\n this.#populateExistingMetadata(id, 'importTime') ?? Date.now(),\n lastSelected: this.#populateExistingMetadata(id, 'lastSelected') ?? 0,\n keyring: {\n type: (keyring as Keyring<Json>).type,\n },\n },\n });\n }\n\n return internalAccounts;\n }\n\n /**\n * Handles changes in the keyring state, specifically when new accounts are added or removed.\n *\n * @param keyringState - The new state of the keyring controller.\n */\n #handleOnKeyringStateChange(keyringState: KeyringControllerState): void {\n // check if there are any new accounts added\n // TODO: change when accountAdded event is added to the keyring controller\n\n // We check for keyrings length to be greater than 0 because the extension client may try execute\n // submit password twice and clear the keyring state.\n // https://github.com/MetaMask/KeyringController/blob/2d73a4deed8d013913f6ef0c9f5c0bb7c614f7d3/src/KeyringController.ts#L910\n if (keyringState.isUnlocked && keyringState.keyrings.length > 0) {\n const updatedNormalKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n const updatedSnapKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n\n for (const keyring of keyringState.keyrings) {\n if (keyring.type === KeyringTypes.snap) {\n updatedSnapKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n } else {\n updatedNormalKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n }\n }\n\n const { previousNormalInternalAccounts, previousSnapInternalAccounts } =\n this.listMultichainAccounts().reduce(\n (accumulator, account) => {\n if (account.metadata.keyring.type === KeyringTypes.snap) {\n accumulator.previousSnapInternalAccounts.push(account);\n } else {\n accumulator.previousNormalInternalAccounts.push(account);\n }\n return accumulator;\n },\n {\n previousNormalInternalAccounts: [] as InternalAccount[],\n previousSnapInternalAccounts: [] as InternalAccount[],\n },\n );\n\n const addedAccounts: AddressAndKeyringTypeObject[] = [];\n const deletedAccounts: InternalAccount[] = [];\n\n // snap account ids are random uuid while normal accounts\n // are determininistic based on the address\n\n // ^NOTE: This will be removed when normal accounts also implement internal accounts\n // finding all the normal accounts that were added\n for (const account of updatedNormalKeyringAddresses) {\n if (\n !this.state.internalAccounts.accounts[\n getUUIDFromAddressOfNormalAccount(account.address)\n ]\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were added\n for (const account of updatedSnapKeyringAddresses) {\n if (\n !previousSnapInternalAccounts.find(\n (internalAccount: InternalAccount) =>\n internalAccount.address.toLowerCase() ===\n account.address.toLowerCase(),\n )\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the normal accounts that were deleted\n for (const account of previousNormalInternalAccounts) {\n if (\n !updatedNormalKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were deleted\n for (const account of previousSnapInternalAccounts) {\n if (\n !updatedSnapKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n if (deletedAccounts.length > 0) {\n for (const account of deletedAccounts) {\n currentState.internalAccounts.accounts = this.#handleAccountRemoved(\n currentState.internalAccounts.accounts,\n account.id,\n );\n }\n }\n\n if (addedAccounts.length > 0) {\n for (const account of addedAccounts) {\n currentState.internalAccounts.accounts =\n this.#handleNewAccountAdded(\n currentState.internalAccounts.accounts,\n account,\n );\n }\n }\n\n // We don't use list accounts because it is not the updated state yet.\n const existingAccounts = Object.values(\n currentState.internalAccounts.accounts,\n );\n\n // handle if the selected account was deleted\n if (\n !currentState.internalAccounts.accounts[\n this.state.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount =\n this.#getLastSelectedAccount(existingAccounts);\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n }\n\n /**\n * Handles the change in SnapControllerState by updating the metadata of accounts that have a snap enabled.\n *\n * @param snapState - The new SnapControllerState.\n */\n #handleOnSnapStateChange(snapState: SnapControllerState) {\n // only check if snaps changed in status\n const { snaps } = snapState;\n const accounts = this.listMultichainAccounts().filter(\n (account) => account.metadata.snap,\n );\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n accounts.forEach((account) => {\n const currentAccount =\n currentState.internalAccounts.accounts[account.id];\n if (currentAccount.metadata.snap) {\n const snapId = currentAccount.metadata.snap.id;\n const storedSnap: Snap = snaps[snapId as SnapId];\n if (storedSnap) {\n currentAccount.metadata.snap.enabled =\n storedSnap.enabled && !storedSnap.blocked;\n }\n }\n });\n });\n }\n\n /**\n * Returns the list of accounts for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Accounts to filter by keyring type.\n * @returns The list of accounts associcated with this keyring type.\n */\n #getAccountsByKeyringType(keyringType: string, accounts?: InternalAccount[]) {\n return (accounts ?? this.listMultichainAccounts()).filter(\n (internalAccount) => {\n // We do consider `hd` and `simple` keyrings to be of same type. So we check those 2 types\n // to group those accounts together!\n if (\n keyringType === KeyringTypes.hd ||\n keyringType === KeyringTypes.simple\n ) {\n return (\n internalAccount.metadata.keyring.type === KeyringTypes.hd ||\n internalAccount.metadata.keyring.type === KeyringTypes.simple\n );\n }\n\n return internalAccount.metadata.keyring.type === keyringType;\n },\n );\n }\n\n /**\n * Returns the last selected account from the given array of accounts.\n *\n * @param accounts - An array of InternalAccount objects.\n * @returns The InternalAccount object that was last selected, or undefined if the array is empty.\n */\n #getLastSelectedAccount(\n accounts: InternalAccount[],\n ): InternalAccount | undefined {\n const [accountToSelect] = accounts.sort((accountA, accountB) => {\n // sort by lastSelected descending\n return (\n (accountB.metadata.lastSelected ?? 0) -\n (accountA.metadata.lastSelected ?? 0)\n );\n });\n\n return accountToSelect;\n }\n\n /**\n * Returns the next account number for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Existing accounts to check for the next available account number.\n * @returns An object containing the account prefix and index to use.\n */\n getNextAvailableAccountName(\n keyringType: string = KeyringTypes.hd,\n accounts?: InternalAccount[],\n ): string {\n const keyringName = keyringTypeToName(keyringType);\n const keyringAccounts = this.#getAccountsByKeyringType(\n keyringType,\n accounts,\n );\n const lastDefaultIndexUsedForKeyringType = keyringAccounts.reduce(\n (maxInternalAccountIndex, internalAccount) => {\n // We **DO NOT USE** `\\d+` here to only consider valid \"human\"\n // number (rounded decimal number)\n const match = new RegExp(`${keyringName} ([0-9]+)$`, 'u').exec(\n internalAccount.metadata.name,\n );\n\n if (match) {\n // Quoting `RegExp.exec` documentation:\n // > The returned array has the matched text as the first item, and then one item for\n // > each capturing group of the matched text.\n // So use `match[1]` to get the captured value\n const internalAccountIndex = parseInt(match[1], 10);\n return Math.max(maxInternalAccountIndex, internalAccountIndex);\n }\n\n return maxInternalAccountIndex;\n },\n 0,\n );\n\n const index = Math.max(\n keyringAccounts.length + 1,\n // ESLint is confused; this is a number.\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n lastDefaultIndexUsedForKeyringType + 1,\n );\n\n return `${keyringName} ${index}`;\n }\n\n /**\n * Checks if an account is compatible with a given chain namespace.\n * @private\n * @param account - The account to check compatibility for.\n * @param chainId - The CAIP2 to check compatibility with.\n * @returns Returns true if the account is compatible with the chain namespace, otherwise false.\n */\n #isAccountCompatibleWithChain(\n account: InternalAccount,\n chainId: CaipChainId,\n ): boolean {\n // TODO: Change this logic to not use account's type\n // Because we currently only use type, we can only use namespace for now.\n return account.type.startsWith(parseCaipChainId(chainId).namespace);\n }\n\n /**\n * Retrieves the index value for `metadata.lastSelected`.\n *\n * @returns The index value.\n */\n #getLastSelectedIndex() {\n // NOTE: For now we use the current date, since we know this value\n // will always be higher than any already selected account index.\n return Date.now();\n }\n\n /**\n * Handles the addition of a new account to the controller.\n * If the account is not a Snap Keyring account, generates an internal account for it and adds it to the controller.\n * If the account is a Snap Keyring account, retrieves the account from the keyring and adds it to the controller.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param account - The address and keyring type object of the new account.\n * @returns The updated AccountsController accounts state.\n */\n #handleNewAccountAdded(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n account: AddressAndKeyringTypeObject,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n let newAccount: InternalAccount;\n if (account.type !== KeyringTypes.snap) {\n newAccount = this.#generateInternalAccountForNonSnapAccount(\n account.address,\n account.type,\n );\n } else {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n\n newAccount = (snapKeyring as SnapKeyring).getAccountByAddress(\n account.address,\n ) as InternalAccount;\n\n // The snap deleted the account before the keyring controller could add it\n if (!newAccount) {\n return accountsState;\n }\n }\n\n const isFirstAccount = Object.keys(accountsState).length === 0;\n\n // Get next account name available for this given keyring\n const accountName = this.getNextAvailableAccountName(\n newAccount.metadata.keyring.type,\n Object.values(accountsState),\n );\n\n const newAccountWithUpdatedMetadata = {\n ...newAccount,\n metadata: {\n ...newAccount.metadata,\n name: accountName,\n importTime: Date.now(),\n lastSelected: isFirstAccount ? this.#getLastSelectedIndex() : 0,\n },\n };\n accountsState[newAccount.id] = newAccountWithUpdatedMetadata;\n\n this.messagingSystem.publish(\n 'AccountsController:accountAdded',\n newAccountWithUpdatedMetadata,\n );\n\n return accountsState;\n }\n\n #publishAccountChangeEvent(account: InternalAccount) {\n if (isEvmAccountType(account.type)) {\n this.messagingSystem.publish(\n 'AccountsController:selectedEvmAccountChange',\n account,\n );\n }\n this.messagingSystem.publish(\n 'AccountsController:selectedAccountChange',\n account,\n );\n }\n\n /**\n * Handles the removal of an account from the internal accounts list.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param accountId - The ID of the account to be removed.\n * @returns The updated AccountsController state.\n */\n #handleAccountRemoved(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n accountId: string,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n delete accountsState[accountId];\n\n this.messagingSystem.publish(\n 'AccountsController:accountRemoved',\n accountId,\n );\n\n return accountsState;\n }\n\n /**\n * Retrieves the value of a specific metadata key for an existing account.\n * @param accountId - The ID of the account.\n * @param metadataKey - The key of the metadata to retrieve.\n * @param account - The account object to retrieve the metadata key from.\n * @returns The value of the specified metadata key, or undefined if the account or metadata key does not exist.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #populateExistingMetadata<T extends keyof InternalAccount['metadata']>(\n accountId: string,\n metadataKey: T,\n account?: InternalAccount,\n ): InternalAccount['metadata'][T] | undefined {\n const internalAccount = account ?? this.getAccount(accountId);\n return internalAccount ? internalAccount.metadata[metadataKey] : undefined;\n }\n\n /**\n * Registers message handlers for the AccountsController.\n * @private\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccount`,\n this.setSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listAccounts`,\n this.listAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listMultichainAccounts`,\n this.listMultichainAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setAccountName`,\n this.setAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateAccounts`,\n this.updateAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccount`,\n this.getSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedMultichainAccount`,\n this.getSelectedMultichainAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountByAddress`,\n this.getAccountByAddress.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getNextAvailableAccountName`,\n this.getNextAvailableAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:getAccount`,\n this.getAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:updateAccountMetadata`,\n this.updateAccountMetadata.bind(this),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"AccountsController.cjs","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n EthAccountType,\n EthMethod,\n EthScopes,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n KeyringControllerState,\n KeyringControllerGetKeyringForAccountAction,\n KeyringControllerGetKeyringsByTypeAction,\n KeyringControllerGetAccountsAction,\n KeyringControllerStateChangeEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n SnapControllerState,\n SnapStateChange,\n} from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { Snap } from '@metamask/snaps-utils';\nimport type { CaipChainId } from '@metamask/utils';\nimport {\n type Keyring,\n type Json,\n isCaipChainId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n getUUIDFromAddressOfNormalAccount,\n isNormalKeyringType,\n keyringTypeToName,\n} from './utils';\n\nconst controllerName = 'AccountsController';\n\nexport type AccountId = string;\n\nexport type AccountsControllerState = {\n internalAccounts: {\n accounts: Record<AccountId, InternalAccount>;\n selectedAccount: string; // id of the selected account\n };\n};\n\nexport type AccountsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSetSelectedAccountAction = {\n type: `${typeof controllerName}:setSelectedAccount`;\n handler: AccountsController['setSelectedAccount'];\n};\n\nexport type AccountsControllerSetAccountNameAction = {\n type: `${typeof controllerName}:setAccountName`;\n handler: AccountsController['setAccountName'];\n};\n\nexport type AccountsControllerListAccountsAction = {\n type: `${typeof controllerName}:listAccounts`;\n handler: AccountsController['listAccounts'];\n};\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `${typeof controllerName}:listMultichainAccounts`;\n handler: AccountsController['listMultichainAccounts'];\n};\n\nexport type AccountsControllerUpdateAccountsAction = {\n type: `${typeof controllerName}:updateAccounts`;\n handler: AccountsController['updateAccounts'];\n};\n\nexport type AccountsControllerGetSelectedAccountAction = {\n type: `${typeof controllerName}:getSelectedAccount`;\n handler: AccountsController['getSelectedAccount'];\n};\n\nexport type AccountsControllerGetSelectedMultichainAccountAction = {\n type: `${typeof controllerName}:getSelectedMultichainAccount`;\n handler: AccountsController['getSelectedMultichainAccount'];\n};\n\nexport type AccountsControllerGetAccountByAddressAction = {\n type: `${typeof controllerName}:getAccountByAddress`;\n handler: AccountsController['getAccountByAddress'];\n};\n\nexport type AccountsControllerGetNextAvailableAccountNameAction = {\n type: `${typeof controllerName}:getNextAvailableAccountName`;\n handler: AccountsController['getNextAvailableAccountName'];\n};\n\nexport type AccountsControllerGetAccountAction = {\n type: `${typeof controllerName}:getAccount`;\n handler: AccountsController['getAccount'];\n};\n\nexport type AccountsControllerUpdateAccountMetadataAction = {\n type: `${typeof controllerName}:updateAccountMetadata`;\n handler: AccountsController['updateAccountMetadata'];\n};\n\nexport type AllowedActions =\n | KeyringControllerGetKeyringForAccountAction\n | KeyringControllerGetKeyringsByTypeAction\n | KeyringControllerGetAccountsAction;\n\nexport type AccountsControllerActions =\n | AccountsControllerGetStateAction\n | AccountsControllerSetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerSetAccountNameAction\n | AccountsControllerUpdateAccountsAction\n | AccountsControllerGetAccountByAddressAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetNextAvailableAccountNameAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetSelectedMultichainAccountAction\n | AccountsControllerUpdateAccountMetadataAction;\n\nexport type AccountsControllerChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSelectedAccountChangeEvent = {\n type: `${typeof controllerName}:selectedAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerSelectedEvmAccountChangeEvent = {\n type: `${typeof controllerName}:selectedEvmAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountAddedEvent = {\n type: `${typeof controllerName}:accountAdded`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountRemovedEvent = {\n type: `${typeof controllerName}:accountRemoved`;\n payload: [AccountId];\n};\n\nexport type AccountsControllerAccountRenamedEvent = {\n type: `${typeof controllerName}:accountRenamed`;\n payload: [InternalAccount];\n};\n\nexport type AllowedEvents = SnapStateChange | KeyringControllerStateChangeEvent;\n\nexport type AccountsControllerEvents =\n | AccountsControllerChangeEvent\n | AccountsControllerSelectedAccountChangeEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountRenamedEvent;\n\nexport type AccountsControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AccountsControllerActions | AllowedActions,\n AccountsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype AddressAndKeyringTypeObject = {\n address: string;\n type: string;\n};\n\nconst accountsControllerMetadata = {\n internalAccounts: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst defaultState: AccountsControllerState = {\n internalAccounts: {\n accounts: {},\n selectedAccount: '',\n },\n};\n\nexport const EMPTY_ACCOUNT = {\n id: '',\n address: '',\n options: {},\n methods: [],\n type: EthAccountType.Eoa,\n scopes: [EthScopes.Namespace],\n metadata: {\n name: '',\n keyring: {\n type: '',\n },\n importTime: 0,\n },\n};\n\n/**\n * Controller that manages internal accounts.\n * The accounts controller is responsible for creating and managing internal accounts.\n * It also provides convenience methods for accessing and updating the internal accounts.\n * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.\n * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.\n *\n */\nexport class AccountsController extends BaseController<\n typeof controllerName,\n AccountsControllerState,\n AccountsControllerMessenger\n> {\n /**\n * Constructor for AccountsController.\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: AccountsControllerMessenger;\n state: AccountsControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountsControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.messagingSystem.subscribe(\n 'SnapController:stateChange',\n (snapStateState) => this.#handleOnSnapStateChange(snapStateState),\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:stateChange',\n (keyringState) => this.#handleOnKeyringStateChange(keyringState),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Returns the internal account object for the given account ID, if it exists.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object, or undefined if the account does not exist.\n */\n getAccount(accountId: string): InternalAccount | undefined {\n return this.state.internalAccounts.accounts[accountId];\n }\n\n /**\n * Returns an array of all evm internal accounts.\n *\n * @returns An array of InternalAccount objects.\n */\n listAccounts(): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n return accounts.filter((account) => isEvmAccountType(account.type));\n }\n\n /**\n * Returns an array of all internal accounts.\n *\n * @param chainId - The chain ID.\n * @returns An array of InternalAccount objects.\n */\n listMultichainAccounts(chainId?: CaipChainId): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n if (!chainId) {\n return accounts;\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${String(chainId)}`);\n }\n\n return accounts.filter((account) =>\n this.#isAccountCompatibleWithChain(account, chainId),\n );\n }\n\n /**\n * Returns the internal account object for the given account ID.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object.\n * @throws An error if the account ID is not found.\n */\n getAccountExpect(accountId: string): InternalAccount {\n const account = this.getAccount(accountId);\n if (account === undefined) {\n throw new Error(`Account Id \"${accountId}\" not found`);\n }\n return account;\n }\n\n /**\n * Returns the last selected EVM account.\n *\n * @returns The selected internal account.\n */\n getSelectedAccount(): InternalAccount {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n const selectedAccount = this.getAccountExpect(\n this.state.internalAccounts.selectedAccount,\n );\n if (isEvmAccountType(selectedAccount.type)) {\n return selectedAccount;\n }\n\n const accounts = this.listAccounts();\n\n if (!accounts.length) {\n // ! Should never reach this.\n throw new Error('No EVM accounts');\n }\n\n // This will never be undefined because we have already checked if accounts.length is > 0\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#getLastSelectedAccount(accounts)!;\n }\n\n /**\n * __WARNING The return value may be undefined if there isn't an account for that chain id.__\n *\n * Retrieves the last selected account by chain ID.\n *\n * @param chainId - The chain ID to filter the accounts.\n * @returns The last selected account compatible with the specified chain ID or undefined.\n */\n getSelectedMultichainAccount(\n chainId?: CaipChainId,\n ): InternalAccount | undefined {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n if (!chainId) {\n return this.getAccountExpect(this.state.internalAccounts.selectedAccount);\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${chainId as string}`);\n }\n\n const accounts = Object.values(this.state.internalAccounts.accounts).filter(\n (account) => this.#isAccountCompatibleWithChain(account, chainId),\n );\n\n return this.#getLastSelectedAccount(accounts);\n }\n\n /**\n * Returns the account with the specified address.\n * ! This method will only return the first account that matches the address\n * @param address - The address of the account to retrieve.\n * @returns The account with the specified address, or undefined if not found.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n return this.listMultichainAccounts().find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n );\n }\n\n /**\n * Sets the selected account by its ID.\n *\n * @param accountId - The ID of the account to be selected.\n */\n setSelectedAccount(accountId: string): void {\n const account = this.getAccountExpect(accountId);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts[account.id].metadata.lastSelected =\n Date.now();\n currentState.internalAccounts.selectedAccount = account.id;\n });\n\n this.#publishAccountChangeEvent(account);\n }\n\n /**\n * Sets the name of the account with the given ID.\n *\n * @param accountId - The ID of the account to set the name for.\n * @param accountName - The new name for the account.\n * @throws An error if an account with the same name already exists.\n */\n setAccountName(accountId: string, accountName: string): void {\n // This will check for name uniqueness and fire the `accountRenamed` event\n // if the account has been renamed.\n this.updateAccountMetadata(accountId, {\n name: accountName,\n nameLastUpdatedAt: Date.now(),\n });\n }\n\n /**\n * Updates the metadata of the account with the given ID.\n *\n * @param accountId - The ID of the account for which the metadata will be updated.\n * @param metadata - The new metadata for the account.\n */\n updateAccountMetadata(\n accountId: string,\n metadata: Partial<InternalAccount['metadata']>,\n ): void {\n const account = this.getAccountExpect(accountId);\n\n if (\n metadata.name &&\n this.listMultichainAccounts().find(\n (internalAccount) =>\n internalAccount.metadata.name === metadata.name &&\n internalAccount.id !== accountId,\n )\n ) {\n throw new Error('Account name already exists');\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n const internalAccount = {\n ...account,\n metadata: { ...account.metadata, ...metadata },\n };\n // Do not remove this comment - This error is flaky: Comment out or restore the `ts-expect-error` directive below as needed.\n // See: https://github.com/MetaMask/utils/issues/168\n // // @ts-expect-error Known issue - `Json` causes recursive error in immer `Draft`/`WritableDraft` types\n currentState.internalAccounts.accounts[accountId] = internalAccount;\n\n if (metadata.name) {\n this.messagingSystem.publish(\n 'AccountsController:accountRenamed',\n internalAccount,\n );\n }\n });\n }\n\n /**\n * Updates the internal accounts list by retrieving normal and snap accounts,\n * removing duplicates, and updating the metadata of each account.\n *\n * @returns A Promise that resolves when the accounts have been updated.\n */\n async updateAccounts(): Promise<void> {\n // We are re-creating the list of internal accounts based on the accounts from\n // each keyrings, following those rules:\n //\n // - If the account already exists on this controller state, we only update\n // metadata. This allows to automatically \"migrate\" new metadata for existing\n // accounts.\n //\n // - Else, we create the associated internal account for that new account. This\n // can happen when the Snap keyring adds a new account. The Snap keyring will\n // create a new account and will automatically \"persists\" by calling this\n // function explicitly to create its associated internal account.\n //\n // FIXME: This logic is kinda tricky and could be replaced with the new\n // incoming notification system that the Snap keyring will use.\n const snapAccounts = await this.#listAccountsFromSnapKeyring();\n const normalAccounts = await this.#listAccountsFromOtherKeyrings();\n\n // Keep track of unnamed account to rename them after.\n const namedAccounts: InternalAccount[] = [];\n const unnamedAccounts: InternalAccount[] = [];\n\n // Compute the updated list of internal accounts:\n const accounts: Record<string, InternalAccount> = {};\n for (const keyringInternalAccount of [...normalAccounts, ...snapAccounts]) {\n const { id } = keyringInternalAccount;\n\n const internalAccount = this.state.internalAccounts.accounts[id];\n if (internalAccount) {\n // The account already exist, we're just updating the metadata.\n const { metadata } = internalAccount;\n accounts[id] = {\n ...internalAccount,\n metadata: this.#getAccountMetadataOrDefaults(\n metadata.keyring.type,\n metadata,\n ),\n };\n } else {\n // The account does not exist yet on this controller. We create a new\n // internal account now using the internal account created from\n // the keyring account.\n const { metadata } = keyringInternalAccount;\n accounts[id] = {\n ...keyringInternalAccount,\n metadata: this.#getAccountMetadataOrDefaults(\n metadata.keyring.type,\n metadata,\n ),\n };\n }\n\n // If the account has no name yet, we mark it and we'll rename it afterward once\n // we have re-created the full state.\n if (accounts[id].metadata.name === '') {\n unnamedAccounts.push(accounts[id]);\n } else {\n // It's important to track named accounts too since the\n // `getNextAvailableAccountname` will use the highest index possible\n // based on account's names.\n namedAccounts.push(accounts[id]);\n }\n }\n\n // Now, we can rename each accounts according to our naming rule.\n for (const account of unnamedAccounts) {\n accounts[account.id].metadata.name = this.getNextAvailableAccountName(\n account.metadata.keyring.type,\n namedAccounts,\n );\n // It has a name now, we need to re-use it when naming other accounts.\n namedAccounts.push(accounts[account.id]);\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts = accounts;\n\n if (\n !currentState.internalAccounts.accounts[\n currentState.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount = this.#getLastSelectedAccount(\n Object.values(accounts),\n );\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n\n /**\n * Loads the backup state of the accounts controller.\n *\n * @param backup - The backup state to load.\n */\n loadBackup(backup: AccountsControllerState): void {\n if (backup.internalAccounts) {\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts = backup.internalAccounts;\n });\n }\n }\n\n /**\n * Generates an internal account for a non-Snap account.\n * @param address - The address of the account.\n * @param keyringType - The keyring type for that account.\n * @returns The generated internal account.\n */\n #generateInternalAccountForNonSnapAccount(\n address: string,\n keyringType: string,\n ): InternalAccount {\n // Non-Snap accounts computes their account ID based on their address (in a\n // deterministic way).\n const id = getUUIDFromAddressOfNormalAccount(address);\n // If the account does not exist yet, metadata will use all default values.\n const account = this.getAccount(id);\n const metadata = this.#getAccountMetadataOrDefaults(\n keyringType,\n account?.metadata,\n );\n\n return {\n id,\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n // Normal accounts are all EOA.\n type: EthAccountType.Eoa,\n // And EOA accounts are compatible on every EVM chains, so use the namespace here.\n scopes: [EthScopes.Namespace],\n metadata: {\n ...metadata,\n keyring: {\n type: keyringType,\n },\n },\n };\n }\n\n /**\n * Gets the Snap keyring if it is available.\n *\n * @returns The Snap keyring if available, undefined otherwise.\n */\n #getSnapKeyring(): SnapKeyring {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n\n return snapKeyring as SnapKeyring;\n }\n\n /**\n * Gets the keyring associated to an account's address.\n *\n * @param address - Account's address.\n * @returns A promise that resolves to the associated keyring.\n */\n async #getKeyringForAccount<KeyringType = Keyring<Json>>(\n address: string,\n ): Promise<KeyringType> {\n const keyring = await this.messagingSystem.call(\n 'KeyringController:getKeyringForAccount',\n address,\n );\n\n return keyring as KeyringType;\n }\n\n /**\n * Gets the address of all accounts.\n *\n * @returns A promise that resolves to the list of account addresses.\n */\n async #getAccountAddresses(): Promise<string[]> {\n return await this.messagingSystem.call('KeyringController:getAccounts');\n }\n\n /**\n * Gets account's metadata with default values when not already defined.\n *\n * @param keyringType - The account keyring type.\n * @param metadata - The account's metadata (if defined).\n * @returns The account's metadata with default values when not already defined.\n */\n #getAccountMetadataOrDefaults(\n keyringType: string,\n metadata?: InternalAccount['metadata'],\n ): InternalAccount['metadata'] {\n return {\n // Expand the account's metadata first, and then adds default if they are not\n // defined.\n ...metadata,\n\n name: metadata?.name ?? '', // This will be renamed by `updateAccounts` if empty.\n keyring: {\n type: keyringType,\n },\n importTime: metadata?.importTime ?? Date.now(),\n lastSelected: metadata?.lastSelected ?? 0, // This means the account has never been selected yet.\n };\n }\n\n /**\n * Returns a list of internal accounts created using the Snap keyring.\n *\n * @returns A promise that resolves to an array of InternalAccount objects.\n */\n async #listAccountsFromSnapKeyring(): Promise<InternalAccount[]> {\n const snapKeyring = this.#getSnapKeyring();\n\n // Snap keyring is not available until the first account is created in the keyring controller\n if (!snapKeyring) {\n return [];\n }\n\n return snapKeyring.listAccounts();\n }\n\n /**\n * Returns a list of normal accounts.\n * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.\n * Once all keyrings implement the InternalAccount interface, this method can be removed and getAccounts can be used instead.\n *\n * @returns A Promise that resolves to an array of InternalAccount objects.\n */\n async #listAccountsFromOtherKeyrings(): Promise<InternalAccount[]> {\n const internalAccounts: InternalAccount[] = [];\n\n for (const address of await this.#getAccountAddresses()) {\n const keyring = await this.#getKeyringForAccount(address);\n\n if (!isNormalKeyringType(keyring.type as KeyringTypes)) {\n // We only consider \"normal accounts\" here, so keep looping.\n continue;\n }\n\n internalAccounts.push(\n this.#generateInternalAccountForNonSnapAccount(\n address,\n // The keyring type can either be \"Simple\" or \"HD\" here.\n keyring.type,\n ),\n );\n }\n\n return internalAccounts;\n }\n\n /**\n * Handles changes in the keyring state, specifically when new accounts are added or removed.\n *\n * @param keyringState - The new state of the keyring controller.\n */\n #handleOnKeyringStateChange(keyringState: KeyringControllerState): void {\n // check if there are any new accounts added\n // TODO: change when accountAdded event is added to the keyring controller\n\n // We check for keyrings length to be greater than 0 because the extension client may try execute\n // submit password twice and clear the keyring state.\n // https://github.com/MetaMask/KeyringController/blob/2d73a4deed8d013913f6ef0c9f5c0bb7c614f7d3/src/KeyringController.ts#L910\n if (keyringState.isUnlocked && keyringState.keyrings.length > 0) {\n const updatedNormalKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n const updatedSnapKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n\n for (const keyring of keyringState.keyrings) {\n if (keyring.type === KeyringTypes.snap) {\n updatedSnapKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n } else {\n updatedNormalKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n }\n }\n\n const { previousNormalInternalAccounts, previousSnapInternalAccounts } =\n this.listMultichainAccounts().reduce(\n (accumulator, account) => {\n if (account.metadata.keyring.type === KeyringTypes.snap) {\n accumulator.previousSnapInternalAccounts.push(account);\n } else {\n accumulator.previousNormalInternalAccounts.push(account);\n }\n return accumulator;\n },\n {\n previousNormalInternalAccounts: [] as InternalAccount[],\n previousSnapInternalAccounts: [] as InternalAccount[],\n },\n );\n\n const addedAccounts: AddressAndKeyringTypeObject[] = [];\n const deletedAccounts: InternalAccount[] = [];\n\n // Snap account IDs are random UUIDs while normal accounts\n // are determininistic based on the address.\n\n // ^NOTE: This will be removed when normal accounts also implement internal accounts\n // finding all the normal accounts that were added\n for (const account of updatedNormalKeyringAddresses) {\n if (\n !this.state.internalAccounts.accounts[\n getUUIDFromAddressOfNormalAccount(account.address)\n ]\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were added\n for (const account of updatedSnapKeyringAddresses) {\n if (\n !previousSnapInternalAccounts.find(\n (internalAccount: InternalAccount) =>\n internalAccount.address.toLowerCase() ===\n account.address.toLowerCase(),\n )\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the normal accounts that were deleted\n for (const account of previousNormalInternalAccounts) {\n if (\n !updatedNormalKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were deleted\n for (const account of previousSnapInternalAccounts) {\n if (\n !updatedSnapKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n if (deletedAccounts.length > 0) {\n for (const account of deletedAccounts) {\n currentState.internalAccounts.accounts = this.#handleAccountRemoved(\n currentState.internalAccounts.accounts,\n account.id,\n );\n }\n }\n\n if (addedAccounts.length > 0) {\n for (const account of addedAccounts) {\n currentState.internalAccounts.accounts =\n this.#handleNewAccountAdded(\n currentState.internalAccounts.accounts,\n account,\n );\n }\n }\n\n // We don't use list accounts because it is not the updated state yet.\n const existingAccounts = Object.values(\n currentState.internalAccounts.accounts,\n );\n\n // handle if the selected account was deleted\n if (\n !currentState.internalAccounts.accounts[\n this.state.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount =\n this.#getLastSelectedAccount(existingAccounts);\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n }\n\n /**\n * Handles the change in SnapControllerState by updating the metadata of accounts that have a snap enabled.\n *\n * @param snapState - The new SnapControllerState.\n */\n #handleOnSnapStateChange(snapState: SnapControllerState) {\n // only check if snaps changed in status\n const { snaps } = snapState;\n const accounts = this.listMultichainAccounts().filter(\n (account) => account.metadata.snap,\n );\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n accounts.forEach((account) => {\n const currentAccount =\n currentState.internalAccounts.accounts[account.id];\n if (currentAccount.metadata.snap) {\n const snapId = currentAccount.metadata.snap.id;\n const storedSnap: Snap = snaps[snapId as SnapId];\n if (storedSnap) {\n currentAccount.metadata.snap.enabled =\n storedSnap.enabled && !storedSnap.blocked;\n }\n }\n });\n });\n }\n\n /**\n * Returns the list of accounts for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Accounts to filter by keyring type.\n * @returns The list of accounts associcated with this keyring type.\n */\n #getAccountsByKeyringType(keyringType: string, accounts?: InternalAccount[]) {\n return (accounts ?? this.listMultichainAccounts()).filter(\n (internalAccount) => {\n // We do consider `hd` and `simple` keyrings to be of same type. So we check those 2 types\n // to group those accounts together!\n if (\n keyringType === KeyringTypes.hd ||\n keyringType === KeyringTypes.simple\n ) {\n return (\n internalAccount.metadata.keyring.type === KeyringTypes.hd ||\n internalAccount.metadata.keyring.type === KeyringTypes.simple\n );\n }\n\n return internalAccount.metadata.keyring.type === keyringType;\n },\n );\n }\n\n /**\n * Returns the last selected account from the given array of accounts.\n *\n * @param accounts - An array of InternalAccount objects.\n * @returns The InternalAccount object that was last selected, or undefined if the array is empty.\n */\n #getLastSelectedAccount(\n accounts: InternalAccount[],\n ): InternalAccount | undefined {\n const [accountToSelect] = accounts.sort((accountA, accountB) => {\n // sort by lastSelected descending\n return (\n (accountB.metadata.lastSelected ?? 0) -\n (accountA.metadata.lastSelected ?? 0)\n );\n });\n\n return accountToSelect;\n }\n\n /**\n * Returns the next account number for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Existing accounts to check for the next available account number.\n * @returns An object containing the account prefix and index to use.\n */\n getNextAvailableAccountName(\n keyringType: string = KeyringTypes.hd,\n accounts?: InternalAccount[],\n ): string {\n const keyringName = keyringTypeToName(keyringType);\n const keyringAccounts = this.#getAccountsByKeyringType(\n keyringType,\n accounts,\n );\n const lastDefaultIndexUsedForKeyringType = keyringAccounts.reduce(\n (maxInternalAccountIndex, internalAccount) => {\n // We **DO NOT USE** `\\d+` here to only consider valid \"human\"\n // number (rounded decimal number)\n const match = new RegExp(`${keyringName} ([0-9]+)$`, 'u').exec(\n internalAccount.metadata.name,\n );\n\n if (match) {\n // Quoting `RegExp.exec` documentation:\n // > The returned array has the matched text as the first item, and then one item for\n // > each capturing group of the matched text.\n // So use `match[1]` to get the captured value\n const internalAccountIndex = parseInt(match[1], 10);\n return Math.max(maxInternalAccountIndex, internalAccountIndex);\n }\n\n return maxInternalAccountIndex;\n },\n 0,\n );\n\n const index = Math.max(\n keyringAccounts.length + 1,\n // ESLint is confused; this is a number.\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n lastDefaultIndexUsedForKeyringType + 1,\n );\n\n return `${keyringName} ${index}`;\n }\n\n /**\n * Checks if an account is compatible with a given chain namespace.\n * @private\n * @param account - The account to check compatibility for.\n * @param chainId - The CAIP2 to check compatibility with.\n * @returns Returns true if the account is compatible with the chain namespace, otherwise false.\n */\n #isAccountCompatibleWithChain(\n account: InternalAccount,\n chainId: CaipChainId,\n ): boolean {\n // TODO: Change this logic to not use account's type\n // Because we currently only use type, we can only use namespace for now.\n return account.type.startsWith(parseCaipChainId(chainId).namespace);\n }\n\n /**\n * Retrieves the index value for `metadata.lastSelected`.\n *\n * @returns The index value.\n */\n #getLastSelectedIndex() {\n // NOTE: For now we use the current date, since we know this value\n // will always be higher than any already selected account index.\n return Date.now();\n }\n\n /**\n * Handles the addition of a new account to the controller.\n * If the account is not a Snap Keyring account, generates an internal account for it and adds it to the controller.\n * If the account is a Snap Keyring account, retrieves the account from the keyring and adds it to the controller.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param account - The address and keyring type object of the new account.\n * @returns The updated AccountsController accounts state.\n */\n #handleNewAccountAdded(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n account: AddressAndKeyringTypeObject,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n let newAccount: InternalAccount;\n if (account.type !== KeyringTypes.snap) {\n newAccount = this.#generateInternalAccountForNonSnapAccount(\n account.address,\n account.type,\n );\n } else {\n const snapKeyring = this.#getSnapKeyring();\n\n newAccount = snapKeyring.getAccountByAddress(\n account.address,\n ) as InternalAccount;\n\n // The snap deleted the account before the keyring controller could add it\n if (!newAccount) {\n return accountsState;\n }\n }\n\n const isFirstAccount = Object.keys(accountsState).length === 0;\n\n // Get next account name available for this given keyring\n const accountName = this.getNextAvailableAccountName(\n newAccount.metadata.keyring.type,\n Object.values(accountsState),\n );\n\n const newAccountWithUpdatedMetadata = {\n ...newAccount,\n metadata: {\n ...newAccount.metadata,\n name: accountName,\n importTime: Date.now(),\n lastSelected: isFirstAccount ? this.#getLastSelectedIndex() : 0,\n },\n };\n accountsState[newAccount.id] = newAccountWithUpdatedMetadata;\n\n this.messagingSystem.publish(\n 'AccountsController:accountAdded',\n newAccountWithUpdatedMetadata,\n );\n\n return accountsState;\n }\n\n #publishAccountChangeEvent(account: InternalAccount) {\n if (isEvmAccountType(account.type)) {\n this.messagingSystem.publish(\n 'AccountsController:selectedEvmAccountChange',\n account,\n );\n }\n this.messagingSystem.publish(\n 'AccountsController:selectedAccountChange',\n account,\n );\n }\n\n /**\n * Handles the removal of an account from the internal accounts list.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param accountId - The ID of the account to be removed.\n * @returns The updated AccountsController state.\n */\n #handleAccountRemoved(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n accountId: string,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n delete accountsState[accountId];\n\n this.messagingSystem.publish(\n 'AccountsController:accountRemoved',\n accountId,\n );\n\n return accountsState;\n }\n\n /**\n * Registers message handlers for the AccountsController.\n * @private\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccount`,\n this.setSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listAccounts`,\n this.listAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listMultichainAccounts`,\n this.listMultichainAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setAccountName`,\n this.setAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateAccounts`,\n this.updateAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccount`,\n this.getSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedMultichainAccount`,\n this.getSelectedMultichainAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountByAddress`,\n this.getAccountByAddress.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getNextAvailableAccountName`,\n this.getNextAvailableAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:getAccount`,\n this.getAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:updateAccountMetadata`,\n this.updateAccountMetadata.bind(this),\n );\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AccountsController.d.cts","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC9B,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,EACL,cAAc,EAEd,SAAS,EAEV,8BAA8B;AAE/B,OAAO,KAAK,EAEV,2CAA2C,EAC3C,wCAAwC,EACxC,kCAAkC,EAClC,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAEV,eAAe,EAChB,oCAAoC;AAGrC,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB;AAenD,QAAA,MAAM,cAAc,uBAAuB,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC7C,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,wBAAwB,CACrE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,GAAG,OAAO,cAAc,qBAAqB,CAAC;IACpD,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,sCAAsC,GAAG;IACnD,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,GAAG,OAAO,cAAc,eAAe,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,8CAA8C,GAAG;IAC3D,IAAI,EAAE,GAAG,OAAO,cAAc,yBAAyB,CAAC;IACxD,OAAO,EAAE,kBAAkB,CAAC,wBAAwB,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,sCAAsC,GAAG;IACnD,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,GAAG,OAAO,cAAc,qBAAqB,CAAC;IACpD,OAAO,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,oDAAoD,GAAG;IACjE,IAAI,EAAE,GAAG,OAAO,cAAc,+BAA+B,CAAC;IAC9D,OAAO,EAAE,kBAAkB,CAAC,8BAA8B,CAAC,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,GAAG,OAAO,cAAc,sBAAsB,CAAC;IACrD,OAAO,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,GAAG,OAAO,cAAc,8BAA8B,CAAC;IAC7D,OAAO,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,GAAG,OAAO,cAAc,aAAa,CAAC;IAC5C,OAAO,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,GAAG,OAAO,cAAc,wBAAwB,CAAC;IACvD,OAAO,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,wCAAwC,GACxC,kCAAkC,CAAC;AAEvC,MAAM,MAAM,yBAAyB,GACjC,gCAAgC,GAChC,0CAA0C,GAC1C,oCAAoC,GACpC,8CAA8C,GAC9C,sCAAsC,GACtC,sCAAsC,GACtC,2CAA2C,GAC3C,0CAA0C,GAC1C,mDAAmD,GACnD,kCAAkC,GAClC,oDAAoD,GACpD,6CAA6C,CAAC;AAElD,MAAM,MAAM,6BAA6B,GAAG,0BAA0B,CACpE,OAAO,cAAc,EACrB,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,GAAG,OAAO,cAAc,wBAAwB,CAAC;IACvD,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,GAAG,OAAO,cAAc,2BAA2B,CAAC;IAC1D,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,IAAI,EAAE,GAAG,OAAO,cAAc,eAAe,CAAC;IAC9C,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,GAAG,OAAO,cAAc,iBAAiB,CAAC;IAChD,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,iCAAiC,CAAC;AAEhF,MAAM,MAAM,wBAAwB,GAChC,6BAA6B,GAC7B,4CAA4C,GAC5C,+CAA+C,GAC/C,mCAAmC,GACnC,qCAAqC,GACrC,qCAAqC,CAAC;AAE1C,MAAM,MAAM,2BAA2B,GAAG,6BAA6B,CACrE,OAAO,cAAc,EACrB,yBAAyB,GAAG,cAAc,EAC1C,wBAAwB,GAAG,aAAa,EACxC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAqBF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;CAczB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,cAAc,CACpD,OAAO,cAAc,EACrB,uBAAuB,EACvB,2BAA2B,CAC5B;;IACC;;;;;;OAMG;gBACS,EACV,SAAS,EACT,KAAK,GACN,EAAE;QACD,SAAS,EAAE,2BAA2B,CAAC;QACvC,KAAK,EAAE,uBAAuB,CAAC;KAChC;IAwBD;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1D;;;;OAIG;IACH,YAAY,IAAI,eAAe,EAAE;IAKjC;;;;;OAKG;IACH,sBAAsB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,eAAe,EAAE;IAehE;;;;;;OAMG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe;IAQpD;;;;OAIG;IACH,kBAAkB,IAAI,eAAe;IA0BrC;;;;;;;OAOG;IACH,4BAA4B,CAC1B,OAAO,CAAC,EAAE,WAAW,GACpB,eAAe,GAAG,SAAS;IAsB9B;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAMjE;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAY3C;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAS5D;;;;;OAKG;IACH,qBAAqB,CACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,GAC7C,IAAI;IAiCP;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAyErC;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAoWjD;;;;;OAKG;IACH,2BAA2B,CACzB,WAAW,GAAE,MAAwB,EACrC,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,MAAM;CA6OV"}
1
+ {"version":3,"file":"AccountsController.d.cts","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AccountsController.d.mts","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AccountsController.d.mts","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
3
  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");
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _AccountsController_instances, _AccountsController_generateInternalAccountForNonSnapAccount, _AccountsController_listSnapAccounts, _AccountsController_listNormalAccounts, _AccountsController_handleOnKeyringStateChange, _AccountsController_handleOnSnapStateChange, _AccountsController_getAccountsByKeyringType, _AccountsController_getLastSelectedAccount, _AccountsController_isAccountCompatibleWithChain, _AccountsController_getLastSelectedIndex, _AccountsController_handleNewAccountAdded, _AccountsController_publishAccountChangeEvent, _AccountsController_handleAccountRemoved, _AccountsController_populateExistingMetadata, _AccountsController_registerMessageHandlers;
6
+ var _AccountsController_instances, _AccountsController_generateInternalAccountForNonSnapAccount, _AccountsController_getSnapKeyring, _AccountsController_getKeyringForAccount, _AccountsController_getAccountAddresses, _AccountsController_getAccountMetadataOrDefaults, _AccountsController_listAccountsFromSnapKeyring, _AccountsController_listAccountsFromOtherKeyrings, _AccountsController_handleOnKeyringStateChange, _AccountsController_handleOnSnapStateChange, _AccountsController_getAccountsByKeyringType, _AccountsController_getLastSelectedAccount, _AccountsController_isAccountCompatibleWithChain, _AccountsController_getLastSelectedIndex, _AccountsController_handleNewAccountAdded, _AccountsController_publishAccountChangeEvent, _AccountsController_handleAccountRemoved, _AccountsController_registerMessageHandlers;
7
7
  import { BaseController } from "@metamask/base-controller";
8
8
  import { SnapKeyring } from "@metamask/eth-snap-keyring";
9
9
  import { EthAccountType, EthMethod, EthScopes, isEvmAccountType } from "@metamask/keyring-api";
@@ -236,37 +236,66 @@ export class AccountsController extends BaseController {
236
236
  * @returns A Promise that resolves when the accounts have been updated.
237
237
  */
238
238
  async updateAccounts() {
239
- const snapAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listSnapAccounts).call(this);
240
- const normalAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listNormalAccounts).call(this);
241
- // keyring type map.
242
- const keyringTypes = new Map();
243
- const previousAccounts = this.state.internalAccounts.accounts;
244
- const accounts = [
245
- ...normalAccounts,
246
- ...snapAccounts,
247
- ].reduce((internalAccountMap, internalAccount) => {
248
- const keyringTypeName = keyringTypeToName(internalAccount.metadata.keyring.type);
249
- const keyringAccountIndex = keyringTypes.get(keyringTypeName) ?? 0;
250
- if (keyringAccountIndex) {
251
- keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);
239
+ // We are re-creating the list of internal accounts based on the accounts from
240
+ // each keyrings, following those rules:
241
+ //
242
+ // - If the account already exists on this controller state, we only update
243
+ // metadata. This allows to automatically "migrate" new metadata for existing
244
+ // accounts.
245
+ //
246
+ // - Else, we create the associated internal account for that new account. This
247
+ // can happen when the Snap keyring adds a new account. The Snap keyring will
248
+ // create a new account and will automatically "persists" by calling this
249
+ // function explicitly to create its associated internal account.
250
+ //
251
+ // FIXME: This logic is kinda tricky and could be replaced with the new
252
+ // incoming notification system that the Snap keyring will use.
253
+ const snapAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listAccountsFromSnapKeyring).call(this);
254
+ const normalAccounts = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listAccountsFromOtherKeyrings).call(this);
255
+ // Keep track of unnamed account to rename them after.
256
+ const namedAccounts = [];
257
+ const unnamedAccounts = [];
258
+ // Compute the updated list of internal accounts:
259
+ const accounts = {};
260
+ for (const keyringInternalAccount of [...normalAccounts, ...snapAccounts]) {
261
+ const { id } = keyringInternalAccount;
262
+ const internalAccount = this.state.internalAccounts.accounts[id];
263
+ if (internalAccount) {
264
+ // The account already exist, we're just updating the metadata.
265
+ const { metadata } = internalAccount;
266
+ accounts[id] = {
267
+ ...internalAccount,
268
+ metadata: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, metadata.keyring.type, metadata),
269
+ };
252
270
  }
253
271
  else {
254
- keyringTypes.set(keyringTypeName, 1);
272
+ // The account does not exist yet on this controller. We create a new
273
+ // internal account now using the internal account created from
274
+ // the keyring account.
275
+ const { metadata } = keyringInternalAccount;
276
+ accounts[id] = {
277
+ ...keyringInternalAccount,
278
+ metadata: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, metadata.keyring.type, metadata),
279
+ };
255
280
  }
256
- const existingAccount = previousAccounts[internalAccount.id];
257
- internalAccountMap[internalAccount.id] = {
258
- ...internalAccount,
259
- metadata: {
260
- ...internalAccount.metadata,
261
- name: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'name') ??
262
- `${keyringTypeName} ${keyringAccountIndex + 1}`,
263
- importTime: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'importTime') ??
264
- Date.now(),
265
- lastSelected: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, existingAccount?.id, 'lastSelected') ?? 0,
266
- },
267
- };
268
- return internalAccountMap;
269
- }, {});
281
+ // If the account has no name yet, we mark it and we'll rename it afterward once
282
+ // we have re-created the full state.
283
+ if (accounts[id].metadata.name === '') {
284
+ unnamedAccounts.push(accounts[id]);
285
+ }
286
+ else {
287
+ // It's important to track named accounts too since the
288
+ // `getNextAvailableAccountname` will use the highest index possible
289
+ // based on account's names.
290
+ namedAccounts.push(accounts[id]);
291
+ }
292
+ }
293
+ // Now, we can rename each accounts according to our naming rule.
294
+ for (const account of unnamedAccounts) {
295
+ accounts[account.id].metadata.name = this.getNextAvailableAccountName(account.metadata.keyring.type, namedAccounts);
296
+ // It has a name now, we need to re-use it when naming other accounts.
297
+ namedAccounts.push(accounts[account.id]);
298
+ }
270
299
  this.update((currentState) => {
271
300
  currentState.internalAccounts.accounts = accounts;
272
301
  if (!currentState.internalAccounts.accounts[currentState.internalAccounts.selectedAccount]) {
@@ -326,9 +355,15 @@ export class AccountsController extends BaseController {
326
355
  return `${keyringName} ${index}`;
327
356
  }
328
357
  }
329
- _AccountsController_instances = new WeakSet(), _AccountsController_generateInternalAccountForNonSnapAccount = function _AccountsController_generateInternalAccountForNonSnapAccount(address, type) {
358
+ _AccountsController_instances = new WeakSet(), _AccountsController_generateInternalAccountForNonSnapAccount = function _AccountsController_generateInternalAccountForNonSnapAccount(address, keyringType) {
359
+ // Non-Snap accounts computes their account ID based on their address (in a
360
+ // deterministic way).
361
+ const id = getUUIDFromAddressOfNormalAccount(address);
362
+ // If the account does not exist yet, metadata will use all default values.
363
+ const account = this.getAccount(id);
364
+ const metadata = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountMetadataOrDefaults).call(this, keyringType, account?.metadata);
330
365
  return {
331
- id: getUUIDFromAddressOfNormalAccount(address),
366
+ id,
332
367
  address,
333
368
  options: {},
334
369
  methods: [
@@ -339,31 +374,64 @@ _AccountsController_instances = new WeakSet(), _AccountsController_generateInter
339
374
  EthMethod.SignTypedDataV3,
340
375
  EthMethod.SignTypedDataV4,
341
376
  ],
342
- scopes: [EthScopes.Namespace],
377
+ // Normal accounts are all EOA.
343
378
  type: EthAccountType.Eoa,
379
+ // And EOA accounts are compatible on every EVM chains, so use the namespace here.
380
+ scopes: [EthScopes.Namespace],
344
381
  metadata: {
345
- name: '',
346
- importTime: Date.now(),
382
+ ...metadata,
347
383
  keyring: {
348
- type,
384
+ type: keyringType,
349
385
  },
350
386
  },
351
387
  };
352
- }, _AccountsController_listSnapAccounts =
388
+ }, _AccountsController_getSnapKeyring = function _AccountsController_getSnapKeyring() {
389
+ const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', SnapKeyring.type);
390
+ return snapKeyring;
391
+ }, _AccountsController_getKeyringForAccount =
353
392
  /**
354
- * Returns a list of internal accounts created using the SnapKeyring.
393
+ * Gets the keyring associated to an account's address.
394
+ *
395
+ * @param address - Account's address.
396
+ * @returns A promise that resolves to the associated keyring.
397
+ */
398
+ async function _AccountsController_getKeyringForAccount(address) {
399
+ const keyring = await this.messagingSystem.call('KeyringController:getKeyringForAccount', address);
400
+ return keyring;
401
+ }, _AccountsController_getAccountAddresses =
402
+ /**
403
+ * Gets the address of all accounts.
404
+ *
405
+ * @returns A promise that resolves to the list of account addresses.
406
+ */
407
+ async function _AccountsController_getAccountAddresses() {
408
+ return await this.messagingSystem.call('KeyringController:getAccounts');
409
+ }, _AccountsController_getAccountMetadataOrDefaults = function _AccountsController_getAccountMetadataOrDefaults(keyringType, metadata) {
410
+ return {
411
+ // Expand the account's metadata first, and then adds default if they are not
412
+ // defined.
413
+ ...metadata,
414
+ name: metadata?.name ?? '',
415
+ keyring: {
416
+ type: keyringType,
417
+ },
418
+ importTime: metadata?.importTime ?? Date.now(),
419
+ lastSelected: metadata?.lastSelected ?? 0, // This means the account has never been selected yet.
420
+ };
421
+ }, _AccountsController_listAccountsFromSnapKeyring =
422
+ /**
423
+ * Returns a list of internal accounts created using the Snap keyring.
355
424
  *
356
425
  * @returns A promise that resolves to an array of InternalAccount objects.
357
426
  */
358
- async function _AccountsController_listSnapAccounts() {
359
- const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', SnapKeyring.type);
360
- // snap keyring is not available until the first account is created in the keyring controller
427
+ async function _AccountsController_listAccountsFromSnapKeyring() {
428
+ const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
429
+ // Snap keyring is not available until the first account is created in the keyring controller
361
430
  if (!snapKeyring) {
362
431
  return [];
363
432
  }
364
- const snapAccounts = snapKeyring.listAccounts();
365
- return snapAccounts;
366
- }, _AccountsController_listNormalAccounts =
433
+ return snapKeyring.listAccounts();
434
+ }, _AccountsController_listAccountsFromOtherKeyrings =
367
435
  /**
368
436
  * Returns a list of normal accounts.
369
437
  * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.
@@ -371,42 +439,17 @@ async function _AccountsController_listSnapAccounts() {
371
439
  *
372
440
  * @returns A Promise that resolves to an array of InternalAccount objects.
373
441
  */
374
- async function _AccountsController_listNormalAccounts() {
375
- const addresses = await this.messagingSystem.call('KeyringController:getAccounts');
442
+ async function _AccountsController_listAccountsFromOtherKeyrings() {
376
443
  const internalAccounts = [];
377
- for (const address of addresses) {
378
- const keyring = await this.messagingSystem.call('KeyringController:getKeyringForAccount', address);
379
- const keyringType = keyring.type;
380
- if (!isNormalKeyringType(keyringType)) {
381
- // We only consider "normal accounts" here, so keep looping
444
+ for (const address of await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountAddresses).call(this)) {
445
+ const keyring = await __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getKeyringForAccount).call(this, address);
446
+ if (!isNormalKeyringType(keyring.type)) {
447
+ // We only consider "normal accounts" here, so keep looping.
382
448
  continue;
383
449
  }
384
- const id = getUUIDFromAddressOfNormalAccount(address);
385
- const nameLastUpdatedAt = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'nameLastUpdatedAt');
386
- internalAccounts.push({
387
- id,
388
- address,
389
- options: {},
390
- methods: [
391
- EthMethod.PersonalSign,
392
- EthMethod.Sign,
393
- EthMethod.SignTransaction,
394
- EthMethod.SignTypedDataV1,
395
- EthMethod.SignTypedDataV3,
396
- EthMethod.SignTypedDataV4,
397
- ],
398
- scopes: [EthScopes.Namespace],
399
- type: EthAccountType.Eoa,
400
- metadata: {
401
- name: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'name') ?? '',
402
- ...(nameLastUpdatedAt && { nameLastUpdatedAt }),
403
- importTime: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'importTime') ?? Date.now(),
404
- lastSelected: __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_populateExistingMetadata).call(this, id, 'lastSelected') ?? 0,
405
- keyring: {
406
- type: keyring.type,
407
- },
408
- },
409
- });
450
+ internalAccounts.push(__classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_generateInternalAccountForNonSnapAccount).call(this, address,
451
+ // The keyring type can either be "Simple" or "HD" here.
452
+ keyring.type));
410
453
  }
411
454
  return internalAccounts;
412
455
  }, _AccountsController_handleOnKeyringStateChange = function _AccountsController_handleOnKeyringStateChange(keyringState) {
@@ -450,8 +493,8 @@ async function _AccountsController_listNormalAccounts() {
450
493
  });
451
494
  const addedAccounts = [];
452
495
  const deletedAccounts = [];
453
- // snap account ids are random uuid while normal accounts
454
- // are determininistic based on the address
496
+ // Snap account IDs are random UUIDs while normal accounts
497
+ // are determininistic based on the address.
455
498
  // ^NOTE: This will be removed when normal accounts also implement internal accounts
456
499
  // finding all the normal accounts that were added
457
500
  for (const account of updatedNormalKeyringAddresses) {
@@ -557,7 +600,7 @@ async function _AccountsController_listNormalAccounts() {
557
600
  newAccount = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_generateInternalAccountForNonSnapAccount).call(this, account.address, account.type);
558
601
  }
559
602
  else {
560
- const [snapKeyring] = this.messagingSystem.call('KeyringController:getKeyringsByType', SnapKeyring.type);
603
+ const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
561
604
  newAccount = snapKeyring.getAccountByAddress(account.address);
562
605
  // The snap deleted the account before the keyring controller could add it
563
606
  if (!newAccount) {
@@ -588,9 +631,6 @@ async function _AccountsController_listNormalAccounts() {
588
631
  delete accountsState[accountId];
589
632
  this.messagingSystem.publish('AccountsController:accountRemoved', accountId);
590
633
  return accountsState;
591
- }, _AccountsController_populateExistingMetadata = function _AccountsController_populateExistingMetadata(accountId, metadataKey, account) {
592
- const internalAccount = account ?? this.getAccount(accountId);
593
- return internalAccount ? internalAccount.metadata[metadataKey] : undefined;
594
634
  }, _AccountsController_registerMessageHandlers = function _AccountsController_registerMessageHandlers() {
595
635
  this.messagingSystem.registerActionHandler(`${controllerName}:setSelectedAccount`, this.setSelectedAccount.bind(this));
596
636
  this.messagingSystem.registerActionHandler(`${controllerName}:listAccounts`, this.listAccounts.bind(this));
@@ -1 +1 @@
1
- {"version":3,"file":"AccountsController.mjs","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n EthAccountType,\n EthMethod,\n EthScopes,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n KeyringControllerState,\n KeyringControllerGetKeyringForAccountAction,\n KeyringControllerGetKeyringsByTypeAction,\n KeyringControllerGetAccountsAction,\n KeyringControllerStateChangeEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n SnapControllerState,\n SnapStateChange,\n} from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { Snap } from '@metamask/snaps-utils';\nimport type { CaipChainId } from '@metamask/utils';\nimport {\n type Keyring,\n type Json,\n isCaipChainId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n getUUIDFromAddressOfNormalAccount,\n isNormalKeyringType,\n keyringTypeToName,\n} from './utils';\n\nconst controllerName = 'AccountsController';\n\nexport type AccountId = string;\n\nexport type AccountsControllerState = {\n internalAccounts: {\n accounts: Record<AccountId, InternalAccount>;\n selectedAccount: string; // id of the selected account\n };\n};\n\nexport type AccountsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSetSelectedAccountAction = {\n type: `${typeof controllerName}:setSelectedAccount`;\n handler: AccountsController['setSelectedAccount'];\n};\n\nexport type AccountsControllerSetAccountNameAction = {\n type: `${typeof controllerName}:setAccountName`;\n handler: AccountsController['setAccountName'];\n};\n\nexport type AccountsControllerListAccountsAction = {\n type: `${typeof controllerName}:listAccounts`;\n handler: AccountsController['listAccounts'];\n};\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `${typeof controllerName}:listMultichainAccounts`;\n handler: AccountsController['listMultichainAccounts'];\n};\n\nexport type AccountsControllerUpdateAccountsAction = {\n type: `${typeof controllerName}:updateAccounts`;\n handler: AccountsController['updateAccounts'];\n};\n\nexport type AccountsControllerGetSelectedAccountAction = {\n type: `${typeof controllerName}:getSelectedAccount`;\n handler: AccountsController['getSelectedAccount'];\n};\n\nexport type AccountsControllerGetSelectedMultichainAccountAction = {\n type: `${typeof controllerName}:getSelectedMultichainAccount`;\n handler: AccountsController['getSelectedMultichainAccount'];\n};\n\nexport type AccountsControllerGetAccountByAddressAction = {\n type: `${typeof controllerName}:getAccountByAddress`;\n handler: AccountsController['getAccountByAddress'];\n};\n\nexport type AccountsControllerGetNextAvailableAccountNameAction = {\n type: `${typeof controllerName}:getNextAvailableAccountName`;\n handler: AccountsController['getNextAvailableAccountName'];\n};\n\nexport type AccountsControllerGetAccountAction = {\n type: `${typeof controllerName}:getAccount`;\n handler: AccountsController['getAccount'];\n};\n\nexport type AccountsControllerUpdateAccountMetadataAction = {\n type: `${typeof controllerName}:updateAccountMetadata`;\n handler: AccountsController['updateAccountMetadata'];\n};\n\nexport type AllowedActions =\n | KeyringControllerGetKeyringForAccountAction\n | KeyringControllerGetKeyringsByTypeAction\n | KeyringControllerGetAccountsAction;\n\nexport type AccountsControllerActions =\n | AccountsControllerGetStateAction\n | AccountsControllerSetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerSetAccountNameAction\n | AccountsControllerUpdateAccountsAction\n | AccountsControllerGetAccountByAddressAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetNextAvailableAccountNameAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetSelectedMultichainAccountAction\n | AccountsControllerUpdateAccountMetadataAction;\n\nexport type AccountsControllerChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSelectedAccountChangeEvent = {\n type: `${typeof controllerName}:selectedAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerSelectedEvmAccountChangeEvent = {\n type: `${typeof controllerName}:selectedEvmAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountAddedEvent = {\n type: `${typeof controllerName}:accountAdded`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountRemovedEvent = {\n type: `${typeof controllerName}:accountRemoved`;\n payload: [AccountId];\n};\n\nexport type AccountsControllerAccountRenamedEvent = {\n type: `${typeof controllerName}:accountRenamed`;\n payload: [InternalAccount];\n};\n\nexport type AllowedEvents = SnapStateChange | KeyringControllerStateChangeEvent;\n\nexport type AccountsControllerEvents =\n | AccountsControllerChangeEvent\n | AccountsControllerSelectedAccountChangeEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountRenamedEvent;\n\nexport type AccountsControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AccountsControllerActions | AllowedActions,\n AccountsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype AddressAndKeyringTypeObject = {\n address: string;\n type: string;\n};\n\nconst accountsControllerMetadata = {\n internalAccounts: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst defaultState: AccountsControllerState = {\n internalAccounts: {\n accounts: {},\n selectedAccount: '',\n },\n};\n\nexport const EMPTY_ACCOUNT = {\n id: '',\n address: '',\n options: {},\n methods: [],\n type: EthAccountType.Eoa,\n scopes: [EthScopes.Namespace],\n metadata: {\n name: '',\n keyring: {\n type: '',\n },\n importTime: 0,\n },\n};\n\n/**\n * Controller that manages internal accounts.\n * The accounts controller is responsible for creating and managing internal accounts.\n * It also provides convenience methods for accessing and updating the internal accounts.\n * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.\n * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.\n *\n */\nexport class AccountsController extends BaseController<\n typeof controllerName,\n AccountsControllerState,\n AccountsControllerMessenger\n> {\n /**\n * Constructor for AccountsController.\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: AccountsControllerMessenger;\n state: AccountsControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountsControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.messagingSystem.subscribe(\n 'SnapController:stateChange',\n (snapStateState) => this.#handleOnSnapStateChange(snapStateState),\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:stateChange',\n (keyringState) => this.#handleOnKeyringStateChange(keyringState),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Returns the internal account object for the given account ID, if it exists.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object, or undefined if the account does not exist.\n */\n getAccount(accountId: string): InternalAccount | undefined {\n return this.state.internalAccounts.accounts[accountId];\n }\n\n /**\n * Returns an array of all evm internal accounts.\n *\n * @returns An array of InternalAccount objects.\n */\n listAccounts(): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n return accounts.filter((account) => isEvmAccountType(account.type));\n }\n\n /**\n * Returns an array of all internal accounts.\n *\n * @param chainId - The chain ID.\n * @returns An array of InternalAccount objects.\n */\n listMultichainAccounts(chainId?: CaipChainId): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n if (!chainId) {\n return accounts;\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${String(chainId)}`);\n }\n\n return accounts.filter((account) =>\n this.#isAccountCompatibleWithChain(account, chainId),\n );\n }\n\n /**\n * Returns the internal account object for the given account ID.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object.\n * @throws An error if the account ID is not found.\n */\n getAccountExpect(accountId: string): InternalAccount {\n const account = this.getAccount(accountId);\n if (account === undefined) {\n throw new Error(`Account Id \"${accountId}\" not found`);\n }\n return account;\n }\n\n /**\n * Returns the last selected EVM account.\n *\n * @returns The selected internal account.\n */\n getSelectedAccount(): InternalAccount {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n const selectedAccount = this.getAccountExpect(\n this.state.internalAccounts.selectedAccount,\n );\n if (isEvmAccountType(selectedAccount.type)) {\n return selectedAccount;\n }\n\n const accounts = this.listAccounts();\n\n if (!accounts.length) {\n // ! Should never reach this.\n throw new Error('No EVM accounts');\n }\n\n // This will never be undefined because we have already checked if accounts.length is > 0\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#getLastSelectedAccount(accounts)!;\n }\n\n /**\n * __WARNING The return value may be undefined if there isn't an account for that chain id.__\n *\n * Retrieves the last selected account by chain ID.\n *\n * @param chainId - The chain ID to filter the accounts.\n * @returns The last selected account compatible with the specified chain ID or undefined.\n */\n getSelectedMultichainAccount(\n chainId?: CaipChainId,\n ): InternalAccount | undefined {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n if (!chainId) {\n return this.getAccountExpect(this.state.internalAccounts.selectedAccount);\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${chainId as string}`);\n }\n\n const accounts = Object.values(this.state.internalAccounts.accounts).filter(\n (account) => this.#isAccountCompatibleWithChain(account, chainId),\n );\n\n return this.#getLastSelectedAccount(accounts);\n }\n\n /**\n * Returns the account with the specified address.\n * ! This method will only return the first account that matches the address\n * @param address - The address of the account to retrieve.\n * @returns The account with the specified address, or undefined if not found.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n return this.listMultichainAccounts().find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n );\n }\n\n /**\n * Sets the selected account by its ID.\n *\n * @param accountId - The ID of the account to be selected.\n */\n setSelectedAccount(accountId: string): void {\n const account = this.getAccountExpect(accountId);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts[account.id].metadata.lastSelected =\n Date.now();\n currentState.internalAccounts.selectedAccount = account.id;\n });\n\n this.#publishAccountChangeEvent(account);\n }\n\n /**\n * Sets the name of the account with the given ID.\n *\n * @param accountId - The ID of the account to set the name for.\n * @param accountName - The new name for the account.\n * @throws An error if an account with the same name already exists.\n */\n setAccountName(accountId: string, accountName: string): void {\n // This will check for name uniqueness and fire the `accountRenamed` event\n // if the account has been renamed.\n this.updateAccountMetadata(accountId, {\n name: accountName,\n nameLastUpdatedAt: Date.now(),\n });\n }\n\n /**\n * Updates the metadata of the account with the given ID.\n *\n * @param accountId - The ID of the account for which the metadata will be updated.\n * @param metadata - The new metadata for the account.\n */\n updateAccountMetadata(\n accountId: string,\n metadata: Partial<InternalAccount['metadata']>,\n ): void {\n const account = this.getAccountExpect(accountId);\n\n if (\n metadata.name &&\n this.listMultichainAccounts().find(\n (internalAccount) =>\n internalAccount.metadata.name === metadata.name &&\n internalAccount.id !== accountId,\n )\n ) {\n throw new Error('Account name already exists');\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n const internalAccount = {\n ...account,\n metadata: { ...account.metadata, ...metadata },\n };\n // Do not remove this comment - This error is flaky: Comment out or restore the `ts-expect-error` directive below as needed.\n // See: https://github.com/MetaMask/utils/issues/168\n // // @ts-expect-error Known issue - `Json` causes recursive error in immer `Draft`/`WritableDraft` types\n currentState.internalAccounts.accounts[accountId] = internalAccount;\n\n if (metadata.name) {\n this.messagingSystem.publish(\n 'AccountsController:accountRenamed',\n internalAccount,\n );\n }\n });\n }\n\n /**\n * Updates the internal accounts list by retrieving normal and snap accounts,\n * removing duplicates, and updating the metadata of each account.\n *\n * @returns A Promise that resolves when the accounts have been updated.\n */\n async updateAccounts(): Promise<void> {\n const snapAccounts = await this.#listSnapAccounts();\n const normalAccounts = await this.#listNormalAccounts();\n\n // keyring type map.\n const keyringTypes = new Map<string, number>();\n const previousAccounts = this.state.internalAccounts.accounts;\n\n const accounts: Record<string, InternalAccount> = [\n ...normalAccounts,\n ...snapAccounts,\n ].reduce((internalAccountMap, internalAccount) => {\n const keyringTypeName = keyringTypeToName(\n internalAccount.metadata.keyring.type,\n );\n const keyringAccountIndex = keyringTypes.get(keyringTypeName) ?? 0;\n if (keyringAccountIndex) {\n keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);\n } else {\n keyringTypes.set(keyringTypeName, 1);\n }\n\n const existingAccount = previousAccounts[internalAccount.id];\n\n internalAccountMap[internalAccount.id] = {\n ...internalAccount,\n\n metadata: {\n ...internalAccount.metadata,\n name:\n this.#populateExistingMetadata(existingAccount?.id, 'name') ??\n `${keyringTypeName} ${keyringAccountIndex + 1}`,\n importTime:\n this.#populateExistingMetadata(existingAccount?.id, 'importTime') ??\n Date.now(),\n lastSelected:\n this.#populateExistingMetadata(\n existingAccount?.id,\n 'lastSelected',\n ) ?? 0,\n },\n };\n\n return internalAccountMap;\n }, {} as Record<string, InternalAccount>);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts = accounts;\n\n if (\n !currentState.internalAccounts.accounts[\n currentState.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount = this.#getLastSelectedAccount(\n Object.values(accounts),\n );\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n\n /**\n * Loads the backup state of the accounts controller.\n *\n * @param backup - The backup state to load.\n */\n loadBackup(backup: AccountsControllerState): void {\n if (backup.internalAccounts) {\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts = backup.internalAccounts;\n });\n }\n }\n\n /**\n * Generates an internal account for a non-Snap account.\n * @param address - The address of the account.\n * @param type - The type of the account.\n * @returns The generated internal account.\n */\n #generateInternalAccountForNonSnapAccount(\n address: string,\n type: string,\n ): InternalAccount {\n return {\n id: getUUIDFromAddressOfNormalAccount(address),\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n scopes: [EthScopes.Namespace],\n type: EthAccountType.Eoa,\n metadata: {\n name: '',\n importTime: Date.now(),\n keyring: {\n type,\n },\n },\n };\n }\n\n /**\n * Returns a list of internal accounts created using the SnapKeyring.\n *\n * @returns A promise that resolves to an array of InternalAccount objects.\n */\n async #listSnapAccounts(): Promise<InternalAccount[]> {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n // snap keyring is not available until the first account is created in the keyring controller\n if (!snapKeyring) {\n return [];\n }\n\n const snapAccounts = (snapKeyring as SnapKeyring).listAccounts();\n\n return snapAccounts;\n }\n\n /**\n * Returns a list of normal accounts.\n * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.\n * Once all keyrings implement the InternalAccount interface, this method can be removed and getAccounts can be used instead.\n *\n * @returns A Promise that resolves to an array of InternalAccount objects.\n */\n async #listNormalAccounts(): Promise<InternalAccount[]> {\n const addresses = await this.messagingSystem.call(\n 'KeyringController:getAccounts',\n );\n const internalAccounts: InternalAccount[] = [];\n for (const address of addresses) {\n const keyring = await this.messagingSystem.call(\n 'KeyringController:getKeyringForAccount',\n address,\n );\n\n const keyringType = (keyring as Keyring<Json>).type;\n if (!isNormalKeyringType(keyringType as KeyringTypes)) {\n // We only consider \"normal accounts\" here, so keep looping\n continue;\n }\n\n const id = getUUIDFromAddressOfNormalAccount(address);\n\n const nameLastUpdatedAt = this.#populateExistingMetadata(\n id,\n 'nameLastUpdatedAt',\n );\n\n internalAccounts.push({\n id,\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n scopes: [EthScopes.Namespace],\n type: EthAccountType.Eoa,\n metadata: {\n name: this.#populateExistingMetadata(id, 'name') ?? '',\n ...(nameLastUpdatedAt && { nameLastUpdatedAt }),\n importTime:\n this.#populateExistingMetadata(id, 'importTime') ?? Date.now(),\n lastSelected: this.#populateExistingMetadata(id, 'lastSelected') ?? 0,\n keyring: {\n type: (keyring as Keyring<Json>).type,\n },\n },\n });\n }\n\n return internalAccounts;\n }\n\n /**\n * Handles changes in the keyring state, specifically when new accounts are added or removed.\n *\n * @param keyringState - The new state of the keyring controller.\n */\n #handleOnKeyringStateChange(keyringState: KeyringControllerState): void {\n // check if there are any new accounts added\n // TODO: change when accountAdded event is added to the keyring controller\n\n // We check for keyrings length to be greater than 0 because the extension client may try execute\n // submit password twice and clear the keyring state.\n // https://github.com/MetaMask/KeyringController/blob/2d73a4deed8d013913f6ef0c9f5c0bb7c614f7d3/src/KeyringController.ts#L910\n if (keyringState.isUnlocked && keyringState.keyrings.length > 0) {\n const updatedNormalKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n const updatedSnapKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n\n for (const keyring of keyringState.keyrings) {\n if (keyring.type === KeyringTypes.snap) {\n updatedSnapKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n } else {\n updatedNormalKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n }\n }\n\n const { previousNormalInternalAccounts, previousSnapInternalAccounts } =\n this.listMultichainAccounts().reduce(\n (accumulator, account) => {\n if (account.metadata.keyring.type === KeyringTypes.snap) {\n accumulator.previousSnapInternalAccounts.push(account);\n } else {\n accumulator.previousNormalInternalAccounts.push(account);\n }\n return accumulator;\n },\n {\n previousNormalInternalAccounts: [] as InternalAccount[],\n previousSnapInternalAccounts: [] as InternalAccount[],\n },\n );\n\n const addedAccounts: AddressAndKeyringTypeObject[] = [];\n const deletedAccounts: InternalAccount[] = [];\n\n // snap account ids are random uuid while normal accounts\n // are determininistic based on the address\n\n // ^NOTE: This will be removed when normal accounts also implement internal accounts\n // finding all the normal accounts that were added\n for (const account of updatedNormalKeyringAddresses) {\n if (\n !this.state.internalAccounts.accounts[\n getUUIDFromAddressOfNormalAccount(account.address)\n ]\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were added\n for (const account of updatedSnapKeyringAddresses) {\n if (\n !previousSnapInternalAccounts.find(\n (internalAccount: InternalAccount) =>\n internalAccount.address.toLowerCase() ===\n account.address.toLowerCase(),\n )\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the normal accounts that were deleted\n for (const account of previousNormalInternalAccounts) {\n if (\n !updatedNormalKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were deleted\n for (const account of previousSnapInternalAccounts) {\n if (\n !updatedSnapKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n if (deletedAccounts.length > 0) {\n for (const account of deletedAccounts) {\n currentState.internalAccounts.accounts = this.#handleAccountRemoved(\n currentState.internalAccounts.accounts,\n account.id,\n );\n }\n }\n\n if (addedAccounts.length > 0) {\n for (const account of addedAccounts) {\n currentState.internalAccounts.accounts =\n this.#handleNewAccountAdded(\n currentState.internalAccounts.accounts,\n account,\n );\n }\n }\n\n // We don't use list accounts because it is not the updated state yet.\n const existingAccounts = Object.values(\n currentState.internalAccounts.accounts,\n );\n\n // handle if the selected account was deleted\n if (\n !currentState.internalAccounts.accounts[\n this.state.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount =\n this.#getLastSelectedAccount(existingAccounts);\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n }\n\n /**\n * Handles the change in SnapControllerState by updating the metadata of accounts that have a snap enabled.\n *\n * @param snapState - The new SnapControllerState.\n */\n #handleOnSnapStateChange(snapState: SnapControllerState) {\n // only check if snaps changed in status\n const { snaps } = snapState;\n const accounts = this.listMultichainAccounts().filter(\n (account) => account.metadata.snap,\n );\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n accounts.forEach((account) => {\n const currentAccount =\n currentState.internalAccounts.accounts[account.id];\n if (currentAccount.metadata.snap) {\n const snapId = currentAccount.metadata.snap.id;\n const storedSnap: Snap = snaps[snapId as SnapId];\n if (storedSnap) {\n currentAccount.metadata.snap.enabled =\n storedSnap.enabled && !storedSnap.blocked;\n }\n }\n });\n });\n }\n\n /**\n * Returns the list of accounts for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Accounts to filter by keyring type.\n * @returns The list of accounts associcated with this keyring type.\n */\n #getAccountsByKeyringType(keyringType: string, accounts?: InternalAccount[]) {\n return (accounts ?? this.listMultichainAccounts()).filter(\n (internalAccount) => {\n // We do consider `hd` and `simple` keyrings to be of same type. So we check those 2 types\n // to group those accounts together!\n if (\n keyringType === KeyringTypes.hd ||\n keyringType === KeyringTypes.simple\n ) {\n return (\n internalAccount.metadata.keyring.type === KeyringTypes.hd ||\n internalAccount.metadata.keyring.type === KeyringTypes.simple\n );\n }\n\n return internalAccount.metadata.keyring.type === keyringType;\n },\n );\n }\n\n /**\n * Returns the last selected account from the given array of accounts.\n *\n * @param accounts - An array of InternalAccount objects.\n * @returns The InternalAccount object that was last selected, or undefined if the array is empty.\n */\n #getLastSelectedAccount(\n accounts: InternalAccount[],\n ): InternalAccount | undefined {\n const [accountToSelect] = accounts.sort((accountA, accountB) => {\n // sort by lastSelected descending\n return (\n (accountB.metadata.lastSelected ?? 0) -\n (accountA.metadata.lastSelected ?? 0)\n );\n });\n\n return accountToSelect;\n }\n\n /**\n * Returns the next account number for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Existing accounts to check for the next available account number.\n * @returns An object containing the account prefix and index to use.\n */\n getNextAvailableAccountName(\n keyringType: string = KeyringTypes.hd,\n accounts?: InternalAccount[],\n ): string {\n const keyringName = keyringTypeToName(keyringType);\n const keyringAccounts = this.#getAccountsByKeyringType(\n keyringType,\n accounts,\n );\n const lastDefaultIndexUsedForKeyringType = keyringAccounts.reduce(\n (maxInternalAccountIndex, internalAccount) => {\n // We **DO NOT USE** `\\d+` here to only consider valid \"human\"\n // number (rounded decimal number)\n const match = new RegExp(`${keyringName} ([0-9]+)$`, 'u').exec(\n internalAccount.metadata.name,\n );\n\n if (match) {\n // Quoting `RegExp.exec` documentation:\n // > The returned array has the matched text as the first item, and then one item for\n // > each capturing group of the matched text.\n // So use `match[1]` to get the captured value\n const internalAccountIndex = parseInt(match[1], 10);\n return Math.max(maxInternalAccountIndex, internalAccountIndex);\n }\n\n return maxInternalAccountIndex;\n },\n 0,\n );\n\n const index = Math.max(\n keyringAccounts.length + 1,\n // ESLint is confused; this is a number.\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n lastDefaultIndexUsedForKeyringType + 1,\n );\n\n return `${keyringName} ${index}`;\n }\n\n /**\n * Checks if an account is compatible with a given chain namespace.\n * @private\n * @param account - The account to check compatibility for.\n * @param chainId - The CAIP2 to check compatibility with.\n * @returns Returns true if the account is compatible with the chain namespace, otherwise false.\n */\n #isAccountCompatibleWithChain(\n account: InternalAccount,\n chainId: CaipChainId,\n ): boolean {\n // TODO: Change this logic to not use account's type\n // Because we currently only use type, we can only use namespace for now.\n return account.type.startsWith(parseCaipChainId(chainId).namespace);\n }\n\n /**\n * Retrieves the index value for `metadata.lastSelected`.\n *\n * @returns The index value.\n */\n #getLastSelectedIndex() {\n // NOTE: For now we use the current date, since we know this value\n // will always be higher than any already selected account index.\n return Date.now();\n }\n\n /**\n * Handles the addition of a new account to the controller.\n * If the account is not a Snap Keyring account, generates an internal account for it and adds it to the controller.\n * If the account is a Snap Keyring account, retrieves the account from the keyring and adds it to the controller.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param account - The address and keyring type object of the new account.\n * @returns The updated AccountsController accounts state.\n */\n #handleNewAccountAdded(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n account: AddressAndKeyringTypeObject,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n let newAccount: InternalAccount;\n if (account.type !== KeyringTypes.snap) {\n newAccount = this.#generateInternalAccountForNonSnapAccount(\n account.address,\n account.type,\n );\n } else {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n\n newAccount = (snapKeyring as SnapKeyring).getAccountByAddress(\n account.address,\n ) as InternalAccount;\n\n // The snap deleted the account before the keyring controller could add it\n if (!newAccount) {\n return accountsState;\n }\n }\n\n const isFirstAccount = Object.keys(accountsState).length === 0;\n\n // Get next account name available for this given keyring\n const accountName = this.getNextAvailableAccountName(\n newAccount.metadata.keyring.type,\n Object.values(accountsState),\n );\n\n const newAccountWithUpdatedMetadata = {\n ...newAccount,\n metadata: {\n ...newAccount.metadata,\n name: accountName,\n importTime: Date.now(),\n lastSelected: isFirstAccount ? this.#getLastSelectedIndex() : 0,\n },\n };\n accountsState[newAccount.id] = newAccountWithUpdatedMetadata;\n\n this.messagingSystem.publish(\n 'AccountsController:accountAdded',\n newAccountWithUpdatedMetadata,\n );\n\n return accountsState;\n }\n\n #publishAccountChangeEvent(account: InternalAccount) {\n if (isEvmAccountType(account.type)) {\n this.messagingSystem.publish(\n 'AccountsController:selectedEvmAccountChange',\n account,\n );\n }\n this.messagingSystem.publish(\n 'AccountsController:selectedAccountChange',\n account,\n );\n }\n\n /**\n * Handles the removal of an account from the internal accounts list.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param accountId - The ID of the account to be removed.\n * @returns The updated AccountsController state.\n */\n #handleAccountRemoved(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n accountId: string,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n delete accountsState[accountId];\n\n this.messagingSystem.publish(\n 'AccountsController:accountRemoved',\n accountId,\n );\n\n return accountsState;\n }\n\n /**\n * Retrieves the value of a specific metadata key for an existing account.\n * @param accountId - The ID of the account.\n * @param metadataKey - The key of the metadata to retrieve.\n * @param account - The account object to retrieve the metadata key from.\n * @returns The value of the specified metadata key, or undefined if the account or metadata key does not exist.\n */\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n #populateExistingMetadata<T extends keyof InternalAccount['metadata']>(\n accountId: string,\n metadataKey: T,\n account?: InternalAccount,\n ): InternalAccount['metadata'][T] | undefined {\n const internalAccount = account ?? this.getAccount(accountId);\n return internalAccount ? internalAccount.metadata[metadataKey] : undefined;\n }\n\n /**\n * Registers message handlers for the AccountsController.\n * @private\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccount`,\n this.setSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listAccounts`,\n this.listAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listMultichainAccounts`,\n this.listMultichainAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setAccountName`,\n this.setAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateAccounts`,\n this.updateAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccount`,\n this.getSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedMultichainAccount`,\n this.getSelectedMultichainAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountByAddress`,\n this.getAccountByAddress.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getNextAvailableAccountName`,\n this.getNextAvailableAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:getAccount`,\n this.getAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:updateAccountMetadata`,\n this.updateAccountMetadata.bind(this),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"AccountsController.mjs","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport {\n EthAccountType,\n EthMethod,\n EthScopes,\n isEvmAccountType,\n} from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n KeyringControllerState,\n KeyringControllerGetKeyringForAccountAction,\n KeyringControllerGetKeyringsByTypeAction,\n KeyringControllerGetAccountsAction,\n KeyringControllerStateChangeEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type {\n SnapControllerState,\n SnapStateChange,\n} from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport type { Snap } from '@metamask/snaps-utils';\nimport type { CaipChainId } from '@metamask/utils';\nimport {\n type Keyring,\n type Json,\n isCaipChainId,\n parseCaipChainId,\n} from '@metamask/utils';\nimport type { Draft } from 'immer';\n\nimport {\n getUUIDFromAddressOfNormalAccount,\n isNormalKeyringType,\n keyringTypeToName,\n} from './utils';\n\nconst controllerName = 'AccountsController';\n\nexport type AccountId = string;\n\nexport type AccountsControllerState = {\n internalAccounts: {\n accounts: Record<AccountId, InternalAccount>;\n selectedAccount: string; // id of the selected account\n };\n};\n\nexport type AccountsControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSetSelectedAccountAction = {\n type: `${typeof controllerName}:setSelectedAccount`;\n handler: AccountsController['setSelectedAccount'];\n};\n\nexport type AccountsControllerSetAccountNameAction = {\n type: `${typeof controllerName}:setAccountName`;\n handler: AccountsController['setAccountName'];\n};\n\nexport type AccountsControllerListAccountsAction = {\n type: `${typeof controllerName}:listAccounts`;\n handler: AccountsController['listAccounts'];\n};\n\nexport type AccountsControllerListMultichainAccountsAction = {\n type: `${typeof controllerName}:listMultichainAccounts`;\n handler: AccountsController['listMultichainAccounts'];\n};\n\nexport type AccountsControllerUpdateAccountsAction = {\n type: `${typeof controllerName}:updateAccounts`;\n handler: AccountsController['updateAccounts'];\n};\n\nexport type AccountsControllerGetSelectedAccountAction = {\n type: `${typeof controllerName}:getSelectedAccount`;\n handler: AccountsController['getSelectedAccount'];\n};\n\nexport type AccountsControllerGetSelectedMultichainAccountAction = {\n type: `${typeof controllerName}:getSelectedMultichainAccount`;\n handler: AccountsController['getSelectedMultichainAccount'];\n};\n\nexport type AccountsControllerGetAccountByAddressAction = {\n type: `${typeof controllerName}:getAccountByAddress`;\n handler: AccountsController['getAccountByAddress'];\n};\n\nexport type AccountsControllerGetNextAvailableAccountNameAction = {\n type: `${typeof controllerName}:getNextAvailableAccountName`;\n handler: AccountsController['getNextAvailableAccountName'];\n};\n\nexport type AccountsControllerGetAccountAction = {\n type: `${typeof controllerName}:getAccount`;\n handler: AccountsController['getAccount'];\n};\n\nexport type AccountsControllerUpdateAccountMetadataAction = {\n type: `${typeof controllerName}:updateAccountMetadata`;\n handler: AccountsController['updateAccountMetadata'];\n};\n\nexport type AllowedActions =\n | KeyringControllerGetKeyringForAccountAction\n | KeyringControllerGetKeyringsByTypeAction\n | KeyringControllerGetAccountsAction;\n\nexport type AccountsControllerActions =\n | AccountsControllerGetStateAction\n | AccountsControllerSetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountsControllerListMultichainAccountsAction\n | AccountsControllerSetAccountNameAction\n | AccountsControllerUpdateAccountsAction\n | AccountsControllerGetAccountByAddressAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetNextAvailableAccountNameAction\n | AccountsControllerGetAccountAction\n | AccountsControllerGetSelectedMultichainAccountAction\n | AccountsControllerUpdateAccountMetadataAction;\n\nexport type AccountsControllerChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n AccountsControllerState\n>;\n\nexport type AccountsControllerSelectedAccountChangeEvent = {\n type: `${typeof controllerName}:selectedAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerSelectedEvmAccountChangeEvent = {\n type: `${typeof controllerName}:selectedEvmAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountAddedEvent = {\n type: `${typeof controllerName}:accountAdded`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerAccountRemovedEvent = {\n type: `${typeof controllerName}:accountRemoved`;\n payload: [AccountId];\n};\n\nexport type AccountsControllerAccountRenamedEvent = {\n type: `${typeof controllerName}:accountRenamed`;\n payload: [InternalAccount];\n};\n\nexport type AllowedEvents = SnapStateChange | KeyringControllerStateChangeEvent;\n\nexport type AccountsControllerEvents =\n | AccountsControllerChangeEvent\n | AccountsControllerSelectedAccountChangeEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | AccountsControllerAccountAddedEvent\n | AccountsControllerAccountRemovedEvent\n | AccountsControllerAccountRenamedEvent;\n\nexport type AccountsControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AccountsControllerActions | AllowedActions,\n AccountsControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\ntype AddressAndKeyringTypeObject = {\n address: string;\n type: string;\n};\n\nconst accountsControllerMetadata = {\n internalAccounts: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst defaultState: AccountsControllerState = {\n internalAccounts: {\n accounts: {},\n selectedAccount: '',\n },\n};\n\nexport const EMPTY_ACCOUNT = {\n id: '',\n address: '',\n options: {},\n methods: [],\n type: EthAccountType.Eoa,\n scopes: [EthScopes.Namespace],\n metadata: {\n name: '',\n keyring: {\n type: '',\n },\n importTime: 0,\n },\n};\n\n/**\n * Controller that manages internal accounts.\n * The accounts controller is responsible for creating and managing internal accounts.\n * It also provides convenience methods for accessing and updating the internal accounts.\n * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.\n * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.\n *\n */\nexport class AccountsController extends BaseController<\n typeof controllerName,\n AccountsControllerState,\n AccountsControllerMessenger\n> {\n /**\n * Constructor for AccountsController.\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: AccountsControllerMessenger;\n state: AccountsControllerState;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountsControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.messagingSystem.subscribe(\n 'SnapController:stateChange',\n (snapStateState) => this.#handleOnSnapStateChange(snapStateState),\n );\n\n this.messagingSystem.subscribe(\n 'KeyringController:stateChange',\n (keyringState) => this.#handleOnKeyringStateChange(keyringState),\n );\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Returns the internal account object for the given account ID, if it exists.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object, or undefined if the account does not exist.\n */\n getAccount(accountId: string): InternalAccount | undefined {\n return this.state.internalAccounts.accounts[accountId];\n }\n\n /**\n * Returns an array of all evm internal accounts.\n *\n * @returns An array of InternalAccount objects.\n */\n listAccounts(): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n return accounts.filter((account) => isEvmAccountType(account.type));\n }\n\n /**\n * Returns an array of all internal accounts.\n *\n * @param chainId - The chain ID.\n * @returns An array of InternalAccount objects.\n */\n listMultichainAccounts(chainId?: CaipChainId): InternalAccount[] {\n const accounts = Object.values(this.state.internalAccounts.accounts);\n if (!chainId) {\n return accounts;\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${String(chainId)}`);\n }\n\n return accounts.filter((account) =>\n this.#isAccountCompatibleWithChain(account, chainId),\n );\n }\n\n /**\n * Returns the internal account object for the given account ID.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object.\n * @throws An error if the account ID is not found.\n */\n getAccountExpect(accountId: string): InternalAccount {\n const account = this.getAccount(accountId);\n if (account === undefined) {\n throw new Error(`Account Id \"${accountId}\" not found`);\n }\n return account;\n }\n\n /**\n * Returns the last selected EVM account.\n *\n * @returns The selected internal account.\n */\n getSelectedAccount(): InternalAccount {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n const selectedAccount = this.getAccountExpect(\n this.state.internalAccounts.selectedAccount,\n );\n if (isEvmAccountType(selectedAccount.type)) {\n return selectedAccount;\n }\n\n const accounts = this.listAccounts();\n\n if (!accounts.length) {\n // ! Should never reach this.\n throw new Error('No EVM accounts');\n }\n\n // This will never be undefined because we have already checked if accounts.length is > 0\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.#getLastSelectedAccount(accounts)!;\n }\n\n /**\n * __WARNING The return value may be undefined if there isn't an account for that chain id.__\n *\n * Retrieves the last selected account by chain ID.\n *\n * @param chainId - The chain ID to filter the accounts.\n * @returns The last selected account compatible with the specified chain ID or undefined.\n */\n getSelectedMultichainAccount(\n chainId?: CaipChainId,\n ): InternalAccount | undefined {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (this.state.internalAccounts.selectedAccount === '') {\n return EMPTY_ACCOUNT;\n }\n\n if (!chainId) {\n return this.getAccountExpect(this.state.internalAccounts.selectedAccount);\n }\n\n if (!isCaipChainId(chainId)) {\n throw new Error(`Invalid CAIP-2 chain ID: ${chainId as string}`);\n }\n\n const accounts = Object.values(this.state.internalAccounts.accounts).filter(\n (account) => this.#isAccountCompatibleWithChain(account, chainId),\n );\n\n return this.#getLastSelectedAccount(accounts);\n }\n\n /**\n * Returns the account with the specified address.\n * ! This method will only return the first account that matches the address\n * @param address - The address of the account to retrieve.\n * @returns The account with the specified address, or undefined if not found.\n */\n getAccountByAddress(address: string): InternalAccount | undefined {\n return this.listMultichainAccounts().find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n );\n }\n\n /**\n * Sets the selected account by its ID.\n *\n * @param accountId - The ID of the account to be selected.\n */\n setSelectedAccount(accountId: string): void {\n const account = this.getAccountExpect(accountId);\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts[account.id].metadata.lastSelected =\n Date.now();\n currentState.internalAccounts.selectedAccount = account.id;\n });\n\n this.#publishAccountChangeEvent(account);\n }\n\n /**\n * Sets the name of the account with the given ID.\n *\n * @param accountId - The ID of the account to set the name for.\n * @param accountName - The new name for the account.\n * @throws An error if an account with the same name already exists.\n */\n setAccountName(accountId: string, accountName: string): void {\n // This will check for name uniqueness and fire the `accountRenamed` event\n // if the account has been renamed.\n this.updateAccountMetadata(accountId, {\n name: accountName,\n nameLastUpdatedAt: Date.now(),\n });\n }\n\n /**\n * Updates the metadata of the account with the given ID.\n *\n * @param accountId - The ID of the account for which the metadata will be updated.\n * @param metadata - The new metadata for the account.\n */\n updateAccountMetadata(\n accountId: string,\n metadata: Partial<InternalAccount['metadata']>,\n ): void {\n const account = this.getAccountExpect(accountId);\n\n if (\n metadata.name &&\n this.listMultichainAccounts().find(\n (internalAccount) =>\n internalAccount.metadata.name === metadata.name &&\n internalAccount.id !== accountId,\n )\n ) {\n throw new Error('Account name already exists');\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n const internalAccount = {\n ...account,\n metadata: { ...account.metadata, ...metadata },\n };\n // Do not remove this comment - This error is flaky: Comment out or restore the `ts-expect-error` directive below as needed.\n // See: https://github.com/MetaMask/utils/issues/168\n // // @ts-expect-error Known issue - `Json` causes recursive error in immer `Draft`/`WritableDraft` types\n currentState.internalAccounts.accounts[accountId] = internalAccount;\n\n if (metadata.name) {\n this.messagingSystem.publish(\n 'AccountsController:accountRenamed',\n internalAccount,\n );\n }\n });\n }\n\n /**\n * Updates the internal accounts list by retrieving normal and snap accounts,\n * removing duplicates, and updating the metadata of each account.\n *\n * @returns A Promise that resolves when the accounts have been updated.\n */\n async updateAccounts(): Promise<void> {\n // We are re-creating the list of internal accounts based on the accounts from\n // each keyrings, following those rules:\n //\n // - If the account already exists on this controller state, we only update\n // metadata. This allows to automatically \"migrate\" new metadata for existing\n // accounts.\n //\n // - Else, we create the associated internal account for that new account. This\n // can happen when the Snap keyring adds a new account. The Snap keyring will\n // create a new account and will automatically \"persists\" by calling this\n // function explicitly to create its associated internal account.\n //\n // FIXME: This logic is kinda tricky and could be replaced with the new\n // incoming notification system that the Snap keyring will use.\n const snapAccounts = await this.#listAccountsFromSnapKeyring();\n const normalAccounts = await this.#listAccountsFromOtherKeyrings();\n\n // Keep track of unnamed account to rename them after.\n const namedAccounts: InternalAccount[] = [];\n const unnamedAccounts: InternalAccount[] = [];\n\n // Compute the updated list of internal accounts:\n const accounts: Record<string, InternalAccount> = {};\n for (const keyringInternalAccount of [...normalAccounts, ...snapAccounts]) {\n const { id } = keyringInternalAccount;\n\n const internalAccount = this.state.internalAccounts.accounts[id];\n if (internalAccount) {\n // The account already exist, we're just updating the metadata.\n const { metadata } = internalAccount;\n accounts[id] = {\n ...internalAccount,\n metadata: this.#getAccountMetadataOrDefaults(\n metadata.keyring.type,\n metadata,\n ),\n };\n } else {\n // The account does not exist yet on this controller. We create a new\n // internal account now using the internal account created from\n // the keyring account.\n const { metadata } = keyringInternalAccount;\n accounts[id] = {\n ...keyringInternalAccount,\n metadata: this.#getAccountMetadataOrDefaults(\n metadata.keyring.type,\n metadata,\n ),\n };\n }\n\n // If the account has no name yet, we mark it and we'll rename it afterward once\n // we have re-created the full state.\n if (accounts[id].metadata.name === '') {\n unnamedAccounts.push(accounts[id]);\n } else {\n // It's important to track named accounts too since the\n // `getNextAvailableAccountname` will use the highest index possible\n // based on account's names.\n namedAccounts.push(accounts[id]);\n }\n }\n\n // Now, we can rename each accounts according to our naming rule.\n for (const account of unnamedAccounts) {\n accounts[account.id].metadata.name = this.getNextAvailableAccountName(\n account.metadata.keyring.type,\n namedAccounts,\n );\n // It has a name now, we need to re-use it when naming other accounts.\n namedAccounts.push(accounts[account.id]);\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts.accounts = accounts;\n\n if (\n !currentState.internalAccounts.accounts[\n currentState.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount = this.#getLastSelectedAccount(\n Object.values(accounts),\n );\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n\n /**\n * Loads the backup state of the accounts controller.\n *\n * @param backup - The backup state to load.\n */\n loadBackup(backup: AccountsControllerState): void {\n if (backup.internalAccounts) {\n this.update((currentState: Draft<AccountsControllerState>) => {\n currentState.internalAccounts = backup.internalAccounts;\n });\n }\n }\n\n /**\n * Generates an internal account for a non-Snap account.\n * @param address - The address of the account.\n * @param keyringType - The keyring type for that account.\n * @returns The generated internal account.\n */\n #generateInternalAccountForNonSnapAccount(\n address: string,\n keyringType: string,\n ): InternalAccount {\n // Non-Snap accounts computes their account ID based on their address (in a\n // deterministic way).\n const id = getUUIDFromAddressOfNormalAccount(address);\n // If the account does not exist yet, metadata will use all default values.\n const account = this.getAccount(id);\n const metadata = this.#getAccountMetadataOrDefaults(\n keyringType,\n account?.metadata,\n );\n\n return {\n id,\n address,\n options: {},\n methods: [\n EthMethod.PersonalSign,\n EthMethod.Sign,\n EthMethod.SignTransaction,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n ],\n // Normal accounts are all EOA.\n type: EthAccountType.Eoa,\n // And EOA accounts are compatible on every EVM chains, so use the namespace here.\n scopes: [EthScopes.Namespace],\n metadata: {\n ...metadata,\n keyring: {\n type: keyringType,\n },\n },\n };\n }\n\n /**\n * Gets the Snap keyring if it is available.\n *\n * @returns The Snap keyring if available, undefined otherwise.\n */\n #getSnapKeyring(): SnapKeyring {\n const [snapKeyring] = this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n\n return snapKeyring as SnapKeyring;\n }\n\n /**\n * Gets the keyring associated to an account's address.\n *\n * @param address - Account's address.\n * @returns A promise that resolves to the associated keyring.\n */\n async #getKeyringForAccount<KeyringType = Keyring<Json>>(\n address: string,\n ): Promise<KeyringType> {\n const keyring = await this.messagingSystem.call(\n 'KeyringController:getKeyringForAccount',\n address,\n );\n\n return keyring as KeyringType;\n }\n\n /**\n * Gets the address of all accounts.\n *\n * @returns A promise that resolves to the list of account addresses.\n */\n async #getAccountAddresses(): Promise<string[]> {\n return await this.messagingSystem.call('KeyringController:getAccounts');\n }\n\n /**\n * Gets account's metadata with default values when not already defined.\n *\n * @param keyringType - The account keyring type.\n * @param metadata - The account's metadata (if defined).\n * @returns The account's metadata with default values when not already defined.\n */\n #getAccountMetadataOrDefaults(\n keyringType: string,\n metadata?: InternalAccount['metadata'],\n ): InternalAccount['metadata'] {\n return {\n // Expand the account's metadata first, and then adds default if they are not\n // defined.\n ...metadata,\n\n name: metadata?.name ?? '', // This will be renamed by `updateAccounts` if empty.\n keyring: {\n type: keyringType,\n },\n importTime: metadata?.importTime ?? Date.now(),\n lastSelected: metadata?.lastSelected ?? 0, // This means the account has never been selected yet.\n };\n }\n\n /**\n * Returns a list of internal accounts created using the Snap keyring.\n *\n * @returns A promise that resolves to an array of InternalAccount objects.\n */\n async #listAccountsFromSnapKeyring(): Promise<InternalAccount[]> {\n const snapKeyring = this.#getSnapKeyring();\n\n // Snap keyring is not available until the first account is created in the keyring controller\n if (!snapKeyring) {\n return [];\n }\n\n return snapKeyring.listAccounts();\n }\n\n /**\n * Returns a list of normal accounts.\n * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.\n * Once all keyrings implement the InternalAccount interface, this method can be removed and getAccounts can be used instead.\n *\n * @returns A Promise that resolves to an array of InternalAccount objects.\n */\n async #listAccountsFromOtherKeyrings(): Promise<InternalAccount[]> {\n const internalAccounts: InternalAccount[] = [];\n\n for (const address of await this.#getAccountAddresses()) {\n const keyring = await this.#getKeyringForAccount(address);\n\n if (!isNormalKeyringType(keyring.type as KeyringTypes)) {\n // We only consider \"normal accounts\" here, so keep looping.\n continue;\n }\n\n internalAccounts.push(\n this.#generateInternalAccountForNonSnapAccount(\n address,\n // The keyring type can either be \"Simple\" or \"HD\" here.\n keyring.type,\n ),\n );\n }\n\n return internalAccounts;\n }\n\n /**\n * Handles changes in the keyring state, specifically when new accounts are added or removed.\n *\n * @param keyringState - The new state of the keyring controller.\n */\n #handleOnKeyringStateChange(keyringState: KeyringControllerState): void {\n // check if there are any new accounts added\n // TODO: change when accountAdded event is added to the keyring controller\n\n // We check for keyrings length to be greater than 0 because the extension client may try execute\n // submit password twice and clear the keyring state.\n // https://github.com/MetaMask/KeyringController/blob/2d73a4deed8d013913f6ef0c9f5c0bb7c614f7d3/src/KeyringController.ts#L910\n if (keyringState.isUnlocked && keyringState.keyrings.length > 0) {\n const updatedNormalKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n const updatedSnapKeyringAddresses: AddressAndKeyringTypeObject[] = [];\n\n for (const keyring of keyringState.keyrings) {\n if (keyring.type === KeyringTypes.snap) {\n updatedSnapKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n } else {\n updatedNormalKeyringAddresses.push(\n ...keyring.accounts.map((address) => {\n return {\n address,\n type: keyring.type,\n };\n }),\n );\n }\n }\n\n const { previousNormalInternalAccounts, previousSnapInternalAccounts } =\n this.listMultichainAccounts().reduce(\n (accumulator, account) => {\n if (account.metadata.keyring.type === KeyringTypes.snap) {\n accumulator.previousSnapInternalAccounts.push(account);\n } else {\n accumulator.previousNormalInternalAccounts.push(account);\n }\n return accumulator;\n },\n {\n previousNormalInternalAccounts: [] as InternalAccount[],\n previousSnapInternalAccounts: [] as InternalAccount[],\n },\n );\n\n const addedAccounts: AddressAndKeyringTypeObject[] = [];\n const deletedAccounts: InternalAccount[] = [];\n\n // Snap account IDs are random UUIDs while normal accounts\n // are determininistic based on the address.\n\n // ^NOTE: This will be removed when normal accounts also implement internal accounts\n // finding all the normal accounts that were added\n for (const account of updatedNormalKeyringAddresses) {\n if (\n !this.state.internalAccounts.accounts[\n getUUIDFromAddressOfNormalAccount(account.address)\n ]\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were added\n for (const account of updatedSnapKeyringAddresses) {\n if (\n !previousSnapInternalAccounts.find(\n (internalAccount: InternalAccount) =>\n internalAccount.address.toLowerCase() ===\n account.address.toLowerCase(),\n )\n ) {\n addedAccounts.push(account);\n }\n }\n\n // finding all the normal accounts that were deleted\n for (const account of previousNormalInternalAccounts) {\n if (\n !updatedNormalKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n // finding all the snap accounts that were deleted\n for (const account of previousSnapInternalAccounts) {\n if (\n !updatedSnapKeyringAddresses.find(\n ({ address }) =>\n address.toLowerCase() === account.address.toLowerCase(),\n )\n ) {\n deletedAccounts.push(account);\n }\n }\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n if (deletedAccounts.length > 0) {\n for (const account of deletedAccounts) {\n currentState.internalAccounts.accounts = this.#handleAccountRemoved(\n currentState.internalAccounts.accounts,\n account.id,\n );\n }\n }\n\n if (addedAccounts.length > 0) {\n for (const account of addedAccounts) {\n currentState.internalAccounts.accounts =\n this.#handleNewAccountAdded(\n currentState.internalAccounts.accounts,\n account,\n );\n }\n }\n\n // We don't use list accounts because it is not the updated state yet.\n const existingAccounts = Object.values(\n currentState.internalAccounts.accounts,\n );\n\n // handle if the selected account was deleted\n if (\n !currentState.internalAccounts.accounts[\n this.state.internalAccounts.selectedAccount\n ]\n ) {\n const lastSelectedAccount =\n this.#getLastSelectedAccount(existingAccounts);\n\n if (lastSelectedAccount) {\n currentState.internalAccounts.selectedAccount =\n lastSelectedAccount.id;\n currentState.internalAccounts.accounts[\n lastSelectedAccount.id\n ].metadata.lastSelected = this.#getLastSelectedIndex();\n this.#publishAccountChangeEvent(lastSelectedAccount);\n } else {\n // It will be undefined if there are no accounts\n currentState.internalAccounts.selectedAccount = '';\n }\n }\n });\n }\n }\n\n /**\n * Handles the change in SnapControllerState by updating the metadata of accounts that have a snap enabled.\n *\n * @param snapState - The new SnapControllerState.\n */\n #handleOnSnapStateChange(snapState: SnapControllerState) {\n // only check if snaps changed in status\n const { snaps } = snapState;\n const accounts = this.listMultichainAccounts().filter(\n (account) => account.metadata.snap,\n );\n\n this.update((currentState: Draft<AccountsControllerState>) => {\n accounts.forEach((account) => {\n const currentAccount =\n currentState.internalAccounts.accounts[account.id];\n if (currentAccount.metadata.snap) {\n const snapId = currentAccount.metadata.snap.id;\n const storedSnap: Snap = snaps[snapId as SnapId];\n if (storedSnap) {\n currentAccount.metadata.snap.enabled =\n storedSnap.enabled && !storedSnap.blocked;\n }\n }\n });\n });\n }\n\n /**\n * Returns the list of accounts for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Accounts to filter by keyring type.\n * @returns The list of accounts associcated with this keyring type.\n */\n #getAccountsByKeyringType(keyringType: string, accounts?: InternalAccount[]) {\n return (accounts ?? this.listMultichainAccounts()).filter(\n (internalAccount) => {\n // We do consider `hd` and `simple` keyrings to be of same type. So we check those 2 types\n // to group those accounts together!\n if (\n keyringType === KeyringTypes.hd ||\n keyringType === KeyringTypes.simple\n ) {\n return (\n internalAccount.metadata.keyring.type === KeyringTypes.hd ||\n internalAccount.metadata.keyring.type === KeyringTypes.simple\n );\n }\n\n return internalAccount.metadata.keyring.type === keyringType;\n },\n );\n }\n\n /**\n * Returns the last selected account from the given array of accounts.\n *\n * @param accounts - An array of InternalAccount objects.\n * @returns The InternalAccount object that was last selected, or undefined if the array is empty.\n */\n #getLastSelectedAccount(\n accounts: InternalAccount[],\n ): InternalAccount | undefined {\n const [accountToSelect] = accounts.sort((accountA, accountB) => {\n // sort by lastSelected descending\n return (\n (accountB.metadata.lastSelected ?? 0) -\n (accountA.metadata.lastSelected ?? 0)\n );\n });\n\n return accountToSelect;\n }\n\n /**\n * Returns the next account number for a given keyring type.\n * @param keyringType - The type of keyring.\n * @param accounts - Existing accounts to check for the next available account number.\n * @returns An object containing the account prefix and index to use.\n */\n getNextAvailableAccountName(\n keyringType: string = KeyringTypes.hd,\n accounts?: InternalAccount[],\n ): string {\n const keyringName = keyringTypeToName(keyringType);\n const keyringAccounts = this.#getAccountsByKeyringType(\n keyringType,\n accounts,\n );\n const lastDefaultIndexUsedForKeyringType = keyringAccounts.reduce(\n (maxInternalAccountIndex, internalAccount) => {\n // We **DO NOT USE** `\\d+` here to only consider valid \"human\"\n // number (rounded decimal number)\n const match = new RegExp(`${keyringName} ([0-9]+)$`, 'u').exec(\n internalAccount.metadata.name,\n );\n\n if (match) {\n // Quoting `RegExp.exec` documentation:\n // > The returned array has the matched text as the first item, and then one item for\n // > each capturing group of the matched text.\n // So use `match[1]` to get the captured value\n const internalAccountIndex = parseInt(match[1], 10);\n return Math.max(maxInternalAccountIndex, internalAccountIndex);\n }\n\n return maxInternalAccountIndex;\n },\n 0,\n );\n\n const index = Math.max(\n keyringAccounts.length + 1,\n // ESLint is confused; this is a number.\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n lastDefaultIndexUsedForKeyringType + 1,\n );\n\n return `${keyringName} ${index}`;\n }\n\n /**\n * Checks if an account is compatible with a given chain namespace.\n * @private\n * @param account - The account to check compatibility for.\n * @param chainId - The CAIP2 to check compatibility with.\n * @returns Returns true if the account is compatible with the chain namespace, otherwise false.\n */\n #isAccountCompatibleWithChain(\n account: InternalAccount,\n chainId: CaipChainId,\n ): boolean {\n // TODO: Change this logic to not use account's type\n // Because we currently only use type, we can only use namespace for now.\n return account.type.startsWith(parseCaipChainId(chainId).namespace);\n }\n\n /**\n * Retrieves the index value for `metadata.lastSelected`.\n *\n * @returns The index value.\n */\n #getLastSelectedIndex() {\n // NOTE: For now we use the current date, since we know this value\n // will always be higher than any already selected account index.\n return Date.now();\n }\n\n /**\n * Handles the addition of a new account to the controller.\n * If the account is not a Snap Keyring account, generates an internal account for it and adds it to the controller.\n * If the account is a Snap Keyring account, retrieves the account from the keyring and adds it to the controller.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param account - The address and keyring type object of the new account.\n * @returns The updated AccountsController accounts state.\n */\n #handleNewAccountAdded(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n account: AddressAndKeyringTypeObject,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n let newAccount: InternalAccount;\n if (account.type !== KeyringTypes.snap) {\n newAccount = this.#generateInternalAccountForNonSnapAccount(\n account.address,\n account.type,\n );\n } else {\n const snapKeyring = this.#getSnapKeyring();\n\n newAccount = snapKeyring.getAccountByAddress(\n account.address,\n ) as InternalAccount;\n\n // The snap deleted the account before the keyring controller could add it\n if (!newAccount) {\n return accountsState;\n }\n }\n\n const isFirstAccount = Object.keys(accountsState).length === 0;\n\n // Get next account name available for this given keyring\n const accountName = this.getNextAvailableAccountName(\n newAccount.metadata.keyring.type,\n Object.values(accountsState),\n );\n\n const newAccountWithUpdatedMetadata = {\n ...newAccount,\n metadata: {\n ...newAccount.metadata,\n name: accountName,\n importTime: Date.now(),\n lastSelected: isFirstAccount ? this.#getLastSelectedIndex() : 0,\n },\n };\n accountsState[newAccount.id] = newAccountWithUpdatedMetadata;\n\n this.messagingSystem.publish(\n 'AccountsController:accountAdded',\n newAccountWithUpdatedMetadata,\n );\n\n return accountsState;\n }\n\n #publishAccountChangeEvent(account: InternalAccount) {\n if (isEvmAccountType(account.type)) {\n this.messagingSystem.publish(\n 'AccountsController:selectedEvmAccountChange',\n account,\n );\n }\n this.messagingSystem.publish(\n 'AccountsController:selectedAccountChange',\n account,\n );\n }\n\n /**\n * Handles the removal of an account from the internal accounts list.\n * @param accountsState - AccountsController accounts state that is to be mutated.\n * @param accountId - The ID of the account to be removed.\n * @returns The updated AccountsController state.\n */\n #handleAccountRemoved(\n accountsState: AccountsControllerState['internalAccounts']['accounts'],\n accountId: string,\n ): AccountsControllerState['internalAccounts']['accounts'] {\n delete accountsState[accountId];\n\n this.messagingSystem.publish(\n 'AccountsController:accountRemoved',\n accountId,\n );\n\n return accountsState;\n }\n\n /**\n * Registers message handlers for the AccountsController.\n * @private\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccount`,\n this.setSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listAccounts`,\n this.listAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listMultichainAccounts`,\n this.listMultichainAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setAccountName`,\n this.setAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateAccounts`,\n this.updateAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedAccount`,\n this.getSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getSelectedMultichainAccount`,\n this.getSelectedMultichainAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getAccountByAddress`,\n this.getAccountByAddress.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getNextAvailableAccountName`,\n this.getNextAvailableAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:getAccount`,\n this.getAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `AccountsController:updateAccountMetadata`,\n this.updateAccountMetadata.bind(this),\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/accounts-controller",
3
- "version": "21.0.0-preview-a7b445fc",
3
+ "version": "21.0.0-preview-d2b96e95",
4
4
  "description": "Manages internal accounts",
5
5
  "keywords": [
6
6
  "MetaMask",