@metamask-previews/account-tree-controller 1.5.0-preview-53e28985 → 1.5.0-preview-31415333
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 +2 -4
- package/dist/AccountTreeController.cjs +87 -200
- package/dist/AccountTreeController.cjs.map +1 -1
- package/dist/AccountTreeController.d.cts +1 -1
- package/dist/AccountTreeController.d.cts.map +1 -1
- package/dist/AccountTreeController.d.mts +1 -1
- package/dist/AccountTreeController.d.mts.map +1 -1
- package/dist/AccountTreeController.mjs +87 -200
- package/dist/AccountTreeController.mjs.map +1 -1
- package/dist/rules/entropy.cjs +34 -2
- package/dist/rules/entropy.cjs.map +1 -1
- package/dist/rules/entropy.d.cts +2 -1
- package/dist/rules/entropy.d.cts.map +1 -1
- package/dist/rules/entropy.d.mts +2 -1
- package/dist/rules/entropy.d.mts.map +1 -1
- package/dist/rules/entropy.mjs +35 -3
- package/dist/rules/entropy.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +6 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +6 -5
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,14 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Changed
|
|
11
|
-
|
|
12
|
-
- Bump `@metamask/base-controller` from `^8.4.1` to `^8.4.2` ([#6917](https://github.com/MetaMask/core/pull/6917))
|
|
13
|
-
|
|
14
10
|
## [1.5.0]
|
|
15
11
|
|
|
16
12
|
### Changed
|
|
17
13
|
|
|
14
|
+
- **BREAKING:** Use new `Messenger` from `@metamask/messenger` ([#6380](https://github.com/MetaMask/core/pull/6380))
|
|
15
|
+
- Previously, `AccountTreeController` accepted a `RestrictedMessenger` instance from `@metamask/base-controller`.
|
|
18
16
|
- Use non-EVM account names for group names ([#6831](https://github.com/MetaMask/core/pull/6831))
|
|
19
17
|
- EVM accounts still take precedence over non-EVM accounts.
|
|
20
18
|
- Before accounts get re-aligned, it is possible that a group contains only non-EVM accounts, in which case, the first non-EVM account name will be used for that account group.
|
|
@@ -10,12 +10,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _AccountTreeController_instances, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_backupAndSyncService, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_initialized, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet,
|
|
13
|
+
var _AccountTreeController_instances, _AccountTreeController_accountIdToContext, _AccountTreeController_groupIdToWalletId, _AccountTreeController_backupAndSyncService, _AccountTreeController_rules, _AccountTreeController_trace, _AccountTreeController_backupAndSyncConfig, _AccountTreeController_initialized, _AccountTreeController_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_getComputedAccountGroupName, _AccountTreeController_getDefaultAccountGroupName, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_getDefaultSelectedAccountGroup, _AccountTreeController_handleSelectedAccountChange, _AccountTreeController_handleMultichainAccountWalletStatusChange, _AccountTreeController_getAccountGroup, _AccountTreeController_getDefaultAccountFromAccountGroupId, _AccountTreeController_getDefaultAccountGroupId, _AccountTreeController_registerMessageHandlers, _AccountTreeController_createBackupAndSyncContext;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AccountTreeController = exports.getDefaultAccountTreeControllerState = exports.controllerName = void 0;
|
|
16
16
|
const account_api_1 = require("@metamask/account-api");
|
|
17
|
-
const
|
|
18
|
-
const base_controller_1 = require("@metamask/base-controller");
|
|
17
|
+
const next_1 = require("@metamask/base-controller/next");
|
|
19
18
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
20
19
|
const utils_1 = require("@metamask/utils");
|
|
21
20
|
const analytics_1 = require("./backup-and-sync/analytics/index.cjs");
|
|
@@ -30,31 +29,31 @@ const accountTreeControllerMetadata = {
|
|
|
30
29
|
accountTree: {
|
|
31
30
|
includeInStateLogs: true,
|
|
32
31
|
persist: false,
|
|
33
|
-
|
|
32
|
+
includeInDebugSnapshot: false,
|
|
34
33
|
usedInUi: true,
|
|
35
34
|
},
|
|
36
35
|
isAccountTreeSyncingInProgress: {
|
|
37
36
|
includeInStateLogs: false,
|
|
38
37
|
persist: false,
|
|
39
|
-
|
|
38
|
+
includeInDebugSnapshot: false,
|
|
40
39
|
usedInUi: true,
|
|
41
40
|
},
|
|
42
41
|
hasAccountTreeSyncingSyncedAtLeastOnce: {
|
|
43
42
|
includeInStateLogs: true,
|
|
44
43
|
persist: true,
|
|
45
|
-
|
|
44
|
+
includeInDebugSnapshot: false,
|
|
46
45
|
usedInUi: true,
|
|
47
46
|
},
|
|
48
47
|
accountGroupsMetadata: {
|
|
49
48
|
includeInStateLogs: true,
|
|
50
49
|
persist: true,
|
|
51
|
-
|
|
50
|
+
includeInDebugSnapshot: false,
|
|
52
51
|
usedInUi: true,
|
|
53
52
|
},
|
|
54
53
|
accountWalletsMetadata: {
|
|
55
54
|
includeInStateLogs: true,
|
|
56
55
|
persist: true,
|
|
57
|
-
|
|
56
|
+
includeInDebugSnapshot: false,
|
|
58
57
|
usedInUi: true,
|
|
59
58
|
},
|
|
60
59
|
};
|
|
@@ -76,7 +75,7 @@ function getDefaultAccountTreeControllerState() {
|
|
|
76
75
|
};
|
|
77
76
|
}
|
|
78
77
|
exports.getDefaultAccountTreeControllerState = getDefaultAccountTreeControllerState;
|
|
79
|
-
class AccountTreeController extends
|
|
78
|
+
class AccountTreeController extends next_1.BaseController {
|
|
80
79
|
/**
|
|
81
80
|
* Constructor for AccountTreeController.
|
|
82
81
|
*
|
|
@@ -115,11 +114,11 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
115
114
|
// Rules to apply to construct the wallets tree.
|
|
116
115
|
__classPrivateFieldSet(this, _AccountTreeController_rules, [
|
|
117
116
|
// 1. We group by entropy-source
|
|
118
|
-
new entropy_1.EntropyRule(this.
|
|
117
|
+
new entropy_1.EntropyRule(this.messenger),
|
|
119
118
|
// 2. We group by Snap ID
|
|
120
|
-
new snap_1.SnapRule(this.
|
|
119
|
+
new snap_1.SnapRule(this.messenger),
|
|
121
120
|
// 3. We group by wallet type (this rule cannot fail and will group all non-matching accounts)
|
|
122
|
-
new keyring_1.KeyringRule(this.
|
|
121
|
+
new keyring_1.KeyringRule(this.messenger),
|
|
123
122
|
], "f");
|
|
124
123
|
// Initialize trace function
|
|
125
124
|
__classPrivateFieldSet(this, _AccountTreeController_trace, config?.trace ?? analytics_1.traceFallback, "f");
|
|
@@ -132,25 +131,19 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
132
131
|
}, "f");
|
|
133
132
|
// Initialize the backup and sync service
|
|
134
133
|
__classPrivateFieldSet(this, _AccountTreeController_backupAndSyncService, new service_1.BackupAndSyncService(__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_createBackupAndSyncContext).call(this)), "f");
|
|
135
|
-
this.
|
|
134
|
+
this.messenger.subscribe('AccountsController:accountAdded', (account) => {
|
|
136
135
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountAdded).call(this, account);
|
|
137
136
|
});
|
|
138
|
-
this.
|
|
137
|
+
this.messenger.subscribe('AccountsController:accountRemoved', (accountId) => {
|
|
139
138
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountRemoved).call(this, accountId);
|
|
140
139
|
});
|
|
141
|
-
this.
|
|
140
|
+
this.messenger.subscribe('AccountsController:selectedAccountChange', (account) => {
|
|
142
141
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleSelectedAccountChange).call(this, account);
|
|
143
142
|
});
|
|
144
|
-
this.
|
|
143
|
+
this.messenger.subscribe('UserStorageController:stateChange', (userStorageControllerState) => {
|
|
145
144
|
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").handleUserStorageStateChange(userStorageControllerState);
|
|
146
145
|
});
|
|
147
|
-
this.
|
|
148
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated).call(this, group);
|
|
149
|
-
});
|
|
150
|
-
this.messagingSystem.subscribe('MultichainAccountService:multichainAccountGroupUpdated', (group) => {
|
|
151
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated).call(this, group);
|
|
152
|
-
});
|
|
153
|
-
this.messagingSystem.subscribe('MultichainAccountService:walletStatusChange', (walletId, status) => {
|
|
146
|
+
this.messenger.subscribe('MultichainAccountService:walletStatusChange', (walletId, status) => {
|
|
154
147
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleMultichainAccountWalletStatusChange).call(this, walletId, status);
|
|
155
148
|
});
|
|
156
149
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_registerMessageHandlers).call(this);
|
|
@@ -169,7 +162,6 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
169
162
|
return;
|
|
170
163
|
}
|
|
171
164
|
(0, logger_1.projectLogger)('Initializing...');
|
|
172
|
-
// For now, we always re-compute all wallets, we do not re-use the existing state.
|
|
173
165
|
const wallets = {};
|
|
174
166
|
// Clear mappings for fresh rebuild.
|
|
175
167
|
__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").clear();
|
|
@@ -177,12 +169,6 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
177
169
|
// Keep the current selected group to check if it's still part of the tree
|
|
178
170
|
// after rebuilding it.
|
|
179
171
|
const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
|
|
180
|
-
// Insert all multichain account wallet/groups.
|
|
181
|
-
for (const wallet of __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getMultichainAccountWallets).call(this)) {
|
|
182
|
-
for (const group of wallet.getMultichainAccountGroups()) {
|
|
183
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup).call(this, wallets, wallet, group);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
172
|
// There's no guarantee that accounts would be sorted by their import time
|
|
187
173
|
// with `listMultichainAccounts`. We have to sort them here before constructing
|
|
188
174
|
// the tree.
|
|
@@ -195,9 +181,9 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
195
181
|
// won't be enough and we would have to use group properties instead (like group
|
|
196
182
|
// index or maybe introduce a `importTime` at group level).
|
|
197
183
|
const accounts = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_listAccounts).call(this).sort((a, b) => a.metadata.importTime - b.metadata.importTime);
|
|
198
|
-
//
|
|
184
|
+
// For now, we always re-compute all wallets, we do not re-use the existing state.
|
|
199
185
|
for (const account of accounts) {
|
|
200
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m",
|
|
186
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, wallets, account);
|
|
201
187
|
}
|
|
202
188
|
// Once we have the account tree, we can apply persisted metadata (names + UI states).
|
|
203
189
|
let previousSelectedAccountGroupStillExists = false;
|
|
@@ -246,7 +232,7 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
246
232
|
if (previousSelectedAccountGroup !==
|
|
247
233
|
this.state.accountTree.selectedAccountGroup) {
|
|
248
234
|
(0, logger_1.projectLogger)(`Selected (initial) group is: [${this.state.accountTree.selectedAccountGroup}]`);
|
|
249
|
-
this.
|
|
235
|
+
this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
|
|
250
236
|
}
|
|
251
237
|
(0, logger_1.projectLogger)('Initialized!');
|
|
252
238
|
__classPrivateFieldSet(this, _AccountTreeController_initialized, true, "f");
|
|
@@ -307,7 +293,7 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
307
293
|
}
|
|
308
294
|
const accounts = [];
|
|
309
295
|
for (const id of group.accounts) {
|
|
310
|
-
const account = this.
|
|
296
|
+
const account = this.messenger.call('AccountsController:getAccount', id);
|
|
311
297
|
// For now, we're filtering undefined account, but I believe
|
|
312
298
|
// throwing would be more appropriate here.
|
|
313
299
|
if (account) {
|
|
@@ -359,10 +345,10 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
359
345
|
state.accountTree.selectedAccountGroup = groupId;
|
|
360
346
|
});
|
|
361
347
|
(0, logger_1.projectLogger)(`Selected group is now: [${this.state.accountTree.selectedAccountGroup}]`);
|
|
362
|
-
this.
|
|
348
|
+
this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
|
|
363
349
|
// Update AccountsController - this will trigger selectedAccountChange event,
|
|
364
350
|
// but our handler is idempotent so it won't cause infinite loop
|
|
365
|
-
this.
|
|
351
|
+
this.messenger.call('AccountsController:setSelectedAccount', accountToSelect);
|
|
366
352
|
}
|
|
367
353
|
/**
|
|
368
354
|
* Resolves name conflicts by adding a suffix to make the name unique.
|
|
@@ -610,7 +596,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
610
596
|
}, _AccountTreeController_getComputedAccountGroupName = function _AccountTreeController_getComputedAccountGroupName(wallet, group) {
|
|
611
597
|
let proposedName = ''; // Empty means there's no computed name for this group.
|
|
612
598
|
for (const id of group.accounts) {
|
|
613
|
-
const account = this.
|
|
599
|
+
const account = this.messenger.call('AccountsController:getAccount', id);
|
|
614
600
|
if (!account || !account.metadata.name.length) {
|
|
615
601
|
continue;
|
|
616
602
|
}
|
|
@@ -735,15 +721,10 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
735
721
|
if (!__classPrivateFieldGet(this, _AccountTreeController_initialized, "f")) {
|
|
736
722
|
return;
|
|
737
723
|
}
|
|
738
|
-
if ((0, account_api_1.isBip44Account)(account)) {
|
|
739
|
-
// We're skipping BIP-44 accounts since we rely on the `MultichainAccountService` to do
|
|
740
|
-
// the grouping of wallets/groups directly.
|
|
741
|
-
return;
|
|
742
|
-
}
|
|
743
724
|
// Check if this account is already known by the tree to avoid double-insertion.
|
|
744
725
|
if (!__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").has(account.id)) {
|
|
745
726
|
this.update((state) => {
|
|
746
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m",
|
|
727
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
|
|
747
728
|
const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
|
|
748
729
|
if (context) {
|
|
749
730
|
const { walletId, groupId } = context;
|
|
@@ -754,7 +735,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
754
735
|
}
|
|
755
736
|
}
|
|
756
737
|
});
|
|
757
|
-
this.
|
|
738
|
+
this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
|
|
758
739
|
}
|
|
759
740
|
}, _AccountTreeController_handleAccountRemoved = function _AccountTreeController_handleAccountRemoved(accountId) {
|
|
760
741
|
// We wait for the first `init` to be called to actually build up the tree and
|
|
@@ -766,39 +747,33 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
766
747
|
const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(accountId);
|
|
767
748
|
if (context) {
|
|
768
749
|
const { walletId, groupId } = context;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
|
|
777
|
-
this.update((state) => {
|
|
778
|
-
const accounts = state.accountTree.wallets[walletId]?.groups[groupId].accounts;
|
|
779
|
-
// Effectively remove account from the group and state.
|
|
750
|
+
const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
|
|
751
|
+
let selectedAccountGroupChanged = false;
|
|
752
|
+
this.update((state) => {
|
|
753
|
+
const accounts = state.accountTree.wallets[walletId]?.groups[groupId]?.accounts;
|
|
754
|
+
if (accounts) {
|
|
755
|
+
const index = accounts.indexOf(accountId);
|
|
756
|
+
if (index !== -1) {
|
|
780
757
|
accounts.splice(index, 1);
|
|
781
|
-
//
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
//
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
newSelectedAccountGroup;
|
|
790
|
-
selectedAccountGroupChanged =
|
|
791
|
-
newSelectedAccountGroup !== previousSelectedAccountGroup;
|
|
792
|
-
}
|
|
793
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_pruneEmptyGroupAndWallet).call(this, state, walletId, groupId);
|
|
758
|
+
// Check if we need to update selectedAccountGroup after removal
|
|
759
|
+
if (state.accountTree.selectedAccountGroup === groupId &&
|
|
760
|
+
accounts.length === 0) {
|
|
761
|
+
// The currently selected group is now empty, find a new group to select
|
|
762
|
+
const newSelectedAccountGroup = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, state.accountTree.wallets);
|
|
763
|
+
state.accountTree.selectedAccountGroup = newSelectedAccountGroup;
|
|
764
|
+
selectedAccountGroupChanged =
|
|
765
|
+
newSelectedAccountGroup !== previousSelectedAccountGroup;
|
|
794
766
|
}
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
if (selectedAccountGroupChanged) {
|
|
799
|
-
this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
|
|
767
|
+
}
|
|
768
|
+
if (accounts.length === 0) {
|
|
769
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_pruneEmptyGroupAndWallet).call(this, state, walletId, groupId);
|
|
800
770
|
}
|
|
801
771
|
}
|
|
772
|
+
});
|
|
773
|
+
this.messenger.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
|
|
774
|
+
// Emit selectedAccountGroupChange event if the selected group changed
|
|
775
|
+
if (selectedAccountGroupChanged) {
|
|
776
|
+
this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
|
|
802
777
|
}
|
|
803
778
|
// Clear reverse-mapping for that account.
|
|
804
779
|
__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").delete(accountId);
|
|
@@ -815,25 +790,9 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
815
790
|
delete state.accountWalletsMetadata[walletId];
|
|
816
791
|
}
|
|
817
792
|
return state;
|
|
818
|
-
},
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
* and return attribution vary across engines; final ordering is covered
|
|
822
|
-
* by behavior tests. Ignoring the entire comparator avoids flaky line
|
|
823
|
-
* coverage without reducing scenario coverage.
|
|
824
|
-
*/
|
|
825
|
-
(a, b) => {
|
|
826
|
-
const aSortOrder = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(a)?.sortOrder;
|
|
827
|
-
const bSortOrder = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(b)?.sortOrder;
|
|
828
|
-
return (aSortOrder ?? group_1.MAX_SORT_ORDER) - (bSortOrder ?? group_1.MAX_SORT_ORDER);
|
|
829
|
-
});
|
|
830
|
-
}, _AccountTreeController_insertAccount = function _AccountTreeController_insertAccount(wallets, account) {
|
|
831
|
-
if ((0, account_api_1.isBip44Account)(account)) {
|
|
832
|
-
// We're skipping BIP-44 accounts since we rely on the `MultichainAccountService` to do
|
|
833
|
-
// the grouping of wallets/groups directly.
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
|
|
793
|
+
}, _AccountTreeController_insert = function _AccountTreeController_insert(wallets, account) {
|
|
794
|
+
const result = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getEntropyRule).call(this).match(account) ??
|
|
795
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getSnapRule).call(this).match(account) ??
|
|
837
796
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).match(account); // This one cannot fail.
|
|
838
797
|
// Update controller's state.
|
|
839
798
|
const walletId = result.wallet.id;
|
|
@@ -852,6 +811,10 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
852
811
|
// the union tag `result.wallet.type`.
|
|
853
812
|
};
|
|
854
813
|
wallet = wallets[walletId];
|
|
814
|
+
// Trigger atomic sync for new wallet (only for entropy wallets)
|
|
815
|
+
if (wallet.type === account_api_1.AccountWalletType.Entropy) {
|
|
816
|
+
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleWalletSync(walletId);
|
|
817
|
+
}
|
|
855
818
|
}
|
|
856
819
|
const groupId = result.group.id;
|
|
857
820
|
let group = wallet.groups[groupId];
|
|
@@ -874,9 +837,28 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
874
837
|
group = wallet.groups[groupId];
|
|
875
838
|
// Map group ID to its containing wallet ID for efficient direct access
|
|
876
839
|
__classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").set(groupId, walletId);
|
|
840
|
+
// Trigger atomic sync for new group (only for entropy wallets)
|
|
841
|
+
if (wallet.type === account_api_1.AccountWalletType.Entropy) {
|
|
842
|
+
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleGroupSync(groupId);
|
|
843
|
+
}
|
|
877
844
|
}
|
|
878
845
|
else {
|
|
879
846
|
group.accounts.push(id);
|
|
847
|
+
// We need to do this at every insertion because race conditions can happen
|
|
848
|
+
// during the account creation process where one provider completes before the other.
|
|
849
|
+
// The discovery process in the service can also lead to some accounts being created "out of order".
|
|
850
|
+
const { accounts } = group;
|
|
851
|
+
accounts.sort(
|
|
852
|
+
/* istanbul ignore next: Comparator branch execution (a===id vs b===id)
|
|
853
|
+
* and return attribution vary across engines; final ordering is covered
|
|
854
|
+
* by behavior tests. Ignoring the entire comparator avoids flaky line
|
|
855
|
+
* coverage without reducing scenario coverage.
|
|
856
|
+
*/
|
|
857
|
+
(a, b) => {
|
|
858
|
+
const aSortOrder = a === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(a)?.sortOrder;
|
|
859
|
+
const bSortOrder = b === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(b)?.sortOrder;
|
|
860
|
+
return ((aSortOrder ?? group_1.MAX_SORT_ORDER) - (bSortOrder ?? group_1.MAX_SORT_ORDER));
|
|
861
|
+
});
|
|
880
862
|
}
|
|
881
863
|
(0, logger_1.projectLogger)(`[${groupId}] Add new account: { id: "${account.id}", type: "${account.type}", address: "${account.address}"`);
|
|
882
864
|
// Update the reverse mapping for this account.
|
|
@@ -885,90 +867,8 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
885
867
|
groupId: group.id,
|
|
886
868
|
sortOrder,
|
|
887
869
|
});
|
|
888
|
-
// We need to do this at every insertion because race conditions can happen
|
|
889
|
-
// during the account creation process where one provider completes before the other.
|
|
890
|
-
// The discovery process in the service can also lead to some accounts being created "out of order".
|
|
891
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_sortAccountsOfGroup).call(this, group);
|
|
892
|
-
}, _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup = function _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup(wallets, multichainAccountWallet, multichainAccountGroup) {
|
|
893
|
-
const walletId = multichainAccountWallet.id;
|
|
894
|
-
const groupId = multichainAccountGroup.id;
|
|
895
|
-
let wallet = null;
|
|
896
|
-
let group = null;
|
|
897
|
-
// Check type, mainly to infer proper wallet object type.
|
|
898
|
-
const walletObject = wallets[walletId];
|
|
899
|
-
if (walletObject && walletObject.type === account_api_1.AccountWalletType.Entropy) {
|
|
900
|
-
wallet = walletObject;
|
|
901
|
-
group = wallet.groups[groupId];
|
|
902
|
-
}
|
|
903
|
-
// We always re-use the account list from the group (if accounts get
|
|
904
|
-
// added/removed/re-ordered within the group).
|
|
905
|
-
const accounts = multichainAccountGroup.getAccounts();
|
|
906
|
-
const accountIds = accounts
|
|
907
|
-
// For now, we need this type-cast because `getAccounts` do not have the same
|
|
908
|
-
// type-constraint (uses string[] instead of [string; ...string])
|
|
909
|
-
.map((account) => account.id);
|
|
910
|
-
// Create the group object first, to inject it in the wallet in case this wallet is
|
|
911
|
-
// not part of the tree yet.
|
|
912
|
-
if (!group) {
|
|
913
|
-
group = {
|
|
914
|
-
id: multichainAccountGroup.id,
|
|
915
|
-
type: multichainAccountGroup.type,
|
|
916
|
-
accounts: accountIds,
|
|
917
|
-
metadata: {
|
|
918
|
-
entropy: {
|
|
919
|
-
groupIndex: multichainAccountGroup.groupIndex,
|
|
920
|
-
},
|
|
921
|
-
name: '',
|
|
922
|
-
pinned: false,
|
|
923
|
-
hidden: false,
|
|
924
|
-
},
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
else {
|
|
928
|
-
group.accounts = accountIds;
|
|
929
|
-
}
|
|
930
|
-
if (!wallet) {
|
|
931
|
-
wallet = {
|
|
932
|
-
id: multichainAccountWallet.id,
|
|
933
|
-
type: multichainAccountWallet.type,
|
|
934
|
-
status: multichainAccountWallet.status,
|
|
935
|
-
groups: {
|
|
936
|
-
[group.id]: group,
|
|
937
|
-
},
|
|
938
|
-
metadata: {
|
|
939
|
-
entropy: {
|
|
940
|
-
id: multichainAccountWallet.entropySource,
|
|
941
|
-
},
|
|
942
|
-
name: '', // Will get updated later.
|
|
943
|
-
},
|
|
944
|
-
};
|
|
945
|
-
wallets[walletId] = wallet;
|
|
946
|
-
// Trigger atomic sync for new wallet.
|
|
947
|
-
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleWalletSync(walletId);
|
|
948
|
-
}
|
|
949
|
-
else {
|
|
950
|
-
wallet.groups[group.id] = group;
|
|
951
|
-
// Trigger atomic sync for new group.
|
|
952
|
-
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").enqueueSingleGroupSync(groupId);
|
|
953
|
-
}
|
|
954
|
-
// Map group ID to its containing wallet ID for efficient direct access
|
|
955
|
-
__classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").set(groupId, walletId);
|
|
956
|
-
// Update the reverse mapping for all accounts account.
|
|
957
|
-
for (const account of accounts) {
|
|
958
|
-
__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").set(account.id, {
|
|
959
|
-
walletId: wallet.id,
|
|
960
|
-
groupId: group.id,
|
|
961
|
-
sortOrder: group_1.ACCOUNT_TYPE_TO_SORT_ORDER[account.type] ?? group_1.MAX_SORT_ORDER,
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
// We need to do this at every insertion because race conditions can happen
|
|
965
|
-
// during the account creation process where one provider completes before the other.
|
|
966
|
-
// The discovery process in the service can also lead to some accounts being created "out of order".
|
|
967
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_sortAccountsOfGroup).call(this, group);
|
|
968
|
-
}, _AccountTreeController_getMultichainAccountWallets = function _AccountTreeController_getMultichainAccountWallets() {
|
|
969
|
-
return this.messagingSystem.call('MultichainAccountService:getMultichainAccountWallets');
|
|
970
870
|
}, _AccountTreeController_listAccounts = function _AccountTreeController_listAccounts() {
|
|
971
|
-
return this.
|
|
871
|
+
return this.messenger.call('AccountsController:listMultichainAccounts');
|
|
972
872
|
}, _AccountTreeController_assertAccountGroupExists = function _AccountTreeController_assertAccountGroupExists(groupId) {
|
|
973
873
|
const exists = __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f").has(groupId);
|
|
974
874
|
if (!exists) {
|
|
@@ -984,7 +884,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
984
884
|
throw new Error('Account group name already exists');
|
|
985
885
|
}
|
|
986
886
|
}, _AccountTreeController_getDefaultSelectedAccountGroup = function _AccountTreeController_getDefaultSelectedAccountGroup(wallets) {
|
|
987
|
-
const selectedAccount = this.
|
|
887
|
+
const selectedAccount = this.messenger.call('AccountsController:getSelectedMultichainAccount');
|
|
988
888
|
if (selectedAccount && selectedAccount.id) {
|
|
989
889
|
const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(selectedAccount.id);
|
|
990
890
|
if (accountMapping) {
|
|
@@ -1010,20 +910,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
1010
910
|
this.update((state) => {
|
|
1011
911
|
state.accountTree.selectedAccountGroup = groupId;
|
|
1012
912
|
});
|
|
1013
|
-
this.
|
|
1014
|
-
}, _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated = function _AccountTreeController_handleMultichainAccountGroupCreatedOrUpdated(multichainAccountGroup) {
|
|
1015
|
-
this.update((state) => {
|
|
1016
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insertOrUpdateMultichainAccountWalletAndGroup).call(this, state.accountTree.wallets, multichainAccountGroup.wallet, multichainAccountGroup);
|
|
1017
|
-
const wallet = state.accountTree.wallets[multichainAccountGroup.wallet.id];
|
|
1018
|
-
if (wallet) {
|
|
1019
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountWalletMetadata).call(this, state, wallet.id);
|
|
1020
|
-
const group = wallet.groups[multichainAccountGroup.id];
|
|
1021
|
-
if (group) {
|
|
1022
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountGroupMetadata).call(this, state, wallet.id, group.id);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
});
|
|
1026
|
-
this.messagingSystem.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
|
|
913
|
+
this.messenger.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
|
|
1027
914
|
}, _AccountTreeController_handleMultichainAccountWalletStatusChange = function _AccountTreeController_handleMultichainAccountWalletStatusChange(walletId, walletStatus) {
|
|
1028
915
|
this.update((state) => {
|
|
1029
916
|
const wallet = state.accountTree.wallets[walletId];
|
|
@@ -1039,7 +926,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
1039
926
|
if (group) {
|
|
1040
927
|
let candidate;
|
|
1041
928
|
for (const id of group.accounts) {
|
|
1042
|
-
const account = this.
|
|
929
|
+
const account = this.messenger.call('AccountsController:getAccount', id);
|
|
1043
930
|
if (!candidate) {
|
|
1044
931
|
candidate = id;
|
|
1045
932
|
}
|
|
@@ -1063,7 +950,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
1063
950
|
candidate = group.id;
|
|
1064
951
|
}
|
|
1065
952
|
for (const id of group.accounts) {
|
|
1066
|
-
const account = this.
|
|
953
|
+
const account = this.messenger.call('AccountsController:getAccount', id);
|
|
1067
954
|
if (account && (0, keyring_api_1.isEvmAccountType)(account.type)) {
|
|
1068
955
|
// EVM accounts have a higher priority, so if we find any, we just
|
|
1069
956
|
// use that group!
|
|
@@ -1074,18 +961,18 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
1074
961
|
}
|
|
1075
962
|
return candidate;
|
|
1076
963
|
}, _AccountTreeController_registerMessageHandlers = function _AccountTreeController_registerMessageHandlers() {
|
|
1077
|
-
this.
|
|
1078
|
-
this.
|
|
1079
|
-
this.
|
|
1080
|
-
this.
|
|
1081
|
-
this.
|
|
1082
|
-
this.
|
|
1083
|
-
this.
|
|
964
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getSelectedAccountGroup`, this.getSelectedAccountGroup.bind(this));
|
|
965
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setSelectedAccountGroup`, this.setSelectedAccountGroup.bind(this));
|
|
966
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:getAccountsFromSelectedAccountGroup`, this.getAccountsFromSelectedAccountGroup.bind(this));
|
|
967
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setAccountWalletName`, this.setAccountWalletName.bind(this));
|
|
968
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupName`, this.setAccountGroupName.bind(this));
|
|
969
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupPinned`, this.setAccountGroupPinned.bind(this));
|
|
970
|
+
this.messenger.registerActionHandler(`${exports.controllerName}:setAccountGroupHidden`, this.setAccountGroupHidden.bind(this));
|
|
1084
971
|
}, _AccountTreeController_createBackupAndSyncContext = function _AccountTreeController_createBackupAndSyncContext() {
|
|
1085
972
|
return {
|
|
1086
973
|
...__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncConfig, "f"),
|
|
1087
974
|
controller: this,
|
|
1088
|
-
messenger: this.
|
|
975
|
+
messenger: this.messenger,
|
|
1089
976
|
controllerStateUpdateFn: this.update.bind(this),
|
|
1090
977
|
traceFn: __classPrivateFieldGet(this, _AccountTreeController_trace, "f").bind(this),
|
|
1091
978
|
groupIdToWalletId: __classPrivateFieldGet(this, _AccountTreeController_groupIdToWalletId, "f"),
|