@metamask-previews/account-tree-controller 1.0.0-preview-8ccfcb37 → 1.3.0-preview-a5441fae
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 +44 -3
- package/dist/AccountTreeController.cjs +106 -43
- package/dist/AccountTreeController.cjs.map +1 -1
- package/dist/AccountTreeController.d.cts +13 -1
- package/dist/AccountTreeController.d.cts.map +1 -1
- package/dist/AccountTreeController.d.mts +13 -1
- package/dist/AccountTreeController.d.mts.map +1 -1
- package/dist/AccountTreeController.mjs +107 -44
- package/dist/AccountTreeController.mjs.map +1 -1
- package/dist/backup-and-sync/syncing/group.cjs +1 -1
- package/dist/backup-and-sync/syncing/group.cjs.map +1 -1
- package/dist/backup-and-sync/syncing/group.mjs +1 -1
- package/dist/backup-and-sync/syncing/group.mjs.map +1 -1
- package/dist/backup-and-sync/syncing/legacy.cjs +1 -1
- package/dist/backup-and-sync/syncing/legacy.cjs.map +1 -1
- package/dist/backup-and-sync/syncing/legacy.mjs +1 -1
- package/dist/backup-and-sync/syncing/legacy.mjs.map +1 -1
- package/dist/group.cjs +17 -1
- package/dist/group.cjs.map +1 -1
- package/dist/group.d.cts +7 -0
- package/dist/group.d.cts.map +1 -1
- package/dist/group.d.mts +7 -0
- package/dist/group.d.mts.map +1 -1
- package/dist/group.mjs +16 -0
- package/dist/group.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -9,11 +9,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708))
|
|
13
|
+
|
|
14
|
+
## [1.3.0]
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Add more internal logs ([#6730](https://github.com/MetaMask/core/pull/6730))
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Preverve import time for account groups ([#6727](https://github.com/MetaMask/core/pull/6727))
|
|
23
|
+
- We now wait sort accounts by their `importTime` before re-building the tree.
|
|
24
|
+
- Prevent `:account{Added,Removed}` to be used if `init` has not been called yet ([#6717](https://github.com/MetaMask/core/pull/6717))
|
|
25
|
+
- We now wait for `init` to have been called at least once. Clients will need to ensure internal accounts are fully ready before calling `init`.
|
|
26
|
+
- This should also enforce account group ordering, since all accounts will be ready to consume right away.
|
|
27
|
+
|
|
28
|
+
## [1.2.0]
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Add `reinit` method ([#6709](https://github.com/MetaMask/core/pull/6709))
|
|
33
|
+
- This method can be used if we change the entire list of accounts of the `AccountsController` and want to re-initilize the tree with it.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Implicitly call `init` before mutating the tree ([#6709](https://github.com/MetaMask/core/pull/6709))
|
|
38
|
+
- This ensure the tree is always using existing accounts before inserting/removing any new accounts if `init` has not been called yet.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Fix use of unknown `group.metadata.name` when checking for group name uniqueness ([#6706](https://github.com/MetaMask/core/pull/6706))
|
|
43
|
+
- Added logic that prevents an account within a group from being out of order ([#6683](https://github.com/MetaMask/core/pull/6683))
|
|
44
|
+
|
|
45
|
+
## [1.1.0]
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Set the `setAccountGroupName`'s option `autoHandleConflict` to `true` for all backup & sync operations ([#6697](https://github.com/MetaMask/core/pull/6697))
|
|
50
|
+
- Add new group naming for non-HD keyring accounts ([#6679](https://github.com/MetaMask/core/pull/6679)), ([#6696](https://github.com/MetaMask/core/pull/6696))
|
|
13
51
|
- Hardware-wallet account groups are now named: "Ledger|Trezor|QR|Lattice|OneKey Account N".
|
|
14
52
|
- Private key account groups are now named: "Imported Account N".
|
|
15
53
|
- Snap account groups are now named: "Snap Account N".
|
|
16
|
-
- Account group names now use natural indexing as a fallback ([#6677](https://github.com/MetaMask/core/pull/6677)), ([#6679](https://github.com/MetaMask/core/pull/6679))
|
|
54
|
+
- Account group names now use natural indexing as a fallback ([#6677](https://github.com/MetaMask/core/pull/6677)), ([#6679](https://github.com/MetaMask/core/pull/6679)), ([#6696](https://github.com/MetaMask/core/pull/6696))
|
|
17
55
|
- If a user names his accounts without any indexes, we would just use the number of accounts to compute the next available index.
|
|
18
56
|
|
|
19
57
|
### Fixed
|
|
@@ -303,7 +341,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
303
341
|
- Initial release ([#5847](https://github.com/MetaMask/core/pull/5847))
|
|
304
342
|
- Grouping accounts into 3 main categories: Entropy source, Snap ID, keyring types.
|
|
305
343
|
|
|
306
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@1.
|
|
344
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@1.3.0...HEAD
|
|
345
|
+
[1.3.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@1.2.0...@metamask/account-tree-controller@1.3.0
|
|
346
|
+
[1.2.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@1.1.0...@metamask/account-tree-controller@1.2.0
|
|
347
|
+
[1.1.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@1.0.0...@metamask/account-tree-controller@1.1.0
|
|
307
348
|
[1.0.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@0.18.1...@metamask/account-tree-controller@1.0.0
|
|
308
349
|
[0.18.1]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@0.18.0...@metamask/account-tree-controller@0.18.1
|
|
309
350
|
[0.18.0]: https://github.com/MetaMask/core/compare/@metamask/account-tree-controller@0.17.0...@metamask/account-tree-controller@0.18.0
|
|
@@ -10,7 +10,7 @@ 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_getEntropyRule, _AccountTreeController_getSnapRule, _AccountTreeController_getKeyringRule, _AccountTreeController_applyAccountWalletMetadata, _AccountTreeController_getRuleForWallet, _AccountTreeController_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_getDefaultSelectedAccountGroup,
|
|
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_applyAccountGroupMetadata, _AccountTreeController_handleAccountAdded, _AccountTreeController_handleAccountRemoved, _AccountTreeController_pruneEmptyGroupAndWallet, _AccountTreeController_insert, _AccountTreeController_listAccounts, _AccountTreeController_assertAccountGroupExists, _AccountTreeController_assertAccountWalletExists, _AccountTreeController_assertAccountGroupNameIsUnique, _AccountTreeController_getDefaultSelectedAccountGroup, _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");
|
|
@@ -20,6 +20,7 @@ const utils_1 = require("@metamask/utils");
|
|
|
20
20
|
const analytics_1 = require("./backup-and-sync/analytics/index.cjs");
|
|
21
21
|
const service_1 = require("./backup-and-sync/service/index.cjs");
|
|
22
22
|
const group_1 = require("./group.cjs");
|
|
23
|
+
const logger_1 = require("./logger.cjs");
|
|
23
24
|
const entropy_1 = require("./rules/entropy.cjs");
|
|
24
25
|
const keyring_1 = require("./rules/keyring.cjs");
|
|
25
26
|
const snap_1 = require("./rules/snap.cjs");
|
|
@@ -103,6 +104,9 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
103
104
|
_AccountTreeController_rules.set(this, void 0);
|
|
104
105
|
_AccountTreeController_trace.set(this, void 0);
|
|
105
106
|
_AccountTreeController_backupAndSyncConfig.set(this, void 0);
|
|
107
|
+
_AccountTreeController_initialized.set(this, void 0);
|
|
108
|
+
// This will be set to true upon the first `init` call.
|
|
109
|
+
__classPrivateFieldSet(this, _AccountTreeController_initialized, false, "f");
|
|
106
110
|
// Reverse map to allow fast node access from an account ID.
|
|
107
111
|
__classPrivateFieldSet(this, _AccountTreeController_accountIdToContext, new Map(), "f");
|
|
108
112
|
// Reverse map to allow fast wallet node access from a group ID.
|
|
@@ -133,9 +137,6 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
133
137
|
this.messagingSystem.subscribe('AccountsController:accountRemoved', (accountId) => {
|
|
134
138
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleAccountRemoved).call(this, accountId);
|
|
135
139
|
});
|
|
136
|
-
this.messagingSystem.subscribe('AccountsController:selectedAccountChange', (account) => {
|
|
137
|
-
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_handleSelectedAccountChange).call(this, account);
|
|
138
|
-
});
|
|
139
140
|
this.messagingSystem.subscribe('UserStorageController:stateChange', (userStorageControllerState) => {
|
|
140
141
|
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").handleUserStorageStateChange(userStorageControllerState);
|
|
141
142
|
});
|
|
@@ -152,6 +153,12 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
152
153
|
* state with it.
|
|
153
154
|
*/
|
|
154
155
|
init() {
|
|
156
|
+
if (__classPrivateFieldGet(this, _AccountTreeController_initialized, "f")) {
|
|
157
|
+
// We prevent re-initilializing the state multiple times. Though, we can use
|
|
158
|
+
// `reinit` to re-init everything from scratch.
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
(0, logger_1.projectLogger)('Initializing...');
|
|
155
162
|
const wallets = {};
|
|
156
163
|
// Clear mappings for fresh rebuild.
|
|
157
164
|
__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").clear();
|
|
@@ -159,8 +166,20 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
159
166
|
// Keep the current selected group to check if it's still part of the tree
|
|
160
167
|
// after rebuilding it.
|
|
161
168
|
const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
|
|
169
|
+
// There's no guarantee that accounts would be sorted by their import time
|
|
170
|
+
// with `listMultichainAccounts`. We have to sort them here before constructing
|
|
171
|
+
// the tree.
|
|
172
|
+
//
|
|
173
|
+
// Because of the alignment mecanism, some accounts from the same group might not
|
|
174
|
+
// have been imported at the same time, but at least of them should have been
|
|
175
|
+
// imported at the right time, thus, inserting the group at the proper place too.
|
|
176
|
+
//
|
|
177
|
+
// Lastly, if one day we allow to have "gaps" in between groups, then this `sort`
|
|
178
|
+
// won't be enough and we would have to use group properties instead (like group
|
|
179
|
+
// index or maybe introduce a `importTime` at group level).
|
|
180
|
+
const accounts = __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_listAccounts).call(this).sort((a, b) => a.metadata.importTime - b.metadata.importTime);
|
|
162
181
|
// For now, we always re-compute all wallets, we do not re-use the existing state.
|
|
163
|
-
for (const account of
|
|
182
|
+
for (const account of accounts) {
|
|
164
183
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, wallets, account);
|
|
165
184
|
}
|
|
166
185
|
// Once we have the account tree, we can apply persisted metadata (names + UI states).
|
|
@@ -203,8 +222,22 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
203
222
|
// case, no need to fire any event.
|
|
204
223
|
if (previousSelectedAccountGroup !==
|
|
205
224
|
this.state.accountTree.selectedAccountGroup) {
|
|
225
|
+
(0, logger_1.projectLogger)(`Selected (initial) group is: [${this.state.accountTree.selectedAccountGroup}]`);
|
|
206
226
|
this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, this.state.accountTree.selectedAccountGroup, previousSelectedAccountGroup);
|
|
207
227
|
}
|
|
228
|
+
(0, logger_1.projectLogger)('Initialized!');
|
|
229
|
+
__classPrivateFieldSet(this, _AccountTreeController_initialized, true, "f");
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Re-initialize the controller's state.
|
|
233
|
+
*
|
|
234
|
+
* This is done in one single (atomic) `update` block to avoid having a temporary
|
|
235
|
+
* cleared state. Use this when you need to force a full re-init even if already initialized.
|
|
236
|
+
*/
|
|
237
|
+
reinit() {
|
|
238
|
+
(0, logger_1.projectLogger)('Re-initializing...');
|
|
239
|
+
__classPrivateFieldSet(this, _AccountTreeController_initialized, false, "f");
|
|
240
|
+
this.init();
|
|
208
241
|
}
|
|
209
242
|
/**
|
|
210
243
|
* Gets the account wallet object from its ID.
|
|
@@ -302,6 +335,7 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
302
335
|
this.update((state) => {
|
|
303
336
|
state.accountTree.selectedAccountGroup = groupId;
|
|
304
337
|
});
|
|
338
|
+
(0, logger_1.projectLogger)(`Selected group is now: [${this.state.accountTree.selectedAccountGroup}]`);
|
|
305
339
|
this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
|
|
306
340
|
// Update AccountsController - this will trigger selectedAccountChange event,
|
|
307
341
|
// but our handler is idempotent so it won't cause infinite loop
|
|
@@ -351,6 +385,7 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
351
385
|
// Validate that the name is unique
|
|
352
386
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_assertAccountGroupNameIsUnique).call(this, groupId, finalName);
|
|
353
387
|
}
|
|
388
|
+
(0, logger_1.projectLogger)(`[${groupId}] Set new name to: "${finalName}" (auto handle conflict: ${autoHandleConflict})`);
|
|
354
389
|
this.update((state) => {
|
|
355
390
|
/* istanbul ignore next */
|
|
356
391
|
if (!state.accountGroupsMetadata[groupId]) {
|
|
@@ -470,12 +505,15 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
470
505
|
* Also clears the backup and sync service state.
|
|
471
506
|
*/
|
|
472
507
|
clearState() {
|
|
508
|
+
(0, logger_1.projectLogger)('Clearing state');
|
|
473
509
|
this.update(() => {
|
|
474
510
|
return {
|
|
475
511
|
...getDefaultAccountTreeControllerState(),
|
|
476
512
|
};
|
|
477
513
|
});
|
|
478
514
|
__classPrivateFieldGet(this, _AccountTreeController_backupAndSyncService, "f").clearState();
|
|
515
|
+
// So we know we have to call `init` again.
|
|
516
|
+
__classPrivateFieldSet(this, _AccountTreeController_initialized, false, "f");
|
|
479
517
|
}
|
|
480
518
|
/**
|
|
481
519
|
* Bi-directionally syncs the account tree with user storage.
|
|
@@ -508,7 +546,7 @@ class AccountTreeController extends base_controller_1.BaseController {
|
|
|
508
546
|
}
|
|
509
547
|
}
|
|
510
548
|
exports.AccountTreeController = AccountTreeController;
|
|
511
|
-
_AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_groupIdToWalletId = new WeakMap(), _AccountTreeController_backupAndSyncService = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_trace = new WeakMap(), _AccountTreeController_backupAndSyncConfig = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getEntropyRule = function _AccountTreeController_getEntropyRule() {
|
|
549
|
+
_AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeController_groupIdToWalletId = new WeakMap(), _AccountTreeController_backupAndSyncService = new WeakMap(), _AccountTreeController_rules = new WeakMap(), _AccountTreeController_trace = new WeakMap(), _AccountTreeController_backupAndSyncConfig = new WeakMap(), _AccountTreeController_initialized = new WeakMap(), _AccountTreeController_instances = new WeakSet(), _AccountTreeController_getEntropyRule = function _AccountTreeController_getEntropyRule() {
|
|
512
550
|
return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[0];
|
|
513
551
|
}, _AccountTreeController_getSnapRule = function _AccountTreeController_getSnapRule() {
|
|
514
552
|
return __classPrivateFieldGet(this, _AccountTreeController_rules, "f")[1];
|
|
@@ -535,6 +573,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
535
573
|
wallet.metadata.name =
|
|
536
574
|
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this).getDefaultAccountWalletName(wallet);
|
|
537
575
|
}
|
|
576
|
+
(0, logger_1.projectLogger)(`[${wallet.id}] Set default name to: "${wallet.metadata.name}"`);
|
|
538
577
|
}
|
|
539
578
|
}, _AccountTreeController_getRuleForWallet = function _AccountTreeController_getRuleForWallet(wallet) {
|
|
540
579
|
switch (wallet.type) {
|
|
@@ -546,7 +585,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
546
585
|
return __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getKeyringRule).call(this);
|
|
547
586
|
}
|
|
548
587
|
}, _AccountTreeController_applyAccountGroupMetadata = function _AccountTreeController_applyAccountGroupMetadata(state, walletId, groupId, nextNaturalNameIndex) {
|
|
549
|
-
var _a
|
|
588
|
+
var _a;
|
|
550
589
|
const wallet = state.accountTree.wallets[walletId];
|
|
551
590
|
const group = wallet.groups[groupId];
|
|
552
591
|
const persistedGroupMetadata = state.accountGroupsMetadata[group.id];
|
|
@@ -564,13 +603,17 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
564
603
|
// TODO: Implement computed names in a future iteration
|
|
565
604
|
// Parse the highest account index being used (similar to accounts-controller)
|
|
566
605
|
let highestNameIndex = 0;
|
|
567
|
-
for (const
|
|
606
|
+
for (const { id: otherGroupId } of Object.values(wallet.groups)) {
|
|
568
607
|
// Skip the current group being processed
|
|
569
|
-
if (
|
|
608
|
+
if (otherGroupId === groupId) {
|
|
570
609
|
continue;
|
|
571
610
|
}
|
|
611
|
+
// We always get the name from the persisted map, since `init` will clear the
|
|
612
|
+
// `state.accountTree.wallets`, thus, given empty `group.metadata.name`.
|
|
613
|
+
// NOTE: If the other group has not been named yet, we just use an empty name.
|
|
614
|
+
const otherGroupName = state.accountGroupsMetadata[otherGroupId]?.name?.value ?? '';
|
|
572
615
|
// Parse the existing group name to extract the numeric index
|
|
573
|
-
const nameMatch =
|
|
616
|
+
const nameMatch = otherGroupName.match(/account\s+(\d+)$/iu);
|
|
574
617
|
if (nameMatch) {
|
|
575
618
|
const nameIndex = parseInt(nameMatch[1], 10);
|
|
576
619
|
if (nameIndex > highestNameIndex) {
|
|
@@ -610,9 +653,10 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
610
653
|
} while (proposedNameExists);
|
|
611
654
|
state.accountTree.wallets[walletId].groups[groupId].metadata.name =
|
|
612
655
|
proposedName;
|
|
656
|
+
(0, logger_1.projectLogger)(`[${group.id}] Set default name to: "${group.metadata.name}"`);
|
|
613
657
|
// Persist the generated name to ensure consistency
|
|
614
|
-
(_a = state.accountGroupsMetadata)[
|
|
615
|
-
state.accountGroupsMetadata[
|
|
658
|
+
(_a = state.accountGroupsMetadata)[groupId] ?? (_a[groupId] = {});
|
|
659
|
+
state.accountGroupsMetadata[groupId].name = {
|
|
616
660
|
value: proposedName,
|
|
617
661
|
// The `lastUpdatedAt` field is used for backup and sync, when comparing local names
|
|
618
662
|
// with backed up names. In this case, the generated name should never take precedence
|
|
@@ -628,20 +672,35 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
628
672
|
group.metadata.hidden = persistedGroupMetadata.hidden.value;
|
|
629
673
|
}
|
|
630
674
|
}, _AccountTreeController_handleAccountAdded = function _AccountTreeController_handleAccountAdded(account) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
675
|
+
// We wait for the first `init` to be called to actually build up the tree and
|
|
676
|
+
// mutate it. We expect the caller to first update the `AccountsController` state
|
|
677
|
+
// to force the migration of accounts, and then call `init`.
|
|
678
|
+
if (!__classPrivateFieldGet(this, _AccountTreeController_initialized, "f")) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
// Check if this account is already known by the tree to avoid double-insertion.
|
|
682
|
+
if (!__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").has(account.id)) {
|
|
683
|
+
this.update((state) => {
|
|
684
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_insert).call(this, state.accountTree.wallets, account);
|
|
685
|
+
const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
|
|
686
|
+
if (context) {
|
|
687
|
+
const { walletId, groupId } = context;
|
|
688
|
+
const wallet = state.accountTree.wallets[walletId];
|
|
689
|
+
if (wallet) {
|
|
690
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountWalletMetadata).call(this, state, walletId);
|
|
691
|
+
__classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_applyAccountGroupMetadata).call(this, state, walletId, groupId);
|
|
692
|
+
}
|
|
640
693
|
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
694
|
+
});
|
|
695
|
+
this.messagingSystem.publish(`${exports.controllerName}:accountTreeChange`, this.state.accountTree);
|
|
696
|
+
}
|
|
644
697
|
}, _AccountTreeController_handleAccountRemoved = function _AccountTreeController_handleAccountRemoved(accountId) {
|
|
698
|
+
// We wait for the first `init` to be called to actually build up the tree and
|
|
699
|
+
// mutate it. We expect the caller to first update the `AccountsController` state
|
|
700
|
+
// to force the migration of accounts, and then call `init`.
|
|
701
|
+
if (!__classPrivateFieldGet(this, _AccountTreeController_initialized, "f")) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
645
704
|
const context = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(accountId);
|
|
646
705
|
if (context) {
|
|
647
706
|
const { walletId, groupId } = context;
|
|
@@ -694,6 +753,7 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
694
753
|
const walletId = result.wallet.id;
|
|
695
754
|
let wallet = wallets[walletId];
|
|
696
755
|
if (!wallet) {
|
|
756
|
+
(0, logger_1.projectLogger)(`[${walletId}] Added as new wallet`);
|
|
697
757
|
wallets[walletId] = {
|
|
698
758
|
...result.wallet,
|
|
699
759
|
status: 'ready',
|
|
@@ -713,11 +773,14 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
713
773
|
}
|
|
714
774
|
const groupId = result.group.id;
|
|
715
775
|
let group = wallet.groups[groupId];
|
|
776
|
+
const { type, id } = account;
|
|
777
|
+
const sortOrder = group_1.ACCOUNT_TYPE_TO_SORT_ORDER[type];
|
|
716
778
|
if (!group) {
|
|
779
|
+
(0, logger_1.projectLogger)(`[${walletId}] Add new group: [${groupId}]`);
|
|
717
780
|
wallet.groups[groupId] = {
|
|
718
781
|
...result.group,
|
|
719
782
|
// Type-wise, we are guaranteed to always have at least 1 account.
|
|
720
|
-
accounts: [
|
|
783
|
+
accounts: [id],
|
|
721
784
|
metadata: {
|
|
722
785
|
name: '',
|
|
723
786
|
...{ pinned: false, hidden: false },
|
|
@@ -735,12 +798,29 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
735
798
|
}
|
|
736
799
|
}
|
|
737
800
|
else {
|
|
738
|
-
group.accounts.push(
|
|
801
|
+
group.accounts.push(id);
|
|
802
|
+
// We need to do this at every insertion because race conditions can happen
|
|
803
|
+
// during the account creation process where one provider completes before the other.
|
|
804
|
+
// The discovery process in the service can also lead to some accounts being created "out of order".
|
|
805
|
+
const { accounts } = group;
|
|
806
|
+
accounts.sort(
|
|
807
|
+
/* istanbul ignore next: Comparator branch execution (a===id vs b===id)
|
|
808
|
+
* and return attribution vary across engines; final ordering is covered
|
|
809
|
+
* by behavior tests. Ignoring the entire comparator avoids flaky line
|
|
810
|
+
* coverage without reducing scenario coverage.
|
|
811
|
+
*/
|
|
812
|
+
(a, b) => {
|
|
813
|
+
const aSortOrder = a === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(a)?.sortOrder;
|
|
814
|
+
const bSortOrder = b === id ? sortOrder : __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(b)?.sortOrder;
|
|
815
|
+
return ((aSortOrder ?? group_1.MAX_SORT_ORDER) - (bSortOrder ?? group_1.MAX_SORT_ORDER));
|
|
816
|
+
});
|
|
739
817
|
}
|
|
818
|
+
(0, logger_1.projectLogger)(`[${groupId}] Add new account: { id: "${account.id}", type: "${account.type}", address: "${account.address}"`);
|
|
740
819
|
// Update the reverse mapping for this account.
|
|
741
820
|
__classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").set(account.id, {
|
|
742
821
|
walletId: wallet.id,
|
|
743
822
|
groupId: group.id,
|
|
823
|
+
sortOrder,
|
|
744
824
|
});
|
|
745
825
|
}, _AccountTreeController_listAccounts = function _AccountTreeController_listAccounts() {
|
|
746
826
|
return this.messagingSystem.call('AccountsController:listMultichainAccounts');
|
|
@@ -769,23 +849,6 @@ _AccountTreeController_accountIdToContext = new WeakMap(), _AccountTreeControlle
|
|
|
769
849
|
}
|
|
770
850
|
// Default to the default group in case of errors.
|
|
771
851
|
return __classPrivateFieldGet(this, _AccountTreeController_instances, "m", _AccountTreeController_getDefaultAccountGroupId).call(this, wallets);
|
|
772
|
-
}, _AccountTreeController_handleSelectedAccountChange = function _AccountTreeController_handleSelectedAccountChange(account) {
|
|
773
|
-
const accountMapping = __classPrivateFieldGet(this, _AccountTreeController_accountIdToContext, "f").get(account.id);
|
|
774
|
-
if (!accountMapping) {
|
|
775
|
-
// Account not in tree yet, might be during initialization
|
|
776
|
-
return;
|
|
777
|
-
}
|
|
778
|
-
const { groupId } = accountMapping;
|
|
779
|
-
const previousSelectedAccountGroup = this.state.accountTree.selectedAccountGroup;
|
|
780
|
-
// Idempotent check - if the same group is already selected, do nothing
|
|
781
|
-
if (previousSelectedAccountGroup === groupId) {
|
|
782
|
-
return;
|
|
783
|
-
}
|
|
784
|
-
// Update selectedAccountGroup to match the selected account
|
|
785
|
-
this.update((state) => {
|
|
786
|
-
state.accountTree.selectedAccountGroup = groupId;
|
|
787
|
-
});
|
|
788
|
-
this.messagingSystem.publish(`${exports.controllerName}:selectedAccountGroupChange`, groupId, previousSelectedAccountGroup);
|
|
789
852
|
}, _AccountTreeController_handleMultichainAccountWalletStatusChange = function _AccountTreeController_handleMultichainAccountWalletStatusChange(walletId, walletStatus) {
|
|
790
853
|
this.update((state) => {
|
|
791
854
|
const wallet = state.accountTree.wallets[walletId];
|