@metamask-previews/keyring-controller 19.0.5-preview-43593c4e → 19.0.5-preview-37653b42

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.
@@ -36,9 +36,9 @@ 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_unsupportedKeyrings, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_checkForDuplicate, _KeyringController_setUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_checkForDuplicate, _KeyringController_setUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
41
+ exports.KeyringController = exports.getKeyringByFingerprint = exports.displayForKeyring = 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
44
  const encryptorUtils = __importStar(require("@metamask/browser-passworder"));
@@ -55,18 +55,31 @@ const name = 'KeyringController';
55
55
  */
56
56
  var KeyringTypes;
57
57
  (function (KeyringTypes) {
58
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
59
+ // eslint-disable-next-line @typescript-eslint/naming-convention
58
60
  KeyringTypes["simple"] = "Simple Key Pair";
61
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
62
+ // eslint-disable-next-line @typescript-eslint/naming-convention
59
63
  KeyringTypes["hd"] = "HD Key Tree";
64
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
65
+ // eslint-disable-next-line @typescript-eslint/naming-convention
60
66
  KeyringTypes["qr"] = "QR Hardware Wallet Device";
67
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
68
+ // eslint-disable-next-line @typescript-eslint/naming-convention
61
69
  KeyringTypes["trezor"] = "Trezor Hardware";
70
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
71
+ // eslint-disable-next-line @typescript-eslint/naming-convention
62
72
  KeyringTypes["ledger"] = "Ledger Hardware";
73
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
74
+ // eslint-disable-next-line @typescript-eslint/naming-convention
63
75
  KeyringTypes["lattice"] = "Lattice Hardware";
76
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
77
+ // eslint-disable-next-line @typescript-eslint/naming-convention
64
78
  KeyringTypes["snap"] = "Snap Keyring";
65
79
  })(KeyringTypes || (exports.KeyringTypes = KeyringTypes = {}));
66
80
  /**
67
81
  * Custody keyring types are a special case, as they are not a single type
68
82
  * but they all start with the prefix "Custody".
69
- *
70
83
  * @param keyringType - The type of the keyring.
71
84
  * @returns Whether the keyring type is a custody keyring.
72
85
  */
@@ -79,7 +92,11 @@ exports.isCustodyKeyring = isCustodyKeyring;
79
92
  */
80
93
  var AccountImportStrategy;
81
94
  (function (AccountImportStrategy) {
95
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
96
+ // eslint-disable-next-line @typescript-eslint/naming-convention
82
97
  AccountImportStrategy["privateKey"] = "privateKey";
98
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
99
+ // eslint-disable-next-line @typescript-eslint/naming-convention
83
100
  AccountImportStrategy["json"] = "json";
84
101
  })(AccountImportStrategy || (exports.AccountImportStrategy = AccountImportStrategy = {}));
85
102
  /**
@@ -187,8 +204,30 @@ async function displayForKeyring(keyring) {
187
204
  // Cast to `string[]` here is safe here because `accounts` has no nullish
188
205
  // values, and `normalize` returns `string` unless given a nullish value
189
206
  accounts: accounts.map(normalize),
207
+ // @ts-expect-error TODO: update type in @metamask/utils
208
+ fingerprint: await keyring?.getFingerprint?.(),
190
209
  };
191
210
  }
211
+ exports.displayForKeyring = displayForKeyring;
212
+ /**
213
+ * Retrieves a keyring from an array of keyrings based on its fingerprint.
214
+ *
215
+ * @param keyrings - Array of keyrings to search through.
216
+ * @param fingerprint - The fingerprint to match against.
217
+ * @returns Promise resolving to the matching keyring, or undefined if not found.
218
+ */
219
+ async function getKeyringByFingerprint(keyrings, fingerprint) {
220
+ // Do not attempt to return a keyring if the fingerprint is not provided
221
+ if (!fingerprint) {
222
+ return undefined;
223
+ }
224
+ const fingerprints = await Promise.all(
225
+ // @ts-expect-error TODO: update type in @metamask/utils
226
+ keyrings.map((kr) => kr?.getFingerprint?.()));
227
+ const index = fingerprints.indexOf(fingerprint);
228
+ return keyrings[index];
229
+ }
230
+ exports.getKeyringByFingerprint = getKeyringByFingerprint;
192
231
  /**
193
232
  * Check if address is an ethereum address
194
233
  *
@@ -259,11 +298,11 @@ class KeyringController extends base_controller_1.BaseController {
259
298
  _KeyringController_controllerOperationMutex.set(this, new async_mutex_1.Mutex());
260
299
  _KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
261
300
  _KeyringController_keyringBuilders.set(this, void 0);
301
+ _KeyringController_keyrings.set(this, void 0);
262
302
  _KeyringController_unsupportedKeyrings.set(this, void 0);
303
+ _KeyringController_password.set(this, void 0);
263
304
  _KeyringController_encryptor.set(this, void 0);
264
305
  _KeyringController_cacheEncryptionKey.set(this, void 0);
265
- _KeyringController_keyrings.set(this, void 0);
266
- _KeyringController_password.set(this, void 0);
267
306
  _KeyringController_qrKeyringStateListener.set(this, void 0);
268
307
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
269
308
  ? keyringBuilders.concat(defaultKeyringBuilders)
@@ -365,7 +404,6 @@ class KeyringController extends base_controller_1.BaseController {
365
404
  * If there is a pre-existing locked vault, it will be replaced.
366
405
  *
367
406
  * @param password - Password to unlock the new vault.
368
- * @returns Promise resolving when the operation ends successfully.
369
407
  */
370
408
  async createNewVaultAndKeychain(password) {
371
409
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
@@ -415,12 +453,27 @@ class KeyringController extends base_controller_1.BaseController {
415
453
  * Gets the seed phrase of the HD keyring.
416
454
  *
417
455
  * @param password - Password of the keyring.
456
+ * @param keyringId - The keyring identifier.
418
457
  * @returns Promise resolving to the seed phrase.
419
458
  */
420
- async exportSeedPhrase(password) {
459
+ async exportSeedPhrase(password, keyringId) {
421
460
  await this.verifyPassword(password);
422
- assertHasUint8ArrayMnemonic(__classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0]);
423
- return __classPrivateFieldGet(this, _KeyringController_keyrings, "f")[0].mnemonic;
461
+ let keyring;
462
+ if (keyringId) {
463
+ keyring = await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), keyringId);
464
+ if (!keyring) {
465
+ throw new Error(constants_1.KeyringControllerError.KeyringNotFound);
466
+ }
467
+ if (keyring.type !== KeyringTypes.hd) {
468
+ throw new Error(constants_1.KeyringControllerError.UnsupportedExportSeedPhrase);
469
+ }
470
+ }
471
+ else {
472
+ // There will always be an HD keyring
473
+ keyring = this.getKeyringsByType(KeyringTypes.hd)[0];
474
+ }
475
+ assertHasUint8ArrayMnemonic(keyring);
476
+ return keyring.mnemonic;
424
477
  }
425
478
  /**
426
479
  * Gets the private key from the keyring controlling an address.
@@ -546,7 +599,7 @@ class KeyringController extends base_controller_1.BaseController {
546
599
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
547
600
  let privateKey;
548
601
  switch (strategy) {
549
- case AccountImportStrategy.privateKey:
602
+ case 'privateKey':
550
603
  const [importedKey] = args;
551
604
  if (!importedKey) {
552
605
  throw new Error('Cannot import an empty key.');
@@ -566,7 +619,7 @@ class KeyringController extends base_controller_1.BaseController {
566
619
  }
567
620
  privateKey = (0, utils_1.remove0x)(prefixed);
568
621
  break;
569
- case AccountImportStrategy.json:
622
+ case 'json':
570
623
  let wallet;
571
624
  const [input, password] = args;
572
625
  try {
@@ -578,7 +631,7 @@ class KeyringController extends base_controller_1.BaseController {
578
631
  privateKey = (0, utils_1.bytesToHex)(wallet.getPrivateKey());
579
632
  break;
580
633
  default:
581
- throw new Error(`Unexpected import strategy: '${String(strategy)}'`);
634
+ throw new Error(`Unexpected import strategy: '${strategy}'`);
582
635
  }
583
636
  const newKeyring = (await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_newKeyring).call(this, KeyringTypes.simple, [
584
637
  privateKey,
@@ -603,6 +656,7 @@ class KeyringController extends base_controller_1.BaseController {
603
656
  }
604
657
  // The `removeAccount` method of snaps keyring is async. We have to update
605
658
  // the interface of the other keyrings to be async as well.
659
+ // eslint-disable-next-line @typescript-eslint/await-thenable
606
660
  // FIXME: We do cast to `Hex` to makes the type checker happy here, and
607
661
  // because `Keyring<State>.removeAccount` requires address to be `Hex`. Those
608
662
  // type would need to be updated for a full non-EVM support.
@@ -833,6 +887,9 @@ class KeyringController extends base_controller_1.BaseController {
833
887
  if ('address' in selector) {
834
888
  keyring = (await this.getKeyringForAccount(selector.address));
835
889
  }
890
+ else if ('fingerprint' in selector) {
891
+ keyring = (await getKeyringByFingerprint(__classPrivateFieldGet(this, _KeyringController_keyrings, "f"), selector.fingerprint));
892
+ }
836
893
  else {
837
894
  keyring = this.getKeyringsByType(selector.type)[selector.index || 0];
838
895
  if (!keyring && options.createIfMissing) {
@@ -1038,7 +1095,7 @@ class KeyringController extends base_controller_1.BaseController {
1038
1095
  }
1039
1096
  }
1040
1097
  exports.KeyringController = KeyringController;
1041
- _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1098
+ _KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1042
1099
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1043
1100
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
1044
1101
  this.messagingSystem.registerActionHandler(`${name}:signTypedMessage`, this.signTypedMessage.bind(this));
@@ -1373,6 +1430,9 @@ async function _KeyringController_newKeyring(type, data) {
1373
1430
  // NOTE: Not all keyrings implement this method in a asynchronous-way. Using `await` for
1374
1431
  // non-thenable will still be valid (despite not being really useful). It allows us to cover both
1375
1432
  // cases and allow retro-compatibility too.
1433
+ // FIXME: For some reason, it seems that eslint is complaining about this call being non-thenable
1434
+ // even though it is... For now, we just disable it:
1435
+ // eslint-disable-next-line @typescript-eslint/await-thenable
1376
1436
  await keyring.generateRandomMnemonic();
1377
1437
  await keyring.addAccounts(1);
1378
1438
  }
@@ -1487,12 +1547,14 @@ async function _KeyringController_checkForDuplicate(type, newAccountArray) {
1487
1547
  * and save the keyrings to state after it, or rollback to their
1488
1548
  * previous state in case of error.
1489
1549
  *
1490
- * @param callback - The function to execute.
1550
+ * @param fn - The function to execute.
1491
1551
  * @returns The result of the function.
1492
1552
  */
1493
- async function _KeyringController_persistOrRollback(callback) {
1553
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1554
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1555
+ async function _KeyringController_persistOrRollback(fn) {
1494
1556
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async ({ releaseLock }) => {
1495
- const callbackResult = await callback({ releaseLock });
1557
+ const callbackResult = await fn({ releaseLock });
1496
1558
  // State is committed only if the operation is successful
1497
1559
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
1498
1560
  return callbackResult;
@@ -1502,15 +1564,17 @@ async function _KeyringController_persistOrRollback(callback) {
1502
1564
  * Execute the given function after acquiring the controller lock
1503
1565
  * and rollback keyrings and password states in case of error.
1504
1566
  *
1505
- * @param callback - The function to execute atomically.
1567
+ * @param fn - The function to execute atomically.
1506
1568
  * @returns The result of the function.
1507
1569
  */
1508
- async function _KeyringController_withRollback(callback) {
1570
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1571
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1572
+ async function _KeyringController_withRollback(fn) {
1509
1573
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1510
1574
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1511
1575
  const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1512
1576
  try {
1513
- return await callback({ releaseLock });
1577
+ return await fn({ releaseLock });
1514
1578
  }
1515
1579
  catch (e) {
1516
1580
  // Keyrings and password are restored to their previous state
@@ -1533,11 +1597,13 @@ async function _KeyringController_withRollback(callback) {
1533
1597
  * controller and that changes its state is executed in a mutually exclusive way,
1534
1598
  * preventing unsafe concurrent access that could lead to unpredictable behavior.
1535
1599
  *
1536
- * @param callback - The function to execute while the controller mutex is locked.
1600
+ * @param fn - The function to execute while the controller mutex is locked.
1537
1601
  * @returns The result of the function.
1538
1602
  */
1539
- async function _KeyringController_withControllerLock(callback) {
1540
- return withLock(__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f"), callback);
1603
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1604
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1605
+ async function _KeyringController_withControllerLock(fn) {
1606
+ return withLock(__classPrivateFieldGet(this, _KeyringController_controllerOperationMutex, "f"), fn);
1541
1607
  }, _KeyringController_withVaultLock =
1542
1608
  /**
1543
1609
  * Lock the vault mutex before executing the given function,
@@ -1547,12 +1613,14 @@ async function _KeyringController_withControllerLock(callback) {
1547
1613
  * This ensures that each operation that interacts with the vault
1548
1614
  * is executed in a mutually exclusive way.
1549
1615
  *
1550
- * @param callback - The function to execute while the vault mutex is locked.
1616
+ * @param fn - The function to execute while the vault mutex is locked.
1551
1617
  * @returns The result of the function.
1552
1618
  */
1553
- async function _KeyringController_withVaultLock(callback) {
1619
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1620
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1621
+ async function _KeyringController_withVaultLock(fn) {
1554
1622
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1555
- return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"), callback);
1623
+ return withLock(__classPrivateFieldGet(this, _KeyringController_vaultOperationMutex, "f"), fn);
1556
1624
  };
1557
1625
  /**
1558
1626
  * Lock the given mutex before executing the given function,
@@ -1560,13 +1628,15 @@ async function _KeyringController_withVaultLock(callback) {
1560
1628
  * error is thrown.
1561
1629
  *
1562
1630
  * @param mutex - The mutex to lock.
1563
- * @param callback - The function to execute while the mutex is locked.
1631
+ * @param fn - The function to execute while the mutex is locked.
1564
1632
  * @returns The result of the function.
1565
1633
  */
1566
- async function withLock(mutex, callback) {
1634
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
1635
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1636
+ async function withLock(mutex, fn) {
1567
1637
  const releaseLock = await mutex.acquire();
1568
1638
  try {
1569
- return await callback({ releaseLock });
1639
+ return await fn({ releaseLock });
1570
1640
  }
1571
1641
  finally {
1572
1642
  releaseLock();