@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.
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- 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;
12
+ 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;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -145,17 +145,6 @@ function assertIsValidPassword(password) {
145
145
  throw new Error(KeyringControllerError.InvalidEmptyPassword);
146
146
  }
147
147
  }
148
- /**
149
- * Assert that the provided cacheEncryptionKey is true.
150
- *
151
- * @param cacheEncryptionKey - The cacheEncryptionKey to check.
152
- * @throws If the cacheEncryptionKey is not true.
153
- */
154
- function assertIsCacheEncryptionKeyTrue(cacheEncryptionKey) {
155
- if (!cacheEncryptionKey) {
156
- throw new Error(KeyringControllerError.CacheEncryptionKeyDisabled);
157
- }
158
- }
159
148
  /**
160
149
  * Checks if the provided value is a serialized keyrings array.
161
150
  *
@@ -246,7 +235,6 @@ export class KeyringController extends BaseController {
246
235
  keyrings: { persist: false, anonymous: false },
247
236
  encryptionKey: { persist: false, anonymous: false },
248
237
  encryptionSalt: { persist: false, anonymous: false },
249
- encryptedEncryptionKey: { persist: true, anonymous: false },
250
238
  },
251
239
  messenger,
252
240
  state: {
@@ -259,24 +247,17 @@ export class KeyringController extends BaseController {
259
247
  _KeyringController_vaultOperationMutex.set(this, new Mutex());
260
248
  _KeyringController_keyringBuilders.set(this, void 0);
261
249
  _KeyringController_encryptor.set(this, void 0);
262
- _KeyringController_cacheEncryptionKey.set(this, void 0);
263
250
  _KeyringController_keyrings.set(this, void 0);
264
251
  _KeyringController_unsupportedKeyrings.set(this, void 0);
265
- _KeyringController_password.set(this, void 0);
266
252
  _KeyringController_encryptionKey.set(this, void 0);
267
253
  _KeyringController_qrKeyringStateListener.set(this, void 0);
268
254
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
269
255
  ? keyringBuilders.concat(defaultKeyringBuilders)
270
256
  : defaultKeyringBuilders, "f");
257
+ assertIsExportableKeyEncryptor(encryptor);
271
258
  __classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
272
259
  __classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
273
260
  __classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
274
- // This option allows the controller to cache an exported key
275
- // for use in decrypting and encrypting data without password
276
- __classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
277
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
278
- assertIsExportableKeyEncryptor(encryptor);
279
- }
280
261
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
281
262
  }
282
263
  /**
@@ -363,22 +344,19 @@ export class KeyringController extends BaseController {
363
344
  /**
364
345
  * Create a new vault and primary keyring.
365
346
  *
366
- * This only works if keyrings are empty. If there is a pre-existing unlocked
367
- * vault, calling this will have no effect. If there is a pre-existing locked
368
- * vault, it will be replaced.
347
+ * This only works if keyrings are empty. If there is a pre-existing unlocked vault, calling this will have no effect.
348
+ * If there is a pre-existing locked vault, it will be replaced.
369
349
  *
370
350
  * @param password - Password to unlock the new vault.
371
- * @param encryptionKey - Optional encryption key to encrypt the new vault. If
372
- * set, envelope encryption will be used.
373
351
  * @returns Promise resolving when the operation ends successfully.
374
352
  */
375
- async createNewVaultAndKeychain(password, encryptionKey) {
353
+ async createNewVaultAndKeychain(password) {
376
354
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
377
355
  const accounts = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getAccountsFromKeyrings).call(this);
378
356
  if (!accounts.length) {
379
357
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createNewVaultWithKeyring).call(this, password, {
380
358
  type: KeyringTypes.hd,
381
- }, encryptionKey);
359
+ });
382
360
  }
383
361
  });
384
362
  }
@@ -407,16 +385,7 @@ export class KeyringController extends BaseController {
407
385
  if (!this.state.vault) {
408
386
  throw new Error(KeyringControllerError.VaultError);
409
387
  }
410
- if (this.state.encryptedEncryptionKey) {
411
- // Envelope encryption mode.
412
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
413
- const key = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.encryptedEncryptionKey));
414
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(key);
415
- await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, this.state.vault);
416
- }
417
- else {
418
- await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
419
- }
388
+ await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, this.state.vault);
420
389
  }
421
390
  /**
422
391
  * Returns the status of the vault.
@@ -605,7 +574,7 @@ export class KeyringController extends BaseController {
605
574
  try {
606
575
  wallet = importers.fromEtherWallet(input, password);
607
576
  }
608
- catch {
577
+ catch (e) {
609
578
  wallet = wallet || (await Wallet.fromV3(input, password, true));
610
579
  }
611
580
  privateKey = bytesToHex(wallet.getPrivateKey());
@@ -663,7 +632,6 @@ export class KeyringController extends BaseController {
663
632
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
664
633
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
665
634
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
666
- __classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
667
635
  __classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
668
636
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
669
637
  this.update((state) => {
@@ -845,33 +813,10 @@ export class KeyringController extends BaseController {
845
813
  * @returns Promise resolving when the operation completes.
846
814
  */
847
815
  changePassword(password) {
848
- return this.changePasswordAndEncryptionKey(password);
849
- }
850
- /**
851
- * Changes the password and encryption key used to encrypt the vault.
852
- *
853
- * @param password - The new password.
854
- * @param encryptionKey - The new encryption key. If omitted, the encryption
855
- * key will not be changed.
856
- * @returns Promise resolving when the operation completes.
857
- */
858
- changePasswordAndEncryptionKey(password, encryptionKey) {
859
816
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
860
817
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
861
818
  assertIsValidPassword(password);
862
- // Update password.
863
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
864
- // Update encryption key.
865
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
866
- // We need to clear encryption key and salt from state
867
- // to force the controller to re-encrypt the vault using
868
- // the new password.
869
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
870
- this.update((state) => {
871
- delete state.encryptionKey;
872
- delete state.encryptionSalt;
873
- });
874
- }
819
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
875
820
  });
876
821
  }
877
822
  /**
@@ -879,12 +824,13 @@ export class KeyringController extends BaseController {
879
824
  * using the given encryption key and salt.
880
825
  *
881
826
  * @param encryptionKey - Key to unlock the keychain.
882
- * @param encryptionSalt - Salt to unlock the keychain.
883
827
  * @returns Promise resolving when the operation completes.
884
828
  */
885
- async submitEncryptionKey(encryptionKey, encryptionSalt) {
829
+ async submitEncryptionKey(encryptionKey) {
886
830
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
887
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
831
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
832
+ exportedEncryptionKey: encryptionKey,
833
+ });
888
834
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
889
835
  return result;
890
836
  });
@@ -912,7 +858,7 @@ export class KeyringController extends BaseController {
912
858
  */
913
859
  async submitPassword(password) {
914
860
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
915
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
861
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
916
862
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
917
863
  return result;
918
864
  });
@@ -922,6 +868,12 @@ export class KeyringController extends BaseController {
922
868
  // can attempt to upgrade the vault.
923
869
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
924
870
  if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
871
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
872
+ // If the vault is being upgraded, we want to ignore the metadata
873
+ // that is already in the vault, so we can effectively
874
+ // re-encrypt the vault with the new encryption config.
875
+ ignoreVautKeyMetadata: true,
876
+ });
925
877
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
926
878
  }
927
879
  });
@@ -1175,7 +1127,7 @@ export class KeyringController extends BaseController {
1175
1127
  });
1176
1128
  }
1177
1129
  }
1178
- _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() {
1130
+ _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() {
1179
1131
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1180
1132
  this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1181
1133
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1244,10 +1196,9 @@ async function _KeyringController_addQRKeyring() {
1244
1196
  * @param keyring - A object containing the params to instantiate a new keyring.
1245
1197
  * @param keyring.type - The keyring type.
1246
1198
  * @param keyring.opts - Optional parameters required to instantiate the keyring.
1247
- * @param encryptionKey - Optional encryption key to encrypt the vault.
1248
1199
  * @returns A promise that resolves to the state.
1249
1200
  */
1250
- async function _KeyringController_createNewVaultWithKeyring(password, keyring, encryptionKey) {
1201
+ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1251
1202
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1252
1203
  if (typeof password !== 'string') {
1253
1204
  throw new TypeError(KeyringControllerError.WrongPasswordType);
@@ -1256,18 +1207,64 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring, e
1256
1207
  delete state.encryptionKey;
1257
1208
  delete state.encryptionSalt;
1258
1209
  });
1259
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1260
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateCachedEncryptionKey).call(this, encryptionKey);
1210
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
1261
1211
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1262
1212
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1263
1213
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
1264
- }, _KeyringController_updateCachedEncryptionKey = function _KeyringController_updateCachedEncryptionKey(encryptionKey) {
1265
- if (!encryptionKey && this.state.encryptedEncryptionKey) {
1266
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, this.state.encryptionKey, "f");
1214
+ }, _KeyringController_deriveEncryptionKey =
1215
+ /**
1216
+ * Derive the vault encryption key from the provided password, and
1217
+ * assign it to the class variable for later use with cryptographic
1218
+ * functions.
1219
+ *
1220
+ * When the controller has a vault in its state, the key is derived
1221
+ * using the salt from the vault. If the vault is empty, a new salt
1222
+ * is generated and used to derive the key.
1223
+ *
1224
+ * @param password - The password to use for decryption or derivation.
1225
+ */
1226
+ async function _KeyringController_deriveEncryptionKey(password, options = {
1227
+ ignoreVautKeyMetadata: false,
1228
+ }) {
1229
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1230
+ const { vault } = this.state;
1231
+ if (typeof password !== 'string') {
1232
+ throw new TypeError(KeyringControllerError.WrongPasswordType);
1233
+ }
1234
+ let salt, keyMetadata;
1235
+ if (vault && !options.ignoreVautKeyMetadata) {
1236
+ const parsedVault = JSON.parse(vault);
1237
+ salt = parsedVault.salt;
1238
+ keyMetadata = parsedVault.keyMetadata;
1267
1239
  }
1268
1240
  else {
1269
- __classPrivateFieldSet(this, _KeyringController_encryptionKey, encryptionKey, "f");
1241
+ salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
1270
1242
  }
1243
+ const exportedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
1244
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1245
+ salt,
1246
+ exported: exportedEncryptionKey,
1247
+ }, "f");
1248
+ }, _KeyringController_useEncryptionKey =
1249
+ /**
1250
+ * Use the provided encryption key and salt to set the
1251
+ * encryptionKey class variable. This method is used
1252
+ * when the user provides an encryption key and salt
1253
+ * to unlock the keychain, instead of using a password.
1254
+ *
1255
+ * @param encryptionKey - The encryption key to use.
1256
+ * @param encryptionSalt - The salt to use for the encryption key.
1257
+ */
1258
+ async function _KeyringController_useEncryptionKey(encryptionKey, encryptionSalt) {
1259
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1260
+ if (typeof encryptionKey !== 'string' ||
1261
+ typeof encryptionSalt !== 'string') {
1262
+ throw new TypeError(KeyringControllerError.WrongEncryptionKeyType);
1263
+ }
1264
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1265
+ salt: encryptionSalt,
1266
+ exported: encryptionKey,
1267
+ }, "f");
1271
1268
  }, _KeyringController_verifySeedPhrase =
1272
1269
  /**
1273
1270
  * Internal non-exclusive method to verify the seed phrase.
@@ -1356,7 +1353,6 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1356
1353
  async function _KeyringController_getSessionState() {
1357
1354
  return {
1358
1355
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1359
- password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1360
1356
  encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
1361
1357
  };
1362
1358
  }, _KeyringController_restoreSerializedKeyrings =
@@ -1386,63 +1382,28 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1386
1382
  * Unlock Keyrings, decrypting the vault and deserializing all
1387
1383
  * keyrings contained in it, using a password or an encryption key with salt.
1388
1384
  *
1389
- * @param password - The keyring controller password.
1390
- * @param encryptionKey - An exported key string to unlock keyrings with.
1391
- * @param encryptionSalt - The salt used to encrypt the vault.
1385
+ * @param credentials - The credentials to unlock the keyrings.
1392
1386
  * @returns A promise resolving to the deserialized keyrings array.
1393
1387
  */
1394
- async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1388
+ async function _KeyringController_unlockKeyrings(credentials) {
1395
1389
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1396
- const { vault: encryptedVault, encryptedEncryptionKey } = this.state;
1397
- if (!encryptedVault) {
1390
+ if (!this.state.vault) {
1398
1391
  throw new Error(KeyringControllerError.VaultError);
1399
1392
  }
1400
- let vault;
1401
- const updatedState = {};
1402
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1403
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1404
- if (password) {
1405
- if (encryptedEncryptionKey) {
1406
- const key = (await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedEncryptionKey));
1407
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(key);
1408
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(importedKey, encryptedVault);
1409
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1410
- updatedState.encryptionKey = key;
1411
- }
1412
- else {
1413
- const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1414
- vault = result.vault;
1415
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1416
- updatedState.encryptionKey = result.exportedKeyString;
1417
- updatedState.encryptionSalt = result.salt;
1418
- }
1419
- }
1420
- else {
1421
- const parsedEncryptedVault = JSON.parse(encryptedVault);
1422
- if (encryptionSalt !== parsedEncryptedVault.salt) {
1423
- throw new Error(KeyringControllerError.ExpiredCredentials);
1424
- }
1425
- if (typeof encryptionKey !== 'string') {
1426
- throw new TypeError(KeyringControllerError.WrongPasswordType);
1427
- }
1428
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1429
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1430
- // This call is required on the first call because encryptionKey
1431
- // is not yet inside the memStore
1432
- updatedState.encryptionKey = encryptionKey;
1433
- // we can safely assume that encryptionSalt is defined here
1434
- // because we compare it with the salt from the vault
1435
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1436
- updatedState.encryptionSalt = encryptionSalt;
1437
- }
1393
+ const parsedEncryptedVault = JSON.parse(this.state.vault);
1394
+ if ('password' in credentials) {
1395
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, credentials.password);
1438
1396
  }
1439
1397
  else {
1440
- if (typeof password !== 'string') {
1441
- throw new TypeError(KeyringControllerError.WrongPasswordType);
1442
- }
1443
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
1444
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1398
+ const { exportedEncryptionKey } = credentials;
1399
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, exportedEncryptionKey, parsedEncryptedVault.salt);
1400
+ }
1401
+ const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1402
+ if (!encryptionKey) {
1403
+ throw new Error(KeyringControllerError.MissingCredentials);
1445
1404
  }
1405
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1406
+ const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1446
1407
  if (!isSerializedKeyringsArray(vault)) {
1447
1408
  throw new Error(KeyringControllerError.VaultDataError);
1448
1409
  }
@@ -1450,10 +1411,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1450
1411
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1451
1412
  this.update((state) => {
1452
1413
  state.keyrings = updatedKeyrings;
1453
- if (updatedState.encryptionKey || updatedState.encryptionSalt) {
1454
- state.encryptionKey = updatedState.encryptionKey;
1455
- state.encryptionSalt = updatedState.encryptionSalt;
1456
- }
1414
+ state.encryptionKey = encryptionKey;
1415
+ state.encryptionSalt = parsedEncryptedVault.salt;
1457
1416
  });
1458
1417
  return { keyrings, newMetadata };
1459
1418
  });
@@ -1461,81 +1420,41 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1461
1420
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1462
1421
  // Ensure no duplicate accounts are persisted.
1463
1422
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
1464
- const { encryptionKey, encryptionSalt, vault } = this.state;
1465
- // READ THIS CAREFULLY:
1466
- // We do check if the vault is still considered up-to-date, if not, we would not re-use the
1467
- // cached key and we will re-generate a new one (based on the password).
1468
- //
1469
- // This helps doing seamless updates of the vault. Useful in case we change some cryptographic
1470
- // parameters to the KDF.
1471
- const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
1472
- if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
1423
+ if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1473
1424
  throw new Error(KeyringControllerError.MissingCredentials);
1474
1425
  }
1475
1426
  const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1476
1427
  if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
1477
1428
  throw new Error(KeyringControllerError.NoHdKeyring);
1478
1429
  }
1479
- const updatedState = {};
1480
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1481
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1482
- if (useCachedKey) {
1483
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1484
- const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1485
- vaultJSON.salt = encryptionSalt;
1486
- updatedState.vault = JSON.stringify(vaultJSON);
1487
- }
1488
- else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1489
- if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1490
- // Update cached key.
1491
- updatedState.encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1492
- // Encrypt key and update encrypted key.
1493
- const encryptedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1494
- updatedState.encryptedEncryptionKey = encryptedKey;
1495
- // Encrypt and update vault.
1496
- const importedKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
1497
- const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(importedKey, serializedKeyrings);
1498
- updatedState.vault = JSON.stringify(vaultJSON);
1499
- }
1500
- else {
1501
- const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1502
- updatedState.vault = newVault;
1503
- updatedState.encryptionKey = exportedKeyString;
1504
- }
1505
- }
1506
- }
1507
- else {
1508
- assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
1509
- updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1510
- }
1511
- if (__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isEnvelopeEncryptionEnabled).call(this)) {
1512
- assertIsCacheEncryptionKeyTrue(__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f"));
1513
- }
1514
- if (!updatedState.vault) {
1515
- throw new Error(KeyringControllerError.MissingVaultData);
1430
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported);
1431
+ const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1432
+ if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt) {
1433
+ // We need to include the salt used to derive
1434
+ // the encryption key, to be able to derive it
1435
+ // from password again.
1436
+ encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
1516
1437
  }
1438
+ const updatedState = {
1439
+ vault: JSON.stringify(encryptedVault),
1440
+ encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported,
1441
+ encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
1442
+ };
1517
1443
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1518
1444
  this.update((state) => {
1519
1445
  state.vault = updatedState.vault;
1520
1446
  state.keyrings = updatedKeyrings;
1521
- if (updatedState.encryptionKey) {
1522
- state.encryptionKey = updatedState.encryptionKey;
1523
- state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1524
- }
1525
- if (updatedState.encryptedEncryptionKey) {
1526
- state.encryptedEncryptionKey = updatedState.encryptedEncryptionKey;
1527
- }
1447
+ state.encryptionKey = updatedState.encryptionKey;
1448
+ state.encryptionSalt = updatedState.encryptionSalt;
1528
1449
  });
1529
1450
  return true;
1530
1451
  });
1531
1452
  }, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
1532
1453
  const { vault } = this.state;
1533
- if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1454
+ if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1534
1455
  return false;
1535
1456
  }
1536
1457
  return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
1537
- }, _KeyringController_isEnvelopeEncryptionEnabled = function _KeyringController_isEnvelopeEncryptionEnabled() {
1538
- return this.state.encryptedEncryptionKey || __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f");
1539
1458
  }, _KeyringController_getAccountsFromKeyrings =
1540
1459
  /**
1541
1460
  * Retrieves all the accounts from keyrings instances
@@ -1620,8 +1539,7 @@ async function _KeyringController_createKeyring(type, data) {
1620
1539
  if (keyring.init) {
1621
1540
  await keyring.init();
1622
1541
  }
1623
- if (type === KeyringTypes.hd &&
1624
- (!isObject(data) || !data.mnemonic)) {
1542
+ if (type === KeyringTypes.hd && (!isObject(data) || !data.mnemonic)) {
1625
1543
  if (!keyring.generateRandomMnemonic) {
1626
1544
  throw new Error(KeyringControllerError.UnsupportedGenerateRandomMnemonic);
1627
1545
  }
@@ -1743,16 +1661,11 @@ async function _KeyringController_assertNoDuplicateAccounts(additionalKeyrings =
1743
1661
  }
1744
1662
  }, _KeyringController_persistOrRollback =
1745
1663
  /**
1746
- * Execute the given function after acquiring the controller lock and save the
1747
- * vault to state after it (only if needed), or rollback to their previous
1748
- * state in case of error.
1749
- *
1750
- * ATTENTION: The callback must **not** alter `controller.state`. Any state
1751
- * change performed by the callback will not be rolled back on error.
1664
+ * Execute the given function after acquiring the controller lock
1665
+ * and save the vault to state after it (only if needed), or rollback to their
1666
+ * previous state in case of error.
1752
1667
  *
1753
- * @param callback - The function to execute. This callback must **not** alter
1754
- * `controller.state`. Any state change performed by the callback will not be
1755
- * rolled back on error.
1668
+ * @param callback - The function to execute.
1756
1669
  * @returns The result of the function.
1757
1670
  */
1758
1671
  async function _KeyringController_persistOrRollback(callback) {
@@ -1777,13 +1690,16 @@ async function _KeyringController_persistOrRollback(callback) {
1777
1690
  async function _KeyringController_withRollback(callback) {
1778
1691
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1779
1692
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1780
- const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1693
+ const currentEncryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1694
+ const currentEncryptionSalt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.salt;
1781
1695
  try {
1782
1696
  return await callback({ releaseLock });
1783
1697
  }
1784
1698
  catch (e) {
1785
- // Keyrings and password are restored to their previous state
1786
- __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1699
+ // Keyrings and encryption credentials are restored to their previous state
1700
+ if (currentEncryptionKey && currentEncryptionSalt) {
1701
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, currentEncryptionKey, currentEncryptionSalt);
1702
+ }
1787
1703
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1788
1704
  throw e;
1789
1705
  }