@metamask-previews/keyring-controller 21.0.4-preview-19ee5ff2 → 21.0.4-preview-b84ab30f

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
@@ -9,12 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
+ - Prevent emitting `:stateChange` from `withKeyring` unnecessarily ([#5732](https://github.com/MetaMask/core/pull/5732))
12
13
  - Bump `@metamask/base-controller` from ^8.0.0 to ^8.0.1 ([#5722](https://github.com/MetaMask/core/pull/5722))
13
14
 
14
- ### Fixed
15
-
16
- - The vault encryption upgrade fails grecefully during login ([#5740](https://github.com/MetaMask/core/pull/5740))
17
-
18
15
  ## [21.0.4]
19
16
 
20
17
  ### 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_keyringsMetadata, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_upgradeVaultEncryptionParams, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_keyringsMetadata, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_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");
@@ -48,6 +48,7 @@ const eth_simple_keyring_1 = __importDefault(require("@metamask/eth-simple-keyri
48
48
  const utils_1 = require("@metamask/utils");
49
49
  const async_mutex_1 = require("async-mutex");
50
50
  const ethereumjs_wallet_1 = __importStar(require("ethereumjs-wallet"));
51
+ const lodash_1 = require("lodash");
51
52
  // When generating a ULID within the same millisecond, monotonicFactory provides some guarantees regarding sort order.
52
53
  const ulid_1 = require("ulid");
53
54
  const constants_1 = require("./constants.cjs");
@@ -553,8 +554,11 @@ class KeyringController extends base_controller_1.BaseController {
553
554
  * operation completes.
554
555
  */
555
556
  async persistAllKeyrings() {
556
- __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
557
- return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => true);
557
+ return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
558
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
559
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
560
+ return true;
561
+ });
558
562
  }
559
563
  /**
560
564
  * Imports an account with the specified import strategy.
@@ -874,20 +878,10 @@ class KeyringController extends base_controller_1.BaseController {
874
878
  * @returns Promise resolving when the operation completes.
875
879
  */
876
880
  async submitPassword(password) {
877
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
881
+ return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
878
882
  __classPrivateFieldSet(this, _KeyringController_keyrings, await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password), "f");
879
883
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
880
884
  });
881
- try {
882
- // If there are stronger encryption params available, we
883
- // can attempt to upgrade the vault encryption params.
884
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_upgradeVaultEncryptionParams).call(this));
885
- }
886
- catch (error) {
887
- // We don't want to throw an error if the upgrade fails
888
- // since the controller is already unlocked.
889
- console.error('Failed to upgrade vault encryption params:', error);
890
- }
891
885
  }
892
886
  /**
893
887
  * Verifies the that the seed phrase restores the current keychain's accounts.
@@ -1294,6 +1288,19 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1294
1288
  serializedKeyrings.push(...__classPrivateFieldGet(this, _KeyringController_unsupportedKeyrings, "f"));
1295
1289
  }
1296
1290
  return serializedKeyrings;
1291
+ }, _KeyringController_getSessionState =
1292
+ /**
1293
+ * Get a snapshot of session data held by class variables.
1294
+ *
1295
+ * @returns An object with serialized keyrings, keyrings metadata,
1296
+ * and the user password.
1297
+ */
1298
+ async function _KeyringController_getSessionState() {
1299
+ return {
1300
+ keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1301
+ keyringsMetadata: __classPrivateFieldGet(this, _KeyringController_keyringsMetadata, "f").slice(),
1302
+ password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1303
+ };
1297
1304
  }, _KeyringController_restoreSerializedKeyrings =
1298
1305
  /**
1299
1306
  * Restore a serialized keyrings array.
@@ -1316,7 +1323,7 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1316
1323
  * @returns A promise resolving to the deserialized keyrings array.
1317
1324
  */
1318
1325
  async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1319
- return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1326
+ return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async ({ releaseLock }) => {
1320
1327
  const encryptedVault = this.state.vault;
1321
1328
  if (!encryptedVault) {
1322
1329
  throw new Error(constants_1.KeyringControllerError.VaultError);
@@ -1375,6 +1382,16 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1375
1382
  state.encryptionSalt = updatedState.encryptionSalt;
1376
1383
  }
1377
1384
  });
1385
+ if (__classPrivateFieldGet(this, _KeyringController_password, "f") &&
1386
+ (!__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f") || !encryptionKey) &&
1387
+ __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated &&
1388
+ !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(encryptedVault)) {
1389
+ // The lock needs to be released before persisting the keyrings
1390
+ // to avoid deadlock
1391
+ releaseLock();
1392
+ // Re-encrypt the vault with safer method if one is available
1393
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1394
+ }
1378
1395
  return __classPrivateFieldGet(this, _KeyringController_keyrings, "f");
1379
1396
  });
1380
1397
  }, _KeyringController_updateVault = function _KeyringController_updateVault() {
@@ -1433,20 +1450,6 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1433
1450
  });
1434
1451
  return true;
1435
1452
  });
1436
- }, _KeyringController_upgradeVaultEncryptionParams =
1437
- /**
1438
- * Upgrade the vault encryption parameters if needed.
1439
- *
1440
- * @returns A promise resolving to `void`.
1441
- */
1442
- async function _KeyringController_upgradeVaultEncryptionParams() {
1443
- const { vault } = this.state;
1444
- if (vault &&
1445
- __classPrivateFieldGet(this, _KeyringController_password, "f") &&
1446
- __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated &&
1447
- !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault)) {
1448
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1449
- }
1450
1453
  }, _KeyringController_getAccountsFromKeyrings =
1451
1454
  /**
1452
1455
  * Retrieves all the accounts from keyrings instances
@@ -1658,7 +1661,7 @@ async function _KeyringController_assertNoDuplicateAccounts() {
1658
1661
  }, _KeyringController_persistOrRollback =
1659
1662
  /**
1660
1663
  * Execute the given function after acquiring the controller lock
1661
- * and save the keyrings to state after it, or rollback to their
1664
+ * and save the vault to state after it (only if needed), or rollback to their
1662
1665
  * previous state in case of error.
1663
1666
  *
1664
1667
  * @param callback - The function to execute.
@@ -1666,9 +1669,13 @@ async function _KeyringController_assertNoDuplicateAccounts() {
1666
1669
  */
1667
1670
  async function _KeyringController_persistOrRollback(callback) {
1668
1671
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async ({ releaseLock }) => {
1672
+ const oldState = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSessionState).call(this);
1669
1673
  const callbackResult = await callback({ releaseLock });
1670
- // State is committed only if the operation is successful
1671
- await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1674
+ const newState = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSessionState).call(this);
1675
+ // State is committed only if the operation is successful and need to trigger a vault update.
1676
+ if (!(0, lodash_1.isEqual)(oldState, newState)) {
1677
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1678
+ }
1672
1679
  return callbackResult;
1673
1680
  });
1674
1681
  }, _KeyringController_withRollback =