@metamask-previews/keyring-controller 14.0.1-preview-f04be62f → 15.0.0-preview-fb52b9eb

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.
@@ -3,7 +3,7 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkCHLPTPMZjs = require('./chunk-CHLPTPMZ.js');
6
+ var _chunkQDPHKQONjs = require('./chunk-QDPHKQON.js');
7
7
 
8
8
  // src/KeyringController.ts
9
9
  var _util = require('@ethereumjs/util');
@@ -86,7 +86,7 @@ async function displayForKeyring(keyring) {
86
86
  accounts: accounts.map(_ethsigutil.normalize)
87
87
  };
88
88
  }
89
- var _keyringBuilders, _keyrings, _unsupportedKeyrings, _password, _encryptor, _cacheEncryptionKey, _qrKeyringStateListener, _registerMessageHandlers, registerMessageHandlers_fn, _getKeyringBuilderForType, getKeyringBuilderForType_fn, _addQRKeyring, addQRKeyring_fn, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn, _unsubscribeFromQRKeyringsEvents, unsubscribeFromQRKeyringsEvents_fn, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn, _updateKeyringsInState, updateKeyringsInState_fn, _unlockKeyrings, unlockKeyrings_fn, _createKeyringWithFirstAccount, createKeyringWithFirstAccount_fn, _newKeyring, newKeyring_fn, _clearKeyrings, clearKeyrings_fn, _restoreKeyring, restoreKeyring_fn, _destroyKeyring, destroyKeyring_fn, _removeEmptyKeyrings, removeEmptyKeyrings_fn, _checkForDuplicate, checkForDuplicate_fn, _setUnlocked, setUnlocked_fn, _getMemState, getMemState_fn;
89
+ var _controllerOperationMutex, _vaultOperationMutex, _keyringBuilders, _keyrings, _unsupportedKeyrings, _password, _encryptor, _cacheEncryptionKey, _qrKeyringStateListener, _registerMessageHandlers, registerMessageHandlers_fn, _getKeyringBuilderForType, getKeyringBuilderForType_fn, _addQRKeyring, addQRKeyring_fn, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn, _unsubscribeFromQRKeyringsEvents, unsubscribeFromQRKeyringsEvents_fn, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn, _getUpdatedKeyrings, getUpdatedKeyrings_fn, _unlockKeyrings, unlockKeyrings_fn, _updateVault, updateVault_fn, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn, _createKeyringWithFirstAccount, createKeyringWithFirstAccount_fn, _newKeyring, newKeyring_fn, _clearKeyrings, clearKeyrings_fn, _restoreKeyring, restoreKeyring_fn, _destroyKeyring, destroyKeyring_fn, _removeEmptyKeyrings, removeEmptyKeyrings_fn, _checkForDuplicate, checkForDuplicate_fn, _setUnlocked, setUnlocked_fn, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn, _withControllerLock, withControllerLock_fn, _withVaultLock, withVaultLock_fn;
90
90
  var KeyringController = class extends _basecontroller.BaseController {
91
91
  /**
92
92
  * Creates a KeyringController instance.
@@ -124,14 +124,14 @@ var KeyringController = class extends _basecontroller.BaseController {
124
124
  * Constructor helper for registering this controller's messaging system
125
125
  * actions.
126
126
  */
127
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _registerMessageHandlers);
127
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _registerMessageHandlers);
128
128
  /**
129
129
  * Get the keyring builder for the given `type`.
130
130
  *
131
131
  * @param type - The type of keyring to get the builder for.
132
132
  * @returns The keyring builder, or undefined if none exists.
133
133
  */
134
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _getKeyringBuilderForType);
134
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _getKeyringBuilderForType);
135
135
  /**
136
136
  * Add qr hardware keyring.
137
137
  *
@@ -139,15 +139,15 @@ var KeyringController = class extends _basecontroller.BaseController {
139
139
  * @throws If a QRKeyring builder is not provided
140
140
  * when initializing the controller
141
141
  */
142
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _addQRKeyring);
142
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _addQRKeyring);
143
143
  /**
144
144
  * Subscribe to a QRKeyring state change events and
145
145
  * forward them through the messaging system.
146
146
  *
147
147
  * @param qrKeyring - The QRKeyring instance to subscribe to
148
148
  */
149
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _subscribeToQRKeyringEvents);
150
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _unsubscribeFromQRKeyringsEvents);
149
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _subscribeToQRKeyringEvents);
150
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _unsubscribeFromQRKeyringsEvents);
151
151
  /**
152
152
  * Create new vault with an initial keyring
153
153
  *
@@ -162,11 +162,14 @@ var KeyringController = class extends _basecontroller.BaseController {
162
162
  * @param keyring.opts - Optional parameters required to instantiate the keyring.
163
163
  * @returns A promise that resolves to the state.
164
164
  */
165
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _createNewVaultWithKeyring);
165
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _createNewVaultWithKeyring);
166
166
  /**
167
- * Update the controller state with its current keyrings.
167
+ * Get the updated array of each keyring's type and
168
+ * accounts list.
169
+ *
170
+ * @returns A promise resolving to the updated keyrings array.
168
171
  */
169
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _updateKeyringsInState);
172
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _getUpdatedKeyrings);
170
173
  /**
171
174
  * Unlock Keyrings, decrypting the vault and deserializing all
172
175
  * keyrings contained in it, using a password or an encryption key with salt.
@@ -176,7 +179,20 @@ var KeyringController = class extends _basecontroller.BaseController {
176
179
  * @param encryptionSalt - The salt used to encrypt the vault.
177
180
  * @returns A promise resolving to the deserialized keyrings array.
178
181
  */
179
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _unlockKeyrings);
182
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _unlockKeyrings);
183
+ /**
184
+ * Update the vault with the current keyrings.
185
+ *
186
+ * @returns A promise resolving to `true` if the operation is successful.
187
+ */
188
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _updateVault);
189
+ /**
190
+ * Retrieves all the accounts from keyrings instances
191
+ * that are currently in memory.
192
+ *
193
+ * @returns A promise resolving to an array of accounts.
194
+ */
195
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _getAccountsFromKeyrings);
180
196
  /**
181
197
  * Create a new keyring, ensuring that the first account is
182
198
  * also created.
@@ -185,22 +201,28 @@ var KeyringController = class extends _basecontroller.BaseController {
185
201
  * @param opts - Optional parameters required to instantiate the keyring.
186
202
  * @returns A promise that resolves if the operation is successful.
187
203
  */
188
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _createKeyringWithFirstAccount);
204
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _createKeyringWithFirstAccount);
189
205
  /**
190
206
  * Instantiate, initialize and return a new keyring of the given `type`,
191
207
  * using the given `opts`. The keyring is built using the keyring builder
192
208
  * registered for the given `type`.
193
209
  *
210
+ *
194
211
  * @param type - The type of keyring to add.
195
212
  * @param data - The data to restore a previously serialized keyring.
213
+ * @param persist - Whether to persist the keyring to the vault.
196
214
  * @returns The new keyring.
215
+ * @throws If the keyring includes duplicated accounts.
197
216
  */
198
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _newKeyring);
217
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _newKeyring);
199
218
  /**
200
219
  * Remove all managed keyrings, destroying all their
201
220
  * instances in memory.
221
+ *
222
+ * @param options - Operations options.
223
+ * @param options.skipStateUpdate - Whether to skip updating the controller state.
202
224
  */
203
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _clearKeyrings);
225
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _clearKeyrings);
204
226
  /**
205
227
  * Restore a Keyring from a provided serialized payload.
206
228
  * On success, returns the resulting keyring instance.
@@ -208,7 +230,7 @@ var KeyringController = class extends _basecontroller.BaseController {
208
230
  * @param serialized - The serialized keyring.
209
231
  * @returns The deserialized keyring or undefined if the keyring type is unsupported.
210
232
  */
211
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _restoreKeyring);
233
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _restoreKeyring);
212
234
  /**
213
235
  * Destroy Keyring
214
236
  *
@@ -218,14 +240,14 @@ var KeyringController = class extends _basecontroller.BaseController {
218
240
  *
219
241
  * @param keyring - The keyring to destroy.
220
242
  */
221
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _destroyKeyring);
243
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _destroyKeyring);
222
244
  /**
223
245
  * Remove empty keyrings.
224
246
  *
225
247
  * Loops through the keyrings and removes the ones with empty accounts
226
248
  * (usually after removing the last / only account) from a keyring.
227
249
  */
228
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _removeEmptyKeyrings);
250
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _removeEmptyKeyrings);
229
251
  /**
230
252
  * Checks for duplicate keypairs, using the the first account in the given
231
253
  * array. Rejects if a duplicate is found.
@@ -236,105 +258,137 @@ var KeyringController = class extends _basecontroller.BaseController {
236
258
  * @param newAccountArray - Array of new accounts.
237
259
  * @returns The account, if no duplicate is found.
238
260
  */
239
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _checkForDuplicate);
261
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _checkForDuplicate);
240
262
  /**
241
263
  * Set the `isUnlocked` to true and notify listeners
242
264
  * through the messenger.
243
265
  *
244
266
  * @fires KeyringController:unlock
245
267
  */
246
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _setUnlocked);
247
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _getMemState);
248
- this.mutex = new (0, _asyncmutex.Mutex)();
249
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _keyringBuilders, void 0);
250
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _keyrings, void 0);
251
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _unsupportedKeyrings, void 0);
252
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _password, void 0);
253
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _encryptor, void 0);
254
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _cacheEncryptionKey, void 0);
255
- _chunkCHLPTPMZjs.__privateAdd.call(void 0, this, _qrKeyringStateListener, void 0);
256
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyringBuilders, keyringBuilders ? defaultKeyringBuilders.concat(keyringBuilders) : defaultKeyringBuilders);
257
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _encryptor, encryptor);
258
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyrings, []);
259
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _unsupportedKeyrings, []);
260
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _cacheEncryptionKey, Boolean(options.cacheEncryptionKey));
261
- if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
268
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _setUnlocked);
269
+ /**
270
+ * Assert that the controller mutex is locked.
271
+ *
272
+ * @throws If the controller mutex is not locked.
273
+ */
274
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _assertControllerMutexIsLocked);
275
+ /**
276
+ * Lock the controller mutex before executing the given function,
277
+ * and release it after the function is resolved or after an
278
+ * error is thrown.
279
+ *
280
+ * This wrapper ensures that each mutable operation that interacts with the
281
+ * controller and that changes its state is executed in a mutually exclusive way,
282
+ * preventing unsafe concurrent access that could lead to unpredictable behavior.
283
+ *
284
+ * @param fn - The function to execute while the controller mutex is locked.
285
+ * @returns The result of the function.
286
+ */
287
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _withControllerLock);
288
+ /**
289
+ * Lock the vault mutex before executing the given function,
290
+ * and release it after the function is resolved or after an
291
+ * error is thrown.
292
+ *
293
+ * This ensures that each operation that interacts with the vault
294
+ * is executed in a mutually exclusive way.
295
+ *
296
+ * @param fn - The function to execute while the vault mutex is locked.
297
+ * @returns The result of the function.
298
+ */
299
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _withVaultLock);
300
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _controllerOperationMutex, new (0, _asyncmutex.Mutex)());
301
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _vaultOperationMutex, new (0, _asyncmutex.Mutex)());
302
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _keyringBuilders, void 0);
303
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _keyrings, void 0);
304
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _unsupportedKeyrings, void 0);
305
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _password, void 0);
306
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _encryptor, void 0);
307
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _cacheEncryptionKey, void 0);
308
+ _chunkQDPHKQONjs.__privateAdd.call(void 0, this, _qrKeyringStateListener, void 0);
309
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyringBuilders, keyringBuilders ? defaultKeyringBuilders.concat(keyringBuilders) : defaultKeyringBuilders);
310
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _encryptor, encryptor);
311
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyrings, []);
312
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _unsupportedKeyrings, []);
313
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _cacheEncryptionKey, Boolean(options.cacheEncryptionKey));
314
+ if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
262
315
  assertIsExportableKeyEncryptor(encryptor);
263
316
  }
264
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
317
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
265
318
  }
266
319
  /**
267
320
  * Adds a new account to the default (first) HD seed phrase keyring.
268
321
  *
269
322
  * @param accountCount - Number of accounts before adding a new one, used to
270
323
  * make the method idempotent.
271
- * @returns Promise resolving to keyring current state and added account
272
- * address.
324
+ * @returns Promise resolving to the added account address.
273
325
  */
274
326
  async addNewAccount(accountCount) {
275
- const primaryKeyring = this.getKeyringsByType("HD Key Tree")[0];
276
- if (!primaryKeyring) {
277
- throw new Error("No HD keyring found");
278
- }
279
- const oldAccounts = await this.getAccounts();
280
- if (accountCount && oldAccounts.length !== accountCount) {
281
- if (accountCount > oldAccounts.length) {
282
- throw new Error("Account out of sequence");
327
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
328
+ const primaryKeyring = this.getKeyringsByType("HD Key Tree")[0];
329
+ if (!primaryKeyring) {
330
+ throw new Error("No HD keyring found");
283
331
  }
284
- const primaryKeyringAccounts = await primaryKeyring.getAccounts();
285
- return {
286
- keyringState: _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this),
287
- addedAccountAddress: primaryKeyringAccounts[accountCount]
288
- };
289
- }
290
- const addedAccountAddress = await this.addNewAccountForKeyring(
291
- primaryKeyring
292
- );
293
- await this.verifySeedPhrase();
294
- return {
295
- keyringState: _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this),
296
- addedAccountAddress
297
- };
332
+ const oldAccounts = await primaryKeyring.getAccounts();
333
+ if (accountCount && oldAccounts.length !== accountCount) {
334
+ if (accountCount > oldAccounts.length) {
335
+ throw new Error("Account out of sequence");
336
+ }
337
+ const existingAccount = oldAccounts[accountCount];
338
+ if (!existingAccount) {
339
+ throw new Error(`Can't find account at index ${accountCount}`);
340
+ }
341
+ return existingAccount;
342
+ }
343
+ const [addedAccountAddress] = await primaryKeyring.addAccounts(1);
344
+ await this.verifySeedPhrase();
345
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
346
+ return addedAccountAddress;
347
+ });
298
348
  }
299
349
  /**
300
350
  * Adds a new account to the specified keyring.
301
351
  *
302
352
  * @param keyring - Keyring to add the account to.
303
353
  * @param accountCount - Number of accounts before adding a new one, used to make the method idempotent.
304
- * @returns Promise resolving to keyring current state and added account
354
+ * @returns Promise resolving to the added account address
305
355
  */
306
356
  async addNewAccountForKeyring(keyring, accountCount) {
307
- const oldAccounts = await this.getAccounts();
308
- if (accountCount && oldAccounts.length !== accountCount) {
309
- if (accountCount > oldAccounts.length) {
310
- throw new Error("Account out of sequence");
357
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
358
+ const oldAccounts = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this);
359
+ if (accountCount && oldAccounts.length !== accountCount) {
360
+ if (accountCount > oldAccounts.length) {
361
+ throw new Error("Account out of sequence");
362
+ }
363
+ const existingAccount = oldAccounts[accountCount];
364
+ _utils.assertIsStrictHexString.call(void 0, existingAccount);
365
+ return existingAccount;
311
366
  }
312
- const existingAccount = oldAccounts[accountCount];
313
- _utils.assertIsStrictHexString.call(void 0, existingAccount);
314
- return existingAccount;
315
- }
316
- await keyring.addAccounts(1);
317
- await this.persistAllKeyrings();
318
- const addedAccountAddress = (await this.getAccounts()).find(
319
- (selectedAddress) => !oldAccounts.includes(selectedAddress)
320
- );
321
- _utils.assertIsStrictHexString.call(void 0, addedAccountAddress);
322
- return addedAccountAddress;
367
+ await keyring.addAccounts(1);
368
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
369
+ const addedAccountAddress = (await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this)).find(
370
+ (selectedAddress) => !oldAccounts.includes(selectedAddress)
371
+ );
372
+ _utils.assertIsStrictHexString.call(void 0, addedAccountAddress);
373
+ return addedAccountAddress;
374
+ });
323
375
  }
324
376
  /**
325
377
  * Adds a new account to the default (first) HD seed phrase keyring without updating identities in preferences.
326
378
  *
327
- * @returns Promise resolving to current state when the account is added.
379
+ * @returns Promise resolving to the added account address.
328
380
  */
329
381
  async addNewAccountWithoutUpdate() {
330
- const primaryKeyring = this.getKeyringsByType("HD Key Tree")[0];
331
- if (!primaryKeyring) {
332
- throw new Error("No HD keyring found");
333
- }
334
- await primaryKeyring.addAccounts(1);
335
- await this.persistAllKeyrings();
336
- await this.verifySeedPhrase();
337
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
382
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
383
+ const primaryKeyring = this.getKeyringsByType("HD Key Tree")[0];
384
+ if (!primaryKeyring) {
385
+ throw new Error("No HD keyring found");
386
+ }
387
+ const [addedAccountAddress] = await primaryKeyring.addAccounts(1);
388
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
389
+ await this.verifySeedPhrase();
390
+ return addedAccountAddress;
391
+ });
338
392
  }
339
393
  /**
340
394
  * Effectively the same as creating a new keychain then populating it
@@ -343,45 +397,37 @@ var KeyringController = class extends _basecontroller.BaseController {
343
397
  * @param password - Password to unlock keychain.
344
398
  * @param seed - A BIP39-compliant seed phrase as Uint8Array,
345
399
  * either as a string or an array of UTF-8 bytes that represent the string.
346
- * @returns Promise resolving to the restored keychain object.
400
+ * @returns Promise resolving when the operation ends successfully.
347
401
  */
348
402
  async createNewVaultAndRestore(password, seed) {
349
- const releaseLock = await this.mutex.acquire();
350
- if (!password || !password.length) {
351
- throw new Error("Invalid password");
352
- }
353
- try {
354
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn).call(this, password, {
403
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
404
+ if (!password || !password.length) {
405
+ throw new Error("Invalid password");
406
+ }
407
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn).call(this, password, {
355
408
  type: "HD Key Tree" /* hd */,
356
409
  opts: {
357
410
  mnemonic: seed,
358
411
  numberOfAccounts: 1
359
412
  }
360
413
  });
361
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
362
- } finally {
363
- releaseLock();
364
- }
414
+ });
365
415
  }
366
416
  /**
367
417
  * Create a new primary keychain and wipe any previous keychains.
368
418
  *
369
419
  * @param password - Password to unlock the new vault.
370
- * @returns Newly-created keychain object.
420
+ * @returns Promise resolving when the operation ends successfully.
371
421
  */
372
422
  async createNewVaultAndKeychain(password) {
373
- const releaseLock = await this.mutex.acquire();
374
- try {
375
- const accounts = await this.getAccounts();
423
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
424
+ const accounts = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this);
376
425
  if (!accounts.length) {
377
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn).call(this, password, {
426
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _createNewVaultWithKeyring, createNewVaultWithKeyring_fn).call(this, password, {
378
427
  type: "HD Key Tree" /* hd */
379
428
  });
380
429
  }
381
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
382
- } finally {
383
- releaseLock();
384
- }
430
+ });
385
431
  }
386
432
  /**
387
433
  * Adds a new keyring of the given `type`.
@@ -395,21 +441,7 @@ var KeyringController = class extends _basecontroller.BaseController {
395
441
  if (type === "QR Hardware Wallet Device" /* qr */) {
396
442
  return this.getOrAddQRKeyring();
397
443
  }
398
- const keyring = await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, type, opts);
399
- if (type === "HD Key Tree" /* hd */ && (!_utils.isObject.call(void 0, opts) || !opts.mnemonic)) {
400
- if (!keyring.generateRandomMnemonic) {
401
- throw new Error(
402
- "KeyringController - The current keyring does not support the method generateRandomMnemonic." /* UnsupportedGenerateRandomMnemonic */
403
- );
404
- }
405
- keyring.generateRandomMnemonic();
406
- await keyring.addAccounts(1);
407
- }
408
- const accounts = await keyring.getAccounts();
409
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _checkForDuplicate, checkForDuplicate_fn).call(this, type, accounts);
410
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).push(keyring);
411
- await this.persistAllKeyrings();
412
- return keyring;
444
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, type, opts, true));
413
445
  }
414
446
  /**
415
447
  * Method to verify a given password validity. Throws an
@@ -421,7 +453,7 @@ var KeyringController = class extends _basecontroller.BaseController {
421
453
  if (!this.state.vault) {
422
454
  throw new Error("KeyringController - Cannot unlock without a previous vault." /* VaultError */);
423
455
  }
424
- await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).decrypt(password, this.state.vault);
456
+ await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).decrypt(password, this.state.vault);
425
457
  }
426
458
  /**
427
459
  * Returns the status of the vault.
@@ -439,8 +471,8 @@ var KeyringController = class extends _basecontroller.BaseController {
439
471
  */
440
472
  async exportSeedPhrase(password) {
441
473
  await this.verifyPassword(password);
442
- assertHasUint8ArrayMnemonic(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings)[0]);
443
- return _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings)[0].mnemonic;
474
+ assertHasUint8ArrayMnemonic(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings)[0]);
475
+ return _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings)[0].mnemonic;
444
476
  }
445
477
  /**
446
478
  * Gets the private key from the keyring controlling an address.
@@ -460,19 +492,15 @@ var KeyringController = class extends _basecontroller.BaseController {
460
492
  return await keyring.exportAccount(_ethsigutil.normalize.call(void 0, address));
461
493
  }
462
494
  /**
463
- * Returns the public addresses of all accounts for the current keyring.
495
+ * Returns the public addresses of all accounts from every keyring.
464
496
  *
465
497
  * @returns A promise resolving to an array of addresses.
466
498
  */
467
499
  async getAccounts() {
468
- const keyrings = _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings);
469
- const keyringArrays = await Promise.all(
470
- keyrings.map(async (keyring) => keyring.getAccounts())
500
+ return this.state.keyrings.reduce(
501
+ (accounts, keyring) => accounts.concat(keyring.accounts),
502
+ []
471
503
  );
472
- const addresses = keyringArrays.reduce((res, arr) => {
473
- return res.concat(arr);
474
- }, []);
475
- return addresses.map(_ethsigutil.normalize);
476
504
  }
477
505
  /**
478
506
  * Get encryption public key.
@@ -523,7 +551,7 @@ var KeyringController = class extends _basecontroller.BaseController {
523
551
  async getKeyringForAccount(account) {
524
552
  const hexed = _ethsigutil.normalize.call(void 0, account);
525
553
  const candidates = await Promise.all(
526
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
554
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
527
555
  return Promise.all([keyring, keyring.getAccounts()]);
528
556
  })
529
557
  );
@@ -556,7 +584,7 @@ var KeyringController = class extends _basecontroller.BaseController {
556
584
  * @returns An array of keyrings of the given type.
557
585
  */
558
586
  getKeyringsByType(type) {
559
- return _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).filter((keyring) => keyring.type === type);
587
+ return _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).filter((keyring) => keyring.type === type);
560
588
  }
561
589
  /**
562
590
  * Persist all serialized keyrings in the vault.
@@ -565,60 +593,7 @@ var KeyringController = class extends _basecontroller.BaseController {
565
593
  * operation completes.
566
594
  */
567
595
  async persistAllKeyrings() {
568
- const { encryptionKey, encryptionSalt } = this.state;
569
- if (!_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password) && !encryptionKey) {
570
- throw new Error("KeyringController - Cannot persist vault without password and encryption key" /* MissingCredentials */);
571
- }
572
- const serializedKeyrings = await Promise.all(
573
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
574
- const [type, data] = await Promise.all([
575
- keyring.type,
576
- keyring.serialize()
577
- ]);
578
- return { type, data };
579
- })
580
- );
581
- serializedKeyrings.push(..._chunkCHLPTPMZjs.__privateGet.call(void 0, this, _unsupportedKeyrings));
582
- let vault;
583
- let newEncryptionKey;
584
- if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
585
- assertIsExportableKeyEncryptor(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor));
586
- if (encryptionKey) {
587
- const key = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).importKey(encryptionKey);
588
- const vaultJSON = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).encryptWithKey(
589
- key,
590
- serializedKeyrings
591
- );
592
- vaultJSON.salt = encryptionSalt;
593
- vault = JSON.stringify(vaultJSON);
594
- } else if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password)) {
595
- const { vault: newVault, exportedKeyString } = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).encryptWithDetail(
596
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password),
597
- serializedKeyrings
598
- );
599
- vault = newVault;
600
- newEncryptionKey = exportedKeyString;
601
- }
602
- } else {
603
- if (typeof _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password) !== "string") {
604
- throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
605
- }
606
- vault = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).encrypt(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password), serializedKeyrings);
607
- }
608
- if (!vault) {
609
- throw new Error("KeyringController - Cannot persist vault without vault information" /* MissingVaultData */);
610
- }
611
- this.update((state) => {
612
- state.vault = vault;
613
- });
614
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _updateKeyringsInState, updateKeyringsInState_fn).call(this);
615
- if (newEncryptionKey) {
616
- this.update((state) => {
617
- state.encryptionKey = newEncryptionKey;
618
- state.encryptionSalt = JSON.parse(vault).salt;
619
- });
620
- }
621
- return true;
596
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this));
622
597
  }
623
598
  /**
624
599
  * Imports an account with the specified import strategy.
@@ -626,90 +601,88 @@ var KeyringController = class extends _basecontroller.BaseController {
626
601
  * @param strategy - Import strategy name.
627
602
  * @param args - Array of arguments to pass to the underlying stategy.
628
603
  * @throws Will throw when passed an unrecognized strategy.
629
- * @returns Promise resolving to keyring current state and imported account
630
- * address.
604
+ * @returns Promise resolving to the imported account address.
631
605
  */
632
606
  async importAccountWithStrategy(strategy, args) {
633
- let privateKey;
634
- switch (strategy) {
635
- case "privateKey":
636
- const [importedKey] = args;
637
- if (!importedKey) {
638
- throw new Error("Cannot import an empty key.");
639
- }
640
- const prefixed = _utils.add0x.call(void 0, importedKey);
641
- let bufferedPrivateKey;
642
- try {
643
- bufferedPrivateKey = _util.toBuffer.call(void 0, prefixed);
644
- } catch {
645
- throw new Error("Cannot import invalid private key.");
646
- }
647
- if (!_util.isValidPrivate.call(void 0, bufferedPrivateKey) || // ensures that the key is 64 bytes long
648
- _util.getBinarySize.call(void 0, prefixed) !== 64 + "0x".length) {
649
- throw new Error("Cannot import invalid private key.");
650
- }
651
- privateKey = _utils.remove0x.call(void 0, prefixed);
652
- break;
653
- case "json":
654
- let wallet;
655
- const [input, password] = args;
656
- try {
657
- wallet = _ethereumjswallet.thirdparty.fromEtherWallet(input, password);
658
- } catch (e) {
659
- wallet = wallet || await _ethereumjswallet2.default.fromV3(input, password, true);
660
- }
661
- privateKey = _utils.bytesToHex.call(void 0, wallet.getPrivateKey());
662
- break;
663
- default:
664
- throw new Error(`Unexpected import strategy: '${strategy}'`);
665
- }
666
- const newKeyring = await this.addNewKeyring("Simple Key Pair" /* simple */, [
667
- privateKey
668
- ]);
669
- const accounts = await newKeyring.getAccounts();
670
- return {
671
- keyringState: _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this),
672
- importedAccountAddress: accounts[0]
673
- };
607
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
608
+ let privateKey;
609
+ switch (strategy) {
610
+ case "privateKey":
611
+ const [importedKey] = args;
612
+ if (!importedKey) {
613
+ throw new Error("Cannot import an empty key.");
614
+ }
615
+ const prefixed = _utils.add0x.call(void 0, importedKey);
616
+ let bufferedPrivateKey;
617
+ try {
618
+ bufferedPrivateKey = _util.toBuffer.call(void 0, prefixed);
619
+ } catch {
620
+ throw new Error("Cannot import invalid private key.");
621
+ }
622
+ if (!_util.isValidPrivate.call(void 0, bufferedPrivateKey) || // ensures that the key is 64 bytes long
623
+ _util.getBinarySize.call(void 0, prefixed) !== 64 + "0x".length) {
624
+ throw new Error("Cannot import invalid private key.");
625
+ }
626
+ privateKey = _utils.remove0x.call(void 0, prefixed);
627
+ break;
628
+ case "json":
629
+ let wallet;
630
+ const [input, password] = args;
631
+ try {
632
+ wallet = _ethereumjswallet.thirdparty.fromEtherWallet(input, password);
633
+ } catch (e) {
634
+ wallet = wallet || await _ethereumjswallet2.default.fromV3(input, password, true);
635
+ }
636
+ privateKey = _utils.bytesToHex.call(void 0, wallet.getPrivateKey());
637
+ break;
638
+ default:
639
+ throw new Error(`Unexpected import strategy: '${strategy}'`);
640
+ }
641
+ const newKeyring = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, "Simple Key Pair" /* simple */, [privateKey], true);
642
+ const accounts = await newKeyring.getAccounts();
643
+ return accounts[0];
644
+ });
674
645
  }
675
646
  /**
676
647
  * Removes an account from keyring state.
677
648
  *
678
649
  * @param address - Address of the account to remove.
679
650
  * @fires KeyringController:accountRemoved
680
- * @returns Promise resolving current state when this account removal completes.
651
+ * @returns Promise resolving when the account is removed.
681
652
  */
682
653
  async removeAccount(address) {
683
- const keyring = await this.getKeyringForAccount(
684
- address
685
- );
686
- if (!keyring.removeAccount) {
687
- throw new Error("`KeyringController - The keyring for the current address does not support the method removeAccount" /* UnsupportedRemoveAccount */);
688
- }
689
- await keyring.removeAccount(address);
690
- const accounts = await keyring.getAccounts();
691
- if (accounts.length === 0) {
692
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _removeEmptyKeyrings, removeEmptyKeyrings_fn).call(this);
693
- }
694
- await this.persistAllKeyrings();
654
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
655
+ const keyring = await this.getKeyringForAccount(
656
+ address
657
+ );
658
+ if (!keyring.removeAccount) {
659
+ throw new Error("`KeyringController - The keyring for the current address does not support the method removeAccount" /* UnsupportedRemoveAccount */);
660
+ }
661
+ await keyring.removeAccount(address);
662
+ const accounts = await keyring.getAccounts();
663
+ if (accounts.length === 0) {
664
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _removeEmptyKeyrings, removeEmptyKeyrings_fn).call(this);
665
+ }
666
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
667
+ });
695
668
  this.messagingSystem.publish(`${name}:accountRemoved`, address);
696
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
697
669
  }
698
670
  /**
699
671
  * Deallocates all secrets and locks the wallet.
700
672
  *
701
- * @returns Promise resolving to current state.
673
+ * @returns Promise resolving when the operation completes.
702
674
  */
703
675
  async setLocked() {
704
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _unsubscribeFromQRKeyringsEvents, unsubscribeFromQRKeyringsEvents_fn).call(this);
705
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _password, void 0);
706
- this.update((state) => {
707
- state.isUnlocked = false;
708
- state.keyrings = [];
676
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
677
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _unsubscribeFromQRKeyringsEvents, unsubscribeFromQRKeyringsEvents_fn).call(this);
678
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _password, void 0);
679
+ this.update((state) => {
680
+ state.isUnlocked = false;
681
+ state.keyrings = [];
682
+ });
683
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this);
684
+ this.messagingSystem.publish(`${name}:lock`);
709
685
  });
710
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this);
711
- this.messagingSystem.publish(`${name}:lock`);
712
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
713
686
  }
714
687
  /**
715
688
  * Signs message by calling down into a specific keyring.
@@ -803,9 +776,10 @@ var KeyringController = class extends _basecontroller.BaseController {
803
776
  *
804
777
  * @param from - Address of the sender.
805
778
  * @param transactions - Base transactions to include in the UserOperation.
779
+ * @param executionContext - The execution context to use for the UserOperation.
806
780
  * @returns A pseudo-UserOperation that can be used to construct a real.
807
781
  */
808
- async prepareUserOperation(from, transactions) {
782
+ async prepareUserOperation(from, transactions, executionContext) {
809
783
  const address = _ethsigutil.normalize.call(void 0, from);
810
784
  const keyring = await this.getKeyringForAccount(
811
785
  address
@@ -813,7 +787,11 @@ var KeyringController = class extends _basecontroller.BaseController {
813
787
  if (!keyring.prepareUserOperation) {
814
788
  throw new Error("KeyringController - The keyring for the current address does not support the method prepareUserOperation." /* UnsupportedPrepareUserOperation */);
815
789
  }
816
- return await keyring.prepareUserOperation(address, transactions);
790
+ return await keyring.prepareUserOperation(
791
+ address,
792
+ transactions,
793
+ executionContext
794
+ );
817
795
  }
818
796
  /**
819
797
  * Patches properties of a UserOperation. Currently, only the
@@ -821,9 +799,10 @@ var KeyringController = class extends _basecontroller.BaseController {
821
799
  *
822
800
  * @param from - Address of the sender.
823
801
  * @param userOp - UserOperation to patch.
802
+ * @param executionContext - The execution context to use for the UserOperation.
824
803
  * @returns A patch to apply to the UserOperation.
825
804
  */
826
- async patchUserOperation(from, userOp) {
805
+ async patchUserOperation(from, userOp, executionContext) {
827
806
  const address = _ethsigutil.normalize.call(void 0, from);
828
807
  const keyring = await this.getKeyringForAccount(
829
808
  address
@@ -831,16 +810,17 @@ var KeyringController = class extends _basecontroller.BaseController {
831
810
  if (!keyring.patchUserOperation) {
832
811
  throw new Error("KeyringController - The keyring for the current address does not support the method patchUserOperation." /* UnsupportedPatchUserOperation */);
833
812
  }
834
- return await keyring.patchUserOperation(address, userOp);
813
+ return await keyring.patchUserOperation(address, userOp, executionContext);
835
814
  }
836
815
  /**
837
816
  * Signs an UserOperation.
838
817
  *
839
818
  * @param from - Address of the sender.
840
819
  * @param userOp - UserOperation to sign.
820
+ * @param executionContext - The execution context to use for the UserOperation.
841
821
  * @returns The signature of the UserOperation.
842
822
  */
843
- async signUserOperation(from, userOp) {
823
+ async signUserOperation(from, userOp, executionContext) {
844
824
  const address = _ethsigutil.normalize.call(void 0, from);
845
825
  const keyring = await this.getKeyringForAccount(
846
826
  address
@@ -848,7 +828,7 @@ var KeyringController = class extends _basecontroller.BaseController {
848
828
  if (!keyring.signUserOperation) {
849
829
  throw new Error("KeyringController - The keyring for the current address does not support the method signUserOperation." /* UnsupportedSignUserOperation */);
850
830
  }
851
- return await keyring.signUserOperation(address, userOp);
831
+ return await keyring.signUserOperation(address, userOp, executionContext);
852
832
  }
853
833
  /**
854
834
  * Attempts to decrypt the current vault and load its keyrings,
@@ -856,32 +836,34 @@ var KeyringController = class extends _basecontroller.BaseController {
856
836
  *
857
837
  * @param encryptionKey - Key to unlock the keychain.
858
838
  * @param encryptionSalt - Salt to unlock the keychain.
859
- * @returns Promise resolving to the current state.
839
+ * @returns Promise resolving when the operation completes.
860
840
  */
861
841
  async submitEncryptionKey(encryptionKey, encryptionSalt) {
862
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyrings, await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _unlockKeyrings, unlockKeyrings_fn).call(this, void 0, encryptionKey, encryptionSalt));
863
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
864
- const qrKeyring = this.getQRKeyring();
865
- if (qrKeyring) {
866
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
867
- }
868
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
842
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
843
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyrings, await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _unlockKeyrings, unlockKeyrings_fn).call(this, void 0, encryptionKey, encryptionSalt));
844
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
845
+ const qrKeyring = this.getQRKeyring();
846
+ if (qrKeyring) {
847
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
848
+ }
849
+ });
869
850
  }
870
851
  /**
871
852
  * Attempts to decrypt the current vault and load its keyrings,
872
853
  * using the given password.
873
854
  *
874
855
  * @param password - Password to unlock the keychain.
875
- * @returns Promise resolving to the current state.
856
+ * @returns Promise resolving when the operation completes.
876
857
  */
877
858
  async submitPassword(password) {
878
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyrings, await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _unlockKeyrings, unlockKeyrings_fn).call(this, password));
879
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
880
- const qrKeyring = this.getQRKeyring();
881
- if (qrKeyring) {
882
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
883
- }
884
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
859
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
860
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyrings, await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _unlockKeyrings, unlockKeyrings_fn).call(this, password));
861
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
862
+ const qrKeyring = this.getQRKeyring();
863
+ if (qrKeyring) {
864
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
865
+ }
866
+ });
885
867
  }
886
868
  /**
887
869
  * Verifies the that the seed phrase restores the current keychain's accounts.
@@ -899,7 +881,7 @@ var KeyringController = class extends _basecontroller.BaseController {
899
881
  if (accounts.length === 0) {
900
882
  throw new Error("Cannot verify an empty keyring.");
901
883
  }
902
- const hdKeyringBuilder = _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getKeyringBuilderForType, getKeyringBuilderForType_fn).call(this, "HD Key Tree" /* hd */);
884
+ const hdKeyringBuilder = _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getKeyringBuilderForType, getKeyringBuilderForType_fn).call(this, "HD Key Tree" /* hd */);
903
885
  const hdKeyring = hdKeyringBuilder();
904
886
  await hdKeyring.deserialize({
905
887
  mnemonic: seedWords,
@@ -931,13 +913,16 @@ var KeyringController = class extends _basecontroller.BaseController {
931
913
  * @returns The added keyring
932
914
  */
933
915
  async getOrAddQRKeyring() {
934
- return this.getQRKeyring() || await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _addQRKeyring, addQRKeyring_fn).call(this);
916
+ return this.getQRKeyring() || await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _addQRKeyring, addQRKeyring_fn).call(this));
935
917
  }
936
918
  // TODO: Replace `any` with type
937
919
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
938
920
  async restoreQRKeyring(serialized) {
939
- (await this.getOrAddQRKeyring()).deserialize(serialized);
940
- await this.persistAllKeyrings();
921
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
922
+ const keyring = this.getQRKeyring() || await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _addQRKeyring, addQRKeyring_fn).call(this);
923
+ keyring.deserialize(serialized);
924
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
925
+ });
941
926
  }
942
927
  async resetQRKeyringState() {
943
928
  (await this.getOrAddQRKeyring()).resetStore();
@@ -964,34 +949,38 @@ var KeyringController = class extends _basecontroller.BaseController {
964
949
  (await this.getOrAddQRKeyring()).cancelSync();
965
950
  }
966
951
  async connectQRHardware(page) {
967
- try {
968
- const keyring = await this.getOrAddQRKeyring();
969
- let accounts;
970
- switch (page) {
971
- case -1:
972
- accounts = await keyring.getPreviousPage();
973
- break;
974
- case 1:
975
- accounts = await keyring.getNextPage();
976
- break;
977
- default:
978
- accounts = await keyring.getFirstPage();
952
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
953
+ try {
954
+ const keyring = this.getQRKeyring() || await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _addQRKeyring, addQRKeyring_fn).call(this);
955
+ let accounts;
956
+ switch (page) {
957
+ case -1:
958
+ accounts = await keyring.getPreviousPage();
959
+ break;
960
+ case 1:
961
+ accounts = await keyring.getNextPage();
962
+ break;
963
+ default:
964
+ accounts = await keyring.getFirstPage();
965
+ }
966
+ return accounts.map((account) => {
967
+ return {
968
+ ...account,
969
+ balance: "0x0"
970
+ };
971
+ });
972
+ } catch (e) {
973
+ throw new Error(`Unspecified error when connect QR Hardware, ${e}`);
979
974
  }
980
- return accounts.map((account) => {
981
- return {
982
- ...account,
983
- balance: "0x0"
984
- };
985
- });
986
- } catch (e) {
987
- throw new Error(`Unspecified error when connect QR Hardware, ${e}`);
988
- }
975
+ });
989
976
  }
990
977
  async unlockQRHardwareWalletAccount(index) {
991
- const keyring = await this.getOrAddQRKeyring();
992
- keyring.setAccountToUnlock(index);
993
- await this.addNewAccountForKeyring(keyring);
994
- await this.persistAllKeyrings();
978
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
979
+ const keyring = this.getQRKeyring() || await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _addQRKeyring, addQRKeyring_fn).call(this);
980
+ keyring.setAccountToUnlock(index);
981
+ await keyring.addAccounts(1);
982
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
983
+ });
995
984
  }
996
985
  async getAccountKeyringType(account) {
997
986
  const keyring = await this.getKeyringForAccount(
@@ -1000,17 +989,24 @@ var KeyringController = class extends _basecontroller.BaseController {
1000
989
  return keyring.type;
1001
990
  }
1002
991
  async forgetQRDevice() {
1003
- const keyring = await this.getOrAddQRKeyring();
1004
- const allAccounts = await this.getAccounts();
1005
- keyring.forgetDevice();
1006
- const remainingAccounts = await this.getAccounts();
1007
- const removedAccounts = allAccounts.filter(
1008
- (address) => !remainingAccounts.includes(address)
1009
- );
1010
- await this.persistAllKeyrings();
1011
- return { removedAccounts, remainingAccounts };
992
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withControllerLock, withControllerLock_fn).call(this, async () => {
993
+ const keyring = this.getQRKeyring();
994
+ if (!keyring) {
995
+ return { removedAccounts: [], remainingAccounts: [] };
996
+ }
997
+ const allAccounts = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this);
998
+ keyring.forgetDevice();
999
+ const remainingAccounts = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this);
1000
+ const removedAccounts = allAccounts.filter(
1001
+ (address) => !remainingAccounts.includes(address)
1002
+ );
1003
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
1004
+ return { removedAccounts, remainingAccounts };
1005
+ });
1012
1006
  }
1013
1007
  };
1008
+ _controllerOperationMutex = new WeakMap();
1009
+ _vaultOperationMutex = new WeakMap();
1014
1010
  _keyringBuilders = new WeakMap();
1015
1011
  _keyrings = new WeakMap();
1016
1012
  _unsupportedKeyrings = new WeakMap();
@@ -1071,28 +1067,29 @@ registerMessageHandlers_fn = function() {
1071
1067
  };
1072
1068
  _getKeyringBuilderForType = new WeakSet();
1073
1069
  getKeyringBuilderForType_fn = function(type) {
1074
- return _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyringBuilders).find(
1070
+ return _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyringBuilders).find(
1075
1071
  (keyringBuilder) => keyringBuilder.type === type
1076
1072
  );
1077
1073
  };
1078
1074
  _addQRKeyring = new WeakSet();
1079
1075
  addQRKeyring_fn = async function() {
1080
- const qrKeyring = await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, "QR Hardware Wallet Device" /* qr */, {
1076
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1077
+ const qrKeyring = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, "QR Hardware Wallet Device" /* qr */, {
1081
1078
  accounts: []
1082
1079
  });
1083
1080
  const accounts = await qrKeyring.getAccounts();
1084
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _checkForDuplicate, checkForDuplicate_fn).call(this, "QR Hardware Wallet Device" /* qr */, accounts);
1085
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).push(qrKeyring);
1086
- await this.persistAllKeyrings();
1087
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
1081
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _checkForDuplicate, checkForDuplicate_fn).call(this, "QR Hardware Wallet Device" /* qr */, accounts);
1082
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).push(qrKeyring);
1083
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
1084
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _subscribeToQRKeyringEvents, subscribeToQRKeyringEvents_fn).call(this, qrKeyring);
1088
1085
  return qrKeyring;
1089
1086
  };
1090
1087
  _subscribeToQRKeyringEvents = new WeakSet();
1091
1088
  subscribeToQRKeyringEvents_fn = function(qrKeyring) {
1092
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _qrKeyringStateListener, (state) => {
1089
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _qrKeyringStateListener, (state) => {
1093
1090
  this.messagingSystem.publish(`${name}:qrKeyringStateChange`, state);
1094
1091
  });
1095
- qrKeyring.getMemStore().subscribe(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _qrKeyringStateListener));
1092
+ qrKeyring.getMemStore().subscribe(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _qrKeyringStateListener));
1096
1093
  };
1097
1094
  _unsubscribeFromQRKeyringsEvents = new WeakSet();
1098
1095
  unsubscribeFromQRKeyringsEvents_fn = function() {
@@ -1100,93 +1097,176 @@ unsubscribeFromQRKeyringsEvents_fn = function() {
1100
1097
  "QR Hardware Wallet Device" /* qr */
1101
1098
  );
1102
1099
  qrKeyrings.forEach((qrKeyring) => {
1103
- if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _qrKeyringStateListener)) {
1104
- qrKeyring.getMemStore().unsubscribe(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _qrKeyringStateListener));
1100
+ if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _qrKeyringStateListener)) {
1101
+ qrKeyring.getMemStore().unsubscribe(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _qrKeyringStateListener));
1105
1102
  }
1106
1103
  });
1107
1104
  };
1108
1105
  _createNewVaultWithKeyring = new WeakSet();
1109
1106
  createNewVaultWithKeyring_fn = async function(password, keyring) {
1107
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1110
1108
  if (typeof password !== "string") {
1111
1109
  throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
1112
1110
  }
1113
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _password, password);
1114
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this);
1115
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _createKeyringWithFirstAccount, createKeyringWithFirstAccount_fn).call(this, keyring.type, keyring.opts);
1116
- _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
1117
- return _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getMemState, getMemState_fn).call(this);
1111
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _password, password);
1112
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this);
1113
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _createKeyringWithFirstAccount, createKeyringWithFirstAccount_fn).call(this, keyring.type, keyring.opts);
1114
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _setUnlocked, setUnlocked_fn).call(this);
1118
1115
  };
1119
- _updateKeyringsInState = new WeakSet();
1120
- updateKeyringsInState_fn = async function() {
1121
- const keyrings = await Promise.all(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).map(displayForKeyring));
1122
- this.update((state) => {
1123
- state.keyrings = keyrings;
1124
- });
1116
+ _getUpdatedKeyrings = new WeakSet();
1117
+ getUpdatedKeyrings_fn = async function() {
1118
+ return Promise.all(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).map(displayForKeyring));
1125
1119
  };
1126
1120
  _unlockKeyrings = new WeakSet();
1127
1121
  unlockKeyrings_fn = async function(password, encryptionKey, encryptionSalt) {
1128
- const encryptedVault = this.state.vault;
1129
- if (!encryptedVault) {
1130
- throw new Error("KeyringController - Cannot unlock without a previous vault." /* VaultError */);
1131
- }
1132
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this);
1133
- let vault;
1134
- if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
1135
- assertIsExportableKeyEncryptor(_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor));
1136
- if (password) {
1137
- const result = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).decryptWithDetail(
1138
- password,
1139
- encryptedVault
1140
- );
1141
- vault = result.vault;
1142
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _password, password);
1143
- this.update((state) => {
1144
- state.encryptionKey = result.exportedKeyString;
1145
- state.encryptionSalt = result.salt;
1146
- });
1122
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withVaultLock, withVaultLock_fn).call(this, async ({ releaseLock }) => {
1123
+ const encryptedVault = this.state.vault;
1124
+ if (!encryptedVault) {
1125
+ throw new Error("KeyringController - Cannot unlock without a previous vault." /* VaultError */);
1126
+ }
1127
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _clearKeyrings, clearKeyrings_fn).call(this, { skipStateUpdate: true });
1128
+ let vault;
1129
+ const updatedState = {};
1130
+ if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
1131
+ assertIsExportableKeyEncryptor(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor));
1132
+ if (password) {
1133
+ const result = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).decryptWithDetail(
1134
+ password,
1135
+ encryptedVault
1136
+ );
1137
+ vault = result.vault;
1138
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _password, password);
1139
+ updatedState.encryptionKey = result.exportedKeyString;
1140
+ updatedState.encryptionSalt = result.salt;
1141
+ } else {
1142
+ const parsedEncryptedVault = JSON.parse(encryptedVault);
1143
+ if (encryptionSalt !== parsedEncryptedVault.salt) {
1144
+ throw new Error("KeyringController - Encryption key and salt provided are expired" /* ExpiredCredentials */);
1145
+ }
1146
+ if (typeof encryptionKey !== "string") {
1147
+ throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
1148
+ }
1149
+ const key = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).importKey(encryptionKey);
1150
+ vault = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).decryptWithKey(
1151
+ key,
1152
+ parsedEncryptedVault
1153
+ );
1154
+ updatedState.encryptionKey = encryptionKey;
1155
+ updatedState.encryptionSalt = encryptionSalt;
1156
+ }
1147
1157
  } else {
1148
- const parsedEncryptedVault = JSON.parse(encryptedVault);
1149
- if (encryptionSalt !== parsedEncryptedVault.salt) {
1150
- throw new Error("KeyringController - Encryption key and salt provided are expired" /* ExpiredCredentials */);
1158
+ if (typeof password !== "string") {
1159
+ throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
1160
+ }
1161
+ vault = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).decrypt(password, encryptedVault);
1162
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _password, password);
1163
+ }
1164
+ if (!isSerializedKeyringsArray(vault)) {
1165
+ throw new Error("KeyringController - The decrypted vault has an unexpected shape." /* VaultDataError */);
1166
+ }
1167
+ await Promise.all(vault.map(_chunkQDPHKQONjs.__privateMethod.call(void 0, this, _restoreKeyring, restoreKeyring_fn).bind(this)));
1168
+ const updatedKeyrings = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getUpdatedKeyrings, getUpdatedKeyrings_fn).call(this);
1169
+ this.update((state) => {
1170
+ state.keyrings = updatedKeyrings;
1171
+ if (updatedState.encryptionKey || updatedState.encryptionSalt) {
1172
+ state.encryptionKey = updatedState.encryptionKey;
1173
+ state.encryptionSalt = updatedState.encryptionSalt;
1174
+ }
1175
+ });
1176
+ if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _password) && (!_chunkQDPHKQONjs.__privateGet.call(void 0, this, _cacheEncryptionKey) || !encryptionKey) && _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).isVaultUpdated && !_chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).isVaultUpdated(encryptedVault)) {
1177
+ releaseLock();
1178
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
1179
+ }
1180
+ return _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings);
1181
+ });
1182
+ };
1183
+ _updateVault = new WeakSet();
1184
+ updateVault_fn = function() {
1185
+ return _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _withVaultLock, withVaultLock_fn).call(this, async () => {
1186
+ const { encryptionKey, encryptionSalt } = this.state;
1187
+ if (!_chunkQDPHKQONjs.__privateGet.call(void 0, this, _password) && !encryptionKey) {
1188
+ throw new Error("KeyringController - Cannot persist vault without password and encryption key" /* MissingCredentials */);
1189
+ }
1190
+ const serializedKeyrings = await Promise.all(
1191
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
1192
+ const [type, data] = await Promise.all([
1193
+ keyring.type,
1194
+ keyring.serialize()
1195
+ ]);
1196
+ return { type, data };
1197
+ })
1198
+ );
1199
+ serializedKeyrings.push(..._chunkQDPHKQONjs.__privateGet.call(void 0, this, _unsupportedKeyrings));
1200
+ if (!serializedKeyrings.some((keyring) => keyring.type === "HD Key Tree" /* hd */)) {
1201
+ throw new Error("KeyringController - No HD Keyring found" /* NoHdKeyring */);
1202
+ }
1203
+ const updatedState = {};
1204
+ if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _cacheEncryptionKey)) {
1205
+ assertIsExportableKeyEncryptor(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor));
1206
+ if (encryptionKey) {
1207
+ const key = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).importKey(encryptionKey);
1208
+ const vaultJSON = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).encryptWithKey(
1209
+ key,
1210
+ serializedKeyrings
1211
+ );
1212
+ vaultJSON.salt = encryptionSalt;
1213
+ updatedState.vault = JSON.stringify(vaultJSON);
1214
+ } else if (_chunkQDPHKQONjs.__privateGet.call(void 0, this, _password)) {
1215
+ const { vault: newVault, exportedKeyString } = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).encryptWithDetail(
1216
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _password),
1217
+ serializedKeyrings
1218
+ );
1219
+ updatedState.vault = newVault;
1220
+ updatedState.encryptionKey = exportedKeyString;
1151
1221
  }
1152
- if (typeof encryptionKey !== "string") {
1222
+ } else {
1223
+ if (typeof _chunkQDPHKQONjs.__privateGet.call(void 0, this, _password) !== "string") {
1153
1224
  throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
1154
1225
  }
1155
- const key = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).importKey(encryptionKey);
1156
- vault = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).decryptWithKey(key, parsedEncryptedVault);
1157
- this.update((state) => {
1158
- state.encryptionKey = encryptionKey;
1159
- state.encryptionSalt = encryptionSalt;
1160
- });
1226
+ updatedState.vault = await _chunkQDPHKQONjs.__privateGet.call(void 0, this, _encryptor).encrypt(
1227
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _password),
1228
+ serializedKeyrings
1229
+ );
1161
1230
  }
1162
- } else {
1163
- if (typeof password !== "string") {
1164
- throw new TypeError("KeyringController - Password must be of type string." /* WrongPasswordType */);
1231
+ if (!updatedState.vault) {
1232
+ throw new Error("KeyringController - Cannot persist vault without vault information" /* MissingVaultData */);
1165
1233
  }
1166
- vault = await _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).decrypt(password, encryptedVault);
1167
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _password, password);
1168
- }
1169
- if (!isSerializedKeyringsArray(vault)) {
1170
- throw new Error("KeyringController - The decrypted vault has an unexpected shape." /* VaultDataError */);
1171
- }
1172
- await Promise.all(vault.map(_chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _restoreKeyring, restoreKeyring_fn).bind(this)));
1173
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _updateKeyringsInState, updateKeyringsInState_fn).call(this);
1174
- if (_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _password) && (!_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _cacheEncryptionKey) || !encryptionKey) && _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).isVaultUpdated && !_chunkCHLPTPMZjs.__privateGet.call(void 0, this, _encryptor).isVaultUpdated(encryptedVault)) {
1175
- await this.persistAllKeyrings();
1176
- }
1177
- return _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings);
1234
+ const updatedKeyrings = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getUpdatedKeyrings, getUpdatedKeyrings_fn).call(this);
1235
+ this.update((state) => {
1236
+ state.vault = updatedState.vault;
1237
+ state.keyrings = updatedKeyrings;
1238
+ if (updatedState.encryptionKey) {
1239
+ state.encryptionKey = updatedState.encryptionKey;
1240
+ state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1241
+ }
1242
+ });
1243
+ return true;
1244
+ });
1245
+ };
1246
+ _getAccountsFromKeyrings = new WeakSet();
1247
+ getAccountsFromKeyrings_fn = async function() {
1248
+ const keyrings = _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings);
1249
+ const keyringArrays = await Promise.all(
1250
+ keyrings.map(async (keyring) => keyring.getAccounts())
1251
+ );
1252
+ const addresses = keyringArrays.reduce((res, arr) => {
1253
+ return res.concat(arr);
1254
+ }, []);
1255
+ return addresses.map(_ethsigutil.normalize);
1178
1256
  };
1179
1257
  _createKeyringWithFirstAccount = new WeakSet();
1180
1258
  createKeyringWithFirstAccount_fn = async function(type, opts) {
1181
- const keyring = await this.addNewKeyring(type, opts);
1259
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1260
+ const keyring = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, type, opts, true);
1182
1261
  const [firstAccount] = await keyring.getAccounts();
1183
1262
  if (!firstAccount) {
1184
1263
  throw new Error("KeyringController - First Account not found." /* NoFirstAccount */);
1185
1264
  }
1186
1265
  };
1187
1266
  _newKeyring = new WeakSet();
1188
- newKeyring_fn = async function(type, data) {
1189
- const keyringBuilder = _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _getKeyringBuilderForType, getKeyringBuilderForType_fn).call(this, type);
1267
+ newKeyring_fn = async function(type, data, persist = false) {
1268
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1269
+ const keyringBuilder = _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getKeyringBuilderForType, getKeyringBuilderForType_fn).call(this, type);
1190
1270
  if (!keyringBuilder) {
1191
1271
  throw new Error(
1192
1272
  `${"KeyringController - No keyringBuilder found for keyring" /* NoKeyringBuilder */}. Keyring type: ${type}`
@@ -1197,28 +1277,46 @@ newKeyring_fn = async function(type, data) {
1197
1277
  if (keyring.init) {
1198
1278
  await keyring.init();
1199
1279
  }
1280
+ if (type === "HD Key Tree" /* hd */ && (!_utils.isObject.call(void 0, data) || !data.mnemonic)) {
1281
+ if (!keyring.generateRandomMnemonic) {
1282
+ throw new Error(
1283
+ "KeyringController - The current keyring does not support the method generateRandomMnemonic." /* UnsupportedGenerateRandomMnemonic */
1284
+ );
1285
+ }
1286
+ keyring.generateRandomMnemonic();
1287
+ await keyring.addAccounts(1);
1288
+ }
1289
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _checkForDuplicate, checkForDuplicate_fn).call(this, type, await keyring.getAccounts());
1290
+ if (persist) {
1291
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).push(keyring);
1292
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _updateVault, updateVault_fn).call(this);
1293
+ }
1200
1294
  return keyring;
1201
1295
  };
1202
1296
  _clearKeyrings = new WeakSet();
1203
- clearKeyrings_fn = async function() {
1204
- for (const keyring of _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings)) {
1205
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _destroyKeyring, destroyKeyring_fn).call(this, keyring);
1297
+ clearKeyrings_fn = async function(options = { skipStateUpdate: false }) {
1298
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1299
+ for (const keyring of _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings)) {
1300
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _destroyKeyring, destroyKeyring_fn).call(this, keyring);
1301
+ }
1302
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyrings, []);
1303
+ if (!options.skipStateUpdate) {
1304
+ this.update((state) => {
1305
+ state.keyrings = [];
1306
+ });
1206
1307
  }
1207
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyrings, []);
1208
- this.update((state) => {
1209
- state.keyrings = [];
1210
- });
1211
1308
  };
1212
1309
  _restoreKeyring = new WeakSet();
1213
1310
  restoreKeyring_fn = async function(serialized) {
1311
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1214
1312
  try {
1215
1313
  const { type, data } = serialized;
1216
- const keyring = await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, type, data);
1314
+ const keyring = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _newKeyring, newKeyring_fn).call(this, type, data);
1217
1315
  await keyring.getAccounts();
1218
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).push(keyring);
1316
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).push(keyring);
1219
1317
  return keyring;
1220
1318
  } catch (_) {
1221
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _unsupportedKeyrings).push(serialized);
1319
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _unsupportedKeyrings).push(serialized);
1222
1320
  return void 0;
1223
1321
  }
1224
1322
  };
@@ -1228,22 +1326,23 @@ destroyKeyring_fn = async function(keyring) {
1228
1326
  };
1229
1327
  _removeEmptyKeyrings = new WeakSet();
1230
1328
  removeEmptyKeyrings_fn = async function() {
1329
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1231
1330
  const validKeyrings = [];
1232
1331
  await Promise.all(
1233
- _chunkCHLPTPMZjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
1332
+ _chunkQDPHKQONjs.__privateGet.call(void 0, this, _keyrings).map(async (keyring) => {
1234
1333
  const accounts = await keyring.getAccounts();
1235
1334
  if (accounts.length > 0) {
1236
1335
  validKeyrings.push(keyring);
1237
1336
  } else {
1238
- await _chunkCHLPTPMZjs.__privateMethod.call(void 0, this, _destroyKeyring, destroyKeyring_fn).call(this, keyring);
1337
+ await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _destroyKeyring, destroyKeyring_fn).call(this, keyring);
1239
1338
  }
1240
1339
  })
1241
1340
  );
1242
- _chunkCHLPTPMZjs.__privateSet.call(void 0, this, _keyrings, validKeyrings);
1341
+ _chunkQDPHKQONjs.__privateSet.call(void 0, this, _keyrings, validKeyrings);
1243
1342
  };
1244
1343
  _checkForDuplicate = new WeakSet();
1245
1344
  checkForDuplicate_fn = async function(type, newAccountArray) {
1246
- const accounts = await this.getAccounts();
1345
+ const accounts = await _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _getAccountsFromKeyrings, getAccountsFromKeyrings_fn).call(this);
1247
1346
  switch (type) {
1248
1347
  case "Simple Key Pair" /* simple */: {
1249
1348
  const isIncluded = Boolean(
@@ -1263,18 +1362,35 @@ checkForDuplicate_fn = async function(type, newAccountArray) {
1263
1362
  };
1264
1363
  _setUnlocked = new WeakSet();
1265
1364
  setUnlocked_fn = function() {
1365
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1266
1366
  this.update((state) => {
1267
1367
  state.isUnlocked = true;
1268
1368
  });
1269
1369
  this.messagingSystem.publish(`${name}:unlock`);
1270
1370
  };
1271
- _getMemState = new WeakSet();
1272
- getMemState_fn = function() {
1273
- return {
1274
- isUnlocked: this.state.isUnlocked,
1275
- keyrings: this.state.keyrings
1276
- };
1371
+ _assertControllerMutexIsLocked = new WeakSet();
1372
+ assertControllerMutexIsLocked_fn = function() {
1373
+ if (!_chunkQDPHKQONjs.__privateGet.call(void 0, this, _controllerOperationMutex).isLocked()) {
1374
+ throw new Error("KeyringController - attempt to update vault during a non mutually exclusive operation" /* ControllerLockRequired */);
1375
+ }
1376
+ };
1377
+ _withControllerLock = new WeakSet();
1378
+ withControllerLock_fn = async function(fn) {
1379
+ return withLock(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _controllerOperationMutex), fn);
1380
+ };
1381
+ _withVaultLock = new WeakSet();
1382
+ withVaultLock_fn = async function(fn) {
1383
+ _chunkQDPHKQONjs.__privateMethod.call(void 0, this, _assertControllerMutexIsLocked, assertControllerMutexIsLocked_fn).call(this);
1384
+ return withLock(_chunkQDPHKQONjs.__privateGet.call(void 0, this, _vaultOperationMutex), fn);
1277
1385
  };
1386
+ async function withLock(mutex, fn) {
1387
+ const releaseLock = await mutex.acquire();
1388
+ try {
1389
+ return await fn({ releaseLock });
1390
+ } finally {
1391
+ releaseLock();
1392
+ }
1393
+ }
1278
1394
  var KeyringController_default = KeyringController;
1279
1395
 
1280
1396
 
@@ -1287,4 +1403,4 @@ var KeyringController_default = KeyringController;
1287
1403
 
1288
1404
 
1289
1405
  exports.KeyringTypes = KeyringTypes; exports.isCustodyKeyring = isCustodyKeyring; exports.AccountImportStrategy = AccountImportStrategy; exports.SignTypedDataVersion = SignTypedDataVersion; exports.keyringBuilderFactory = keyringBuilderFactory; exports.getDefaultKeyringState = getDefaultKeyringState; exports.KeyringController = KeyringController; exports.KeyringController_default = KeyringController_default;
1290
- //# sourceMappingURL=chunk-BVSGYW4D.js.map
1406
+ //# sourceMappingURL=chunk-ISACMNF3.js.map