[pull] main from MetaMask:main#734
Merged
Merged
Conversation
…86) (#29754) ## **Description** Empties `ALLOWLISTED_URLS` in `tests/api-mocking/mock-e2e-allowlist.ts` by mocking the last remaining entry — the test-dapp's hardcoded `metamask-fox.svg` URL. After [MMQA-1785](https://consensyssoftware.atlassian.net/browse/MMQA-1785), `ALLOWLISTED_URLS` was down to one URL. This PR drops it to zero by adding a default static-assets mock and deleting the entry. Cosmetic milestone for parent epic [MMQA-1364](https://consensyssoftware.atlassian.net/browse/MMQA-1364) (epic AC: *"`ALLOWLISTED_URLS` is empty"*). **Context — why no runtime change:** - `metamask.github.io` is still in `ALLOWLISTED_HOSTS` (driven separately by [MMQA-1367](https://consensyssoftware.atlassian.net/browse/MMQA-1367)). Hosts are matched first in `MockServerE2E.ts`, so the URL entry was redundant in practice. - The local DappServer serves `node_modules/@metamask/test-dapp/dist/`, which contains a local `metamask-fox.svg`. The HTML references it relatively (`<img src="metamask-fox.svg">`), so normal test-dapp loads never hit GitHub. - The hardcoded `https://metamask.github.io/test-dapp/metamask-fox.svg` only appears inside the test-dapp's `wallet_watchAsset` button (sample token image). Specs that exercise "Add Token" trigger that fetch — the new mock now intercepts it with a minimal SVG response. ## **Changelog** CHANGELOG entry: null ## **Related issues** [MMQA-1786](https://consensyssoftware.atlassian.net/browse/MMQA-1786) Parent epic: [MMQA-1364](https://consensyssoftware.atlassian.net/browse/MMQA-1364) Fixes: ## **Manual testing steps** ```gherkin Feature: Empty ALLOWLISTED_URLS via test-dapp fox SVG mock Scenario: ALLOWLISTED_URLS is empty after this change Given the e2e test infrastructure is running When MockServerE2E starts up Then ALLOWLISTED_URLS in mock-e2e-allowlist.ts contains zero entries Scenario: test-dapp wallet_watchAsset flow uses mocked SVG Given a spec exercises the Add Token button on the test-dapp When the test-dapp performs wallet_watchAsset with the metamask-fox.svg image URL Then the request to https://metamask.github.io/test-dapp/metamask-fox.svg is answered by the static-assets default mock with a minimal SVG And no live request leaks per validateLiveRequests() ``` ## **Screenshots/Recordings** ### **Before** `tests/api-mocking/mock-e2e-allowlist.ts`: ```ts export const ALLOWLISTED_URLS = [ // Temporarily allow existing live requests during migration 'https://metamask.github.io/test-dapp/metamask-fox.svg', ]; ``` ### **After** `tests/api-mocking/mock-e2e-allowlist.ts`: ```ts export const ALLOWLISTED_URLS: string[] = []; ``` `tests/api-mocking/mock-responses/defaults/static-assets.ts` — new GET matcher serving `MINIMAL_SVG`: ```ts { urlEndpoint: /^https:\/\/metamask\.github\.io\/test-dapp\/metamask-fox\.svg$/, responseCode: 200, response: MINIMAL_SVG, }, ``` CI verification will be added once smoke tests complete on this PR. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MMQA-1785]: https://consensyssoftware.atlassian.net/browse/MMQA-1785?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [MMQA-1364]: https://consensyssoftware.atlassian.net/browse/MMQA-1364?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [MMQA-1367]: https://consensyssoftware.atlassian.net/browse/MMQA-1367?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [MMQA-1786]: https://consensyssoftware.atlassian.net/browse/MMQA-1786?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only affects e2e API-mocking configuration by replacing a previously allowlisted live URL with a deterministic mock response. > > **Overview** > Removes the last entry from `ALLOWLISTED_URLS` in e2e mocking so *no full URLs are explicitly allowed* to hit live servers. > > Adds a static-assets default GET mock for `https://metamask.github.io/test-dapp/metamask-fox.svg`, returning `MINIMAL_SVG`, so tests that fetch the test-dapp’s token image are handled entirely by the mock server. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f5bb7bc. 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: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## **Description** Removes all four Tenderly host entries from `ALLOWLISTED_HOSTS` in `tests/api-mocking/mock-e2e-allowlist.ts`. Parent epic [MMQA-1364](https://consensyssoftware.atlassian.net/browse/MMQA-1364). The parent epic carved Tenderly out of scope on the assumption that fork-based tests required live Tenderly virtual networks for contract simulation. Re-investigation showed that assumption no longer holds. **Disposition per host:** | Entry | Disposition | | --- | --- | | `api.tenderly.co` | Delete — zero references in tests/app code | | `rpc.tenderly.co` | Delete — zero references in tests/app code | | `virtual.linea.rpc.tenderly.co` | Delete — already mocked by `cardholder-mocks.ts:247-268` for the only specs that exercise it (`card-home-add-funds.spec.ts`, `card-button.spec.ts`) | | `virtual.mainnet.rpc.tenderly.co` | Default RPC mock added with regex matcher (URL has UUID path); returns `0x0` to standard JSON-RPC methods, mirroring the avax / zksync entries from [MMQA-1785](https://consensyssoftware.atlassian.net/browse/MMQA-1785) | **Bonus cleanup:** `tests/helpers/tenderly/tenderly.js` is deleted. Its only function (`Tenderly.addFunds()` calling `tenderly_setBalance`) was never called from anywhere in the codebase — that helper was the original reason for the Tenderly carve-out, and it's dead code. The Detox blacklist entry `.*rpc.tenderly.co/.*` in `blacklistURLs.json` is also dropped — those URLs are now intercepted by the mock server. After this lands, `ALLOWLISTED_HOSTS` is down to **7** entries (4 local + Polymarket carve-out + `metamask.github.io`). ## **Changelog** CHANGELOG entry: null ## **Related issues** [MMQA-1787](https://consensyssoftware.atlassian.net/browse/MMQA-1787) Parent epic: [MMQA-1364](https://consensyssoftware.atlassian.net/browse/MMQA-1364) Fixes: ## **Manual testing steps** ```gherkin Feature: E2E mock coverage for Tenderly virtual networks Scenario: on-ramp specs that load Tenderly Mainnet no longer leak live requests Given the on-ramp spec onramp-unified-buy.spec.ts is run And it builds a fixture with withNetworkController(CustomNetworks.Tenderly.Mainnet.providerConfig) When the wallet boots and the NetworkController initializes Then requests to virtual.mainnet.rpc.tenderly.co are answered by the default RPC mock And no entry for that host is required in mock-e2e-allowlist.ts Scenario: card specs continue to pass with Tenderly Linea host removed from allowlist Given the card spec card-home-add-funds.spec.ts is run When the wallet wires Tenderly.Linea and the test exercises the card flow Then RPC calls to virtual.linea.rpc.tenderly.co are intercepted by cardholder-mocks.ts And the spec passes without a live request leak Scenario: removed Tenderly helper does not break compilation Given tests/helpers/tenderly/tenderly.js has been deleted When the test suite is type-checked and built Then there are no broken import references ``` ## **Screenshots/Recordings** ### **Before** `tests/api-mocking/mock-e2e-allowlist.ts`: ```ts export const ALLOWLISTED_HOSTS = [ '0.0.0.0', '127.0.0.1', 'localhost', '10.0.2.2', 'api.tenderly.co', 'rpc.tenderly.co', 'virtual.mainnet.rpc.tenderly.co', 'virtual.linea.rpc.tenderly.co', 'gamma-api.polymarket.com', '*.polymarket.com', 'metamask.github.io', ]; ``` `tests/resources/blacklistURLs.json` — Detox dropping the host at the network layer: ``` ".*rpc.tenderly.co/.*" ``` `tests/helpers/tenderly/tenderly.js` — dead helper class with `Tenderly.addFunds()`. ### **After** `tests/api-mocking/mock-e2e-allowlist.ts` — four hosts removed: ```ts export const ALLOWLISTED_HOSTS = [ '0.0.0.0', '127.0.0.1', 'localhost', '10.0.2.2', 'gamma-api.polymarket.com', '*.polymarket.com', 'metamask.github.io', ]; ``` `tests/api-mocking/mock-responses/defaults/rpc-endpoints.ts` — new entry for Tenderly mainnet: ```ts { urlEndpoint: /^https:\/\/virtual\.mainnet\.rpc\.tenderly\.co\/.+$/, responseCode: 200, response: { jsonrpc: '2.0', id: 1, result: '0x0' }, }, ``` `tests/resources/blacklistURLs.json` — Tenderly entry removed. `tests/helpers/tenderly/tenderly.js` — file deleted. CI verification will be added once smoke tests complete on this PR. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MMQA-1364]: https://consensyssoftware.atlassian.net/browse/MMQA-1364?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [MMQA-1785]: https://consensyssoftware.atlassian.net/browse/MMQA-1785?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk test-infrastructure change that tightens E2E network mocking; main risk is unintended interception/mismatch of Tenderly RPC URLs causing E2E failures. > > **Overview** > Removes all Tenderly domains from the E2E `ALLOWLISTED_HOSTS`, reducing live-network carve-outs. > > Adds a default RPC mock for `virtual.mainnet.rpc.tenderly.co` using a regex URL matcher, deletes the unused `tests/helpers/tenderly/tenderly.js` helper, and drops the Detox `.*rpc.tenderly.co/.*` blacklist entry so these requests are handled by the mock server instead. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 485d840. 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: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This change aligns MetaMask Mobile’s Send flow with the extension by surfacing **first-time recipient interaction** and **token contract** warnings before the user continues to confirmation. **Reason:** Users should be explicitly warned when sending to an address they have not interacted with on-chain before, and when the recipient looks like a token contract, so they can double-check the destination. **Solution:** - Added `checkFirstTimeInteraction` in `app/util/transaction-controller/index.ts`, using `getAccountAddressRelationship` from the transaction-controller preview package so semantics match the extension. - Introduced send-flow alert hooks (`useFirstTimeInteractionSendAlert`, `useTokenContractSendAlert`) and an aggregator `useSendAlerts` that orders alerts (token contract first, then first-time interaction). - Refactored `SendAlertModal` to accept multiple `SendAlert` items with prev/next navigation (design-system `ButtonIcon`, no “N of M” counter) and per-step acknowledge labels where needed. - Updated `Recipient` to open the modal when there are unacknowledged alerts, reset acknowledgement when the recipient changes, and block Review / auto-advance while alert checks are pending. - Removed the old `toAddressErrorAllowAcknowledge` path from address validation in favor of the dedicated alert pipeline; token-contract detection moved out of `validateHexAddress` into the alert hook. - Added/updated unit tests and locale strings for the new copy and navigation accessibility labels. <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Added Send flow warnings for first-time recipient interaction ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1016 ## **Manual testing steps** ```gherkin Feature: Send flow first-time recipient Background: Given I am logged into MetaMask Mobile And I am on the Send flow recipient step for an EVM network Scenario: user sees first-time interaction alert for a new recipient Given I have an externally owned recipient address I have never sent to on this network And the recipient is not one of my accounts and is not shown as verified while trust data loads When user enters or selects that recipient and taps Review (or equivalent continue) Then a warning modal should appear about sending to this address for the first time And the modal should show the recipient address in the message When user acknowledges the alert (e.g. Continue / I understand as labeled) Then the flow should proceed toward confirmation as usual ``` ## **Screenshots/Recordings** https://github.com/user-attachments/assets/920408e5-a5b1-484c-9b1d-162bd170a666 <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the Send recipient step gating logic and adds new asynchronous alert checks (token contract lookup and first-time interaction API), which can affect when users can proceed and may introduce edge cases around pending/acknowledgement state. > > **Overview** > Adds a new Send-flow alert pipeline (`useSendAlerts`) that surfaces **token contract** and **first-time recipient interaction** warnings before proceeding to confirmation, backed by a new `checkFirstTimeInteraction` util that calls `getAccountAddressRelationship`. > > Refactors `SendAlertModal` to accept a list of `SendAlert`s with prev/next navigation and per-alert acknowledge labels, and updates `Recipient` to block Review/auto-advance while alert checks are pending and to require acknowledging any unacknowledged alerts. > > Removes the old `toAddressErrorAllowAcknowledge`/token-contract detection from address validation (`validateHexAddress`/`useToAddressValidation`) and updates tests/locales accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 45a6f81. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Update font for token details label.
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: Update font for token details label
## **Related issues**
Fixes: null
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk UI-only typography change that does not affect navigation,
data, or analytics behavior.
>
> **Overview**
> Updates the `SecurityTrustEntryCard` result label styling by switching
from `TextVariant.HeadingMd` with a hard-coded `600` weight to
`TextVariant.BodyMd` with `FontWeight.Medium`, aligning the label’s
typography with the design system.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
827c6b1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…29774) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Update package @metamask/transaction-pay-controller. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1241 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** NA ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I've included tests if applicable - [X] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Upgrades the `@metamask/transaction-pay-controller` and related controller dependencies, which could subtly affect transaction/payment flows even though this PR mostly updates dependency metadata and test fixtures. > > **Overview** > Updates `@metamask/transaction-pay-controller` from `^20.0.0` to `^21.0.0`, pulling in newer versions of several MetaMask controller packages via `yarn.lock`. > > Adjusts test fixtures to match the new dependency behavior: `initial-background-state.json` now seeds `AssetsController.assetsInfo` with `mUSD` token metadata on multiple chains, and E2E RPC mocking adds a default mock for `https://testnet-rpc.monad.xyz/`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c20bef9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Adds Perps Trading campaign outcome support to the Rewards stack,
mirroring the Ondo GM outcome pattern.
After a Perps Trading campaign ends, opted-in participants can query
`GET /perps-trading/:campaignId/outcome/me` to learn whether they won.
This PR wires that endpoint into the mobile app end-to-end:
- **Winners** (have a `winnerVerificationCode` + `pending` status) see a
toast → tap → `PerpsTradingCampaignWinningView` showing their rank,
verification code (copy or email to claim prize)
- **Non-winners once results are final** (`finalized` status, no code)
see a toast → tap → campaigns view
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: rwds-perps-trading-outcome
## **Changes**
| Layer | File | What |
|---|---|---|
| Types | `types.ts` | `CampaignType.PERPS_TRADING`,
`PerpsTradingCampaignParticipantOutcomeDto` |
| Data service | `rewards-data-service.ts` |
`getPerpsTradingCampaignParticipantOutcome()` → `GET
/perps-trading/:campaignId/outcome/me` |
| Controller | `RewardsController.ts` | Method with 10-min in-memory
cache + auth retry |
| Action types / Messenger | multiple | Registered in action union and
allowed actions |
| Hook | `usePerpsTradingCampaignParticipantOutcome.ts` | Fetches
outcome via controller messenger |
| Toast hook | `usePerpsTradingCampaignEndedOutcomeToast.ts` |
`winner_pending` → winning view; `participant_finalized` → campaigns |
| Screen | `PerpsTradingCampaignWinningView.tsx` | Rank + verification
code, copy + mailto |
| Utility | `formatUtils.ts` | `formatOrdinalRank()` (1st/2nd/3rd…) |
| Routes / Navigator | multiple | New route constant, screen registered,
toast hook wired |
| Strings | `en.json` | Toast + winning view copy |
## **Manual testing steps**
```gherkin
Feature: Perps Trading campaign outcome
Scenario: winner sees outcome toast and winning view
Given a Perps Trading campaign that has ended
And the current user is opted in and has a winner row with status "pending" and a verification code
When the user opens the Rewards section
Then a toast appears: "You won! 🏆" with "View details" link
When the user taps "View details"
Then the PerpsTradingCampaignWinningView opens showing their rank and verification code
And the user can copy the code or tap "Open mail" to email perpscampaign@consensys.net
Scenario: non-winner sees finalized toast
Given a Perps Trading campaign that has ended with 20 finalized winners
And the current user is opted in but has no winner row
When the user opens the Rewards section
Then a toast appears: "The results are in" with "View" link
When the user taps "View"
Then the user is navigated to the campaigns view
```
## **Screenshots/Recordings**
### **Before**
No Perps Trading outcome UI.
### **After**
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-05 at 19 33 02"
src="https://github.com/user-attachments/assets/c2d21dda-6db6-4260-b0b3-480cbea38f18"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-05 at 20 50 09"
src="https://github.com/user-attachments/assets/aae8fafb-2bac-4349-83d7-ba00182fa498"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-05 at 20 53 05"
src="https://github.com/user-attachments/assets/425fc361-d51f-4d54-a8e6-39f3b34fe1c3"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-05 at 20 53 10"
src="https://github.com/user-attachments/assets/c96b8fb0-c19d-4b85-a1a4-81af881aa612"
/>
_(to be added — requires a completed Perps Trading campaign with backend
data)_
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Adds new post-campaign outcome UI/UX (toasts, auto-navigation, new
routes/screens) that can affect user navigation and state gating across
Rewards; issues would mainly surface as incorrect redirects or missing
banners/toasts.
>
> **Overview**
> Adds a shared `CampaignWinningView` and wires both Ondo and Perps
campaigns to use it for winner verification-code display (copy + mailto)
with a consistent fallback when no code is available.
>
> Introduces a generic `useCampaignParticipantOutcome` +
`useCampaignOutcomeToast` pattern, then adds Perps Trading support via
`usePerpsTradingCampaignParticipantOutcome` and
`usePerpsTradingCampaignEndedOutcomeToast`, mounting these toasts on
`RewardsDashboard` and `CampaignsView`.
>
> Expands Perps Trading end-of-campaign UX: new
`PerpsTradingCampaignWinningView` route/screen, outcome banners on
details/stats (with one-time session auto-navigation for pending
winners), an ended-campaign stats panel, and tweaks to
completed-campaign stat presentation (hide pending tag; hide
volume/margin once complete). Also consolidates outcome banner locale
keys and generalizes `CampaignOutcomeBanner` usage across campaigns.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
464bd29. 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: sophieqgu <sophieqgu@gmail.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] 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](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: changes are confined to Playwright test
tagging/configuration and documentation, primarily affecting which tests
are selected by `--grep` and CI scripts.
>
> **Overview**
> Introduces **test-type tags** `@Performance` and `@System` (in
`tests/tags.performance.js`) and updates performance specs to include
these tags in `test.describe()` names so Playwright configs can filter
suites via `grep`.
>
> Adds new `package.json` scripts to run **system tests on local Android
emulators and iOS simulators** using
`tests/playwright.system-emulator.config.ts`, and updates MM Connect and
other performance/system specs to be grouped under the new tagging
convention. Documentation in `tests/performance/README.md` is expanded
to explain the new tag types, conventions, and examples.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
28088c1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Seitrace (`https://seitrace.com`), the current Sei Mainnet block explorer, is being decommissioned. This PR swaps every hardcoded reference to `seiscan.io` and adds migration **134** to rewrite existing users' persisted `NetworkController` state on upgrade. Hardcoded URL swaps: - `app/util/networks/customNetworks.tsx` — Sei Mainnet `blockExplorerUrl` - `tests/resources/networks.e2e.js` — e2e resource - `tests/api-mocking/mock-responses/tx-sentinel-networks-map.ts` — mock `explorer` Migration 134 rewrites `engine.backgroundState.NetworkController.networkConfigurationsByChainId['0x531'].blockExplorerUrls` from `seitrace.com` to `seiscan.io` for existing installs. It only touches entries still pointing at `seitrace.com` — a user who customized their Sei block explorer (e.g. to `seistream.app`) is left alone. The migration follows mobile's current pattern (sync arrow function with in-place `state` mutation), and is registered in `app/store/migrations/index.ts`. Cross-repo reference for this family of block-explorer-URL migrations is [`metamask-extension/app/scripts/migrations/197.ts`](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/migrations/197.ts). The `@metamask/controller-utils` bump is deliberately deferred until the sibling PR in `MetaMask/core` releases; this PR stands alone. ## **Changelog** CHANGELOG entry: Fixed Sei Mainnet: replaced deprecated Seitrace explorer with Seiscan (`https://seiscan.io`). Existing installs are migrated via migration 134. ## **Related issues** Fixes: Companion PRs: - [`MetaMask/core#8545`](MetaMask/core#8545) — default `BlockExplorerUrl[SeiMainnet]` - [`MetaMask/metafi-sdk#525`](MetaMask/metafi-sdk#525) — shared SDK `SEI_EXPLORER` - [`MetaMask/metamask-extension#42064`](MetaMask/metamask-extension#42064) — extension migration 207 ## **Manual testing steps** ```gherkin Feature: Sei Mainnet block explorer URL Scenario: fresh install uses Seiscan Given a fresh install of MetaMask Mobile When the user adds the Sei Mainnet network Then the network's block-explorer URL is "https://seiscan.io/" And tapping a Sei transaction's "View on block explorer" opens "https://seiscan.io/tx/<hash>" Scenario: existing user with Seitrace URL is migrated Given a build prior to this change with Sei Mainnet added And the stored "blockExplorerUrls" is ["https://seitrace.com"] When the user upgrades to this build Then migration 134 runs And the stored "blockExplorerUrls" for Sei Mainnet is ["https://seiscan.io"] Scenario: user-customized URL is preserved Given a build prior to this change with Sei Mainnet added And the user has customized "blockExplorerUrls" to ["https://seistream.app"] When the user upgrades to this build Then migration 134 is a no-op for this entry And the stored "blockExplorerUrls" for Sei Mainnet remains ["https://seistream.app"] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new persisted-state migration that mutates `NetworkController` network configs for Sei Mainnet; while narrowly scoped, migrations run on upgrade and can affect existing user state if bugs slip through. > > **Overview** > Updates Sei Mainnet’s default block explorer from **Seitrace** to **Seiscan** across the in-app popular network config and test fixtures. > > Adds migration `134` (registered in `app/store/migrations/index.ts`) to rewrite persisted Sei Mainnet `blockExplorerUrls` entries whose URL hostname is exactly `seitrace.com` to `seiscan.io`, while leaving missing/invalid controller state and user-customized/lookalike URLs untouched; includes unit tests covering the rewrite and no-op cases. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 68e91bc. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
The "Move mUSD" row in the Add money sheet was showing a balance that
did not match the Money Account balance displayed at the top of the
screen. The two figures were sourced from different places, which
surfaced as an obvious mismatch whenever the selected EVM account was
not the same as the Money Account.
Root cause: the sheet was reading from
`useMusdBalance().fiatBalanceAggregatedFormatted`, which aggregates mUSD
across the currently selected EVM account. The screen header, by
contrast, uses `useMoneyAccountBalance`, which is the canonical Money
Account balance.
Fix: switch the sheet to consume
`useMoneyAccountBalance().totalFiatFormatted` so the "Move mUSD" amount
and the header always agree. Tests were updated to mock the new hook and
assert the same fallback behaviour (no-amount copy when the balance is
unavailable, locale fiat prefix preserved).
Credit to Matthew Grainger for diagnosing the source-of-truth mismatch
on the Jira ticket.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes: MUSD-701
## **Manual testing steps**
```gherkin
Feature: Add money sheet balance consistency
Scenario: user opens the Add money sheet with a funded Money Account
Given the user has a non-zero Money Account balance
And the selected EVM account is not the Money Account
When the user opens the Add money sheet
Then the "Move mUSD" row shows the same fiat amount as the Money Account header
Scenario: user opens the Add money sheet with no mUSD
Given the user's Money Account balance is unavailable or zero
When the user opens the Add money sheet
Then the "Move mUSD" row shows the no-amount copy
```
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- [ ] I've tested with a power user scenario
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk UI data-source swap: the “Move mUSD” row now reads from the
canonical Money Account balance, which could only affect displayed copy
if the previous EVM-account-aggregated value differed or was undefined.
>
> **Overview**
> Updates the Add Money bottom sheet so the “Move mUSD” option displays
the **Money Account** fiat balance (via
`useMoneyAccountBalance().totalFiatFormatted`) instead of the previously
EVM-account-aggregated `useMusdBalance()` value, eliminating mismatches
with the header balance.
>
> Adjusts `MoneyAddMoneySheet` tests to mock the new hook and keep the
same behaviors for locale-prefixed amounts and the no-amount fallback
copy.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
88dd0bc. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )