Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: decouple push logic to be platform agnostic #5120

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Prithpal-Sooriya
Copy link
Contributor

@Prithpal-Sooriya Prithpal-Sooriya commented Jan 9, 2025

Explanation

Decouples web push notifications so that the controller is platform agnostic.

This controller was tied heavily to web, and was not compatible for mobile use (react-native). We have now isolated and moved the web specific code into a single file (web/push-helpers.ts), and we expect the platforms to inject the push service interface into the controller (which allows platforms to controller how to display push notifications and click on push notifications).

This is a large restructuring and is a breaking change.

References

Changelog

@metamask/notification-services-controller

  • ADDED: New interface PushService
  • CHANGED (BREAKING): NotificationServicesPushController config property to inject a PushService interface during controller creation.
  • ADDED: New subpath exports for @metamask/notification-services-controller/push-services/web to help web platforms inject push-services into the push controller.

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 highlighted breaking changes using the "BREAKING" category above as appropriate
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

…form agnostic

this controller was ties to web, and was not compatible for react-native. We now have moves the logic that touches firebase and browser built-ins to an isolated file, and expect platforms to inject this into the controller

This breaks the controller and forces the platform to inject how push notifications should be received and clicked
reduces complexity that the platform needs to write.
@Prithpal-Sooriya
Copy link
Contributor Author

@metamaskbot publish-preview

Copy link
Contributor

github-actions bot commented Jan 9, 2025

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

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "20.0.2-preview-4e54ae1",
  "@metamask-previews/address-book-controller": "6.0.2-preview-4e54ae1",
  "@metamask-previews/announcement-controller": "7.0.2-preview-4e54ae1",
  "@metamask-previews/approval-controller": "7.1.1-preview-4e54ae1",
  "@metamask-previews/assets-controllers": "45.1.2-preview-4e54ae1",
  "@metamask-previews/base-controller": "7.1.0-preview-4e54ae1",
  "@metamask-previews/build-utils": "3.0.2-preview-4e54ae1",
  "@metamask-previews/chain-controller": "0.2.2-preview-4e54ae1",
  "@metamask-previews/composable-controller": "10.0.0-preview-4e54ae1",
  "@metamask-previews/controller-utils": "11.4.4-preview-4e54ae1",
  "@metamask-previews/ens-controller": "15.0.1-preview-4e54ae1",
  "@metamask-previews/eth-json-rpc-provider": "4.1.7-preview-4e54ae1",
  "@metamask-previews/gas-fee-controller": "22.0.2-preview-4e54ae1",
  "@metamask-previews/json-rpc-engine": "10.0.2-preview-4e54ae1",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.6-preview-4e54ae1",
  "@metamask-previews/keyring-controller": "19.0.2-preview-4e54ae1",
  "@metamask-previews/logging-controller": "6.0.3-preview-4e54ae1",
  "@metamask-previews/message-manager": "11.0.3-preview-4e54ae1",
  "@metamask-previews/multichain": "2.0.0-preview-4e54ae1",
  "@metamask-previews/name-controller": "8.0.2-preview-4e54ae1",
  "@metamask-previews/network-controller": "22.1.1-preview-4e54ae1",
  "@metamask-previews/notification-services-controller": "0.15.0-preview-4e54ae1",
  "@metamask-previews/permission-controller": "11.0.4-preview-4e54ae1",
  "@metamask-previews/permission-log-controller": "3.0.2-preview-4e54ae1",
  "@metamask-previews/phishing-controller": "12.3.1-preview-4e54ae1",
  "@metamask-previews/polling-controller": "12.0.2-preview-4e54ae1",
  "@metamask-previews/preferences-controller": "15.0.1-preview-4e54ae1",
  "@metamask-previews/profile-sync-controller": "3.2.0-preview-4e54ae1",
  "@metamask-previews/queued-request-controller": "8.0.2-preview-4e54ae1",
  "@metamask-previews/rate-limit-controller": "6.0.2-preview-4e54ae1",
  "@metamask-previews/remote-feature-flag-controller": "1.2.0-preview-4e54ae1",
  "@metamask-previews/selected-network-controller": "20.0.2-preview-4e54ae1",
  "@metamask-previews/signature-controller": "23.2.0-preview-4e54ae1",
  "@metamask-previews/transaction-controller": "42.1.0-preview-4e54ae1",
  "@metamask-previews/user-operation-controller": "21.0.0-preview-4e54ae1"
}

@@ -67,6 +67,16 @@
"default": "./dist/NotificationServicesPushController/index.cjs"
}
},
"./push-services/web": {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

exposing new subpath exports to differ between web and mobile specific helpers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can be done iteratively. We have done web, since there was existing code that we refactored and gutted from this controller.

We will do Mobile after PoC'ing this and seeing if there is value from it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also to note that these subpaths are fully isolated and not used anywhere, so they should be tree-shakeable for bundle splitting.

However specific modules for web/mobile might run into lavamoat issues... or maybe not... we'll see.

* determine the config used for push notification services
*/
platform: 'extension' | 'mobile';
pushService: PushService;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The controller now must be initialised with this Push Service interface.
The /web/push-helpers can assist extension when injecting.
We will see if we can do the same for mobile.

NotificationServicesPushControllerMessenger,
} from '..';

export const buildPushPlatformNotificationsControllerMessenger =
Copy link
Contributor Author

@Prithpal-Sooriya Prithpal-Sooriya Jan 9, 2025

Choose a reason for hiding this comment

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

This mock was lifted out of a test file, and exported, so it can be reused in other tests.

import {
listenToPushNotificationsClicked,
listenToPushNotificationsReceived,
} from './push/push-web';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the initial design, we did a decent start at decoupling the webby parts from this controller (to make it agnostic). However the issue was we were directly importing and using the web module directly!

Comment on lines +187 to +197
export function createSubscribeToPushNotifications(props: {
onReceivedHandler: (
notification: Types.INotification,
) => void | Promise<void>;
onClickHandler: (
e: NotificationEvent,
notification: Types.INotification,
) => void;
messenger: NotificationServicesPushControllerMessenger;
}) {
return async function (env: PushNotificationEnv) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a scary interface, but see tests on how to use it.

  1. This is a func that returns a func (curried function), mostly since we need the return function to have the same interface for web and mobile so we can correctly inject it.
  2. The props we expose is to add some extra customisability from the platform. E.g. when you receive a notification what icon or thing show we show; when you click a notification, where should this navigate you to.
    • It allows the platform to take control of showing/interacting, but the core can still control publishing events; and when to invoke the methods the platform provides.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of word vomit here, I'll record a video once this has been PoC'ed and ready for review.

@Prithpal-Sooriya
Copy link
Contributor Author

@metamaskbot publish-preview

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/accounts-controller": "21.0.0-preview-55b37eea",
  "@metamask-previews/address-book-controller": "6.0.2-preview-55b37eea",
  "@metamask-previews/announcement-controller": "7.0.2-preview-55b37eea",
  "@metamask-previews/approval-controller": "7.1.2-preview-55b37eea",
  "@metamask-previews/assets-controllers": "46.0.0-preview-55b37eea",
  "@metamask-previews/base-controller": "7.1.1-preview-55b37eea",
  "@metamask-previews/build-utils": "3.0.2-preview-55b37eea",
  "@metamask-previews/composable-controller": "10.0.0-preview-55b37eea",
  "@metamask-previews/controller-utils": "11.4.5-preview-55b37eea",
  "@metamask-previews/ens-controller": "15.0.1-preview-55b37eea",
  "@metamask-previews/eth-json-rpc-provider": "4.1.7-preview-55b37eea",
  "@metamask-previews/gas-fee-controller": "22.0.2-preview-55b37eea",
  "@metamask-previews/json-rpc-engine": "10.0.2-preview-55b37eea",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.6-preview-55b37eea",
  "@metamask-previews/keyring-controller": "19.0.3-preview-55b37eea",
  "@metamask-previews/logging-controller": "6.0.3-preview-55b37eea",
  "@metamask-previews/message-manager": "11.0.3-preview-55b37eea",
  "@metamask-previews/multichain": "2.0.0-preview-55b37eea",
  "@metamask-previews/name-controller": "8.0.2-preview-55b37eea",
  "@metamask-previews/network-controller": "22.1.1-preview-55b37eea",
  "@metamask-previews/notification-services-controller": "0.16.0-preview-55b37eea",
  "@metamask-previews/permission-controller": "11.0.5-preview-55b37eea",
  "@metamask-previews/permission-log-controller": "3.0.2-preview-55b37eea",
  "@metamask-previews/phishing-controller": "12.3.1-preview-55b37eea",
  "@metamask-previews/polling-controller": "12.0.2-preview-55b37eea",
  "@metamask-previews/preferences-controller": "15.0.1-preview-55b37eea",
  "@metamask-previews/profile-sync-controller": "4.1.0-preview-55b37eea",
  "@metamask-previews/queued-request-controller": "8.0.2-preview-55b37eea",
  "@metamask-previews/rate-limit-controller": "6.0.2-preview-55b37eea",
  "@metamask-previews/remote-feature-flag-controller": "1.3.0-preview-55b37eea",
  "@metamask-previews/selected-network-controller": "20.0.2-preview-55b37eea",
  "@metamask-previews/signature-controller": "23.2.0-preview-55b37eea",
  "@metamask-previews/transaction-controller": "43.0.0-preview-55b37eea",
  "@metamask-previews/user-operation-controller": "22.0.0-preview-55b37eea"
}

@Prithpal-Sooriya
Copy link
Contributor Author

@metamaskbot publish-preview

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/accounts-controller": "21.0.0-preview-a7b445fc",
  "@metamask-previews/address-book-controller": "6.0.2-preview-a7b445fc",
  "@metamask-previews/announcement-controller": "7.0.2-preview-a7b445fc",
  "@metamask-previews/approval-controller": "7.1.2-preview-a7b445fc",
  "@metamask-previews/assets-controllers": "46.0.0-preview-a7b445fc",
  "@metamask-previews/base-controller": "7.1.1-preview-a7b445fc",
  "@metamask-previews/build-utils": "3.0.2-preview-a7b445fc",
  "@metamask-previews/composable-controller": "10.0.0-preview-a7b445fc",
  "@metamask-previews/controller-utils": "11.4.5-preview-a7b445fc",
  "@metamask-previews/ens-controller": "15.0.1-preview-a7b445fc",
  "@metamask-previews/eth-json-rpc-provider": "4.1.7-preview-a7b445fc",
  "@metamask-previews/gas-fee-controller": "22.0.2-preview-a7b445fc",
  "@metamask-previews/json-rpc-engine": "10.0.2-preview-a7b445fc",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.6-preview-a7b445fc",
  "@metamask-previews/keyring-controller": "19.0.3-preview-a7b445fc",
  "@metamask-previews/logging-controller": "6.0.3-preview-a7b445fc",
  "@metamask-previews/message-manager": "11.0.3-preview-a7b445fc",
  "@metamask-previews/multichain": "2.0.0-preview-a7b445fc",
  "@metamask-previews/name-controller": "8.0.2-preview-a7b445fc",
  "@metamask-previews/network-controller": "22.1.1-preview-a7b445fc",
  "@metamask-previews/notification-services-controller": "0.16.0-preview-a7b445fc",
  "@metamask-previews/permission-controller": "11.0.5-preview-a7b445fc",
  "@metamask-previews/permission-log-controller": "3.0.2-preview-a7b445fc",
  "@metamask-previews/phishing-controller": "12.3.1-preview-a7b445fc",
  "@metamask-previews/polling-controller": "12.0.2-preview-a7b445fc",
  "@metamask-previews/preferences-controller": "15.0.1-preview-a7b445fc",
  "@metamask-previews/profile-sync-controller": "4.1.0-preview-a7b445fc",
  "@metamask-previews/queued-request-controller": "8.0.2-preview-a7b445fc",
  "@metamask-previews/rate-limit-controller": "6.0.2-preview-a7b445fc",
  "@metamask-previews/remote-feature-flag-controller": "1.3.0-preview-a7b445fc",
  "@metamask-previews/selected-network-controller": "20.0.2-preview-a7b445fc",
  "@metamask-previews/signature-controller": "23.2.0-preview-a7b445fc",
  "@metamask-previews/transaction-controller": "43.0.0-preview-a7b445fc",
  "@metamask-previews/user-operation-controller": "22.0.0-preview-a7b445fc"
}

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.

1 participant