Skip to content

Commit 8bf4c2a

Browse files
feat: use withKeyring to get notification accounts for main keyring (#5459)
## Explanation For notification settings, we only want to fetch accounts that our on the main keyring. ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> ## Changelog <!-- If you're making any consumer-facing changes, list those changes here as if you were updating a changelog, using the template below as a guide. (CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or FIXED. For security-related issues, follow the Security Advisory process.) Please take care to name the exact pieces of the API you've added or changed (e.g. types, interfaces, functions, or methods). If there are any breaking changes, make sure to offer a solution for consumers to follow once they upgrade to the changes. Finally, if you're only making changes to development scripts or tests, you may replace the template below with "None". --> ### `@metamask/notification-services-controller` - **CHANGED**: Replaced `KeyringController:getAccounts` with `KeyringController:withKeyring` ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've highlighted breaking changes using the "BREAKING" category above as appropriate - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent dc7db83 commit 8bf4c2a

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

packages/notification-services-controller/src/NotificationServicesController/NotificationServicesController.test.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ describe('metamask-notifications - constructor()', () => {
110110
});
111111

112112
it('keyring Change Event but feature not enabled will not add or remove triggers', async () => {
113-
const { messenger, globalMessenger, mockListAccounts } = arrangeMocks();
113+
const { messenger, globalMessenger, mockWithKeyring } = arrangeMocks();
114114

115115
// initialize controller with 1 address
116-
mockListAccounts.mockResolvedValueOnce([ADDRESS_1]);
116+
mockWithKeyring.mockResolvedValueOnce([ADDRESS_1]);
117117
const controller = new NotificationServicesController({
118118
messenger,
119119
env: { featureAnnouncements: featureAnnouncementsEnv },
@@ -127,15 +127,15 @@ describe('metamask-notifications - constructor()', () => {
127127
.mockResolvedValue({} as UserStorage);
128128

129129
// listAccounts has a new address
130-
mockListAccounts.mockResolvedValueOnce([ADDRESS_1, ADDRESS_2]);
130+
mockWithKeyring.mockResolvedValueOnce([ADDRESS_1, ADDRESS_2]);
131131
await actPublishKeyringStateChange(globalMessenger);
132132

133133
expect(mockUpdate).not.toHaveBeenCalled();
134134
expect(mockDelete).not.toHaveBeenCalled();
135135
});
136136

137137
it('keyring Change Event with new triggers will update triggers correctly', async () => {
138-
const { messenger, globalMessenger, mockListAccounts } = arrangeMocks();
138+
const { messenger, globalMessenger, mockWithKeyring } = arrangeMocks();
139139

140140
// initialize controller with 1 address
141141
const controller = new NotificationServicesController({
@@ -155,7 +155,7 @@ describe('metamask-notifications - constructor()', () => {
155155
.mockResolvedValue({} as UserStorage);
156156

157157
const act = async (addresses: string[], assertion: () => void) => {
158-
mockListAccounts.mockResolvedValueOnce(addresses);
158+
mockWithKeyring.mockResolvedValueOnce(addresses);
159159
await actPublishKeyringStateChange(globalMessenger);
160160
await waitFor(() => {
161161
assertion();
@@ -184,9 +184,9 @@ describe('metamask-notifications - constructor()', () => {
184184
expect(mockDelete).toHaveBeenCalled();
185185
});
186186

187-
// If the address is added back to the list, because it is seen we won't update
187+
// If the address is added back to the list, we will perform an update
188188
await act([ADDRESS_1, ADDRESS_2], () => {
189-
expect(mockUpdate).not.toHaveBeenCalled();
189+
expect(mockUpdate).toHaveBeenCalled();
190190
expect(mockDelete).not.toHaveBeenCalled();
191191
});
192192
});
@@ -300,42 +300,43 @@ describe('metamask-notifications - constructor()', () => {
300300
};
301301

302302
it('should initialse accounts to track notifications on', async () => {
303-
const { mockListAccounts } =
303+
const { mockWithKeyring } =
304304
arrangeActInitialiseNotificationAccountTracking();
305305
await waitFor(() => {
306-
expect(mockListAccounts).toHaveBeenCalled();
306+
expect(mockWithKeyring).toHaveBeenCalled();
307307
});
308308
});
309309

310310
it('should not initialise accounts if wallet is locked', async () => {
311-
const { mockListAccounts } =
312-
arrangeActInitialiseNotificationAccountTracking((mocks) => {
311+
const { mockWithKeyring } = arrangeActInitialiseNotificationAccountTracking(
312+
(mocks) => {
313313
mocks.mockKeyringControllerGetState.mockReturnValue({
314314
isUnlocked: false,
315315
} as MockVar);
316-
});
316+
},
317+
);
317318
await waitFor(() => {
318-
expect(mockListAccounts).not.toHaveBeenCalled();
319+
expect(mockWithKeyring).not.toHaveBeenCalled();
319320
});
320321
});
321322

322323
it('should re-initialise if the wallet was locked, and then unlocked', async () => {
323324
// Test Wallet Locked
324-
const { globalMessenger, mockListAccounts } =
325+
const { globalMessenger, mockWithKeyring } =
325326
arrangeActInitialiseNotificationAccountTracking((mocks) => {
326327
mocks.mockKeyringControllerGetState.mockReturnValue({
327328
isUnlocked: false,
328329
} as MockVar);
329330
});
330331
await waitFor(() => {
331-
expect(mockListAccounts).not.toHaveBeenCalled();
332+
expect(mockWithKeyring).not.toHaveBeenCalled();
332333
});
333334

334335
// Test Wallet Unlock
335336
jest.clearAllMocks();
336337
globalMessenger.publish('KeyringController:unlock');
337338
await waitFor(() => {
338-
expect(mockListAccounts).toHaveBeenCalled();
339+
expect(mockWithKeyring).toHaveBeenCalled();
339340
});
340341
});
341342
});
@@ -927,7 +928,7 @@ describe('metamask-notifications - enableMetamaskNotifications()', () => {
927928

928929
it('should sign a user in if not already signed in', async () => {
929930
const mocks = arrangeMocks();
930-
mocks.mockListAccounts.mockResolvedValue([ADDRESS_1]);
931+
mocks.mockWithKeyring.mockResolvedValue([ADDRESS_1]);
931932
mocks.mockIsSignedIn.mockReturnValue(false); // mock that auth is not enabled
932933
const controller = new NotificationServicesController({
933934
messenger: mocks.messenger,
@@ -943,7 +944,7 @@ describe('metamask-notifications - enableMetamaskNotifications()', () => {
943944

944945
it('create new notifications when switched on and no new notifications', async () => {
945946
const mocks = arrangeMocks();
946-
mocks.mockListAccounts.mockResolvedValue([ADDRESS_1]);
947+
mocks.mockWithKeyring.mockResolvedValue([ADDRESS_1]);
947948
const controller = new NotificationServicesController({
948949
messenger: mocks.messenger,
949950
env: { featureAnnouncements: featureAnnouncementsEnv },
@@ -966,7 +967,7 @@ describe('metamask-notifications - enableMetamaskNotifications()', () => {
966967

967968
it('not create new notifications when enabling an account already in storage', async () => {
968969
const mocks = arrangeMocks();
969-
mocks.mockListAccounts.mockResolvedValue([ADDRESS_1]);
970+
mocks.mockWithKeyring.mockResolvedValue([ADDRESS_1]);
970971
const userStorage = createMockFullUserStorage({ address: ADDRESS_1 });
971972
mocks.mockPerformGetStorage.mockResolvedValue(JSON.stringify(userStorage));
972973
const controller = new NotificationServicesController({
@@ -1153,7 +1154,7 @@ function mockNotificationMessenger() {
11531154
const messenger = globalMessenger.getRestricted({
11541155
name: 'NotificationServicesController',
11551156
allowedActions: [
1156-
'KeyringController:getAccounts',
1157+
'KeyringController:withKeyring',
11571158
'KeyringController:getState',
11581159
'AuthenticationController:getBearerToken',
11591160
'AuthenticationController:isSignedIn',
@@ -1175,7 +1176,7 @@ function mockNotificationMessenger() {
11751176
],
11761177
});
11771178

1178-
const mockListAccounts =
1179+
const mockWithKeyring =
11791180
typedMockAction<KeyringControllerGetAccountsAction>().mockResolvedValue([]);
11801181

11811182
const mockGetBearerToken =
@@ -1230,8 +1231,8 @@ function mockNotificationMessenger() {
12301231
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12311232
const [, ...params]: any[] = args;
12321233

1233-
if (actionType === 'KeyringController:getAccounts') {
1234-
return mockListAccounts();
1234+
if (actionType === 'KeyringController:withKeyring') {
1235+
return mockWithKeyring();
12351236
}
12361237

12371238
if (actionType === 'KeyringController:getState') {
@@ -1299,7 +1300,7 @@ function mockNotificationMessenger() {
12991300
return {
13001301
globalMessenger,
13011302
messenger,
1302-
mockListAccounts,
1303+
mockWithKeyring,
13031304
mockGetBearerToken,
13041305
mockIsSignedIn,
13051306
mockAuthPerformSignIn,

packages/notification-services-controller/src/NotificationServicesController/NotificationServicesController.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import {
99
isValidHexAddress,
1010
toChecksumHexAddress,
1111
} from '@metamask/controller-utils';
12-
import type {
13-
KeyringControllerGetAccountsAction,
14-
KeyringControllerStateChangeEvent,
15-
KeyringControllerGetStateAction,
16-
KeyringControllerLockEvent,
17-
KeyringControllerUnlockEvent,
12+
import {
13+
type KeyringControllerStateChangeEvent,
14+
type KeyringControllerGetStateAction,
15+
type KeyringControllerLockEvent,
16+
type KeyringControllerUnlockEvent,
17+
type KeyringControllerWithKeyringAction,
18+
KeyringTypes,
1819
} from '@metamask/keyring-controller';
1920
import type {
2021
AuthenticationController,
@@ -199,7 +200,7 @@ export type Actions =
199200
// Allowed Actions
200201
export type AllowedActions =
201202
// Keyring Controller Requests
202-
| KeyringControllerGetAccountsAction
203+
| KeyringControllerWithKeyringAction
203204
| KeyringControllerGetStateAction
204205
// Auth Controller Requests
205206
| AuthenticationController.AuthenticationControllerGetBearerToken
@@ -408,16 +409,30 @@ export default class NotificationServicesController extends BaseController<
408409
// Flag to ensure we only setup once
409410
isNotificationAccountsSetup: false,
410411

412+
getNotificationAccounts: async () => {
413+
const mainHDWalletAccounts = (await this.messagingSystem.call(
414+
'KeyringController:withKeyring',
415+
{
416+
type: KeyringTypes.hd,
417+
index: 0,
418+
},
419+
async ({ keyring }): Promise<string[]> => {
420+
return await keyring.getAccounts();
421+
},
422+
)) as string[];
423+
424+
return mainHDWalletAccounts;
425+
},
426+
411427
/**
412428
* Used to get list of addresses from keyring (wallet addresses)
413429
*
414430
* @returns addresses removed, added, and latest list of addresses
415431
*/
416432
listAccounts: async () => {
417433
// Get previous and current account sets
418-
const nonChecksumAccounts = await this.messagingSystem.call(
419-
'KeyringController:getAccounts',
420-
);
434+
const nonChecksumAccounts =
435+
await this.#accounts.getNotificationAccounts();
421436
const accounts = nonChecksumAccounts
422437
.map((a) => toChecksumHexAddress(a))
423438
.filter((a) => isValidHexAddress(a));
@@ -442,7 +457,7 @@ export default class NotificationServicesController extends BaseController<
442457

443458
// Update accounts seen
444459
this.update((state) => {
445-
state.subscriptionAccountsSeen = [...prevAccountsSet, ...accountsAdded];
460+
state.subscriptionAccountsSeen = [...currentAccountsSet];
446461
});
447462

448463
return {

0 commit comments

Comments
 (0)