Skip to content

Conversation

@Prithpal-Sooriya
Copy link
Contributor

@Prithpal-Sooriya Prithpal-Sooriya commented Nov 10, 2025

Explanation

This is a large notification architecture API change but offers dynamic platform notifications

Details

Devlog: https://www.loom.com/share/ea5fc1457c224b2988fadacbfc21ca2a

Extension Preview: MetaMask/metamask-extension#37709
Mobile Preview: MetaMask/metamask-mobile#22539

References

https://consensyssoftware.atlassian.net/browse/ASSETS-1301

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

Note

Migrates notifications to the v3 API with unified on-chain/platform notifications, locale-aware fetching, and updated controller/types/push logic.

  • BREAKING – API v3 migration:
    • Endpoints moved to /api/v3/notifications and /api/v3/notifications/mark-as-read.
    • List body now { addresses: string[], locale: string, platform: 'extension'|'mobile' }; config query unchanged; mark-as-read body { ids }.
    • Auto-expiry reduced to 30 days.
  • Types & processing:
    • Introduce NormalisedAPINotification (union of on-chain + platform) and UnprocessedRawNotification.
    • Add TRIGGER_TYPES.PLATFORM; update trigger type set and constants.
    • Replace toRawOnChainNotification with toRawAPINotification; remove process-onchain-notifications in favor of processAPINotifications.
    • Add OpenAPI v3 schema and new notification-api types.
  • Controller changes:
    • Switch services from onchain-notifications to api-notifications (getAPINotifications, getNotificationsApiConfigCached, markNotificationsAsRead).
    • Add locale provider to constructor; fetch uses locale + platform; update read flow to v3.
  • Push notifications:
    • Update SW handlers to parse new payload shape; support platform notifications; adjust messaging text extraction to nested payload.
  • Tests & mocks:
    • Update mocks to new shapes; add platform notification mocks; revise tests across processors, services, push, and shared utils.

Written by Cursor Bugbot for commit 3562e62. This will update automatically on new commits. Configure here.

this is a large notification architecture API change but offers dynamic platform notifications
@Prithpal-Sooriya
Copy link
Contributor Author

@metamaskbot publish-preview

mockGetOnChainNotificationsConfig,
mockUpdateOnChainNotifications,
mockGetOnChainNotifications,
mockGetAPINotifications,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed mock util

env: {
featureAnnouncements: FeatureAnnouncementEnv;
isPushIntegrated?: boolean;
locale?: () => string;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now pass in locale to handle server side in-app platform notifications

@github-actions
Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "2.0.0-preview-952b49c0",
  "@metamask-previews/accounts-controller": "34.0.0-preview-952b49c0",
  "@metamask-previews/address-book-controller": "7.0.0-preview-952b49c0",
  "@metamask-previews/analytics-controller": "0.0.0-preview-952b49c0",
  "@metamask-previews/announcement-controller": "8.0.0-preview-952b49c0",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-952b49c0",
  "@metamask-previews/approval-controller": "8.0.0-preview-952b49c0",
  "@metamask-previews/assets-controllers": "87.1.1-preview-952b49c0",
  "@metamask-previews/base-controller": "9.0.0-preview-952b49c0",
  "@metamask-previews/bridge-controller": "59.0.0-preview-952b49c0",
  "@metamask-previews/bridge-status-controller": "59.0.0-preview-952b49c0",
  "@metamask-previews/build-utils": "3.0.4-preview-952b49c0",
  "@metamask-previews/chain-agnostic-permission": "1.2.2-preview-952b49c0",
  "@metamask-previews/claims-controller": "0.1.0-preview-952b49c0",
  "@metamask-previews/composable-controller": "12.0.0-preview-952b49c0",
  "@metamask-previews/controller-utils": "11.15.0-preview-952b49c0",
  "@metamask-previews/core-backend": "4.0.0-preview-952b49c0",
  "@metamask-previews/delegation-controller": "1.0.0-preview-952b49c0",
  "@metamask-previews/earn-controller": "9.0.0-preview-952b49c0",
  "@metamask-previews/eip-5792-middleware": "2.0.0-preview-952b49c0",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-952b49c0",
  "@metamask-previews/eip1193-permission-middleware": "1.0.2-preview-952b49c0",
  "@metamask-previews/ens-controller": "18.0.0-preview-952b49c0",
  "@metamask-previews/error-reporting-service": "3.0.0-preview-952b49c0",
  "@metamask-previews/eth-block-tracker": "14.0.0-preview-952b49c0",
  "@metamask-previews/eth-json-rpc-middleware": "21.0.0-preview-952b49c0",
  "@metamask-previews/eth-json-rpc-provider": "5.0.1-preview-952b49c0",
  "@metamask-previews/foundryup": "1.0.1-preview-952b49c0",
  "@metamask-previews/gas-fee-controller": "25.0.0-preview-952b49c0",
  "@metamask-previews/gator-permissions-controller": "0.4.0-preview-952b49c0",
  "@metamask-previews/json-rpc-engine": "10.1.1-preview-952b49c0",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-952b49c0",
  "@metamask-previews/keyring-controller": "24.0.0-preview-952b49c0",
  "@metamask-previews/logging-controller": "7.0.0-preview-952b49c0",
  "@metamask-previews/message-manager": "14.0.0-preview-952b49c0",
  "@metamask-previews/messenger": "0.3.0-preview-952b49c0",
  "@metamask-previews/multichain-account-service": "2.1.0-preview-952b49c0",
  "@metamask-previews/multichain-api-middleware": "1.2.4-preview-952b49c0",
  "@metamask-previews/multichain-network-controller": "2.0.0-preview-952b49c0",
  "@metamask-previews/multichain-transactions-controller": "6.0.0-preview-952b49c0",
  "@metamask-previews/name-controller": "9.0.0-preview-952b49c0",
  "@metamask-previews/network-controller": "25.0.0-preview-952b49c0",
  "@metamask-previews/network-enablement-controller": "3.1.0-preview-952b49c0",
  "@metamask-previews/notification-services-controller": "19.0.0-preview-952b49c0",
  "@metamask-previews/permission-controller": "12.1.0-preview-952b49c0",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-952b49c0",
  "@metamask-previews/phishing-controller": "15.0.0-preview-952b49c0",
  "@metamask-previews/polling-controller": "15.0.0-preview-952b49c0",
  "@metamask-previews/preferences-controller": "21.0.0-preview-952b49c0",
  "@metamask-previews/profile-sync-controller": "26.0.0-preview-952b49c0",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-952b49c0",
  "@metamask-previews/remote-feature-flag-controller": "2.0.0-preview-952b49c0",
  "@metamask-previews/sample-controllers": "3.0.0-preview-952b49c0",
  "@metamask-previews/seedless-onboarding-controller": "6.1.0-preview-952b49c0",
  "@metamask-previews/selected-network-controller": "25.0.0-preview-952b49c0",
  "@metamask-previews/shield-controller": "2.0.0-preview-952b49c0",
  "@metamask-previews/signature-controller": "36.0.0-preview-952b49c0",
  "@metamask-previews/subscription-controller": "3.3.0-preview-952b49c0",
  "@metamask-previews/token-search-discovery-controller": "4.0.0-preview-952b49c0",
  "@metamask-previews/transaction-controller": "61.1.0-preview-952b49c0",
  "@metamask-previews/transaction-pay-controller": "3.1.0-preview-952b49c0",
  "@metamask-previews/user-operation-controller": "40.0.0-preview-952b49c0"
}

}

export const TRIGGER_TYPES_WALLET_SET: Set<string> = new Set([
export const NOTIFICATION_API_TRIGGER_TYPES_SET: Set<string> = new Set([
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update set and add new types supported by our API

TRIGGER_TYPES.ERC1155_RECEIVED,
]) satisfies Set<Exclude<TRIGGER_TYPES, TRIGGER_TYPES.FEATURES_ANNOUNCEMENT>>;

export enum TRIGGER_TYPES_GROUPS {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never used, removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API returns new data shapes, so mocks needed updating

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added mock Platform Notification shape.

* @param notification - API Notification (On-Chain or Platform Notification)
* @returns Normalized Notification
*/
export function processAPINotifications(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New process to handle our API notifications (wallet notifs and platform notifs).
Replaces the old processOnChainNotifications.
Also added an auto-expire to expire old notifications (30 days).

/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
* Script: `npx openapi-typescript <PATH TO NOTIFICATION API SPEC> -o ./schema.d.ts`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new schema generated from our open-api spec

const tokenDecimals = n?.data?.token?.decimals;
const symbol = n?.payload?.data?.token?.symbol;
const tokenAmount = n?.payload?.data?.token?.amount;
const tokenDecimals = n?.payload?.data?.token?.decimals;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shape has changed, we now have a payload object that contains these properties.

@Prithpal-Sooriya Prithpal-Sooriya marked this pull request as ready for review November 10, 2025 17:42
@Prithpal-Sooriya Prithpal-Sooriya requested review from a team as code owners November 10, 2025 17:42
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Platform Notifications Silently Dropped

The createOnChainPushNotificationMessage function doesn't handle platform notifications. When a platform notification (with type: 'platform') is passed to this function, it returns null because TRIGGER_TYPES.PLATFORM isn't included in the createOnChainPushNotificationMessages dictionary. Platform notifications have a template field with localized content instead of payload.data, but the function doesn't check for or use this field. This means platform notifications won't generate push notification messages, potentially causing them to be silently dropped in the push notification flow.

packages/notification-services-controller/src/NotificationServicesPushController/utils/get-notification-message.ts#L255-L276

*/
export function createOnChainPushNotificationMessage(
n: Types.INotification,
translations: TranslationKeys,
): PushNotificationMessage | null {
if (!n?.type) {
return null;
}
const notificationMessage =
createOnChainPushNotificationMessages(translations)[n.type];
if (!notificationMessage) {
return null;
}
let description: string | null = null;
try {
description =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
notificationMessage?.getDescription?.(n as any) ??
notificationMessage.defaultDescription ??
null;

Fix in Cursor Fix in Web


allows us to filter server side different notifications for each platform
@Prithpal-Sooriya
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "3.0.0-preview-ba016213",
  "@metamask-previews/accounts-controller": "34.0.0-preview-ba016213",
  "@metamask-previews/address-book-controller": "7.0.0-preview-ba016213",
  "@metamask-previews/analytics-controller": "0.0.0-preview-ba016213",
  "@metamask-previews/announcement-controller": "8.0.0-preview-ba016213",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-ba016213",
  "@metamask-previews/approval-controller": "8.0.0-preview-ba016213",
  "@metamask-previews/assets-controllers": "88.0.0-preview-ba016213",
  "@metamask-previews/base-controller": "9.0.0-preview-ba016213",
  "@metamask-previews/bridge-controller": "60.0.0-preview-ba016213",
  "@metamask-previews/bridge-status-controller": "60.0.0-preview-ba016213",
  "@metamask-previews/build-utils": "3.0.4-preview-ba016213",
  "@metamask-previews/chain-agnostic-permission": "1.2.2-preview-ba016213",
  "@metamask-previews/claims-controller": "0.1.0-preview-ba016213",
  "@metamask-previews/composable-controller": "12.0.0-preview-ba016213",
  "@metamask-previews/controller-utils": "11.15.0-preview-ba016213",
  "@metamask-previews/core-backend": "4.0.0-preview-ba016213",
  "@metamask-previews/delegation-controller": "1.0.0-preview-ba016213",
  "@metamask-previews/earn-controller": "10.0.0-preview-ba016213",
  "@metamask-previews/eip-5792-middleware": "2.0.0-preview-ba016213",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-ba016213",
  "@metamask-previews/eip1193-permission-middleware": "1.0.2-preview-ba016213",
  "@metamask-previews/ens-controller": "18.0.0-preview-ba016213",
  "@metamask-previews/error-reporting-service": "3.0.0-preview-ba016213",
  "@metamask-previews/eth-block-tracker": "14.0.0-preview-ba016213",
  "@metamask-previews/eth-json-rpc-middleware": "21.0.0-preview-ba016213",
  "@metamask-previews/eth-json-rpc-provider": "5.0.1-preview-ba016213",
  "@metamask-previews/foundryup": "1.0.1-preview-ba016213",
  "@metamask-previews/gas-fee-controller": "25.0.0-preview-ba016213",
  "@metamask-previews/gator-permissions-controller": "0.4.0-preview-ba016213",
  "@metamask-previews/json-rpc-engine": "10.1.1-preview-ba016213",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-ba016213",
  "@metamask-previews/keyring-controller": "24.0.0-preview-ba016213",
  "@metamask-previews/logging-controller": "7.0.0-preview-ba016213",
  "@metamask-previews/message-manager": "14.0.0-preview-ba016213",
  "@metamask-previews/messenger": "0.3.0-preview-ba016213",
  "@metamask-previews/multichain-account-service": "3.0.0-preview-ba016213",
  "@metamask-previews/multichain-api-middleware": "1.2.4-preview-ba016213",
  "@metamask-previews/multichain-network-controller": "2.0.0-preview-ba016213",
  "@metamask-previews/multichain-transactions-controller": "6.0.0-preview-ba016213",
  "@metamask-previews/name-controller": "9.0.0-preview-ba016213",
  "@metamask-previews/network-controller": "25.0.0-preview-ba016213",
  "@metamask-previews/network-enablement-controller": "3.1.0-preview-ba016213",
  "@metamask-previews/notification-services-controller": "19.0.0-preview-ba016213",
  "@metamask-previews/permission-controller": "12.1.0-preview-ba016213",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-ba016213",
  "@metamask-previews/phishing-controller": "15.0.0-preview-ba016213",
  "@metamask-previews/polling-controller": "15.0.0-preview-ba016213",
  "@metamask-previews/preferences-controller": "21.0.0-preview-ba016213",
  "@metamask-previews/profile-sync-controller": "26.0.0-preview-ba016213",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-ba016213",
  "@metamask-previews/remote-feature-flag-controller": "2.0.0-preview-ba016213",
  "@metamask-previews/sample-controllers": "3.0.0-preview-ba016213",
  "@metamask-previews/seedless-onboarding-controller": "6.1.0-preview-ba016213",
  "@metamask-previews/selected-network-controller": "25.0.0-preview-ba016213",
  "@metamask-previews/shield-controller": "2.0.0-preview-ba016213",
  "@metamask-previews/signature-controller": "36.0.0-preview-ba016213",
  "@metamask-previews/subscription-controller": "3.3.0-preview-ba016213",
  "@metamask-previews/token-search-discovery-controller": "4.0.0-preview-ba016213",
  "@metamask-previews/transaction-controller": "61.1.0-preview-ba016213",
  "@metamask-previews/transaction-pay-controller": "4.0.0-preview-ba016213",
  "@metamask-previews/user-operation-controller": "40.0.0-preview-ba016213"
}

@Prithpal-Sooriya Prithpal-Sooriya changed the title feat: migration notification API from v2 to v3 feat: migration notification API from v2 to v3 & add platform notifications Nov 12, 2025
@Prithpal-Sooriya Prithpal-Sooriya changed the title feat: migration notification API from v2 to v3 & add platform notifications feat: migration notification API from v2 to v3 Nov 12, 2025
@Prithpal-Sooriya Prithpal-Sooriya enabled auto-merge (squash) November 12, 2025 18:16
@Prithpal-Sooriya Prithpal-Sooriya merged commit 095f256 into main Nov 12, 2025
271 checks passed
@Prithpal-Sooriya Prithpal-Sooriya deleted the ASSETS-1301/refactor-update-notifications-to-v3-api branch November 12, 2025 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants