@metamask-previews/keyring-controller 22.0.2-preview-a272c5e1 → 22.0.2-preview-cf465cec

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,14 +7,6 @@ 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
-
14
- ### Changed
15
-
16
- - Upgrade mock encryptor to support multiple ciphertexts ([#5943](https://github.com/MetaMask/core/pull/5943))
17
-
18
10
  ## [22.0.2]
19
11
 
20
12
  ### 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_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;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveEncryptionKey, _KeyringController_useEncryptionKey, _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");
@@ -168,17 +168,6 @@ 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
- }
182
171
  /**
183
172
  * Checks if the provided value is a serialized keyrings array.
184
173
  *
@@ -269,7 +258,6 @@ class KeyringController extends base_controller_1.BaseController {
269
258
  keyrings: { persist: false, anonymous: false },
270
259
  encryptionKey: { persist: false, anonymous: false },
271
260
  encryptionSalt: { persist: false, anonymous: false },
272
- encryptedEncryptionKey: { persist: true, anonymous: false },
273
261
  },
274
262
  messenger,
275
263
  state: {
@@ -282,24 +270,17 @@ class KeyringController extends base_controller_1.BaseController {
282
270
  _KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
283
271
  _KeyringController_keyringBuilders.set(this, void 0);
284
272
  _KeyringController_encryptor.set(this, void 0);
285
- _KeyringController_cacheEncryptionKey.set(this, void 0);
286
273
  _KeyringController_keyrings.set(this, void 0);
287
274
  _KeyringController_unsupportedKeyrings.set(this, void 0);
288
- _KeyringController_password.set(this, void 0);
289
275
  _KeyringController_encryptionKey.set(this, void 0);
290
276
  _KeyringController_qrKeyringStateListener.set(this, void 0);
291
277
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
292
278
  ? keyringBuilders.concat(defaultKeyringBuilders)
293
279
  : defaultKeyringBuilders, "f");
280
+ assertIsExportableKeyEncryptor(encryptor);
294
281
  __classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
295
282
  __classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
296
283
  __classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
297
- // This option allows the controller to cache an exported key
298
- // for use in decrypting and encrypting data without password
299
- __classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
300
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
301
- assertIsExportableKeyEncryptor(encryptor);
302
- }
303
284
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
304
285
  }
305
286
  /**
@@ -386,22 +367,19 @@ class KeyringController extends base_controller_1.BaseController {
386
367
  /**
387
368
  * Create a new vault and primary keyring.
388
369
  *
389
- * This only works if keyrings are empty. If there is a pre-existing unlocked
390
- * vault, calling this will have no effect. If there is a pre-existing locked
391
- * vault, it will be replaced.
370
+ * This only works if keyrings are empty. If there is a pre-existing unlocked vault, calling this will have no effect.
371
+ * If there is a pre-existing locked vault, it will be replaced.
392
372
  *
393
373
  * @param password - Password to unlock the new vault.
394
- * @param encryptionKey - Optional encryption key to encrypt the new vault. If
395
- * set, envelope encryption will be used.
396
374
  * @returns Promise resolving when the operation ends successfully.
397
375
  */
398
- async createNewVaultAndKeychain(password, encryptionKey) {
376
+ async createNewVaultAndKeychain(password) {
399
377
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
400
378
  const accounts = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getAccountsFromKeyrings).call(this);
401
379
  if (!accounts.length) {
402
380
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
403
381
  type: KeyringTypes.hd,
404
- }, encryptionKey);
382
+ });
405
383
  }
406
384
  });
407
385
  }
@@ -430,16 +408,7 @@ class KeyringController extends base_controller_1.BaseController {
430
408
  if (!this.state.vault) {
431
409
  throw new Error(constants_1.KeyringControllerError.VaultError);
432
410
  }
433
- if (this.state.encryptedEncryptionKey) {
434
- // Envelope encryption mode.
435
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
436
- const key = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.encryptedEncryptionKey));
437
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(key);
438
- await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, this.state.vault);
439
- }
440
- else {
441
- await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
442
- }
411
+ await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
443
412
  }
444
413
  /**
445
414
  * Returns the status of the vault.
@@ -628,7 +597,7 @@ class KeyringController extends base_controller_1.BaseController {
628
597
  try {
629
598
  wallet = ethereumjs_wallet_1.thirdparty.fromEtherWallet(input, password);
630
599
  }
631
- catch {
600
+ catch (e) {
632
601
  wallet = wallet || (await ethereumjs_wallet_1.default.fromV3(input, password, true));
633
602
  }
634
603
  privateKey = (0, utils_1.bytesToHex)(wallet.getPrivateKey());
@@ -686,7 +655,6 @@ class KeyringController extends base_controller_1.BaseController {
686
655
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
687
656
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
688
657
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
689
- __classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
690
658
  __classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
691
659
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
692
660
  this.update((state) => {
@@ -868,33 +836,10 @@ class KeyringController extends base_controller_1.BaseController {
868
836
  * @returns Promise resolving when the operation completes.
869
837
  */
870
838
  changePassword(password) {
871
- return this.changePasswordAndEncryptionKey(password);
872
- }
873
- /**
874
- * Changes the password and encryption key used to encrypt the vault.
875
- *
876
- * @param password - The new password.
877
- * @param encryptionKey - The new encryption key. If omitted, the encryption
878
- * key will not be changed.
879
- * @returns Promise resolving when the operation completes.
880
- */
881
- changePasswordAndEncryptionKey(password, encryptionKey) {
882
839
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
883
840
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
884
841
  assertIsValidPassword(password);
885
- // Update password.
886
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
887
- // Update encryption key.
888
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
889
- // We need to clear encryption key and salt from state
890
- // to force the controller to re-encrypt the vault using
891
- // the new password.
892
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
893
- this.update((state) => {
894
- delete state.encryptionKey;
895
- delete state.encryptionSalt;
896
- });
897
- }
842
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
898
843
  });
899
844
  }
900
845
  /**
@@ -902,12 +847,13 @@ class KeyringController extends base_controller_1.BaseController {
902
847
  * using the given encryption key and salt.
903
848
  *
904
849
  * @param encryptionKey - Key to unlock the keychain.
905
- * @param encryptionSalt - Salt to unlock the keychain.
906
850
  * @returns Promise resolving when the operation completes.
907
851
  */
908
- async submitEncryptionKey(encryptionKey, encryptionSalt) {
852
+ async submitEncryptionKey(encryptionKey) {
909
853
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
910
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
854
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
855
+ exportedEncryptionKey: encryptionKey,
856
+ });
911
857
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
912
858
  return result;
913
859
  });
@@ -935,7 +881,7 @@ class KeyringController extends base_controller_1.BaseController {
935
881
  */
936
882
  async submitPassword(password) {
937
883
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
938
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
884
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
939
885
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
940
886
  return result;
941
887
  });
@@ -945,6 +891,12 @@ class KeyringController extends base_controller_1.BaseController {
945
891
  // can attempt to upgrade the vault.
946
892
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
947
893
  if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
894
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
895
+ // If the vault is being upgraded, we want to ignore the metadata
896
+ // that is already in the vault, so we can effectively
897
+ // re-encrypt the vault with the new encryption config.
898
+ ignoreVautKeyMetadata: true,
899
+ });
948
900
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
949
901
  }
950
902
  });
@@ -1199,7 +1151,7 @@ class KeyringController extends base_controller_1.BaseController {
1199
1151
  }
1200
1152
  }
1201
1153
  exports.KeyringController = KeyringController;
1202
- _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() {
1154
+ _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_encryptionKey = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1203
1155
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1204
1156
  this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1205
1157
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1268,10 +1220,9 @@ async function _KeyringController_addQRKeyring() {
1268
1220
  * @param keyring - A object containing the params to instantiate a new keyring.
1269
1221
  * @param keyring.type - The keyring type.
1270
1222
  * @param keyring.opts - Optional parameters required to instantiate the keyring.
1271
- * @param encryptionKey - Optional encryption key to encrypt the vault.
1272
1223
  * @returns A promise that resolves to the state.
1273
1224
  */
1274
- async function _KeyringController_createNewVaultWithKeyring(password, keyring, encryptionKey) {
1225
+ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1275
1226
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1276
1227
  if (typeof password !== 'string') {
1277
1228
  throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
@@ -1280,18 +1231,64 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring, e
1280
1231
  delete state.encryptionKey;
1281
1232
  delete state.encryptionSalt;
1282
1233
  });
1283
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1284
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
1234
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
1285
1235
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1286
1236
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1287
1237
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
1288
- }, _KeyringController_updateCachedEncryptionKey = function _KeyringController_updateCachedEncryptionKey(encryptionKey) {
1289
- if (!encryptionKey && this.state.encryptedEncryptionKey) {
1290
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, this.state.encryptionKey, "f");
1238
+ }, _KeyringController_deriveEncryptionKey =
1239
+ /**
1240
+ * Derive the vault encryption key from the provided password, and
1241
+ * assign it to the class variable for later use with cryptographic
1242
+ * functions.
1243
+ *
1244
+ * When the controller has a vault in its state, the key is derived
1245
+ * using the salt from the vault. If the vault is empty, a new salt
1246
+ * is generated and used to derive the key.
1247
+ *
1248
+ * @param password - The password to use for decryption or derivation.
1249
+ */
1250
+ async function _KeyringController_deriveEncryptionKey(password, options = {
1251
+ ignoreVautKeyMetadata: false,
1252
+ }) {
1253
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1254
+ const { vault } = this.state;
1255
+ if (typeof password !== 'string') {
1256
+ throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1257
+ }
1258
+ let salt, keyMetadata;
1259
+ if (vault && !options.ignoreVautKeyMetadata) {
1260
+ const parsedVault = JSON.parse(vault);
1261
+ salt = parsedVault.salt;
1262
+ keyMetadata = parsedVault.keyMetadata;
1291
1263
  }
1292
1264
  else {
1293
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, encryptionKey, "f");
1265
+ salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
1294
1266
  }
1267
+ const exportedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
1268
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1269
+ salt,
1270
+ exported: exportedEncryptionKey,
1271
+ }, "f");
1272
+ }, _KeyringController_useEncryptionKey =
1273
+ /**
1274
+ * Use the provided encryption key and salt to set the
1275
+ * encryptionKey class variable. This method is used
1276
+ * when the user provides an encryption key and salt
1277
+ * to unlock the keychain, instead of using a password.
1278
+ *
1279
+ * @param encryptionKey - The encryption key to use.
1280
+ * @param encryptionSalt - The salt to use for the encryption key.
1281
+ */
1282
+ async function _KeyringController_useEncryptionKey(encryptionKey, encryptionSalt) {
1283
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1284
+ if (typeof encryptionKey !== 'string' ||
1285
+ typeof encryptionSalt !== 'string') {
1286
+ throw new TypeError(constants_1.KeyringControllerError.WrongEncryptionKeyType);
1287
+ }
1288
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1289
+ salt: encryptionSalt,
1290
+ exported: encryptionKey,
1291
+ }, "f");
1295
1292
  }, _KeyringController_verifySeedPhrase =
1296
1293
  /**
1297
1294
  * Internal non-exclusive method to verify the seed phrase.
@@ -1380,7 +1377,6 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1380
1377
  async function _KeyringController_getSessionState() {
1381
1378
  return {
1382
1379
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1383
- password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1384
1380
  encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
1385
1381
  };
1386
1382
  }, _KeyringController_restoreSerializedKeyrings =
@@ -1410,63 +1406,28 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1410
1406
  * Unlock Keyrings, decrypting the vault and deserializing all
1411
1407
  * keyrings contained in it, using a password or an encryption key with salt.
1412
1408
  *
1413
- * @param password - The keyring controller password.
1414
- * @param encryptionKey - An exported key string to unlock keyrings with.
1415
- * @param encryptionSalt - The salt used to encrypt the vault.
1409
+ * @param credentials - The credentials to unlock the keyrings.
1416
1410
  * @returns A promise resolving to the deserialized keyrings array.
1417
1411
  */
1418
- async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1412
+ async function _KeyringController_unlockKeyrings(credentials) {
1419
1413
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1420
- const { vault: encryptedVault, encryptedEncryptionKey } = this.state;
1421
- if (!encryptedVault) {
1414
+ if (!this.state.vault) {
1422
1415
  throw new Error(constants_1.KeyringControllerError.VaultError);
1423
1416
  }
1424
- let vault;
1425
- const updatedState = {};
1426
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1427
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1428
- if (password) {
1429
- if (encryptedEncryptionKey) {
1430
- const key = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedEncryptionKey));
1431
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(key);
1432
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, encryptedVault);
1433
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1434
- updatedState.encryptionKey = key;
1435
- }
1436
- else {
1437
- const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1438
- vault = result.vault;
1439
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1440
- updatedState.encryptionKey = result.exportedKeyString;
1441
- updatedState.encryptionSalt = result.salt;
1442
- }
1443
- }
1444
- else {
1445
- const parsedEncryptedVault = JSON.parse(encryptedVault);
1446
- if (encryptionSalt !== parsedEncryptedVault.salt) {
1447
- throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
1448
- }
1449
- if (typeof encryptionKey !== 'string') {
1450
- throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1451
- }
1452
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1453
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1454
- // This call is required on the first call because encryptionKey
1455
- // is not yet inside the memStore
1456
- updatedState.encryptionKey = encryptionKey;
1457
- // we can safely assume that encryptionSalt is defined here
1458
- // because we compare it with the salt from the vault
1459
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1460
- updatedState.encryptionSalt = encryptionSalt;
1461
- }
1417
+ const parsedEncryptedVault = JSON.parse(this.state.vault);
1418
+ if ('password' in credentials) {
1419
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, credentials.password);
1462
1420
  }
1463
1421
  else {
1464
- if (typeof password !== 'string') {
1465
- throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1466
- }
1467
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
1468
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1422
+ const { exportedEncryptionKey } = credentials;
1423
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, exportedEncryptionKey, parsedEncryptedVault.salt);
1424
+ }
1425
+ const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1426
+ if (!encryptionKey) {
1427
+ throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1469
1428
  }
1429
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1430
+ const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1470
1431
  if (!isSerializedKeyringsArray(vault)) {
1471
1432
  throw new Error(constants_1.KeyringControllerError.VaultDataError);
1472
1433
  }
@@ -1474,10 +1435,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1474
1435
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1475
1436
  this.update((state) => {
1476
1437
  state.keyrings = updatedKeyrings;
1477
- if (updatedState.encryptionKey || updatedState.encryptionSalt) {
1478
- state.encryptionKey = updatedState.encryptionKey;
1479
- state.encryptionSalt = updatedState.encryptionSalt;
1480
- }
1438
+ state.encryptionKey = encryptionKey;
1439
+ state.encryptionSalt = parsedEncryptedVault.salt;
1481
1440
  });
1482
1441
  return { keyrings, newMetadata };
1483
1442
  });
@@ -1485,81 +1444,41 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1485
1444
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1486
1445
  // Ensure no duplicate accounts are persisted.
1487
1446
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
1488
- const { encryptionKey, encryptionSalt, vault } = this.state;
1489
- // READ THIS CAREFULLY:
1490
- // We do check if the vault is still considered up-to-date, if not, we would not re-use the
1491
- // cached key and we will re-generate a new one (based on the password).
1492
- //
1493
- // This helps doing seamless updates of the vault. Useful in case we change some cryptographic
1494
- // parameters to the KDF.
1495
- const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
1496
- if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
1447
+ if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1497
1448
  throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1498
1449
  }
1499
1450
  const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1500
1451
  if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
1501
1452
  throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
1502
1453
  }
1503
- const updatedState = {};
1504
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1505
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1506
- if (useCachedKey) {
1507
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1508
- const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1509
- vaultJSON.salt = encryptionSalt;
1510
- updatedState.vault = JSON.stringify(vaultJSON);
1511
- }
1512
- else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1513
- if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1514
- // Update cached key.
1515
- updatedState.encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1516
- // Encrypt key and update encrypted key.
1517
- const encryptedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1518
- updatedState.encryptedEncryptionKey = encryptedKey;
1519
- // Encrypt and update vault.
1520
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1521
- const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(importedKey, serializedKeyrings);
1522
- updatedState.vault = JSON.stringify(vaultJSON);
1523
- }
1524
- else {
1525
- const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1526
- updatedState.vault = newVault;
1527
- updatedState.encryptionKey = exportedKeyString;
1528
- }
1529
- }
1530
- }
1531
- else {
1532
- assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
1533
- updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1534
- }
1535
- if (__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isEnvelopeEncryptionEnabled).call(this)) {
1536
- assertIsCacheEncryptionKeyTrue(__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f"));
1537
- }
1538
- if (!updatedState.vault) {
1539
- throw new Error(constants_1.KeyringControllerError.MissingVaultData);
1454
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported);
1455
+ const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1456
+ if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt) {
1457
+ // We need to include the salt used to derive
1458
+ // the encryption key, to be able to derive it
1459
+ // from password again.
1460
+ encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
1540
1461
  }
1462
+ const updatedState = {
1463
+ vault: JSON.stringify(encryptedVault),
1464
+ encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported,
1465
+ encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
1466
+ };
1541
1467
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1542
1468
  this.update((state) => {
1543
1469
  state.vault = updatedState.vault;
1544
1470
  state.keyrings = updatedKeyrings;
1545
- if (updatedState.encryptionKey) {
1546
- state.encryptionKey = updatedState.encryptionKey;
1547
- state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1548
- }
1549
- if (updatedState.encryptedEncryptionKey) {
1550
- state.encryptedEncryptionKey = updatedState.encryptedEncryptionKey;
1551
- }
1471
+ state.encryptionKey = updatedState.encryptionKey;
1472
+ state.encryptionSalt = updatedState.encryptionSalt;
1552
1473
  });
1553
1474
  return true;
1554
1475
  });
1555
1476
  }, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
1556
1477
  const { vault } = this.state;
1557
- if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1478
+ if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1558
1479
  return false;
1559
1480
  }
1560
1481
  return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
1561
- }, _KeyringController_isEnvelopeEncryptionEnabled = function _KeyringController_isEnvelopeEncryptionEnabled() {
1562
- return this.state.encryptedEncryptionKey || __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1563
1482
  }, _KeyringController_getAccountsFromKeyrings =
1564
1483
  /**
1565
1484
  * Retrieves all the accounts from keyrings instances
@@ -1644,8 +1563,7 @@ async function _KeyringController_createKeyring(type, data) {
1644
1563
  if (keyring.init) {
1645
1564
  await keyring.init();
1646
1565
  }
1647
- if (type === KeyringTypes.hd &&
1648
- (!(0, utils_1.isObject)(data) || !data.mnemonic)) {
1566
+ if (type === KeyringTypes.hd && (!(0, utils_1.isObject)(data) || !data.mnemonic)) {
1649
1567
  if (!keyring.generateRandomMnemonic) {
1650
1568
  throw new Error(constants_1.KeyringControllerError.UnsupportedGenerateRandomMnemonic);
1651
1569
  }
@@ -1767,16 +1685,11 @@ async function _KeyringController_assertNoDuplicateAccounts(additionalKeyrings =
1767
1685
  }
1768
1686
  }, _KeyringController_persistOrRollback =
1769
1687
  /**
1770
- * Execute the given function after acquiring the controller lock and save the
1771
- * vault to state after it (only if needed), or rollback to their previous
1772
- * state in case of error.
1773
- *
1774
- * ATTENTION: The callback must **not** alter `controller.state`. Any state
1775
- * change performed by the callback will not be rolled back on error.
1688
+ * Execute the given function after acquiring the controller lock
1689
+ * and save the vault to state after it (only if needed), or rollback to their
1690
+ * previous state in case of error.
1776
1691
  *
1777
- * @param callback - The function to execute. This callback must **not** alter
1778
- * `controller.state`. Any state change performed by the callback will not be
1779
- * rolled back on error.
1692
+ * @param callback - The function to execute.
1780
1693
  * @returns The result of the function.
1781
1694
  */
1782
1695
  async function _KeyringController_persistOrRollback(callback) {
@@ -1801,13 +1714,16 @@ async function _KeyringController_persistOrRollback(callback) {
1801
1714
  async function _KeyringController_withRollback(callback) {
1802
1715
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1803
1716
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1804
- const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1717
+ const currentEncryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1718
+ const currentEncryptionSalt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.salt;
1805
1719
  try {
1806
1720
  return await callback({ releaseLock });
1807
1721
  }
1808
1722
  catch (e) {
1809
- // Keyrings and password are restored to their previous state
1810
- __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1723
+ // Keyrings and encryption credentials are restored to their previous state
1724
+ if (currentEncryptionKey && currentEncryptionSalt) {
1725
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, currentEncryptionKey, currentEncryptionSalt);
1726
+ }
1811
1727
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1812
1728
  throw e;
1813
1729
  }