release: 7.73.2#29233
Merged
Merged
Conversation
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
|
No dependency changes detected. Learn more about Socket for GitHub. 👍 No dependency changes detected in pull request |
- chore(ci): bump xmldom & ignore uuid advisory to address ci audit failure (#29222) <!-- 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? --> uuid version update in progress https://consensyssoftware.atlassian.net/browse/MCWP-557 ## **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: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-556 ## **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 - [ ] 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. [dbdf5b0](dbdf5b0) Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…p-7.72.2 (#29237) - fix(perps): complete spot-balance parity cp-7.72.2 (#29110) <!-- 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** Full fix for **TAT-3016 — [PROD INCIDENT] MetaMask UI shows $0 balance for accounts with spot + perps funds on HyperLiquid**. Builds on Matt's stream fix ([#29089](#29089)) and adds the two missing pieces uncovered during investigation. ### What was broken For HyperLiquid accounts that hold collateral as spot USDC (non-zero `spotClearinghouseState.balances.USDC`) but zero perps clearinghouse balance (`clearinghouseState.withdrawable == 0`, `marginSummary.accountValue == 0`), three independent code paths were under-reporting the balance: | Path | Pre-fix `totalBalance` | Pre-fix `availableBalance` | Why | |---|---|---|---| | Streamed (`HyperLiquidSubscriptionService` webData2 + clearinghouseState callbacks) | `0` | `0` | `adaptAccountStateFromSDK(data.clearinghouseState, undefined)` never fetched/attached `spotClearinghouseState` | | Standalone fetch (`PerpsController.getAccountState({standalone: true})`) | `0` | `0` | Same omission pattern in a separate provider path (`HyperLiquidProvider.ts:5545-5573`) | | Full fetch (`PerpsController.getAccountState()`) | **correct** (`101.13…`) | `0` | Only path that correctly queried both clearinghouse + spot | ### Why it surfaced now Two independent changes in the week leading up to the incident made a long-standing omission visible at scale: 1. **`feat(perps): disk-backed cold-start cache for instant data display` ([#27898](#27898), merged 2026-04-11)** changed `usePerpsLiveAccount` to seed first render from the in-memory stream snapshot (`streamManager.account.getSnapshot()`) before falling back to the preloaded disk cache. The stream snapshot has always been spot-less because `HyperLiquidSubscriptionService.ts:1406` and `:1604` have passed `spotState=undefined` to `adaptAccountStateFromSDK` since December 2025 / February 2026 (git blame). Flipping the trust order from disk cache → live stream exposed the pre-existing zero on first paint. 2. **HyperLiquid Portfolio Margin alpha shipped on the 2026-04-18 network upgrade.** PM pushes more users to hold collateral as spot USDC rather than transferring into perps clearinghouse, expanding the population hitting the spot-only account shape. Neither change is the root cause. The fix is on the MetaMask side: the streamed and standalone account paths must read `spotClearinghouseState` alongside `clearinghouseState` and include spot balance in `totalBalance` for parity with the full-fetch path. ### What this PR does - **Spot-inclusive balance across all three account-state paths.** Streamed, standalone, and full-fetch paths now fold `spotClearinghouseState.balances` into `AccountState.totalBalance` via the shared `addSpotBalanceToAccountState` helper. Only collateral-eligible coins contribute (`SPOT_COLLATERAL_COINS = {USDC, USDH}`) — non-collateral spot assets (HYPE, PURR, …) are excluded so they don't mis-gate the CTA for users who can't actually trade them. - **USDH handled for HIP-3 USDH DEXs.** The codebase already models USDH as auto-collateral (`HyperLiquidProvider.#isUsdhCollateralDex` / `#getSpotUsdhBalance`); including USDH in the allowlist keeps USDH-only HIP-3 users from hitting the same $0 regression. - **`Add Funds` CTA gates on `totalBalance`.** `PerpsMarketDetailsView.showAddFundsCTA` now checks `totalBalance < threshold && defaultPayToken === null`. "User has any money in the perps ecosystem → hide Add Funds." Also fixes the pre-existing edge case where funds locked in an open position incorrectly prompted Add Funds. - **Order-form preselect keeps `availableBalance`.** `useDefaultPayWithTokenWhenNoPerpsBalance` gates on withdrawable so spot-funded / margin-locked accounts still get an external pay token preselected in `PerpsOrderView`. CTA correctness is preserved by the component-level `totalBalance` guard. - **Race-free spot state cache.** `#spotStateGeneration` token + `#spotStatePromiseUserAddress` tracker in `HyperLiquidSubscriptionService`. `#ensureSpotState` only shares in-flight promises when the user matches; `#refreshSpotState` discards result + error if generation was bumped post-await; `cleanUp` / `clearAll` bump generation and null promise refs. Prevents user-A's spot fetch from re-populating the cache after a switch to user B. - **Cold-start SDK init.** `#refreshSpotState` now awaits `ensureSubscriptionClient` before `getInfoClient()` (which throws on fresh instances) so the first `subscribeToAccount` on a cold service gets the spot-adjusted snapshot instead of perps-only until resubscribe. - **`NaN` guard** in `addSpotBalanceToAccountState` keeps `FallbackDataDisplay` sentinels intact when upstream `totalBalance` is non-numeric. ### What this PR deliberately does NOT change - **Order-form slider and order-placement warnings** (`usePerpsOrderForm.ts`, `PerpsOrderView.tsx`) keep reading `availableBalance`. Those surfaces need *immediately-spendable withdrawable*. On standard-margin (non-Unified/non-PM) HyperLiquid accounts, spot USDC is not directly usable as perps margin — users must transfer spot → perps clearinghouse first. Showing a max order size that HyperLiquid would reject at submit would be worse UX than the current behaviour. This is HL's model for standard accounts and outside the scope of the `$0 balance` incident. - **No new fields on `AccountState`**. Considered adding `availableToTradeBalance` (see [#29090](#29090)) or `spotUsdcBalance` (see [#29092](#29092)); both leak HL primitives into the shared protocol-agnostic contract and will need reshaping once Portfolio Margin graduates from [pre-alpha](https://hyperliquid.gitbook.io/hyperliquid-docs/trading/portfolio-margin). Reusing existing `totalBalance` for the CTA gate solves the incident with zero contract changes. - **Portfolio Margin buying-power**. PM pre-alpha uses HYPE-as-collateral with LTV-based borrow (`token_balance * oracle_price * ltv`, LTV 0.5 for HYPE, `borrow_cap(USDC) = 1000` per user). Correct PM buying-power math needs live oracle prices, LTV queries, and account-mode detection — deferred until PM graduates and the API stabilises. The spot USDC/USDH fix here still handles PM users who happen to hold spot collateral. - **Account-mode UI surface** (standard / Unified / PM). Valuable UX signal, but independent of the balance math — tracked as a separate follow-up. The fix on this PR is correct whether or not we surface mode in the UI. - **Core-side companion.** Matt's core PR [#8533](MetaMask/core#8533) covers the stream fix. The standalone-path fix on this PR needs a 1-liner mirror in `@metamask/perps-controller` before mobile syncs that package — flagging as follow-up. ## **Changelog** CHANGELOG entry: Fixed Perps $0 balance display for accounts funded via HyperLiquid spot USDC ## **Related issues** Fixes: [TAT-3016](https://consensyssoftware.atlassian.net/browse/TAT-3016) Supersedes: [#29090](#29090), [#29092](#29092) (both introduce a new `AccountState` field; this PR achieves the same user-visible outcome via `totalBalance` without a contract change) ## **Manual testing steps** ```gherkin Feature: Perps balance visibility for spot-funded accounts Background: Given the user holds spot USDC on HyperLiquid mainnet And the user's HyperLiquid perps clearinghouse balance (withdrawable, marginSummary.accountValue) is 0 And the user is on MetaMask mobile with Perps enabled Scenario: Header reflects spot-backed collateral When user navigates to the Perps tab Then the Perps header shows the spot USDC balance (e.g. $101.14), not $0 And "$0.00 available" is shown as the subtitle (correctly reflecting withdrawable) Scenario: Market detail CTA respects total balance Given user is on the Perps tab with the spot-only account When user opens the BTC market detail view Then the Long and Short action buttons are visible And the "Add Funds" CTA is not shown Scenario: Standalone account-state fetch Given a developer queries Engine.context.PerpsController.getAccountState({ standalone: true, userAddress }) Then totalBalance matches the full-fetch path and includes the spot USDC balance ``` **Agentic recipe**: `evidence/recipe.json` (also in this branch) replays the scenario via CDP and captures the stream / full-fetch / standalone values plus screenshots. Run: ```bash bash scripts/perps/agentic/validate-recipe.sh evidence --no-hud --skip-manual ``` Expected captures (after fix): `{stream,fetch,standalone}_totalBalance = "101.13506928"` for the `0x316BDE155acd07609872a56Bc32CcfB0B13201fA` Trading fixture; CTA state `{addFundsVisible:false, longButtonVisible:true, shortButtonVisible:true}`. ## **Screenshots/Recordings** Recipe: `evidence/recipe.json` on this branch — captures the 3 balance paths, screenshots PerpsHome + PerpsMarketDetails, and probes CTA testIDs on every run. <table> <tr> <th width="50%">Before (pre-fix main)</th> <th width="50%">After (this PR)</th> </tr> <tr> <td> <em>Perps tab header</em><br/> Shows <code>$0</code> — the streamed value (spot-less). PerpsHome renders the <code>PerpsEmptyBalance</code> placeholder instead of Withdraw + Add Funds action buttons. </td> <td> <em>Perps tab header</em><br/> <img src="https://raw.githubusercontent.com/abretonc7s/mm-mobile-farm-artifacts/main/fixes/29110/after-perps-home.png" width="320"/><br/> <code>$101.14</code> balance + "$0.00 available" subtitle + Withdraw / Add Funds row (non-empty funded-state UI) </td> </tr> <tr> <td> <em>PerpsMarketDetails (BTC)</em><br/> Shows "Add Funds" CTA instead of Long / Short buttons. Trade path blocked for spot-only accounts. </td> <td> <em>PerpsMarketDetails (BTC)</em><br/> <img src="https://raw.githubusercontent.com/abretonc7s/mm-mobile-farm-artifacts/main/fixes/29110/after-market-details.png" width="320"/><br/> Long + Short buttons, no "Add Funds" CTA </td> </tr> </table> Visual before-fix screenshot was blocked by intermittent iOS Simulator crashes during this session (unrelated Apple `libsystem_sim_platform` issue). Trace-level evidence from the unfixed code stands: ``` // Streamed (HyperLiquidSubscriptionService #cachedAccount replayed via fresh subscribeToAccount listener) { "availableBalance": "0", "totalBalance": "0", ... } // Standalone fetch: getAccountState({ standalone: true, userAddress: '0x316B...' }) { "availableBalance": "0", "totalBalance": "0", ... } // Full fetch: getAccountState() — the only path that was correct pre-fix { "availableBalance": "0", "totalBalance": "101.13506928", ... } ``` Three paths disagreed on the same account at the same moment. Matt's `[PerpsDiag][ImportedAccount]` Sentry trace from prod confirms the same spot-less streamed payload shape for multiple users hitting TAT-3016. After-fix `trace.json` captures (from `evidence/recipe.json` run on commit `7f0e9def6f`): ``` stream: totalBalance = "101.13506928", availableBalance = "0" fetch: totalBalance = "101.13506928", availableBalance = "0" standalone: totalBalance = "101.13506928", availableBalance = "0" CTA probe: addFundsVisible = false, longButtonVisible = true, shortButtonVisible = true ``` All three balance paths now agree; CTA probe confirms Long + Short visible, Add Funds hidden on the BTC market detail view. ## **Pre-merge author checklist** - [ ] 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 - [ ] 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 - 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. [TAT-3016]: https://consensyssoftware.atlassian.net/browse/TAT-3016?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches core perps balance reporting and adds new async spot-state caching logic, so regressions could impact displayed totals and streaming updates across accounts/DEXs. Changes are localized and covered by targeted unit tests, but still affect user-visible funded-state gating. > > **Overview** > Fixes HyperLiquid *spot-funded* accounts showing a `$0` perps balance by folding eligible spot collateral (USDC only) into `AccountState.totalBalance` across **full fetch, standalone fetch, and WebSocket-streamed** account updates via new `getSpotBalance`/`addSpotBalanceToAccountState` helpers. > > Updates `HyperLiquidSubscriptionService` to fetch/cache `spotClearinghouseState` (with generation-based anti-stale guards) and apply spot-adjusted totals for both multi-DEX aggregation and single-DEX `webData2` updates; `HyperLiquidProvider`’s standalone `getAccountState` path now also fetches spot state and applies the same adjustment. > > Adjusts `PerpsMarketDetailsView` funding CTA logic to key off “has direct order funding path” (spendable balance above threshold *or* pay-with-token preselect available), adds coverage for the “total funded but not spendable/no direct order path” case, and updates a perps market list page-object selector to tap rows by test id instead of text. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 385c39c. 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: geositta <matthew.denton@consensys.net> Co-authored-by: Michal Szorad <michal.szorad@consensys.net> Co-authored-by: Javier Garcia Vera <javier.vera@consensys.net> [3e535e6](3e535e6) [TAT-3016]: https://consensyssoftware.atlassian.net/browse/TAT-3016?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Co-authored-by: geositta <matthew.denton@consensys.net> Co-authored-by: Michal Szorad <michal.szorad@consensys.net> Co-authored-by: Javier Garcia Vera <javier.vera@consensys.net> Co-authored-by: chloeYue <105063779+chloeYue@users.noreply.github.com>
…ort cp-7.73.1 (#29256) - feat(predict): add Polymarket CLOB v2 support cp-7.73.1 (#29076) ## **Description** This PR implements Polymarket CLOB v2 support for MetaMask Predict (7.74 target), introducing a clean coexistence architecture that keeps v1 working while v2 is toggled on via `predictClobV2`. During the temporary CLOB host migration window, a companion rollout flag (`predictClobV2UseLegacyClobHost`) can force v2 traffic onto the legacy host for internal RC testing without turning v2 on for everyone by default. The implementation is designed with deletion in mind — after the v1/v2 coexistence window, v1 can be cleanly removed with minimal surgery. The work follows the "data-first protocol definition" architecture from the internal plan: a private `protocol/` module owns all version-specific differences and is resolved once at the provider entry point. Lower-level helpers never read feature flags directly. **Key design decisions:** - Primary remote flag: `predictClobV2` (default `false`) enables the v2 protocol - Temporary rollout flag: `predictClobV2UseLegacyClobHost` forces v2 to use `https://clob-v2.polymarket.com` during the migration window - Canonical/default v2 host remains `https://clob.polymarket.com` - Host selection is resolved once into `protocol.transport.clobBaseUrl`; lower-level helpers never read raw flags - v2 API key caching is host-aware to avoid reusing credentials across host changes - v2 `getBalance()` always returns `Safe USDC.e + Safe pUSD` — no branching on upgrade state - Trade path is **relayer-only**, **Permit2-only** fee collection on pUSD, always runs preflight before submission - Canonical v2 allowance requirement set defined once; inspector + compiler are small pure modules - Deposit/withdraw use **release-time code choices** for preferred vs fallback variant — not runtime flags - Wrap: always wraps **entire current Safe USDC.e balance** (never `MaxUint256`) when maintenance tx is already being emitted - Unwrap: always unwraps **exact deficit** needed — no over-unwrapping --- ## **Commits** This PR is now structured as 12 focused commits for easier review: ### 1. `feat(predict): add CLOB v2 feature flag plumbing` Wires the `predictClobV2` boolean through the Predict feature-flag infrastructure: - Adds `predictClobV2Enabled` to `PredictFeatureFlags` interface - Adds `selectPredictClobV2EnabledFlag` selector - Extends `resolvePredictFeatureFlags` to resolve the new flag - Refactors `resolveVersionGatedBooleanFlag` helper to reduce duplication across the existing flag resolution logic - Adds selector and resolver tests ### 2. `feat(predict): add CLOB v2 protocol and preflight foundation` Introduces the two new private modules that everything else builds on: **`protocol/`** — data-first protocol definitions: - `definitions.ts`: v1 and v2 `PolymarketProtocolDefinition` objects; protocol resolution; builder code env config (`MM_PREDICT_BUILDER_CODE`); deposit/withdraw execution mode types - `orderCodec.ts`: v2-aware order build, EIP-712 typed data, and relayer payload serialization - `transport.ts`: shared CLOB transport helpers parameterized by protocol endpoint; collapses v1/v2 endpoint differences **`preflight/`** — private readiness inspection and Safe plan construction: - `v2AllowanceRequirements.ts`: canonical declarative list of all 10 v2 allowance requirements (7 ERC-20, 3 ERC-1155) - `inspectMissingRequirements.ts`: reads on-chain state and returns the subset of requirements not yet satisfied - `compileRequirementTransactions.ts`: compiles missing requirements into `SafeTransaction[]` - `core.ts`: shared raw-fact readers, wrap/unwrap builders, and signed Safe execution helpers All modules covered by unit tests. ### 3. `feat(predict): add CLOB v2 buy and sell flow` Implements the full v2 trade path inside `PolymarketProvider`: - `preflight/trade.ts`: `planTradePreflight` + `buildTradeAllowancesTx` — inspects missing v2 allowances and Safe USDC.e balance; compiles optional maintenance tx (allowances-only / wrap-only / allowances+wrap / none) - `PolymarketProvider`: `placeOrder` now resolves the protocol once, runs preflight under v2, builds the optional `allowancesTx`, and uses the protocol's `orderCodec` for order construction, EIP-712 signing, and relayer payload - `utils.ts`: adds `encodeWrapUsdceTransaction` and `encodeUnwrapTransaction` helpers (+ tests) - v2 preview keeps `feeRateBps = '0'` until the upstream fee endpoint is confirmed ### 4. `feat(predict): add CLOB v2 deposit flow` Adds the v2 deposit maintenance planner and wires it into `PolymarketProvider.prepareDeposit`: - `preflight/deposit.ts`: `planDepositMaintenance` + `compileDepositMaintenanceTransactions` — inspects missing v2 allowances and **pre-existing** Safe USDC.e balance (does not incorporate the just-entered deposit amount); emits optional maintenance tx - `PolymarketProvider.prepareDeposit`: under v2, resolves protocol, runs the maintenance planner, and attaches the optional maintenance tx to the deposit plan — the 3-step shape (optional deploy → transfer funding asset → optional maintenance tx) is preserved - Currently wired to the `usdce-transfer` fallback mode; flip `depositMode` in the protocol definition to switch to pUSD-native when that dependency lands ### 5. `feat(predict): add CLOB v2 withdraw flow` Adds the v2 withdraw planner and wires both the `prepareWithdraw` / `signWithdraw` contract: - `preflight/withdraw.ts`: `planWithdraw` — reads missing v2 allowances and Safe USDC.e balance; computes the exact USDC.e deficit; compiles the final MultiSend (allowance repair → exact-deficit unwrap-to-Safe → USDC.e transfer to EOA) - `PolymarketProvider.signWithdraw`: under v2, parses the requested amount from the original template calldata, calls `planWithdraw`, and returns the user-requested amount (not any larger intermediate amount) - `safe/utils.ts`: adds `parseTransactionCalldata` helper to extract the withdraw amount from the stored template - Currently wired to the `usdce-deficit-unwrap` fallback mode; flip `withdrawMode` in the protocol definition to switch to pUSD-native ### 6. `feat(predict): add CLOB v2 claim flow` Adds the v2 claim planner and wires it into `PolymarketProvider.claimWinnings`: - `preflight/claim.ts`: `planClaim` — reads EOA USDC.e directly (not Safe balances or provider `getBalance()`); computes `gasStationDeficit = max(0, MIN_GAS_STATION_USDCE_BALANCE - eoaUsdceBalance)`; proactively wraps the **entire current Safe USDC.e balance**; compiles the MultiSend in the required order: (1) missing allowance/operator repair, (2) wrap-all current Safe USDC.e, (3) claim subcalls, (4) optional exact-deficit unwrap to EOA - `PolymarketProvider.claimWinnings`: under v2, resolves protocol and delegates to `planClaim`; uses protocol-owned claim targets (pUSD as collateral) rather than per-position collateral metadata ### 7. `test(predict): add CLOB v2 integration coverage` Adds integration-level tests and reorganizes the provider test suite: - `preflight/workflows.test.ts`: end-to-end workflow planner tests covering all four preflight paths (trade, deposit, claim, withdraw) with concrete on-chain mock scenarios — verifies MultiSend ordering invariant (approvals first, then wraps/claims/transfers) - `PolymarketProvider.test.ts`: reorganized into `v1` / `v2` describe blocks; covers protocol routing (flag off → v1, flag on → v2), v2 `getBalance()` aggregation, all four trade preflight outcomes (none / allowances-only / wrap-only / allowances+wrap), deposit/withdraw preferred vs fallback shape, and claim ordering ### 8. `fix: preserve EIP-712 field order in buildProtocolUnsignedOrder` Fixes the v2 order-signing codec so the generated typed data preserves the expected field ordering for EIP-712 signing. ### 9. `codex: address PR review feedback (#29076)` Addresses review feedback in the allowance inspector path: - forwards `requirement.tokenAddress` into the ERC-1155 operator approval read instead of relying on a hardcoded contract address - adds assertions proving the token address is propagated correctly through the read path ### 10. `refactor(predict): tighten CLOB v2 preflight workflow seams` Addresses follow-up review feedback without changing behavior: - makes lower-level transaction compilers private where possible - keeps `getClaimRequirements` exported for focused pure testing - tightens `preflight/workflows.test.ts` to assert through planner entry points instead of private helpers - renames claim gas-top-up terminology for clarity (`MIN_GAS_STATION_USDCE_BALANCE_RAW`, `gasStationDeficit`) while keeping `eoaUsdceBalance` unchanged ### 11. `feat(predict): add configurable CLOB v2 host override` Adds temporary host-migration plumbing while keeping canonical host resolution centralized: - introduces canonical and legacy CLOB host constants - resolves the selected host into `protocol.transport.clobBaseUrl` - threads the resolved host through API key creation, order-book reads, and preview flow - isolates API key cache entries by protocol + host + address ### 12. `refactor(predict): gate legacy CLOB v2 host with boolean flag` Simplifies the rollout shape for internal RC testing: - replaces the nested raw `predictClobV2.clobBaseUrl` rollout control with a second version-gated boolean flag: `predictClobV2UseLegacyClobHost` - keeps the lower-level host plumbing from commit 11 intact - allows internal RC builds to enable the legacy host remotely while internal users locally toggle `predictClobV2` --- ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/PRED-817 ## **Manual testing steps** ```gherkin Feature: Polymarket CLOB v2 trading Scenario: user trades with CLOB v2 enabled Given the predictClobV2 remote flag is enabled And the user has an active Polymarket Safe When user places a buy or sell order Then the provider runs preflight and submits any needed allowance/wrap tx first And the order is submitted via the relayer with X-Clob-Version: 2 Scenario: internal RC uses the legacy v2 CLOB host Given the predictClobV2UseLegacyClobHost remote flag is enabled And predictClobV2 is enabled via local override When user places a buy or sell order Then v2 CLOB requests use https://clob-v2.polymarket.com And API keys are cached separately from canonical-host credentials Scenario: user deposits with CLOB v2 enabled Given the predictClobV2 remote flag is enabled When user initiates a deposit Then the deposit plan includes an optional maintenance tx (allowance repair + wrap pre-existing USDC.e) And the newly deposited amount is not included in the wrap Scenario: user withdraws with CLOB v2 enabled Given the predictClobV2 remote flag is enabled And the user requests a specific withdrawal amount When user confirms the withdraw Then only the exact USDC.e deficit is unwrapped (not all pUSD) And the reported amount matches the user-requested amount Scenario: user claims winnings with CLOB v2 enabled Given the predictClobV2 remote flag is enabled And the user has winning positions When user claims Then all missing v2 allowances are repaired first And the entire pre-existing Safe USDC.e is wrapped And claim subcalls execute after And only the exact EOA gas-top-up deficit is unwrapped to USDC.e Scenario: CLOB v2 flag is disabled (v1 behavior) Given the predictClobV2 remote flag is disabled When user interacts with any predict flow Then v1 protocol is used unchanged ``` ## **Screenshots/Recordings** https://www.loom.com/share/155120bd46c44723a8b838172b4fd45b ## **Pre-merge author checklist** - [ ] 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** - [ ] 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] > **High Risk** > High risk because it changes Polymarket trade/claim/deposit/withdraw transaction construction and relayer submission paths, including new Safe preflight logic and EIP-712 signing for a new protocol version. > > **Overview** > Adds **Polymarket CLOB v2** support behind new Predict feature flags (`predictClobV2Enabled` plus optional legacy host override), with host-aware API key caching and endpoint selection. > > Refactors `PolymarketProvider` to resolve a protocol definition once and route **preview + order submission** through a new `protocol/` module (v2 uses new order schema/typed data, zero preview fee rate, and a relayer request header for v2 routing). > > Introduces a `preflight/` layer that inspects on-chain allowance/approval requirements and builds signed Safe executions for **trade allowances**, **deposit maintenance**, **claim**, and **withdraw** (including wrap/unwrap flows and balance aggregation across USDC.e + pUSD for v2). Adds extensive unit/integration tests and updates Safe utilities (raw USDC amount decoding, token-address-aware approvals, Permit2 token selection) plus CI env wiring for `MM_PREDICT_BUILDER_CODE`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5df04d5. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [d9f38f2](d9f38f2) Co-authored-by: Luis Taniça <matallui@gmail.com>
Made-with: Cursor
10 tasks
This comment has been minimized.
This comment has been minimized.
… spotState ws + tradeable-balance + total-balance math cp-7.72.2 (#29270) - fix(perps): HL Unified-mode live balance — spotState ws + tradeable-balance + total-balance math cp-7.72.2 (#29226) ## **Description** TAT-3016 follow-up covering the remaining HL balance gaps after the initial spot-balance parity work. **What's broken on main** 1. `AccountState.totalBalance` is never updated live after a limit order is placed or cancelled — the HL spot clearinghouse state changes but nothing reflects it in our streamed cache. The REST `#refreshSpotState` path only runs on cold-start and standalone fetches, so the cached snapshot goes stale on every on-chain event (local trade, external-client trade, funding, liquidation, deposit, transfer). 2. `AccountState.availableToTradeBalance` doesn't exist — order-entry surfaces read `availableBalance` (= HL `withdrawable`), which is always `$0` on Unified-mode accounts whose collateral is held as spot USDC. Users with tradeable balance see the app refuse to open an order. 3. `totalBalance` on the three account-state paths sums `perps.accountValue + spot.total` without subtracting `spot.hold`. On Unified/PM the held margin is reported in both fields, so pre-fix `totalBalance` inflates by the margin amount whenever a limit order is placed and deflates when cancelled — even though no wealth changed hands. **What this PR does** - Subscribes to HL's `spotState` WebSocket channel alongside the existing `webData2/3` user-data subscription. Handler updates `#cachedSpotState`, bumps `#spotStateGeneration` to invalidate any in-flight REST race, and re-runs `#aggregateAndNotifySubscribers` so UI consumers see spot-folded totals within one network round-trip of the change. REST fallback stays for cold-start and the standalone path. - Adds `AccountState.availableToTradeBalance` as a first-class optional field: `withdrawable + (spot.total − spot.hold)` for HL, `availableBalance` trivial default for other providers. Order-entry surfaces (`PerpsMarketBalanceActions`, `PerpsMarketDetailsView`, `useDefaultPayWithTokenWhenNoPerpsBalance`, `usePerpsOrderForm`) read `availableToTradeBalance ?? availableBalance`. Withdraw path (`PerpsWithdrawView`) keeps reading `availableBalance` unchanged so the withdraw row never leaks the spot fold. - Subtracts `spot.hold` from the `totalBalance` sum in both the single-DEX adapter and the aggregated fold helper. On Standard mode `spot.hold = 0` so the subtraction is a no-op; on Unified/PM it cancels the double-count. Result: `totalBalance` no longer ping-pongs on limit place/cancel, matching HL web. - Exposes `HyperLiquidProvider.getExchangeClient()` as a non-interface escape hatch for agentic validation flows that drive HL mutations directly. - Adds a `perps-withdraw-available-balance-text` testID to anchor the non-regression check that withdraw keeps rendering `availableBalance`. - Adds the latest HL reference docs (`account-abstraction-modes.md`, `portfolio-margin.md`, `margin-tiers.md`, updated `subscriptions.md` + `margining.md`) so the code rationale can cite them. **Follow-ups (not in this PR)** - Rename `availableBalance → withdrawableBalance` (TAT-3047) — pure rename against main, kept separate so OTA cherry-picks don't see symbol drift. - Agentic regression recipe exercising mode-flip + limit-cycle + REST parity — tracked separately. ## **Changelog** CHANGELOG entry: Fixed Perps balance not refreshing after trades, funding, or transfers for HyperLiquid users, and corrected total balance inflation on Unified-mode accounts. ## **Related issues** Fixes: [TAT-3016](https://consensyssoftware.atlassian.net/browse/TAT-3016) Supersedes: #29150, #29217 (both closed). ## **Manual testing steps** ```gherkin Feature: HL spotState live-balance refresh Scenario: Spot-funded Unified account sees live balance Given the Trading fixture (0x316B…01fA) is connected in Unified mode And the Perps screen is open Then AccountState.availableToTradeBalance reflects withdrawable + (spot.total − spot.hold) And PerpsMarketBalanceActions 'Available' row shows the same value And PerpsWithdrawView 'Available Perps balance' row shows $0 (withdrawable only) And PerpsOrderView 'Pay with' row defaults to 'Perps balance' Scenario: Limit order cycle leaves totalBalance stable When the user places a limit order on BTC Then AccountState.availableToTradeBalance drops by the reserved margin And AccountState.totalBalance is unchanged When the user cancels the limit Then AccountState.availableToTradeBalance returns to baseline within 5s And AccountState.totalBalance is still unchanged Scenario: Screenshot parity with HL web Then the total shown in the MetaMask Perps header matches app.hyperliquid.xyz (within $0.20) And the order-form 'Available' value matches HL 'Available to trade' ``` ## **Screenshots/Recordings** ### **Before** <img width="422" height="865" alt="image" src="https://github.com/user-attachments/assets/c83cba7e-c70d-442a-9fd3-db0feb7341a0" /> ### **After** <img width="412" height="881" alt="image" src="https://github.com/user-attachments/assets/fd351457-1233-4105-9388-658c527f144e" /> ## **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. [TAT-3016]: https://consensyssoftware.atlassian.net/browse/TAT-3016?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [756b701](756b701) [TAT-3016]: https://consensyssoftware.atlassian.net/browse/TAT-3016?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Contributor
🚀 RC Builds Ready for Testing
More Info
|
## **Description** Merges `stable` into `release/7.73.2` so [#29233](#29233) (`release/7.73.2` → `stable`) can merge without conflicts after [#29107](#29107) landed on `stable`. Version strings and native build numbers were kept at **7.73.2** / **4637** on the release line (`android/app/build.gradle`, `bitrise.yml`, `ios/MetaMask.xcodeproj/project.pbxproj`). `CHANGELOG.md` includes updates from `stable`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #29233 ## **Manual testing steps** ```gherkin Feature: Release branch merge readiness Scenario: release/7.73.2 reflects stable after merge Given this PR is merged into release/7.73.2 When viewing PR 29233 (release/7.73.2 to stable) Then the branch merges cleanly or shows no merge conflicts ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **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) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: documentation-only update to `CHANGELOG.md` with no functional code changes. > > **Overview** > Updates `CHANGELOG.md` to include release notes for **7.73.0** and **7.73.1** (including a fix for Google/Apple login) and adjusts the compare links so `Unreleased` now starts from `v7.73.1`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit cb70d79. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
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?
-->
This PR updates the change log for 7.73.2
## **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: null
## **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 documentation-only change: updates `CHANGELOG.md` to include
the `7.73.2` release notes and adjusts compare links; no runtime code is
modified.
>
> **Overview**
> Adds a new `7.73.2` section to `CHANGELOG.md` documenting Polymarket
CLOB v2 support and fixes for HyperLiquid Perps balance display/refresh
issues.
>
> Updates the changelog reference links so `[Unreleased]` compares from
`v7.73.2` and adds a `[7.73.2]` compare link.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d55c543. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - base branch is not main or a release branch (base: stable) All E2E tests pre-selected. |
Contributor
|
✅ E2E Fixture Validation — Schema is up to date |
|
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.



🚀 v7.73.2 Testing & Release Quality Process
Hi Team,
As part of our new MetaMask Release Quality Process, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment.
📋 Key Processes
Testing Strategy
Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows.
Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing.
Validate new functionalities and provide feedback to support release monitoring.
GitHub Signoff
Issue Resolution
Cherry-Picking Criteria
🗓️ Timeline and Milestones
✅ Signoff Checklist
Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion:
Team sign-off checklist
This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀
Feel free to reach out if you have questions or need clarification.
Many thanks in advance
Reference