@metamask-previews/keyring-controller 21.0.6-preview-8a04e037 → 21.0.6-preview-aa280426

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Changed
11
+
12
+ - **BREAKING** `keyringsMetadata` has been removed from the controller state ([#5725](https://github.com/MetaMask/core/pull/5725))
13
+ - The metadata is now stored in each keyring object in the `state.keyrings` array.
14
+ - When updating to this version, we recommend removing the `keyringsMetadata` state and all state referencing a keyring ID with a migration. New metadata will be generated for each keyring automatically after the update.
15
+
16
+ ### Fixed
17
+
18
+ - Keyrings with duplicate accounts are skipped as unsupported on unlock ([#5775](https://github.com/MetaMask/core/pull/5775))
19
+
10
20
  ## [21.0.6]
11
21
 
12
22
  ### Changed
@@ -36,7 +36,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
36
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
38
  };
39
- var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_keyringsMetadata, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_upgradeVaultEncryptionParams, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
41
  exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
42
42
  const util_1 = require("@ethereumjs/util");
@@ -122,7 +122,6 @@ const getDefaultKeyringState = () => {
122
122
  return {
123
123
  isUnlocked: false,
124
124
  keyrings: [],
125
- keyringsMetadata: [],
126
125
  };
127
126
  };
128
127
  exports.getDefaultKeyringState = getDefaultKeyringState;
@@ -185,16 +184,19 @@ function isSerializedKeyringsArray(array) {
185
184
  *
186
185
  * Is used for adding the current keyrings to the state object.
187
186
  *
188
- * @param keyring - The keyring to display.
187
+ * @param keyringWithMetadata - The keyring and its metadata.
188
+ * @param keyringWithMetadata.keyring - The keyring to display.
189
+ * @param keyringWithMetadata.metadata - The metadata of the keyring.
189
190
  * @returns A keyring display object, with type and accounts properties.
190
191
  */
191
- async function displayForKeyring(keyring) {
192
+ async function displayForKeyring({ keyring, metadata, }) {
192
193
  const accounts = await keyring.getAccounts();
193
194
  return {
194
195
  type: keyring.type,
195
196
  // Cast to `string[]` here is safe here because `accounts` has no nullish
196
197
  // values, and `normalize` returns `string` unless given a nullish value
197
198
  accounts: accounts.map(normalize),
199
+ metadata,
198
200
  };
199
201
  }
200
202
  /**
@@ -254,7 +256,6 @@ class KeyringController extends base_controller_1.BaseController {
254
256
  vault: { persist: true, anonymous: false },
255
257
  isUnlocked: { persist: false, anonymous: true },
256
258
  keyrings: { persist: false, anonymous: false },
257
- keyringsMetadata: { persist: true, anonymous: false },
258
259
  encryptionKey: { persist: false, anonymous: false },
259
260
  encryptionSalt: { persist: false, anonymous: false },
260
261
  },
@@ -272,7 +273,6 @@ class KeyringController extends base_controller_1.BaseController {
272
273
  _KeyringController_cacheEncryptionKey.set(this, void 0);
273
274
  _KeyringController_keyrings.set(this, void 0);
274
275
  _KeyringController_unsupportedKeyrings.set(this, void 0);
275
- _KeyringController_keyringsMetadata.set(this, void 0);
276
276
  _KeyringController_password.set(this, void 0);
277
277
  _KeyringController_qrKeyringStateListener.set(this, void 0);
278
278
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
@@ -280,7 +280,6 @@ class KeyringController extends base_controller_1.BaseController {
280
280
  : defaultKeyringBuilders, "f");
281
281
  __classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
282
282
  __classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
283
- __classPrivateFieldSet(this, _KeyringController_keyringsMetadata, state?.keyringsMetadata?.slice() ?? [], "f");
284
283
  __classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
285
284
  // This option allows the controller to cache an exported key
286
285
  // for use in decrypting and encrypting data without password
@@ -513,7 +512,7 @@ class KeyringController extends base_controller_1.BaseController {
513
512
  async getKeyringForAccount(account) {
514
513
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
515
514
  const address = normalize(account);
516
- const candidates = await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async (keyring) => {
515
+ const candidates = await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async ({ keyring }) => {
517
516
  return Promise.all([keyring, keyring.getAccounts()]);
518
517
  }));
519
518
  const winners = candidates.filter((candidate) => {
@@ -544,7 +543,9 @@ class KeyringController extends base_controller_1.BaseController {
544
543
  */
545
544
  getKeyringsByType(type) {
546
545
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
547
- return __classPrivateFieldGet(this, _KeyringController_keyrings, "f").filter((keyring) => keyring.type === type);
546
+ return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")
547
+ .filter(({ keyring }) => keyring.type === type)
548
+ .map(({ keyring }) => keyring);
548
549
  }
549
550
  /**
550
551
  * Persist all serialized keyrings in the vault.
@@ -865,10 +866,25 @@ class KeyringController extends base_controller_1.BaseController {
865
866
  * @returns Promise resolving when the operation completes.
866
867
  */
867
868
  async submitEncryptionKey(encryptionKey, encryptionSalt) {
868
- return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
869
- __classPrivateFieldSet(this, _KeyringController_keyrings, await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt), "f");
869
+ const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
870
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
870
871
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
872
+ return result;
871
873
  });
874
+ try {
875
+ // if new metadata has been generated during login, we
876
+ // can attempt to upgrade the vault.
877
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
878
+ if (newMetadata) {
879
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
880
+ }
881
+ });
882
+ }
883
+ catch (error) {
884
+ // We don't want to throw an error if the upgrade fails
885
+ // since the controller is already unlocked.
886
+ console.error('Failed to update vault during login:', error);
887
+ }
872
888
  }
873
889
  /**
874
890
  * Attempts to decrypt the current vault and load its keyrings,
@@ -878,19 +894,25 @@ class KeyringController extends base_controller_1.BaseController {
878
894
  * @returns Promise resolving when the operation completes.
879
895
  */
880
896
  async submitPassword(password) {
881
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
882
- __classPrivateFieldSet(this, _KeyringController_keyrings, await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password), "f");
897
+ const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
898
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
883
899
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
900
+ return result;
884
901
  });
885
902
  try {
886
- // If there are stronger encryption params available, we
903
+ // If there are stronger encryption params available, or
904
+ // if new metadata has been generated during login, we
887
905
  // can attempt to upgrade the vault.
888
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_upgradeVaultEncryptionParams).call(this));
906
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
907
+ if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
908
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
909
+ }
910
+ });
889
911
  }
890
912
  catch (error) {
891
913
  // We don't want to throw an error if the upgrade fails
892
914
  // since the controller is already unlocked.
893
- console.error('Failed to upgrade vault encryption params:', error);
915
+ console.error('Failed to update vault during login:', error);
894
916
  }
895
917
  }
896
918
  /**
@@ -1137,7 +1159,7 @@ class KeyringController extends base_controller_1.BaseController {
1137
1159
  }
1138
1160
  }
1139
1161
  exports.KeyringController = KeyringController;
1140
- _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_keyringsMetadata = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1162
+ _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1141
1163
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1142
1164
  this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1143
1165
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1154,17 +1176,19 @@ _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_
1154
1176
  this.messagingSystem.registerActionHandler(`${name}:addNewAccount`, this.addNewAccount.bind(this));
1155
1177
  this.messagingSystem.registerActionHandler(`${name}:withKeyring`, this.withKeyring.bind(this));
1156
1178
  }, _KeyringController_getKeyringById = function _KeyringController_getKeyringById(keyringId) {
1157
- const index = this.state.keyringsMetadata.findIndex((metadata) => metadata.id === keyringId);
1158
- return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[index];
1179
+ return __classPrivateFieldGet(this, _KeyringController_keyrings, "f").find(({ metadata }) => metadata.id === keyringId)
1180
+ ?.keyring;
1159
1181
  }, _KeyringController_getKeyringByIdOrDefault = function _KeyringController_getKeyringByIdOrDefault(keyringId) {
1160
1182
  if (!keyringId) {
1161
- return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0];
1183
+ return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0]?.keyring;
1162
1184
  }
1163
1185
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getKeyringById).call(this, keyringId);
1164
1186
  }, _KeyringController_getKeyringMetadata = function _KeyringController_getKeyringMetadata(keyring) {
1165
- const index = __classPrivateFieldGet(this, _KeyringController_keyrings, "f").findIndex((keyringCandidate) => keyringCandidate === keyring);
1166
- (0, utils_1.assert)(index !== -1, constants_1.KeyringControllerError.KeyringNotFound);
1167
- return __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f")[index];
1187
+ const keyringWithMetadata = __classPrivateFieldGet(this, _KeyringController_keyrings, "f").find((candidate) => candidate.keyring === keyring);
1188
+ if (!keyringWithMetadata) {
1189
+ throw new Error(constants_1.KeyringControllerError.KeyringNotFound);
1190
+ }
1191
+ return keyringWithMetadata.metadata;
1168
1192
  }, _KeyringController_getKeyringBuilderForType = function _KeyringController_getKeyringBuilderForType(type) {
1169
1193
  return __classPrivateFieldGet(this, _KeyringController_keyringBuilders, "f").find((keyringBuilder) => keyringBuilder.type === type);
1170
1194
  }, _KeyringController_addQRKeyring =
@@ -1217,7 +1241,6 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1217
1241
  });
1218
1242
  __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1219
1243
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1220
- __classPrivateFieldSet(this, _KeyringController_keyringsMetadata, [], "f");
1221
1244
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1222
1245
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
1223
1246
  }, _KeyringController_verifySeedPhrase =
@@ -1287,12 +1310,12 @@ async function _KeyringController_getUpdatedKeyrings() {
1287
1310
  async function _KeyringController_getSerializedKeyrings({ includeUnsupported } = {
1288
1311
  includeUnsupported: true,
1289
1312
  }) {
1290
- const serializedKeyrings = await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async (keyring) => {
1291
- const [type, data] = await Promise.all([
1292
- keyring.type,
1293
- keyring.serialize(),
1294
- ]);
1295
- return { type, data };
1313
+ const serializedKeyrings = await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async ({ keyring, metadata }) => {
1314
+ return {
1315
+ type: keyring.type,
1316
+ data: await keyring.serialize(),
1317
+ metadata,
1318
+ };
1296
1319
  }));
1297
1320
  if (includeUnsupported) {
1298
1321
  serializedKeyrings.push(...__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f"));
@@ -1308,7 +1331,6 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1308
1331
  async function _KeyringController_getSessionState() {
1309
1332
  return {
1310
1333
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1311
- keyringsMetadata: __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").slice(),
1312
1334
  password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1313
1335
  };
1314
1336
  }, _KeyringController_restoreSerializedKeyrings =
@@ -1316,12 +1338,23 @@ async function _KeyringController_getSessionState() {
1316
1338
  * Restore a serialized keyrings array.
1317
1339
  *
1318
1340
  * @param serializedKeyrings - The serialized keyrings array.
1341
+ * @returns The restored keyrings.
1319
1342
  */
1320
1343
  async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings) {
1321
1344
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1345
+ const keyrings = [];
1346
+ let newMetadata = false;
1322
1347
  for (const serializedKeyring of serializedKeyrings) {
1323
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreKeyring).call(this, serializedKeyring);
1348
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreKeyring).call(this, serializedKeyring);
1349
+ if (result) {
1350
+ const { keyring, metadata } = result;
1351
+ keyrings.push({ keyring, metadata });
1352
+ if (result.newMetadata) {
1353
+ newMetadata = true;
1354
+ }
1355
+ }
1324
1356
  }
1357
+ return { keyrings, newMetadata };
1325
1358
  }, _KeyringController_unlockKeyrings =
1326
1359
  /**
1327
1360
  * Unlock Keyrings, decrypting the vault and deserializing all
@@ -1378,12 +1411,7 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1378
1411
  if (!isSerializedKeyringsArray(vault)) {
1379
1412
  throw new Error(constants_1.KeyringControllerError.VaultDataError);
1380
1413
  }
1381
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, vault);
1382
- // The keyrings array and the keyringsMetadata array should
1383
- // always have the same length while the controller is unlocked.
1384
- if (__classPrivateFieldGet(this, _KeyringController_keyrings, "f").length !== __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").length) {
1385
- throw new Error(constants_1.KeyringControllerError.KeyringMetadataLengthMismatch);
1386
- }
1414
+ const { keyrings, newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, vault);
1387
1415
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1388
1416
  this.update((state) => {
1389
1417
  state.keyrings = updatedKeyrings;
@@ -1392,7 +1420,7 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1392
1420
  state.encryptionSalt = updatedState.encryptionSalt;
1393
1421
  }
1394
1422
  });
1395
- return __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
1423
+ return { keyrings, newMetadata };
1396
1424
  });
1397
1425
  }, _KeyringController_updateVault = function _KeyringController_updateVault() {
1398
1426
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
@@ -1436,13 +1464,9 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1436
1464
  throw new Error(constants_1.KeyringControllerError.MissingVaultData);
1437
1465
  }
1438
1466
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1439
- if (updatedKeyrings.length !== __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").length) {
1440
- throw new Error(constants_1.KeyringControllerError.KeyringMetadataLengthMismatch);
1441
- }
1442
1467
  this.update((state) => {
1443
1468
  state.vault = updatedState.vault;
1444
1469
  state.keyrings = updatedKeyrings;
1445
- state.keyringsMetadata = __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").slice();
1446
1470
  if (updatedState.encryptionKey) {
1447
1471
  state.encryptionKey = updatedState.encryptionKey;
1448
1472
  state.encryptionSalt = JSON.parse(updatedState.vault).salt;
@@ -1450,31 +1474,23 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1450
1474
  });
1451
1475
  return true;
1452
1476
  });
1453
- }, _KeyringController_upgradeVaultEncryptionParams =
1454
- /**
1455
- * Upgrade the vault encryption parameters if needed.
1456
- *
1457
- * @returns A promise resolving to `void`.
1458
- */
1459
- async function _KeyringController_upgradeVaultEncryptionParams() {
1460
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1477
+ }, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
1461
1478
  const { vault } = this.state;
1462
- if (vault &&
1463
- __classPrivateFieldGet(this, _KeyringController_password, "f") &&
1464
- __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated &&
1465
- !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault)) {
1466
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1479
+ if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1480
+ return false;
1467
1481
  }
1482
+ return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
1468
1483
  }, _KeyringController_getAccountsFromKeyrings =
1469
1484
  /**
1470
1485
  * Retrieves all the accounts from keyrings instances
1471
1486
  * that are currently in memory.
1472
1487
  *
1488
+ * @param additionalKeyrings - Additional keyrings to include in the search.
1473
1489
  * @returns A promise resolving to an array of accounts.
1474
1490
  */
1475
- async function _KeyringController_getAccountsFromKeyrings() {
1476
- const keyrings = __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
1477
- const keyringArrays = await Promise.all(keyrings.map(async (keyring) => keyring.getAccounts()));
1491
+ async function _KeyringController_getAccountsFromKeyrings(additionalKeyrings = []) {
1492
+ const keyrings = __classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(({ keyring }) => keyring);
1493
+ const keyringArrays = await Promise.all([...keyrings, ...additionalKeyrings].map(async (keyring) => keyring.getAccounts()));
1478
1494
  const addresses = keyringArrays.reduce((res, arr) => {
1479
1495
  return res.concat(arr);
1480
1496
  }, []);
@@ -1514,11 +1530,7 @@ async function _KeyringController_createKeyringWithFirstAccount(type, opts) {
1514
1530
  */
1515
1531
  async function _KeyringController_newKeyring(type, data) {
1516
1532
  const keyring = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyring).call(this, type, data);
1517
- if (__classPrivateFieldGet(this, _KeyringController_keyrings, "f").length !== __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").length) {
1518
- throw new Error('Keyring metadata missing');
1519
- }
1520
- __classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
1521
- __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").push(getDefaultKeyringMetadata());
1533
+ __classPrivateFieldGet(this, _KeyringController_keyrings, "f").push({ keyring, metadata: getDefaultKeyringMetadata() });
1522
1534
  return keyring;
1523
1535
  }, _KeyringController_createKeyring =
1524
1536
  /**
@@ -1575,7 +1587,7 @@ async function _KeyringController_createKeyring(type, data) {
1575
1587
  */
1576
1588
  async function _KeyringController_clearKeyrings() {
1577
1589
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1578
- for (const keyring of __classPrivateFieldGet(this, _KeyringController_keyrings, "f")) {
1590
+ for (const { keyring } of __classPrivateFieldGet(this, _KeyringController_keyrings, "f")) {
1579
1591
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
1580
1592
  }
1581
1593
  __classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
@@ -1591,18 +1603,24 @@ async function _KeyringController_clearKeyrings() {
1591
1603
  async function _KeyringController_restoreKeyring(serialized) {
1592
1604
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1593
1605
  try {
1594
- const { type, data } = serialized;
1606
+ const { type, data, metadata: serializedMetadata } = serialized;
1607
+ let newMetadata = false;
1608
+ let metadata = serializedMetadata;
1595
1609
  const keyring = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyring).call(this, type, data);
1610
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this, [keyring]);
1596
1611
  // If metadata is missing, assume the data is from an installation before
1597
1612
  // we had keyring metadata.
1598
- if (__classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").length <= __classPrivateFieldGet(this, _KeyringController_keyrings, "f").length) {
1599
- console.log(`Adding missing metadata for '${type}' keyring`);
1600
- __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").push(getDefaultKeyringMetadata());
1613
+ if (!metadata) {
1614
+ newMetadata = true;
1615
+ metadata = getDefaultKeyringMetadata();
1601
1616
  }
1602
1617
  // The keyring is added to the keyrings array only if it's successfully restored
1603
1618
  // and the metadata is successfully added to the controller
1604
- __classPrivateFieldGet(this, _KeyringController_keyrings, "f").push(keyring);
1605
- return keyring;
1619
+ __classPrivateFieldGet(this, _KeyringController_keyrings, "f").push({
1620
+ keyring,
1621
+ metadata,
1622
+ });
1623
+ return { keyring, metadata, newMetadata };
1606
1624
  }
1607
1625
  catch (error) {
1608
1626
  console.error(error);
@@ -1631,30 +1649,28 @@ async function _KeyringController_destroyKeyring(keyring) {
1631
1649
  async function _KeyringController_removeEmptyKeyrings() {
1632
1650
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1633
1651
  const validKeyrings = [];
1634
- const validKeyringMetadata = [];
1635
1652
  // Since getAccounts returns a Promise
1636
1653
  // We need to wait to hear back form each keyring
1637
1654
  // in order to decide which ones are now valid (accounts.length > 0)
1638
- await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async (keyring, index) => {
1655
+ await Promise.all(__classPrivateFieldGet(this, _KeyringController_keyrings, "f").map(async ({ keyring, metadata }) => {
1639
1656
  const accounts = await keyring.getAccounts();
1640
1657
  if (accounts.length > 0) {
1641
- validKeyrings.push(keyring);
1642
- validKeyringMetadata.push(__classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f")[index]);
1658
+ validKeyrings.push({ keyring, metadata });
1643
1659
  }
1644
1660
  else {
1645
1661
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_destroyKeyring).call(this, keyring);
1646
1662
  }
1647
1663
  }));
1648
1664
  __classPrivateFieldSet(this, _KeyringController_keyrings, validKeyrings, "f");
1649
- __classPrivateFieldSet(this, _KeyringController_keyringsMetadata, validKeyringMetadata, "f");
1650
1665
  }, _KeyringController_assertNoDuplicateAccounts =
1651
1666
  /**
1652
1667
  * Assert that there are no duplicate accounts in the keyrings.
1653
1668
  *
1669
+ * @param additionalKeyrings - Additional keyrings to include in the check.
1654
1670
  * @throws If there are duplicate accounts.
1655
1671
  */
1656
- async function _KeyringController_assertNoDuplicateAccounts() {
1657
- const accounts = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getAccountsFromKeyrings).call(this);
1672
+ async function _KeyringController_assertNoDuplicateAccounts(additionalKeyrings = []) {
1673
+ const accounts = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getAccountsFromKeyrings).call(this, additionalKeyrings);
1658
1674
  if (new Set(accounts).size !== accounts.length) {
1659
1675
  throw new Error(constants_1.KeyringControllerError.DuplicatedAccount);
1660
1676
  }
@@ -1662,11 +1678,6 @@ async function _KeyringController_assertNoDuplicateAccounts() {
1662
1678
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1663
1679
  this.update((state) => {
1664
1680
  state.isUnlocked = true;
1665
- // If new keyringsMetadata was generated during the unlock operation,
1666
- // we'll have to update the state with the new array
1667
- if (__classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").length > state.keyringsMetadata.length) {
1668
- state.keyringsMetadata = __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").slice();
1669
- }
1670
1681
  });
1671
1682
  this.messagingSystem.publish(`${name}:unlock`);
1672
1683
  }, _KeyringController_assertIsUnlocked = function _KeyringController_assertIsUnlocked() {
@@ -1705,13 +1716,11 @@ async function _KeyringController_withRollback(callback) {
1705
1716
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1706
1717
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1707
1718
  const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1708
- const currentKeyringsMetadata = __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").slice();
1709
1719
  try {
1710
1720
  return await callback({ releaseLock });
1711
1721
  }
1712
1722
  catch (e) {
1713
1723
  // Keyrings and password are restored to their previous state
1714
- __classPrivateFieldSet(this, _KeyringController_keyringsMetadata, currentKeyringsMetadata, "f");
1715
1724
  __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1716
1725
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1717
1726
  throw e;