Skip to content

feat(transaction-controller): pass isInternal: true at internal call sites#29525

Draft
matthewwalsh0 wants to merge 1 commit intomainfrom
feat/transaction-controller-is-internal
Draft

feat(transaction-controller): pass isInternal: true at internal call sites#29525
matthewwalsh0 wants to merge 1 commit intomainfrom
feat/transaction-controller-is-internal

Conversation

@matthewwalsh0
Copy link
Copy Markdown
Member

Description

Adopts the new isInternal flag introduced in @metamask/transaction-controller@65.0.0. The controller previously inferred internal vs external trust from the request origin (origin === ORIGIN_METAMASK ⇒ internal). That coupling has been replaced with an explicit, optional isInternal: boolean flag on addTransaction / addTransactionBatch, defaulting to false. To keep current behaviour, every internal call site in mobile must opt in.

This PR adopts isInternal: true at the internal entry points and leaves dapp-driven paths defaulting to false:

Call site Classification Action
Main Send flow (confirmations/utils/send.ts) Internal isInternal: true
mUSD conversion (Earn/utils/musdConversionTransaction.ts) Internal isInternal: true
Merkl claim (Earn/.../useMerklClaimTransaction.ts) Internal isInternal: true
MMM Card delegation (Card/hooks/useCardDelegation.ts) Internal isInternal: true
Money Account deposit + withdrawal (Money/hooks/useMoneyAccount.ts and Money/utils/moneyAccountTransactions.ts) Internal isInternal: true
Perps withdrawal (Perps/hooks/usePerpsWithdrawConfirmation.ts) Internal isInternal: true
Pooled staking (deposit / unstake / claim hooks) Internal isInternal: true
Predict claim (Predict/controllers/PredictController.ts) Internal isInternal: true
BridgeStatusController batch callback Internal isInternal: true
Confirmations developer tools Internal isInternal: true
BackgroundBridge (eth_sendTransaction, wallet_sendCalls) External Default (false)
WalletConnect v2 session request External Default (false)
Deeplink handlers (deeplink.ts, handleApproveUrl.ts) External Default (false)

Incidental changes

  • Bumps @metamask/messenger to ^1.2.0 to match the version required by transaction-controller 65.0.0. After dedupe, all packages resolve to 1.2.0.
  • Fixes a latent generic-arity issue in app/core/Engine/types.ts's ControllerMessenger alias. Messenger 1.2 declares Messenger with four generic parameters (Namespace, Action, Event, Parent), and mobile's alias only provided three, so Parent defaulted to never. Concrete controller messengers (which set Parent explicitly) were therefore not assignable to ControllerMessenger. Widened to Messenger<string, ActionConstraint, EventConstraint, any>.
  • Adapts SnapsMethodMiddleware to messenger 1.2's call-overload-bound this typing. The pre-existing controllerMessenger.call.bind(controllerMessenger, ...) pattern no longer type-checks because each call overload now declares its own this. A small typed callMessenger wrapper restores partial application without changing runtime behaviour.

Preview build

This PR depends on the unreleased core PR via previewBuilds:

"@metamask/transaction-controller": { "type": "breaking", "previewVersion": "65.0.0-preview-156c8ccf7" },
"@metamask/transaction-pay-controller": { "type": "non-breaking", "previewVersion": "20.0.1-preview-156c8ccf7" },
"@metamask/bridge-status-controller": { "type": "non-breaking", "previewVersion": "71.1.0-preview-156c8ccf7" }

These will be replaced with released versions before this PR merges.

Manual testing steps

  1. Send a native asset / token via the in-app Send flow — should still work and reach submitted.
  2. Open a dapp in the in-app browser and trigger eth_sendTransaction — confirmation flow should still display the dapp's origin and dapp-suggested gas fees.
  3. Pair a WalletConnect session and approve a transaction — origin / size limits / EIP-7702 rejection rules still apply.
  4. Convert ETH → mUSD via Earn — internal transaction is accepted and tracked.
  5. Claim Merkl rewards — internal transaction is accepted.
  6. Approve the Card delegation — internal approval transaction is accepted.
  7. Withdraw from Perps — internal batch is accepted.
  8. Deposit to / withdraw from a Money Account — internal batch (deposit) and internal single tx (withdrawal) are accepted.
  9. Pooled staking deposit, unstake, and claim — each internal transaction is accepted.
  10. Claim a winning Predict position — internal batch is accepted.
  11. Bridge a token and confirm BridgeStatusController's status callback completes without rejection.

Pre-merge author checklist

  • I've followed the MetaMask Mobile Coding Standards.
  • I've completed the PR template to the best of my ability
  • I've included tests if applicable
  • I've documented my code using JSDoc format if applicable
  • I've applied the right labels on the PR

…sites

Adopts the new `isInternal` flag introduced in
`@metamask/transaction-controller@65.0.0`. Every internal call site
(Send, mUSD, Merkl, Card, Perps, Money, Stake, Predict, BridgeStatus,
developer tools) now passes `isInternal: true` so the controller's
internal-only validation behaviour is preserved without relying on
`origin === 'metamask'` or `origin === MMM_ORIGIN`. Dapp-driven paths
(BackgroundBridge, WalletConnect, deeplink handlers) keep the default
`isInternal: false`.

Also bumps `@metamask/messenger` to `^1.2.0` to match the version
required by the new transaction-controller, fixes a latent generic
type-arity issue in `ControllerMessenger`'s definition surfaced by
the stricter typing in messenger 1.2, and adapts SnapsMethodMiddleware
to the new `call`-overload-bound `this` typing.
@metamaskbotv2 metamaskbotv2 Bot added the team-confirmations Push issues to confirmations team label Apr 29, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeIdentity, SmokeNetworkAbstractions, SmokeNetworkExpansion, SmokeTrade, SmokeWalletPlatform, SmokeCard, SmokePerps, SmokeRamps, SmokeMultiChainAPI, SmokePredictions, SmokeSeedlessOnboarding, SmokeBrowser, SmokeSnaps
  • Selected Performance tags: @PerformanceAccountList, @PerformanceOnboarding, @PerformanceLogin, @PerformanceSwaps, @PerformanceLaunch, @PerformanceAssetLoading, @PerformancePredict, @PerformancePreps
  • Risk Level: high
  • AI Confidence: 100%
click to see 🤖 AI reasoning details

E2E Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/transaction-controller, @metamask/transaction-pay-controller, @metamask/bridge-status-controller. Running all tests.

Performance Test Selection:
Hard rule (controller-version-update): @MetaMask controller package version updated in package.json: @metamask/transaction-controller, @metamask/transaction-pay-controller, @metamask/bridge-status-controller. Running all tests.

View GitHub Actions results

@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​metamask/​bridge-status-controller@​71.0.0 ⏵ 71.1.0-preview-156c8ccf7100 +4100100 +23100 +2100
Updatednpm/​@​metamask/​transaction-pay-controller@​20.0.0 ⏵ 20.0.1-preview-156c8ccf7100 +3100100 +21100 +3100

View full report

@github-actions
Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
12 value mismatches detected (expected — fixture represents an existing user).
View details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-M team-confirmations Push issues to confirmations team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant