@metamask-previews/notification-services-controller 29.0.2-preview-247ba396c → 29.0.2-preview-576eebcfe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -7
- package/dist/NotificationServicesController/NotificationServicesController-method-action-types.d.ts +1 -16
- package/dist/NotificationServicesController/NotificationServicesController-method-action-types.d.ts.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController-method-action-types.js.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController.d.ts +2 -24
- package/dist/NotificationServicesController/NotificationServicesController.d.ts.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController.js +1 -58
- package/dist/NotificationServicesController/NotificationServicesController.js.map +1 -1
- package/dist/NotificationServicesController/index.d.ts +1 -1
- package/dist/NotificationServicesController/index.d.ts.map +1 -1
- package/dist/NotificationServicesController/index.js.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.ts +0 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.ts.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.js +1 -21
- package/dist/NotificationServicesController/mocks/mockResponses.js.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.d.ts +1 -11
- package/dist/NotificationServicesController/services/api-notifications.d.ts.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.js +4 -40
- package/dist/NotificationServicesController/services/api-notifications.js.map +1 -1
- package/dist/NotificationServicesController/types/notification-api/notification-api.d.ts +0 -1
- package/dist/NotificationServicesController/types/notification-api/notification-api.d.ts.map +1 -1
- package/dist/NotificationServicesController/types/notification-api/notification-api.js.map +1 -1
- package/dist/NotificationServicesController/utils/utils.d.ts +5 -14
- package/dist/NotificationServicesController/utils/utils.d.ts.map +1 -1
- package/dist/NotificationServicesController/utils/utils.js +14 -17
- package/dist/NotificationServicesController/utils/utils.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,13 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Added
|
|
11
|
-
|
|
12
|
-
- Add `fetchMetamaskNotificationsCategories()` controller method that fetches the notification categories manifest from `GET /api/v4/notifications/categories`, stores the result in new `metamaskNotificationsCategories` state, and exposes it through the messenger as `NotificationServicesController:fetchMetamaskNotificationsCategories` ([#9984](https://github.com/MetaMask/core/pull/9984))
|
|
13
|
-
- Add `metamaskNotificationsCategories` state field (`NotificationsCategory[]`) for the server-driven notification settings taxonomy ([#9984](https://github.com/MetaMask/core/pull/9984))
|
|
14
|
-
- Add `isFetchingMetamaskNotificationsCategories` state flag that reflects whether the categories request is in flight ([#9984](https://github.com/MetaMask/core/pull/9984))
|
|
15
|
-
- Export `NotificationsCategory` type from the notification-api schema ([#9984](https://github.com/MetaMask/core/pull/9984))
|
|
16
|
-
|
|
17
10
|
### Changed
|
|
18
11
|
|
|
19
12
|
- Bump `lodash-es` from `^4.17.21` to `^4.18.1` ([#10447](https://github.com/MetaMask/core/pull/10447))
|
package/dist/NotificationServicesController/NotificationServicesController-method-action-types.d.ts
CHANGED
|
@@ -193,23 +193,8 @@ export type NotificationServicesControllerSendPerpPlaceOrderNotificationAction =
|
|
|
193
193
|
type: `NotificationServicesController:sendPerpPlaceOrderNotification`;
|
|
194
194
|
handler: NotificationServicesController['sendPerpPlaceOrderNotification'];
|
|
195
195
|
};
|
|
196
|
-
/**
|
|
197
|
-
* Fetches the list of MetaMask notification categories from the notifications API,
|
|
198
|
-
* stores the result in controller state, and returns the categories.
|
|
199
|
-
*
|
|
200
|
-
* This method sets the categories-loading flag while the request is in flight
|
|
201
|
-
* so the UI can reflect the loading state. If the request fails, it logs the
|
|
202
|
-
* error and throws a generic failure error.
|
|
203
|
-
*
|
|
204
|
-
* @returns A promise that resolves to the fetched notification categories.
|
|
205
|
-
* @throws {Error} If the categories request fails.
|
|
206
|
-
*/
|
|
207
|
-
export type NotificationServicesControllerFetchMetamaskNotificationsCategoriesAction = {
|
|
208
|
-
type: `NotificationServicesController:fetchMetamaskNotificationsCategories`;
|
|
209
|
-
handler: NotificationServicesController['fetchMetamaskNotificationsCategories'];
|
|
210
|
-
};
|
|
211
196
|
/**
|
|
212
197
|
* Union of all NotificationServicesController action types.
|
|
213
198
|
*/
|
|
214
|
-
export type NotificationServicesControllerMethodActions = NotificationServicesControllerInitAction | NotificationServicesControllerEnablePushNotificationsAction | NotificationServicesControllerDisablePushNotificationsAction | NotificationServicesControllerCheckAccountsPresenceAction | NotificationServicesControllerSetFeatureAnnouncementsEnabledAction | NotificationServicesControllerCreateOnChainTriggersAction | NotificationServicesControllerEnableMetamaskNotificationsAction | NotificationServicesControllerDisableNotificationServicesAction | NotificationServicesControllerDisableAccountsAction | NotificationServicesControllerEnableAccountsAction | NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction | NotificationServicesControllerGetNotificationsByTypeAction | NotificationServicesControllerDeleteNotificationByIdAction | NotificationServicesControllerDeleteNotificationsByIdAction | NotificationServicesControllerMarkMetamaskNotificationsAsReadAction | NotificationServicesControllerUpdateMetamaskNotificationsListAction | NotificationServicesControllerSendPerpPlaceOrderNotificationAction
|
|
199
|
+
export type NotificationServicesControllerMethodActions = NotificationServicesControllerInitAction | NotificationServicesControllerEnablePushNotificationsAction | NotificationServicesControllerDisablePushNotificationsAction | NotificationServicesControllerCheckAccountsPresenceAction | NotificationServicesControllerSetFeatureAnnouncementsEnabledAction | NotificationServicesControllerCreateOnChainTriggersAction | NotificationServicesControllerEnableMetamaskNotificationsAction | NotificationServicesControllerDisableNotificationServicesAction | NotificationServicesControllerDisableAccountsAction | NotificationServicesControllerEnableAccountsAction | NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction | NotificationServicesControllerGetNotificationsByTypeAction | NotificationServicesControllerDeleteNotificationByIdAction | NotificationServicesControllerDeleteNotificationsByIdAction | NotificationServicesControllerMarkMetamaskNotificationsAsReadAction | NotificationServicesControllerUpdateMetamaskNotificationsListAction | NotificationServicesControllerSendPerpPlaceOrderNotificationAction;
|
|
215
200
|
//# sourceMappingURL=NotificationServicesController-method-action-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationServicesController-method-action-types.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController-method-action-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"NotificationServicesController-method-action-types.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController-method-action-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationServicesController-method-action-types.js","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NotificationServicesController } from './NotificationServicesController.js';\n\nexport type NotificationServicesControllerInitAction = {\n type: `NotificationServicesController:init`;\n handler: NotificationServicesController['init'];\n};\n\n/**\n * Public method to expose enabling push notifications\n */\nexport type NotificationServicesControllerEnablePushNotificationsAction = {\n type: `NotificationServicesController:enablePushNotifications`;\n handler: NotificationServicesController['enablePushNotifications'];\n};\n\n/**\n * Public method to expose disabling push notifications\n */\nexport type NotificationServicesControllerDisablePushNotificationsAction = {\n type: `NotificationServicesController:disablePushNotifications`;\n handler: NotificationServicesController['disablePushNotifications'];\n};\n\nexport type NotificationServicesControllerCheckAccountsPresenceAction = {\n type: `NotificationServicesController:checkAccountsPresence`;\n handler: NotificationServicesController['checkAccountsPresence'];\n};\n\n/**\n * Sets the enabled state of feature announcements.\n *\n * **Action** - used in the notification settings to enable/disable feature announcements.\n *\n * @param featureAnnouncementsEnabled - A boolean value indicating the desired enabled state of the feature announcements.\n * @async\n * @throws {Error} If fails to update\n */\nexport type NotificationServicesControllerSetFeatureAnnouncementsEnabledAction =\n {\n type: `NotificationServicesController:setFeatureAnnouncementsEnabled`;\n handler: NotificationServicesController['setFeatureAnnouncementsEnabled'];\n };\n\n/**\n * This creates/re-creates on-chain triggers defined in User Storage.\n *\n * **Action** - Used during Sign In / Enabling of notifications.\n *\n * Notification preferences are initialized only when\n * {@link AuthenticatedUserStorageService} has no stored preferences yet.\n * Existing preferences are left as-is.\n *\n * @param opts - optional options to mutate this functionality\n * @param opts.hasMarketingConsent - The user's marketing-consent flag.\n * Used only during initialization to seed marketing push notifications.\n * @param opts.productAnnouncementEnabled - The user's product-announcement flag.\n * Used only during initialization to seed marketing in-app notifications.\n * @param opts.registerPushNotifications - Whether to attempt FCM/device push registration.\n * @returns The updated or newly created user storage.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerCreateOnChainTriggersAction = {\n type: `NotificationServicesController:createOnChainTriggers`;\n handler: NotificationServicesController['createOnChainTriggers'];\n};\n\n/**\n * Enables all MetaMask notifications for the user.\n * This is identical flow when initializing notifications for the first time.\n *\n * @param opts - Optional options to mutate this functionality.\n * @throws {Error} If there is an error during the process of enabling notifications.\n */\nexport type NotificationServicesControllerEnableMetamaskNotificationsAction = {\n type: `NotificationServicesController:enableMetamaskNotifications`;\n handler: NotificationServicesController['enableMetamaskNotifications'];\n};\n\n/**\n * Disables all MetaMask notifications for the user.\n * This method ensures that the user is authenticated, retrieves all linked accounts,\n * and disables on-chain triggers for each account. It also sets the global notification\n * settings for MetaMask, feature announcements to false.\n *\n * @throws {Error} If the user is not authenticated or if there is an error during the process.\n */\nexport type NotificationServicesControllerDisableNotificationServicesAction = {\n type: `NotificationServicesController:disableNotificationServices`;\n handler: NotificationServicesController['disableNotificationServices'];\n};\n\n/**\n * Disables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. The device's FCM links stay in place,\n * because those links deliver every notification source for an address.\n *\n * **Action** - When a user disables wallet activity for a given account.\n *\n * @param accounts - The accounts whose wallet-activity subscriptions are disabled.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerDisableAccountsAction = {\n type: `NotificationServicesController:disableAccounts`;\n handler: NotificationServicesController['disableAccounts'];\n};\n\n/**\n * Enables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. Linking the device token is handled\n * when the account is added or when notifications are enabled.\n *\n * **Action** - When a user enables wallet activity for an account.\n *\n * @param accounts - List of accounts to subscribe.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerEnableAccountsAction = {\n type: `NotificationServicesController:enableAccounts`;\n handler: NotificationServicesController['enableAccounts'];\n};\n\n/**\n * Fetches the list of metamask notifications.\n * This includes OnChain notifications; Feature Announcements; and Snap Notifications.\n *\n * **Action** - When a user views the notification list page/dropdown\n *\n * @param previewToken - the preview token to use if needed\n * @returns A promise that resolves to the list of notifications.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction =\n {\n type: `NotificationServicesController:fetchAndUpdateMetamaskNotifications`;\n handler: NotificationServicesController['fetchAndUpdateMetamaskNotifications'];\n };\n\n/**\n * Gets the specified type of notifications from state.\n *\n * @param type - The trigger type.\n * @returns An array of notifications of the passed in type.\n * @throws Throws an error if an invalid trigger type is passed.\n */\nexport type NotificationServicesControllerGetNotificationsByTypeAction = {\n type: `NotificationServicesController:getNotificationsByType`;\n handler: NotificationServicesController['getNotificationsByType'];\n};\n\n/**\n * Used to delete a notification by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param id - The id of the notification to delete.\n */\nexport type NotificationServicesControllerDeleteNotificationByIdAction = {\n type: `NotificationServicesController:deleteNotificationById`;\n handler: NotificationServicesController['deleteNotificationById'];\n};\n\n/**\n * Used to batch delete notifications by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param ids - The ids of the notifications to delete.\n */\nexport type NotificationServicesControllerDeleteNotificationsByIdAction = {\n type: `NotificationServicesController:deleteNotificationsById`;\n handler: NotificationServicesController['deleteNotificationsById'];\n};\n\n/**\n * Marks specified metamask notifications as read.\n *\n * @param notifications - An array of notifications to be marked as read. Each notification should include its type and read status.\n * @returns A promise that resolves when the operation is complete.\n */\nexport type NotificationServicesControllerMarkMetamaskNotificationsAsReadAction =\n {\n type: `NotificationServicesController:markMetamaskNotificationsAsRead`;\n handler: NotificationServicesController['markMetamaskNotificationsAsRead'];\n };\n\n/**\n * Updates the list of MetaMask notifications by adding a new notification at the beginning of the list.\n * This method ensures that the most recent notification is displayed first in the UI.\n *\n * @param notification - The new notification object to be added to the list.\n * @returns A promise that resolves when the notification list has been successfully updated.\n */\nexport type NotificationServicesControllerUpdateMetamaskNotificationsListAction =\n {\n type: `NotificationServicesController:updateMetamaskNotificationsList`;\n handler: NotificationServicesController['updateMetamaskNotificationsList'];\n };\n\n/**\n * Creates an perp order notification subscription.\n * Requires notifications and auth to be enabled to start receiving this notifications\n *\n * @param input perp input\n */\nexport type NotificationServicesControllerSendPerpPlaceOrderNotificationAction =\n {\n type: `NotificationServicesController:sendPerpPlaceOrderNotification`;\n handler: NotificationServicesController['sendPerpPlaceOrderNotification'];\n };\n\n/**\n * Fetches the list of MetaMask notification categories from the notifications API,\n * stores the result in controller state, and returns the categories.\n *\n * This method sets the categories-loading flag while the request is in flight\n * so the UI can reflect the loading state. If the request fails, it logs the\n * error and throws a generic failure error.\n *\n * @returns A promise that resolves to the fetched notification categories.\n * @throws {Error} If the categories request fails.\n */\nexport type NotificationServicesControllerFetchMetamaskNotificationsCategoriesAction =\n {\n type: `NotificationServicesController:fetchMetamaskNotificationsCategories`;\n handler: NotificationServicesController['fetchMetamaskNotificationsCategories'];\n };\n\n/**\n * Union of all NotificationServicesController action types.\n */\nexport type NotificationServicesControllerMethodActions =\n | NotificationServicesControllerInitAction\n | NotificationServicesControllerEnablePushNotificationsAction\n | NotificationServicesControllerDisablePushNotificationsAction\n | NotificationServicesControllerCheckAccountsPresenceAction\n | NotificationServicesControllerSetFeatureAnnouncementsEnabledAction\n | NotificationServicesControllerCreateOnChainTriggersAction\n | NotificationServicesControllerEnableMetamaskNotificationsAction\n | NotificationServicesControllerDisableNotificationServicesAction\n | NotificationServicesControllerDisableAccountsAction\n | NotificationServicesControllerEnableAccountsAction\n | NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction\n | NotificationServicesControllerGetNotificationsByTypeAction\n | NotificationServicesControllerDeleteNotificationByIdAction\n | NotificationServicesControllerDeleteNotificationsByIdAction\n | NotificationServicesControllerMarkMetamaskNotificationsAsReadAction\n | NotificationServicesControllerUpdateMetamaskNotificationsListAction\n | NotificationServicesControllerSendPerpPlaceOrderNotificationAction\n | NotificationServicesControllerFetchMetamaskNotificationsCategoriesAction;\n"]}
|
|
1
|
+
{"version":3,"file":"NotificationServicesController-method-action-types.js","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { NotificationServicesController } from './NotificationServicesController.js';\n\nexport type NotificationServicesControllerInitAction = {\n type: `NotificationServicesController:init`;\n handler: NotificationServicesController['init'];\n};\n\n/**\n * Public method to expose enabling push notifications\n */\nexport type NotificationServicesControllerEnablePushNotificationsAction = {\n type: `NotificationServicesController:enablePushNotifications`;\n handler: NotificationServicesController['enablePushNotifications'];\n};\n\n/**\n * Public method to expose disabling push notifications\n */\nexport type NotificationServicesControllerDisablePushNotificationsAction = {\n type: `NotificationServicesController:disablePushNotifications`;\n handler: NotificationServicesController['disablePushNotifications'];\n};\n\nexport type NotificationServicesControllerCheckAccountsPresenceAction = {\n type: `NotificationServicesController:checkAccountsPresence`;\n handler: NotificationServicesController['checkAccountsPresence'];\n};\n\n/**\n * Sets the enabled state of feature announcements.\n *\n * **Action** - used in the notification settings to enable/disable feature announcements.\n *\n * @param featureAnnouncementsEnabled - A boolean value indicating the desired enabled state of the feature announcements.\n * @async\n * @throws {Error} If fails to update\n */\nexport type NotificationServicesControllerSetFeatureAnnouncementsEnabledAction =\n {\n type: `NotificationServicesController:setFeatureAnnouncementsEnabled`;\n handler: NotificationServicesController['setFeatureAnnouncementsEnabled'];\n };\n\n/**\n * This creates/re-creates on-chain triggers defined in User Storage.\n *\n * **Action** - Used during Sign In / Enabling of notifications.\n *\n * Notification preferences are initialized only when\n * {@link AuthenticatedUserStorageService} has no stored preferences yet.\n * Existing preferences are left as-is.\n *\n * @param opts - optional options to mutate this functionality\n * @param opts.hasMarketingConsent - The user's marketing-consent flag.\n * Used only during initialization to seed marketing push notifications.\n * @param opts.productAnnouncementEnabled - The user's product-announcement flag.\n * Used only during initialization to seed marketing in-app notifications.\n * @param opts.registerPushNotifications - Whether to attempt FCM/device push registration.\n * @returns The updated or newly created user storage.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerCreateOnChainTriggersAction = {\n type: `NotificationServicesController:createOnChainTriggers`;\n handler: NotificationServicesController['createOnChainTriggers'];\n};\n\n/**\n * Enables all MetaMask notifications for the user.\n * This is identical flow when initializing notifications for the first time.\n *\n * @param opts - Optional options to mutate this functionality.\n * @throws {Error} If there is an error during the process of enabling notifications.\n */\nexport type NotificationServicesControllerEnableMetamaskNotificationsAction = {\n type: `NotificationServicesController:enableMetamaskNotifications`;\n handler: NotificationServicesController['enableMetamaskNotifications'];\n};\n\n/**\n * Disables all MetaMask notifications for the user.\n * This method ensures that the user is authenticated, retrieves all linked accounts,\n * and disables on-chain triggers for each account. It also sets the global notification\n * settings for MetaMask, feature announcements to false.\n *\n * @throws {Error} If the user is not authenticated or if there is an error during the process.\n */\nexport type NotificationServicesControllerDisableNotificationServicesAction = {\n type: `NotificationServicesController:disableNotificationServices`;\n handler: NotificationServicesController['disableNotificationServices'];\n};\n\n/**\n * Disables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. The device's FCM links stay in place,\n * because those links deliver every notification source for an address.\n *\n * **Action** - When a user disables wallet activity for a given account.\n *\n * @param accounts - The accounts whose wallet-activity subscriptions are disabled.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerDisableAccountsAction = {\n type: `NotificationServicesController:disableAccounts`;\n handler: NotificationServicesController['disableAccounts'];\n};\n\n/**\n * Enables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. Linking the device token is handled\n * when the account is added or when notifications are enabled.\n *\n * **Action** - When a user enables wallet activity for an account.\n *\n * @param accounts - List of accounts to subscribe.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerEnableAccountsAction = {\n type: `NotificationServicesController:enableAccounts`;\n handler: NotificationServicesController['enableAccounts'];\n};\n\n/**\n * Fetches the list of metamask notifications.\n * This includes OnChain notifications; Feature Announcements; and Snap Notifications.\n *\n * **Action** - When a user views the notification list page/dropdown\n *\n * @param previewToken - the preview token to use if needed\n * @returns A promise that resolves to the list of notifications.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\nexport type NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction =\n {\n type: `NotificationServicesController:fetchAndUpdateMetamaskNotifications`;\n handler: NotificationServicesController['fetchAndUpdateMetamaskNotifications'];\n };\n\n/**\n * Gets the specified type of notifications from state.\n *\n * @param type - The trigger type.\n * @returns An array of notifications of the passed in type.\n * @throws Throws an error if an invalid trigger type is passed.\n */\nexport type NotificationServicesControllerGetNotificationsByTypeAction = {\n type: `NotificationServicesController:getNotificationsByType`;\n handler: NotificationServicesController['getNotificationsByType'];\n};\n\n/**\n * Used to delete a notification by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param id - The id of the notification to delete.\n */\nexport type NotificationServicesControllerDeleteNotificationByIdAction = {\n type: `NotificationServicesController:deleteNotificationById`;\n handler: NotificationServicesController['deleteNotificationById'];\n};\n\n/**\n * Used to batch delete notifications by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param ids - The ids of the notifications to delete.\n */\nexport type NotificationServicesControllerDeleteNotificationsByIdAction = {\n type: `NotificationServicesController:deleteNotificationsById`;\n handler: NotificationServicesController['deleteNotificationsById'];\n};\n\n/**\n * Marks specified metamask notifications as read.\n *\n * @param notifications - An array of notifications to be marked as read. Each notification should include its type and read status.\n * @returns A promise that resolves when the operation is complete.\n */\nexport type NotificationServicesControllerMarkMetamaskNotificationsAsReadAction =\n {\n type: `NotificationServicesController:markMetamaskNotificationsAsRead`;\n handler: NotificationServicesController['markMetamaskNotificationsAsRead'];\n };\n\n/**\n * Updates the list of MetaMask notifications by adding a new notification at the beginning of the list.\n * This method ensures that the most recent notification is displayed first in the UI.\n *\n * @param notification - The new notification object to be added to the list.\n * @returns A promise that resolves when the notification list has been successfully updated.\n */\nexport type NotificationServicesControllerUpdateMetamaskNotificationsListAction =\n {\n type: `NotificationServicesController:updateMetamaskNotificationsList`;\n handler: NotificationServicesController['updateMetamaskNotificationsList'];\n };\n\n/**\n * Creates an perp order notification subscription.\n * Requires notifications and auth to be enabled to start receiving this notifications\n *\n * @param input perp input\n */\nexport type NotificationServicesControllerSendPerpPlaceOrderNotificationAction =\n {\n type: `NotificationServicesController:sendPerpPlaceOrderNotification`;\n handler: NotificationServicesController['sendPerpPlaceOrderNotification'];\n };\n\n/**\n * Union of all NotificationServicesController action types.\n */\nexport type NotificationServicesControllerMethodActions =\n | NotificationServicesControllerInitAction\n | NotificationServicesControllerEnablePushNotificationsAction\n | NotificationServicesControllerDisablePushNotificationsAction\n | NotificationServicesControllerCheckAccountsPresenceAction\n | NotificationServicesControllerSetFeatureAnnouncementsEnabledAction\n | NotificationServicesControllerCreateOnChainTriggersAction\n | NotificationServicesControllerEnableMetamaskNotificationsAction\n | NotificationServicesControllerDisableNotificationServicesAction\n | NotificationServicesControllerDisableAccountsAction\n | NotificationServicesControllerEnableAccountsAction\n | NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction\n | NotificationServicesControllerGetNotificationsByTypeAction\n | NotificationServicesControllerDeleteNotificationByIdAction\n | NotificationServicesControllerDeleteNotificationsByIdAction\n | NotificationServicesControllerMarkMetamaskNotificationsAsReadAction\n | NotificationServicesControllerUpdateMetamaskNotificationsListAction\n | NotificationServicesControllerSendPerpPlaceOrderNotificationAction;\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuthenticatedUserStorageServiceGetNotificationPreferencesAction, AuthenticatedUserStorageServicePutNotificationPreferencesAction, PerpsPreference, SocialAIPreference } from '@metamask/authenticated-user-storage';
|
|
2
|
-
import type { ControllerGetStateAction,
|
|
2
|
+
import type { ControllerGetStateAction, ControllerStateChangeEvent } from '@metamask/base-controller';
|
|
3
3
|
import { BaseController } from '@metamask/base-controller';
|
|
4
4
|
import type { KeyringControllerStateChangeEvent, KeyringControllerGetStateAction, KeyringControllerLockEvent, KeyringControllerUnlockEvent } from '@metamask/keyring-controller';
|
|
5
5
|
import type { Messenger } from '@metamask/messenger';
|
|
@@ -7,7 +7,6 @@ import type { AuthenticationController } from '@metamask/profile-sync-controller
|
|
|
7
7
|
import type { NotificationServicesPushControllerStateChangeEvent, NotificationServicesPushControllerOnNewNotificationEvent } from '../NotificationServicesPushController/index.js';
|
|
8
8
|
import type { NotificationServicesPushControllerMethodActions } from '../NotificationServicesPushController/NotificationServicesPushController-method-action-types.js';
|
|
9
9
|
import { TRIGGER_TYPES } from './constants/notification-schema.js';
|
|
10
|
-
import type { NotificationsCategory } from './index.js';
|
|
11
10
|
import type { NotificationServicesControllerMethodActions } from './NotificationServicesController-method-action-types.js';
|
|
12
11
|
import type { ENV } from './services/api-notifications.js';
|
|
13
12
|
import type { INotification, MarkAsReadNotificationsParam } from './types/notification/notification.js';
|
|
@@ -43,10 +42,6 @@ export type NotificationServicesControllerState = {
|
|
|
43
42
|
* List of read metamask notifications
|
|
44
43
|
*/
|
|
45
44
|
metamaskNotificationsReadList: string[];
|
|
46
|
-
/**
|
|
47
|
-
* List of notification categories
|
|
48
|
-
*/
|
|
49
|
-
metamaskNotificationsCategories: NotificationsCategory[];
|
|
50
45
|
/**
|
|
51
46
|
* Flag that indicates that the creating notifications is in progress
|
|
52
47
|
*/
|
|
@@ -57,11 +52,6 @@ export type NotificationServicesControllerState = {
|
|
|
57
52
|
* when fetching notifications
|
|
58
53
|
*/
|
|
59
54
|
isFetchingMetamaskNotifications: boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Flag that indicates that fetching notification categories
|
|
62
|
-
* is in progress. Used for readiness checks for categories consumers
|
|
63
|
-
*/
|
|
64
|
-
isFetchingMetamaskNotificationsCategories: boolean;
|
|
65
55
|
/**
|
|
66
56
|
* Flag that indicates that the updating notifications for a specific address is in progress
|
|
67
57
|
*/
|
|
@@ -110,7 +100,7 @@ export { DEFAULT_AGENTIC_CLI_PREFERENCES, DEFAULT_PRICE_ALERT_PREFERENCES, } fro
|
|
|
110
100
|
export type NotificationServicesControllerGetStateAction = ControllerGetStateAction<typeof controllerName, NotificationServicesControllerState>;
|
|
111
101
|
export type Actions = NotificationServicesControllerGetStateAction | NotificationServicesControllerMethodActions;
|
|
112
102
|
type AllowedActions = KeyringControllerGetStateAction | AuthenticationController.AuthenticationControllerGetBearerTokenAction | AuthenticationController.AuthenticationControllerIsSignedInAction | AuthenticationController.AuthenticationControllerPerformSignInAction | AuthenticatedUserStorageServiceGetNotificationPreferencesAction | AuthenticatedUserStorageServicePutNotificationPreferencesAction | NotificationServicesPushControllerMethodActions;
|
|
113
|
-
export type NotificationServicesControllerStateChangeEvent =
|
|
103
|
+
export type NotificationServicesControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, NotificationServicesControllerState>;
|
|
114
104
|
export type NotificationListUpdatedEvent = {
|
|
115
105
|
type: `${typeof controllerName}:notificationsListUpdated`;
|
|
116
106
|
payload: [INotification[]];
|
|
@@ -292,17 +282,5 @@ export declare class NotificationServicesController extends BaseController<typeo
|
|
|
292
282
|
* @param input perp input
|
|
293
283
|
*/
|
|
294
284
|
sendPerpPlaceOrderNotification(input: OrderInput): Promise<void>;
|
|
295
|
-
/**
|
|
296
|
-
* Fetches the list of MetaMask notification categories from the notifications API,
|
|
297
|
-
* stores the result in controller state, and returns the categories.
|
|
298
|
-
*
|
|
299
|
-
* This method sets the categories-loading flag while the request is in flight
|
|
300
|
-
* so the UI can reflect the loading state. If the request fails, it logs the
|
|
301
|
-
* error and throws a generic failure error.
|
|
302
|
-
*
|
|
303
|
-
* @returns A promise that resolves to the fetched notification categories.
|
|
304
|
-
* @throws {Error} If the categories request fails.
|
|
305
|
-
*/
|
|
306
|
-
fetchMetamaskNotificationsCategories(): Promise<NotificationsCategory[]>;
|
|
307
285
|
}
|
|
308
286
|
//# sourceMappingURL=NotificationServicesController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationServicesController.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,+DAA+D,EAC/D,+DAA+D,EAE/D,eAAe,EACf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAK9C,OAAO,KAAK,EACV,wBAAwB,EACxB,
|
|
1
|
+
{"version":3,"file":"NotificationServicesController.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,+DAA+D,EAC/D,+DAA+D,EAE/D,eAAe,EACf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAK9C,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAK3D,OAAO,KAAK,EACV,iCAAiC,EACjC,+BAA+B,EAC/B,0BAA0B,EAC1B,4BAA4B,EAE7B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAKlF,OAAO,KAAK,EACV,kDAAkD,EAClD,wDAAwD,EACzD,MAAM,gDAAgD,CAAC;AACxD,OAAO,KAAK,EAAE,+CAA+C,EAAE,MAAM,iGAAiG,CAAC;AACvK,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAEnE,OAAO,KAAK,EAAE,2CAA2C,EAAE,MAAM,yDAAyD,CAAC;AAK3H,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iCAAiC,CAAC;AAS3D,OAAO,KAAK,EACV,aAAa,EACb,4BAA4B,EAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,QAAA,MAAM,cAAc,mCAAmC,CAAC;AAExD,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAAG;IAChD;;;OAGG;IACH,wBAAwB,EAAE,MAAM,EAAE,CAAC;IAEnC;;OAEG;IACH,kCAAkC,EAAE,OAAO,CAAC;IAE5C;;OAEG;IACH,6BAA6B,EAAE,OAAO,CAAC;IAEvC;;OAEG;IACH,6BAA6B,EAAE,OAAO,CAAC;IAEvC;;OAEG;IACH,yBAAyB,EAAE,aAAa,EAAE,CAAC;IAE3C;;OAEG;IACH,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC;;OAEG;IACH,+BAA+B,EAAE,OAAO,CAAC;IACzC;;;;OAIG;IACH,+BAA+B,EAAE,OAAO,CAAC;IACzC;;OAEG;IACH,sCAAsC,EAAE,MAAM,EAAE,CAAC;IACjD;;OAEG;IACH,0BAA0B,EAAE,OAAO,CAAC;CACrC,CAAC;AAiEF,eAAO,MAAM,YAAY,EAAE,mCAW1B,CAAC;AAEF,MAAM,MAAM,wDAAwD,GAAG;IACrE;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;OAMG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,0DAA0D,GACpE,wDAAwD,CAAC;AAE3D,MAAM,MAAM,gEAAgE,GAC1E,wDAAwD,CAAC;AAM3D;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,eAGvC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,kBAAkB,CAKtE,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,sCAAsC,CAAC;AAyF9C,MAAM,MAAM,4CAA4C,GACtD,wBAAwB,CACtB,OAAO,cAAc,EACrB,mCAAmC,CACpC,CAAC;AAGJ,MAAM,MAAM,OAAO,GACf,4CAA4C,GAC5C,2CAA2C,CAAC;AAGhD,KAAK,cAAc,GAEf,+BAA+B,GAE/B,wBAAwB,CAAC,4CAA4C,GACrE,wBAAwB,CAAC,wCAAwC,GACjE,wBAAwB,CAAC,2CAA2C,GAEpE,+DAA+D,GAC/D,+DAA+D,GAE/D,+CAA+C,CAAC;AAGpD,MAAM,MAAM,8CAA8C,GACxD,0BAA0B,CACxB,OAAO,cAAc,EACrB,mCAAmC,CACpC,CAAC;AAEJ,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,GAAG,OAAO,cAAc,2BAA2B,CAAC;IAC1D,OAAO,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,GAAG,OAAO,cAAc,0BAA0B,CAAC;IACzD,OAAO,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;CAC5B,CAAC;AAGF,MAAM,MAAM,MAAM,GACd,8CAA8C,GAC9C,4BAA4B,GAC5B,4BAA4B,CAAC;AAGjC,KAAK,aAAa,GAEd,iCAAiC,GACjC,0BAA0B,GAC1B,4BAA4B,GAE5B,wDAAwD,GACxD,kDAAkD,CAAC;AAGvD,MAAM,MAAM,uCAAuC,GAAG,SAAS,CAC7D,OAAO,cAAc,EACrB,OAAO,GAAG,cAAc,EACxB,MAAM,GAAG,aAAa,CACvB,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,qBAAa,8BAA+B,SAAQ,cAAc,CAChE,OAAO,cAAc,EACrB,mCAAmC,EACnC,uCAAuC,CACxC;;IAkTC;;;;;;;;;;OAUG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EACL,GAAG,GACJ,EAAE;QACD,SAAS,EAAE,uCAAuC,CAAC;QACnD,KAAK,CAAC,EAAE,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACrD,GAAG,EAAE;YACH,oBAAoB,EAAE,sBAAsB,CAAC;YAC7C,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;YACtB,GAAG,CAAC,EAAE,GAAG,CAAC;SACX,CAAC;KACH,EAkBA;IAED,IAAI,IAAI,IAAI,CAaX;IAkID;;OAEG;IACU,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBpD;IAED;;OAEG;IACU,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAErD;IAEY,qBAAqB,CAChC,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmClC;IAED;;;;;;;;OAQG;IACU,8BAA8B,CACzC,2BAA2B,EAAE,OAAO,GACnC,OAAO,CAAC,IAAI,CAAC,CASf;IAED;;;;;;;;;;;;;;;;;OAiBG;IACU,qBAAqB,CAChC,IAAI,GAAE,0DAA+D,GACpE,OAAO,CAAC,IAAI,CAAC,CAuGf;IAED;;;;;;OAMG;IACU,2BAA2B,CACtC,IAAI,GAAE,gEAAqE,GAC1E,OAAO,CAAC,IAAI,CAAC,CAWf;IAED;;;;;;;OAOG;IACU,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBxD;IAED;;;;;;;;;;OAUG;IACU,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAe9D;IAED;;;;;;;;;;OAUG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7D;IAED;;;;;;;;;OASG;IACU,mCAAmC,CAC9C,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,CA2F1B;IAED;;;;;;OAMG;IACI,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,EAAE,CAQlE;IAED;;;;;;;OAOG;IACU,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B7D;IAED;;;;;;;OAOG;IACU,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CASjE;IAED;;;;;OAKG;IACU,+BAA+B,CAC1C,aAAa,EAAE,4BAA4B,GAC1C,OAAO,CAAC,IAAI,CAAC,CA0Gf;IAED;;;;;;OAMG;IACU,+BAA+B,CAC1C,YAAY,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgCf;IAED;;;;;OAKG;IACU,8BAA8B,CACzC,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAOf;CACF"}
|
|
@@ -6,7 +6,7 @@ import { debounce } from 'lodash-es';
|
|
|
6
6
|
import log from 'loglevel';
|
|
7
7
|
import { TRIGGER_TYPES } from './constants/notification-schema.js';
|
|
8
8
|
import { processAndFilterNotifications, safeProcessNotification, } from './processors/process-notifications.js';
|
|
9
|
-
import { getAPINotifications, getNotificationsApiConfigCached,
|
|
9
|
+
import { getAPINotifications, getNotificationsApiConfigCached, markNotificationsAsRead, updateOnChainNotifications, } from './services/api-notifications.js';
|
|
10
10
|
import { getFeatureAnnouncementNotifications } from './services/feature-announcements.js';
|
|
11
11
|
import { createPerpOrderNotification } from './services/perp-notifications.js';
|
|
12
12
|
// Unique name for the controller
|
|
@@ -49,12 +49,6 @@ const metadata = {
|
|
|
49
49
|
includeInDebugSnapshot: true,
|
|
50
50
|
usedInUi: true,
|
|
51
51
|
},
|
|
52
|
-
metamaskNotificationsCategories: {
|
|
53
|
-
includeInStateLogs: true,
|
|
54
|
-
persist: true,
|
|
55
|
-
includeInDebugSnapshot: true,
|
|
56
|
-
usedInUi: true,
|
|
57
|
-
},
|
|
58
52
|
isUpdatingMetamaskNotifications: {
|
|
59
53
|
includeInStateLogs: false,
|
|
60
54
|
persist: false,
|
|
@@ -79,12 +73,6 @@ const metadata = {
|
|
|
79
73
|
includeInDebugSnapshot: false,
|
|
80
74
|
usedInUi: true,
|
|
81
75
|
},
|
|
82
|
-
isFetchingMetamaskNotificationsCategories: {
|
|
83
|
-
includeInStateLogs: false,
|
|
84
|
-
persist: false,
|
|
85
|
-
includeInDebugSnapshot: false,
|
|
86
|
-
usedInUi: true,
|
|
87
|
-
},
|
|
88
76
|
};
|
|
89
77
|
export const defaultState = {
|
|
90
78
|
subscriptionAccountsSeen: [],
|
|
@@ -93,12 +81,10 @@ export const defaultState = {
|
|
|
93
81
|
isFeatureAnnouncementsEnabled: false,
|
|
94
82
|
metamaskNotificationsList: [],
|
|
95
83
|
metamaskNotificationsReadList: [],
|
|
96
|
-
metamaskNotificationsCategories: [],
|
|
97
84
|
isUpdatingMetamaskNotifications: false,
|
|
98
85
|
isFetchingMetamaskNotifications: false,
|
|
99
86
|
isUpdatingMetamaskNotificationsAccount: [],
|
|
100
87
|
isCheckingAccountsPresence: false,
|
|
101
|
-
isFetchingMetamaskNotificationsCategories: false,
|
|
102
88
|
};
|
|
103
89
|
const locallyPersistedNotificationTypes = new Set([
|
|
104
90
|
TRIGGER_TYPES.SNAP,
|
|
@@ -186,7 +172,6 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
186
172
|
'disableAccounts',
|
|
187
173
|
'enableAccounts',
|
|
188
174
|
'fetchAndUpdateMetamaskNotifications',
|
|
189
|
-
'fetchMetamaskNotificationsCategories',
|
|
190
175
|
'getNotificationsByType',
|
|
191
176
|
'deleteNotificationById',
|
|
192
177
|
'deleteNotificationsById',
|
|
@@ -573,20 +558,6 @@ export class NotificationServicesController extends BaseController {
|
|
|
573
558
|
state.isUpdatingMetamaskNotificationsAccount.filter((existingAccount) => !accounts.includes(existingAccount));
|
|
574
559
|
});
|
|
575
560
|
}
|
|
576
|
-
/**
|
|
577
|
-
* Updates the state to indicate whether fetching of MetaMask notification categories is in progress.
|
|
578
|
-
*
|
|
579
|
-
* This method is used to set the `isFetchingMetamaskNotificationsCategories` state, which can be utilized
|
|
580
|
-
* to show or hide loading indicators in the UI when notifications categories are being fetched.
|
|
581
|
-
*
|
|
582
|
-
* @param isFetchingNotificationCategories - A boolean value representing the fetching state.
|
|
583
|
-
*/
|
|
584
|
-
#setIsFetchingNotificationsCategories(isFetchingNotificationCategories) {
|
|
585
|
-
this.update((state) => {
|
|
586
|
-
state.isFetchingMetamaskNotificationsCategories =
|
|
587
|
-
isFetchingNotificationCategories;
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
561
|
/**
|
|
591
562
|
* Public method to expose enabling push notifications
|
|
592
563
|
*/
|
|
@@ -1087,33 +1058,5 @@ export class NotificationServicesController extends BaseController {
|
|
|
1087
1058
|
// Do Nothing
|
|
1088
1059
|
}
|
|
1089
1060
|
}
|
|
1090
|
-
/**
|
|
1091
|
-
* Fetches the list of MetaMask notification categories from the notifications API,
|
|
1092
|
-
* stores the result in controller state, and returns the categories.
|
|
1093
|
-
*
|
|
1094
|
-
* This method sets the categories-loading flag while the request is in flight
|
|
1095
|
-
* so the UI can reflect the loading state. If the request fails, it logs the
|
|
1096
|
-
* error and throws a generic failure error.
|
|
1097
|
-
*
|
|
1098
|
-
* @returns A promise that resolves to the fetched notification categories.
|
|
1099
|
-
* @throws {Error} If the categories request fails.
|
|
1100
|
-
*/
|
|
1101
|
-
async fetchMetamaskNotificationsCategories() {
|
|
1102
|
-
this.#setIsFetchingNotificationsCategories(true);
|
|
1103
|
-
try {
|
|
1104
|
-
const categories = await getNotificationsCategories();
|
|
1105
|
-
this.update((state) => {
|
|
1106
|
-
state.metamaskNotificationsCategories = categories;
|
|
1107
|
-
});
|
|
1108
|
-
return categories;
|
|
1109
|
-
}
|
|
1110
|
-
catch (error) {
|
|
1111
|
-
log.error('Failed to fetch notifications categories', error);
|
|
1112
|
-
throw new Error('Failed to fetch notifications categories');
|
|
1113
|
-
}
|
|
1114
|
-
finally {
|
|
1115
|
-
this.#setIsFetchingNotificationsCategories(false);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
1061
|
}
|
|
1119
1062
|
//# sourceMappingURL=NotificationServicesController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationServicesController.js","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,GAAG,MAAM,UAAU,CAAC;AAO3B,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAMnE,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mCAAmC,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAO/E,iCAAiC;AACjC,MAAM,cAAc,GAAG,gCAAgC,CAAC;AAExD,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAiErD,MAAM,QAAQ,GAAuD;IACnE,wBAAwB,EAAE;QACxB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IAED,kCAAkC,EAAE;QAClC,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,6BAA6B,EAAE;QAC7B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,6BAA6B,EAAE;QAC7B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,yBAAyB,EAAE;QACzB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,6BAA6B,EAAE;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,+BAA+B,EAAE;QAC/B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,IAAI;QAC5B,QAAQ,EAAE,IAAI;KACf;IACD,+BAA+B,EAAE;QAC/B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,+BAA+B,EAAE;QAC/B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,sCAAsC,EAAE;QACtC,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,0BAA0B,EAAE;QAC1B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;IACD,yCAAyC,EAAE;QACzC,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AACF,MAAM,CAAC,MAAM,YAAY,GAAwC;IAC/D,wBAAwB,EAAE,EAAE;IAC5B,kCAAkC,EAAE,KAAK;IACzC,6BAA6B,EAAE,KAAK;IACpC,6BAA6B,EAAE,KAAK;IACpC,yBAAyB,EAAE,EAAE;IAC7B,6BAA6B,EAAE,EAAE;IACjC,+BAA+B,EAAE,EAAE;IACnC,+BAA+B,EAAE,KAAK;IACtC,+BAA+B,EAAE,KAAK;IACtC,sCAAsC,EAAE,EAAE;IAC1C,0BAA0B,EAAE,KAAK;IACjC,yCAAyC,EAAE,KAAK;CACjD,CAAC;AA+BF,MAAM,iCAAiC,GAAG,IAAI,GAAG,CAAgB;IAC/D,aAAa,CAAC,IAAI;CACnB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAoB;IACxD,yBAAyB,EAAE,IAAI;IAC/B,wBAAwB,EAAE,IAAI;CAC/B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAiC;IACzE,yBAAyB,EAAE,IAAI;IAC/B,wBAAwB,EAAE,IAAI;IAC9B,aAAa,EAAE,GAAG;IAClB,qBAAqB,EAAE,EAAE;CAC1B,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,sCAAsC,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,kBAAkB,GAAG,KAAK,EAC9B,WAAmB,EACnB,QAAkB,EAClB,GAAQ,EACkB,EAAE;IAC5B,MAAM,aAAa,GAAG,MAAM,+BAA+B,CACzD,WAAW,EACX,QAAQ,EACR,GAAG,CACJ,CAAC;IAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,aAAa;SACjB,MAAM,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;SACzD,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,qBAAqB,GAAG,CAC5B,mBAA4B,EAC5B,0BAAmC,EACV,EAAE,CAAC,CAAC;IAC7B,cAAc,EAAE;QACd,yBAAyB,EAAE,IAAI;QAC/B,wBAAwB,EAAE,IAAI;QAC9B,QAAQ,EAAE,EAAE;KACb;IACD,SAAS,EAAE;QACT,yBAAyB,EAAE,0BAA0B;QACrD,wBAAwB,EAAE,mBAAmB;KAC9C;IACD,KAAK,EAAE,EAAE,GAAG,yBAAyB,EAAE;IACvC,QAAQ,EAAE,EAAE,GAAG,6BAA6B,EAAE;IAC9C,UAAU,EAAE,EAAE,GAAG,+BAA+B,EAAE;IAClD,WAAW,EAAE,EAAE,GAAG,+BAA+B,EAAE;CACpD,CAAC,CAAC;AAEH,MAAM,yBAAyB,GAAG;IAChC,MAAM;IACN,yBAAyB;IACzB,0BAA0B;IAC1B,uBAAuB;IACvB,gCAAgC;IAChC,uBAAuB;IACvB,6BAA6B;IAC7B,6BAA6B;IAC7B,iBAAiB;IACjB,gBAAgB;IAChB,qCAAqC;IACrC,sCAAsC;IACtC,wBAAwB;IACxB,wBAAwB;IACxB,yBAAyB;IACzB,iCAAiC;IACjC,iCAAiC;IACjC,gCAAgC;CACxB,CAAC;AA0EX;;GAEG;AACH,MAAM,OAAO,8BAA+B,SAAQ,cAInD;IACU,kBAAkB,GAAG;QAC5B,UAAU,EAAE,KAAK;QAEjB,6BAA6B,EAAE,CAAC,QAA6B,EAAQ,EAAE;YACrE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YACzE,IAAI,CAAC,kBAAkB,CAAC,UAAU,GAAG,UAAU,CAAC;YAEhD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,0BAA0B,EAAE,GAAS,EAAE;gBAC9D,IAAI,CAAC,kBAAkB,CAAC,UAAU,GAAG,IAAI,CAAC;gBAC1C,yCAAyC;gBACzC,8CAA8C;gBAC9C,mEAAmE;gBACnE,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAS,EAAE;gBAC5D,IAAI,CAAC,kBAAkB,CAAC,UAAU,GAAG,KAAK,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IAEO,KAAK,GAAG;QACf,cAAc,EAAE,KAAK,IAA4B,EAAE;YACjD,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9B,yCAAyC,CAC1C,CAAC;QACJ,CAAC;QACD,UAAU,EAAE,GAAY,EAAE;YACxB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,EAAE,KAAK,IAAuB,EAAE;YACpC,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9B,wCAAwC,CACzC,CAAC;QACJ,CAAC;KACF,CAAC;IAEO,kBAAkB,GAAG;QAC5B,4FAA4F;QAC5F,sFAAsF;QACtF,8DAA8D;QAC9D,OAAO,EAAE,KAAK;QAEd,4BAA4B,EAAE,KAAK,IAAmB,EAAE;YACtD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,iEAAiE,CAClE,CAAC;QACJ,CAAC;QACD,uBAAuB,EAAE,KAAK,EAAE,SAAmB,EAAiB,EAAE;YACpE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,4DAA4D,EAC5D,SAAS,CACV,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;QACD,wBAAwB,EAAE,KAAK,EAAE,SAAmB,EAAiB,EAAE;YACrE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,6DAA6D,EAC7D,SAAS,CACV,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;QACD,wBAAwB,EAAE,KAAK,IAAmB,EAAE;YAClD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,6DAA6D,CAC9D,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;QACD,2BAA2B,EAAE,KAAK,EAAE,SAAmB,EAAiB,EAAE;YACxE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,gEAAgE,EAChE,SAAS,CACV,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;QACD,SAAS,EAAE,GAAS,EAAE;YACpB,4DAA4D;YAC5D,8FAA8F;YAC9F,IAAI,iBAAiB,GAAG,KAAK,CAAC;YAC9B,IAAI,kBAAkB,GAAG,KAAK,CAAC;YAE/B,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;gBAC5C,iBAAiB,GAAG,IAAI,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,mCAAmC,EAAE,CAAC;gBACnD,CAAC;wBAAS,CAAC;oBACT,iBAAiB,GAAG,KAAK,CAAC;oBAC1B,IAAI,kBAAkB,EAAE,CAAC;wBACvB,kBAAkB,GAAG,KAAK,CAAC;wBAC3B,mEAAmE;wBACnE,WAAW,EAAE,CAAC;oBAChB,CAAC;gBACH,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,uDAAuD,EACvD,GAAS,EAAE;gBACT,IAAI,iBAAiB,EAAE,CAAC;oBACtB,kBAAkB,GAAG,IAAI,CAAC;oBAC1B,OAAO;gBACT,CAAC;gBACD,mEAAmE;gBACnE,WAAW,EAAE,CAAC;YAChB,CAAC,CACF,CAAC;QACJ,CAAC;QACD,2BAA2B,EAAE,KAAK,IAAmB,EAAE;YACrD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC;gBAC9C,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,iEAAiE;YACjE,sDAAsD;YACtD,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC;oBACxC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACvC,CAAC;gBACD,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBACrC,IAAI,CAAC,kBAAkB,CAAC,OAAO,GAAG,IAAI,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,CAAC,kBAAkB;qBAC1B,4BAA4B,EAAE;qBAC9B,KAAK,CAAC,GAAG,EAAE;oBACV,aAAa;gBACf,CAAC,CAAC,CAAC;YACP,CAAC;QACH,CAAC;KACF,CAAC;IAEO,SAAS,GAAG;QACnB,oCAAoC;QACpC,2BAA2B,EAAE,KAAK;QAElC,uBAAuB,EAAE,GAAoB,EAAE;YAC7C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;YACvE,MAAM,eAAe,GAAG;gBACtB,GAAG,IAAI,GAAG,CACR,QAAQ;qBACL,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;qBACtC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;oBACf,IAAI,CAAC;wBACH,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;oBACvC,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC,CAAC;qBACD,MAAM,CACL,CAAC,OAAO,EAAqB,EAAE,CAC7B,OAAO,KAAK,IAAI,IAAI,iBAAiB,CAAC,OAAO,CAAC,CACjD,CACJ;aACF,CAAC;YACF,OAAO,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7D,CAAC;QAED;;;;WAIG;QACH,YAAY,EAAE,GAIZ,EAAE;YACF,wCAAwC;YACxC,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,uBAAuB,EAAE,CAAC;YACrE,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,OAAO;oBACL,aAAa,EAAE,EAAE;oBACjB,eAAe,EAAE,EAAE;oBACnB,QAAQ,EAAE,EAAE;iBACb,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,mBAAmB;iBACjC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;iBAC/C,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;YACnD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YAErE,8CAA8C;YAC9C,4DAA4D;YAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,aAAa,EAAE,EAAE;oBACjB,eAAe,EAAE,EAAE;oBACnB,QAAQ,EAAE,EAAE;iBACb,CAAC;YACJ,CAAC;YAED,wCAAwC;YACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CACnC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAC3C,CAAC;YACF,MAAM,eAAe,GAAG,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAC1D,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAC9C,CAAC;YAEF,uBAAuB;YACvB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,wBAAwB,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,aAAa;gBACb,eAAe;gBACf,QAAQ;aACT,CAAC;QACJ,CAAC;QAED;;WAEG;QACH,UAAU,EAAE,GAAS,EAAE;YACrB,IACE,IAAI,CAAC,kBAAkB,CAAC,UAAU;gBAClC,CAAC,IAAI,CAAC,SAAS,CAAC,2BAA2B,EAC3C,CAAC;gBACD,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;gBAC9B,IAAI,CAAC,SAAS,CAAC,2BAA2B,GAAG,IAAI,CAAC;YACpD,CAAC;QACH,CAAC;QAED;;;;WAIG;QACH,SAAS,EAAE,GAAS,EAAE;YACpB,MAAM,mCAAmC,GAAG,QAAQ,CAClD,KAAK,EACH,aAAsB,EACtB,iBAA0B,EACX,EAAE;gBACjB,MAAM,uBAAuB,GAAG,aAAa,KAAK,iBAAiB,CAAC;gBACpE,IACE,CAAC,IAAI,CAAC,KAAK,CAAC,6BAA6B;oBACzC,CAAC,uBAAuB,EACxB,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GACtC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;gBAEhC,MAAM,QAAQ,GAAuB,EAAE,CAAC;gBACxC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;oBAClD,iEAAiE;oBACjE,0EAA0E;oBAC1E,QAAQ,CAAC,IAAI,CACX,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,aAAa,CAAC,CAChE,CAAC;gBACJ,CAAC;gBACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC;oBACrD,QAAQ,CAAC,IAAI,CACX,IAAI,CAAC,kBAAkB,CAAC,2BAA2B,CACjD,eAAe,CAChB,CACF,CAAC;gBACJ,CAAC;gBACD,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC,EACD,gCAAgC,CACjC,CAAC;YAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,+BAA+B;YAC/B,yEAAyE;YACzE,kEAAkE;YAClE,mCAAmC,EACnC,CAAC,KAA6B,EAAU,EAAE;gBACxC,OAAO,CACL,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM;oBACjE,CAAC,CACF,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEO,OAAO,CAAe;IAEtB,uBAAuB,CAAyB;IAEhD,IAAI,CAAM;IAEnB;;;;;;;;;;OAUG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EACL,GAAG,GASJ;QACC,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ;YACR,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,EAAE;SACrC,CAAC,CAAC;QAEH,IAAI,CAAC,uBAAuB,GAAG,GAAG,CAAC,oBAAoB,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,GAAW,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC;QAE7B,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;QAEF,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,kBAAkB,CAAC,6BAA6B,CACnD,KAAK,IAAmB,EAAE;YACxB,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,kBAAkB,CAAC,2BAA2B,EAAE,CAAC;QAC9D,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;QAC5B,mEAAmE;QACnE,IAAI,CAAC,kBAAkB,CAAC,2BAA2B,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,+BAA+B,GAAG,KAAK,CAAC;YAC9C,KAAK,CAAC,0BAA0B,GAAG,KAAK,CAAC;YACzC,KAAK,CAAC,+BAA+B,GAAG,KAAK,CAAC;YAC9C,KAAK,CAAC,sCAAsC,GAAG,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,6BAA6B,GAAG,KAAK,CAAC;YAC9C,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,0BAA0B,CAAC,SAAmB;QAClD,MAAM,IAAI,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC;IAED;;;;;;;;;OASG;IACH,mCAAmC,CACjC,+BAAwC;QAExC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,+BAA+B,GAAG,+BAA+B,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,mCAAmC,CACjC,+BAAwC;QAExC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,+BAA+B,GAAG,+BAA+B,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,8BAA8B,CAAC,0BAAmC;QAChE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,0BAA0B,GAAG,0BAA0B,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,4BAA4B,CAAC,QAAkB;QAC7C,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;gBAC7B,GAAG,KAAK,CAAC,sCAAsC;gBAC/C,GAAG,QAAQ;aACZ,CAAC,CAAC;YACH,KAAK,CAAC,sCAAsC,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,2BAA2B,CAAC,QAAkB;QAC5C,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,sCAAsC;gBAC1C,KAAK,CAAC,sCAAsC,CAAC,MAAM,CACjD,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CACzD,CAAC;QACN,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,qCAAqC,CACnC,gCAAyC;QAEzC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,yCAAyC;gBAC7C,gCAAgC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,uBAAuB;QAClC,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjE,uFAAuF;gBACvF,8EAA8E;gBAC9E,OAAO;YACT,CAAC;YAED,wEAAwE;YACxE,iFAAiF;YACjF,MAAM,IAAI,CAAC,0BAA0B,CACnC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CACjD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,wBAAwB;QACnC,MAAM,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,EAAE,CAAC;IAC3D,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAChC,QAAkB;QAElB,IAAI,CAAC;YACH,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;YAE1C,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,MAAM,aAAa,GAAG,MAAM,+BAA+B,CACzD,WAAW,EACX,QAAQ,EACR,IAAI,CAAC,IAAI,CACV,CAAC;YAEF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,oEAAoE;gBACpE,4CAA4C;gBAC5C,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,aAAa,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC;gBACnC,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE;gBACnC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC;aAC/B,CAAC,CACH,CAAC;YAEF,MAAM,MAAM,GAA4B,EAAE,CAAC;YAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,MAAM,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,KAAK,CAAC;YACzE,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,8BAA8B,CACzC,2BAAoC;QAEpC,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,6BAA6B,GAAG,2BAA2B,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACI,KAAK,CAAC,qBAAqB,CAChC,IAAI,GAA+D,EAAE;QAErE,IAAI,CAAC;YACH,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC;YAE/C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,UAAU,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjE,uFAAuF;gBACvF,8EAA8E;gBAC9E,OAAO;YACT,CAAC;YAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAErD,uEAAuE;YACvE,gEAAgE;YAChE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC3C,4DAA4D,CAC7D,CAAC;YAEF,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;YAC/D,MAAM,0BAA0B,GAAG,OAAO,CACxC,IAAI,EAAE,0BAA0B,CACjC,CAAC;YAEF,MAAM,gBAAgB,GAAG,WAAW,KAAK,IAAI,CAAC;YAE9C,gEAAgE;YAChE,EAAE;YACF,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,8DAA8D;YAC9D,EAAE;YACF,yEAAyE;YACzE,oEAAoE;YACpE,sCAAsC;YACtC,MAAM,yBAAyB,GAAG,MAAM,kBAAkB,CACxD,WAAW,EACX,QAAQ,EACR,IAAI,CAAC,IAAI,CACV,CAAC;YAEF,IAAI,yBAAyB,KAAK,IAAI,EAAE,CAAC;gBACvC,mEAAmE;gBACnE,mEAAmE;gBACnE,oCAAoC;gBACpC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,CAAC;YAED,IAAI,gBAAgB,IAAI,yBAAyB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/D,MAAM,0BAA0B,CAC9B,WAAW,EACX,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EACvD,IAAI,CAAC,IAAI,CACV,CAAC;YACJ,CAAC;YAED,wEAAwE;YACxE,wEAAwE;YACxE,oEAAoE;YACpE,sEAAsE;YACtE,qCAAqC;YACrC,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,4DAA4D,EAC5D,qBAAqB,CACnB,mBAAmB,EACnB,0BAA0B,CAC3B,EACD,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CACtC,CAAC;YACJ,CAAC;YAED,IAAI,IAAI,CAAC,yBAAyB,IAAI,IAAI,EAAE,CAAC;gBAC3C,iEAAiE;gBACjE,gEAAgE;gBAChE,mCAAmC;gBACnC,IAAI,CAAC,0BAA0B,CAC7B,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CACjD,CAAC,KAAK,CAAC,GAAG,EAAE;oBACX,aAAa;gBACf,CAAC,CAAC,CAAC;YACL,CAAC;YAED,qCAAqC;YACrC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,mEAAmE;gBACnE,IAAI,KAAK,CAAC,6BAA6B,EAAE,CAAC;oBACxC,kDAAkD;oBAClD,+DAA+D;gBACjE,CAAC;qBAAM,CAAC;oBACN,yDAAyD;oBACzD,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC;oBAC3C,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC;oBAC3C,KAAK,CAAC,kCAAkC,GAAG,IAAI,CAAC;gBAClD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,2BAA2B,CACtC,IAAI,GAAqE,EAAE;QAE3E,IAAI,CAAC;YACH,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,2BAA2B;QACtC,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC;QAE/C,qCAAqC;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,EAAE,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;QAED,mEAAmE;QACnE,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CACnE,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAC3D,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,6BAA6B,GAAG,KAAK,CAAC;YAC5C,KAAK,CAAC,6BAA6B,GAAG,KAAK,CAAC;YAC5C,qDAAqD;YACrD,yDAAyD;YACzD,KAAK,CAAC,yBAAyB,GAAG,iBAAiB,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,IAAI,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,eAAe,CAAC,QAAkB;QAC7C,IAAI,CAAC;YACH,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAErD,MAAM,0BAA0B,CAC9B,WAAW,EACX,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EACxD,IAAI,CAAC,IAAI,CACV,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,cAAc,CAAC,QAAkB;QAC5C,IAAI,CAAC;YACH,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,MAAM,0BAA0B,CAC9B,WAAW,EACX,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EACvD,IAAI,CAAC,IAAI,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACI,KAAK,CAAC,mCAAmC,CAC9C,YAAqB;QAErB,IAAI,CAAC;YACH,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC;YAE/C,kDAAkD;YAClD,oBAAoB;YACpB,MAAM,qBAAqB,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC;YACvE,MAAM,uBAAuB,GAAG,qBAAqB;gBACnD,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS;qBACjB,IAAI,CAAC,4DAA4D,CAAC;qBAClE,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;gBACtB,CAAC,CAAC,IAAI,CAAC;YAET,4BAA4B;YAC5B,MAAM,gBAAgB,GACpB,qBAAqB;gBACrB,uBAAuB,EAAE,SAAS,CAAC,yBAAyB;gBAC1D,CAAC,CAAC,MAAM,mCAAmC,CACvC,IAAI,CAAC,uBAAuB,EAC5B,YAAY,CACb,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;gBACnB,CAAC,CAAC,EAAE,CAAC;YAET,6BAA6B;YAC7B,MAAM,uBAAuB,GAAgC,EAAE,CAAC;YAChE,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrD,sEAAsE;oBACtE,kEAAkE;oBAClE,iDAAiD;oBACjD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;oBACnD,MAAM,0BAA0B,GAAG,MAAM,kBAAkB,CACzD,WAAW,EACX,QAAQ,EACR,IAAI,CAAC,IAAI,CACV,CAAC;oBACF,IAAI,0BAA0B,KAAK,IAAI,EAAE,CAAC;wBACxC,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAC7C,WAAW,EACX,0BAA0B,EAC1B,IAAI,CAAC,OAAO,EAAE,EACd,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EACrC,IAAI,CAAC,IAAI,CACV,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;wBAClB,uBAAuB,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;oBACjD,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,aAAa;gBACf,CAAC;YACH,CAAC;YAED,gCAAgC;YAChC,gCAAgC;YAChC,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CACnE,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAC3D,CAAC;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC;YAEzD,wBAAwB;YACxB,MAAM,qBAAqB,GAAoB;gBAC7C,GAAG,6BAA6B,CAAC,gBAAgB,EAAE,OAAO,CAAC;gBAC3D,GAAG,6BAA6B,CAAC,uBAAuB,EAAE,OAAO,CAAC;gBAClE,GAAG,iBAAiB;aACrB,CAAC;YAEF,qBAAqB;YACrB,qBAAqB,CAAC,IAAI,CACxB,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,CAC/B,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;gBAC3C,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC9C,CAAC;YAEF,eAAe;YACf,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,yBAAyB,GAAG,qBAAqB,CAAC;YAC1D,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,2BAA2B,EAC5C,IAAI,CAAC,KAAK,CAAC,yBAAyB,CACrC,CAAC;YAEF,IAAI,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO,qBAAqB,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,sBAAsB,CAAC,IAAmB;QAC/C,MAAM,CACJ,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC3C,uBAAuB,CACxB,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAChD,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,KAAK,IAAI,CAC7C,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,sBAAsB,CAAC,EAAU;QAC5C,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,IAAI,CACnE,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CACzC,CAAC;QAEF,MAAM,CACJ,mBAAmB,EACnB,gDAAgD,CACjD,CAAC;QAEF,MAAM,CACJ,iCAAiC,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAC/D,6BAA6B;QAC3B,+EAA+E;QAC/E,mBAAmB,CAAC,IACtB,+EAA+E;YAC7E,GAAG,iCAAiC;SACrC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,MAAM,CACzD,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CACzC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,yBAAyB,GAAG,OAAO,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,uBAAuB,CAAC,GAAa;QAChD,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,2BAA2B,EAC5C,IAAI,CAAC,KAAK,CAAC,yBAAyB,CACrC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,+BAA+B,CAC1C,aAA2C;QAE3C,IAAI,sBAAsB,GAAa,EAAE,CAAC;QAC1C,IAAI,kCAAkC,GAAa,EAAE,CAAC;QACtD,IAAI,mBAAmB,GAAa,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,CACJ,oBAAoB,EACpB,gCAAgC,EAChC,iBAAiB,EAClB,GAAG,aAAa,CAAC,MAAM,CAOtB,CAAC,gBAAgB,EAAE,YAAY,EAAE,EAAE;gBACjC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;oBACzB,QAAQ,YAAY,CAAC,IAAI,EAAE,CAAC;wBAC1B,KAAK,aAAa,CAAC,qBAAqB;4BACtC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;4BACvC,MAAM;wBACR,KAAK,aAAa,CAAC,IAAI;4BACrB,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;4BACvC,MAAM;wBACR;4BACE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBAC3C,CAAC;gBACH,CAAC;gBACD,OAAO,gBAAgB,CAAC;YAC1B,CAAC,EACD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CACb,CAAC;YAEF,sCAAsC;YACtC,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;gBAEtD,IAAI,WAAW,EAAE,CAAC;oBAChB,sBAAsB,GAAG,oBAAoB,CAAC,GAAG,CAC/C,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAClC,CAAC;oBACF,MAAM,uBAAuB,CAC3B,WAAW,EACX,sBAAsB,EACtB,IAAI,CAAC,IAAI,CACV,CAAC,KAAK,CAAC,GAAG,EAAE;wBACX,sBAAsB,GAAG,EAAE,CAAC;wBAC5B,GAAG,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;oBAC3D,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,uCAAuC;YACvC,IAAI,gCAAgC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,kCAAkC;oBAChC,gCAAgC,CAAC,GAAG,CAClC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAClC,CAAC;YACN,CAAC;YAED,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,mBAAmB,GAAG,iBAAiB,CAAC,GAAG,CACzC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAClC,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;QAED,2DAA2D;QAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,eAAe,GAAG,KAAK,CAAC,6BAA6B,CAAC;YAC5D,MAAM,UAAU,GAAG;gBACjB,GAAG,kCAAkC;gBACrC,GAAG,mBAAmB;aACvB,CAAC;YACF,KAAK,CAAC,6BAA6B,GAAG;gBACpC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,UAAU,CAAC,CAAC;aAChD,CAAC;YAEF,KAAK,CAAC,yBAAyB,GAAG,KAAK,CAAC,yBAAyB,CAAC,GAAG,CACnE,CAAC,YAA2B,EAAE,EAAE;gBAC9B,IACE,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACpC,sBAAsB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,EAChD,CAAC;oBACD,IAAI,YAAY,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;wBAC7C,OAAO;4BACL,GAAG,YAAY;4BACf,MAAM,EAAE,IAAI;4BACZ,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;yBACnC,CAAC;oBACJ,CAAC;oBACD,OAAO,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBAC3C,CAAC;gBACD,OAAO,YAAY,CAAC;YACtB,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,0BAA0B,EAC3C,IAAI,CAAC,KAAK,CAAC,yBAAyB,CACrC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,+BAA+B,CAC1C,YAA2B;QAE3B,IACE,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,IAAI,CACvC,CAAC,oBAAoB,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,KAAK,YAAY,CAAC,EAAE,CACtE,EACD,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,qBAAqB,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAC;QAEpE,IAAI,qBAAqB,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,MAAM,uBAAuB,GAAG,IAAI,GAAG,CACrC,KAAK,CAAC,yBAAyB,CAAC,GAAG,CACjC,CAAC,oBAAoB,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAClD,CACF,CAAC;gBACF,6EAA6E;gBAC7E,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC3D,KAAK,CAAC,yBAAyB,GAAG;wBAChC,qBAAqB;wBACrB,GAAG,KAAK,CAAC,yBAAyB;qBACnC,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,CAAC,OAAO,CACpB,GAAG,cAAc,2BAA2B,EAC5C,IAAI,CAAC,KAAK,CAAC,yBAAyB,CACrC,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,8BAA8B,CACzC,KAAiB;QAEjB,IAAI,CAAC;YACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,MAAM,2BAA2B,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,oCAAoC;QAG/C,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,0BAA0B,EAAE,CAAC;YAEtD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,+BAA+B,GAAG,UAAU,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,qCAAqC,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF","sourcesContent":["import type {\n AuthenticatedUserStorageServiceGetNotificationPreferencesAction,\n AuthenticatedUserStorageServicePutNotificationPreferencesAction,\n NotificationPreferences,\n PerpsPreference,\n SocialAIPreference,\n} from '@metamask/authenticated-user-storage';\nimport {\n DEFAULT_AGENTIC_CLI_PREFERENCES,\n DEFAULT_PRICE_ALERT_PREFERENCES,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangedEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport {\n isValidHexAddress,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type {\n KeyringControllerStateChangeEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n KeyringControllerState,\n} from '@metamask/keyring-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport { assert } from '@metamask/utils';\nimport { debounce } from 'lodash-es';\nimport log from 'loglevel';\n\nimport type {\n NotificationServicesPushControllerStateChangeEvent,\n NotificationServicesPushControllerOnNewNotificationEvent,\n} from '../NotificationServicesPushController/index.js';\nimport type { NotificationServicesPushControllerMethodActions } from '../NotificationServicesPushController/NotificationServicesPushController-method-action-types.js';\nimport { TRIGGER_TYPES } from './constants/notification-schema.js';\nimport type {\n NormalisedAPINotification,\n NotificationsCategory,\n} from './index.js';\nimport type { NotificationServicesControllerMethodActions } from './NotificationServicesController-method-action-types.js';\nimport {\n processAndFilterNotifications,\n safeProcessNotification,\n} from './processors/process-notifications.js';\nimport type { ENV } from './services/api-notifications.js';\nimport {\n getAPINotifications,\n getNotificationsApiConfigCached,\n getNotificationsCategories,\n markNotificationsAsRead,\n updateOnChainNotifications,\n} from './services/api-notifications.js';\nimport { getFeatureAnnouncementNotifications } from './services/feature-announcements.js';\nimport { createPerpOrderNotification } from './services/perp-notifications.js';\nimport type {\n INotification,\n MarkAsReadNotificationsParam,\n} from './types/notification/notification.js';\nimport type { OrderInput } from './types/perps/index.js';\n\n// Unique name for the controller\nconst controllerName = 'NotificationServicesController';\n\nexport const ACCOUNTS_UPDATE_DEBOUNCE_TIME_MS = 1000;\n\n/**\n * State shape for NotificationServicesController\n */\nexport type NotificationServicesControllerState = {\n /**\n * We store and manage accounts that have been seen/visited through the\n * account subscription. This allows us to track and add notifications for new accounts and not previous accounts added.\n */\n subscriptionAccountsSeen: string[];\n\n /**\n * Flag that indicates if the metamask notifications feature has been seen\n */\n isMetamaskNotificationsFeatureSeen: boolean;\n\n /**\n * Flag that indicates if the metamask notifications are enabled\n */\n isNotificationServicesEnabled: boolean;\n\n /**\n * Flag that indicates if the feature announcements are enabled\n */\n isFeatureAnnouncementsEnabled: boolean;\n\n /**\n * List of metamask notifications\n */\n metamaskNotificationsList: INotification[];\n\n /**\n * List of read metamask notifications\n */\n metamaskNotificationsReadList: string[];\n /**\n * List of notification categories\n */\n metamaskNotificationsCategories: NotificationsCategory[];\n /**\n * Flag that indicates that the creating notifications is in progress\n */\n isUpdatingMetamaskNotifications: boolean;\n /**\n * Flag that indicates that the fetching notifications is in progress\n * This is used to show a loading spinner in the UI\n * when fetching notifications\n */\n isFetchingMetamaskNotifications: boolean;\n /**\n * Flag that indicates that fetching notification categories\n * is in progress. Used for readiness checks for categories consumers\n */\n isFetchingMetamaskNotificationsCategories: boolean;\n /**\n * Flag that indicates that the updating notifications for a specific address is in progress\n */\n isUpdatingMetamaskNotificationsAccount: string[];\n /**\n * Flag that indicates that the checking accounts presence is in progress\n */\n isCheckingAccountsPresence: boolean;\n};\n\nconst metadata: StateMetadata<NotificationServicesControllerState> = {\n subscriptionAccountsSeen: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n\n isMetamaskNotificationsFeatureSeen: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isNotificationServicesEnabled: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isFeatureAnnouncementsEnabled: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n metamaskNotificationsList: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n metamaskNotificationsReadList: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n metamaskNotificationsCategories: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n isUpdatingMetamaskNotifications: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isFetchingMetamaskNotifications: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isUpdatingMetamaskNotificationsAccount: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isCheckingAccountsPresence: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isFetchingMetamaskNotificationsCategories: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\nexport const defaultState: NotificationServicesControllerState = {\n subscriptionAccountsSeen: [],\n isMetamaskNotificationsFeatureSeen: false,\n isNotificationServicesEnabled: false,\n isFeatureAnnouncementsEnabled: false,\n metamaskNotificationsList: [],\n metamaskNotificationsReadList: [],\n metamaskNotificationsCategories: [],\n isUpdatingMetamaskNotifications: false,\n isFetchingMetamaskNotifications: false,\n isUpdatingMetamaskNotificationsAccount: [],\n isCheckingAccountsPresence: false,\n isFetchingMetamaskNotificationsCategories: false,\n};\n\nexport type NotificationServicesControllerEnableNotificationsOptions = {\n /**\n * Whether the user has consented to marketing notifications. Used only when\n * notification preferences are being initialized for the first time to seed\n * marketing push notifications.\n */\n hasMarketingConsent?: boolean;\n /**\n * Whether product announcements are enabled. Used only when notification\n * preferences are being initialized for the first time to seed marketing\n * in-app notifications.\n */\n productAnnouncementEnabled?: boolean;\n /**\n * Whether to attempt FCM/device push registration after notification\n * preferences are initialized or refreshed. This does not request OS push\n * permission.\n *\n * @default true\n */\n registerPushNotifications?: boolean;\n};\n\nexport type NotificationServicesControllerCreateOnChainTriggersOptions =\n NotificationServicesControllerEnableNotificationsOptions;\n\nexport type NotificationServicesControllerEnableMetamaskNotificationsOptions =\n NotificationServicesControllerEnableNotificationsOptions;\n\nconst locallyPersistedNotificationTypes = new Set<TRIGGER_TYPES>([\n TRIGGER_TYPES.SNAP,\n]);\n\n/**\n * Hardcoded default Perps notification preferences. Applied when notification\n * preferences are initialized for the first time.\n */\nexport const DEFAULT_PERPS_PREFERENCES: PerpsPreference = {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n};\n\n/**\n * Hardcoded default Social AI notification preferences. Applied when\n * notification preferences are initialized for the first time.\n */\nexport const DEFAULT_SOCIAL_AI_PREFERENCES: Required<SocialAIPreference> = {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n txAmountLimit: 500,\n mutedTraderProfileIds: [],\n};\n\nexport {\n DEFAULT_AGENTIC_CLI_PREFERENCES,\n DEFAULT_PRICE_ALERT_PREFERENCES,\n} from '@metamask/authenticated-user-storage';\n\n/**\n * Returns the subset of `accounts` that has a wallet-activity subscription in\n * the Trigger API, which is the source of truth for the per-address enabled bit.\n *\n * The address universe is always supplied by the caller from the keyring, so the\n * result cannot contain an address this installation does not hold.\n *\n * @param bearerToken - JWT used to query the Trigger API.\n * @param accounts - The keyring accounts to check.\n * @param env - The environment to use for the Trigger API call.\n * @returns The enabled addresses, as returned by the Trigger API, or `null` if\n * the Trigger API could not be read.\n */\nconst getEnabledAccounts = async (\n bearerToken: string,\n accounts: string[],\n env: ENV,\n): Promise<string[] | null> => {\n const triggerConfig = await getNotificationsApiConfigCached(\n bearerToken,\n accounts,\n env,\n );\n\n if (triggerConfig === null) {\n return null;\n }\n\n return triggerConfig\n .filter((addressConfig) => Boolean(addressConfig.enabled))\n .map((addressConfig) => addressConfig.address);\n};\n\n/**\n * Builds a fresh `NotificationPreferences` blob using hardcoded defaults for\n * Perps, Social AI, and Agentic CLI and the user's\n * marketing/product-announcement flags.\n *\n * `walletActivity` is written only because the blob schema requires the field;\n * nothing reads it back. Both channels are always on, and subscriptions are\n * held per address by the Trigger API rather than here — addresses are scoped\n * to a keyring, but this blob is keyed by canonical profile ID, which pairing\n * shares across every SRP belonging to the same user.\n *\n * @param hasMarketingConsent - Whether marketing push notifications should be enabled.\n * @param productAnnouncementEnabled - Whether marketing in-app notifications should be enabled.\n * @returns A complete `NotificationPreferences` object.\n */\nconst buildFreshPreferences = (\n hasMarketingConsent: boolean,\n productAnnouncementEnabled: boolean,\n): NotificationPreferences => ({\n walletActivity: {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n accounts: [],\n },\n marketing: {\n inAppNotificationsEnabled: productAnnouncementEnabled,\n pushNotificationsEnabled: hasMarketingConsent,\n },\n perps: { ...DEFAULT_PERPS_PREFERENCES },\n socialAI: { ...DEFAULT_SOCIAL_AI_PREFERENCES },\n agenticCli: { ...DEFAULT_AGENTIC_CLI_PREFERENCES },\n priceAlerts: { ...DEFAULT_PRICE_ALERT_PREFERENCES },\n});\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'init',\n 'enablePushNotifications',\n 'disablePushNotifications',\n 'checkAccountsPresence',\n 'setFeatureAnnouncementsEnabled',\n 'createOnChainTriggers',\n 'enableMetamaskNotifications',\n 'disableNotificationServices',\n 'disableAccounts',\n 'enableAccounts',\n 'fetchAndUpdateMetamaskNotifications',\n 'fetchMetamaskNotificationsCategories',\n 'getNotificationsByType',\n 'deleteNotificationById',\n 'deleteNotificationsById',\n 'markMetamaskNotificationsAsRead',\n 'updateMetamaskNotificationsList',\n 'sendPerpPlaceOrderNotification',\n] as const;\n\nexport type NotificationServicesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NotificationServicesControllerState\n >;\n\n// Messenger Actions\nexport type Actions =\n | NotificationServicesControllerGetStateAction\n | NotificationServicesControllerMethodActions;\n\n// Allowed Actions\ntype AllowedActions =\n // Keyring Controller Requests\n | KeyringControllerGetStateAction\n // Auth Controller Requests\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction\n | AuthenticationController.AuthenticationControllerIsSignedInAction\n | AuthenticationController.AuthenticationControllerPerformSignInAction\n // Authenticated User Storage Requests\n | AuthenticatedUserStorageServiceGetNotificationPreferencesAction\n | AuthenticatedUserStorageServicePutNotificationPreferencesAction\n // Push Notifications Controller Requests\n | NotificationServicesPushControllerMethodActions;\n\n// Events\nexport type NotificationServicesControllerStateChangeEvent =\n ControllerStateChangedEvent<\n typeof controllerName,\n NotificationServicesControllerState\n >;\n\nexport type NotificationListUpdatedEvent = {\n type: `${typeof controllerName}:notificationsListUpdated`;\n payload: [INotification[]];\n};\n\nexport type MarkNotificationsAsReadEvent = {\n type: `${typeof controllerName}:markNotificationsAsRead`;\n payload: [INotification[]];\n};\n\n// Events\nexport type Events =\n | NotificationServicesControllerStateChangeEvent\n | NotificationListUpdatedEvent\n | MarkNotificationsAsReadEvent;\n\n// Allowed Events\ntype AllowedEvents =\n // Keyring Events\n | KeyringControllerStateChangeEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n // Push Notification Events\n | NotificationServicesPushControllerOnNewNotificationEvent\n | NotificationServicesPushControllerStateChangeEvent;\n\n// Type for the messenger of NotificationServicesController\nexport type NotificationServicesControllerMessenger = Messenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events | AllowedEvents\n>;\n\ntype FeatureAnnouncementEnv = {\n spaceId: string;\n accessToken: string;\n platform: 'extension' | 'mobile';\n platformVersion?: string;\n};\n\n/**\n * Controller that enables wallet notifications and feature announcements\n */\nexport class NotificationServicesController extends BaseController<\n typeof controllerName,\n NotificationServicesControllerState,\n NotificationServicesControllerMessenger\n> {\n readonly #keyringController = {\n isUnlocked: false,\n\n setupLockedStateSubscriptions: (onUnlock: () => Promise<void>): void => {\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#keyringController.isUnlocked = isUnlocked;\n\n this.messenger.subscribe('KeyringController:unlock', (): void => {\n this.#keyringController.isUnlocked = true;\n // messaging system cannot await promises\n // we don't need to wait for a result on this.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n onUnlock();\n });\n\n this.messenger.subscribe('KeyringController:lock', (): void => {\n this.#keyringController.isUnlocked = false;\n });\n },\n };\n\n readonly #auth = {\n getBearerToken: async (): Promise<string | null> => {\n return await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n },\n isSignedIn: (): boolean => {\n return this.messenger.call('AuthenticationController:isSignedIn');\n },\n signIn: async (): Promise<string[]> => {\n return await this.messenger.call(\n 'AuthenticationController:performSignIn',\n );\n },\n };\n\n readonly #pushNotifications = {\n // Flag to check is notifications have been setup when the browser/extension is initialized.\n // We want to re-initialize push notifications when the browser/extension is refreshed\n // To ensure we subscribe to the most up-to-date notifications\n isSetup: false,\n\n subscribeToPushNotifications: async (): Promise<void> => {\n await this.messenger.call(\n 'NotificationServicesPushController:subscribeToPushNotifications',\n );\n },\n enablePushNotifications: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:enablePushNotifications',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n addPushNotificationLinks: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:addPushNotificationLinks',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n disablePushNotifications: async (): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:disablePushNotifications',\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n deletePushNotificationLinks: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:deletePushNotificationLinks',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n subscribe: (): void => {\n // Coalesce pushes: at most one fetch in-flight, one queued.\n // Re-fetch after completion because the new row may not be visible yet when the push arrives.\n let pushFetchInFlight = false;\n let pendingPushRefetch = false;\n\n const fetchOnPush = async (): Promise<void> => {\n pushFetchInFlight = true;\n try {\n await this.fetchAndUpdateMetamaskNotifications();\n } finally {\n pushFetchInFlight = false;\n if (pendingPushRefetch) {\n pendingPushRefetch = false;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fetchOnPush();\n }\n }\n };\n\n this.messenger.subscribe(\n 'NotificationServicesPushController:onNewNotifications',\n (): void => {\n if (pushFetchInFlight) {\n pendingPushRefetch = true;\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fetchOnPush();\n },\n );\n },\n initializePushNotifications: async (): Promise<void> => {\n if (!this.state.isNotificationServicesEnabled) {\n return;\n }\n if (this.#pushNotifications.isSetup) {\n return;\n }\n\n // If wallet is unlocked, we can create a fresh push subscription\n // Otherwise we can subscribe to original subscription\n try {\n if (!this.#keyringController.isUnlocked) {\n throw new Error('Keyring is locked');\n }\n await this.enablePushNotifications();\n this.#pushNotifications.isSetup = true;\n } catch {\n await this.#pushNotifications\n .subscribeToPushNotifications()\n .catch(() => {\n // do nothing\n });\n }\n },\n };\n\n readonly #accounts = {\n // Flag to ensure we only setup once\n isNotificationAccountsSetup: false,\n\n getNotificationAccounts: (): string[] | null => {\n const { keyrings } = this.messenger.call('KeyringController:getState');\n const keyringAccounts = [\n ...new Set(\n keyrings\n .flatMap((keyring) => keyring.accounts)\n .map((address) => {\n try {\n return toChecksumHexAddress(address);\n } catch {\n return null;\n }\n })\n .filter(\n (address): address is string =>\n address !== null && isValidHexAddress(address),\n ),\n ),\n ];\n return keyringAccounts.length > 0 ? keyringAccounts : null;\n },\n\n /**\n * Used to get list of addresses from keyring (wallet addresses)\n *\n * @returns addresses removed, added, and latest list of addresses\n */\n listAccounts: (): {\n accountsAdded: string[];\n accountsRemoved: string[];\n accounts: string[];\n } => {\n // Get previous and current account sets\n const nonChecksumAccounts = this.#accounts.getNotificationAccounts();\n if (!nonChecksumAccounts) {\n return {\n accountsAdded: [],\n accountsRemoved: [],\n accounts: [],\n };\n }\n\n const accounts = nonChecksumAccounts\n .map((address) => toChecksumHexAddress(address))\n .filter((address) => isValidHexAddress(address));\n const currentAccountsSet = new Set(accounts);\n const prevAccountsSet = new Set(this.state.subscriptionAccountsSeen);\n\n // Invalid value you cannot have zero accounts\n // Only occurs when the Accounts controller is initializing.\n if (accounts.length === 0) {\n return {\n accountsAdded: [],\n accountsRemoved: [],\n accounts: [],\n };\n }\n\n // Calculate added and removed addresses\n const accountsAdded = accounts.filter(\n (account) => !prevAccountsSet.has(account),\n );\n const accountsRemoved = [...prevAccountsSet.values()].filter(\n (account) => !currentAccountsSet.has(account),\n );\n\n // Update accounts seen\n this.update((state) => {\n state.subscriptionAccountsSeen = [...currentAccountsSet];\n });\n\n return {\n accountsAdded,\n accountsRemoved,\n accounts,\n };\n },\n\n /**\n * Initializes the cache/previous list. This is handy so we have an accurate in-mem state of the previous list of accounts.\n */\n initialize: (): void => {\n if (\n this.#keyringController.isUnlocked &&\n !this.#accounts.isNotificationAccountsSetup\n ) {\n this.#accounts.listAccounts();\n this.#accounts.isNotificationAccountsSetup = true;\n }\n },\n\n /**\n * Subscription to any state change in the keyring controller (aka wallet accounts).\n * We can call the `listAccounts` defined above to find out about any accounts added, removed\n * And call effects to subscribe/unsubscribe to notifications.\n */\n subscribe: (): void => {\n const debouncedUpdateAccountNotifications = debounce(\n async (\n totalAccounts?: number,\n prevTotalAccounts?: number,\n ): Promise<void> => {\n const hasTotalAccountsChanged = totalAccounts !== prevTotalAccounts;\n if (\n !this.state.isNotificationServicesEnabled ||\n !hasTotalAccountsChanged\n ) {\n return;\n }\n\n const { accountsAdded, accountsRemoved } =\n this.#accounts.listAccounts();\n\n const promises: Promise<unknown>[] = [];\n if (accountsAdded.length > 0) {\n promises.push(this.enableAccounts(accountsAdded));\n // The push link covers every notification source for an address,\n // so it follows account ownership rather than the wallet-activity toggle.\n promises.push(\n this.#pushNotifications.addPushNotificationLinks(accountsAdded),\n );\n }\n if (accountsRemoved.length > 0) {\n promises.push(this.disableAccounts(accountsRemoved));\n promises.push(\n this.#pushNotifications.deletePushNotificationLinks(\n accountsRemoved,\n ),\n );\n }\n await Promise.allSettled(promises);\n },\n ACCOUNTS_UPDATE_DEBOUNCE_TIME_MS,\n );\n\n this.messenger.subscribe(\n 'KeyringController:stateChange',\n // Using void return for async callback - result is intentionally ignored\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n debouncedUpdateAccountNotifications,\n (state: KeyringControllerState): number => {\n return (\n state?.keyrings?.flatMap?.((keyring) => keyring.accounts)?.length ??\n 0\n );\n },\n );\n },\n };\n\n readonly #locale: () => string;\n\n readonly #featureAnnouncementEnv: FeatureAnnouncementEnv;\n\n readonly #env: ENV;\n\n /**\n * Creates a NotificationServicesController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n * @param args.env - environment variables for a given controller.\n * @param args.env.featureAnnouncements - env variables for feature announcements.\n * @param args.env.locale - users locale for better dynamic server notifications\n * @param args.env.env - the environment to use for the controller\n */\n constructor({\n messenger,\n state,\n env,\n }: {\n messenger: NotificationServicesControllerMessenger;\n state?: Partial<NotificationServicesControllerState>;\n env: {\n featureAnnouncements: FeatureAnnouncementEnv;\n locale?: () => string;\n env?: ENV;\n };\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...state },\n });\n\n this.#featureAnnouncementEnv = env.featureAnnouncements;\n this.#locale = env.locale ?? ((): string => 'en');\n this.#env = env.env ?? 'prd';\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n this.#clearLoadingStates();\n }\n\n init(): void {\n this.#keyringController.setupLockedStateSubscriptions(\n async (): Promise<void> => {\n this.#accounts.initialize();\n await this.#pushNotifications.initializePushNotifications();\n },\n );\n\n this.#accounts.initialize();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#pushNotifications.initializePushNotifications();\n this.#accounts.subscribe();\n this.#pushNotifications.subscribe();\n }\n\n #clearLoadingStates(): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotifications = false;\n state.isCheckingAccountsPresence = false;\n state.isFetchingMetamaskNotifications = false;\n state.isUpdatingMetamaskNotificationsAccount = [];\n });\n }\n\n #assertAuthEnabled(): void {\n if (!this.#auth.isSignedIn()) {\n this.update((state) => {\n state.isNotificationServicesEnabled = false;\n });\n throw new Error('User is not signed in.');\n }\n }\n\n async #enableAuth(): Promise<void> {\n const isSignedIn = this.#auth.isSignedIn();\n if (!isSignedIn) {\n await this.#auth.signIn();\n }\n }\n\n async #getBearerToken(): Promise<{ bearerToken: string }> {\n this.#assertAuthEnabled();\n\n const bearerToken = await this.#auth.getBearerToken();\n\n if (!bearerToken) {\n throw new Error('Missing BearerToken');\n }\n\n return { bearerToken };\n }\n\n /**\n * Registers this device for push notifications on the given addresses.\n *\n * Always register the device token, including when no addresses are enabled.\n * The links API rejects an empty list without removing the token.\n *\n * @param addresses - The addresses to receive push notifications for.\n */\n async #registerPushNotifications(addresses: string[]): Promise<void> {\n await this.#pushNotifications.enablePushNotifications(addresses);\n }\n\n /**\n * Sets the state of notification creation process.\n *\n * This method updates the `isUpdatingMetamaskNotifications` state, which can be used to indicate\n * whether the notification creation process is currently active or not. This is useful\n * for UI elements that need to reflect the state of ongoing operations, such as loading\n * indicators or disabled buttons during processing.\n *\n * @param isUpdatingMetamaskNotifications - A boolean value representing the new state of the notification creation process.\n */\n #setIsUpdatingMetamaskNotifications(\n isUpdatingMetamaskNotifications: boolean,\n ): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotifications = isUpdatingMetamaskNotifications;\n });\n }\n\n /**\n * Updates the state to indicate whether fetching of MetaMask notifications is in progress.\n *\n * This method is used to set the `isFetchingMetamaskNotifications` state, which can be utilized\n * to show or hide loading indicators in the UI when notifications are being fetched.\n *\n * @param isFetchingMetamaskNotifications - A boolean value representing the fetching state.\n */\n #setIsFetchingMetamaskNotifications(\n isFetchingMetamaskNotifications: boolean,\n ): void {\n this.update((state) => {\n state.isFetchingMetamaskNotifications = isFetchingMetamaskNotifications;\n });\n }\n\n /**\n * Updates the state to indicate that the checking of accounts presence is in progress.\n *\n * This method modifies the `isCheckingAccountsPresence` state, which can be used to manage UI elements\n * that depend on the status of account presence checks, such as displaying loading indicators or disabling\n * buttons while the check is ongoing.\n *\n * @param isCheckingAccountsPresence - A boolean value indicating whether the account presence check is currently active.\n */\n #setIsCheckingAccountsPresence(isCheckingAccountsPresence: boolean): void {\n this.update((state) => {\n state.isCheckingAccountsPresence = isCheckingAccountsPresence;\n });\n }\n\n /**\n * Updates the state to indicate that account updates are in progress.\n * Removes duplicate accounts before updating the state.\n *\n * @param accounts - The accounts being updated.\n */\n #updateUpdatingAccountsState(accounts: string[]): void {\n this.update((state) => {\n const uniqueAccounts = new Set([\n ...state.isUpdatingMetamaskNotificationsAccount,\n ...accounts,\n ]);\n state.isUpdatingMetamaskNotificationsAccount = Array.from(uniqueAccounts);\n });\n }\n\n /**\n * Clears the state indicating that account updates are complete.\n *\n * @param accounts - The accounts that have finished updating.\n */\n #clearUpdatingAccountsState(accounts: string[]): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotificationsAccount =\n state.isUpdatingMetamaskNotificationsAccount.filter(\n (existingAccount) => !accounts.includes(existingAccount),\n );\n });\n }\n\n /**\n * Updates the state to indicate whether fetching of MetaMask notification categories is in progress.\n *\n * This method is used to set the `isFetchingMetamaskNotificationsCategories` state, which can be utilized\n * to show or hide loading indicators in the UI when notifications categories are being fetched.\n *\n * @param isFetchingNotificationCategories - A boolean value representing the fetching state.\n */\n #setIsFetchingNotificationsCategories(\n isFetchingNotificationCategories: boolean,\n ): void {\n this.update((state) => {\n state.isFetchingMetamaskNotificationsCategories =\n isFetchingNotificationCategories;\n });\n }\n\n /**\n * Public method to expose enabling push notifications\n */\n public async enablePushNotifications(): Promise<void> {\n try {\n const { accounts } = this.#accounts.listAccounts();\n if (!this.#keyringController.isUnlocked || accounts.length === 0) {\n // no keyring accounts could be caused by calling this function while keyring is locked\n // it does not mean the user does not have any enabled accounts on Trigger API\n return;\n }\n\n // The push link is this device's set of held addresses. Wallet-activity\n // delivery stays gated by the Trigger API, so a disabled account remains linked.\n await this.#registerPushNotifications(\n accounts.map((address) => address.toLowerCase()),\n );\n } catch {\n // Do nothing, failing silently.\n }\n }\n\n /**\n * Public method to expose disabling push notifications\n */\n public async disablePushNotifications(): Promise<void> {\n await this.#pushNotifications.disablePushNotifications();\n }\n\n public async checkAccountsPresence(\n accounts: string[],\n ): Promise<Record<string, boolean>> {\n try {\n this.#setIsCheckingAccountsPresence(true);\n\n const { bearerToken } = await this.#getBearerToken();\n const triggerConfig = await getNotificationsApiConfigCached(\n bearerToken,\n accounts,\n this.#env,\n );\n\n if (triggerConfig === null) {\n // Reporting every account as disabled would misrepresent the user's\n // settings, so surface the failure instead.\n throw new Error('Failed to read wallet-activity subscriptions');\n }\n\n const enabledByAddress = new Map(\n triggerConfig.map((addressConfig) => [\n addressConfig.address.toLowerCase(),\n Boolean(addressConfig.enabled),\n ]),\n );\n\n const result: Record<string, boolean> = {};\n for (const address of accounts) {\n result[address] = enabledByAddress.get(address.toLowerCase()) ?? false;\n }\n return result;\n } catch (error) {\n log.error('Failed to check accounts presence', error);\n throw error;\n } finally {\n this.#setIsCheckingAccountsPresence(false);\n }\n }\n\n /**\n * Sets the enabled state of feature announcements.\n *\n * **Action** - used in the notification settings to enable/disable feature announcements.\n *\n * @param featureAnnouncementsEnabled - A boolean value indicating the desired enabled state of the feature announcements.\n * @async\n * @throws {Error} If fails to update\n */\n public async setFeatureAnnouncementsEnabled(\n featureAnnouncementsEnabled: boolean,\n ): Promise<void> {\n try {\n this.update((state) => {\n state.isFeatureAnnouncementsEnabled = featureAnnouncementsEnabled;\n });\n } catch (error) {\n log.error('Unable to toggle feature announcements', error);\n throw new Error('Unable to toggle feature announcements');\n }\n }\n\n /**\n * This creates/re-creates on-chain triggers defined in User Storage.\n *\n * **Action** - Used during Sign In / Enabling of notifications.\n *\n * Notification preferences are initialized only when\n * {@link AuthenticatedUserStorageService} has no stored preferences yet.\n * Existing preferences are left as-is.\n *\n * @param opts - optional options to mutate this functionality\n * @param opts.hasMarketingConsent - The user's marketing-consent flag.\n * Used only during initialization to seed marketing push notifications.\n * @param opts.productAnnouncementEnabled - The user's product-announcement flag.\n * Used only during initialization to seed marketing in-app notifications.\n * @param opts.registerPushNotifications - Whether to attempt FCM/device push registration.\n * @returns The updated or newly created user storage.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async createOnChainTriggers(\n opts: NotificationServicesControllerCreateOnChainTriggersOptions = {},\n ): Promise<void> {\n try {\n this.#setIsUpdatingMetamaskNotifications(true);\n\n const { accounts } = this.#accounts.listAccounts();\n if (!this.#keyringController.isUnlocked || accounts.length === 0) {\n // no keyring accounts could be caused by calling this function while keyring is locked\n // it does not mean the user does not have any enabled accounts on Trigger API\n return;\n }\n\n const { bearerToken } = await this.#getBearerToken();\n\n // 1. Read existing AUS notification preferences. Their absence is what\n // marks a first-time setup, and they are initialized in step 3.\n const preferences = await this.messenger.call(\n 'AuthenticatedUserStorageService:getNotificationPreferences',\n );\n\n const hasMarketingConsent = Boolean(opts?.hasMarketingConsent);\n const productAnnouncementEnabled = Boolean(\n opts?.productAnnouncementEnabled,\n );\n\n const isFirstTimeSetup = preferences === null;\n\n // 2. Subscribe the keyring's accounts on first-time setup only.\n //\n // This method also runs on the daily re-subscribe, so the absence of a\n // preferences blob — not the absence of subscriptions — is what marks a\n // genuine first-time setup. Keying off \"no subscriptions\" would re-enable\n // every account daily for a user who had turned them all off.\n //\n // Even at first-time setup, existing subscriptions win: a user upgrading\n // from a client that never wrote a preferences blob keeps whichever\n // accounts they had already disabled.\n const accountsWithNotifications = await getEnabledAccounts(\n bearerToken,\n accounts,\n this.#env,\n );\n\n if (accountsWithNotifications === null) {\n // An unreadable subscription list is not an empty one. Subscribing\n // every account here would re-enable ones the user had turned off,\n // so fail and let the caller retry.\n throw new Error('Failed to read wallet-activity subscriptions');\n }\n\n if (isFirstTimeSetup && accountsWithNotifications.length === 0) {\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: true })),\n this.#env,\n );\n }\n\n // 3. Initialize the preferences blob, only once the subscriptions above\n // are in place. Its existence is what makes the next run a re-subscribe\n // rather than a first-time setup, so writing it earlier would let a\n // failed subscribe leave the user enabled with no accounts subscribed\n // and no second chance to seed them.\n if (isFirstTimeSetup) {\n await this.messenger.call(\n 'AuthenticatedUserStorageService:putNotificationPreferences',\n buildFreshPreferences(\n hasMarketingConsent,\n productAnnouncementEnabled,\n ),\n this.#featureAnnouncementEnv.platform,\n );\n }\n\n if (opts.registerPushNotifications ?? true) {\n // Link this device to every address it holds. Clients request OS\n // permission separately, and wallet activity stays gated by the\n // Trigger API subscriptions above.\n this.#registerPushNotifications(\n accounts.map((address) => address.toLowerCase()),\n ).catch(() => {\n // Do Nothing\n });\n }\n\n // Update the state of the controller\n this.update((state) => {\n // User is re-subscribing (daily resub to get latest notifications)\n if (state.isNotificationServicesEnabled) {\n // Keep their existing preferences on re-subscribe\n // No state updates needed - preserving user's current settings\n } else {\n // User is turning on notifications from a disabled state\n state.isNotificationServicesEnabled = true;\n state.isFeatureAnnouncementsEnabled = true;\n state.isMetamaskNotificationsFeatureSeen = true;\n }\n });\n } catch (error) {\n log.error('Failed to create On Chain triggers', error);\n throw new Error('Failed to create On Chain triggers');\n } finally {\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n }\n\n /**\n * Enables all MetaMask notifications for the user.\n * This is identical flow when initializing notifications for the first time.\n *\n * @param opts - Optional options to mutate this functionality.\n * @throws {Error} If there is an error during the process of enabling notifications.\n */\n public async enableMetamaskNotifications(\n opts: NotificationServicesControllerEnableMetamaskNotificationsOptions = {},\n ): Promise<void> {\n try {\n this.#setIsUpdatingMetamaskNotifications(true);\n await this.#enableAuth();\n await this.createOnChainTriggers(opts);\n } catch (error) {\n log.error('Unable to enable notifications', error);\n throw new Error('Unable to enable notifications');\n } finally {\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n }\n\n /**\n * Disables all MetaMask notifications for the user.\n * This method ensures that the user is authenticated, retrieves all linked accounts,\n * and disables on-chain triggers for each account. It also sets the global notification\n * settings for MetaMask, feature announcements to false.\n *\n * @throws {Error} If the user is not authenticated or if there is an error during the process.\n */\n public async disableNotificationServices(): Promise<void> {\n this.#setIsUpdatingMetamaskNotifications(true);\n\n // Attempt Disable Push Notifications\n try {\n await this.#pushNotifications.disablePushNotifications();\n } catch {\n // Do nothing\n }\n\n // Update State: remove non-permitted notifications & disable flags\n const snapNotifications = this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === TRIGGER_TYPES.SNAP,\n );\n this.update((state) => {\n state.isNotificationServicesEnabled = false;\n state.isFeatureAnnouncementsEnabled = false;\n // reassigning the notifications list with just snaps\n // since the disable shouldn't affect snaps notifications\n state.metamaskNotificationsList = snapNotifications;\n });\n\n // Finish Updating State\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n\n /**\n * Disables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. The device's FCM links stay in place,\n * because those links deliver every notification source for an address.\n *\n * **Action** - When a user disables wallet activity for a given account.\n *\n * @param accounts - The accounts whose wallet-activity subscriptions are disabled.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async disableAccounts(accounts: string[]): Promise<void> {\n try {\n this.#updateUpdatingAccountsState(accounts);\n const { bearerToken } = await this.#getBearerToken();\n\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: false })),\n this.#env,\n );\n } catch {\n throw new Error('Failed to delete OnChain triggers');\n } finally {\n this.#clearUpdatingAccountsState(accounts);\n }\n }\n\n /**\n * Enables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. Linking the device token is handled\n * when the account is added or when notifications are enabled.\n *\n * **Action** - When a user enables wallet activity for an account.\n *\n * @param accounts - List of accounts to subscribe.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async enableAccounts(accounts: string[]): Promise<void> {\n try {\n this.#updateUpdatingAccountsState(accounts);\n\n const { bearerToken } = await this.#getBearerToken();\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: true })),\n this.#env,\n );\n } catch (error) {\n log.error('Failed to update OnChain triggers', error);\n throw new Error('Failed to update OnChain triggers');\n } finally {\n this.#clearUpdatingAccountsState(accounts);\n }\n }\n\n /**\n * Fetches the list of metamask notifications.\n * This includes OnChain notifications; Feature Announcements; and Snap Notifications.\n *\n * **Action** - When a user views the notification list page/dropdown\n *\n * @param previewToken - the preview token to use if needed\n * @returns A promise that resolves to the list of notifications.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async fetchAndUpdateMetamaskNotifications(\n previewToken?: string,\n ): Promise<INotification[]> {\n try {\n this.#setIsFetchingMetamaskNotifications(true);\n\n // This is used by Feature Announcement & On Chain\n // Not used by Snaps\n const isGlobalNotifsEnabled = this.state.isNotificationServicesEnabled;\n const notificationPreferences = isGlobalNotifsEnabled\n ? await this.messenger\n .call('AuthenticatedUserStorageService:getNotificationPreferences')\n .catch(() => null)\n : null;\n\n // Raw Feature Notifications\n const rawAnnouncements =\n isGlobalNotifsEnabled &&\n notificationPreferences?.marketing.inAppNotificationsEnabled\n ? await getFeatureAnnouncementNotifications(\n this.#featureAnnouncementEnv,\n previewToken,\n ).catch(() => [])\n : [];\n\n // Raw On Chain Notifications\n const rawOnChainNotifications: NormalisedAPINotification[] = [];\n if (isGlobalNotifsEnabled) {\n try {\n const { bearerToken } = await this.#getBearerToken();\n // Addresses come from the keyring, so this installation can only ever\n // ask for activity on accounts it actually holds. The Trigger API\n // narrows that to the ones the user has enabled.\n const { accounts } = this.#accounts.listAccounts();\n const addressesWithNotifications = await getEnabledAccounts(\n bearerToken,\n accounts,\n this.#env,\n );\n if (addressesWithNotifications !== null) {\n const notifications = await getAPINotifications(\n bearerToken,\n addressesWithNotifications,\n this.#locale(),\n this.#featureAnnouncementEnv.platform,\n this.#env,\n ).catch(() => []);\n rawOnChainNotifications.push(...notifications);\n }\n } catch {\n // Do nothing\n }\n }\n\n // Snap Notifications (original)\n // We do not want to remove them\n const snapNotifications = this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === TRIGGER_TYPES.SNAP,\n );\n\n const readIds = this.state.metamaskNotificationsReadList;\n\n // Combine Notifications\n const metamaskNotifications: INotification[] = [\n ...processAndFilterNotifications(rawAnnouncements, readIds),\n ...processAndFilterNotifications(rawOnChainNotifications, readIds),\n ...snapNotifications,\n ];\n\n // Sort Notifications\n metamaskNotifications.sort(\n (notificationA, notificationB) =>\n new Date(notificationB.createdAt).getTime() -\n new Date(notificationA.createdAt).getTime(),\n );\n\n // Update State\n this.update((state) => {\n state.metamaskNotificationsList = metamaskNotifications;\n });\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n\n this.#setIsFetchingMetamaskNotifications(false);\n return metamaskNotifications;\n } catch (error) {\n this.#setIsFetchingMetamaskNotifications(false);\n log.error('Failed to fetch notifications', error);\n throw new Error('Failed to fetch notifications');\n }\n }\n\n /**\n * Gets the specified type of notifications from state.\n *\n * @param type - The trigger type.\n * @returns An array of notifications of the passed in type.\n * @throws Throws an error if an invalid trigger type is passed.\n */\n public getNotificationsByType(type: TRIGGER_TYPES): INotification[] {\n assert(\n Object.values(TRIGGER_TYPES).includes(type),\n 'Invalid trigger type.',\n );\n return this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === type,\n );\n }\n\n /**\n * Used to delete a notification by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param id - The id of the notification to delete.\n */\n public async deleteNotificationById(id: string): Promise<void> {\n const fetchedNotification = this.state.metamaskNotificationsList.find(\n (notification) => notification.id === id,\n );\n\n assert(\n fetchedNotification,\n 'The notification to be deleted does not exist.',\n );\n\n assert(\n locallyPersistedNotificationTypes.has(fetchedNotification.type),\n `The notification type of \"${\n // notifications are guaranteed to have type properties which equate to strings\n fetchedNotification.type as string\n }\" is not locally persisted, only the following types can use this function: ${[\n ...locallyPersistedNotificationTypes,\n ].join(', ')}.`,\n );\n\n const newList = this.state.metamaskNotificationsList.filter(\n (notification) => notification.id !== id,\n );\n\n this.update((state) => {\n state.metamaskNotificationsList = newList;\n });\n }\n\n /**\n * Used to batch delete notifications by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param ids - The ids of the notifications to delete.\n */\n public async deleteNotificationsById(ids: string[]): Promise<void> {\n for (const id of ids) {\n await this.deleteNotificationById(id);\n }\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n }\n\n /**\n * Marks specified metamask notifications as read.\n *\n * @param notifications - An array of notifications to be marked as read. Each notification should include its type and read status.\n * @returns A promise that resolves when the operation is complete.\n */\n public async markMetamaskNotificationsAsRead(\n notifications: MarkAsReadNotificationsParam,\n ): Promise<void> {\n let onchainNotificationIds: string[] = [];\n let featureAnnouncementNotificationIds: string[] = [];\n let snapNotificationIds: string[] = [];\n\n try {\n const [\n onChainNotifications,\n featureAnnouncementNotifications,\n snapNotifications,\n ] = notifications.reduce<\n [\n MarkAsReadNotificationsParam,\n MarkAsReadNotificationsParam,\n MarkAsReadNotificationsParam,\n ]\n >(\n (allNotifications, notification) => {\n if (!notification.isRead) {\n switch (notification.type) {\n case TRIGGER_TYPES.FEATURES_ANNOUNCEMENT:\n allNotifications[1].push(notification);\n break;\n case TRIGGER_TYPES.SNAP:\n allNotifications[2].push(notification);\n break;\n default:\n allNotifications[0].push(notification);\n }\n }\n return allNotifications;\n },\n [[], [], []],\n );\n\n // Mark On-Chain Notifications as Read\n if (onChainNotifications.length > 0) {\n const bearerToken = await this.#auth.getBearerToken();\n\n if (bearerToken) {\n onchainNotificationIds = onChainNotifications.map(\n (notification) => notification.id,\n );\n await markNotificationsAsRead(\n bearerToken,\n onchainNotificationIds,\n this.#env,\n ).catch(() => {\n onchainNotificationIds = [];\n log.warn('Unable to mark onchain notifications as read');\n });\n }\n }\n\n // Mark Off-Chain notifications as Read\n if (featureAnnouncementNotifications.length > 0) {\n featureAnnouncementNotificationIds =\n featureAnnouncementNotifications.map(\n (notification) => notification.id,\n );\n }\n\n if (snapNotifications.length > 0) {\n snapNotificationIds = snapNotifications.map(\n (notification) => notification.id,\n );\n }\n } catch (error) {\n log.warn('Something failed when marking notifications as read', error);\n }\n\n // Update the state (state is also used on counter & badge)\n this.update((state) => {\n const currentReadList = state.metamaskNotificationsReadList;\n const newReadIds = [\n ...featureAnnouncementNotificationIds,\n ...snapNotificationIds,\n ];\n state.metamaskNotificationsReadList = [\n ...new Set([...currentReadList, ...newReadIds]),\n ];\n\n state.metamaskNotificationsList = state.metamaskNotificationsList.map(\n (notification: INotification) => {\n if (\n newReadIds.includes(notification.id) ||\n onchainNotificationIds.includes(notification.id)\n ) {\n if (notification.type === TRIGGER_TYPES.SNAP) {\n return {\n ...notification,\n isRead: true,\n readDate: new Date().toISOString(),\n };\n }\n return { ...notification, isRead: true };\n }\n return notification;\n },\n );\n });\n\n this.messenger.publish(\n `${controllerName}:markNotificationsAsRead`,\n this.state.metamaskNotificationsList,\n );\n }\n\n /**\n * Updates the list of MetaMask notifications by adding a new notification at the beginning of the list.\n * This method ensures that the most recent notification is displayed first in the UI.\n *\n * @param notification - The new notification object to be added to the list.\n * @returns A promise that resolves when the notification list has been successfully updated.\n */\n public async updateMetamaskNotificationsList(\n notification: INotification,\n ): Promise<void> {\n if (\n this.state.metamaskNotificationsList.some(\n (existingNotification) => existingNotification.id === notification.id,\n )\n ) {\n return;\n }\n\n const processedNotification = safeProcessNotification(notification);\n\n if (processedNotification) {\n this.update((state) => {\n const existingNotificationIds = new Set(\n state.metamaskNotificationsList.map(\n (existingNotification) => existingNotification.id,\n ),\n );\n // Add the new notification only if its ID is not already present in the list\n if (!existingNotificationIds.has(processedNotification.id)) {\n state.metamaskNotificationsList = [\n processedNotification,\n ...state.metamaskNotificationsList,\n ];\n }\n });\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n }\n }\n\n /**\n * Creates an perp order notification subscription.\n * Requires notifications and auth to be enabled to start receiving this notifications\n *\n * @param input perp input\n */\n public async sendPerpPlaceOrderNotification(\n input: OrderInput,\n ): Promise<void> {\n try {\n const { bearerToken } = await this.#getBearerToken();\n await createPerpOrderNotification(bearerToken, input);\n } catch {\n // Do Nothing\n }\n }\n\n /**\n * Fetches the list of MetaMask notification categories from the notifications API,\n * stores the result in controller state, and returns the categories.\n *\n * This method sets the categories-loading flag while the request is in flight\n * so the UI can reflect the loading state. If the request fails, it logs the\n * error and throws a generic failure error.\n *\n * @returns A promise that resolves to the fetched notification categories.\n * @throws {Error} If the categories request fails.\n */\n public async fetchMetamaskNotificationsCategories(): Promise<\n NotificationsCategory[]\n > {\n this.#setIsFetchingNotificationsCategories(true);\n\n try {\n const categories = await getNotificationsCategories();\n\n this.update((state) => {\n state.metamaskNotificationsCategories = categories;\n });\n\n return categories;\n } catch (error) {\n log.error('Failed to fetch notifications categories', error);\n throw new Error('Failed to fetch notifications categories');\n } finally {\n this.#setIsFetchingNotificationsCategories(false);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NotificationServicesController.js","sourceRoot":"","sources":["../../src/NotificationServicesController/NotificationServicesController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AuthenticatedUserStorageServiceGetNotificationPreferencesAction,\n AuthenticatedUserStorageServicePutNotificationPreferencesAction,\n NotificationPreferences,\n PerpsPreference,\n SocialAIPreference,\n} from '@metamask/authenticated-user-storage';\nimport {\n DEFAULT_AGENTIC_CLI_PREFERENCES,\n DEFAULT_PRICE_ALERT_PREFERENCES,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport {\n isValidHexAddress,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type {\n KeyringControllerStateChangeEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n KeyringControllerState,\n} from '@metamask/keyring-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport { assert } from '@metamask/utils';\nimport { debounce } from 'lodash-es';\nimport log from 'loglevel';\n\nimport type {\n NotificationServicesPushControllerStateChangeEvent,\n NotificationServicesPushControllerOnNewNotificationEvent,\n} from '../NotificationServicesPushController/index.js';\nimport type { NotificationServicesPushControllerMethodActions } from '../NotificationServicesPushController/NotificationServicesPushController-method-action-types.js';\nimport { TRIGGER_TYPES } from './constants/notification-schema.js';\nimport type { NormalisedAPINotification } from './index.js';\nimport type { NotificationServicesControllerMethodActions } from './NotificationServicesController-method-action-types.js';\nimport {\n processAndFilterNotifications,\n safeProcessNotification,\n} from './processors/process-notifications.js';\nimport type { ENV } from './services/api-notifications.js';\nimport {\n getAPINotifications,\n getNotificationsApiConfigCached,\n markNotificationsAsRead,\n updateOnChainNotifications,\n} from './services/api-notifications.js';\nimport { getFeatureAnnouncementNotifications } from './services/feature-announcements.js';\nimport { createPerpOrderNotification } from './services/perp-notifications.js';\nimport type {\n INotification,\n MarkAsReadNotificationsParam,\n} from './types/notification/notification.js';\nimport type { OrderInput } from './types/perps/index.js';\n\n// Unique name for the controller\nconst controllerName = 'NotificationServicesController';\n\nexport const ACCOUNTS_UPDATE_DEBOUNCE_TIME_MS = 1000;\n\n/**\n * State shape for NotificationServicesController\n */\nexport type NotificationServicesControllerState = {\n /**\n * We store and manage accounts that have been seen/visited through the\n * account subscription. This allows us to track and add notifications for new accounts and not previous accounts added.\n */\n subscriptionAccountsSeen: string[];\n\n /**\n * Flag that indicates if the metamask notifications feature has been seen\n */\n isMetamaskNotificationsFeatureSeen: boolean;\n\n /**\n * Flag that indicates if the metamask notifications are enabled\n */\n isNotificationServicesEnabled: boolean;\n\n /**\n * Flag that indicates if the feature announcements are enabled\n */\n isFeatureAnnouncementsEnabled: boolean;\n\n /**\n * List of metamask notifications\n */\n metamaskNotificationsList: INotification[];\n\n /**\n * List of read metamask notifications\n */\n metamaskNotificationsReadList: string[];\n /**\n * Flag that indicates that the creating notifications is in progress\n */\n isUpdatingMetamaskNotifications: boolean;\n /**\n * Flag that indicates that the fetching notifications is in progress\n * This is used to show a loading spinner in the UI\n * when fetching notifications\n */\n isFetchingMetamaskNotifications: boolean;\n /**\n * Flag that indicates that the updating notifications for a specific address is in progress\n */\n isUpdatingMetamaskNotificationsAccount: string[];\n /**\n * Flag that indicates that the checking accounts presence is in progress\n */\n isCheckingAccountsPresence: boolean;\n};\n\nconst metadata: StateMetadata<NotificationServicesControllerState> = {\n subscriptionAccountsSeen: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n\n isMetamaskNotificationsFeatureSeen: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isNotificationServicesEnabled: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isFeatureAnnouncementsEnabled: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n metamaskNotificationsList: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n metamaskNotificationsReadList: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n isUpdatingMetamaskNotifications: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isFetchingMetamaskNotifications: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isUpdatingMetamaskNotificationsAccount: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n isCheckingAccountsPresence: {\n includeInStateLogs: false,\n persist: false,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\nexport const defaultState: NotificationServicesControllerState = {\n subscriptionAccountsSeen: [],\n isMetamaskNotificationsFeatureSeen: false,\n isNotificationServicesEnabled: false,\n isFeatureAnnouncementsEnabled: false,\n metamaskNotificationsList: [],\n metamaskNotificationsReadList: [],\n isUpdatingMetamaskNotifications: false,\n isFetchingMetamaskNotifications: false,\n isUpdatingMetamaskNotificationsAccount: [],\n isCheckingAccountsPresence: false,\n};\n\nexport type NotificationServicesControllerEnableNotificationsOptions = {\n /**\n * Whether the user has consented to marketing notifications. Used only when\n * notification preferences are being initialized for the first time to seed\n * marketing push notifications.\n */\n hasMarketingConsent?: boolean;\n /**\n * Whether product announcements are enabled. Used only when notification\n * preferences are being initialized for the first time to seed marketing\n * in-app notifications.\n */\n productAnnouncementEnabled?: boolean;\n /**\n * Whether to attempt FCM/device push registration after notification\n * preferences are initialized or refreshed. This does not request OS push\n * permission.\n *\n * @default true\n */\n registerPushNotifications?: boolean;\n};\n\nexport type NotificationServicesControllerCreateOnChainTriggersOptions =\n NotificationServicesControllerEnableNotificationsOptions;\n\nexport type NotificationServicesControllerEnableMetamaskNotificationsOptions =\n NotificationServicesControllerEnableNotificationsOptions;\n\nconst locallyPersistedNotificationTypes = new Set<TRIGGER_TYPES>([\n TRIGGER_TYPES.SNAP,\n]);\n\n/**\n * Hardcoded default Perps notification preferences. Applied when notification\n * preferences are initialized for the first time.\n */\nexport const DEFAULT_PERPS_PREFERENCES: PerpsPreference = {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n};\n\n/**\n * Hardcoded default Social AI notification preferences. Applied when\n * notification preferences are initialized for the first time.\n */\nexport const DEFAULT_SOCIAL_AI_PREFERENCES: Required<SocialAIPreference> = {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n txAmountLimit: 500,\n mutedTraderProfileIds: [],\n};\n\nexport {\n DEFAULT_AGENTIC_CLI_PREFERENCES,\n DEFAULT_PRICE_ALERT_PREFERENCES,\n} from '@metamask/authenticated-user-storage';\n\n/**\n * Returns the subset of `accounts` that has a wallet-activity subscription in\n * the Trigger API, which is the source of truth for the per-address enabled bit.\n *\n * The address universe is always supplied by the caller from the keyring, so the\n * result cannot contain an address this installation does not hold.\n *\n * @param bearerToken - JWT used to query the Trigger API.\n * @param accounts - The keyring accounts to check.\n * @param env - The environment to use for the Trigger API call.\n * @returns The enabled addresses, as returned by the Trigger API, or `null` if\n * the Trigger API could not be read.\n */\nconst getEnabledAccounts = async (\n bearerToken: string,\n accounts: string[],\n env: ENV,\n): Promise<string[] | null> => {\n const triggerConfig = await getNotificationsApiConfigCached(\n bearerToken,\n accounts,\n env,\n );\n\n if (triggerConfig === null) {\n return null;\n }\n\n return triggerConfig\n .filter((addressConfig) => Boolean(addressConfig.enabled))\n .map((addressConfig) => addressConfig.address);\n};\n\n/**\n * Builds a fresh `NotificationPreferences` blob using hardcoded defaults for\n * Perps, Social AI, and Agentic CLI and the user's\n * marketing/product-announcement flags.\n *\n * `walletActivity` is written only because the blob schema requires the field;\n * nothing reads it back. Both channels are always on, and subscriptions are\n * held per address by the Trigger API rather than here — addresses are scoped\n * to a keyring, but this blob is keyed by canonical profile ID, which pairing\n * shares across every SRP belonging to the same user.\n *\n * @param hasMarketingConsent - Whether marketing push notifications should be enabled.\n * @param productAnnouncementEnabled - Whether marketing in-app notifications should be enabled.\n * @returns A complete `NotificationPreferences` object.\n */\nconst buildFreshPreferences = (\n hasMarketingConsent: boolean,\n productAnnouncementEnabled: boolean,\n): NotificationPreferences => ({\n walletActivity: {\n inAppNotificationsEnabled: true,\n pushNotificationsEnabled: true,\n accounts: [],\n },\n marketing: {\n inAppNotificationsEnabled: productAnnouncementEnabled,\n pushNotificationsEnabled: hasMarketingConsent,\n },\n perps: { ...DEFAULT_PERPS_PREFERENCES },\n socialAI: { ...DEFAULT_SOCIAL_AI_PREFERENCES },\n agenticCli: { ...DEFAULT_AGENTIC_CLI_PREFERENCES },\n priceAlerts: { ...DEFAULT_PRICE_ALERT_PREFERENCES },\n});\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'init',\n 'enablePushNotifications',\n 'disablePushNotifications',\n 'checkAccountsPresence',\n 'setFeatureAnnouncementsEnabled',\n 'createOnChainTriggers',\n 'enableMetamaskNotifications',\n 'disableNotificationServices',\n 'disableAccounts',\n 'enableAccounts',\n 'fetchAndUpdateMetamaskNotifications',\n 'getNotificationsByType',\n 'deleteNotificationById',\n 'deleteNotificationsById',\n 'markMetamaskNotificationsAsRead',\n 'updateMetamaskNotificationsList',\n 'sendPerpPlaceOrderNotification',\n] as const;\n\nexport type NotificationServicesControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n NotificationServicesControllerState\n >;\n\n// Messenger Actions\nexport type Actions =\n | NotificationServicesControllerGetStateAction\n | NotificationServicesControllerMethodActions;\n\n// Allowed Actions\ntype AllowedActions =\n // Keyring Controller Requests\n | KeyringControllerGetStateAction\n // Auth Controller Requests\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction\n | AuthenticationController.AuthenticationControllerIsSignedInAction\n | AuthenticationController.AuthenticationControllerPerformSignInAction\n // Authenticated User Storage Requests\n | AuthenticatedUserStorageServiceGetNotificationPreferencesAction\n | AuthenticatedUserStorageServicePutNotificationPreferencesAction\n // Push Notifications Controller Requests\n | NotificationServicesPushControllerMethodActions;\n\n// Events\nexport type NotificationServicesControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n NotificationServicesControllerState\n >;\n\nexport type NotificationListUpdatedEvent = {\n type: `${typeof controllerName}:notificationsListUpdated`;\n payload: [INotification[]];\n};\n\nexport type MarkNotificationsAsReadEvent = {\n type: `${typeof controllerName}:markNotificationsAsRead`;\n payload: [INotification[]];\n};\n\n// Events\nexport type Events =\n | NotificationServicesControllerStateChangeEvent\n | NotificationListUpdatedEvent\n | MarkNotificationsAsReadEvent;\n\n// Allowed Events\ntype AllowedEvents =\n // Keyring Events\n | KeyringControllerStateChangeEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n // Push Notification Events\n | NotificationServicesPushControllerOnNewNotificationEvent\n | NotificationServicesPushControllerStateChangeEvent;\n\n// Type for the messenger of NotificationServicesController\nexport type NotificationServicesControllerMessenger = Messenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events | AllowedEvents\n>;\n\ntype FeatureAnnouncementEnv = {\n spaceId: string;\n accessToken: string;\n platform: 'extension' | 'mobile';\n platformVersion?: string;\n};\n\n/**\n * Controller that enables wallet notifications and feature announcements\n */\nexport class NotificationServicesController extends BaseController<\n typeof controllerName,\n NotificationServicesControllerState,\n NotificationServicesControllerMessenger\n> {\n readonly #keyringController = {\n isUnlocked: false,\n\n setupLockedStateSubscriptions: (onUnlock: () => Promise<void>): void => {\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#keyringController.isUnlocked = isUnlocked;\n\n this.messenger.subscribe('KeyringController:unlock', (): void => {\n this.#keyringController.isUnlocked = true;\n // messaging system cannot await promises\n // we don't need to wait for a result on this.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n onUnlock();\n });\n\n this.messenger.subscribe('KeyringController:lock', (): void => {\n this.#keyringController.isUnlocked = false;\n });\n },\n };\n\n readonly #auth = {\n getBearerToken: async (): Promise<string | null> => {\n return await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n },\n isSignedIn: (): boolean => {\n return this.messenger.call('AuthenticationController:isSignedIn');\n },\n signIn: async (): Promise<string[]> => {\n return await this.messenger.call(\n 'AuthenticationController:performSignIn',\n );\n },\n };\n\n readonly #pushNotifications = {\n // Flag to check is notifications have been setup when the browser/extension is initialized.\n // We want to re-initialize push notifications when the browser/extension is refreshed\n // To ensure we subscribe to the most up-to-date notifications\n isSetup: false,\n\n subscribeToPushNotifications: async (): Promise<void> => {\n await this.messenger.call(\n 'NotificationServicesPushController:subscribeToPushNotifications',\n );\n },\n enablePushNotifications: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:enablePushNotifications',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n addPushNotificationLinks: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:addPushNotificationLinks',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n disablePushNotifications: async (): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:disablePushNotifications',\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n deletePushNotificationLinks: async (addresses: string[]): Promise<void> => {\n try {\n await this.messenger.call(\n 'NotificationServicesPushController:deletePushNotificationLinks',\n addresses,\n );\n } catch {\n // Do nothing, failing silently.\n }\n },\n subscribe: (): void => {\n // Coalesce pushes: at most one fetch in-flight, one queued.\n // Re-fetch after completion because the new row may not be visible yet when the push arrives.\n let pushFetchInFlight = false;\n let pendingPushRefetch = false;\n\n const fetchOnPush = async (): Promise<void> => {\n pushFetchInFlight = true;\n try {\n await this.fetchAndUpdateMetamaskNotifications();\n } finally {\n pushFetchInFlight = false;\n if (pendingPushRefetch) {\n pendingPushRefetch = false;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fetchOnPush();\n }\n }\n };\n\n this.messenger.subscribe(\n 'NotificationServicesPushController:onNewNotifications',\n (): void => {\n if (pushFetchInFlight) {\n pendingPushRefetch = true;\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n fetchOnPush();\n },\n );\n },\n initializePushNotifications: async (): Promise<void> => {\n if (!this.state.isNotificationServicesEnabled) {\n return;\n }\n if (this.#pushNotifications.isSetup) {\n return;\n }\n\n // If wallet is unlocked, we can create a fresh push subscription\n // Otherwise we can subscribe to original subscription\n try {\n if (!this.#keyringController.isUnlocked) {\n throw new Error('Keyring is locked');\n }\n await this.enablePushNotifications();\n this.#pushNotifications.isSetup = true;\n } catch {\n await this.#pushNotifications\n .subscribeToPushNotifications()\n .catch(() => {\n // do nothing\n });\n }\n },\n };\n\n readonly #accounts = {\n // Flag to ensure we only setup once\n isNotificationAccountsSetup: false,\n\n getNotificationAccounts: (): string[] | null => {\n const { keyrings } = this.messenger.call('KeyringController:getState');\n const keyringAccounts = [\n ...new Set(\n keyrings\n .flatMap((keyring) => keyring.accounts)\n .map((address) => {\n try {\n return toChecksumHexAddress(address);\n } catch {\n return null;\n }\n })\n .filter(\n (address): address is string =>\n address !== null && isValidHexAddress(address),\n ),\n ),\n ];\n return keyringAccounts.length > 0 ? keyringAccounts : null;\n },\n\n /**\n * Used to get list of addresses from keyring (wallet addresses)\n *\n * @returns addresses removed, added, and latest list of addresses\n */\n listAccounts: (): {\n accountsAdded: string[];\n accountsRemoved: string[];\n accounts: string[];\n } => {\n // Get previous and current account sets\n const nonChecksumAccounts = this.#accounts.getNotificationAccounts();\n if (!nonChecksumAccounts) {\n return {\n accountsAdded: [],\n accountsRemoved: [],\n accounts: [],\n };\n }\n\n const accounts = nonChecksumAccounts\n .map((address) => toChecksumHexAddress(address))\n .filter((address) => isValidHexAddress(address));\n const currentAccountsSet = new Set(accounts);\n const prevAccountsSet = new Set(this.state.subscriptionAccountsSeen);\n\n // Invalid value you cannot have zero accounts\n // Only occurs when the Accounts controller is initializing.\n if (accounts.length === 0) {\n return {\n accountsAdded: [],\n accountsRemoved: [],\n accounts: [],\n };\n }\n\n // Calculate added and removed addresses\n const accountsAdded = accounts.filter(\n (account) => !prevAccountsSet.has(account),\n );\n const accountsRemoved = [...prevAccountsSet.values()].filter(\n (account) => !currentAccountsSet.has(account),\n );\n\n // Update accounts seen\n this.update((state) => {\n state.subscriptionAccountsSeen = [...currentAccountsSet];\n });\n\n return {\n accountsAdded,\n accountsRemoved,\n accounts,\n };\n },\n\n /**\n * Initializes the cache/previous list. This is handy so we have an accurate in-mem state of the previous list of accounts.\n */\n initialize: (): void => {\n if (\n this.#keyringController.isUnlocked &&\n !this.#accounts.isNotificationAccountsSetup\n ) {\n this.#accounts.listAccounts();\n this.#accounts.isNotificationAccountsSetup = true;\n }\n },\n\n /**\n * Subscription to any state change in the keyring controller (aka wallet accounts).\n * We can call the `listAccounts` defined above to find out about any accounts added, removed\n * And call effects to subscribe/unsubscribe to notifications.\n */\n subscribe: (): void => {\n const debouncedUpdateAccountNotifications = debounce(\n async (\n totalAccounts?: number,\n prevTotalAccounts?: number,\n ): Promise<void> => {\n const hasTotalAccountsChanged = totalAccounts !== prevTotalAccounts;\n if (\n !this.state.isNotificationServicesEnabled ||\n !hasTotalAccountsChanged\n ) {\n return;\n }\n\n const { accountsAdded, accountsRemoved } =\n this.#accounts.listAccounts();\n\n const promises: Promise<unknown>[] = [];\n if (accountsAdded.length > 0) {\n promises.push(this.enableAccounts(accountsAdded));\n // The push link covers every notification source for an address,\n // so it follows account ownership rather than the wallet-activity toggle.\n promises.push(\n this.#pushNotifications.addPushNotificationLinks(accountsAdded),\n );\n }\n if (accountsRemoved.length > 0) {\n promises.push(this.disableAccounts(accountsRemoved));\n promises.push(\n this.#pushNotifications.deletePushNotificationLinks(\n accountsRemoved,\n ),\n );\n }\n await Promise.allSettled(promises);\n },\n ACCOUNTS_UPDATE_DEBOUNCE_TIME_MS,\n );\n\n this.messenger.subscribe(\n 'KeyringController:stateChange',\n // Using void return for async callback - result is intentionally ignored\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n debouncedUpdateAccountNotifications,\n (state: KeyringControllerState): number => {\n return (\n state?.keyrings?.flatMap?.((keyring) => keyring.accounts)?.length ??\n 0\n );\n },\n );\n },\n };\n\n readonly #locale: () => string;\n\n readonly #featureAnnouncementEnv: FeatureAnnouncementEnv;\n\n readonly #env: ENV;\n\n /**\n * Creates a NotificationServicesController instance.\n *\n * @param args - The arguments to this function.\n * @param args.messenger - Messenger used to communicate with BaseV2 controller.\n * @param args.state - Initial state to set on this controller.\n * @param args.env - environment variables for a given controller.\n * @param args.env.featureAnnouncements - env variables for feature announcements.\n * @param args.env.locale - users locale for better dynamic server notifications\n * @param args.env.env - the environment to use for the controller\n */\n constructor({\n messenger,\n state,\n env,\n }: {\n messenger: NotificationServicesControllerMessenger;\n state?: Partial<NotificationServicesControllerState>;\n env: {\n featureAnnouncements: FeatureAnnouncementEnv;\n locale?: () => string;\n env?: ENV;\n };\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...state },\n });\n\n this.#featureAnnouncementEnv = env.featureAnnouncements;\n this.#locale = env.locale ?? ((): string => 'en');\n this.#env = env.env ?? 'prd';\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n\n this.#clearLoadingStates();\n }\n\n init(): void {\n this.#keyringController.setupLockedStateSubscriptions(\n async (): Promise<void> => {\n this.#accounts.initialize();\n await this.#pushNotifications.initializePushNotifications();\n },\n );\n\n this.#accounts.initialize();\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.#pushNotifications.initializePushNotifications();\n this.#accounts.subscribe();\n this.#pushNotifications.subscribe();\n }\n\n #clearLoadingStates(): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotifications = false;\n state.isCheckingAccountsPresence = false;\n state.isFetchingMetamaskNotifications = false;\n state.isUpdatingMetamaskNotificationsAccount = [];\n });\n }\n\n #assertAuthEnabled(): void {\n if (!this.#auth.isSignedIn()) {\n this.update((state) => {\n state.isNotificationServicesEnabled = false;\n });\n throw new Error('User is not signed in.');\n }\n }\n\n async #enableAuth(): Promise<void> {\n const isSignedIn = this.#auth.isSignedIn();\n if (!isSignedIn) {\n await this.#auth.signIn();\n }\n }\n\n async #getBearerToken(): Promise<{ bearerToken: string }> {\n this.#assertAuthEnabled();\n\n const bearerToken = await this.#auth.getBearerToken();\n\n if (!bearerToken) {\n throw new Error('Missing BearerToken');\n }\n\n return { bearerToken };\n }\n\n /**\n * Registers this device for push notifications on the given addresses.\n *\n * Always register the device token, including when no addresses are enabled.\n * The links API rejects an empty list without removing the token.\n *\n * @param addresses - The addresses to receive push notifications for.\n */\n async #registerPushNotifications(addresses: string[]): Promise<void> {\n await this.#pushNotifications.enablePushNotifications(addresses);\n }\n\n /**\n * Sets the state of notification creation process.\n *\n * This method updates the `isUpdatingMetamaskNotifications` state, which can be used to indicate\n * whether the notification creation process is currently active or not. This is useful\n * for UI elements that need to reflect the state of ongoing operations, such as loading\n * indicators or disabled buttons during processing.\n *\n * @param isUpdatingMetamaskNotifications - A boolean value representing the new state of the notification creation process.\n */\n #setIsUpdatingMetamaskNotifications(\n isUpdatingMetamaskNotifications: boolean,\n ): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotifications = isUpdatingMetamaskNotifications;\n });\n }\n\n /**\n * Updates the state to indicate whether fetching of MetaMask notifications is in progress.\n *\n * This method is used to set the `isFetchingMetamaskNotifications` state, which can be utilized\n * to show or hide loading indicators in the UI when notifications are being fetched.\n *\n * @param isFetchingMetamaskNotifications - A boolean value representing the fetching state.\n */\n #setIsFetchingMetamaskNotifications(\n isFetchingMetamaskNotifications: boolean,\n ): void {\n this.update((state) => {\n state.isFetchingMetamaskNotifications = isFetchingMetamaskNotifications;\n });\n }\n\n /**\n * Updates the state to indicate that the checking of accounts presence is in progress.\n *\n * This method modifies the `isCheckingAccountsPresence` state, which can be used to manage UI elements\n * that depend on the status of account presence checks, such as displaying loading indicators or disabling\n * buttons while the check is ongoing.\n *\n * @param isCheckingAccountsPresence - A boolean value indicating whether the account presence check is currently active.\n */\n #setIsCheckingAccountsPresence(isCheckingAccountsPresence: boolean): void {\n this.update((state) => {\n state.isCheckingAccountsPresence = isCheckingAccountsPresence;\n });\n }\n\n /**\n * Updates the state to indicate that account updates are in progress.\n * Removes duplicate accounts before updating the state.\n *\n * @param accounts - The accounts being updated.\n */\n #updateUpdatingAccountsState(accounts: string[]): void {\n this.update((state) => {\n const uniqueAccounts = new Set([\n ...state.isUpdatingMetamaskNotificationsAccount,\n ...accounts,\n ]);\n state.isUpdatingMetamaskNotificationsAccount = Array.from(uniqueAccounts);\n });\n }\n\n /**\n * Clears the state indicating that account updates are complete.\n *\n * @param accounts - The accounts that have finished updating.\n */\n #clearUpdatingAccountsState(accounts: string[]): void {\n this.update((state) => {\n state.isUpdatingMetamaskNotificationsAccount =\n state.isUpdatingMetamaskNotificationsAccount.filter(\n (existingAccount) => !accounts.includes(existingAccount),\n );\n });\n }\n\n /**\n * Public method to expose enabling push notifications\n */\n public async enablePushNotifications(): Promise<void> {\n try {\n const { accounts } = this.#accounts.listAccounts();\n if (!this.#keyringController.isUnlocked || accounts.length === 0) {\n // no keyring accounts could be caused by calling this function while keyring is locked\n // it does not mean the user does not have any enabled accounts on Trigger API\n return;\n }\n\n // The push link is this device's set of held addresses. Wallet-activity\n // delivery stays gated by the Trigger API, so a disabled account remains linked.\n await this.#registerPushNotifications(\n accounts.map((address) => address.toLowerCase()),\n );\n } catch {\n // Do nothing, failing silently.\n }\n }\n\n /**\n * Public method to expose disabling push notifications\n */\n public async disablePushNotifications(): Promise<void> {\n await this.#pushNotifications.disablePushNotifications();\n }\n\n public async checkAccountsPresence(\n accounts: string[],\n ): Promise<Record<string, boolean>> {\n try {\n this.#setIsCheckingAccountsPresence(true);\n\n const { bearerToken } = await this.#getBearerToken();\n const triggerConfig = await getNotificationsApiConfigCached(\n bearerToken,\n accounts,\n this.#env,\n );\n\n if (triggerConfig === null) {\n // Reporting every account as disabled would misrepresent the user's\n // settings, so surface the failure instead.\n throw new Error('Failed to read wallet-activity subscriptions');\n }\n\n const enabledByAddress = new Map(\n triggerConfig.map((addressConfig) => [\n addressConfig.address.toLowerCase(),\n Boolean(addressConfig.enabled),\n ]),\n );\n\n const result: Record<string, boolean> = {};\n for (const address of accounts) {\n result[address] = enabledByAddress.get(address.toLowerCase()) ?? false;\n }\n return result;\n } catch (error) {\n log.error('Failed to check accounts presence', error);\n throw error;\n } finally {\n this.#setIsCheckingAccountsPresence(false);\n }\n }\n\n /**\n * Sets the enabled state of feature announcements.\n *\n * **Action** - used in the notification settings to enable/disable feature announcements.\n *\n * @param featureAnnouncementsEnabled - A boolean value indicating the desired enabled state of the feature announcements.\n * @async\n * @throws {Error} If fails to update\n */\n public async setFeatureAnnouncementsEnabled(\n featureAnnouncementsEnabled: boolean,\n ): Promise<void> {\n try {\n this.update((state) => {\n state.isFeatureAnnouncementsEnabled = featureAnnouncementsEnabled;\n });\n } catch (error) {\n log.error('Unable to toggle feature announcements', error);\n throw new Error('Unable to toggle feature announcements');\n }\n }\n\n /**\n * This creates/re-creates on-chain triggers defined in User Storage.\n *\n * **Action** - Used during Sign In / Enabling of notifications.\n *\n * Notification preferences are initialized only when\n * {@link AuthenticatedUserStorageService} has no stored preferences yet.\n * Existing preferences are left as-is.\n *\n * @param opts - optional options to mutate this functionality\n * @param opts.hasMarketingConsent - The user's marketing-consent flag.\n * Used only during initialization to seed marketing push notifications.\n * @param opts.productAnnouncementEnabled - The user's product-announcement flag.\n * Used only during initialization to seed marketing in-app notifications.\n * @param opts.registerPushNotifications - Whether to attempt FCM/device push registration.\n * @returns The updated or newly created user storage.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async createOnChainTriggers(\n opts: NotificationServicesControllerCreateOnChainTriggersOptions = {},\n ): Promise<void> {\n try {\n this.#setIsUpdatingMetamaskNotifications(true);\n\n const { accounts } = this.#accounts.listAccounts();\n if (!this.#keyringController.isUnlocked || accounts.length === 0) {\n // no keyring accounts could be caused by calling this function while keyring is locked\n // it does not mean the user does not have any enabled accounts on Trigger API\n return;\n }\n\n const { bearerToken } = await this.#getBearerToken();\n\n // 1. Read existing AUS notification preferences. Their absence is what\n // marks a first-time setup, and they are initialized in step 3.\n const preferences = await this.messenger.call(\n 'AuthenticatedUserStorageService:getNotificationPreferences',\n );\n\n const hasMarketingConsent = Boolean(opts?.hasMarketingConsent);\n const productAnnouncementEnabled = Boolean(\n opts?.productAnnouncementEnabled,\n );\n\n const isFirstTimeSetup = preferences === null;\n\n // 2. Subscribe the keyring's accounts on first-time setup only.\n //\n // This method also runs on the daily re-subscribe, so the absence of a\n // preferences blob — not the absence of subscriptions — is what marks a\n // genuine first-time setup. Keying off \"no subscriptions\" would re-enable\n // every account daily for a user who had turned them all off.\n //\n // Even at first-time setup, existing subscriptions win: a user upgrading\n // from a client that never wrote a preferences blob keeps whichever\n // accounts they had already disabled.\n const accountsWithNotifications = await getEnabledAccounts(\n bearerToken,\n accounts,\n this.#env,\n );\n\n if (accountsWithNotifications === null) {\n // An unreadable subscription list is not an empty one. Subscribing\n // every account here would re-enable ones the user had turned off,\n // so fail and let the caller retry.\n throw new Error('Failed to read wallet-activity subscriptions');\n }\n\n if (isFirstTimeSetup && accountsWithNotifications.length === 0) {\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: true })),\n this.#env,\n );\n }\n\n // 3. Initialize the preferences blob, only once the subscriptions above\n // are in place. Its existence is what makes the next run a re-subscribe\n // rather than a first-time setup, so writing it earlier would let a\n // failed subscribe leave the user enabled with no accounts subscribed\n // and no second chance to seed them.\n if (isFirstTimeSetup) {\n await this.messenger.call(\n 'AuthenticatedUserStorageService:putNotificationPreferences',\n buildFreshPreferences(\n hasMarketingConsent,\n productAnnouncementEnabled,\n ),\n this.#featureAnnouncementEnv.platform,\n );\n }\n\n if (opts.registerPushNotifications ?? true) {\n // Link this device to every address it holds. Clients request OS\n // permission separately, and wallet activity stays gated by the\n // Trigger API subscriptions above.\n this.#registerPushNotifications(\n accounts.map((address) => address.toLowerCase()),\n ).catch(() => {\n // Do Nothing\n });\n }\n\n // Update the state of the controller\n this.update((state) => {\n // User is re-subscribing (daily resub to get latest notifications)\n if (state.isNotificationServicesEnabled) {\n // Keep their existing preferences on re-subscribe\n // No state updates needed - preserving user's current settings\n } else {\n // User is turning on notifications from a disabled state\n state.isNotificationServicesEnabled = true;\n state.isFeatureAnnouncementsEnabled = true;\n state.isMetamaskNotificationsFeatureSeen = true;\n }\n });\n } catch (error) {\n log.error('Failed to create On Chain triggers', error);\n throw new Error('Failed to create On Chain triggers');\n } finally {\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n }\n\n /**\n * Enables all MetaMask notifications for the user.\n * This is identical flow when initializing notifications for the first time.\n *\n * @param opts - Optional options to mutate this functionality.\n * @throws {Error} If there is an error during the process of enabling notifications.\n */\n public async enableMetamaskNotifications(\n opts: NotificationServicesControllerEnableMetamaskNotificationsOptions = {},\n ): Promise<void> {\n try {\n this.#setIsUpdatingMetamaskNotifications(true);\n await this.#enableAuth();\n await this.createOnChainTriggers(opts);\n } catch (error) {\n log.error('Unable to enable notifications', error);\n throw new Error('Unable to enable notifications');\n } finally {\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n }\n\n /**\n * Disables all MetaMask notifications for the user.\n * This method ensures that the user is authenticated, retrieves all linked accounts,\n * and disables on-chain triggers for each account. It also sets the global notification\n * settings for MetaMask, feature announcements to false.\n *\n * @throws {Error} If the user is not authenticated or if there is an error during the process.\n */\n public async disableNotificationServices(): Promise<void> {\n this.#setIsUpdatingMetamaskNotifications(true);\n\n // Attempt Disable Push Notifications\n try {\n await this.#pushNotifications.disablePushNotifications();\n } catch {\n // Do nothing\n }\n\n // Update State: remove non-permitted notifications & disable flags\n const snapNotifications = this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === TRIGGER_TYPES.SNAP,\n );\n this.update((state) => {\n state.isNotificationServicesEnabled = false;\n state.isFeatureAnnouncementsEnabled = false;\n // reassigning the notifications list with just snaps\n // since the disable shouldn't affect snaps notifications\n state.metamaskNotificationsList = snapNotifications;\n });\n\n // Finish Updating State\n this.#setIsUpdatingMetamaskNotifications(false);\n }\n\n /**\n * Disables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. The device's FCM links stay in place,\n * because those links deliver every notification source for an address.\n *\n * **Action** - When a user disables wallet activity for a given account.\n *\n * @param accounts - The accounts whose wallet-activity subscriptions are disabled.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async disableAccounts(accounts: string[]): Promise<void> {\n try {\n this.#updateUpdatingAccountsState(accounts);\n const { bearerToken } = await this.#getBearerToken();\n\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: false })),\n this.#env,\n );\n } catch {\n throw new Error('Failed to delete OnChain triggers');\n } finally {\n this.#clearUpdatingAccountsState(accounts);\n }\n }\n\n /**\n * Enables wallet-activity subscriptions for the given accounts.\n *\n * This only writes the Trigger API. Linking the device token is handled\n * when the account is added or when notifications are enabled.\n *\n * **Action** - When a user enables wallet activity for an account.\n *\n * @param accounts - List of accounts to subscribe.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async enableAccounts(accounts: string[]): Promise<void> {\n try {\n this.#updateUpdatingAccountsState(accounts);\n\n const { bearerToken } = await this.#getBearerToken();\n await updateOnChainNotifications(\n bearerToken,\n accounts.map((address) => ({ address, enabled: true })),\n this.#env,\n );\n } catch (error) {\n log.error('Failed to update OnChain triggers', error);\n throw new Error('Failed to update OnChain triggers');\n } finally {\n this.#clearUpdatingAccountsState(accounts);\n }\n }\n\n /**\n * Fetches the list of metamask notifications.\n * This includes OnChain notifications; Feature Announcements; and Snap Notifications.\n *\n * **Action** - When a user views the notification list page/dropdown\n *\n * @param previewToken - the preview token to use if needed\n * @returns A promise that resolves to the list of notifications.\n * @throws {Error} Throws an error if unauthenticated or from other operations.\n */\n public async fetchAndUpdateMetamaskNotifications(\n previewToken?: string,\n ): Promise<INotification[]> {\n try {\n this.#setIsFetchingMetamaskNotifications(true);\n\n // This is used by Feature Announcement & On Chain\n // Not used by Snaps\n const isGlobalNotifsEnabled = this.state.isNotificationServicesEnabled;\n const notificationPreferences = isGlobalNotifsEnabled\n ? await this.messenger\n .call('AuthenticatedUserStorageService:getNotificationPreferences')\n .catch(() => null)\n : null;\n\n // Raw Feature Notifications\n const rawAnnouncements =\n isGlobalNotifsEnabled &&\n notificationPreferences?.marketing.inAppNotificationsEnabled\n ? await getFeatureAnnouncementNotifications(\n this.#featureAnnouncementEnv,\n previewToken,\n ).catch(() => [])\n : [];\n\n // Raw On Chain Notifications\n const rawOnChainNotifications: NormalisedAPINotification[] = [];\n if (isGlobalNotifsEnabled) {\n try {\n const { bearerToken } = await this.#getBearerToken();\n // Addresses come from the keyring, so this installation can only ever\n // ask for activity on accounts it actually holds. The Trigger API\n // narrows that to the ones the user has enabled.\n const { accounts } = this.#accounts.listAccounts();\n const addressesWithNotifications = await getEnabledAccounts(\n bearerToken,\n accounts,\n this.#env,\n );\n if (addressesWithNotifications !== null) {\n const notifications = await getAPINotifications(\n bearerToken,\n addressesWithNotifications,\n this.#locale(),\n this.#featureAnnouncementEnv.platform,\n this.#env,\n ).catch(() => []);\n rawOnChainNotifications.push(...notifications);\n }\n } catch {\n // Do nothing\n }\n }\n\n // Snap Notifications (original)\n // We do not want to remove them\n const snapNotifications = this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === TRIGGER_TYPES.SNAP,\n );\n\n const readIds = this.state.metamaskNotificationsReadList;\n\n // Combine Notifications\n const metamaskNotifications: INotification[] = [\n ...processAndFilterNotifications(rawAnnouncements, readIds),\n ...processAndFilterNotifications(rawOnChainNotifications, readIds),\n ...snapNotifications,\n ];\n\n // Sort Notifications\n metamaskNotifications.sort(\n (notificationA, notificationB) =>\n new Date(notificationB.createdAt).getTime() -\n new Date(notificationA.createdAt).getTime(),\n );\n\n // Update State\n this.update((state) => {\n state.metamaskNotificationsList = metamaskNotifications;\n });\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n\n this.#setIsFetchingMetamaskNotifications(false);\n return metamaskNotifications;\n } catch (error) {\n this.#setIsFetchingMetamaskNotifications(false);\n log.error('Failed to fetch notifications', error);\n throw new Error('Failed to fetch notifications');\n }\n }\n\n /**\n * Gets the specified type of notifications from state.\n *\n * @param type - The trigger type.\n * @returns An array of notifications of the passed in type.\n * @throws Throws an error if an invalid trigger type is passed.\n */\n public getNotificationsByType(type: TRIGGER_TYPES): INotification[] {\n assert(\n Object.values(TRIGGER_TYPES).includes(type),\n 'Invalid trigger type.',\n );\n return this.state.metamaskNotificationsList.filter(\n (notification) => notification.type === type,\n );\n }\n\n /**\n * Used to delete a notification by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param id - The id of the notification to delete.\n */\n public async deleteNotificationById(id: string): Promise<void> {\n const fetchedNotification = this.state.metamaskNotificationsList.find(\n (notification) => notification.id === id,\n );\n\n assert(\n fetchedNotification,\n 'The notification to be deleted does not exist.',\n );\n\n assert(\n locallyPersistedNotificationTypes.has(fetchedNotification.type),\n `The notification type of \"${\n // notifications are guaranteed to have type properties which equate to strings\n fetchedNotification.type as string\n }\" is not locally persisted, only the following types can use this function: ${[\n ...locallyPersistedNotificationTypes,\n ].join(', ')}.`,\n );\n\n const newList = this.state.metamaskNotificationsList.filter(\n (notification) => notification.id !== id,\n );\n\n this.update((state) => {\n state.metamaskNotificationsList = newList;\n });\n }\n\n /**\n * Used to batch delete notifications by id.\n *\n * Note: This function should only be used for notifications that are stored\n * in this controller directly, currently only snaps notifications.\n *\n * @param ids - The ids of the notifications to delete.\n */\n public async deleteNotificationsById(ids: string[]): Promise<void> {\n for (const id of ids) {\n await this.deleteNotificationById(id);\n }\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n }\n\n /**\n * Marks specified metamask notifications as read.\n *\n * @param notifications - An array of notifications to be marked as read. Each notification should include its type and read status.\n * @returns A promise that resolves when the operation is complete.\n */\n public async markMetamaskNotificationsAsRead(\n notifications: MarkAsReadNotificationsParam,\n ): Promise<void> {\n let onchainNotificationIds: string[] = [];\n let featureAnnouncementNotificationIds: string[] = [];\n let snapNotificationIds: string[] = [];\n\n try {\n const [\n onChainNotifications,\n featureAnnouncementNotifications,\n snapNotifications,\n ] = notifications.reduce<\n [\n MarkAsReadNotificationsParam,\n MarkAsReadNotificationsParam,\n MarkAsReadNotificationsParam,\n ]\n >(\n (allNotifications, notification) => {\n if (!notification.isRead) {\n switch (notification.type) {\n case TRIGGER_TYPES.FEATURES_ANNOUNCEMENT:\n allNotifications[1].push(notification);\n break;\n case TRIGGER_TYPES.SNAP:\n allNotifications[2].push(notification);\n break;\n default:\n allNotifications[0].push(notification);\n }\n }\n return allNotifications;\n },\n [[], [], []],\n );\n\n // Mark On-Chain Notifications as Read\n if (onChainNotifications.length > 0) {\n const bearerToken = await this.#auth.getBearerToken();\n\n if (bearerToken) {\n onchainNotificationIds = onChainNotifications.map(\n (notification) => notification.id,\n );\n await markNotificationsAsRead(\n bearerToken,\n onchainNotificationIds,\n this.#env,\n ).catch(() => {\n onchainNotificationIds = [];\n log.warn('Unable to mark onchain notifications as read');\n });\n }\n }\n\n // Mark Off-Chain notifications as Read\n if (featureAnnouncementNotifications.length > 0) {\n featureAnnouncementNotificationIds =\n featureAnnouncementNotifications.map(\n (notification) => notification.id,\n );\n }\n\n if (snapNotifications.length > 0) {\n snapNotificationIds = snapNotifications.map(\n (notification) => notification.id,\n );\n }\n } catch (error) {\n log.warn('Something failed when marking notifications as read', error);\n }\n\n // Update the state (state is also used on counter & badge)\n this.update((state) => {\n const currentReadList = state.metamaskNotificationsReadList;\n const newReadIds = [\n ...featureAnnouncementNotificationIds,\n ...snapNotificationIds,\n ];\n state.metamaskNotificationsReadList = [\n ...new Set([...currentReadList, ...newReadIds]),\n ];\n\n state.metamaskNotificationsList = state.metamaskNotificationsList.map(\n (notification: INotification) => {\n if (\n newReadIds.includes(notification.id) ||\n onchainNotificationIds.includes(notification.id)\n ) {\n if (notification.type === TRIGGER_TYPES.SNAP) {\n return {\n ...notification,\n isRead: true,\n readDate: new Date().toISOString(),\n };\n }\n return { ...notification, isRead: true };\n }\n return notification;\n },\n );\n });\n\n this.messenger.publish(\n `${controllerName}:markNotificationsAsRead`,\n this.state.metamaskNotificationsList,\n );\n }\n\n /**\n * Updates the list of MetaMask notifications by adding a new notification at the beginning of the list.\n * This method ensures that the most recent notification is displayed first in the UI.\n *\n * @param notification - The new notification object to be added to the list.\n * @returns A promise that resolves when the notification list has been successfully updated.\n */\n public async updateMetamaskNotificationsList(\n notification: INotification,\n ): Promise<void> {\n if (\n this.state.metamaskNotificationsList.some(\n (existingNotification) => existingNotification.id === notification.id,\n )\n ) {\n return;\n }\n\n const processedNotification = safeProcessNotification(notification);\n\n if (processedNotification) {\n this.update((state) => {\n const existingNotificationIds = new Set(\n state.metamaskNotificationsList.map(\n (existingNotification) => existingNotification.id,\n ),\n );\n // Add the new notification only if its ID is not already present in the list\n if (!existingNotificationIds.has(processedNotification.id)) {\n state.metamaskNotificationsList = [\n processedNotification,\n ...state.metamaskNotificationsList,\n ];\n }\n });\n\n this.messenger.publish(\n `${controllerName}:notificationsListUpdated`,\n this.state.metamaskNotificationsList,\n );\n }\n }\n\n /**\n * Creates an perp order notification subscription.\n * Requires notifications and auth to be enabled to start receiving this notifications\n *\n * @param input perp input\n */\n public async sendPerpPlaceOrderNotification(\n input: OrderInput,\n ): Promise<void> {\n try {\n const { bearerToken } = await this.#getBearerToken();\n await createPerpOrderNotification(bearerToken, input);\n } catch {\n // Do Nothing\n }\n }\n}\n"]}
|
|
@@ -12,5 +12,5 @@ export * as Mocks from './mocks/index.js';
|
|
|
12
12
|
export * from '../shared/index.js';
|
|
13
13
|
export { isVersionInBounds } from './utils/isVersionInBounds.js';
|
|
14
14
|
export { getNotificationSubtype } from './utils/get-notification-subtype.js';
|
|
15
|
-
export type { NotificationServicesControllerInitAction, NotificationServicesControllerEnablePushNotificationsAction, NotificationServicesControllerDisablePushNotificationsAction, NotificationServicesControllerCheckAccountsPresenceAction, NotificationServicesControllerSetFeatureAnnouncementsEnabledAction, NotificationServicesControllerCreateOnChainTriggersAction, NotificationServicesControllerEnableMetamaskNotificationsAction, NotificationServicesControllerDisableNotificationServicesAction, NotificationServicesControllerDisableAccountsAction, NotificationServicesControllerEnableAccountsAction, NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction,
|
|
15
|
+
export type { NotificationServicesControllerInitAction, NotificationServicesControllerEnablePushNotificationsAction, NotificationServicesControllerDisablePushNotificationsAction, NotificationServicesControllerCheckAccountsPresenceAction, NotificationServicesControllerSetFeatureAnnouncementsEnabledAction, NotificationServicesControllerCreateOnChainTriggersAction, NotificationServicesControllerEnableMetamaskNotificationsAction, NotificationServicesControllerDisableNotificationServicesAction, NotificationServicesControllerDisableAccountsAction, NotificationServicesControllerEnableAccountsAction, NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction, NotificationServicesControllerGetNotificationsByTypeAction, NotificationServicesControllerDeleteNotificationByIdAction, NotificationServicesControllerDeleteNotificationsByIdAction, NotificationServicesControllerMarkMetamaskNotificationsAsReadAction, NotificationServicesControllerUpdateMetamaskNotificationsListAction, NotificationServicesControllerSendPerpPlaceOrderNotificationAction, } from './NotificationServicesController-method-action-types.js';
|
|
16
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EAAE,8BAA8B,IAAI,UAAU,EAAE,CAAC;eACzC,8BAA8B;AAC7C,cAAc,qCAAqC,CAAC;AACpD,YAAY,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC/C,mBAAmB,kBAAkB,CAAC;AACtC,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,cAAc,uBAAuB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,cAAc,sBAAsB,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,YAAY,EACV,wCAAwC,EACxC,2DAA2D,EAC3D,4DAA4D,EAC5D,yDAAyD,EACzD,kEAAkE,EAClE,yDAAyD,EACzD,+DAA+D,EAC/D,+DAA+D,EAC/D,mDAAmD,EACnD,kDAAkD,EAClD,uEAAuE,EACvE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/NotificationServicesController/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EAAE,8BAA8B,IAAI,UAAU,EAAE,CAAC;eACzC,8BAA8B;AAC7C,cAAc,qCAAqC,CAAC;AACpD,YAAY,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC/C,mBAAmB,kBAAkB,CAAC;AACtC,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,cAAc,uBAAuB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,cAAc,sBAAsB,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,YAAY,EACV,wCAAwC,EACxC,2DAA2D,EAC3D,4DAA4D,EAC5D,yDAAyD,EACzD,kEAAkE,EAClE,yDAAyD,EACzD,+DAA+D,EAC/D,+DAA+D,EAC/D,mDAAmD,EACnD,kDAAkD,EAClD,uEAAuE,EACvE,0DAA0D,EAC1D,0DAA0D,EAC1D,2DAA2D,EAC3D,mEAAmE,EACnE,mEAAmE,EACnE,kEAAkE,GACnE,MAAM,yDAAyD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/NotificationServicesController/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EAAE,8BAA8B,IAAI,UAAU,EAAE,CAAC;AACxD,eAAe,8BAA8B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AAGpD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,cAAc,uBAAuB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,cAAc,sBAAsB,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC","sourcesContent":["import { NotificationServicesController } from './NotificationServicesController.js';\n\nexport { NotificationServicesController as Controller };\nexport default NotificationServicesController;\nexport * from './NotificationServicesController.js';\nexport type * as Types from './types/index.js';\nexport type * from './types/index.js';\nexport * as Processors from './processors/index.js';\nexport * from './processors/index.js';\nexport * as Constants from './constants/index.js';\nexport * from './constants/index.js';\nexport * as Mocks from './mocks/index.js';\nexport * from '../shared/index.js';\nexport { isVersionInBounds } from './utils/isVersionInBounds.js';\nexport { getNotificationSubtype } from './utils/get-notification-subtype.js';\n\nexport type {\n NotificationServicesControllerInitAction,\n NotificationServicesControllerEnablePushNotificationsAction,\n NotificationServicesControllerDisablePushNotificationsAction,\n NotificationServicesControllerCheckAccountsPresenceAction,\n NotificationServicesControllerSetFeatureAnnouncementsEnabledAction,\n NotificationServicesControllerCreateOnChainTriggersAction,\n NotificationServicesControllerEnableMetamaskNotificationsAction,\n NotificationServicesControllerDisableNotificationServicesAction,\n NotificationServicesControllerDisableAccountsAction,\n NotificationServicesControllerEnableAccountsAction,\n NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction,\n
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/NotificationServicesController/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EAAE,8BAA8B,IAAI,UAAU,EAAE,CAAC;AACxD,eAAe,8BAA8B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AAGpD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,cAAc,uBAAuB,CAAC;AACtC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,cAAc,sBAAsB,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC","sourcesContent":["import { NotificationServicesController } from './NotificationServicesController.js';\n\nexport { NotificationServicesController as Controller };\nexport default NotificationServicesController;\nexport * from './NotificationServicesController.js';\nexport type * as Types from './types/index.js';\nexport type * from './types/index.js';\nexport * as Processors from './processors/index.js';\nexport * from './processors/index.js';\nexport * as Constants from './constants/index.js';\nexport * from './constants/index.js';\nexport * as Mocks from './mocks/index.js';\nexport * from '../shared/index.js';\nexport { isVersionInBounds } from './utils/isVersionInBounds.js';\nexport { getNotificationSubtype } from './utils/get-notification-subtype.js';\n\nexport type {\n NotificationServicesControllerInitAction,\n NotificationServicesControllerEnablePushNotificationsAction,\n NotificationServicesControllerDisablePushNotificationsAction,\n NotificationServicesControllerCheckAccountsPresenceAction,\n NotificationServicesControllerSetFeatureAnnouncementsEnabledAction,\n NotificationServicesControllerCreateOnChainTriggersAction,\n NotificationServicesControllerEnableMetamaskNotificationsAction,\n NotificationServicesControllerDisableNotificationServicesAction,\n NotificationServicesControllerDisableAccountsAction,\n NotificationServicesControllerEnableAccountsAction,\n NotificationServicesControllerFetchAndUpdateMetamaskNotificationsAction,\n NotificationServicesControllerGetNotificationsByTypeAction,\n NotificationServicesControllerDeleteNotificationByIdAction,\n NotificationServicesControllerDeleteNotificationsByIdAction,\n NotificationServicesControllerMarkMetamaskNotificationsAsReadAction,\n NotificationServicesControllerUpdateMetamaskNotificationsListAction,\n NotificationServicesControllerSendPerpPlaceOrderNotificationAction,\n} from './NotificationServicesController-method-action-types.js';\n"]}
|
|
@@ -10,7 +10,6 @@ export declare const getMockUpdateOnChainNotifications: () => MockResponse;
|
|
|
10
10
|
export declare const MOCK_RAW_ON_CHAIN_NOTIFICATIONS: import("../index.js").NormalisedAPINotification[];
|
|
11
11
|
export declare const getMockListNotificationsResponse: () => MockResponse;
|
|
12
12
|
export declare const getMockMarkNotificationsAsReadResponse: () => MockResponse;
|
|
13
|
-
export declare const getMockNotificationsCategoriesResponse: () => MockResponse;
|
|
14
13
|
export declare const getMockCreatePerpOrderNotification: () => MockResponse;
|
|
15
14
|
export {};
|
|
16
15
|
//# sourceMappingURL=mockResponses.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockResponses.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/mocks/mockResponses.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mockResponses.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/mocks/mockResponses.ts"],"names":[],"mappings":"AAWA,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACjD,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,iEAA2C,CAAC;AAG5E,eAAO,MAAM,kCAAkC,QAAO,YAMrD,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAO,YAMpD,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAO,YAMpD,CAAC;AAEF,eAAO,MAAM,+BAA+B,mDACP,CAAC;AAGtC,eAAO,MAAM,gCAAgC,QAAO,YAMnD,CAAC;AAEF,eAAO,MAAM,sCAAsC,QAAO,YAMzD,CAAC;AAEF,eAAO,MAAM,kCAAkC,QAAO,YAMrD,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NOTIFICATION_API_LIST_ENDPOINT, NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT, TRIGGER_API_NOTIFICATIONS_ENDPOINT, TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT, } from '../services/api-notifications.js';
|
|
2
2
|
import { FEATURE_ANNOUNCEMENT_API } from '../services/feature-announcements.js';
|
|
3
3
|
import { PERPS_API_CREATE_ORDERS } from '../services/perp-notifications.js';
|
|
4
4
|
import { createMockFeatureAnnouncementAPIResult } from './mock-feature-announcements.js';
|
|
@@ -42,26 +42,6 @@ export const getMockMarkNotificationsAsReadResponse = () => {
|
|
|
42
42
|
response: null,
|
|
43
43
|
};
|
|
44
44
|
};
|
|
45
|
-
export const getMockNotificationsCategoriesResponse = () => {
|
|
46
|
-
return {
|
|
47
|
-
url: NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT(),
|
|
48
|
-
requestMethod: 'GET',
|
|
49
|
-
response: [
|
|
50
|
-
{
|
|
51
|
-
category_id: 'trading_activity',
|
|
52
|
-
visible_on: ['extension', 'mobile'],
|
|
53
|
-
aus_keys: ['perps'],
|
|
54
|
-
notification_types: ['perps'],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
category_id: 'wallet_activity',
|
|
58
|
-
visible_on: ['extension', 'mobile', 'portfolio'],
|
|
59
|
-
aus_keys: ['walletActivity'],
|
|
60
|
-
notification_types: [],
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
45
|
export const getMockCreatePerpOrderNotification = () => {
|
|
66
46
|
return {
|
|
67
47
|
url: PERPS_API_CREATE_ORDERS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockResponses.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/mocks/mockResponses.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"mockResponses.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/mocks/mockResponses.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,0CAA0C,EAC1C,kCAAkC,EAClC,wCAAwC,GACzC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,sCAAsC,EAAE,MAAM,iCAAiC,CAAC;AACzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAC;AAQhF,MAAM,CAAC,MAAM,mBAAmB,GAAG,sCAAsC,EAAE,CAAC;AAE5E,kIAAkI;AAClI,MAAM,CAAC,MAAM,kCAAkC,GAAG,GAAiB,EAAE;IACnE,OAAO;QACL,GAAG,EAAE,wBAAwB;QAC7B,aAAa,EAAE,KAAK;QACpB,QAAQ,EAAE,mBAAmB;KACP,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,GAAiB,EAAE;IAClE,OAAO;QACL,GAAG,EAAE,wCAAwC,EAAE;QAC/C,aAAa,EAAE,MAAM;QACrB,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KACjC,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,GAAiB,EAAE;IAClE,OAAO;QACL,GAAG,EAAE,kCAAkC,EAAE;QACzC,aAAa,EAAE,MAAM;QACrB,QAAQ,EAAE,IAAI;KACQ,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAC1C,iCAAiC,EAAE,CAAC;AAEtC,kIAAkI;AAClI,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAiB,EAAE;IACjE,OAAO;QACL,GAAG,EAAE,8BAA8B,EAAE;QACrC,aAAa,EAAE,MAAM;QACrB,QAAQ,EAAE,+BAA+B;KACnB,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sCAAsC,GAAG,GAAiB,EAAE;IACvE,OAAO;QACL,GAAG,EAAE,0CAA0C,EAAE;QACjD,aAAa,EAAE,MAAM;QACrB,QAAQ,EAAE,IAAI;KACQ,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,GAAiB,EAAE;IACnE,OAAO;QACL,GAAG,EAAE,uBAAuB;QAC5B,aAAa,EAAE,MAAM;QACrB,QAAQ,EAAE,IAAI;KACQ,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["import {\n NOTIFICATION_API_LIST_ENDPOINT,\n NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT,\n TRIGGER_API_NOTIFICATIONS_ENDPOINT,\n TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT,\n} from '../services/api-notifications.js';\nimport { FEATURE_ANNOUNCEMENT_API } from '../services/feature-announcements.js';\nimport { PERPS_API_CREATE_ORDERS } from '../services/perp-notifications.js';\nimport { createMockFeatureAnnouncementAPIResult } from './mock-feature-announcements.js';\nimport { createMockRawOnChainNotifications } from './mock-raw-notifications.js';\n\ntype MockResponse = {\n url: string;\n requestMethod: 'GET' | 'POST' | 'PUT' | 'DELETE';\n response: unknown;\n};\n\nexport const CONTENTFUL_RESPONSE = createMockFeatureAnnouncementAPIResult();\n\n// Using `satisfies` to preserve narrow return types while ensuring type safety; explicit return types would widen to MockResponse\nexport const getMockFeatureAnnouncementResponse = (): MockResponse => {\n return {\n url: FEATURE_ANNOUNCEMENT_API,\n requestMethod: 'GET',\n response: CONTENTFUL_RESPONSE,\n } satisfies MockResponse;\n};\n\nexport const getMockOnChainNotificationsConfig = (): MockResponse => {\n return {\n url: TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(),\n requestMethod: 'POST',\n response: [{ address: '0xTestAddress', enabled: true }],\n } satisfies MockResponse;\n};\n\nexport const getMockUpdateOnChainNotifications = (): MockResponse => {\n return {\n url: TRIGGER_API_NOTIFICATIONS_ENDPOINT(),\n requestMethod: 'POST',\n response: null,\n } satisfies MockResponse;\n};\n\nexport const MOCK_RAW_ON_CHAIN_NOTIFICATIONS =\n createMockRawOnChainNotifications();\n\n// Using `satisfies` to preserve narrow return types while ensuring type safety; explicit return types would widen to MockResponse\nexport const getMockListNotificationsResponse = (): MockResponse => {\n return {\n url: NOTIFICATION_API_LIST_ENDPOINT(),\n requestMethod: 'POST',\n response: MOCK_RAW_ON_CHAIN_NOTIFICATIONS,\n } satisfies MockResponse;\n};\n\nexport const getMockMarkNotificationsAsReadResponse = (): MockResponse => {\n return {\n url: NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT(),\n requestMethod: 'POST',\n response: null,\n } satisfies MockResponse;\n};\n\nexport const getMockCreatePerpOrderNotification = (): MockResponse => {\n return {\n url: PERPS_API_CREATE_ORDERS,\n requestMethod: 'POST',\n response: null,\n } satisfies MockResponse;\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NormalisedAPINotification
|
|
1
|
+
import type { NormalisedAPINotification } from '../types/notification-api/index.js';
|
|
2
2
|
export type ENV = 'prd' | 'uat' | 'dev';
|
|
3
3
|
export declare const TRIGGER_API: (env?: ENV) => string;
|
|
4
4
|
export declare const NOTIFICATION_API: (env?: ENV) => string;
|
|
@@ -6,7 +6,6 @@ export declare const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT: (env?: ENV) => st
|
|
|
6
6
|
export declare const TRIGGER_API_NOTIFICATIONS_ENDPOINT: (env?: ENV) => string;
|
|
7
7
|
export declare const NOTIFICATION_API_LIST_ENDPOINT: (env?: ENV) => string;
|
|
8
8
|
export declare const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT: (env?: ENV) => string;
|
|
9
|
-
export declare const NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT: (env?: ENV) => string;
|
|
10
9
|
/**
|
|
11
10
|
* fetches notification config (accounts enabled vs disabled)
|
|
12
11
|
*
|
|
@@ -63,13 +62,4 @@ export declare function getAPINotifications(bearerToken: string, addresses: stri
|
|
|
63
62
|
* @returns A promise that resolves to void. The promise will reject if there's an error during the API call or if the response status is not 200.
|
|
64
63
|
*/
|
|
65
64
|
export declare function markNotificationsAsRead(bearerToken: string, notificationIds: string[], env?: ENV): Promise<void>;
|
|
66
|
-
/**
|
|
67
|
-
* Fetches the notification categories manifest (server-driven settings taxonomy).
|
|
68
|
-
*
|
|
69
|
-
* This endpoint is unauthenticated and returns the same manifest for every user.
|
|
70
|
-
*
|
|
71
|
-
* @param env - the environment to use for the API call
|
|
72
|
-
* @returns The list of notification categories, or an empty array on transport or parse errors.
|
|
73
|
-
*/
|
|
74
|
-
export declare function getNotificationsCategories(env?: ENV): Promise<NotificationsCategory[]>;
|
|
75
65
|
//# sourceMappingURL=api-notifications.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,
|
|
1
|
+
{"version":3,"file":"api-notifications.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EAG1B,MAAM,oCAAoC,CAAC;AAI5C,MAAM,MAAM,GAAG,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAQxC,eAAO,MAAM,WAAW,SAAS,GAAG,KAAW,MACF,CAAC;AAQ9C,eAAO,MAAM,gBAAgB,SAAS,GAAG,KAAW,MACG,CAAC;AAGxD,eAAO,MAAM,wCAAwC,SAC9C,GAAG,KACP,MAA0D,CAAC;AAG9D,eAAO,MAAM,kCAAkC,SAAS,GAAG,KAAW,MAC1B,CAAC;AAG7C,eAAO,MAAM,8BAA8B,SAAS,GAAG,KAAW,MACjB,CAAC;AAGlD,eAAO,MAAM,0CAA0C,SAChD,GAAG,KACP,MAAsE,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,GAAG,GAAE,GAAW,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,GAAG,IAAI,CAAC,CAiCzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,EAClD,GAAG,GAAE,GAAW,GACf,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,GAAG,QAAQ,EAChC,GAAG,GAAE,GAAW,GACf,OAAO,CAAC,yBAAyB,EAAE,CAAC,CA0CtC;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EAAE,EACzB,GAAG,GAAE,GAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -22,7 +22,6 @@ export const TRIGGER_API_NOTIFICATIONS_ENDPOINT = (env = 'prd') => `${TRIGGER_AP
|
|
|
22
22
|
export const NOTIFICATION_API_LIST_ENDPOINT = (env = 'prd') => `${NOTIFICATION_API(env)}/api/v4/notifications`;
|
|
23
23
|
// Marks notifications as read
|
|
24
24
|
export const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = (env = 'prd') => `${NOTIFICATION_API(env)}/api/v4/notifications/mark-as-read`;
|
|
25
|
-
export const NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT = (env = 'prd') => `${NOTIFICATION_API(env)}/api/v4/notifications/categories`;
|
|
26
25
|
/**
|
|
27
26
|
* fetches notification config (accounts enabled vs disabled)
|
|
28
27
|
*
|
|
@@ -46,11 +45,7 @@ export async function getNotificationsApiConfigCached(bearerToken, addresses, en
|
|
|
46
45
|
return cached;
|
|
47
46
|
}
|
|
48
47
|
const body = normalizedAddresses.map((address) => ({ address }));
|
|
49
|
-
const result = await makeApiCall(TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(env),
|
|
50
|
-
method: 'POST',
|
|
51
|
-
body,
|
|
52
|
-
bearerToken,
|
|
53
|
-
})
|
|
48
|
+
const result = await makeApiCall(bearerToken, TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(env), 'POST', body)
|
|
54
49
|
.then((response) => (response.ok ? response.json() : null))
|
|
55
50
|
.catch(() => null);
|
|
56
51
|
if (result === null) {
|
|
@@ -83,11 +78,7 @@ export async function updateOnChainNotifications(bearerToken, addresses, env = '
|
|
|
83
78
|
address: item.address.toLowerCase(),
|
|
84
79
|
}));
|
|
85
80
|
const body = normalizedAddresses;
|
|
86
|
-
const response = await makeApiCall(TRIGGER_API_NOTIFICATIONS_ENDPOINT(env),
|
|
87
|
-
method: 'POST',
|
|
88
|
-
body,
|
|
89
|
-
bearerToken,
|
|
90
|
-
});
|
|
81
|
+
const response = await makeApiCall(bearerToken, TRIGGER_API_NOTIFICATIONS_ENDPOINT(env), 'POST', body);
|
|
91
82
|
if (!response.ok) {
|
|
92
83
|
throw new Error(`Failed to update on-chain notifications: ${response.status}`);
|
|
93
84
|
}
|
|
@@ -114,11 +105,7 @@ export async function getAPINotifications(bearerToken, addresses, locale, platfo
|
|
|
114
105
|
locale,
|
|
115
106
|
platform,
|
|
116
107
|
};
|
|
117
|
-
const notifications = await makeApiCall(NOTIFICATION_API_LIST_ENDPOINT(env),
|
|
118
|
-
method: 'POST',
|
|
119
|
-
body,
|
|
120
|
-
bearerToken,
|
|
121
|
-
})
|
|
108
|
+
const notifications = await makeApiCall(bearerToken, NOTIFICATION_API_LIST_ENDPOINT(env), 'POST', body)
|
|
122
109
|
.then((response) => response.ok ? response.json() : null)
|
|
123
110
|
.catch(() => null);
|
|
124
111
|
// Transform and sort notifications
|
|
@@ -155,33 +142,10 @@ export async function markNotificationsAsRead(bearerToken, notificationIds, env
|
|
|
155
142
|
ids: notificationIds,
|
|
156
143
|
};
|
|
157
144
|
try {
|
|
158
|
-
await makeApiCall(NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT(env),
|
|
159
|
-
method: 'POST',
|
|
160
|
-
body,
|
|
161
|
-
bearerToken,
|
|
162
|
-
});
|
|
145
|
+
await makeApiCall(bearerToken, NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT(env), 'POST', body);
|
|
163
146
|
}
|
|
164
147
|
catch (error) {
|
|
165
148
|
log.error('Error marking notifications as read:', error);
|
|
166
149
|
}
|
|
167
150
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Fetches the notification categories manifest (server-driven settings taxonomy).
|
|
170
|
-
*
|
|
171
|
-
* This endpoint is unauthenticated and returns the same manifest for every user.
|
|
172
|
-
*
|
|
173
|
-
* @param env - the environment to use for the API call
|
|
174
|
-
* @returns The list of notification categories, or an empty array on transport or parse errors.
|
|
175
|
-
*/
|
|
176
|
-
export async function getNotificationsCategories(env = 'prd') {
|
|
177
|
-
const categories = await makeApiCall(NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT(env), {
|
|
178
|
-
method: 'GET',
|
|
179
|
-
})
|
|
180
|
-
.then((response) => response.ok ? response.json() : null)
|
|
181
|
-
.catch((error) => {
|
|
182
|
-
log.error('Error fetching notifications categories', error);
|
|
183
|
-
return null;
|
|
184
|
-
});
|
|
185
|
-
return categories ?? [];
|
|
186
|
-
}
|
|
187
151
|
//# sourceMappingURL=api-notifications.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"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","sourcesContent":["import log from 'loglevel';\n\nimport { toRawAPINotification } from '../../shared/to-raw-notification.js';\nimport type {\n NormalisedAPINotification,\n NotificationsCategory,\n Schema,\n UnprocessedRawNotification,\n} from '../types/notification-api/index.js';\nimport { makeApiCall } from '../utils/utils.js';\nimport { notificationsConfigCache } from './notification-config-cache.js';\n\nexport type ENV = 'prd' | 'uat' | 'dev';\n\nconst TRIGGER_API_ENV = {\n dev: 'https://trigger.dev-api.cx.metamask.io',\n uat: 'https://trigger.uat-api.cx.metamask.io',\n prd: 'https://trigger.api.cx.metamask.io',\n} satisfies Record<ENV, string>;\n\nexport const TRIGGER_API = (env: ENV = 'prd'): string =>\n TRIGGER_API_ENV[env] ?? TRIGGER_API_ENV.prd;\n\nconst NOTIFICATION_API_ENV = {\n dev: 'https://notification.dev-api.cx.metamask.io',\n uat: 'https://notification.uat-api.cx.metamask.io',\n prd: 'https://notification.api.cx.metamask.io',\n};\n\nexport const NOTIFICATION_API = (env: ENV = 'prd'): string =>\n NOTIFICATION_API_ENV[env] ?? NOTIFICATION_API_ENV.prd;\n\n// Gets notification settings for each account provided\nexport const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = (\n env: ENV = 'prd',\n): string => `${TRIGGER_API(env)}/api/v2/notifications/query`;\n\n// Creates/updates account notification subscriptions for each account provided\nexport const TRIGGER_API_NOTIFICATIONS_ENDPOINT = (env: ENV = 'prd'): string =>\n `${TRIGGER_API(env)}/api/v2/notifications`;\n\n// Lists notifications for each address provided\nexport const NOTIFICATION_API_LIST_ENDPOINT = (env: ENV = 'prd'): string =>\n `${NOTIFICATION_API(env)}/api/v4/notifications`;\n\n// Marks notifications as read\nexport const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = (\n env: ENV = 'prd',\n): string => `${NOTIFICATION_API(env)}/api/v4/notifications/mark-as-read`;\n\nexport const NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT = (\n env: ENV = 'prd',\n): string => `${NOTIFICATION_API(env)}/api/v4/notifications/categories`;\n\n/**\n * fetches notification config (accounts enabled vs disabled)\n *\n * @param bearerToken - jwt\n * @param addresses - list of addresses to check\n * @param env - the environment to use for the API call\n * NOTE the API will return addresses config with false if they have not been created before.\n * NOTE this is cached for 1s to prevent multiple update calls\n * @returns the config for each requested address, or `null` if the config could\n * not be read. An empty array means the API answered and no address is\n * subscribed; callers must not read a failure as \"nothing is enabled\", since\n * acting on that would re-subscribe or unregister addresses behind the user.\n */\nexport async function getNotificationsApiConfigCached(\n bearerToken: string,\n addresses: string[],\n env: ENV = 'prd',\n): Promise<{ address: string; enabled: boolean }[] | null> {\n if (addresses.length === 0) {\n return [];\n }\n\n const normalizedAddresses = addresses.map((addr) => addr.toLowerCase());\n\n const cached = notificationsConfigCache.get(normalizedAddresses);\n if (cached) {\n return cached;\n }\n\n type RequestBody = { address: string }[];\n type Response = { address: string; enabled: boolean }[];\n const body: RequestBody = normalizedAddresses.map((address) => ({ address }));\n const result = await makeApiCall(\n TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(env),\n {\n method: 'POST',\n body,\n bearerToken,\n },\n )\n .then<Response | null>((response) => (response.ok ? response.json() : null))\n .catch(() => null);\n\n if (result === null) {\n return null;\n }\n\n if (result.length > 0) {\n notificationsConfigCache.set(result);\n }\n\n return result;\n}\n\n/**\n * Creates or removes wallet-activity subscriptions for the given addresses.\n *\n * The endpoint is a per-address upsert-or-delete batch rather than a full\n * replace, so two installations authenticating as the same profile do not\n * clobber each other's subscriptions.\n *\n * @param bearerToken - jwt\n * @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)\n * @param env - the environment to use for the API call\n * @throws if the request could not be made or the API rejected it, so callers\n * do not report a subscription change the server never applied.\n */\nexport async function updateOnChainNotifications(\n bearerToken: string,\n addresses: { address: string; enabled: boolean }[],\n env: ENV = 'prd',\n): Promise<void> {\n if (addresses.length === 0) {\n return;\n }\n\n const normalizedAddresses = addresses.map((item) => ({\n ...item,\n address: item.address.toLowerCase(),\n }));\n\n type RequestBody = { address: string; enabled: boolean }[];\n const body: RequestBody = normalizedAddresses;\n const response = await makeApiCall(TRIGGER_API_NOTIFICATIONS_ENDPOINT(env), {\n method: 'POST',\n body,\n bearerToken,\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to update on-chain notifications: ${response.status}`,\n );\n }\n\n // Seeded only once the server has accepted the change: the settings UI reads\n // this back for the whole TTL, so a rejected write must not look applied.\n notificationsConfigCache.set(normalizedAddresses);\n}\n\n/**\n * Fetches on-chain notifications for the given addresses\n *\n * @param bearerToken - The JSON Web Token used for authentication in the API call.\n * @param addresses - List of addresses\n * @param locale - to generate translated notifications\n * @param platform - filter notifications for specific platforms ('extension' | 'mobile')\n * @param env - the environment to use for the API call\n * @returns An array of {@link NormalisedAPINotification}. Returns an empty array on transport or parse errors.\n */\nexport async function getAPINotifications(\n bearerToken: string,\n addresses: string[],\n locale: string,\n platform: 'extension' | 'mobile',\n env: ENV = 'prd',\n): Promise<NormalisedAPINotification[]> {\n if (addresses.length === 0) {\n return [];\n }\n\n type RequestBody =\n Schema.paths['/api/v4/notifications']['post']['requestBody']['content']['application/json'];\n type APIResponse =\n Schema.paths['/api/v4/notifications']['post']['responses']['200']['content']['application/json'];\n\n const body: RequestBody = {\n addresses: addresses.map((addr) => addr.toLowerCase()),\n locale,\n platform,\n };\n const notifications = await makeApiCall(NOTIFICATION_API_LIST_ENDPOINT(env), {\n method: 'POST',\n body,\n bearerToken,\n })\n .then<APIResponse | null>((response) =>\n response.ok ? response.json() : null,\n )\n .catch(() => null);\n\n // Transform and sort notifications\n const transformedNotifications = notifications\n ?.map((notification): UnprocessedRawNotification | undefined => {\n if (!notification.notification_type) {\n return undefined;\n }\n\n try {\n return toRawAPINotification(notification);\n } catch {\n return undefined;\n }\n })\n .filter((item): item is NormalisedAPINotification => Boolean(item));\n\n return transformedNotifications ?? [];\n}\n\n/**\n * Marks the specified notifications as read.\n * This method sends a POST request to the notifications service to mark the provided notification IDs as read.\n * If the operation is successful, it completes without error. If the operation fails, it throws an error with details.\n *\n * @param bearerToken - The JSON Web Token used for authentication in the API call.\n * @param notificationIds - An array of notification IDs to be marked as read.\n * @param env - the environment to use for the API call\n * @returns A promise that resolves to void. The promise will reject if there's an error during the API call or if the response status is not 200.\n */\nexport async function markNotificationsAsRead(\n bearerToken: string,\n notificationIds: string[],\n env: ENV = 'prd',\n): Promise<void> {\n if (notificationIds.length === 0) {\n return;\n }\n\n type ResponseBody =\n Schema.paths['/api/v4/notifications/mark-as-read']['post']['requestBody']['content']['application/json'];\n const body: ResponseBody = {\n ids: notificationIds,\n };\n\n try {\n await makeApiCall(NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT(env), {\n method: 'POST',\n body,\n bearerToken,\n });\n } catch (error) {\n log.error('Error marking notifications as read:', error);\n }\n}\n\n/**\n * Fetches the notification categories manifest (server-driven settings taxonomy).\n *\n * This endpoint is unauthenticated and returns the same manifest for every user.\n *\n * @param env - the environment to use for the API call\n * @returns The list of notification categories, or an empty array on transport or parse errors.\n */\nexport async function getNotificationsCategories(\n env: ENV = 'prd',\n): Promise<NotificationsCategory[]> {\n type APIResponse =\n Schema.paths['/api/v4/notifications/categories']['get']['responses']['200']['content']['application/json'];\n\n const categories: APIResponse | null = await makeApiCall(\n NOTIFICATION_API_CATEGORIES_LIST_ENDPOINT(env),\n {\n method: 'GET',\n },\n )\n .then<APIResponse | null>((response) =>\n response.ok ? response.json() : null,\n )\n .catch((error) => {\n log.error('Error fetching notifications categories', error);\n\n return null;\n });\n\n return categories ?? [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api-notifications.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"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","sourcesContent":["import log from 'loglevel';\n\nimport { toRawAPINotification } from '../../shared/to-raw-notification.js';\nimport type {\n NormalisedAPINotification,\n Schema,\n UnprocessedRawNotification,\n} from '../types/notification-api/index.js';\nimport { makeApiCall } from '../utils/utils.js';\nimport { notificationsConfigCache } from './notification-config-cache.js';\n\nexport type ENV = 'prd' | 'uat' | 'dev';\n\nconst TRIGGER_API_ENV = {\n dev: 'https://trigger.dev-api.cx.metamask.io',\n uat: 'https://trigger.uat-api.cx.metamask.io',\n prd: 'https://trigger.api.cx.metamask.io',\n} satisfies Record<ENV, string>;\n\nexport const TRIGGER_API = (env: ENV = 'prd'): string =>\n TRIGGER_API_ENV[env] ?? TRIGGER_API_ENV.prd;\n\nconst NOTIFICATION_API_ENV = {\n dev: 'https://notification.dev-api.cx.metamask.io',\n uat: 'https://notification.uat-api.cx.metamask.io',\n prd: 'https://notification.api.cx.metamask.io',\n};\n\nexport const NOTIFICATION_API = (env: ENV = 'prd'): string =>\n NOTIFICATION_API_ENV[env] ?? NOTIFICATION_API_ENV.prd;\n\n// Gets notification settings for each account provided\nexport const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = (\n env: ENV = 'prd',\n): string => `${TRIGGER_API(env)}/api/v2/notifications/query`;\n\n// Creates/updates account notification subscriptions for each account provided\nexport const TRIGGER_API_NOTIFICATIONS_ENDPOINT = (env: ENV = 'prd'): string =>\n `${TRIGGER_API(env)}/api/v2/notifications`;\n\n// Lists notifications for each address provided\nexport const NOTIFICATION_API_LIST_ENDPOINT = (env: ENV = 'prd'): string =>\n `${NOTIFICATION_API(env)}/api/v4/notifications`;\n\n// Marks notifications as read\nexport const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = (\n env: ENV = 'prd',\n): string => `${NOTIFICATION_API(env)}/api/v4/notifications/mark-as-read`;\n\n/**\n * fetches notification config (accounts enabled vs disabled)\n *\n * @param bearerToken - jwt\n * @param addresses - list of addresses to check\n * @param env - the environment to use for the API call\n * NOTE the API will return addresses config with false if they have not been created before.\n * NOTE this is cached for 1s to prevent multiple update calls\n * @returns the config for each requested address, or `null` if the config could\n * not be read. An empty array means the API answered and no address is\n * subscribed; callers must not read a failure as \"nothing is enabled\", since\n * acting on that would re-subscribe or unregister addresses behind the user.\n */\nexport async function getNotificationsApiConfigCached(\n bearerToken: string,\n addresses: string[],\n env: ENV = 'prd',\n): Promise<{ address: string; enabled: boolean }[] | null> {\n if (addresses.length === 0) {\n return [];\n }\n\n const normalizedAddresses = addresses.map((addr) => addr.toLowerCase());\n\n const cached = notificationsConfigCache.get(normalizedAddresses);\n if (cached) {\n return cached;\n }\n\n type RequestBody = { address: string }[];\n type Response = { address: string; enabled: boolean }[];\n const body: RequestBody = normalizedAddresses.map((address) => ({ address }));\n const result = await makeApiCall(\n bearerToken,\n TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(env),\n 'POST',\n body,\n )\n .then<Response | null>((response) => (response.ok ? response.json() : null))\n .catch(() => null);\n\n if (result === null) {\n return null;\n }\n\n if (result.length > 0) {\n notificationsConfigCache.set(result);\n }\n\n return result;\n}\n\n/**\n * Creates or removes wallet-activity subscriptions for the given addresses.\n *\n * The endpoint is a per-address upsert-or-delete batch rather than a full\n * replace, so two installations authenticating as the same profile do not\n * clobber each other's subscriptions.\n *\n * @param bearerToken - jwt\n * @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)\n * @param env - the environment to use for the API call\n * @throws if the request could not be made or the API rejected it, so callers\n * do not report a subscription change the server never applied.\n */\nexport async function updateOnChainNotifications(\n bearerToken: string,\n addresses: { address: string; enabled: boolean }[],\n env: ENV = 'prd',\n): Promise<void> {\n if (addresses.length === 0) {\n return;\n }\n\n const normalizedAddresses = addresses.map((item) => ({\n ...item,\n address: item.address.toLowerCase(),\n }));\n\n type RequestBody = { address: string; enabled: boolean }[];\n const body: RequestBody = normalizedAddresses;\n const response = await makeApiCall(\n bearerToken,\n TRIGGER_API_NOTIFICATIONS_ENDPOINT(env),\n 'POST',\n body,\n );\n\n if (!response.ok) {\n throw new Error(\n `Failed to update on-chain notifications: ${response.status}`,\n );\n }\n\n // Seeded only once the server has accepted the change: the settings UI reads\n // this back for the whole TTL, so a rejected write must not look applied.\n notificationsConfigCache.set(normalizedAddresses);\n}\n\n/**\n * Fetches on-chain notifications for the given addresses\n *\n * @param bearerToken - The JSON Web Token used for authentication in the API call.\n * @param addresses - List of addresses\n * @param locale - to generate translated notifications\n * @param platform - filter notifications for specific platforms ('extension' | 'mobile')\n * @param env - the environment to use for the API call\n * @returns An array of {@link NormalisedAPINotification}. Returns an empty array on transport or parse errors.\n */\nexport async function getAPINotifications(\n bearerToken: string,\n addresses: string[],\n locale: string,\n platform: 'extension' | 'mobile',\n env: ENV = 'prd',\n): Promise<NormalisedAPINotification[]> {\n if (addresses.length === 0) {\n return [];\n }\n\n type RequestBody =\n Schema.paths['/api/v4/notifications']['post']['requestBody']['content']['application/json'];\n type APIResponse =\n Schema.paths['/api/v4/notifications']['post']['responses']['200']['content']['application/json'];\n\n const body: RequestBody = {\n addresses: addresses.map((addr) => addr.toLowerCase()),\n locale,\n platform,\n };\n const notifications = await makeApiCall(\n bearerToken,\n NOTIFICATION_API_LIST_ENDPOINT(env),\n 'POST',\n body,\n )\n .then<APIResponse | null>((response) =>\n response.ok ? response.json() : null,\n )\n .catch(() => null);\n\n // Transform and sort notifications\n const transformedNotifications = notifications\n ?.map((notification): UnprocessedRawNotification | undefined => {\n if (!notification.notification_type) {\n return undefined;\n }\n\n try {\n return toRawAPINotification(notification);\n } catch {\n return undefined;\n }\n })\n .filter((item): item is NormalisedAPINotification => Boolean(item));\n\n return transformedNotifications ?? [];\n}\n\n/**\n * Marks the specified notifications as read.\n * This method sends a POST request to the notifications service to mark the provided notification IDs as read.\n * If the operation is successful, it completes without error. If the operation fails, it throws an error with details.\n *\n * @param bearerToken - The JSON Web Token used for authentication in the API call.\n * @param notificationIds - An array of notification IDs to be marked as read.\n * @param env - the environment to use for the API call\n * @returns A promise that resolves to void. The promise will reject if there's an error during the API call or if the response status is not 200.\n */\nexport async function markNotificationsAsRead(\n bearerToken: string,\n notificationIds: string[],\n env: ENV = 'prd',\n): Promise<void> {\n if (notificationIds.length === 0) {\n return;\n }\n\n type ResponseBody =\n Schema.paths['/api/v4/notifications/mark-as-read']['post']['requestBody']['content']['application/json'];\n const body: ResponseBody = {\n ids: notificationIds,\n };\n\n try {\n await makeApiCall(\n bearerToken,\n NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT(env),\n 'POST',\n body,\n );\n } catch (error) {\n log.error('Error marking notifications as read:', error);\n }\n}\n"]}
|
|
@@ -19,7 +19,6 @@ export type BlockExplorer = components['schemas']['BlockExplorer'];
|
|
|
19
19
|
export type UnprocessedRawNotification = components['schemas']['NotificationOutputV4'][number];
|
|
20
20
|
export type PlatformNotification = components['schemas']['PlatformNotificationV4'];
|
|
21
21
|
export type OnChainNotification = components['schemas']['OnChainNotificationV4'];
|
|
22
|
-
export type NotificationsCategory = components['schemas']['NotificationCategory'];
|
|
23
22
|
type ConvertToEnum<Kind> = {
|
|
24
23
|
[K in TRIGGER_TYPES]: Kind extends `${K}` ? K : never;
|
|
25
24
|
}[TRIGGER_TYPES];
|
package/dist/NotificationServicesController/types/notification-api/notification-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-api.d.ts","sourceRoot":"","sources":["../../../../src/NotificationServicesController/types/notification-api/notification-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,0BAA0B,GACpC,UAAU,CAAC,SAAS,CAAC,CAAC,4BAA4B,CAAC,CAAC;AACtD,MAAM,MAAM,gCAAgC,GAC1C,UAAU,CAAC,SAAS,CAAC,CAAC,kCAAkC,CAAC,CAAC;AAC5D,MAAM,MAAM,uBAAuB,GACjC,UAAU,CAAC,SAAS,CAAC,CAAC,yBAAyB,CAAC,CAAC;AACnD,MAAM,MAAM,4BAA4B,GACtC,UAAU,CAAC,SAAS,CAAC,CAAC,8BAA8B,CAAC,CAAC;AACxD,MAAM,MAAM,4BAA4B,GACtC,UAAU,CAAC,SAAS,CAAC,CAAC,8BAA8B,CAAC,CAAC;AACxD,MAAM,MAAM,6BAA6B,GACvC,UAAU,CAAC,SAAS,CAAC,CAAC,+BAA+B,CAAC,CAAC;AACzD,MAAM,MAAM,+BAA+B,GACzC,UAAU,CAAC,SAAS,CAAC,CAAC,iCAAiC,CAAC,CAAC;AAC3D,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC;AACjE,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,kBAAkB,CAAC,CAAC;AACzE,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,oBAAoB,CAAC,CAAC;AAC7E,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC;AAEnE,MAAM,MAAM,0BAA0B,GACpC,UAAU,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AACxD,MAAM,MAAM,oBAAoB,GAC9B,UAAU,CAAC,SAAS,CAAC,CAAC,wBAAwB,CAAC,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAC7B,UAAU,CAAC,SAAS,CAAC,CAAC,uBAAuB,CAAC,CAAC;AAEjD,
|
|
1
|
+
{"version":3,"file":"notification-api.d.ts","sourceRoot":"","sources":["../../../../src/NotificationServicesController/types/notification-api/notification-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-api.js","sourceRoot":"","sources":["../../../../src/NotificationServicesController/types/notification-api/notification-api.ts"],"names":[],"mappings":"","sourcesContent":["import { TRIGGER_TYPES } from '../../constants/notification-schema.js';\nimport type { Compute } from '../type-utils.js';\n// Types derived from external Notification API schema - naming follows API conventions\n/* eslint-disable @typescript-eslint/naming-convention */\nimport type { components } from './schema.js';\n\nexport type Data_MetamaskSwapCompleted =\n components['schemas']['Data_MetamaskSwapCompleted'];\nexport type Data_LidoStakeReadyToBeWithdrawn =\n components['schemas']['Data_LidoStakeReadyToBeWithdrawn'];\nexport type Data_LidoStakeCompleted =\n components['schemas']['Data_LidoStakeCompleted'];\nexport type Data_LidoWithdrawalRequested =\n components['schemas']['Data_LidoWithdrawalRequested'];\nexport type Data_LidoWithdrawalCompleted =\n components['schemas']['Data_LidoWithdrawalCompleted'];\nexport type Data_RocketPoolStakeCompleted =\n components['schemas']['Data_RocketPoolStakeCompleted'];\nexport type Data_RocketPoolUnstakeCompleted =\n components['schemas']['Data_RocketPoolUnstakeCompleted'];\nexport type Data_ETHSent = components['schemas']['Data_ETHSent'];\nexport type Data_ETHReceived = components['schemas']['Data_ETHReceived'];\nexport type Data_ERC20Sent = components['schemas']['Data_ERC20Sent'];\nexport type Data_ERC20Received = components['schemas']['Data_ERC20Received'];\nexport type Data_ERC721Sent = components['schemas']['Data_ERC721Sent'];\nexport type Data_ERC721Received = components['schemas']['Data_ERC721Received'];\nexport type NetworkMetadata = components['schemas']['NetworkMetadata'];\nexport type BlockExplorer = components['schemas']['BlockExplorer'];\n\nexport type UnprocessedRawNotification =\n components['schemas']['NotificationOutputV4'][number];\nexport type PlatformNotification =\n components['schemas']['PlatformNotificationV4'];\nexport type OnChainNotification =\n components['schemas']['OnChainNotificationV4'];\n\
|
|
1
|
+
{"version":3,"file":"notification-api.js","sourceRoot":"","sources":["../../../../src/NotificationServicesController/types/notification-api/notification-api.ts"],"names":[],"mappings":"","sourcesContent":["import { TRIGGER_TYPES } from '../../constants/notification-schema.js';\nimport type { Compute } from '../type-utils.js';\n// Types derived from external Notification API schema - naming follows API conventions\n/* eslint-disable @typescript-eslint/naming-convention */\nimport type { components } from './schema.js';\n\nexport type Data_MetamaskSwapCompleted =\n components['schemas']['Data_MetamaskSwapCompleted'];\nexport type Data_LidoStakeReadyToBeWithdrawn =\n components['schemas']['Data_LidoStakeReadyToBeWithdrawn'];\nexport type Data_LidoStakeCompleted =\n components['schemas']['Data_LidoStakeCompleted'];\nexport type Data_LidoWithdrawalRequested =\n components['schemas']['Data_LidoWithdrawalRequested'];\nexport type Data_LidoWithdrawalCompleted =\n components['schemas']['Data_LidoWithdrawalCompleted'];\nexport type Data_RocketPoolStakeCompleted =\n components['schemas']['Data_RocketPoolStakeCompleted'];\nexport type Data_RocketPoolUnstakeCompleted =\n components['schemas']['Data_RocketPoolUnstakeCompleted'];\nexport type Data_ETHSent = components['schemas']['Data_ETHSent'];\nexport type Data_ETHReceived = components['schemas']['Data_ETHReceived'];\nexport type Data_ERC20Sent = components['schemas']['Data_ERC20Sent'];\nexport type Data_ERC20Received = components['schemas']['Data_ERC20Received'];\nexport type Data_ERC721Sent = components['schemas']['Data_ERC721Sent'];\nexport type Data_ERC721Received = components['schemas']['Data_ERC721Received'];\nexport type NetworkMetadata = components['schemas']['NetworkMetadata'];\nexport type BlockExplorer = components['schemas']['BlockExplorer'];\n\nexport type UnprocessedRawNotification =\n components['schemas']['NotificationOutputV4'][number];\nexport type PlatformNotification =\n components['schemas']['PlatformNotificationV4'];\nexport type OnChainNotification =\n components['schemas']['OnChainNotificationV4'];\n\ntype ConvertToEnum<Kind> = {\n [K in TRIGGER_TYPES]: Kind extends `${K}` ? K : never;\n}[TRIGGER_TYPES];\n\n/**\n * Type-Computation.\n * Adds a `type` field to on-chain notifications for easier enum checking.\n * Preserves the original nested payload structure.\n */\ntype NormalizeOnChainNotification<\n N extends OnChainNotification = OnChainNotification,\n NotificationDataKinds extends string = NonNullable<\n N['payload']['data']\n >['kind'],\n> = {\n [K in NotificationDataKinds]: Compute<\n Omit<N, 'payload'> & {\n type: ConvertToEnum<K>;\n payload: Compute<\n Omit<N['payload'], 'data'> & {\n data: Extract<NonNullable<N['payload']['data']>, { kind: K }>;\n }\n >;\n }\n >;\n}[NotificationDataKinds];\n\n/**\n * Type-Computation.\n * Adds a `type` field to platform notifications for easier enum checking.\n * Preserves the original nested payload structure.\n */\ntype NormalizePlatformNotification<\n N extends PlatformNotification = PlatformNotification,\n> = Compute<\n N & {\n type: TRIGGER_TYPES.PLATFORM;\n }\n>;\n\nexport type OnChainRawNotification = Compute<\n NormalizeOnChainNotification<OnChainNotification>\n>;\n\nexport type PlatformRawNotification = Compute<\n NormalizePlatformNotification<PlatformNotification>\n>;\n\nexport type NormalisedAPINotification =\n | OnChainRawNotification\n | PlatformRawNotification;\n\nexport type OnChainRawNotificationsWithNetworkFields = Extract<\n OnChainRawNotification,\n { payload: { data: { network_fee: unknown } } }\n>;\n"]}
|
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
type JsonRequestMethod = 'POST';
|
|
2
|
-
type NoBodyMethod = 'GET' | 'DELETE';
|
|
3
|
-
type MakeApiCallOptions<Body> = {
|
|
4
|
-
method: NoBodyMethod;
|
|
5
|
-
bearerToken?: string;
|
|
6
|
-
} | {
|
|
7
|
-
method: JsonRequestMethod;
|
|
8
|
-
body: Body;
|
|
9
|
-
bearerToken?: string;
|
|
10
|
-
};
|
|
11
1
|
/**
|
|
12
|
-
* Performs an API call with
|
|
2
|
+
* Performs an API call with automatic retries on failure.
|
|
13
3
|
*
|
|
4
|
+
* @param bearerToken - The JSON Web Token for authorization.
|
|
14
5
|
* @param endpoint - The URL of the API endpoint to call.
|
|
15
|
-
* @param
|
|
6
|
+
* @param method - The HTTP method ('POST' or 'DELETE').
|
|
7
|
+
* @param body - The body of the request. It should be an object that can be serialized to JSON.
|
|
16
8
|
* @returns A Promise that resolves to the response of the fetch request.
|
|
17
9
|
*/
|
|
18
|
-
export declare function makeApiCall<Body
|
|
19
|
-
export {};
|
|
10
|
+
export declare function makeApiCall<Body>(bearerToken: string, endpoint: string, method: 'POST' | 'DELETE', body: Body): Promise<Response>;
|
|
20
11
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/utils/utils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/NotificationServicesController/utils/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,IAAI,EACpC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,QAAQ,EACzB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,QAAQ,CAAC,CAWnB"}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Performs an API call with
|
|
2
|
+
* Performs an API call with automatic retries on failure.
|
|
3
3
|
*
|
|
4
|
+
* @param bearerToken - The JSON Web Token for authorization.
|
|
4
5
|
* @param endpoint - The URL of the API endpoint to call.
|
|
5
|
-
* @param
|
|
6
|
+
* @param method - The HTTP method ('POST' or 'DELETE').
|
|
7
|
+
* @param body - The body of the request. It should be an object that can be serialized to JSON.
|
|
6
8
|
* @returns A Promise that resolves to the response of the fetch request.
|
|
7
9
|
*/
|
|
8
|
-
export async function makeApiCall(endpoint,
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
headers
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return fetch(endpoint, {
|
|
19
|
-
method: options.method,
|
|
20
|
-
headers,
|
|
21
|
-
body,
|
|
22
|
-
});
|
|
10
|
+
export async function makeApiCall(bearerToken, endpoint, method, body) {
|
|
11
|
+
const options = {
|
|
12
|
+
method,
|
|
13
|
+
headers: {
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
Authorization: `Bearer ${bearerToken}`,
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify(body),
|
|
18
|
+
};
|
|
19
|
+
return await fetch(endpoint, options);
|
|
23
20
|
}
|
|
24
21
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/utils/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/NotificationServicesController/utils/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,WAAmB,EACnB,QAAgB,EAChB,MAAyB,EACzB,IAAU;IAEV,MAAM,OAAO,GAAgB;QAC3B,MAAM;QACN,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,WAAW,EAAE;SACvC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC;IAEF,OAAO,MAAM,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC","sourcesContent":["/**\n * Performs an API call with automatic retries on failure.\n *\n * @param bearerToken - The JSON Web Token for authorization.\n * @param endpoint - The URL of the API endpoint to call.\n * @param method - The HTTP method ('POST' or 'DELETE').\n * @param body - The body of the request. It should be an object that can be serialized to JSON.\n * @returns A Promise that resolves to the response of the fetch request.\n */\nexport async function makeApiCall<Body>(\n bearerToken: string,\n endpoint: string,\n method: 'POST' | 'DELETE',\n body: Body,\n): Promise<Response> {\n const options: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${bearerToken}`,\n },\n body: JSON.stringify(body),\n };\n\n return await fetch(endpoint, options);\n}\n"]}
|
package/package.json
CHANGED