@metamask-previews/keyring-controller 24.0.0-preview-7a813ba4 → 24.0.0-preview-afa0dd61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ 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
+ - Added optional `EncryptionKey`, `SupportedKeyDerivationOptions` and `EncryptionResult` type parameters to the `KeyringController`, `ExportableKeyEncryptor` and `KeyringControllerOptions` types ([#7127](https://github.com/MetaMask/core/pull/7127))
13
+ - This type parameter allows specifying the encryption key, key derivation options and encryption result types supported by the injected encryptor, defaulting to `@metamask/browser-passworder` types.
14
+
15
+ ### Changed
16
+
17
+ - **BREAKING:** The `KeyringController` constructor options now require an encryptor ([#7127](https://github.com/MetaMask/core/pull/7127))
18
+ - The `encryptor` constructor option was previously optional and defaulted to an instance of `@metamask/browser-passworder`.
19
+ - **BREAKING:** The `GenericEncryptor` and `ExportableKeyEncryptor` types have been merged into a single `Encryptor` type ([#7127](https://github.com/MetaMask/core/pull/7127))
20
+
21
+ ### Removed
22
+
23
+ - **BREAKING:** The `cacheEncryptionKey` parameter has been removed from the `KeyringController` constructor options ([#7127](https://github.com/MetaMask/core/pull/7127))
24
+ - This parameter was previously used to enable encryption key in-memory caching, but it is no longer needed as the controller now always uses the latest encryption key.
25
+
26
+ ### Fixed
27
+
28
+ - Fixed incorrect type for `decryptWithKey` method of `ExportableKeyEncryptor` (now `Encryptor`) ([#7127](https://github.com/MetaMask/core/pull/7127))
29
+
10
30
  ## [24.0.0]
11
31
 
12
32
  ### Changed
@@ -36,12 +36,11 @@ 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_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;
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");
43
43
  const base_controller_1 = require("@metamask/base-controller");
44
- const encryptorUtils = __importStar(require("@metamask/browser-passworder"));
45
44
  const eth_hd_keyring_1 = require("@metamask/eth-hd-keyring");
46
45
  const eth_sig_util_1 = require("@metamask/eth-sig-util");
47
46
  const eth_simple_keyring_1 = __importDefault(require("@metamask/eth-simple-keyring"));
@@ -136,23 +135,6 @@ function assertHasUint8ArrayMnemonic(keyring) {
136
135
  throw new Error("Can't get mnemonic bytes from keyring");
137
136
  }
138
137
  }
139
- /**
140
- * Assert that the provided encryptor supports
141
- * encryption and encryption key export.
142
- *
143
- * @param encryptor - The encryptor to check.
144
- * @throws If the encryptor does not support key encryption.
145
- */
146
- function assertIsExportableKeyEncryptor(encryptor) {
147
- if (!('importKey' in encryptor &&
148
- typeof encryptor.importKey === 'function' &&
149
- 'decryptWithKey' in encryptor &&
150
- typeof encryptor.decryptWithKey === 'function' &&
151
- 'encryptWithKey' in encryptor &&
152
- typeof encryptor.encryptWithKey === 'function')) {
153
- throw new Error(constants_1.KeyringControllerError.UnsupportedEncryptionKeyExport);
154
- }
155
- }
156
138
  /**
157
139
  * Assert that the provided password is a valid non-empty string.
158
140
  *
@@ -259,7 +241,7 @@ class KeyringController extends base_controller_1.BaseController {
259
241
  * @param options.state - Initial state to set on this controller.
260
242
  */
261
243
  constructor(options) {
262
- const { encryptor = encryptorUtils, keyringBuilders, messenger, state, } = options;
244
+ const { encryptor, keyringBuilders, messenger, state } = options;
263
245
  super({
264
246
  name,
265
247
  metadata: {
@@ -305,7 +287,6 @@ class KeyringController extends base_controller_1.BaseController {
305
287
  _KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
306
288
  _KeyringController_keyringBuilders.set(this, void 0);
307
289
  _KeyringController_encryptor.set(this, void 0);
308
- _KeyringController_cacheEncryptionKey.set(this, void 0);
309
290
  _KeyringController_keyrings.set(this, void 0);
310
291
  _KeyringController_unsupportedKeyrings.set(this, void 0);
311
292
  _KeyringController_password.set(this, void 0);
@@ -315,12 +296,6 @@ class KeyringController extends base_controller_1.BaseController {
315
296
  __classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
316
297
  __classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
317
298
  __classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
318
- // This option allows the controller to cache an exported key
319
- // for use in decrypting and encrypting data without password
320
- __classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
321
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
322
- assertIsExportableKeyEncryptor(encryptor);
323
- }
324
299
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
325
300
  }
326
301
  /**
@@ -883,12 +858,10 @@ class KeyringController extends base_controller_1.BaseController {
883
858
  // We need to clear encryption key and salt from state
884
859
  // to force the controller to re-encrypt the vault using
885
860
  // the new password.
886
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
887
- this.update((state) => {
888
- delete state.encryptionKey;
889
- delete state.encryptionSalt;
890
- });
891
- }
861
+ this.update((state) => {
862
+ delete state.encryptionKey;
863
+ delete state.encryptionSalt;
864
+ });
892
865
  });
893
866
  }
894
867
  /**
@@ -1015,7 +988,7 @@ class KeyringController extends base_controller_1.BaseController {
1015
988
  }
1016
989
  }
1017
990
  exports.KeyringController = KeyringController;
1018
- _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_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() {
1019
992
  this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1020
993
  this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1021
994
  this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1208,40 +1181,30 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1208
1181
  }
1209
1182
  let vault;
1210
1183
  const updatedState = {};
1211
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1212
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1213
- if (password) {
1214
- const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1215
- vault = result.vault;
1216
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1217
- updatedState.encryptionKey = result.exportedKeyString;
1218
- updatedState.encryptionSalt = result.salt;
1184
+ if (password) {
1185
+ const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
1186
+ vault = result.vault;
1187
+ __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1188
+ updatedState.encryptionKey = result.exportedKeyString;
1189
+ updatedState.encryptionSalt = result.salt;
1190
+ }
1191
+ else {
1192
+ const parsedEncryptedVault = JSON.parse(encryptedVault);
1193
+ if (encryptionSalt && encryptionSalt !== parsedEncryptedVault.salt) {
1194
+ throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
1219
1195
  }
1220
1196
  else {
1221
- const parsedEncryptedVault = JSON.parse(encryptedVault);
1222
- if (encryptionSalt && encryptionSalt !== parsedEncryptedVault.salt) {
1223
- throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
1224
- }
1225
- else {
1226
- encryptionSalt = parsedEncryptedVault.salt;
1227
- }
1228
- if (typeof encryptionKey !== 'string') {
1229
- throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1230
- }
1231
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1232
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1233
- // This call is required on the first call because encryptionKey
1234
- // is not yet inside the memStore
1235
- updatedState.encryptionKey = encryptionKey;
1236
- updatedState.encryptionSalt = encryptionSalt;
1197
+ encryptionSalt = parsedEncryptedVault.salt;
1237
1198
  }
1238
- }
1239
- else {
1240
- if (typeof password !== 'string') {
1199
+ if (typeof encryptionKey !== 'string') {
1241
1200
  throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1242
1201
  }
1243
- vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
1244
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1202
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1203
+ vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1204
+ // This call is required on the first call because encryptionKey
1205
+ // is not yet inside the memStore
1206
+ updatedState.encryptionKey = encryptionKey;
1207
+ updatedState.encryptionSalt = encryptionSalt;
1245
1208
  }
1246
1209
  if (!isSerializedKeyringsArray(vault)) {
1247
1210
  throw new Error(constants_1.KeyringControllerError.VaultDataError);
@@ -1277,23 +1240,16 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1277
1240
  throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
1278
1241
  }
1279
1242
  const updatedState = {};
1280
- if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
1281
- assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
1282
- if (useCachedKey) {
1283
- const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1284
- const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1285
- vaultJSON.salt = encryptionSalt;
1286
- updatedState.vault = JSON.stringify(vaultJSON);
1287
- }
1288
- else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1289
- const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1290
- updatedState.vault = newVault;
1291
- updatedState.encryptionKey = exportedKeyString;
1292
- }
1243
+ if (useCachedKey) {
1244
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1245
+ const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1246
+ vaultJSON.salt = encryptionSalt;
1247
+ updatedState.vault = JSON.stringify(vaultJSON);
1293
1248
  }
1294
- else {
1295
- assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
1296
- updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1249
+ else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
1250
+ const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
1251
+ updatedState.vault = newVault;
1252
+ updatedState.encryptionKey = exportedKeyString;
1297
1253
  }
1298
1254
  if (!updatedState.vault) {
1299
1255
  throw new Error(constants_1.KeyringControllerError.MissingVaultData);