Skip to content

feat: Add MembershipSubscription type - #10340

Merged
OGPoyraz merged 2 commits into
mainfrom
ogp/add-new-transaction-type
Sep 22, 2026
Merged

OGPoyraz merged 2 commits into
mainfrom
ogp/add-new-transaction-type

Conversation

@OGPoyraz

@OGPoyraz OGPoyraz commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Explanation

Add MembershipSubscription transaction type to the transaction controller.

This new transaction type represents a transaction to top-up Money Account balance to the required threshold.

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

Low Risk
Additive enum and changelog only; no transaction lifecycle or validation logic changes in this package.

Overview
Adds membershipSubscription to the public TransactionType enum so callers can label transactions that top up a Money Account balance to the required membership threshold (alongside existing Money Account types like moneyAccountDeposit).

The [Unreleased] changelog documents the new type; behavior is unchanged unless a client sets type: TransactionType.membershipSubscription when creating a transaction.

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

@OGPoyraz
OGPoyraz marked this pull request as ready for review September 22, 2026 07:39
@OGPoyraz
OGPoyraz requested review from a team as code owners September 22, 2026 07:39
@OGPoyraz
OGPoyraz deployed to default-branch September 22, 2026 07:39 — with GitHub Actions Active
@matthewwalsh0
matthewwalsh0 self-requested a review September 22, 2026 11:00
@OGPoyraz
OGPoyraz added this pull request to the merge queue Sep 22, 2026
Merged via the queue into main with commit 6b2b147 Sep 22, 2026
116 checks passed
@OGPoyraz
OGPoyraz deleted the ogp/add-new-transaction-type branch September 22, 2026 13:41
pull Bot pushed a commit to Reality2byte/core that referenced this pull request Sep 23, 2026
## Explanation

Release `1275.0.0` with a **major** version bump for
`@metamask/transaction-controller` and a **minor** version bump for
`@metamask/transaction-pay-controller`.

- **`@metamask/transaction-controller`** `70.1.0` → `71.0.0` (major)
- **`@metamask/transaction-pay-controller`** `29.0.2` → `29.1.0` (minor)

### `@metamask/transaction-controller@71.0.0`

**Breaking:** Move sponsorship and signing decisions to optional
approval-time `isSponsored` and `shouldSign` hooks
([MetaMask#10109](MetaMask#10109))
- The hooks default to non-sponsored and local signing when omitted.
Sponsored transactions skip the `shouldSign` hook and local signing,
while transactions that skip local signing retain an existing nonce and
require a publish hook.
- `isGasFeeSponsored` and `isExternalSign` remain in the public types as
deprecated compatibility properties but no longer control the
transaction lifecycle; `isGasFeeSponsored` remains available as
migration metadata.
- Add `TransactionMeta.isGasFeeSponsoredAvailable` and refresh it during
approval preparation when simulation is enabled so sponsorship hooks
receive current availability without overriding simulation preferences.

Other changes:
- Add `membershipSubscription` transaction type
([MetaMask#10340](MetaMask#10340))
- Bump `bn.js` from `^5.2.1` to `^5.2.5`
([MetaMask#10362](MetaMask#10362))

### `@metamask/transaction-pay-controller@29.1.0`

- Support subsidized max Relay deposits using atomic `EXACT_OUTPUT`
quotes with transaction calls embedded, gated by
`payStrategies.relay.atomicMaxEnabled`
([MetaMask#10224](MetaMask#10224))
- Bump `bn.js` from `^5.2.1` to `^5.2.5`
([MetaMask#10362](MetaMask#10362))
- Bump `immer` from `^9.0.6` to `^9.0.21`
([MetaMask#10331](MetaMask#10331))

### Dependency updates

16 packages had their `@metamask/transaction-controller` dependency
range updated to `^71.0.0` with `package.json` changes under this
release branch. Changelog entries for those packages will be generated
by commenting `@metamaskbot update-changelogs` on this PR.

## References

- [MetaMask#10109](MetaMask#10109) — Move
sponsorship and signing decisions to optional approval-time hooks
- [MetaMask#10340](MetaMask#10340) — Add
`membershipSubscription` transaction type
- [MetaMask#10224](MetaMask#10224) — Support
subsidized max Relay deposits using atomic `EXACT_OUTPUT` quotes

## 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
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> The major transaction-controller release changes core transaction
approval, sponsorship, and signing behavior across many downstream
packages that depend on it.
> 
> **Overview**
> Release **`1275.0.0`** cuts published versions for
**`@metamask/transaction-controller`** `71.0.0` (major) and
**`@metamask/transaction-pay-controller`** `29.1.0` (minor), and bumps
the monorepo root version accordingly.
> 
> The transaction-controller release documents **breaking**
approval-time behavior: sponsorship and signing now flow through
optional **`isSponsored`** / **`shouldSign`** hooks instead of
**`isGasFeeSponsored`** / **`isExternalSign`**, plus a new
**`membershipSubscription`** transaction type. This PR mostly
**propagates** that major by setting dependent packages’
`@metamask/transaction-controller` ranges to **`^71.0.0`**, updating
**`yarn.lock`**, and recording bump entries in package changelogs
(including transaction-pay’s dependency bump under `29.1.0`).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b93ad54. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
pull Bot pushed a commit to firas9941/metamask-mobile that referenced this pull request Sep 28, 2026
…k#36696)

## **Description**

Split 2 of 2 from MetaMask#36484, which remains open and unchanged. **Stacked on
MetaMask#36695** so this diff excludes the bottom-sheet implementation. Merge
MetaMask#36695 first, then rebase/retarget this PR to main.

Adds the Membership Subscription developer section, fixed membership
amount handling, membership coverage info, shared
`MONEY_ACCOUNT_DEPOSIT_TYPES`, 1:1 USD/mUSD amount encoding,
generic-banner suppression, and wallet funding-account
initialization/selection. Includes the explicit amount deposit API and
auto-quote/prefill behavior required by the fixed top-up flow, plus an
editable $5 developer example for that API.

### Controller prerequisite

Assumes `TransactionType.membershipSubscription` is available from
transaction-controller. Core PR
MetaMask/core#10340 has merged. **The Mobile
controller dependency update remains a separate prerequisite before this
PR is ready.** No guessed package bump or node_modules patch is
committed here. Production accesses use the actual enum directly;
temporary OGP casts/comments and test enum shims have been removed.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: MetaMask#36484
Depends on: MetaMask#36695
Refs: MetaMask/core#10340
Refs: https://consensyssoftware.atlassian.net/browse/CONF-2010

## **Manual testing steps**

```gherkin
Scenario: Fixed membership top-up
  Given the controller dependency includes membershipSubscription
  And the wallet has a configured Money Account and funded EVM account
  When I choose Top-up 1$ in the Membership Subscription developer section
  Then the membership coverage message replaces the balance projection
  And the amount cannot be edited through the keypad or percentage controls
  And the amount stays 1 mUSD regardless of its market exchange rate
  And the funding account is the selected EVM wallet rather than the Money account
  And changing payment token or account preserves the fixed amount
  And Back dismisses the confirmation
  And the generic alert banner is suppressed without suppressing inline alerts

Scenario: Explicit editable deposit
  When I choose Deposit 5$ in the Money Account developer section
  Then the amount remains editable and a quote is prepared automatically
  And no transaction is automatically approved
```

Validation: **459 tests passed across 13 focused Jest suites** in the
split worktree. Local execution used the existing locally patched
controller runtime; it is not evidence that the unmodified pinned
dependency supports the new enum. Clean-install type/build validation is
blocked on the separate controller update. No lint run, per request.
Fresh device validation remains pending.

## **Screenshots/Recordings**

### **Before**
N/A; new membership-specific flow.

### **After**

#### ** Primary use case ** : Membership top-up with locked 5$ (user
can't change amount)


https://github.com/user-attachments/assets/f5ea6c86-0a93-41b2-87ba-c1e5763b44bf

## **Pre-merge author checklist**

- [x] I have considered contributor and coding standards.
- [x] I have completed the PR template to the best of my ability.
- [x] I have included focused regression tests.
- [x] I have considered documentation requirements.
- [ ] Controller dependency update must land before marking ready.
- [ ] Merge the bottom-sheet prerequisite and retarget this PR to main.
- [ ] Fresh device validation and CI must pass before marking ready.

## **Pre-merge reviewer checklist**

- [ ] I have manually tested the PR.
- [ ] I confirm that the PR addresses its stated scope and testing
requirements.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches MetaMask Pay deposit confirmation, transaction batch typing,
and account override for money movement, though changes reuse existing
deposit infrastructure with heavy test coverage.
> 
> **Overview**
> Adds **membership subscription top-ups** on the existing Money deposit
confirmation path, backed by `@metamask/transaction-controller`
**72.0.0** and `TransactionType.membershipSubscription`.
> 
> **`MONEY_ACCOUNT_DEPOSIT_TYPES`** groups `moneyAccountDeposit` and
membership subscriptions so pay, footer/title, account override, alert
suppression, and related confirmation behavior apply to both.
**`initiateDeposit`** now accepts optional **`amount`** and
**`transactionType`**, passes **`amount`** through navigation, picks
**PrefillCustomAmount** when a positive explicit amount should
auto-quote (excluding card/fiat), and can stamp the nested deposit tx
with the chosen type.
> 
> **Membership-specific UX** in `CustomAmountInfo`: fixed amount (no
keypad/percent edits), **`MembershipInfo`** coverage copy instead of
balance projection, and prepare/quote behavior wired through deposit
prefill and custom-amount hooks. **Developer options** add “Deposit $5”
and “Membership top-up $1” entry points.
> 
> Broad test updates cover navigation params, forced bottom-sheet
failure handling, and parity with money deposits.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5b5c4d5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@tuna1207 tuna1207 mentioned this pull request Oct 2, 2026
3 of 4 tasks
Naz-Ovh pushed a commit to 0x-fork/metamask-core that referenced this pull request Oct 7, 2026
## Explanation

`SubscriptionDelegationService:startSubscriptionWithDelegation` used to
call `ApprovalController:addRequest` with a custom
`subscription_delegation` approval and required the result to contain a
`fundingTransactionHash`. That contract no longer fits how clients fund
Money Account Plus checkout:

- When the Money Account already holds enough mUSD, there is no funding
transaction, so the approval could never succeed.
- When it does not, funding is a `membershipSubscription` transaction
(MetaMask#10340) submitted through MetaMask Pay, and clients
confirm it through the normal transaction confirmation flow
(MetaMask/metamask-mobile#36696) rather than a custom approval nested
inside the service.

This PR moves consent and funding out of core and into the client:

1. The client calls
`SubscriptionDelegationService:checkMoneyAccountBalance`.
2. If the balance is sufficient, the client shows its own consent
approval. If not, it initiates a `membershipSubscription` MetaMask Pay
transaction.
3. Once the user has confirmed, the client calls
`startSubscriptionWithDelegation`.

The service now does the following, in order: refreshes subscriptions
and rejects an active one, upgrades the Money Account, signs or reuses
the payment delegation, verifies it with CHOMP and registers the intent,
then calls `SubscriptionController:startSubscriptionWithCrypto`. It
performs no approval, funding, transaction, or balance check in this
path; the Subscription API validates the Money Account balance
server-side once the subscription is created. `checkMoneyAccountBalance`
and `prepareDelegation` (including `checkBalance`) are unchanged.

Changes in `@metamask/subscription-controller`:

- Remove `#requestApproval`, `#validateApprovalResult`, the
`skipApproval` branch, the approval `bundle` construction, and the
`resultCallbacks` wiring from `startSubscriptionWithDelegation`.
- Remove `skipApproval` from `StartSubscriptionWithDelegationRequest`.
- Remove `SUBSCRIPTION_DELEGATION_APPROVAL_TYPE`,
`SubscriptionFundingRequest`, and
`SubscriptionDelegationApprovalResult`.
- Remove `ApprovalResultMissing` and `InvalidFundingTransactionHash`
from `SubscriptionDelegationServiceErrorMessage`.
- Remove `ApprovalController:addRequest` from
`SubscriptionDelegationServiceMessenger` allowed actions.
- Drop the `@metamask/approval-controller` dependency and its tsconfig
references; regenerate the method action types and README dependency
graph.

Changes in `@metamask/wallet`:

- Stop delegating `ApprovalController:addRequest` to
`SubscriptionDelegationService`, since the narrowed messenger type no
longer allows it.

## References

- Related to MetaMask#10340 (`membershipSubscription` transaction
type)
- Related to MetaMask/metamask-mobile#36696 (membership subscription
top-up confirmation)
- Related to MetaMask#10339 (introduced the approval flow being
removed)

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> Breaking payment-checkout contract: consent and funding move to
clients, so incorrect integration could start subscriptions without
proper user approval or balance.
> 
> **Overview**
> **Breaking:** Money Account Plus checkout no longer runs consent or
funding inside
`SubscriptionDelegationService:startSubscriptionWithDelegation`. The
service drops `ApprovalController:addRequest`, the
`subscription_delegation` approval payload, `skipApproval`, and exported
types/constants tied to funding approval (`SubscriptionFundingRequest`,
`SubscriptionDelegationApprovalResult`,
`SUBSCRIPTION_DELEGATION_APPROVAL_TYPE`, plus related error messages).
The `@metamask/approval-controller` dependency and messenger allowance
for `ApprovalController:addRequest` are removed; `@metamask/wallet`
stops delegating that action to the delegation service.
> 
> After subscription refresh and duplicate-subscription checks, the flow
is unchanged in spirit: upgrade the Money Account, sign or reuse the
payment delegation, CHOMP verify/intent, then
`SubscriptionController:startSubscriptionWithCrypto`. **Callers** must
use `checkMoneyAccountBalance`, show consent, and fund via client flows
(e.g. `membershipSubscription` / MetaMask Pay) **before** calling
`startSubscriptionWithDelegation`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f0e1709. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

This branch was successfully deployed

1 active deployment
default-branch — 904cad2b Deployed Sep 22, 2026 by OGPoyraz via Determine whether this PR is a release PR #4358
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.

2 participants