@metamask-previews/notification-services-controller 10.0.0-preview-53749f1 → 10.0.0-preview-e11fb169

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +0 -16
  2. package/dist/NotificationServicesController/NotificationServicesController.cjs +188 -67
  3. package/dist/NotificationServicesController/NotificationServicesController.cjs.map +1 -1
  4. package/dist/NotificationServicesController/NotificationServicesController.d.cts +16 -10
  5. package/dist/NotificationServicesController/NotificationServicesController.d.cts.map +1 -1
  6. package/dist/NotificationServicesController/NotificationServicesController.d.mts +16 -10
  7. package/dist/NotificationServicesController/NotificationServicesController.d.mts.map +1 -1
  8. package/dist/NotificationServicesController/NotificationServicesController.mjs +189 -68
  9. package/dist/NotificationServicesController/NotificationServicesController.mjs.map +1 -1
  10. package/dist/NotificationServicesController/constants/constants.cjs +7 -0
  11. package/dist/NotificationServicesController/constants/constants.cjs.map +1 -0
  12. package/dist/NotificationServicesController/constants/constants.d.cts +3 -0
  13. package/dist/NotificationServicesController/constants/constants.d.cts.map +1 -0
  14. package/dist/NotificationServicesController/constants/constants.d.mts +3 -0
  15. package/dist/NotificationServicesController/constants/constants.d.mts.map +1 -0
  16. package/dist/NotificationServicesController/constants/constants.mjs +4 -0
  17. package/dist/NotificationServicesController/constants/constants.mjs.map +1 -0
  18. package/dist/NotificationServicesController/constants/index.cjs +1 -0
  19. package/dist/NotificationServicesController/constants/index.cjs.map +1 -1
  20. package/dist/NotificationServicesController/constants/index.d.cts +1 -0
  21. package/dist/NotificationServicesController/constants/index.d.cts.map +1 -1
  22. package/dist/NotificationServicesController/constants/index.d.mts +1 -0
  23. package/dist/NotificationServicesController/constants/index.d.mts.map +1 -1
  24. package/dist/NotificationServicesController/constants/index.mjs +1 -0
  25. package/dist/NotificationServicesController/constants/index.mjs.map +1 -1
  26. package/dist/NotificationServicesController/mocks/index.cjs +2 -0
  27. package/dist/NotificationServicesController/mocks/index.cjs.map +1 -1
  28. package/dist/NotificationServicesController/mocks/index.d.cts +2 -0
  29. package/dist/NotificationServicesController/mocks/index.d.cts.map +1 -1
  30. package/dist/NotificationServicesController/mocks/index.d.mts +2 -0
  31. package/dist/NotificationServicesController/mocks/index.d.mts.map +1 -1
  32. package/dist/NotificationServicesController/mocks/index.mjs +2 -0
  33. package/dist/NotificationServicesController/mocks/index.mjs.map +1 -1
  34. package/dist/NotificationServicesController/mocks/mock-notification-trigger.cjs +22 -0
  35. package/dist/NotificationServicesController/mocks/mock-notification-trigger.cjs.map +1 -0
  36. package/dist/NotificationServicesController/mocks/mock-notification-trigger.d.cts +9 -0
  37. package/dist/NotificationServicesController/mocks/mock-notification-trigger.d.cts.map +1 -0
  38. package/dist/NotificationServicesController/mocks/mock-notification-trigger.d.mts +9 -0
  39. package/dist/NotificationServicesController/mocks/mock-notification-trigger.d.mts.map +1 -0
  40. package/dist/NotificationServicesController/mocks/mock-notification-trigger.mjs +18 -0
  41. package/dist/NotificationServicesController/mocks/mock-notification-trigger.mjs.map +1 -0
  42. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.cjs +82 -0
  43. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.cjs.map +1 -0
  44. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.d.cts +35 -0
  45. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.d.cts.map +1 -0
  46. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.d.mts +35 -0
  47. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.d.mts.map +1 -0
  48. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.mjs +76 -0
  49. package/dist/NotificationServicesController/mocks/mock-notification-user-storage.mjs.map +1 -0
  50. package/dist/NotificationServicesController/mocks/mockResponses.cjs +9 -9
  51. package/dist/NotificationServicesController/mocks/mockResponses.cjs.map +1 -1
  52. package/dist/NotificationServicesController/mocks/mockResponses.d.cts +4 -7
  53. package/dist/NotificationServicesController/mocks/mockResponses.d.cts.map +1 -1
  54. package/dist/NotificationServicesController/mocks/mockResponses.d.mts +4 -7
  55. package/dist/NotificationServicesController/mocks/mockResponses.d.mts.map +1 -1
  56. package/dist/NotificationServicesController/mocks/mockResponses.mjs +7 -7
  57. package/dist/NotificationServicesController/mocks/mockResponses.mjs.map +1 -1
  58. package/dist/NotificationServicesController/processors/process-notifications.cjs +1 -4
  59. package/dist/NotificationServicesController/processors/process-notifications.cjs.map +1 -1
  60. package/dist/NotificationServicesController/processors/process-notifications.d.cts +0 -623
  61. package/dist/NotificationServicesController/processors/process-notifications.d.cts.map +1 -1
  62. package/dist/NotificationServicesController/processors/process-notifications.d.mts +0 -623
  63. package/dist/NotificationServicesController/processors/process-notifications.d.mts.map +1 -1
  64. package/dist/NotificationServicesController/processors/process-notifications.mjs +0 -2
  65. package/dist/NotificationServicesController/processors/process-notifications.mjs.map +1 -1
  66. package/dist/NotificationServicesController/services/onchain-notifications.cjs +142 -50
  67. package/dist/NotificationServicesController/services/onchain-notifications.cjs.map +1 -1
  68. package/dist/NotificationServicesController/services/onchain-notifications.d.cts +31 -23
  69. package/dist/NotificationServicesController/services/onchain-notifications.d.cts.map +1 -1
  70. package/dist/NotificationServicesController/services/onchain-notifications.d.mts +31 -23
  71. package/dist/NotificationServicesController/services/onchain-notifications.d.mts.map +1 -1
  72. package/dist/NotificationServicesController/services/onchain-notifications.mjs +139 -48
  73. package/dist/NotificationServicesController/services/onchain-notifications.mjs.map +1 -1
  74. package/dist/NotificationServicesController/types/index.cjs.map +1 -1
  75. package/dist/NotificationServicesController/types/index.d.cts +1 -0
  76. package/dist/NotificationServicesController/types/index.d.cts.map +1 -1
  77. package/dist/NotificationServicesController/types/index.d.mts +1 -0
  78. package/dist/NotificationServicesController/types/index.d.mts.map +1 -1
  79. package/dist/NotificationServicesController/types/index.mjs.map +1 -1
  80. package/dist/NotificationServicesController/types/user-storage/index.cjs +3 -0
  81. package/dist/NotificationServicesController/types/user-storage/index.cjs.map +1 -0
  82. package/dist/NotificationServicesController/types/user-storage/index.d.cts +2 -0
  83. package/dist/NotificationServicesController/types/user-storage/index.d.cts.map +1 -0
  84. package/dist/NotificationServicesController/types/user-storage/index.d.mts +2 -0
  85. package/dist/NotificationServicesController/types/user-storage/index.d.mts.map +1 -0
  86. package/dist/NotificationServicesController/types/user-storage/index.mjs +2 -0
  87. package/dist/NotificationServicesController/types/user-storage/index.mjs.map +1 -0
  88. package/dist/NotificationServicesController/types/user-storage/user-storage.cjs +3 -0
  89. package/dist/NotificationServicesController/types/user-storage/user-storage.cjs.map +1 -0
  90. package/dist/NotificationServicesController/types/user-storage/user-storage.d.cts +26 -0
  91. package/dist/NotificationServicesController/types/user-storage/user-storage.d.cts.map +1 -0
  92. package/dist/NotificationServicesController/types/user-storage/user-storage.d.mts +26 -0
  93. package/dist/NotificationServicesController/types/user-storage/user-storage.d.mts.map +1 -0
  94. package/dist/NotificationServicesController/types/user-storage/user-storage.mjs +2 -0
  95. package/dist/NotificationServicesController/types/user-storage/user-storage.mjs.map +1 -0
  96. package/dist/NotificationServicesController/utils/utils.cjs +350 -1
  97. package/dist/NotificationServicesController/utils/utils.cjs.map +1 -1
  98. package/dist/NotificationServicesController/utils/utils.d.cts +141 -0
  99. package/dist/NotificationServicesController/utils/utils.d.cts.map +1 -1
  100. package/dist/NotificationServicesController/utils/utils.d.mts +141 -0
  101. package/dist/NotificationServicesController/utils/utils.d.mts.map +1 -1
  102. package/dist/NotificationServicesController/utils/utils.mjs +337 -0
  103. package/dist/NotificationServicesController/utils/utils.mjs.map +1 -1
  104. package/dist/NotificationServicesPushController/NotificationServicesPushController.cjs +14 -20
  105. package/dist/NotificationServicesPushController/NotificationServicesPushController.cjs.map +1 -1
  106. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.cts +5 -6
  107. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.cts.map +1 -1
  108. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.mts +5 -6
  109. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.mts.map +1 -1
  110. package/dist/NotificationServicesPushController/NotificationServicesPushController.mjs +15 -21
  111. package/dist/NotificationServicesPushController/NotificationServicesPushController.mjs.map +1 -1
  112. package/dist/NotificationServicesPushController/mocks/mockResponse.cjs +16 -1
  113. package/dist/NotificationServicesPushController/mocks/mockResponse.cjs.map +1 -1
  114. package/dist/NotificationServicesPushController/mocks/mockResponse.d.cts +7 -0
  115. package/dist/NotificationServicesPushController/mocks/mockResponse.d.cts.map +1 -1
  116. package/dist/NotificationServicesPushController/mocks/mockResponse.d.mts +7 -0
  117. package/dist/NotificationServicesPushController/mocks/mockResponse.d.mts.map +1 -1
  118. package/dist/NotificationServicesPushController/mocks/mockResponse.mjs +14 -0
  119. package/dist/NotificationServicesPushController/mocks/mockResponse.mjs.map +1 -1
  120. package/dist/NotificationServicesPushController/services/endpoints.cjs +1 -1
  121. package/dist/NotificationServicesPushController/services/endpoints.cjs.map +1 -1
  122. package/dist/NotificationServicesPushController/services/endpoints.d.cts +1 -1
  123. package/dist/NotificationServicesPushController/services/endpoints.d.cts.map +1 -1
  124. package/dist/NotificationServicesPushController/services/endpoints.d.mts +1 -1
  125. package/dist/NotificationServicesPushController/services/endpoints.d.mts.map +1 -1
  126. package/dist/NotificationServicesPushController/services/endpoints.mjs +1 -1
  127. package/dist/NotificationServicesPushController/services/endpoints.mjs.map +1 -1
  128. package/dist/NotificationServicesPushController/services/services.cjs +41 -18
  129. package/dist/NotificationServicesPushController/services/services.cjs.map +1 -1
  130. package/dist/NotificationServicesPushController/services/services.d.cts +33 -19
  131. package/dist/NotificationServicesPushController/services/services.d.cts.map +1 -1
  132. package/dist/NotificationServicesPushController/services/services.d.mts +33 -19
  133. package/dist/NotificationServicesPushController/services/services.d.mts.map +1 -1
  134. package/dist/NotificationServicesPushController/services/services.mjs +39 -17
  135. package/dist/NotificationServicesPushController/services/services.mjs.map +1 -1
  136. package/package.json +1 -1
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  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");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _NotificationServicesController_instances, _NotificationServicesController_keyringController, _NotificationServicesController_auth, _NotificationServicesController_pushNotifications, _NotificationServicesController_accounts, _NotificationServicesController_featureAnnouncementEnv, _NotificationServicesController_registerMessageHandlers, _NotificationServicesController_clearLoadingStates, _NotificationServicesController_assertAuthEnabled, _NotificationServicesController_enableAuth, _NotificationServicesController_getBearerToken, _NotificationServicesController_setIsUpdatingMetamaskNotifications, _NotificationServicesController_setIsFetchingMetamaskNotifications, _NotificationServicesController_setIsCheckingAccountsPresence, _NotificationServicesController_updateUpdatingAccountsState, _NotificationServicesController_clearUpdatingAccountsState;
12
+ var _NotificationServicesController_instances, _NotificationServicesController_keyringController, _NotificationServicesController_auth, _NotificationServicesController_storage, _NotificationServicesController_pushNotifications, _NotificationServicesController_accounts, _NotificationServicesController_featureAnnouncementEnv, _NotificationServicesController_registerMessageHandlers, _NotificationServicesController_clearLoadingStates, _NotificationServicesController_assertAuthEnabled, _NotificationServicesController_enableAuth, _NotificationServicesController_getValidStorageKeyAndBearerToken, _NotificationServicesController_assertUserStorage, _NotificationServicesController_getUserStorage, _NotificationServicesController_setIsUpdatingMetamaskNotifications, _NotificationServicesController_setIsFetchingMetamaskNotifications, _NotificationServicesController_setIsCheckingAccountsPresence, _NotificationServicesController_updateUpdatingAccountsState, _NotificationServicesController_clearUpdatingAccountsState;
13
13
  function $importDefault(module) {
14
14
  if (module?.__esModule) {
15
15
  return module.default;
@@ -22,10 +22,12 @@ import { KeyringTypes } from "@metamask/keyring-controller";
22
22
  import { assert } from "@metamask/utils";
23
23
  import $log from "loglevel";
24
24
  const log = $importDefault($log);
25
+ import { USER_STORAGE_VERSION_KEY } from "./constants/constants.mjs";
25
26
  import { TRIGGER_TYPES } from "./constants/notification-schema.mjs";
26
- import { processAndFilterNotifications, safeProcessNotification } from "./processors/process-notifications.mjs";
27
+ import { safeProcessNotification } from "./processors/process-notifications.mjs";
27
28
  import * as FeatureNotifications from "./services/feature-announcements.mjs";
28
29
  import * as OnChainNotifications from "./services/onchain-notifications.mjs";
30
+ import * as Utils from "./utils/utils.mjs";
29
31
  // Unique name for the controller
30
32
  const controllerName = 'NotificationServicesController';
31
33
  const metadata = {
@@ -135,6 +137,17 @@ class NotificationServicesController extends BaseController {
135
137
  return await this.messagingSystem.call('AuthenticationController:performSignIn');
136
138
  },
137
139
  });
140
+ _NotificationServicesController_storage.set(this, {
141
+ getStorageKey: () => {
142
+ return this.messagingSystem.call('UserStorageController:getStorageKey');
143
+ },
144
+ getNotificationStorage: async () => {
145
+ return await this.messagingSystem.call('UserStorageController:performGetStorage', 'notifications.notification_settings');
146
+ },
147
+ setNotificationStorage: async (state) => {
148
+ return await this.messagingSystem.call('UserStorageController:performSetStorage', 'notifications.notification_settings', state);
149
+ },
150
+ });
138
151
  _NotificationServicesController_pushNotifications.set(this, {
139
152
  // Flag to check is notifications have been setup when the browser/extension is initialized.
140
153
  // We want to re-initialize push notifications when the browser/extension is refreshed
@@ -143,9 +156,9 @@ class NotificationServicesController extends BaseController {
143
156
  subscribeToPushNotifications: async () => {
144
157
  await this.messagingSystem.call('NotificationServicesPushController:subscribeToPushNotifications');
145
158
  },
146
- enablePushNotifications: async (addresses) => {
159
+ enablePushNotifications: async (UUIDs) => {
147
160
  try {
148
- await this.messagingSystem.call('NotificationServicesPushController:enablePushNotifications', addresses);
161
+ await this.messagingSystem.call('NotificationServicesPushController:enablePushNotifications', UUIDs);
149
162
  }
150
163
  catch (e) {
151
164
  log.error('Silently failed to enable push notifications', e);
@@ -159,6 +172,14 @@ class NotificationServicesController extends BaseController {
159
172
  log.error('Silently failed to disable push notifications', e);
160
173
  }
161
174
  },
175
+ updatePushNotifications: async (UUIDs) => {
176
+ try {
177
+ await this.messagingSystem.call('NotificationServicesPushController:updateTriggerPushNotifications', UUIDs);
178
+ }
179
+ catch (e) {
180
+ log.error('Silently failed to update push notifications', e);
181
+ }
182
+ },
162
183
  subscribe: () => {
163
184
  this.messagingSystem.subscribe('NotificationServicesPushController:onNewNotifications', (notification) => {
164
185
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
@@ -193,7 +214,7 @@ class NotificationServicesController extends BaseController {
193
214
  _NotificationServicesController_accounts.set(this, {
194
215
  // Flag to ensure we only setup once
195
216
  isNotificationAccountsSetup: false,
196
- getNotificationAccounts: () => {
217
+ getNotificationAccounts: async () => {
197
218
  const { keyrings } = this.messagingSystem.call('KeyringController:getState');
198
219
  const firstHDKeyring = keyrings.find((k) => k.type === KeyringTypes.hd.toString());
199
220
  const keyringAccounts = firstHDKeyring?.accounts ?? null;
@@ -204,9 +225,9 @@ class NotificationServicesController extends BaseController {
204
225
  *
205
226
  * @returns addresses removed, added, and latest list of addresses
206
227
  */
207
- listAccounts: () => {
228
+ listAccounts: async () => {
208
229
  // Get previous and current account sets
209
- const nonChecksumAccounts = __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").getNotificationAccounts();
230
+ const nonChecksumAccounts = await __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").getNotificationAccounts();
210
231
  if (!nonChecksumAccounts) {
211
232
  return {
212
233
  accountsAdded: [],
@@ -243,11 +264,13 @@ class NotificationServicesController extends BaseController {
243
264
  },
244
265
  /**
245
266
  * Initializes the cache/previous list. This is handy so we have an accurate in-mem state of the previous list of accounts.
267
+ *
268
+ * @returns result from list accounts
246
269
  */
247
- initialize: () => {
270
+ initialize: async () => {
248
271
  if (__classPrivateFieldGet(this, _NotificationServicesController_keyringController, "f").isUnlocked &&
249
272
  !__classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").isNotificationAccountsSetup) {
250
- __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
273
+ await __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
251
274
  __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").isNotificationAccountsSetup = true;
252
275
  }
253
276
  },
@@ -263,15 +286,15 @@ class NotificationServicesController extends BaseController {
263
286
  !hasTotalAccountsChanged) {
264
287
  return;
265
288
  }
266
- const { accountsAdded, accountsRemoved } = __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
289
+ const { accountsAdded, accountsRemoved } = await __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
267
290
  const promises = [];
268
291
  if (accountsAdded.length > 0) {
269
- promises.push(this.enableAccounts(accountsAdded));
292
+ promises.push(this.updateOnChainTriggersByAccount(accountsAdded));
270
293
  }
271
294
  if (accountsRemoved.length > 0) {
272
- promises.push(this.disableAccounts(accountsRemoved));
295
+ promises.push(this.deleteOnChainTriggersByAccount(accountsRemoved));
273
296
  }
274
- await Promise.allSettled(promises);
297
+ await Promise.all(promises);
275
298
  }, (state) => {
276
299
  return (state?.keyrings?.flatMap?.((keyring) => keyring.accounts)?.length ??
277
300
  0);
@@ -285,9 +308,10 @@ class NotificationServicesController extends BaseController {
285
308
  }
286
309
  init() {
287
310
  __classPrivateFieldGet(this, _NotificationServicesController_keyringController, "f").setupLockedStateSubscriptions(async () => {
288
- __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").initialize();
311
+ await __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").initialize();
289
312
  await __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").initializePushNotifications();
290
313
  });
314
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
291
315
  __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").initialize();
292
316
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
293
317
  __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").initializePushNotifications();
@@ -298,18 +322,13 @@ class NotificationServicesController extends BaseController {
298
322
  * Public method to expose enabling push notifications
299
323
  */
300
324
  async enablePushNotifications() {
301
- try {
302
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
303
- const { accounts } = __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
304
- const addressesWithNotifications = await OnChainNotifications.getOnChainNotificationsConfig(bearerToken, accounts);
305
- const addresses = addressesWithNotifications.map((a) => a.address);
306
- if (addresses.length > 0) {
307
- await __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").enablePushNotifications(addresses);
308
- }
309
- }
310
- catch (e) {
311
- log.error('Failed to enable push notifications', e);
325
+ await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_enableAuth).call(this);
326
+ const storage = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getUserStorage).call(this);
327
+ if (!storage) {
328
+ throw new Error('Unable to get triggers');
312
329
  }
330
+ const uuids = Utils.getAllUUIDs(storage);
331
+ await __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").enablePushNotifications(uuids);
313
332
  }
314
333
  /**
315
334
  * Public method to expose disabling push notifications
@@ -321,13 +340,10 @@ class NotificationServicesController extends BaseController {
321
340
  try {
322
341
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_setIsCheckingAccountsPresence).call(this, true);
323
342
  // Retrieve user storage
324
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
325
- const addressesWithNotifications = await OnChainNotifications.getOnChainNotificationsConfig(bearerToken, accounts);
326
- const result = {};
327
- addressesWithNotifications.forEach((a) => {
328
- result[a.address] = a.enabled;
329
- });
330
- return result;
343
+ const userStorage = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getUserStorage).call(this);
344
+ __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_assertUserStorage).call(this, userStorage);
345
+ const presence = Utils.checkAccountsPresence(userStorage, accounts);
346
+ return presence;
331
347
  }
332
348
  catch (error) {
333
349
  log.error('Failed to check accounts presence', error);
@@ -371,26 +387,40 @@ class NotificationServicesController extends BaseController {
371
387
  async createOnChainTriggers(opts) {
372
388
  try {
373
389
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_setIsUpdatingMetamaskNotifications).call(this, true);
374
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
375
- const { accounts } = __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
376
- // 1. See if has enabled notifications before
377
- const addressesWithNotifications = await OnChainNotifications.getOnChainNotificationsConfig(bearerToken, accounts);
378
- // Notifications have been enabled before, so returning early
379
- if (addressesWithNotifications.length > 0 && !opts?.resetNotifications) {
380
- return;
390
+ const { bearerToken, storageKey } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getValidStorageKeyAndBearerToken).call(this);
391
+ const { accounts } = await __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
392
+ // Attempt Get User Storage
393
+ // Will be null if entry does not exist, or a user is resetting their notifications
394
+ // Will be defined if entry exists
395
+ // Will throw if fails to get the user storage entry
396
+ let userStorage = opts?.resetNotifications
397
+ ? null
398
+ : await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getUserStorage).call(this);
399
+ // If userStorage does not exist, create a new one
400
+ // All the triggers created are set as: "disabled"
401
+ if (userStorage?.[USER_STORAGE_VERSION_KEY] === undefined) {
402
+ userStorage = Utils.initializeUserStorage(accounts.map((account) => ({ address: account })), false);
403
+ // Write the userStorage
404
+ await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").setNotificationStorage(JSON.stringify(userStorage));
381
405
  }
382
- // 2. Create Notifications
383
- await OnChainNotifications.updateOnChainNotifications(bearerToken, accounts.map((address) => ({ address, enabled: true })));
384
- // 3. Lazily enable push notifications (FCM may take some time, so keeps UI unblocked)
385
- __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").enablePushNotifications(accounts).catch(() => {
406
+ // Create the triggers
407
+ const triggers = Utils.traverseUserStorageTriggers(userStorage);
408
+ await OnChainNotifications.createOnChainTriggers(userStorage, storageKey, bearerToken, triggers);
409
+ // Create push notifications triggers in background
410
+ const allUUIDS = Utils.getAllUUIDs(userStorage);
411
+ // We do not want to wait for this request as it may take a while (e.g. for Firebase to setup)
412
+ __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").enablePushNotifications(allUUIDS).catch(() => {
386
413
  // Do Nothing
387
414
  });
415
+ // Write the new userStorage (triggers are now "enabled")
416
+ await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").setNotificationStorage(JSON.stringify(userStorage));
388
417
  // Update the state of the controller
389
418
  this.update((state) => {
390
419
  state.isNotificationServicesEnabled = true;
391
420
  state.isFeatureAnnouncementsEnabled = true;
392
421
  state.isMetamaskNotificationsFeatureSeen = true;
393
422
  });
423
+ return userStorage;
394
424
  }
395
425
  catch (err) {
396
426
  log.error('Failed to create On Chain triggers', err);
@@ -403,6 +433,10 @@ class NotificationServicesController extends BaseController {
403
433
  /**
404
434
  * Enables all MetaMask notifications for the user.
405
435
  * This is identical flow when initializing notifications for the first time.
436
+ * 1. Enable Profile Syncing
437
+ * 2. Get or Create Notification User Storage
438
+ * 3. Upsert Triggers
439
+ * 4. Update Push notifications
406
440
  *
407
441
  * @throws {Error} If there is an error during the process of enabling notifications.
408
442
  */
@@ -450,11 +484,12 @@ class NotificationServicesController extends BaseController {
450
484
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_setIsUpdatingMetamaskNotifications).call(this, false);
451
485
  }
452
486
  /**
453
- * Deletes on-chain triggers associated with a specific account/s.
487
+ * Deletes on-chain triggers associated with a specific account.
454
488
  * This method performs several key operations:
455
- * 1. Validates Auth
456
- * 2. Deletes accounts
457
- * (note) We do not need to look through push notifications as we've deleted triggers
489
+ * 1. Validates Auth & Storage
490
+ * 2. Finds and deletes all triggers associated with the account
491
+ * 3. Disables any related push notifications
492
+ * 4. Updates Storage to reflect new state.
458
493
  *
459
494
  * **Action** - When a user disables notifications for a given account in settings.
460
495
  *
@@ -462,13 +497,29 @@ class NotificationServicesController extends BaseController {
462
497
  * @returns A promise that resolves to void or an object containing a success message.
463
498
  * @throws {Error} Throws an error if unauthenticated or from other operations.
464
499
  */
465
- async disableAccounts(accounts) {
500
+ async deleteOnChainTriggersByAccount(accounts) {
466
501
  try {
467
502
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_updateUpdatingAccountsState).call(this, accounts);
468
503
  // Get and Validate BearerToken and User Storage Key
469
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
504
+ const { bearerToken, storageKey } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getValidStorageKeyAndBearerToken).call(this);
505
+ // Get & Validate User Storage
506
+ const userStorage = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getUserStorage).call(this);
507
+ __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_assertUserStorage).call(this, userStorage);
508
+ // Get the UUIDs to delete
509
+ const UUIDs = accounts
510
+ .map((a) => Utils.getUUIDsForAccount(userStorage, a.toLowerCase()))
511
+ .flat();
512
+ if (UUIDs.length === 0) {
513
+ return userStorage;
514
+ }
470
515
  // Delete these UUIDs (Mutates User Storage)
471
- await OnChainNotifications.updateOnChainNotifications(bearerToken, accounts.map((address) => ({ address, enabled: false })));
516
+ await OnChainNotifications.deleteOnChainTriggers(userStorage, storageKey, bearerToken, UUIDs);
517
+ // Update Push Notifications with new list of IDs
518
+ const remainingTriggerIds = Utils.getAllUUIDs(userStorage);
519
+ await __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").updatePushNotifications(remainingTriggerIds);
520
+ // Update User Storage
521
+ await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").setNotificationStorage(JSON.stringify(userStorage));
522
+ return userStorage;
472
523
  }
473
524
  catch (err) {
474
525
  log.error('Failed to delete OnChain triggers', err);
@@ -493,11 +544,45 @@ class NotificationServicesController extends BaseController {
493
544
  * @returns A promise that resolves to the updated user storage.
494
545
  * @throws {Error} Throws an error if unauthenticated or from other operations.
495
546
  */
496
- async enableAccounts(accounts) {
547
+ async updateOnChainTriggersByAccount(accounts) {
497
548
  try {
498
549
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_updateUpdatingAccountsState).call(this, accounts);
499
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
500
- await OnChainNotifications.updateOnChainNotifications(bearerToken, accounts.map((address) => ({ address, enabled: true })));
550
+ // Get and Validate BearerToken and User Storage Key
551
+ const { bearerToken, storageKey } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getValidStorageKeyAndBearerToken).call(this);
552
+ // Get & Validate User Storage
553
+ const userStorage = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getUserStorage).call(this);
554
+ __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_assertUserStorage).call(this, userStorage);
555
+ // Add any missing triggers
556
+ accounts.forEach((a) => Utils.upsertAddressTriggers(a, userStorage));
557
+ const newTriggers = Utils.traverseUserStorageTriggers(userStorage, {
558
+ mapTrigger: (t) => {
559
+ if (!t.enabled) {
560
+ return t;
561
+ }
562
+ return undefined;
563
+ },
564
+ });
565
+ // Create any missing triggers.
566
+ if (newTriggers.length > 0) {
567
+ // Write te updated userStorage (where triggers are disabled)
568
+ await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").setNotificationStorage(JSON.stringify(userStorage));
569
+ // Create the triggers
570
+ const triggers = Utils.traverseUserStorageTriggers(userStorage, {
571
+ mapTrigger: (t) => {
572
+ if (accounts.some((a) => a.toLowerCase() === t.address.toLowerCase())) {
573
+ return t;
574
+ }
575
+ return undefined;
576
+ },
577
+ });
578
+ await OnChainNotifications.createOnChainTriggers(userStorage, storageKey, bearerToken, triggers);
579
+ }
580
+ // Update Push Notifications Triggers
581
+ const UUIDs = Utils.getAllUUIDs(userStorage);
582
+ await __classPrivateFieldGet(this, _NotificationServicesController_pushNotifications, "f").updatePushNotifications(UUIDs);
583
+ // Update the userStorage (where triggers are enabled)
584
+ await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").setNotificationStorage(JSON.stringify(userStorage));
585
+ return userStorage;
501
586
  }
502
587
  catch (err) {
503
588
  log.error('Failed to update OnChain triggers', err);
@@ -524,30 +609,37 @@ class NotificationServicesController extends BaseController {
524
609
  // Not used by Snaps
525
610
  const isGlobalNotifsEnabled = this.state.isNotificationServicesEnabled;
526
611
  // Raw Feature Notifications
527
- const rawAnnouncements = isGlobalNotifsEnabled && this.state.isFeatureAnnouncementsEnabled
612
+ const rawFeatureAnnouncementNotifications = isGlobalNotifsEnabled && this.state.isFeatureAnnouncementsEnabled
528
613
  ? await FeatureNotifications.getFeatureAnnouncementNotifications(__classPrivateFieldGet(this, _NotificationServicesController_featureAnnouncementEnv, "f"), previewToken).catch(() => [])
529
614
  : [];
530
615
  // Raw On Chain Notifications
531
616
  const rawOnChainNotifications = [];
532
617
  if (isGlobalNotifsEnabled) {
533
- try {
534
- const { bearerToken } = await __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_getBearerToken).call(this);
535
- const { accounts } = __classPrivateFieldGet(this, _NotificationServicesController_accounts, "f").listAccounts();
536
- const notifications = await OnChainNotifications.getOnChainNotifications(bearerToken, accounts).catch(() => []);
618
+ const userStorage = await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f")
619
+ .getNotificationStorage()
620
+ .then((s) => s && JSON.parse(s))
621
+ .catch(() => null);
622
+ const bearerToken = await __classPrivateFieldGet(this, _NotificationServicesController_auth, "f").getBearerToken().catch(() => null);
623
+ if (userStorage && bearerToken) {
624
+ const notifications = await OnChainNotifications.getOnChainNotifications(userStorage, bearerToken).catch(() => []);
537
625
  rawOnChainNotifications.push(...notifications);
538
626
  }
539
- catch {
540
- // Do nothing
541
- }
542
627
  }
543
628
  // Snap Notifications (original)
544
629
  // We do not want to remove them
545
630
  const snapNotifications = this.state.metamaskNotificationsList.filter((notification) => notification.type === TRIGGER_TYPES.SNAP);
631
+ // Process Notifications
546
632
  const readIds = this.state.metamaskNotificationsReadList;
633
+ const isNotUndefined = (t) => Boolean(t);
634
+ const processAndFilter = (ns) => ns
635
+ .map((n) => safeProcessNotification(n, readIds))
636
+ .filter(isNotUndefined);
637
+ const featureAnnouncementNotifications = processAndFilter(rawFeatureAnnouncementNotifications);
638
+ const onChainNotifications = processAndFilter(rawOnChainNotifications);
547
639
  // Combine Notifications
548
640
  const metamaskNotifications = [
549
- ...processAndFilterNotifications(rawAnnouncements, readIds),
550
- ...processAndFilterNotifications(rawOnChainNotifications, readIds),
641
+ ...featureAnnouncementNotifications,
642
+ ...onChainNotifications,
551
643
  ...snapNotifications,
552
644
  ];
553
645
  // Sort Notifications
@@ -715,7 +807,7 @@ class NotificationServicesController extends BaseController {
715
807
  }
716
808
  }
717
809
  }
718
- _NotificationServicesController_keyringController = new WeakMap(), _NotificationServicesController_auth = new WeakMap(), _NotificationServicesController_pushNotifications = new WeakMap(), _NotificationServicesController_accounts = new WeakMap(), _NotificationServicesController_featureAnnouncementEnv = new WeakMap(), _NotificationServicesController_instances = new WeakSet(), _NotificationServicesController_registerMessageHandlers = function _NotificationServicesController_registerMessageHandlers() {
810
+ _NotificationServicesController_keyringController = new WeakMap(), _NotificationServicesController_auth = new WeakMap(), _NotificationServicesController_storage = new WeakMap(), _NotificationServicesController_pushNotifications = new WeakMap(), _NotificationServicesController_accounts = new WeakMap(), _NotificationServicesController_featureAnnouncementEnv = new WeakMap(), _NotificationServicesController_instances = new WeakSet(), _NotificationServicesController_registerMessageHandlers = function _NotificationServicesController_registerMessageHandlers() {
719
811
  this.messagingSystem.registerActionHandler(`${controllerName}:updateMetamaskNotificationsList`, this.updateMetamaskNotificationsList.bind(this));
720
812
  this.messagingSystem.registerActionHandler(`${controllerName}:disableNotificationServices`, this.disableNotificationServices.bind(this));
721
813
  this.messagingSystem.registerActionHandler(`${controllerName}:getNotificationsByType`, this.getNotificationsByType.bind(this));
@@ -739,13 +831,42 @@ _NotificationServicesController_keyringController = new WeakMap(), _Notification
739
831
  if (!isSignedIn) {
740
832
  await __classPrivateFieldGet(this, _NotificationServicesController_auth, "f").signIn();
741
833
  }
742
- }, _NotificationServicesController_getBearerToken = async function _NotificationServicesController_getBearerToken() {
834
+ }, _NotificationServicesController_getValidStorageKeyAndBearerToken = async function _NotificationServicesController_getValidStorageKeyAndBearerToken() {
743
835
  __classPrivateFieldGet(this, _NotificationServicesController_instances, "m", _NotificationServicesController_assertAuthEnabled).call(this);
744
836
  const bearerToken = await __classPrivateFieldGet(this, _NotificationServicesController_auth, "f").getBearerToken();
745
- if (!bearerToken) {
746
- throw new Error('Missing BearerToken');
837
+ const storageKey = await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").getStorageKey();
838
+ if (!bearerToken || !storageKey) {
839
+ throw new Error('Missing BearerToken or storage key');
840
+ }
841
+ return { bearerToken, storageKey };
842
+ }, _NotificationServicesController_assertUserStorage = function _NotificationServicesController_assertUserStorage(storage) {
843
+ if (!storage) {
844
+ throw new Error('User Storage does not exist');
845
+ }
846
+ }, _NotificationServicesController_getUserStorage =
847
+ /**
848
+ * Retrieves and parses the user storage from the storage key.
849
+ *
850
+ * This method attempts to retrieve the user storage using the specified storage key,
851
+ * then parses the JSON string to an object. If the storage is not found or cannot be parsed,
852
+ * it throws an error.
853
+ *
854
+ * @returns The parsed user storage object or null
855
+ */
856
+ async function _NotificationServicesController_getUserStorage() {
857
+ const userStorageString = await __classPrivateFieldGet(this, _NotificationServicesController_storage, "f").getNotificationStorage();
858
+ if (!userStorageString) {
859
+ return null;
860
+ }
861
+ try {
862
+ const userStorage = JSON.parse(userStorageString);
863
+ Utils.cleanUserStorage(userStorage);
864
+ return userStorage;
865
+ }
866
+ catch {
867
+ log.error('Unable to parse User Storage');
868
+ return null;
747
869
  }
748
- return { bearerToken };
749
870
  }, _NotificationServicesController_setIsUpdatingMetamaskNotifications = function _NotificationServicesController_setIsUpdatingMetamaskNotifications(isUpdatingMetamaskNotifications) {
750
871
  this.update((state) => {
751
872
  state.isUpdatingMetamaskNotifications = isUpdatingMetamaskNotifications;