@metamask-previews/keyring-controller 22.0.2-preview-4193b35 → 22.0.2-preview-0013a1bd

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,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Add support for envelope encryption ([#5940](https://github.com/MetaMask/core/pull/5940))
13
+
10
14
  ## [22.0.2]
11
15
 
12
16
  ### Fixed
@@ -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_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;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_encryptionKey, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_updateCachedEncryptionKey, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_isEnvelopeEncryptionEnabled, _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");
@@ -168,6 +168,17 @@ function assertIsValidPassword(password) {
168
168
  throw new Error(constants_1.KeyringControllerError.InvalidEmptyPassword);
169
169
  }
170
170
  }
171
+ /**
172
+ * Assert that the provided cacheEncryptionKey is true.
173
+ *
174
+ * @param cacheEncryptionKey - The cacheEncryptionKey to check.
175
+ * @throws If the cacheEncryptionKey is not true.
176
+ */
177
+ function assertIsCacheEncryptionKeyTrue(cacheEncryptionKey) {
178
+ if (!cacheEncryptionKey) {
179
+ throw new Error(constants_1.KeyringControllerError.CacheEncryptionKeyDisabled);
180
+ }
181
+ }
171
182
  /**
172
183
  * Checks if the provided value is a serialized keyrings array.
173
184
  *
@@ -258,6 +269,7 @@ class KeyringController extends base_controller_1.BaseController {
258
269
  keyrings: { persist: false, anonymous: false },
259
270
  encryptionKey: { persist: false, anonymous: false },
260
271
  encryptionSalt: { persist: false, anonymous: false },
272
+ encryptedEncryptionKey: { persist: true, anonymous: false },
261
273
  },
262
274
  messenger,
263
275
  state: {
@@ -274,6 +286,7 @@ class KeyringController extends base_controller_1.BaseController {
274
286
  _KeyringController_keyrings.set(this, void 0);
275
287
  _KeyringController_unsupportedKeyrings.set(this, void 0);
276
288
  _KeyringController_password.set(this, void 0);
289
+ _KeyringController_encryptionKey.set(this, void 0);
277
290
  _KeyringController_qrKeyringStateListener.set(this, void 0);
278
291
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
279
292
  ? keyringBuilders.concat(defaultKeyringBuilders)
@@ -356,9 +369,11 @@ class KeyringController extends base_controller_1.BaseController {
356
369
  * @param password - Password to unlock keychain.
357
370
  * @param seed - A BIP39-compliant seed phrase as Uint8Array,
358
371
  * either as a string or an array of UTF-8 bytes that represent the string.
372
+ * @param encryptionKey - Optional encryption key to encrypt the new vault. If
373
+ * set, envelope encryption will be used.
359
374
  * @returns Promise resolving when the operation ends successfully.
360
375
  */
361
- async createNewVaultAndRestore(password, seed) {
376
+ async createNewVaultAndRestore(password, seed, encryptionKey) {
362
377
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
363
378
  assertIsValidPassword(password);
364
379
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
@@ -367,25 +382,28 @@ class KeyringController extends base_controller_1.BaseController {
367
382
  mnemonic: seed,
368
383
  numberOfAccounts: 1,
369
384
  },
370
- });
385
+ }, encryptionKey);
371
386
  });
372
387
  }
373
388
  /**
374
389
  * Create a new vault and primary keyring.
375
390
  *
376
- * This only works if keyrings are empty. If there is a pre-existing unlocked vault, calling this will have no effect.
377
- * If there is a pre-existing locked vault, it will be replaced.
391
+ * This only works if keyrings are empty. If there is a pre-existing unlocked
392
+ * vault, calling this will have no effect. If there is a pre-existing locked
393
+ * vault, it will be replaced.
378
394
  *
379
395
  * @param password - Password to unlock the new vault.
396
+ * @param encryptionKey - Optional encryption key to encrypt the new vault. If
397
+ * set, envelope encryption will be used.
380
398
  * @returns Promise resolving when the operation ends successfully.
381
399
  */
382
- async createNewVaultAndKeychain(password) {
400
+ async createNewVaultAndKeychain(password, encryptionKey) {
383
401
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
384
402
  const accounts = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getAccountsFromKeyrings).call(this);
385
403
  if (!accounts.length) {
386
404
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
387
405
  type: KeyringTypes.hd,
388
- });
406
+ }, encryptionKey);
389
407
  }
390
408
  });
391
409
  }
@@ -414,7 +432,16 @@ class KeyringController extends base_controller_1.BaseController {
414
432
  if (!this.state.vault) {
415
433
  throw new Error(constants_1.KeyringControllerError.VaultError);
416
434
  }
417
- await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
435
+ if (this.state.encryptedEncryptionKey) {
436
+ // Envelope encryption mode.
437
+ assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
438
+ const decryptedEncryptionKey = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.encryptedEncryptionKey));
439
+ const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(decryptedEncryptionKey);
440
+ await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, this.state.vault);
441
+ }
442
+ else {
443
+ await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
444
+ }
418
445
  }
419
446
  /**
420
447
  * Returns the status of the vault.
@@ -603,7 +630,7 @@ class KeyringController extends base_controller_1.BaseController {
603
630
  try {
604
631
  wallet = ethereumjs_wallet_1.thirdparty.fromEtherWallet(input, password);
605
632
  }
606
- catch (e) {
633
+ catch {
607
634
  wallet = wallet || (await ethereumjs_wallet_1.default.fromV3(input, password, true));
608
635
  }
609
636
  privateKey = (0, utils_1.bytesToHex)(wallet.getPrivateKey());
@@ -662,6 +689,7 @@ class KeyringController extends base_controller_1.BaseController {
662
689
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
663
690
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
664
691
  __classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
692
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
665
693
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
666
694
  this.update((state) => {
667
695
  state.isUnlocked = false;
@@ -842,10 +870,24 @@ class KeyringController extends base_controller_1.BaseController {
842
870
  * @returns Promise resolving when the operation completes.
843
871
  */
844
872
  changePassword(password) {
873
+ return this.changePasswordAndEncryptionKey(password);
874
+ }
875
+ /**
876
+ * Changes the password and encryption key used to encrypt the vault.
877
+ *
878
+ * @param password - The new password.
879
+ * @param encryptionKey - The new encryption key. If omitted, the encryption
880
+ * key will not be changed.
881
+ * @returns Promise resolving when the operation completes.
882
+ */
883
+ changePasswordAndEncryptionKey(password, encryptionKey) {
845
884
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
846
885
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
847
886
  assertIsValidPassword(password);
887
+ // Update password.
848
888
  __classPrivateFieldSet(this, _KeyringController_password, password, "f");
889
+ // Update encryption key.
890
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
849
891
  // We need to clear encryption key and salt from state
850
892
  // to force the controller to re-encrypt the vault using
851
893
  // the new password.
@@ -1159,7 +1201,7 @@ class KeyringController extends base_controller_1.BaseController {
1159
1201
  }
1160
1202
  }
1161
1203
  exports.KeyringController = KeyringController;
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() {
1204
+ _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_encryptionKey = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1163
1205
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1164
1206
  this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1165
1207
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1228,9 +1270,10 @@ async function _KeyringController_addQRKeyring() {
1228
1270
  * @param keyring - A object containing the params to instantiate a new keyring.
1229
1271
  * @param keyring.type - The keyring type.
1230
1272
  * @param keyring.opts - Optional parameters required to instantiate the keyring.
1273
+ * @param encryptionKey - Optional encryption key to encrypt the vault.
1231
1274
  * @returns A promise that resolves to the state.
1232
1275
  */
1233
- async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1276
+ async function _KeyringController_createNewVaultWithKeyring(password, keyring, encryptionKey) {
1234
1277
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1235
1278
  if (typeof password !== 'string') {
1236
1279
  throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
@@ -1240,9 +1283,20 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1240
1283
  delete state.encryptionSalt;
1241
1284
  });
1242
1285
  __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1286
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
1243
1287
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1244
1288
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1245
1289
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
1290
+ }, _KeyringController_updateCachedEncryptionKey = function _KeyringController_updateCachedEncryptionKey(encryptionKey) {
1291
+ if (!encryptionKey && this.state.encryptedEncryptionKey) {
1292
+ // If no encryption key is provided and we are in envelope encryption
1293
+ // mode, use the cached encryption key. This case occurs when we call
1294
+ // change password without providing a new encryption key.
1295
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, this.state.encryptionKey, "f");
1296
+ }
1297
+ else {
1298
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, encryptionKey, "f");
1299
+ }
1246
1300
  }, _KeyringController_verifySeedPhrase =
1247
1301
  /**
1248
1302
  * Internal non-exclusive method to verify the seed phrase.
@@ -1332,6 +1386,7 @@ async function _KeyringController_getSessionState() {
1332
1386
  return {
1333
1387
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1334
1388
  password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1389
+ encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
1335
1390
  };
1336
1391
  }, _KeyringController_restoreSerializedKeyrings =
1337
1392
  /**
@@ -1367,7 +1422,7 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1367
1422
  */
1368
1423
  async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1369
1424
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1370
- const encryptedVault = this.state.vault;
1425
+ const { vault: encryptedVault, encryptedEncryptionKey } = this.state;
1371
1426
  if (!encryptedVault) {
1372
1427
  throw new Error(constants_1.KeyringControllerError.VaultError);
1373
1428
  }
@@ -1376,11 +1431,20 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1376
1431
  if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1377
1432
  assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1378
1433
  if (password) {
1379
- const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1380
- vault = result.vault;
1381
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1382
- updatedState.encryptionKey = result.exportedKeyString;
1383
- updatedState.encryptionSalt = result.salt;
1434
+ if (encryptedEncryptionKey) {
1435
+ const decryptedEncryptionKey = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedEncryptionKey));
1436
+ const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(decryptedEncryptionKey);
1437
+ vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, encryptedVault);
1438
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1439
+ updatedState.encryptionKey = decryptedEncryptionKey;
1440
+ }
1441
+ else {
1442
+ const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1443
+ vault = result.vault;
1444
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1445
+ updatedState.encryptionKey = result.exportedKeyString;
1446
+ updatedState.encryptionSalt = result.salt;
1447
+ }
1384
1448
  }
1385
1449
  else {
1386
1450
  const parsedEncryptedVault = JSON.parse(encryptedVault);
@@ -1390,8 +1454,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1390
1454
  if (typeof encryptionKey !== 'string') {
1391
1455
  throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1392
1456
  }
1393
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1394
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1457
+ const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1458
+ vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, parsedEncryptedVault);
1395
1459
  // This call is required on the first call because encryptionKey
1396
1460
  // is not yet inside the memStore
1397
1461
  updatedState.encryptionKey = encryptionKey;
@@ -1451,15 +1515,34 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1451
1515
  updatedState.vault = JSON.stringify(vaultJSON);
1452
1516
  }
1453
1517
  else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1454
- const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1455
- updatedState.vault = newVault;
1456
- updatedState.encryptionKey = exportedKeyString;
1518
+ if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1519
+ // Update cached key.
1520
+ updatedState.encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1521
+ // Encrypt key and update encrypted key.
1522
+ const encryptedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1523
+ updatedState.encryptedEncryptionKey = encryptedEncryptionKey;
1524
+ // Encrypt and update vault.
1525
+ const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1526
+ const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(importedKey, serializedKeyrings);
1527
+ // Note that we don't need to explicitly append the salt to the
1528
+ // vault here as it's already stored as part of the encrypted
1529
+ // encryption key.
1530
+ updatedState.vault = JSON.stringify(vaultJSON);
1531
+ }
1532
+ else {
1533
+ const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1534
+ updatedState.vault = newVault;
1535
+ updatedState.encryptionKey = exportedKeyString;
1536
+ }
1457
1537
  }
1458
1538
  }
1459
1539
  else {
1460
1540
  assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
1461
1541
  updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1462
1542
  }
1543
+ if (__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isEnvelopeEncryptionEnabled).call(this)) {
1544
+ assertIsCacheEncryptionKeyTrue(__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f"));
1545
+ }
1463
1546
  if (!updatedState.vault) {
1464
1547
  throw new Error(constants_1.KeyringControllerError.MissingVaultData);
1465
1548
  }
@@ -1471,6 +1554,9 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1471
1554
  state.encryptionKey = updatedState.encryptionKey;
1472
1555
  state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1473
1556
  }
1557
+ if (updatedState.encryptedEncryptionKey) {
1558
+ state.encryptedEncryptionKey = updatedState.encryptedEncryptionKey;
1559
+ }
1474
1560
  });
1475
1561
  return true;
1476
1562
  });
@@ -1480,6 +1566,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1480
1566
  return false;
1481
1567
  }
1482
1568
  return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
1569
+ }, _KeyringController_isEnvelopeEncryptionEnabled = function _KeyringController_isEnvelopeEncryptionEnabled() {
1570
+ return this.state.encryptedEncryptionKey || __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1483
1571
  }, _KeyringController_getAccountsFromKeyrings =
1484
1572
  /**
1485
1573
  * Retrieves all the accounts from keyrings instances
@@ -1564,7 +1652,8 @@ async function _KeyringController_createKeyring(type, data) {
1564
1652
  if (keyring.init) {
1565
1653
  await keyring.init();
1566
1654
  }
1567
- if (type === KeyringTypes.hd && (!(0, utils_1.isObject)(data) || !data.mnemonic)) {
1655
+ if (type === KeyringTypes.hd &&
1656
+ (!(0, utils_1.isObject)(data) || !data.mnemonic)) {
1568
1657
  if (!keyring.generateRandomMnemonic) {
1569
1658
  throw new Error(constants_1.KeyringControllerError.UnsupportedGenerateRandomMnemonic);
1570
1659
  }
@@ -1686,11 +1775,16 @@ async function _KeyringController_assertNoDuplicateAccounts(additionalKeyrings =
1686
1775
  }
1687
1776
  }, _KeyringController_persistOrRollback =
1688
1777
  /**
1689
- * Execute the given function after acquiring the controller lock
1690
- * and save the vault to state after it (only if needed), or rollback to their
1691
- * previous state in case of error.
1778
+ * Execute the given function after acquiring the controller lock and save the
1779
+ * vault to state after it (only if needed), or rollback to their previous
1780
+ * state in case of error.
1781
+ *
1782
+ * ATTENTION: The callback must **not** alter `controller.state`. Any state
1783
+ * change performed by the callback will not be rolled back on error.
1692
1784
  *
1693
- * @param callback - The function to execute.
1785
+ * @param callback - The function to execute. This callback must **not** alter
1786
+ * `controller.state`. Any state change performed by the callback will not be
1787
+ * rolled back on error.
1694
1788
  * @returns The result of the function.
1695
1789
  */
1696
1790
  async function _KeyringController_persistOrRollback(callback) {
@@ -1716,12 +1810,14 @@ async function _KeyringController_withRollback(callback) {
1716
1810
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1717
1811
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1718
1812
  const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1813
+ const currentEncryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1719
1814
  try {
1720
1815
  return await callback({ releaseLock });
1721
1816
  }
1722
1817
  catch (e) {
1723
- // Keyrings and password are restored to their previous state
1818
+ // Previous state is restored.
1724
1819
  __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1820
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, currentEncryptionKey, "f");
1725
1821
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1726
1822
  throw e;
1727
1823
  }