@metamask/accounts-controller 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [1.0.0]
10
+ ### Added
11
+ - Initial release ([#1637](https://github.com/MetaMask/core/pull/1637))
12
+
13
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/accounts-controller@1.0.0...HEAD
14
+ [1.0.0]: https://github.com/MetaMask/core/releases/tag/@metamask/accounts-controller@1.0.0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 MetaMask
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # `@metamask/accounts-controller`
2
+
3
+ Manages internal accounts used in place of regular ethereum addresses.
4
+
5
+ ## Installation
6
+
7
+ `yarn add @metamask/accounts-controller`
8
+
9
+ or
10
+
11
+ `npm install @metamask/accounts-controller`
12
+
13
+ ## Contributing
14
+
15
+ This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).
@@ -0,0 +1,132 @@
1
+ import type { RestrictedControllerMessenger } from '@metamask/base-controller';
2
+ import { BaseControllerV2 } from '@metamask/base-controller';
3
+ import type { InternalAccount } from '@metamask/keyring-api';
4
+ import type { KeyringControllerEvents, KeyringControllerGetKeyringForAccountAction, KeyringControllerGetKeyringsByTypeAction, KeyringControllerGetAccountsAction } from '@metamask/keyring-controller';
5
+ import type { SnapControllerEvents } from '@metamask/snaps-controllers';
6
+ import type { Patch } from 'immer';
7
+ declare const controllerName = "AccountsController";
8
+ export declare type AccountsControllerState = {
9
+ internalAccounts: {
10
+ accounts: Record<string, InternalAccount>;
11
+ selectedAccount: string;
12
+ };
13
+ };
14
+ export declare type AccountsControllerGetStateAction = {
15
+ type: `${typeof controllerName}:getState`;
16
+ handler: () => AccountsControllerState;
17
+ };
18
+ export declare type AccountsControllerSetSelectedAccount = {
19
+ type: `${typeof controllerName}:setSelectedAccount`;
20
+ handler: AccountsController['setSelectedAccount'];
21
+ };
22
+ export declare type AccountsControllerSetAccountName = {
23
+ type: `${typeof controllerName}:setAccountName`;
24
+ handler: AccountsController['setAccountName'];
25
+ };
26
+ export declare type AccountsControllerListAccounts = {
27
+ type: `${typeof controllerName}:listAccounts`;
28
+ handler: AccountsController['listAccounts'];
29
+ };
30
+ export declare type AccountsControllerUpdateAccounts = {
31
+ type: `${typeof controllerName}:updateAccounts`;
32
+ handler: AccountsController['updateAccounts'];
33
+ };
34
+ export declare type AccountsControllerActions = AccountsControllerGetStateAction | AccountsControllerSetSelectedAccount | AccountsControllerListAccounts | AccountsControllerSetAccountName | AccountsControllerUpdateAccounts | KeyringControllerGetKeyringForAccountAction | KeyringControllerGetKeyringsByTypeAction | KeyringControllerGetAccountsAction;
35
+ export declare type AccountsControllerChangeEvent = {
36
+ type: `${typeof controllerName}:stateChange`;
37
+ payload: [AccountsControllerState, Patch[]];
38
+ };
39
+ export declare type AccountsControllerSelectedAccountChangeEvent = {
40
+ type: `${typeof controllerName}:selectedAccountChange`;
41
+ payload: [InternalAccount];
42
+ };
43
+ export declare type AccountsControllerEvents = AccountsControllerChangeEvent | AccountsControllerSelectedAccountChangeEvent | SnapControllerEvents | KeyringControllerEvents;
44
+ export declare type AccountsControllerMessenger = RestrictedControllerMessenger<typeof controllerName, AccountsControllerActions, AccountsControllerEvents, string, string>;
45
+ /**
46
+ * Controller that manages internal accounts.
47
+ * The accounts controller is responsible for creating and managing internal accounts.
48
+ * It also provides convenience methods for accessing and updating the internal accounts.
49
+ * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.
50
+ * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.
51
+ *
52
+ */
53
+ export declare class AccountsController extends BaseControllerV2<typeof controllerName, AccountsControllerState, AccountsControllerMessenger> {
54
+ #private;
55
+ keyringApiEnabled: boolean;
56
+ /**
57
+ * Constructor for AccountsController.
58
+ *
59
+ * @param options - The controller options.
60
+ * @param options.messenger - The messenger object.
61
+ * @param options.state - Initial state to set on this controller
62
+ * @param [options.keyringApiEnabled] - The keyring API enabled flag.
63
+ */
64
+ constructor({ messenger, state, keyringApiEnabled, }: {
65
+ messenger: AccountsControllerMessenger;
66
+ state: AccountsControllerState;
67
+ keyringApiEnabled?: boolean;
68
+ });
69
+ /**
70
+ * Returns the internal account object for the given account ID, if it exists.
71
+ *
72
+ * @param accountId - The ID of the account to retrieve.
73
+ * @returns The internal account object, or undefined if the account does not exist.
74
+ */
75
+ getAccount(accountId: string): InternalAccount | undefined;
76
+ /**
77
+ * Returns an array of all internal accounts.
78
+ *
79
+ * @returns An array of InternalAccount objects.
80
+ */
81
+ listAccounts(): InternalAccount[];
82
+ /**
83
+ * Returns the internal account object for the given account ID.
84
+ *
85
+ * @param accountId - The ID of the account to retrieve.
86
+ * @returns The internal account object.
87
+ * @throws An error if the account ID is not found.
88
+ */
89
+ getAccountExpect(accountId: string): InternalAccount;
90
+ /**
91
+ * Returns the selected internal account.
92
+ *
93
+ * @returns The selected internal account.
94
+ */
95
+ getSelectedAccount(): InternalAccount;
96
+ /**
97
+ * Sets the selected account by its ID.
98
+ *
99
+ * @param accountId - The ID of the account to be selected.
100
+ */
101
+ setSelectedAccount(accountId: string): void;
102
+ /**
103
+ * Sets the name of the account with the given ID.
104
+ *
105
+ * @param accountId - The ID of the account to set the name for.
106
+ * @param accountName - The new name for the account.
107
+ * @throws An error if an account with the same name already exists.
108
+ */
109
+ setAccountName(accountId: string, accountName: string): void;
110
+ /**
111
+ * Updates the internal accounts list by retrieving normal and snap accounts,
112
+ * removing duplicates, and updating the metadata of each account.
113
+ *
114
+ * @returns A Promise that resolves when the accounts have been updated.
115
+ */
116
+ updateAccounts(): Promise<void>;
117
+ /**
118
+ * Loads the backup state of the accounts controller.
119
+ *
120
+ * @param backup - The backup state to load.
121
+ */
122
+ loadBackup(backup: AccountsControllerState): void;
123
+ }
124
+ /**
125
+ * Returns the name of the keyring type.
126
+ *
127
+ * @param keyringType - The type of the keyring.
128
+ * @returns The name of the keyring type.
129
+ */
130
+ export declare function keyringTypeToName(keyringType: string): string;
131
+ export {};
132
+ //# sourceMappingURL=AccountsController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountsController.d.ts","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
+ 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");
14
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
+ };
16
+ var _AccountsController_instances, _AccountsController_listSnapAccounts, _AccountsController_listNormalAccounts, _AccountsController_handleSelectedAccountRemoved, _AccountsController_handleOnKeyringStateChange, _AccountsController_handleOnSnapStateChange, _AccountsController_handleNewAccountAdded, _AccountsController_registerMessageHandlers;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.keyringTypeToName = exports.AccountsController = void 0;
19
+ const base_controller_1 = require("@metamask/base-controller");
20
+ const eth_snap_keyring_1 = require("@metamask/eth-snap-keyring");
21
+ const keyring_api_1 = require("@metamask/keyring-api");
22
+ const ethereumjs_util_1 = require("ethereumjs-util");
23
+ const uuid_1 = require("uuid");
24
+ const controllerName = 'AccountsController';
25
+ const accountsControllerMetadata = {
26
+ internalAccounts: {
27
+ persist: true,
28
+ anonymous: false,
29
+ },
30
+ selectedAccount: {
31
+ persist: true,
32
+ anonymous: false,
33
+ },
34
+ };
35
+ const defaultState = {
36
+ internalAccounts: {
37
+ accounts: {},
38
+ selectedAccount: '',
39
+ },
40
+ };
41
+ /**
42
+ * Controller that manages internal accounts.
43
+ * The accounts controller is responsible for creating and managing internal accounts.
44
+ * It also provides convenience methods for accessing and updating the internal accounts.
45
+ * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.
46
+ * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.
47
+ *
48
+ */
49
+ class AccountsController extends base_controller_1.BaseControllerV2 {
50
+ /**
51
+ * Constructor for AccountsController.
52
+ *
53
+ * @param options - The controller options.
54
+ * @param options.messenger - The messenger object.
55
+ * @param options.state - Initial state to set on this controller
56
+ * @param [options.keyringApiEnabled] - The keyring API enabled flag.
57
+ */
58
+ constructor({ messenger, state, keyringApiEnabled, }) {
59
+ super({
60
+ messenger,
61
+ name: controllerName,
62
+ metadata: accountsControllerMetadata,
63
+ state: Object.assign(Object.assign({}, defaultState), state),
64
+ });
65
+ _AccountsController_instances.add(this);
66
+ this.keyringApiEnabled = Boolean(keyringApiEnabled);
67
+ if (this.keyringApiEnabled) {
68
+ this.messagingSystem.subscribe('SnapController:stateChange', (snapStateState) => __awaiter(this, void 0, void 0, function* () { return yield __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnSnapStateChange).call(this, snapStateState); }));
69
+ }
70
+ this.messagingSystem.subscribe('KeyringController:stateChange', (keyringState) => __awaiter(this, void 0, void 0, function* () { return yield __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleOnKeyringStateChange).call(this, keyringState); }));
71
+ __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_registerMessageHandlers).call(this);
72
+ // if somehow the selected account becomes lost then select the first account
73
+ if (this.state.internalAccounts.selectedAccount !== '' &&
74
+ !this.getAccount(this.state.internalAccounts.selectedAccount) &&
75
+ this.listAccounts().length > 0) {
76
+ this.setSelectedAccount(this.listAccounts()[0].id);
77
+ }
78
+ }
79
+ /**
80
+ * Returns the internal account object for the given account ID, if it exists.
81
+ *
82
+ * @param accountId - The ID of the account to retrieve.
83
+ * @returns The internal account object, or undefined if the account does not exist.
84
+ */
85
+ getAccount(accountId) {
86
+ return this.state.internalAccounts.accounts[accountId];
87
+ }
88
+ /**
89
+ * Returns an array of all internal accounts.
90
+ *
91
+ * @returns An array of InternalAccount objects.
92
+ */
93
+ listAccounts() {
94
+ return Object.values(this.state.internalAccounts.accounts);
95
+ }
96
+ /**
97
+ * Returns the internal account object for the given account ID.
98
+ *
99
+ * @param accountId - The ID of the account to retrieve.
100
+ * @returns The internal account object.
101
+ * @throws An error if the account ID is not found.
102
+ */
103
+ getAccountExpect(accountId) {
104
+ // Edge case where the extension is setup but the srp is not yet created
105
+ // certain ui elements will query the selected address before any accounts are created.
106
+ if (!accountId) {
107
+ return {
108
+ id: '',
109
+ address: '',
110
+ options: {},
111
+ methods: [],
112
+ type: keyring_api_1.EthAccountType.Eoa,
113
+ metadata: {
114
+ name: '',
115
+ keyring: {
116
+ type: '',
117
+ },
118
+ },
119
+ };
120
+ }
121
+ const account = this.getAccount(accountId);
122
+ if (account === undefined) {
123
+ throw new Error(`Account Id ${accountId} not found`);
124
+ }
125
+ return account;
126
+ }
127
+ /**
128
+ * Returns the selected internal account.
129
+ *
130
+ * @returns The selected internal account.
131
+ */
132
+ getSelectedAccount() {
133
+ return this.getAccountExpect(this.state.internalAccounts.selectedAccount);
134
+ }
135
+ /**
136
+ * Sets the selected account by its ID.
137
+ *
138
+ * @param accountId - The ID of the account to be selected.
139
+ */
140
+ setSelectedAccount(accountId) {
141
+ const account = this.getAccountExpect(accountId);
142
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
143
+ // @ts-ignore Type instantiation is excessively deep and possibly infinite.
144
+ this.update((currentState) => {
145
+ currentState.internalAccounts.accounts[account.id].metadata.lastSelected =
146
+ Date.now();
147
+ currentState.internalAccounts.selectedAccount = account.id;
148
+ });
149
+ this.messagingSystem.publish(`${this.name}:selectedAccountChange`, account);
150
+ }
151
+ /**
152
+ * Sets the name of the account with the given ID.
153
+ *
154
+ * @param accountId - The ID of the account to set the name for.
155
+ * @param accountName - The new name for the account.
156
+ * @throws An error if an account with the same name already exists.
157
+ */
158
+ setAccountName(accountId, accountName) {
159
+ const account = this.getAccountExpect(accountId);
160
+ if (this.listAccounts().find((internalAccount) => internalAccount.metadata.name === accountName &&
161
+ internalAccount.id !== accountId)) {
162
+ throw new Error('Account name already exists');
163
+ }
164
+ this.update((currentState) => {
165
+ currentState.internalAccounts.accounts[accountId] = Object.assign(Object.assign({}, account), { metadata: Object.assign(Object.assign({}, account.metadata), { name: accountName }) });
166
+ });
167
+ }
168
+ /**
169
+ * Updates the internal accounts list by retrieving normal and snap accounts,
170
+ * removing duplicates, and updating the metadata of each account.
171
+ *
172
+ * @returns A Promise that resolves when the accounts have been updated.
173
+ */
174
+ updateAccounts() {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ let normalAccounts = yield __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listNormalAccounts).call(this);
177
+ let snapAccounts = [];
178
+ if (this.keyringApiEnabled) {
179
+ snapAccounts = yield __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_listSnapAccounts).call(this);
180
+ // remove duplicate accounts that are retrieved from the snap keyring.
181
+ normalAccounts = normalAccounts.filter((account) => !snapAccounts.find((snapAccount) => snapAccount.address === account.address));
182
+ }
183
+ // keyring type map.
184
+ const keyringTypes = new Map();
185
+ const previousAccounts = this.state.internalAccounts.accounts;
186
+ const accounts = [
187
+ ...normalAccounts,
188
+ ...snapAccounts,
189
+ ].reduce((internalAccountMap, internalAccount) => {
190
+ var _a, _b;
191
+ const keyringTypeName = keyringTypeToName(internalAccount.metadata.keyring.type);
192
+ const keyringAccountIndex = (_a = keyringTypes.get(keyringTypeName)) !== null && _a !== void 0 ? _a : 0;
193
+ if (keyringAccountIndex) {
194
+ keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);
195
+ }
196
+ else {
197
+ keyringTypes.set(keyringTypeName, 1);
198
+ }
199
+ const existingAccount = previousAccounts[internalAccount.id];
200
+ internalAccountMap[internalAccount.id] = Object.assign(Object.assign({}, internalAccount), { metadata: Object.assign(Object.assign({}, internalAccount.metadata), { name: existingAccount && existingAccount.metadata.name !== ''
201
+ ? existingAccount.metadata.name
202
+ : `${keyringTypeName} ${keyringAccountIndex + 1}`, lastSelected: (_b = existingAccount === null || existingAccount === void 0 ? void 0 : existingAccount.metadata) === null || _b === void 0 ? void 0 : _b.lastSelected }) });
203
+ return internalAccountMap;
204
+ }, {});
205
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
206
+ // @ts-ignore Type instantiation is excessively deep and possibly infinite.
207
+ this.update((currentState) => {
208
+ currentState.internalAccounts.accounts = accounts;
209
+ });
210
+ });
211
+ }
212
+ /**
213
+ * Loads the backup state of the accounts controller.
214
+ *
215
+ * @param backup - The backup state to load.
216
+ */
217
+ loadBackup(backup) {
218
+ if (backup.internalAccounts) {
219
+ this.update((currentState) => {
220
+ currentState.internalAccounts = backup.internalAccounts;
221
+ });
222
+ }
223
+ }
224
+ }
225
+ exports.AccountsController = AccountsController;
226
+ _AccountsController_instances = new WeakSet(), _AccountsController_listSnapAccounts = function _AccountsController_listSnapAccounts() {
227
+ return __awaiter(this, void 0, void 0, function* () {
228
+ const [snapKeyring] = yield this.messagingSystem.call('KeyringController:getKeyringsByType', eth_snap_keyring_1.SnapKeyring.type);
229
+ // snap keyring is not available until the first account is created in the keyring controller
230
+ if (!snapKeyring) {
231
+ return [];
232
+ }
233
+ const snapAccounts = yield snapKeyring.listAccounts();
234
+ return snapAccounts;
235
+ });
236
+ }, _AccountsController_listNormalAccounts = function _AccountsController_listNormalAccounts() {
237
+ return __awaiter(this, void 0, void 0, function* () {
238
+ const addresses = yield this.messagingSystem.call('KeyringController:getAccounts');
239
+ const internalAccounts = [];
240
+ for (const address of addresses) {
241
+ const keyring = yield this.messagingSystem.call('KeyringController:getKeyringForAccount', address);
242
+ const v4options = {
243
+ random: (0, ethereumjs_util_1.sha256FromString)(address).slice(0, 16),
244
+ };
245
+ internalAccounts.push({
246
+ id: (0, uuid_1.v4)(v4options),
247
+ address,
248
+ options: {},
249
+ methods: [
250
+ 'personal_sign',
251
+ 'eth_sign',
252
+ 'eth_signTransaction',
253
+ 'eth_signTypedData_v1',
254
+ 'eth_signTypedData_v3',
255
+ 'eth_signTypedData_v4',
256
+ ],
257
+ type: keyring_api_1.EthAccountType.Eoa,
258
+ metadata: {
259
+ name: '',
260
+ keyring: {
261
+ type: keyring.type,
262
+ },
263
+ },
264
+ });
265
+ }
266
+ return internalAccounts.filter((account) => account.metadata.keyring.type !== 'Snap Keyring');
267
+ });
268
+ }, _AccountsController_handleSelectedAccountRemoved = function _AccountsController_handleSelectedAccountRemoved() {
269
+ const previousAccount = this.listAccounts()
270
+ .filter((account) => account.id !== this.state.internalAccounts.selectedAccount)
271
+ .sort((accountA, accountB) => {
272
+ var _a, _b;
273
+ // sort by lastSelected descending
274
+ return (((_a = accountB.metadata.lastSelected) !== null && _a !== void 0 ? _a : 0) -
275
+ ((_b = accountA.metadata.lastSelected) !== null && _b !== void 0 ? _b : 0));
276
+ })[0];
277
+ this.setSelectedAccount(previousAccount.id);
278
+ }, _AccountsController_handleOnKeyringStateChange = function _AccountsController_handleOnKeyringStateChange(keyringState) {
279
+ return __awaiter(this, void 0, void 0, function* () {
280
+ // check if there are any new accounts added
281
+ // TODO: change when accountAdded event is added to the keyring controller
282
+ if (keyringState.isUnlocked) {
283
+ // TODO: ACCOUNTS_CONTROLLER keyring will return accounts instead of addresses, remove this flatMap after and just get the latest id
284
+ const updatedKeyringAddresses = keyringState.keyrings.flatMap((keyring) => keyring.accounts);
285
+ const previousAccounts = this.listAccounts();
286
+ // if there are no overlaps between the addresses in the keyring and previous accounts,
287
+ // it means the keyring is being reinitialized because the vault is being restored with the same SRP
288
+ const overlaps = updatedKeyringAddresses.filter((address) => previousAccounts.find((account) => account.address.toLowerCase() === address.toLowerCase()));
289
+ yield this.updateAccounts();
290
+ if (updatedKeyringAddresses.length > previousAccounts.length) {
291
+ __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleNewAccountAdded).call(this, updatedKeyringAddresses, previousAccounts);
292
+ }
293
+ else if (updatedKeyringAddresses.length > 0 && overlaps.length === 0) {
294
+ // if the keyring is being reinitialized, the selected account will be reset to the first account
295
+ this.setSelectedAccount(this.listAccounts()[0].id);
296
+ }
297
+ else if (updatedKeyringAddresses.length < previousAccounts.length &&
298
+ overlaps.length > 0 &&
299
+ !this.getAccount(this.state.internalAccounts.selectedAccount)) {
300
+ __classPrivateFieldGet(this, _AccountsController_instances, "m", _AccountsController_handleSelectedAccountRemoved).call(this);
301
+ }
302
+ }
303
+ });
304
+ }, _AccountsController_handleOnSnapStateChange = function _AccountsController_handleOnSnapStateChange(snapState) {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ // only check if snaps changed in status
307
+ const { snaps } = snapState;
308
+ const accounts = this.listAccounts().filter((account) => account.metadata.snap);
309
+ this.update((currentState) => {
310
+ accounts.forEach((account) => {
311
+ const currentAccount = currentState.internalAccounts.accounts[account.id];
312
+ if (currentAccount.metadata.snap) {
313
+ currentAccount.metadata.snap.enabled =
314
+ snaps[currentAccount.metadata.snap.id].enabled &&
315
+ !snaps[currentAccount.metadata.snap.id].blocked;
316
+ }
317
+ });
318
+ });
319
+ });
320
+ }, _AccountsController_handleNewAccountAdded = function _AccountsController_handleNewAccountAdded(updatedKeyringAddresses, previousAccounts) {
321
+ const [newAddress] = updatedKeyringAddresses.filter((address) => !previousAccounts.find((account) => account.address.toLowerCase() === address.toLowerCase()));
322
+ const [newAccount] = this.listAccounts().filter((account) => account.address.toLowerCase() === newAddress.toLowerCase());
323
+ this.setSelectedAccount(newAccount.id);
324
+ }, _AccountsController_registerMessageHandlers = function _AccountsController_registerMessageHandlers() {
325
+ this.messagingSystem.registerActionHandler(`${controllerName}:setSelectedAccount`, this.setSelectedAccount.bind(this));
326
+ this.messagingSystem.registerActionHandler(`${controllerName}:listAccounts`, this.listAccounts.bind(this));
327
+ this.messagingSystem.registerActionHandler(`${controllerName}:setAccountName`, this.setAccountName.bind(this));
328
+ this.messagingSystem.registerActionHandler(`${controllerName}:updateAccounts`, this.updateAccounts.bind(this));
329
+ };
330
+ /**
331
+ * Returns the name of the keyring type.
332
+ *
333
+ * @param keyringType - The type of the keyring.
334
+ * @returns The name of the keyring type.
335
+ */
336
+ function keyringTypeToName(keyringType) {
337
+ switch (keyringType) {
338
+ case 'Simple Key Pair': {
339
+ return 'Account';
340
+ }
341
+ case 'HD Key Tree': {
342
+ return 'Account';
343
+ }
344
+ case 'Trezor Hardware': {
345
+ return 'Trezor';
346
+ }
347
+ case 'Ledger Hardware': {
348
+ return 'Ledger';
349
+ }
350
+ case 'Lattice Hardware': {
351
+ return 'Lattice';
352
+ }
353
+ case 'QR Hardware Wallet Device': {
354
+ return 'QR';
355
+ }
356
+ case 'Snap Keyring': {
357
+ return 'Snap Account';
358
+ }
359
+ case 'Custody': {
360
+ return 'Custody';
361
+ }
362
+ default: {
363
+ throw new Error(`Unknown keyring ${keyringType}`);
364
+ }
365
+ }
366
+ }
367
+ exports.keyringTypeToName = keyringTypeToName;
368
+ //# sourceMappingURL=AccountsController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountsController.js","sourceRoot":"","sources":["../src/AccountsController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseControllerV2 } from '@metamask/base-controller';\nimport { SnapKeyring } from '@metamask/eth-snap-keyring';\nimport type { InternalAccount } from '@metamask/keyring-api';\nimport { EthAccountType } from '@metamask/keyring-api';\nimport type {\n KeyringControllerState,\n KeyringControllerEvents,\n KeyringControllerGetKeyringForAccountAction,\n KeyringControllerGetKeyringsByTypeAction,\n KeyringControllerGetAccountsAction,\n} from '@metamask/keyring-controller';\nimport type {\n SnapControllerEvents,\n SnapControllerState,\n} from '@metamask/snaps-controllers';\nimport type { Keyring, Json } from '@metamask/utils';\nimport { sha256FromString } from 'ethereumjs-util';\nimport type { Patch } from 'immer';\nimport { v4 as uuid } from 'uuid';\n\nconst controllerName = 'AccountsController';\n\nexport type AccountsControllerState = {\n internalAccounts: {\n accounts: Record<string, InternalAccount>;\n selectedAccount: string; // id of the selected account\n };\n};\n\nexport type AccountsControllerGetStateAction = {\n type: `${typeof controllerName}:getState`;\n handler: () => AccountsControllerState;\n};\n\nexport type AccountsControllerSetSelectedAccount = {\n type: `${typeof controllerName}:setSelectedAccount`;\n handler: AccountsController['setSelectedAccount'];\n};\n\nexport type AccountsControllerSetAccountName = {\n type: `${typeof controllerName}:setAccountName`;\n handler: AccountsController['setAccountName'];\n};\n\nexport type AccountsControllerListAccounts = {\n type: `${typeof controllerName}:listAccounts`;\n handler: AccountsController['listAccounts'];\n};\n\nexport type AccountsControllerUpdateAccounts = {\n type: `${typeof controllerName}:updateAccounts`;\n handler: AccountsController['updateAccounts'];\n};\n\nexport type AccountsControllerActions =\n | AccountsControllerGetStateAction\n | AccountsControllerSetSelectedAccount\n | AccountsControllerListAccounts\n | AccountsControllerSetAccountName\n | AccountsControllerUpdateAccounts\n | KeyringControllerGetKeyringForAccountAction\n | KeyringControllerGetKeyringsByTypeAction\n | KeyringControllerGetAccountsAction;\n\nexport type AccountsControllerChangeEvent = {\n type: `${typeof controllerName}:stateChange`;\n payload: [AccountsControllerState, Patch[]];\n};\n\nexport type AccountsControllerSelectedAccountChangeEvent = {\n type: `${typeof controllerName}:selectedAccountChange`;\n payload: [InternalAccount];\n};\n\nexport type AccountsControllerEvents =\n | AccountsControllerChangeEvent\n | AccountsControllerSelectedAccountChangeEvent\n | SnapControllerEvents\n | KeyringControllerEvents;\n\nexport type AccountsControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AccountsControllerActions,\n AccountsControllerEvents,\n string,\n string\n>;\n\nconst accountsControllerMetadata = {\n internalAccounts: {\n persist: true,\n anonymous: false,\n },\n selectedAccount: {\n persist: true,\n anonymous: false,\n },\n};\n\nconst defaultState: AccountsControllerState = {\n internalAccounts: {\n accounts: {},\n selectedAccount: '',\n },\n};\n\n/**\n * Controller that manages internal accounts.\n * The accounts controller is responsible for creating and managing internal accounts.\n * It also provides convenience methods for accessing and updating the internal accounts.\n * The accounts controller also listens for keyring state changes and updates the internal accounts accordingly.\n * The accounts controller also listens for snap state changes and updates the internal accounts accordingly.\n *\n */\nexport class AccountsController extends BaseControllerV2<\n typeof controllerName,\n AccountsControllerState,\n AccountsControllerMessenger\n> {\n keyringApiEnabled: boolean;\n\n /**\n * Constructor for AccountsController.\n *\n * @param options - The controller options.\n * @param options.messenger - The messenger object.\n * @param options.state - Initial state to set on this controller\n * @param [options.keyringApiEnabled] - The keyring API enabled flag.\n */\n constructor({\n messenger,\n state,\n keyringApiEnabled,\n }: {\n messenger: AccountsControllerMessenger;\n state: AccountsControllerState;\n keyringApiEnabled?: boolean;\n }) {\n super({\n messenger,\n name: controllerName,\n metadata: accountsControllerMetadata,\n state: {\n ...defaultState,\n ...state,\n },\n });\n\n this.keyringApiEnabled = Boolean(keyringApiEnabled);\n\n if (this.keyringApiEnabled) {\n this.messagingSystem.subscribe(\n 'SnapController:stateChange',\n async (snapStateState) =>\n await this.#handleOnSnapStateChange(snapStateState),\n );\n }\n\n this.messagingSystem.subscribe(\n 'KeyringController:stateChange',\n async (keyringState) =>\n await this.#handleOnKeyringStateChange(keyringState),\n );\n\n this.#registerMessageHandlers();\n\n // if somehow the selected account becomes lost then select the first account\n if (\n this.state.internalAccounts.selectedAccount !== '' &&\n !this.getAccount(this.state.internalAccounts.selectedAccount) &&\n this.listAccounts().length > 0\n ) {\n this.setSelectedAccount(this.listAccounts()[0].id);\n }\n }\n\n /**\n * Returns the internal account object for the given account ID, if it exists.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object, or undefined if the account does not exist.\n */\n getAccount(accountId: string): InternalAccount | undefined {\n return this.state.internalAccounts.accounts[accountId];\n }\n\n /**\n * Returns an array of all internal accounts.\n *\n * @returns An array of InternalAccount objects.\n */\n listAccounts(): InternalAccount[] {\n return Object.values(this.state.internalAccounts.accounts);\n }\n\n /**\n * Returns the internal account object for the given account ID.\n *\n * @param accountId - The ID of the account to retrieve.\n * @returns The internal account object.\n * @throws An error if the account ID is not found.\n */\n getAccountExpect(accountId: string): InternalAccount {\n // Edge case where the extension is setup but the srp is not yet created\n // certain ui elements will query the selected address before any accounts are created.\n if (!accountId) {\n return {\n id: '',\n address: '',\n options: {},\n methods: [],\n type: EthAccountType.Eoa,\n metadata: {\n name: '',\n keyring: {\n type: '',\n },\n },\n };\n }\n\n const account = this.getAccount(accountId);\n if (account === undefined) {\n throw new Error(`Account Id ${accountId} not found`);\n }\n return account;\n }\n\n /**\n * Returns the selected internal account.\n *\n * @returns The selected internal account.\n */\n getSelectedAccount(): InternalAccount {\n return this.getAccountExpect(this.state.internalAccounts.selectedAccount);\n }\n\n /**\n * Sets the selected account by its ID.\n *\n * @param accountId - The ID of the account to be selected.\n */\n setSelectedAccount(accountId: string): void {\n const account = this.getAccountExpect(accountId);\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Type instantiation is excessively deep and possibly infinite.\n this.update((currentState: AccountsControllerState) => {\n currentState.internalAccounts.accounts[account.id].metadata.lastSelected =\n Date.now();\n currentState.internalAccounts.selectedAccount = account.id;\n });\n\n this.messagingSystem.publish(`${this.name}:selectedAccountChange`, account);\n }\n\n /**\n * Sets the name of the account with the given ID.\n *\n * @param accountId - The ID of the account to set the name for.\n * @param accountName - The new name for the account.\n * @throws An error if an account with the same name already exists.\n */\n setAccountName(accountId: string, accountName: string): void {\n const account = this.getAccountExpect(accountId);\n\n if (\n this.listAccounts().find(\n (internalAccount) =>\n internalAccount.metadata.name === accountName &&\n internalAccount.id !== accountId,\n )\n ) {\n throw new Error('Account name already exists');\n }\n\n this.update((currentState: AccountsControllerState) => {\n currentState.internalAccounts.accounts[accountId] = {\n ...account,\n metadata: {\n ...account.metadata,\n name: accountName,\n },\n };\n });\n }\n\n /**\n * Updates the internal accounts list by retrieving normal and snap accounts,\n * removing duplicates, and updating the metadata of each account.\n *\n * @returns A Promise that resolves when the accounts have been updated.\n */\n async updateAccounts(): Promise<void> {\n let normalAccounts = await this.#listNormalAccounts();\n let snapAccounts: InternalAccount[] = [];\n if (this.keyringApiEnabled) {\n snapAccounts = await this.#listSnapAccounts();\n // remove duplicate accounts that are retrieved from the snap keyring.\n normalAccounts = normalAccounts.filter(\n (account) =>\n !snapAccounts.find(\n (snapAccount) => snapAccount.address === account.address,\n ),\n );\n }\n\n // keyring type map.\n const keyringTypes = new Map<string, number>();\n const previousAccounts = this.state.internalAccounts.accounts;\n\n const accounts: Record<string, InternalAccount> = [\n ...normalAccounts,\n ...snapAccounts,\n ].reduce((internalAccountMap, internalAccount) => {\n const keyringTypeName = keyringTypeToName(\n internalAccount.metadata.keyring.type,\n );\n const keyringAccountIndex = keyringTypes.get(keyringTypeName) ?? 0;\n if (keyringAccountIndex) {\n keyringTypes.set(keyringTypeName, keyringAccountIndex + 1);\n } else {\n keyringTypes.set(keyringTypeName, 1);\n }\n\n const existingAccount = previousAccounts[internalAccount.id];\n\n internalAccountMap[internalAccount.id] = {\n ...internalAccount,\n\n metadata: {\n ...internalAccount.metadata,\n name:\n existingAccount && existingAccount.metadata.name !== ''\n ? existingAccount.metadata.name\n : `${keyringTypeName} ${keyringAccountIndex + 1}`,\n lastSelected: existingAccount?.metadata?.lastSelected,\n },\n };\n\n return internalAccountMap;\n }, {} as Record<string, InternalAccount>);\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Type instantiation is excessively deep and possibly infinite.\n this.update((currentState: AccountsControllerState) => {\n currentState.internalAccounts.accounts = accounts;\n });\n }\n\n /**\n * Loads the backup state of the accounts controller.\n *\n * @param backup - The backup state to load.\n */\n loadBackup(backup: AccountsControllerState): void {\n if (backup.internalAccounts) {\n this.update((currentState: AccountsControllerState) => {\n currentState.internalAccounts = backup.internalAccounts;\n });\n }\n }\n\n /**\n * Returns a list of internal accounts created using the SnapKeyring.\n *\n * @returns A promise that resolves to an array of InternalAccount objects.\n */\n async #listSnapAccounts(): Promise<InternalAccount[]> {\n const [snapKeyring] = await this.messagingSystem.call(\n 'KeyringController:getKeyringsByType',\n SnapKeyring.type,\n );\n // snap keyring is not available until the first account is created in the keyring controller\n if (!snapKeyring) {\n return [];\n }\n\n const snapAccounts = await (snapKeyring as SnapKeyring).listAccounts();\n\n return snapAccounts;\n }\n\n /**\n * Returns a list of normal accounts.\n * Note: listNormalAccounts is a temporary method until the keyrings all implement the InternalAccount interface.\n * Once all keyrings implement the InternalAccount interface, this method can be removed and getAccounts can be used instead.\n *\n * @returns A Promise that resolves to an array of InternalAccount objects.\n */\n async #listNormalAccounts(): Promise<InternalAccount[]> {\n const addresses = await this.messagingSystem.call(\n 'KeyringController:getAccounts',\n );\n const internalAccounts: InternalAccount[] = [];\n for (const address of addresses) {\n const keyring = await this.messagingSystem.call(\n 'KeyringController:getKeyringForAccount',\n address,\n );\n const v4options = {\n random: sha256FromString(address).slice(0, 16),\n };\n\n internalAccounts.push({\n id: uuid(v4options),\n address,\n options: {},\n methods: [\n 'personal_sign',\n 'eth_sign',\n 'eth_signTransaction',\n 'eth_signTypedData_v1',\n 'eth_signTypedData_v3',\n 'eth_signTypedData_v4',\n ],\n type: EthAccountType.Eoa,\n metadata: {\n name: '',\n keyring: {\n type: (keyring as Keyring<Json>).type,\n },\n },\n });\n }\n\n return internalAccounts.filter(\n (account) => account.metadata.keyring.type !== 'Snap Keyring',\n );\n }\n\n /**\n * Handles the removal of the currently selected account by selecting the previous account in the list.\n */\n #handleSelectedAccountRemoved() {\n const previousAccount = this.listAccounts()\n .filter(\n (account) => account.id !== this.state.internalAccounts.selectedAccount,\n )\n .sort((accountA, accountB) => {\n // sort by lastSelected descending\n return (\n (accountB.metadata.lastSelected ?? 0) -\n (accountA.metadata.lastSelected ?? 0)\n );\n })[0];\n\n this.setSelectedAccount(previousAccount.id);\n }\n\n /**\n * Handles changes in the keyring state, specifically when new accounts are added or removed.\n *\n * @param keyringState - The new state of the keyring controller.\n * @returns A Promise that resolves when the function has finished executing.\n */\n async #handleOnKeyringStateChange(\n keyringState: KeyringControllerState,\n ): Promise<void> {\n // check if there are any new accounts added\n // TODO: change when accountAdded event is added to the keyring controller\n\n if (keyringState.isUnlocked) {\n // TODO: ACCOUNTS_CONTROLLER keyring will return accounts instead of addresses, remove this flatMap after and just get the latest id\n const updatedKeyringAddresses = keyringState.keyrings.flatMap(\n (keyring) => keyring.accounts,\n );\n const previousAccounts = this.listAccounts();\n\n // if there are no overlaps between the addresses in the keyring and previous accounts,\n // it means the keyring is being reinitialized because the vault is being restored with the same SRP\n const overlaps = updatedKeyringAddresses.filter((address) =>\n previousAccounts.find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n ),\n );\n\n await this.updateAccounts();\n\n if (updatedKeyringAddresses.length > previousAccounts.length) {\n this.#handleNewAccountAdded(updatedKeyringAddresses, previousAccounts);\n } else if (updatedKeyringAddresses.length > 0 && overlaps.length === 0) {\n // if the keyring is being reinitialized, the selected account will be reset to the first account\n this.setSelectedAccount(this.listAccounts()[0].id);\n } else if (\n updatedKeyringAddresses.length < previousAccounts.length &&\n overlaps.length > 0 &&\n !this.getAccount(this.state.internalAccounts.selectedAccount)\n ) {\n this.#handleSelectedAccountRemoved();\n }\n }\n }\n\n /**\n * Handles the change in SnapControllerState by updating the metadata of accounts that have a snap enabled.\n *\n * @param snapState - The new SnapControllerState.\n * @returns A Promise that resolves when the update is complete.\n */\n async #handleOnSnapStateChange(\n snapState: SnapControllerState,\n ): Promise<void> {\n // only check if snaps changed in status\n const { snaps } = snapState;\n const accounts = this.listAccounts().filter(\n (account) => account.metadata.snap,\n );\n\n this.update((currentState: AccountsControllerState) => {\n accounts.forEach((account) => {\n const currentAccount =\n currentState.internalAccounts.accounts[account.id];\n if (currentAccount.metadata.snap) {\n currentAccount.metadata.snap.enabled =\n snaps[currentAccount.metadata.snap.id].enabled &&\n !snaps[currentAccount.metadata.snap.id].blocked;\n }\n });\n });\n }\n\n /**\n * Handles the event when a new account is added to the keyring.\n *\n * @param updatedKeyringAddresses - An array of updated keyring addresses.\n * @param previousAccounts - An array of previous internal accounts.\n */\n #handleNewAccountAdded(\n updatedKeyringAddresses: string[],\n previousAccounts: InternalAccount[],\n ) {\n const [newAddress] = updatedKeyringAddresses.filter(\n (address) =>\n !previousAccounts.find(\n (account) => account.address.toLowerCase() === address.toLowerCase(),\n ),\n );\n\n const [newAccount] = this.listAccounts().filter(\n (account) => account.address.toLowerCase() === newAddress.toLowerCase(),\n );\n\n this.setSelectedAccount(newAccount.id);\n }\n\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setSelectedAccount`,\n this.setSelectedAccount.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:listAccounts`,\n this.listAccounts.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:setAccountName`,\n this.setAccountName.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateAccounts`,\n this.updateAccounts.bind(this),\n );\n }\n}\n\n/**\n * Returns the name of the keyring type.\n *\n * @param keyringType - The type of the keyring.\n * @returns The name of the keyring type.\n */\nexport function keyringTypeToName(keyringType: string): string {\n switch (keyringType) {\n case 'Simple Key Pair': {\n return 'Account';\n }\n case 'HD Key Tree': {\n return 'Account';\n }\n case 'Trezor Hardware': {\n return 'Trezor';\n }\n case 'Ledger Hardware': {\n return 'Ledger';\n }\n case 'Lattice Hardware': {\n return 'Lattice';\n }\n case 'QR Hardware Wallet Device': {\n return 'QR';\n }\n case 'Snap Keyring': {\n return 'Snap Account';\n }\n case 'Custody': {\n return 'Custody';\n }\n default: {\n throw new Error(`Unknown keyring ${keyringType}`);\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './AccountsController';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./AccountsController"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC","sourcesContent":["export * from './AccountsController';\n"]}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@metamask/accounts-controller",
3
+ "version": "1.0.0",
4
+ "description": "Manages internal accounts",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Ethereum"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/core/tree/main/packages/accounts-controller#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/core/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/core.git"
16
+ },
17
+ "license": "MIT",
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist/"
22
+ ],
23
+ "scripts": {
24
+ "build:docs": "typedoc",
25
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/accounts-controller",
26
+ "publish:preview": "yarn npm publish --tag preview",
27
+ "test": "jest",
28
+ "test:watch": "jest --watch"
29
+ },
30
+ "dependencies": {
31
+ "@metamask/base-controller": "^3.2.1",
32
+ "@metamask/eth-snap-keyring": "^0.2.2",
33
+ "@metamask/keyring-api": "^0.2.5",
34
+ "@metamask/snaps-utils": "^1.0.1",
35
+ "@metamask/utils": "^6.2.0",
36
+ "deepmerge": "^4.2.2",
37
+ "eth-rpc-errors": "^4.0.2",
38
+ "ethereumjs-util": "^7.0.10",
39
+ "immer": "^9.0.6",
40
+ "nanoid": "^3.1.31",
41
+ "uuid": "^8.3.2"
42
+ },
43
+ "devDependencies": {
44
+ "@metamask/auto-changelog": "^3.1.0",
45
+ "@metamask/keyring-controller": "^7.5.0",
46
+ "@metamask/snaps-controllers": "^1.0.1",
47
+ "@types/jest": "^27.4.1",
48
+ "@types/readable-stream": "^2.3.0",
49
+ "jest": "^27.5.1",
50
+ "ts-jest": "^27.1.4",
51
+ "typedoc": "^0.22.15",
52
+ "typedoc-plugin-missing-exports": "^0.22.6",
53
+ "typescript": "~4.6.3"
54
+ },
55
+ "peerDependencies": {
56
+ "@metamask/keyring-controller": "^7.5.0"
57
+ },
58
+ "engines": {
59
+ "node": ">=16.0.0"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "registry": "https://registry.npmjs.org/"
64
+ }
65
+ }