Skip to content

feat: add is user elibile for trial method - #10622

Merged
tuna1207 merged 9 commits into
mainfrom
feat/subscription-trial-eligibility
Oct 1, 2026
Merged

tuna1207 merged 9 commits into
mainfrom
feat/subscription-trial-eligibility

Conversation

@tuna1207

@tuna1207 tuna1207 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Explanation

Clients currently have no single place to ask whether a user can start a free trial for a subscription product. Each product has its own rule:

  • Shield: the user has never trialed Shield.
  • Money Account Plus: the user has never trialed it and signed in with social login.

This PR adds SubscriptionController:isUserEligibleForTrial(productType), which returns a Promise<boolean>:

  • If trialedProducts already includes productType, it returns false straight away.
  • For Shield, it returns true without calling any other controller.
  • For Money Account Plus, it returns the result of SeedlessOnboardingController:getIsUserAuthenticated. That action returns false for SRP users and for locked wallets. Only unlocked users can subscribe, so this works as the social-login check.
  • The method uses a switch on productType. Adding a new member to PRODUCT_TYPES fails compilation until the switch handles it.
    To call the seedless action, @metamask/subscription-controller now depends on @metamask/seedless-onboarding-controller. It's a type-only import, and the package is already a dependency of profile-sync-controller, so this adds no circular dependency.
    @metamask/wallet now delegates SeedlessOnboardingController:getIsUserAuthenticated to the SubscriptionController messenger, so the default wallet setup keeps working.

References

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
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Breaking messenger wiring is required for all non-wallet hosts, and trial gating for Money Account Plus depends on seedless auth state being correct.

Overview
Adds SubscriptionController:isUserEligibleForTrial, a single messenger-backed way for clients to ask whether a user can start a free trial for a product.

Eligibility first checks trialedProducts in controller state; if the product was already trialed, the method returns false. Shield is eligible when that check passes. Money Account Plus also requires SeedlessOnboardingController:getIsUserAuthenticated (used as the social-login gate). Unknown product types throw at runtime, and new PRODUCT_TYPES values must be handled in the switch or TypeScript fails to compile.

This is a breaking integration change: SubscriptionControllerMessenger must be allowed to call SeedlessOnboardingController:getIsUserAuthenticated. @metamask/subscription-controller adds a dependency on @metamask/seedless-onboarding-controller, and @metamask/wallet delegates that action in its default SubscriptionController setup so trial checks work out of the box.

Reviewed by Cursor Bugbot for commit 9670d93. Bugbot is set up for automated code reviews on this repo. Configure here.

@tuna1207
tuna1207 marked this pull request as ready for review September 30, 2026 13:18
@tuna1207
tuna1207 requested review from a team as code owners September 30, 2026 13:18
chaitanyapotti
chaitanyapotti previously approved these changes Sep 30, 2026
@tuna1207
tuna1207 enabled auto-merge September 30, 2026 13:38
chaitanyapotti
chaitanyapotti previously approved these changes Sep 30, 2026

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just a few suggestions to the changelogs.

Comment thread packages/subscription-controller/CHANGELOG.md Outdated
Comment thread packages/wallet/CHANGELOG.md Outdated
Comment on lines +12 to +14
- **BREAKING:** Add `SubscriptionController:isUserEligibleForTrial` to report whether a user can start a trial for a product ([#10622](https://github.com/MetaMask/core/pull/10622))
- Shield is eligible when the user has not trialed Shield before.
- Money Account Plus is eligible when the user has not trialed it before and `SeedlessOnboardingController:getIsUserAuthenticated` is true.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this a breaking change? Adding a new method to a class should not be breaking. It's also not common to provide implementation details in changelogs so perhaps we can simplify this a bit:

Suggested change
- **BREAKING:** Add `SubscriptionController:isUserEligibleForTrial` to report whether a user can start a trial for a product ([#10622](https://github.com/MetaMask/core/pull/10622))
- Shield is eligible when the user has not trialed Shield before.
- Money Account Plus is eligible when the user has not trialed it before and `SeedlessOnboardingController:getIsUserAuthenticated` is true.
- Add `SubscriptionController:isUserEligibleForTrial` to report whether a user can start a trial for a product ([#10622](https://github.com/MetaMask/core/pull/10622))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

oh this is breaking because it requires adding new messenger action for this new method

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Are you saying that in order to call this method, SeedlessOnboardingController:getIsUserAuthenticated must be delegated? If so, we could combine this and the entry below. I've made a separate suggestion for that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, agree 👍

tuna1207 and others added 2 commits September 30, 2026 21:38
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
Comment thread packages/subscription-controller/CHANGELOG.md Outdated
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
@tuna1207
tuna1207 requested a review from mcmire September 30, 2026 15:24
Comment thread packages/subscription-controller/CHANGELOG.md
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
@tuna1207
tuna1207 requested a review from mcmire September 30, 2026 15:25

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Everything looks good now! Thanks for your patience.

@tuna1207
tuna1207 added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit 42a92c3 Oct 1, 2026
55 checks passed
@tuna1207
tuna1207 deleted the feat/subscription-trial-eligibility branch October 1, 2026 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants