feat(transaction-pay-controller): gate server strategy per transaction type - #10312
matthewwalsh0 wants to merge 4 commits into
Conversation
…n type `ServerStrategy.supports` previously returned the `payStrategies.server.enabled` feature flag directly, so enabling the strategy selected it for every Pay flow at once, including flows it does not yet implement. Add a `server-support` module with two independent gating layers: - An allowlist of transaction types, sourced from the new `payStrategies.server.enabledTransactionTypes` remote feature flag, so flows can be enabled individually. - Capability guards for request shapes the strategy does not implement, which the feature flag cannot override. Both layers match nested transactions via `hasTransactionType`, since a transaction can carry several types.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1c425f3. Configure here.
|
|
||
| if (request.hyperliquidActivationFeeUsd !== undefined) { | ||
| return ServerUnsupportedReason.HyperliquidActivationFee; | ||
| } |
There was a problem hiding this comment.
Activation fee guard never triggers
Medium Severity
The HyperLiquid activation-fee guard checks hyperliquidActivationFeeUsd, but the quote orchestrator never sets that field before supports runs. Relay writes it only while fetching quotes, after a strategy is already chosen. Enabling an allowlisted HyperLiquid-source type therefore still selects the server strategy for unactivated accounts, and those quotes will not reserve the activation fee.
Reviewed by Cursor Bugbot for commit 1c425f3. Configure here.


Explanation
ServerStrategy.supportsreturned thepayStrategies.server.enabledfeature flag directly, so the flag was all-or-nothing: enabling it selected the server strategy for every MetaMask Pay flow at once, including flows the strategy does not yet implement. That makes the strategy difficult to validate, because there is no way to try one flow while leaving the rest on the relay strategy.This PR adds a
server-supportmodule that narrowssupportsthrough two independent layers:payStrategies.server.enabledTransactionTypesremote feature flag. It defaults to an empty list, sopayStrategies.server.enabledon its own no longer selects the strategy for anything, and flows are opted in one at a time.Declines are reported as a named
ServerUnsupportedReasonand logged, so it is clear which layer rejected a request.Both layers match against nested transactions using
hasTransactionType, since a transaction can carry several types. The exact-output guard is evaluated after the allowlist so that a transaction combining an allowlisted type with an exact-output type is still declined.Unrecognised values in the feature flag are discarded rather than trusted, so a malformed remote configuration cannot widen the allowlist.
References
Checklist
Note
Medium Risk
Changes which MetaMask Pay flows use the server strategy at quote time; incorrect flag config could leave flows on relay unexpectedly, but defaults are conservative and hard guards block known-bad request shapes.
Overview
Server pay strategy selection is no longer all-or-nothing when
payStrategies.server.enabledis on.ServerStrategy.supportsnow requires the transaction (including nested types) to appear in the new remote flagpayStrategies.server.enabledTransactionTypes, which defaults to an empty list so enabling the server strategy alone does not route any flows until types are opted in individually.A new
server-supportlayer evaluates requests after the global enable check:getServerUnsupportedReasonreturns named decline reasons for flows that are not allowlisted or that use request shapes the server strategy does not implement yet (e.g. max amount, non-atomic, exact-output deposit-and-order types, HyperLiquid activation fee, Polymarket deposit wallet, direct mUSD money account). Those capability checks cannot be overridden by the flag. Declines are logged with reason and transaction type.Feature-flag parsing adds
enabledTransactionTypestoPayStrategiesConfig, normalizing remote strings to knownTransactionTypevalues and discarding unknown or duplicate entries.Reviewed by Cursor Bugbot for commit 1c425f3. Bugbot is set up for automated code reviews on this repo. Configure here.