@metamask-previews/notification-services-controller 26.0.1-preview-b63fbdb38 → 26.0.1-preview-e0510042f
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 -18
- package/dist/NotificationServicesController/NotificationServicesController.cjs +112 -137
- package/dist/NotificationServicesController/NotificationServicesController.cjs.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController.d.cts.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController.d.mts.map +1 -1
- package/dist/NotificationServicesController/NotificationServicesController.mjs +113 -138
- package/dist/NotificationServicesController/NotificationServicesController.mjs.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.cjs +1 -9
- package/dist/NotificationServicesController/mocks/mockResponses.cjs.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.cts +0 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.cts.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.mts +0 -1
- package/dist/NotificationServicesController/mocks/mockResponses.d.mts.map +1 -1
- package/dist/NotificationServicesController/mocks/mockResponses.mjs +1 -8
- package/dist/NotificationServicesController/mocks/mockResponses.mjs.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.cjs +4 -43
- package/dist/NotificationServicesController/services/api-notifications.cjs.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.d.cts +2 -23
- package/dist/NotificationServicesController/services/api-notifications.d.cts.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.d.mts +2 -23
- package/dist/NotificationServicesController/services/api-notifications.d.mts.map +1 -1
- package/dist/NotificationServicesController/services/api-notifications.mjs +3 -40
- package/dist/NotificationServicesController/services/api-notifications.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.markNotificationsAsRead = exports.getAPINotifications = exports.
|
|
6
|
+
exports.markNotificationsAsRead = exports.getAPINotifications = exports.getNotificationsApiConfigCached = exports.NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = exports.NOTIFICATION_API_LIST_ENDPOINT = exports.TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = exports.NOTIFICATION_API = exports.TRIGGER_API = void 0;
|
|
7
7
|
const loglevel_1 = __importDefault(require("loglevel"));
|
|
8
8
|
const to_raw_notification_js_1 = require("../../shared/to-raw-notification.cjs");
|
|
9
9
|
const utils_js_1 = require("../utils/utils.cjs");
|
|
@@ -25,9 +25,6 @@ exports.NOTIFICATION_API = NOTIFICATION_API;
|
|
|
25
25
|
// Gets notification settings for each account provided
|
|
26
26
|
const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = (env = 'prd') => `${(0, exports.TRIGGER_API)(env)}/api/v2/notifications/query`;
|
|
27
27
|
exports.TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT;
|
|
28
|
-
// Creates/updates account notification subscriptions for each account provided
|
|
29
|
-
const TRIGGER_API_NOTIFICATIONS_ENDPOINT = (env = 'prd') => `${(0, exports.TRIGGER_API)(env)}/api/v2/notifications`;
|
|
30
|
-
exports.TRIGGER_API_NOTIFICATIONS_ENDPOINT = TRIGGER_API_NOTIFICATIONS_ENDPOINT;
|
|
31
28
|
// Lists notifications for each address provided
|
|
32
29
|
const NOTIFICATION_API_LIST_ENDPOINT = (env = 'prd') => `${(0, exports.NOTIFICATION_API)(env)}/api/v4/notifications`;
|
|
33
30
|
exports.NOTIFICATION_API_LIST_ENDPOINT = NOTIFICATION_API_LIST_ENDPOINT;
|
|
@@ -42,10 +39,7 @@ exports.NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = NOTIFICATION_API_MARK_ALL_A
|
|
|
42
39
|
* @param env - the environment to use for the API call
|
|
43
40
|
* NOTE the API will return addresses config with false if they have not been created before.
|
|
44
41
|
* NOTE this is cached for 1s to prevent multiple update calls
|
|
45
|
-
* @returns
|
|
46
|
-
* not be read. An empty array means the API answered and no address is
|
|
47
|
-
* subscribed; callers must not read a failure as "nothing is enabled", since
|
|
48
|
-
* acting on that would re-subscribe or unregister addresses behind the user.
|
|
42
|
+
* @returns object of notification config, or null if missing
|
|
49
43
|
*/
|
|
50
44
|
async function getNotificationsApiConfigCached(bearerToken, addresses, env = 'prd') {
|
|
51
45
|
if (addresses.length === 0) {
|
|
@@ -57,49 +51,16 @@ async function getNotificationsApiConfigCached(bearerToken, addresses, env = 'pr
|
|
|
57
51
|
return cached;
|
|
58
52
|
}
|
|
59
53
|
const body = normalizedAddresses.map((address) => ({ address }));
|
|
60
|
-
const
|
|
54
|
+
const apiResponse = await (0, utils_js_1.makeApiCall)(bearerToken, (0, exports.TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT)(env), 'POST', body)
|
|
61
55
|
.then((response) => (response.ok ? response.json() : null))
|
|
62
56
|
.catch(() => null);
|
|
63
|
-
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
57
|
+
const result = apiResponse ?? [];
|
|
66
58
|
if (result.length > 0) {
|
|
67
59
|
notification_config_cache_js_1.notificationsConfigCache.set(result);
|
|
68
60
|
}
|
|
69
61
|
return result;
|
|
70
62
|
}
|
|
71
63
|
exports.getNotificationsApiConfigCached = getNotificationsApiConfigCached;
|
|
72
|
-
/**
|
|
73
|
-
* Creates or removes wallet-activity subscriptions for the given addresses.
|
|
74
|
-
*
|
|
75
|
-
* The endpoint is a per-address upsert-or-delete batch rather than a full
|
|
76
|
-
* replace, so two installations authenticating as the same profile do not
|
|
77
|
-
* clobber each other's subscriptions.
|
|
78
|
-
*
|
|
79
|
-
* @param bearerToken - jwt
|
|
80
|
-
* @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)
|
|
81
|
-
* @param env - the environment to use for the API call
|
|
82
|
-
* @throws if the request could not be made or the API rejected it, so callers
|
|
83
|
-
* do not report a subscription change the server never applied.
|
|
84
|
-
*/
|
|
85
|
-
async function updateOnChainNotifications(bearerToken, addresses, env = 'prd') {
|
|
86
|
-
if (addresses.length === 0) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const normalizedAddresses = addresses.map((item) => ({
|
|
90
|
-
...item,
|
|
91
|
-
address: item.address.toLowerCase(),
|
|
92
|
-
}));
|
|
93
|
-
const body = normalizedAddresses;
|
|
94
|
-
const response = await (0, utils_js_1.makeApiCall)(bearerToken, (0, exports.TRIGGER_API_NOTIFICATIONS_ENDPOINT)(env), 'POST', body);
|
|
95
|
-
if (!response.ok) {
|
|
96
|
-
throw new Error(`Failed to update on-chain notifications: ${response.status}`);
|
|
97
|
-
}
|
|
98
|
-
// Seeded only once the server has accepted the change: the settings UI reads
|
|
99
|
-
// this back for the whole TTL, so a rejected write must not look applied.
|
|
100
|
-
notification_config_cache_js_1.notificationsConfigCache.set(normalizedAddresses);
|
|
101
|
-
}
|
|
102
|
-
exports.updateOnChainNotifications = updateOnChainNotifications;
|
|
103
64
|
/**
|
|
104
65
|
* Fetches on-chain notifications for the given addresses
|
|
105
66
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.cjs","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"]}
|
|
1
|
+
{"version":3,"file":"api-notifications.cjs","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// 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 object of notification config, or null if missing\n */\nexport async function getNotificationsApiConfigCached(\n bearerToken: string,\n addresses: string[],\n env: ENV = 'prd',\n): Promise<{ address: string; enabled: boolean }[]> {\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 apiResponse = 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 const result = apiResponse ?? [];\n\n if (result.length > 0) {\n notificationsConfigCache.set(result);\n }\n\n return result;\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"]}
|
|
@@ -3,7 +3,6 @@ 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;
|
|
5
5
|
export declare const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT: (env?: ENV) => string;
|
|
6
|
-
export declare const TRIGGER_API_NOTIFICATIONS_ENDPOINT: (env?: ENV) => string;
|
|
7
6
|
export declare const NOTIFICATION_API_LIST_ENDPOINT: (env?: ENV) => string;
|
|
8
7
|
export declare const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT: (env?: ENV) => string;
|
|
9
8
|
/**
|
|
@@ -14,32 +13,12 @@ export declare const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT: (env?: ENV) =>
|
|
|
14
13
|
* @param env - the environment to use for the API call
|
|
15
14
|
* NOTE the API will return addresses config with false if they have not been created before.
|
|
16
15
|
* NOTE this is cached for 1s to prevent multiple update calls
|
|
17
|
-
* @returns
|
|
18
|
-
* not be read. An empty array means the API answered and no address is
|
|
19
|
-
* subscribed; callers must not read a failure as "nothing is enabled", since
|
|
20
|
-
* acting on that would re-subscribe or unregister addresses behind the user.
|
|
16
|
+
* @returns object of notification config, or null if missing
|
|
21
17
|
*/
|
|
22
18
|
export declare function getNotificationsApiConfigCached(bearerToken: string, addresses: string[], env?: ENV): Promise<{
|
|
23
19
|
address: string;
|
|
24
20
|
enabled: boolean;
|
|
25
|
-
}[]
|
|
26
|
-
/**
|
|
27
|
-
* Creates or removes wallet-activity subscriptions for the given addresses.
|
|
28
|
-
*
|
|
29
|
-
* The endpoint is a per-address upsert-or-delete batch rather than a full
|
|
30
|
-
* replace, so two installations authenticating as the same profile do not
|
|
31
|
-
* clobber each other's subscriptions.
|
|
32
|
-
*
|
|
33
|
-
* @param bearerToken - jwt
|
|
34
|
-
* @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)
|
|
35
|
-
* @param env - the environment to use for the API call
|
|
36
|
-
* @throws if the request could not be made or the API rejected it, so callers
|
|
37
|
-
* do not report a subscription change the server never applied.
|
|
38
|
-
*/
|
|
39
|
-
export declare function updateOnChainNotifications(bearerToken: string, addresses: {
|
|
40
|
-
address: string;
|
|
41
|
-
enabled: boolean;
|
|
42
|
-
}[], env?: ENV): Promise<void>;
|
|
21
|
+
}[]>;
|
|
43
22
|
/**
|
|
44
23
|
* Fetches on-chain notifications for the given addresses
|
|
45
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.d.cts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EAG1B,4CAA2C;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,
|
|
1
|
+
{"version":3,"file":"api-notifications.d.cts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EAG1B,4CAA2C;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,8BAA8B,SAAS,GAAG,KAAW,MACjB,CAAC;AAGlD,eAAO,MAAM,0CAA0C,SAChD,GAAG,KACP,MAAsE,CAAC;AAE1E;;;;;;;;;GASG;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,CAAC,CA+BlD;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"}
|
|
@@ -3,7 +3,6 @@ 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;
|
|
5
5
|
export declare const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT: (env?: ENV) => string;
|
|
6
|
-
export declare const TRIGGER_API_NOTIFICATIONS_ENDPOINT: (env?: ENV) => string;
|
|
7
6
|
export declare const NOTIFICATION_API_LIST_ENDPOINT: (env?: ENV) => string;
|
|
8
7
|
export declare const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT: (env?: ENV) => string;
|
|
9
8
|
/**
|
|
@@ -14,32 +13,12 @@ export declare const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT: (env?: ENV) =>
|
|
|
14
13
|
* @param env - the environment to use for the API call
|
|
15
14
|
* NOTE the API will return addresses config with false if they have not been created before.
|
|
16
15
|
* NOTE this is cached for 1s to prevent multiple update calls
|
|
17
|
-
* @returns
|
|
18
|
-
* not be read. An empty array means the API answered and no address is
|
|
19
|
-
* subscribed; callers must not read a failure as "nothing is enabled", since
|
|
20
|
-
* acting on that would re-subscribe or unregister addresses behind the user.
|
|
16
|
+
* @returns object of notification config, or null if missing
|
|
21
17
|
*/
|
|
22
18
|
export declare function getNotificationsApiConfigCached(bearerToken: string, addresses: string[], env?: ENV): Promise<{
|
|
23
19
|
address: string;
|
|
24
20
|
enabled: boolean;
|
|
25
|
-
}[]
|
|
26
|
-
/**
|
|
27
|
-
* Creates or removes wallet-activity subscriptions for the given addresses.
|
|
28
|
-
*
|
|
29
|
-
* The endpoint is a per-address upsert-or-delete batch rather than a full
|
|
30
|
-
* replace, so two installations authenticating as the same profile do not
|
|
31
|
-
* clobber each other's subscriptions.
|
|
32
|
-
*
|
|
33
|
-
* @param bearerToken - jwt
|
|
34
|
-
* @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)
|
|
35
|
-
* @param env - the environment to use for the API call
|
|
36
|
-
* @throws if the request could not be made or the API rejected it, so callers
|
|
37
|
-
* do not report a subscription change the server never applied.
|
|
38
|
-
*/
|
|
39
|
-
export declare function updateOnChainNotifications(bearerToken: string, addresses: {
|
|
40
|
-
address: string;
|
|
41
|
-
enabled: boolean;
|
|
42
|
-
}[], env?: ENV): Promise<void>;
|
|
21
|
+
}[]>;
|
|
43
22
|
/**
|
|
44
23
|
* Fetches on-chain notifications for the given addresses
|
|
45
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.d.mts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EAG1B,4CAA2C;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,
|
|
1
|
+
{"version":3,"file":"api-notifications.d.mts","sourceRoot":"","sources":["../../../src/NotificationServicesController/services/api-notifications.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EAG1B,4CAA2C;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,8BAA8B,SAAS,GAAG,KAAW,MACjB,CAAC;AAGlD,eAAO,MAAM,0CAA0C,SAChD,GAAG,KACP,MAAsE,CAAC;AAE1E;;;;;;;;;GASG;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,CAAC,CA+BlD;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"}
|
|
@@ -23,8 +23,6 @@ const NOTIFICATION_API_ENV = {
|
|
|
23
23
|
export const NOTIFICATION_API = (env = 'prd') => NOTIFICATION_API_ENV[env] ?? NOTIFICATION_API_ENV.prd;
|
|
24
24
|
// Gets notification settings for each account provided
|
|
25
25
|
export const TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT = (env = 'prd') => `${TRIGGER_API(env)}/api/v2/notifications/query`;
|
|
26
|
-
// Creates/updates account notification subscriptions for each account provided
|
|
27
|
-
export const TRIGGER_API_NOTIFICATIONS_ENDPOINT = (env = 'prd') => `${TRIGGER_API(env)}/api/v2/notifications`;
|
|
28
26
|
// Lists notifications for each address provided
|
|
29
27
|
export const NOTIFICATION_API_LIST_ENDPOINT = (env = 'prd') => `${NOTIFICATION_API(env)}/api/v4/notifications`;
|
|
30
28
|
// Marks notifications as read
|
|
@@ -37,10 +35,7 @@ export const NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT = (env = 'prd') => `${NO
|
|
|
37
35
|
* @param env - the environment to use for the API call
|
|
38
36
|
* NOTE the API will return addresses config with false if they have not been created before.
|
|
39
37
|
* NOTE this is cached for 1s to prevent multiple update calls
|
|
40
|
-
* @returns
|
|
41
|
-
* not be read. An empty array means the API answered and no address is
|
|
42
|
-
* subscribed; callers must not read a failure as "nothing is enabled", since
|
|
43
|
-
* acting on that would re-subscribe or unregister addresses behind the user.
|
|
38
|
+
* @returns object of notification config, or null if missing
|
|
44
39
|
*/
|
|
45
40
|
export async function getNotificationsApiConfigCached(bearerToken, addresses, env = 'prd') {
|
|
46
41
|
if (addresses.length === 0) {
|
|
@@ -52,47 +47,15 @@ export async function getNotificationsApiConfigCached(bearerToken, addresses, en
|
|
|
52
47
|
return cached;
|
|
53
48
|
}
|
|
54
49
|
const body = normalizedAddresses.map((address) => ({ address }));
|
|
55
|
-
const
|
|
50
|
+
const apiResponse = await makeApiCall(bearerToken, TRIGGER_API_NOTIFICATIONS_QUERY_ENDPOINT(env), 'POST', body)
|
|
56
51
|
.then((response) => (response.ok ? response.json() : null))
|
|
57
52
|
.catch(() => null);
|
|
58
|
-
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
53
|
+
const result = apiResponse ?? [];
|
|
61
54
|
if (result.length > 0) {
|
|
62
55
|
notificationsConfigCache.set(result);
|
|
63
56
|
}
|
|
64
57
|
return result;
|
|
65
58
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Creates or removes wallet-activity subscriptions for the given addresses.
|
|
68
|
-
*
|
|
69
|
-
* The endpoint is a per-address upsert-or-delete batch rather than a full
|
|
70
|
-
* replace, so two installations authenticating as the same profile do not
|
|
71
|
-
* clobber each other's subscriptions.
|
|
72
|
-
*
|
|
73
|
-
* @param bearerToken - jwt
|
|
74
|
-
* @param addresses - addresses to subscribe (`enabled: true`) or unsubscribe (`enabled: false`)
|
|
75
|
-
* @param env - the environment to use for the API call
|
|
76
|
-
* @throws if the request could not be made or the API rejected it, so callers
|
|
77
|
-
* do not report a subscription change the server never applied.
|
|
78
|
-
*/
|
|
79
|
-
export async function updateOnChainNotifications(bearerToken, addresses, env = 'prd') {
|
|
80
|
-
if (addresses.length === 0) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
const normalizedAddresses = addresses.map((item) => ({
|
|
84
|
-
...item,
|
|
85
|
-
address: item.address.toLowerCase(),
|
|
86
|
-
}));
|
|
87
|
-
const body = normalizedAddresses;
|
|
88
|
-
const response = await makeApiCall(bearerToken, TRIGGER_API_NOTIFICATIONS_ENDPOINT(env), 'POST', body);
|
|
89
|
-
if (!response.ok) {
|
|
90
|
-
throw new Error(`Failed to update on-chain notifications: ${response.status}`);
|
|
91
|
-
}
|
|
92
|
-
// Seeded only once the server has accepted the change: the settings UI reads
|
|
93
|
-
// this back for the whole TTL, so a rejected write must not look applied.
|
|
94
|
-
notificationsConfigCache.set(normalizedAddresses);
|
|
95
|
-
}
|
|
96
59
|
/**
|
|
97
60
|
* Fetches on-chain notifications for the given addresses
|
|
98
61
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-notifications.mjs","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"]}
|
|
1
|
+
{"version":3,"file":"api-notifications.mjs","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// 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 object of notification config, or null if missing\n */\nexport async function getNotificationsApiConfigCached(\n bearerToken: string,\n addresses: string[],\n env: ENV = 'prd',\n): Promise<{ address: string; enabled: boolean }[]> {\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 apiResponse = 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 const result = apiResponse ?? [];\n\n if (result.length > 0) {\n notificationsConfigCache.set(result);\n }\n\n return result;\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"]}
|
package/package.json
CHANGED