@metamask/accounts-controller 37.2.0 → 38.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [38.1.0]
11
+
12
+ ### Changed
13
+
14
+ - Use `KeyringV1Adapter` for `SnapKeyring` v2 accounts ([#8703](https://github.com/MetaMask/core/pull/8703))
15
+ - `SnapKeyring` v2 instances will be adapted/wrapped by a v1 keyring adapter, making it compatible with the current `KeyringController` keyrings management.
16
+ - Bump `@metamask/keyring-utils` from `^3.1.0` to `^3.2.1` ([#8703](https://github.com/MetaMask/core/pull/8703))
17
+ - Bump `@metamask/keyring-controller` from `^25.4.0` to `^25.5.0` ([#8722](https://github.com/MetaMask/core/pull/8722))
18
+ - Bump `@metamask/network-controller` from `^30.1.0` to `^31.0.0` ([#8755](https://github.com/MetaMask/core/pull/8755))
19
+
20
+ ## [38.0.0]
21
+
22
+ ### Added
23
+
24
+ - Add support for `SnapKeyring` v2 accounts ([#8513](https://github.com/MetaMask/core/pull/8513))
25
+
26
+ ### Changed
27
+
28
+ - Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632))
29
+ - Bump `@metamask/base-controller` from `^9.0.1` to `^9.1.0` ([#8457](https://github.com/MetaMask/core/pull/8457))
30
+ - Bump `@metamask/eth-snap-keyring` from `^19.0.0` to `^22.0.1` ([#8464](https://github.com/MetaMask/core/pull/8464), [#8584](https://github.com/MetaMask/core/pull/8584), [#8647](https://github.com/MetaMask/core/pull/8647))
31
+ - Bump `@metamask/keyring-api` from `^21.6.0` to `^23.1.0` ([#8464](https://github.com/MetaMask/core/pull/8464), [#8647](https://github.com/MetaMask/core/pull/8647))
32
+ - Bump `@metamask/keyring-internal-api` from `^10.0.0` to `^11.0.1` ([#8464](https://github.com/MetaMask/core/pull/8464), [#8584](https://github.com/MetaMask/core/pull/8584), [#8647](https://github.com/MetaMask/core/pull/8647))
33
+ - Bump `@metamask/keyring-controller` from `^25.2.0` to `^25.4.0` ([#8634](https://github.com/MetaMask/core/pull/8634), [#8665](https://github.com/MetaMask/core/pull/8665))
34
+ - Bump `@metamask/network-controller` from `^30.0.1` to `^30.1.0` ([#8636](https://github.com/MetaMask/core/pull/8636))
35
+
36
+ ### Removed
37
+
38
+ - **BREAKING:** `InternalAccount.metadata.snap.{enabled,name}` properties have been removed ([#8584](https://github.com/MetaMask/core/pull/8584))
39
+ - You now need to use `metadata.snap.id` and the `SnapController:<actions>` to get those information.
40
+ - No longer depend on `SnapController:stateChange` event ([#8584](https://github.com/MetaMask/core/pull/8584))
41
+
10
42
  ## [37.2.0]
11
43
 
12
44
  ### Added
@@ -761,7 +793,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
761
793
 
762
794
  - Initial release ([#1637](https://github.com/MetaMask/core/pull/1637))
763
795
 
764
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@37.2.0...HEAD
796
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.1.0...HEAD
797
+ [38.1.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@38.0.0...@metamask/accounts-controller@38.1.0
798
+ [38.0.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@37.2.0...@metamask/accounts-controller@38.0.0
765
799
  [37.2.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@37.1.1...@metamask/accounts-controller@37.2.0
766
800
  [37.1.1]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@37.1.0...@metamask/accounts-controller@37.1.1
767
801
  [37.1.0]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@37.0.0...@metamask/accounts-controller@37.1.0
@@ -4,12 +4,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var _AccountsController_instances, _AccountsController_getAccountExpect, _AccountsController_assertAccountCanBeRenamed, _AccountsController_getInternalAccountForNonSnapAccount, _AccountsController_getSnapKeyring, _AccountsController_handleOnSnapKeyringAccountEvent, _AccountsController_handleOnKeyringStateChange, _AccountsController_update, _AccountsController_handleOnSnapStateChange, _AccountsController_getLastSelectedAccount, _AccountsController_getLastSelectedIndex, _AccountsController_getInternalAccountFromAddressAndType, _AccountsController_handleOnMultichainNetworkDidChange, _AccountsController_subscribeToMessageEvents;
7
+ var _AccountsController_instances, _AccountsController_getAccountExpect, _AccountsController_assertAccountCanBeRenamed, _AccountsController_getInternalAccountForNonSnapAccount, _AccountsController_getSnapKeyring, _AccountsController_getAccountFromSnapKeyringV1, _AccountsController_getAccountFromSnapKeyringV2, _AccountsController_handleOnSnapKeyringAccountEvent, _AccountsController_handleOnKeyringStateChange, _AccountsController_update, _AccountsController_getLastSelectedAccount, _AccountsController_getLastSelectedIndex, _AccountsController_getInternalAccountFromAddressAndType, _AccountsController_handleOnMultichainNetworkDidChange, _AccountsController_subscribeToMessageEvents;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.AccountsController = exports.EMPTY_ACCOUNT = void 0;
10
10
  const base_controller_1 = require("@metamask/base-controller");
11
11
  const eth_snap_keyring_1 = require("@metamask/eth-snap-keyring");
12
+ const v2_1 = require("@metamask/eth-snap-keyring/v2");
12
13
  const keyring_api_1 = require("@metamask/keyring-api");
14
+ const v2_2 = require("@metamask/keyring-api/v2");
15
+ const v2_3 = require("@metamask/keyring-sdk/v2");
13
16
  const keyring_utils_1 = require("@metamask/keyring-utils");
14
17
  const utils_1 = require("@metamask/utils");
15
18
  const lodash_1 = require("lodash");
@@ -475,6 +478,50 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
475
478
  // Snap keyring is not available until the first account is created in the keyring
476
479
  // controller, so this might be undefined.
477
480
  return snapKeyring;
481
+ }, _AccountsController_getAccountFromSnapKeyringV1 = function _AccountsController_getAccountFromSnapKeyringV1(address) {
482
+ const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
483
+ // We need the Snap keyring to retrieve the account from its address.
484
+ if (!snapKeyring) {
485
+ return undefined;
486
+ }
487
+ // This might be undefined if the Snap deleted the account before
488
+ // reaching that point.
489
+ return snapKeyring.getAccountByAddress(address);
490
+ }, _AccountsController_getAccountFromSnapKeyringV2 = function _AccountsController_getAccountFromSnapKeyringV2(address) {
491
+ const keyrings = this.messenger.call('KeyringController:getKeyringsByType', v2_2.KeyringType.Snap);
492
+ // Snap keyring v2 are "per-Snaps" (and can be accessed using their v1 adapter), so we need to
493
+ // iterate over all of them to find the account.
494
+ // NOTE: `:getKeyringsByType` will only return v1 instances, that's why we need to use their v1
495
+ // adapter + `unwrap` method to get the reference to their v2 instance.
496
+ for (const keyring of keyrings) {
497
+ if (keyring instanceof v2_3.KeyringV1Adapter) {
498
+ // NOTE: We already filtering by `KeyringType.Snap`, so we are sure that those adapters
499
+ // are wrapping a Snap keyring v2.
500
+ const adapter = keyring;
501
+ const keyringV2 = adapter.unwrap();
502
+ // We use the synchronous method here since this method is used during `:stateChange` that are
503
+ // use synchronous handlers.
504
+ const account = keyringV2.lookupByAddress(address);
505
+ if (account) {
506
+ return {
507
+ ...account,
508
+ // We still have to use internal account for now, so we inject some metadata.
509
+ metadata: {
510
+ name: '',
511
+ importTime: Date.now(),
512
+ lastSelected: 0,
513
+ keyring: {
514
+ type: v2_2.KeyringType.Snap,
515
+ },
516
+ snap: {
517
+ id: keyringV2.snapId,
518
+ },
519
+ },
520
+ };
521
+ }
522
+ }
523
+ }
524
+ return undefined;
478
525
  }, _AccountsController_handleOnSnapKeyringAccountEvent = function _AccountsController_handleOnSnapKeyringAccountEvent(event, ...payload) {
479
526
  this.messenger.publish(event, ...payload);
480
527
  }, _AccountsController_handleOnKeyringStateChange = function _AccountsController_handleOnKeyringStateChange({ isUnlocked, keyrings, }) {
@@ -487,30 +534,15 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
487
534
  }
488
535
  (0, logger_1.projectLogger)('Synchronizing accounts with keyrings (through :stateChange)...');
489
536
  // State patches.
490
- const generatePatch = () => {
491
- return {
492
- previous: {},
493
- added: [],
494
- updated: [],
495
- removed: [],
496
- };
497
- };
498
- const patches = {
499
- snap: generatePatch(),
500
- normal: generatePatch(),
501
- };
502
- // Gets the patch object based on the keyring type (since Snap accounts and other accounts
503
- // are handled differently).
504
- const patchOf = (type) => {
505
- if ((0, utils_2.isSnapKeyringType)(type)) {
506
- return patches.snap;
507
- }
508
- return patches.normal;
537
+ const patch = {
538
+ previous: {},
539
+ added: [],
540
+ updated: [],
541
+ removed: [],
509
542
  };
510
543
  // Create a map (with lower-cased addresses) of all existing accounts.
511
544
  for (const account of this.listMultichainAccounts()) {
512
545
  const address = account.address.toLowerCase();
513
- const patch = patchOf(account.metadata.keyring.type);
514
546
  patch.previous[address] = account;
515
547
  }
516
548
  // Go over all keyring changes and create patches out of it.
@@ -521,7 +553,6 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
521
553
  if ((0, utils_2.isMoneyKeyringType)(keyring.type)) {
522
554
  continue;
523
555
  }
524
- const patch = patchOf(keyring.type);
525
556
  for (const accountAddress of keyring.accounts) {
526
557
  // Lower-case address to use it in the `previous` map.
527
558
  const address = accountAddress.toLowerCase();
@@ -543,12 +574,10 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
543
574
  }
544
575
  // We might have accounts associated with removed keyrings, so we iterate
545
576
  // over all previous known accounts and check against the keyring addresses.
546
- for (const patch of [patches.snap, patches.normal]) {
547
- for (const [address, account] of Object.entries(patch.previous)) {
548
- // If a previous address is not part of the new addesses, then it got removed.
549
- if (!addresses.has(address)) {
550
- patch.removed.push(account);
551
- }
577
+ for (const [address, account] of Object.entries(patch.previous)) {
578
+ // If a previous address is not part of the new addesses, then it got removed.
579
+ if (!addresses.has(address)) {
580
+ patch.removed.push(account);
552
581
  }
553
582
  }
554
583
  // Diff that we will use to publish events afterward.
@@ -558,29 +587,27 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
558
587
  };
559
588
  __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_update).call(this, (state) => {
560
589
  const { internalAccounts, accountIdByAddress } = state;
561
- for (const patch of [patches.snap, patches.normal]) {
562
- for (const account of patch.removed) {
563
- delete internalAccounts.accounts[account.id];
564
- delete accountIdByAddress[account.address];
565
- diff.removed.push(account.id);
566
- }
567
- for (const added of patch.added) {
568
- const account = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getInternalAccountFromAddressAndType).call(this, added.address, added.keyring);
569
- if (account) {
570
- const accounts = Object.values(internalAccounts.accounts);
571
- // If it's the first account, we need to select it.
572
- const lastSelected = accounts.length === 0 ? __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getLastSelectedIndex).call(this) : 0;
573
- internalAccounts.accounts[account.id] = {
574
- ...account,
575
- metadata: {
576
- ...account.metadata,
577
- importTime: Date.now(),
578
- lastSelected,
579
- },
580
- };
581
- accountIdByAddress[account.address] = account.id;
582
- diff.added.push(internalAccounts.accounts[account.id]);
583
- }
590
+ for (const account of patch.removed) {
591
+ delete internalAccounts.accounts[account.id];
592
+ delete accountIdByAddress[account.address];
593
+ diff.removed.push(account.id);
594
+ }
595
+ for (const added of patch.added) {
596
+ const account = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getInternalAccountFromAddressAndType).call(this, added.address, added.keyring);
597
+ if (account) {
598
+ const accounts = Object.values(internalAccounts.accounts);
599
+ // If it's the first account, we need to select it.
600
+ const lastSelected = accounts.length === 0 ? __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getLastSelectedIndex).call(this) : 0;
601
+ internalAccounts.accounts[account.id] = {
602
+ ...account,
603
+ metadata: {
604
+ ...account.metadata,
605
+ importTime: Date.now(),
606
+ lastSelected,
607
+ },
608
+ };
609
+ accountIdByAddress[account.address] = account.id;
610
+ diff.added.push(internalAccounts.accounts[account.id]);
584
611
  }
585
612
  }
586
613
  },
@@ -641,36 +668,6 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
641
668
  this.messenger.publish('AccountsController:selectedAccountChange', account);
642
669
  }
643
670
  }
644
- }, _AccountsController_handleOnSnapStateChange = function _AccountsController_handleOnSnapStateChange(snapState) {
645
- // Only check if Snaps changed in status.
646
- const { snaps } = snapState;
647
- const accounts = [];
648
- for (const account of this.listMultichainAccounts()) {
649
- if (account.metadata.snap) {
650
- const snap = snaps[account.metadata.snap.id];
651
- if (snap) {
652
- const enabled = snap.enabled && !snap.blocked;
653
- const metadata = account.metadata.snap;
654
- if (metadata.enabled !== enabled) {
655
- accounts.push({ id: account.id, enabled });
656
- }
657
- }
658
- else {
659
- // If Snap could not be found on the state, we consider it disabled.
660
- accounts.push({ id: account.id, enabled: false });
661
- }
662
- }
663
- }
664
- if (accounts.length > 0) {
665
- this.update((state) => {
666
- for (const { id, enabled } of accounts) {
667
- const account = state.internalAccounts.accounts[id];
668
- if (account.metadata.snap) {
669
- account.metadata.snap.enabled = enabled;
670
- }
671
- }
672
- });
673
- }
674
671
  }, _AccountsController_getLastSelectedAccount = function _AccountsController_getLastSelectedAccount(accounts) {
675
672
  const [accountToSelect] = accounts.sort((accountA, accountB) => {
676
673
  // sort by lastSelected descending
@@ -683,15 +680,16 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
683
680
  // will always be higher than any already selected account index.
684
681
  return Date.now();
685
682
  }, _AccountsController_getInternalAccountFromAddressAndType = function _AccountsController_getInternalAccountFromAddressAndType(address, keyring) {
686
- if ((0, utils_2.isSnapKeyringType)(keyring.type)) {
687
- const snapKeyring = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getSnapKeyring).call(this);
688
- // We need the Snap keyring to retrieve the account from its address.
689
- if (!snapKeyring) {
690
- return undefined;
683
+ const isSnapKeyringV1 = (0, utils_2.isSnapKeyringType)(keyring.type);
684
+ const isSnapKeyringV2 = (0, utils_2.isSnapKeyringV2Type)(keyring.type);
685
+ if (isSnapKeyringV1 || isSnapKeyringV2) {
686
+ let account;
687
+ if (isSnapKeyringV1) {
688
+ account = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountFromSnapKeyringV1).call(this, address);
689
+ }
690
+ else {
691
+ account = __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_getAccountFromSnapKeyringV2).call(this, address);
691
692
  }
692
- // This might be undefined if the Snap deleted the account before
693
- // reaching that point.
694
- let account = snapKeyring.getAccountByAddress(address);
695
693
  if (account) {
696
694
  // We force the copy here, to avoid mutating the reference returned by the Snap keyring.
697
695
  account = (0, lodash_1.cloneDeep)(account);
@@ -741,7 +739,6 @@ _AccountsController_instances = new WeakSet(), _AccountsController_getAccountExp
741
739
  });
742
740
  // DO NOT publish AccountsController:setSelectedAccount to prevent circular listener loops
743
741
  }, _AccountsController_subscribeToMessageEvents = function _AccountsController_subscribeToMessageEvents() {
744
- this.messenger.subscribe('SnapController:stateChange', (snapStateState) => __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnSnapStateChange).call(this, snapStateState));
745
742
  this.messenger.subscribe('KeyringController:stateChange', (keyringState) => __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnKeyringStateChange).call(this, keyringState));
746
743
  this.messenger.subscribe('SnapKeyring:accountAssetListUpdated', (snapAccountEvent) => __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnSnapKeyringAccountEvent).call(this, 'AccountsController:accountAssetListUpdated', snapAccountEvent));
747
744
  this.messenger.subscribe('SnapKeyring:accountBalancesUpdated', (snapAccountEvent) => __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnSnapKeyringAccountEvent).call(this, 'AccountsController:accountBalancesUpdated', snapAccountEvent));