Skip to content

feat: harden relay status polling#8189

Merged
matthewwalsh0 merged 4 commits intomainfrom
feat/relay-polling-improvements
Mar 17, 2026
Merged

feat: harden relay status polling#8189
matthewwalsh0 merged 4 commits intomainfrom
feat/relay-polling-improvements

Conversation

@matthewwalsh0
Copy link
Member

@matthewwalsh0 matthewwalsh0 commented Mar 11, 2026

Explanation

Relay status polling currently treats any non-success/failure status as pending, meaning an unexpected API response silently loops forever. This PR hardens the polling logic to handle an explicit set of known statuses and throw immediately on unrecognized values, preventing silent infinite loops.

Additionally, the polling interval and timeout are now configurable via feature flags (relay.pollingInterval and relay.pollingTimeout), and transient network errors are silently retried instead of immediately propagating — only surfacing if the configured timeout is reached.

On the transaction controller side, the startup cleanup now uses a distinct error message when an incomplete transaction has requiredTransactionIds that are all confirmed, distinguishing "relay completed but parent didn't finish" from the general incomplete case.

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
Changes Relay intent completion polling behavior (status handling, retries, and optional timeouts), which could affect MetaMask Pay transaction finalization in edge cases. Startup transaction cleanup now emits a new failure message variant, impacting downstream error handling/telemetry expectations.

Overview
Hardens Relay status polling by explicitly categorizing statuses as pending vs failure, throwing on unrecognized statuses (instead of polling indefinitely), and retrying transient network errors.

Makes polling configurable via new feature-flag fields relay.pollingInterval (defaulting to the existing constant) and optional relay.pollingTimeout, with timeout errors including the last seen status.

Improves startup cleanup diagnostics in TransactionController by using a distinct failure message when an incomplete transaction’s requiredTransactionIds are all already confirmed.

Written by Cursor Bugbot for commit 80b21ff. This will update automatically on new commits. Configure here.

matthewwalsh0 added a commit that referenced this pull request Mar 12, 2026
… statuses

- Add unit tests for getRelayPollingInterval and getRelayPollingTimeout
- Move RELAY_PENDING_STATUSES and RELAY_FAILURE_STATUSES to constants.ts
- Add missing 'depositing' status from Relay v3 API docs
- Add PR number (#8189) to changelog entries
@matthewwalsh0 matthewwalsh0 changed the title feat: harden relay status polling and improve startup error messages feat: harden relay status polling Mar 12, 2026
@matthewwalsh0 matthewwalsh0 marked this pull request as ready for review March 12, 2026 00:43
@matthewwalsh0 matthewwalsh0 requested review from a team as code owners March 12, 2026 00:43
@matthewwalsh0
Copy link
Member Author

@metamaskbot publish-preview

@github-actions
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/account-tree-controller": "5.0.1-preview-e0ce55a8c",
  "@metamask-previews/accounts-controller": "37.0.0-preview-e0ce55a8c",
  "@metamask-previews/address-book-controller": "7.0.1-preview-e0ce55a8c",
  "@metamask-previews/ai-controllers": "0.2.0-preview-e0ce55a8c",
  "@metamask-previews/analytics-controller": "1.0.0-preview-e0ce55a8c",
  "@metamask-previews/analytics-data-regulation-controller": "0.0.0-preview-e0ce55a8c",
  "@metamask-previews/announcement-controller": "8.0.0-preview-e0ce55a8c",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-e0ce55a8c",
  "@metamask-previews/approval-controller": "8.0.0-preview-e0ce55a8c",
  "@metamask-previews/assets-controller": "2.3.0-preview-e0ce55a8c",
  "@metamask-previews/assets-controllers": "100.2.1-preview-e0ce55a8c",
  "@metamask-previews/base-controller": "9.0.0-preview-e0ce55a8c",
  "@metamask-previews/base-data-service": "0.0.0-preview-e0ce55a8c",
  "@metamask-previews/bridge-controller": "69.1.0-preview-e0ce55a8c",
  "@metamask-previews/bridge-status-controller": "68.1.0-preview-e0ce55a8c",
  "@metamask-previews/build-utils": "3.0.4-preview-e0ce55a8c",
  "@metamask-previews/chain-agnostic-permission": "1.4.0-preview-e0ce55a8c",
  "@metamask-previews/claims-controller": "0.4.3-preview-e0ce55a8c",
  "@metamask-previews/client-controller": "1.0.0-preview-e0ce55a8c",
  "@metamask-previews/compliance-controller": "1.0.1-preview-e0ce55a8c",
  "@metamask-previews/composable-controller": "12.0.0-preview-e0ce55a8c",
  "@metamask-previews/config-registry-controller": "0.1.1-preview-e0ce55a8c",
  "@metamask-previews/connectivity-controller": "0.1.0-preview-e0ce55a8c",
  "@metamask-previews/controller-utils": "11.19.0-preview-e0ce55a8c",
  "@metamask-previews/core-backend": "6.1.1-preview-e0ce55a8c",
  "@metamask-previews/delegation-controller": "2.0.2-preview-e0ce55a8c",
  "@metamask-previews/earn-controller": "11.1.2-preview-e0ce55a8c",
  "@metamask-previews/eip-5792-middleware": "3.0.0-preview-e0ce55a8c",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-e0ce55a8c",
  "@metamask-previews/eip1193-permission-middleware": "1.0.3-preview-e0ce55a8c",
  "@metamask-previews/ens-controller": "19.0.3-preview-e0ce55a8c",
  "@metamask-previews/error-reporting-service": "3.0.1-preview-e0ce55a8c",
  "@metamask-previews/eth-block-tracker": "15.0.1-preview-e0ce55a8c",
  "@metamask-previews/eth-json-rpc-middleware": "23.1.0-preview-e0ce55a8c",
  "@metamask-previews/eth-json-rpc-provider": "6.0.0-preview-e0ce55a8c",
  "@metamask-previews/foundryup": "1.0.1-preview-e0ce55a8c",
  "@metamask-previews/gas-fee-controller": "26.0.3-preview-e0ce55a8c",
  "@metamask-previews/gator-permissions-controller": "2.1.0-preview-e0ce55a8c",
  "@metamask-previews/geolocation-controller": "0.1.1-preview-e0ce55a8c",
  "@metamask-previews/json-rpc-engine": "10.2.3-preview-e0ce55a8c",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-e0ce55a8c",
  "@metamask-previews/keyring-controller": "25.1.0-preview-e0ce55a8c",
  "@metamask-previews/logging-controller": "7.0.1-preview-e0ce55a8c",
  "@metamask-previews/message-manager": "14.1.0-preview-e0ce55a8c",
  "@metamask-previews/messenger": "0.3.0-preview-e0ce55a8c",
  "@metamask-previews/multichain-account-service": "7.1.0-preview-e0ce55a8c",
  "@metamask-previews/multichain-api-middleware": "1.2.7-preview-e0ce55a8c",
  "@metamask-previews/multichain-network-controller": "3.0.5-preview-e0ce55a8c",
  "@metamask-previews/multichain-transactions-controller": "7.0.2-preview-e0ce55a8c",
  "@metamask-previews/name-controller": "9.0.0-preview-e0ce55a8c",
  "@metamask-previews/network-controller": "30.0.0-preview-e0ce55a8c",
  "@metamask-previews/network-enablement-controller": "4.2.0-preview-e0ce55a8c",
  "@metamask-previews/notification-services-controller": "23.0.0-preview-e0ce55a8c",
  "@metamask-previews/permission-controller": "12.2.0-preview-e0ce55a8c",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-e0ce55a8c",
  "@metamask-previews/perps-controller": "1.0.1-preview-e0ce55a8c",
  "@metamask-previews/phishing-controller": "16.3.0-preview-e0ce55a8c",
  "@metamask-previews/polling-controller": "16.0.3-preview-e0ce55a8c",
  "@metamask-previews/preferences-controller": "23.0.0-preview-e0ce55a8c",
  "@metamask-previews/profile-metrics-controller": "3.0.3-preview-e0ce55a8c",
  "@metamask-previews/profile-sync-controller": "28.0.0-preview-e0ce55a8c",
  "@metamask-previews/ramps-controller": "12.0.0-preview-e0ce55a8c",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-e0ce55a8c",
  "@metamask-previews/remote-feature-flag-controller": "4.1.0-preview-e0ce55a8c",
  "@metamask-previews/sample-controllers": "4.0.3-preview-e0ce55a8c",
  "@metamask-previews/seedless-onboarding-controller": "8.1.0-preview-e0ce55a8c",
  "@metamask-previews/selected-network-controller": "26.0.3-preview-e0ce55a8c",
  "@metamask-previews/shield-controller": "5.0.1-preview-e0ce55a8c",
  "@metamask-previews/signature-controller": "39.0.5-preview-e0ce55a8c",
  "@metamask-previews/storage-service": "1.0.0-preview-e0ce55a8c",
  "@metamask-previews/subscription-controller": "6.0.1-preview-e0ce55a8c",
  "@metamask-previews/transaction-controller": "62.21.0-preview-e0ce55a8c",
  "@metamask-previews/transaction-pay-controller": "16.4.1-preview-e0ce55a8c",
  "@metamask-previews/user-operation-controller": "41.0.3-preview-e0ce55a8c"
}

@matthewwalsh0 matthewwalsh0 force-pushed the feat/relay-polling-improvements branch from e0ce55a to e5d0f42 Compare March 16, 2026 11:11
@matthewwalsh0 matthewwalsh0 enabled auto-merge March 16, 2026 13:59
@matthewwalsh0 matthewwalsh0 added this pull request to the merge queue Mar 17, 2026
Merged via the queue into main with commit d063551 Mar 17, 2026
322 checks passed
@matthewwalsh0 matthewwalsh0 deleted the feat/relay-polling-improvements branch March 17, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants