@metamask-previews/keyring-controller 24.0.0-preview-ca16f8f → 24.0.0-preview-dabf9bd8

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
@@ -17,7 +17,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
17
  - **BREAKING:** The `KeyringController` constructor options now require an encryptor ([#7127](https://github.com/MetaMask/core/pull/7127))
18
18
  - The `encryptor` constructor option was previously optional and defaulted to an instance of `@metamask/browser-passworder`.
19
19
  - **BREAKING:** The `GenericEncryptor` and `ExportableKeyEncryptor` types have been merged into a single `Encryptor` type ([#7127](https://github.com/MetaMask/core/pull/7127))
20
- - **BREAKING:** The `Encryptor` type requires `exportKey`, `keyFromPassword` and `generateSalt` methods ([#7128](https://github.com/MetaMask/core/pull/7128))
21
20
 
22
21
  ### Removed
23
22
 
@@ -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_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveAndSetEncryptionKey, _KeyringController_setEncryptionKey, _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_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _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");
@@ -289,7 +289,7 @@ class KeyringController extends base_controller_1.BaseController {
289
289
  _KeyringController_encryptor.set(this, void 0);
290
290
  _KeyringController_keyrings.set(this, void 0);
291
291
  _KeyringController_unsupportedKeyrings.set(this, void 0);
292
- _KeyringController_encryptionKey.set(this, void 0);
292
+ _KeyringController_password.set(this, void 0);
293
293
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
294
294
  ? keyringBuilders.concat(defaultKeyringBuilders)
295
295
  : defaultKeyringBuilders, "f");
@@ -666,7 +666,7 @@ class KeyringController extends base_controller_1.BaseController {
666
666
  async setLocked() {
667
667
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
668
668
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
669
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
669
+ __classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
670
670
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
671
671
  this.update((state) => {
672
672
  state.isUnlocked = false;
@@ -848,10 +848,19 @@ class KeyringController extends base_controller_1.BaseController {
848
848
  */
849
849
  changePassword(password) {
850
850
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
851
+ // If the password is the same, do nothing.
852
+ if (__classPrivateFieldGet(this, _KeyringController_password, "f") === password) {
853
+ return Promise.resolve();
854
+ }
851
855
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
852
856
  assertIsValidPassword(password);
853
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveAndSetEncryptionKey).call(this, password, {
854
- ignoreExistingVault: true,
857
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
858
+ // We need to clear encryption key and salt from state
859
+ // to force the controller to re-encrypt the vault using
860
+ // the new password.
861
+ this.update((state) => {
862
+ delete state.encryptionKey;
863
+ delete state.encryptionSalt;
855
864
  });
856
865
  });
857
866
  }
@@ -866,10 +875,7 @@ class KeyringController extends base_controller_1.BaseController {
866
875
  */
867
876
  async submitEncryptionKey(encryptionKey, encryptionSalt) {
868
877
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
869
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
870
- encryptionKey,
871
- encryptionSalt,
872
- });
878
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
873
879
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
874
880
  return result;
875
881
  });
@@ -896,8 +902,9 @@ class KeyringController extends base_controller_1.BaseController {
896
902
  async exportEncryptionKey() {
897
903
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
898
904
  return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
899
- assertIsEncryptionKeySet(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized);
900
- return __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized;
905
+ const { encryptionKey } = this.state;
906
+ assertIsEncryptionKeySet(encryptionKey);
907
+ return encryptionKey;
901
908
  });
902
909
  }
903
910
  /**
@@ -909,7 +916,7 @@ class KeyringController extends base_controller_1.BaseController {
909
916
  */
910
917
  async submitPassword(password) {
911
918
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
912
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
919
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
913
920
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
914
921
  return result;
915
922
  });
@@ -919,12 +926,6 @@ class KeyringController extends base_controller_1.BaseController {
919
926
  // can attempt to upgrade the vault.
920
927
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
921
928
  if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
922
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveAndSetEncryptionKey).call(this, password, {
923
- // If the vault is being upgraded, we want to ignore the metadata
924
- // that is already in the vault, so we can effectively
925
- // re-encrypt the vault with the new encryption config.
926
- ignoreExistingVault: true,
927
- });
928
929
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
929
930
  }
930
931
  });
@@ -987,7 +988,7 @@ class KeyringController extends base_controller_1.BaseController {
987
988
  }
988
989
  }
989
990
  exports.KeyringController = KeyringController;
990
- _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_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
991
+ _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_password = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
991
992
  this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
992
993
  this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
993
994
  this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1046,70 +1047,10 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1046
1047
  delete state.encryptionKey;
1047
1048
  delete state.encryptionSalt;
1048
1049
  });
1049
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveAndSetEncryptionKey).call(this, password, {
1050
- ignoreExistingVault: true,
1051
- });
1050
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1052
1051
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1053
1052
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1054
1053
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
1055
- }, _KeyringController_deriveAndSetEncryptionKey =
1056
- /**
1057
- * Derive the vault encryption key from the provided password, and
1058
- * assign it to the instance variable for later use with cryptographic
1059
- * functions.
1060
- *
1061
- * When the controller has a vault in its state, the key is derived
1062
- * using the salt from the vault. If the vault is empty, a new salt
1063
- * is generated and used to derive the key.
1064
- *
1065
- * If `options.ignoreExistingVault` is set to `true`, the existing
1066
- * vault is completely ignored: the new key won't be able to decrypt
1067
- * the existing vault, and should be used to re-encrypt it.
1068
- *
1069
- * @param password - The password to use for decryption or derivation.
1070
- * @param options - Options for the key derivation.
1071
- * @param options.ignoreExistingVault - Whether to ignore the existing vault salt and key metadata
1072
- */
1073
- async function _KeyringController_deriveAndSetEncryptionKey(password, options = {
1074
- ignoreExistingVault: false,
1075
- }) {
1076
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1077
- const { vault } = this.state;
1078
- if (typeof password !== 'string') {
1079
- throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1080
- }
1081
- let serializedEncryptionKey, salt;
1082
- if (vault && !options.ignoreExistingVault) {
1083
- // The `decryptWithDetail` method is being used here instead of
1084
- // `keyFromPassword` + `exportKey` to let the encryptor handle
1085
- // any legacy encryption formats and metadata that might be
1086
- // present (or absent) in the vault.
1087
- const { exportedKeyString, salt: existingSalt } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, vault);
1088
- serializedEncryptionKey = exportedKeyString;
1089
- salt = existingSalt;
1090
- }
1091
- else {
1092
- salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
1093
- serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true));
1094
- }
1095
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1096
- salt,
1097
- serialized: serializedEncryptionKey,
1098
- }, "f");
1099
- }, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
1100
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1101
- if (typeof encryptionKey !== 'string' ||
1102
- typeof keyDerivationSalt !== 'string') {
1103
- throw new TypeError(constants_1.KeyringControllerError.WrongEncryptionKeyType);
1104
- }
1105
- const { vault } = this.state;
1106
- if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
1107
- throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
1108
- }
1109
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1110
- salt: keyDerivationSalt,
1111
- serialized: encryptionKey,
1112
- }, "f");
1113
1054
  }, _KeyringController_verifySeedPhrase =
1114
1055
  /**
1115
1056
  * Internal non-exclusive method to verify the seed phrase.
@@ -1189,7 +1130,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1189
1130
  return serializedKeyrings;
1190
1131
  }, _KeyringController_getSessionState =
1191
1132
  /**
1192
- * Get a snapshot of session data held by instance variables.
1133
+ * Get a snapshot of session data held by class variables.
1193
1134
  *
1194
1135
  * @returns An object with serialized keyrings, keyrings metadata,
1195
1136
  * and the user password.
@@ -1197,7 +1138,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1197
1138
  async function _KeyringController_getSessionState() {
1198
1139
  return {
1199
1140
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1200
- encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
1141
+ password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1201
1142
  };
1202
1143
  }, _KeyringController_restoreSerializedKeyrings =
1203
1144
  /**
@@ -1226,27 +1167,44 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1226
1167
  * Unlock Keyrings, decrypting the vault and deserializing all
1227
1168
  * keyrings contained in it, using a password or an encryption key with salt.
1228
1169
  *
1229
- * @param credentials - The credentials to unlock the keyrings.
1170
+ * @param password - The keyring controller password.
1171
+ * @param encryptionKey - An exported key string to unlock keyrings with.
1172
+ * @param encryptionSalt - The salt used to encrypt the vault.
1230
1173
  * @returns A promise resolving to the deserialized keyrings array.
1231
1174
  */
1232
- async function _KeyringController_unlockKeyrings(credentials) {
1175
+ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1233
1176
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1234
- if (!this.state.vault) {
1177
+ const encryptedVault = this.state.vault;
1178
+ if (!encryptedVault) {
1235
1179
  throw new Error(constants_1.KeyringControllerError.VaultError);
1236
1180
  }
1237
- const parsedEncryptedVault = JSON.parse(this.state.vault);
1238
- if ('password' in credentials) {
1239
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveAndSetEncryptionKey).call(this, credentials.password);
1181
+ let vault;
1182
+ const updatedState = {};
1183
+ if (password) {
1184
+ const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1185
+ vault = result.vault;
1186
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1187
+ updatedState.encryptionKey = result.exportedKeyString;
1188
+ updatedState.encryptionSalt = result.salt;
1240
1189
  }
1241
1190
  else {
1242
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setEncryptionKey).call(this, credentials.encryptionKey, credentials.encryptionSalt || parsedEncryptedVault.salt);
1243
- }
1244
- const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized;
1245
- if (!encryptionKey) {
1246
- throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1191
+ const parsedEncryptedVault = JSON.parse(encryptedVault);
1192
+ if (encryptionSalt && encryptionSalt !== parsedEncryptedVault.salt) {
1193
+ throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
1194
+ }
1195
+ else {
1196
+ encryptionSalt = parsedEncryptedVault.salt;
1197
+ }
1198
+ if (typeof encryptionKey !== 'string') {
1199
+ throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1200
+ }
1201
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1202
+ vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1203
+ // This call is required on the first call because encryptionKey
1204
+ // is not yet inside the memStore
1205
+ updatedState.encryptionKey = encryptionKey;
1206
+ updatedState.encryptionSalt = encryptionSalt;
1247
1207
  }
1248
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1249
- const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1250
1208
  if (!isSerializedKeyringsArray(vault)) {
1251
1209
  throw new Error(constants_1.KeyringControllerError.VaultDataError);
1252
1210
  }
@@ -1254,8 +1212,10 @@ async function _KeyringController_unlockKeyrings(credentials) {
1254
1212
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1255
1213
  this.update((state) => {
1256
1214
  state.keyrings = updatedKeyrings;
1257
- state.encryptionKey = encryptionKey;
1258
- state.encryptionSalt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.salt;
1215
+ if (updatedState.encryptionKey || updatedState.encryptionSalt) {
1216
+ state.encryptionKey = updatedState.encryptionKey;
1217
+ state.encryptionSalt = updatedState.encryptionSalt;
1218
+ }
1259
1219
  });
1260
1220
  return { keyrings, newMetadata };
1261
1221
  });
@@ -1263,36 +1223,50 @@ async function _KeyringController_unlockKeyrings(credentials) {
1263
1223
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1264
1224
  // Ensure no duplicate accounts are persisted.
1265
1225
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
1266
- if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1226
+ const { encryptionKey, encryptionSalt, vault } = this.state;
1227
+ // READ THIS CAREFULLY:
1228
+ // We do check if the vault is still considered up-to-date, if not, we would not re-use the
1229
+ // cached key and we will re-generate a new one (based on the password).
1230
+ //
1231
+ // This helps doing seamless updates of the vault. Useful in case we change some cryptographic
1232
+ // parameters to the KDF.
1233
+ const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
1234
+ if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
1267
1235
  throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1268
1236
  }
1269
1237
  const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1270
1238
  if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
1271
1239
  throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
1272
1240
  }
1273
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized);
1274
- const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1275
- // We need to include the salt used to derive
1276
- // the encryption key, to be able to derive it
1277
- // from password again.
1278
- encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
1279
- const updatedState = {
1280
- vault: JSON.stringify(encryptedVault),
1281
- encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized,
1282
- encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
1283
- };
1241
+ const updatedState = {};
1242
+ if (useCachedKey) {
1243
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1244
+ const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1245
+ vaultJSON.salt = encryptionSalt;
1246
+ updatedState.vault = JSON.stringify(vaultJSON);
1247
+ }
1248
+ else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1249
+ const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1250
+ updatedState.vault = newVault;
1251
+ updatedState.encryptionKey = exportedKeyString;
1252
+ }
1253
+ if (!updatedState.vault) {
1254
+ throw new Error(constants_1.KeyringControllerError.MissingVaultData);
1255
+ }
1284
1256
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1285
1257
  this.update((state) => {
1286
1258
  state.vault = updatedState.vault;
1287
1259
  state.keyrings = updatedKeyrings;
1288
- state.encryptionKey = updatedState.encryptionKey;
1289
- state.encryptionSalt = updatedState.encryptionSalt;
1260
+ if (updatedState.encryptionKey) {
1261
+ state.encryptionKey = updatedState.encryptionKey;
1262
+ state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1263
+ }
1290
1264
  });
1291
1265
  return true;
1292
1266
  });
1293
1267
  }, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
1294
1268
  const { vault } = this.state;
1295
- if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1269
+ if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1296
1270
  return false;
1297
1271
  }
1298
1272
  return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
@@ -1526,13 +1500,13 @@ async function _KeyringController_persistOrRollback(callback) {
1526
1500
  async function _KeyringController_withRollback(callback) {
1527
1501
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1528
1502
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1529
- const currentEncryptionKey = (0, lodash_1.cloneDeep)(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1503
+ const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1530
1504
  try {
1531
1505
  return await callback({ releaseLock });
1532
1506
  }
1533
1507
  catch (e) {
1534
- // Keyrings and encryption credentials are restored to their previous state
1535
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, currentEncryptionKey, "f");
1508
+ // Keyrings and password are restored to their previous state
1509
+ __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1536
1510
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1537
1511
  throw e;
1538
1512
  }