Skip to content

release: 7.78.1 (OTA)#30695

Merged
joaoloureirop merged 10 commits into
stablefrom
release/7.78.1-ota
May 29, 2026
Merged

release: 7.78.1 (OTA)#30695
joaoloureirop merged 10 commits into
stablefrom
release/7.78.1-ota

Conversation

@metamaskbotv2

@metamaskbotv2 metamaskbotv2 Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

OTA hotfix: branch release/7.78.1-ota.

  • Native semver and build version are not bumped.
  • OTA_VERSION in app/constants/ota.ts is v7.78.1.
  • CHANGELOG.md header and production git tag both use bare 7.78.1 / v7.78.1; the -ota suffix is branch-only.

@metamaskbotv2 metamaskbotv2 Bot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label May 27, 2026
@github-actions github-actions Bot added pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. size-XS labels May 27, 2026
…' on 'EventTa… (#30701)

…rget': parameter 1 is not of type 'Event' (#30612)

## **Description**

Fix `TypeError: Failed to execute 'dispatchEvent' on 'EventTarget':
parameter 1 is not of type 'Event'` crash caused by the `CloseEvent`
polyfill in `shim.js` using `event-target-shim`'s `Event` class instead
of React Native's own `Event` class. When `@nktkas/rews` (Hyperliquid
SDK WebSocket transport) dispatches a `CloseEvent` on the native
WebSocket, RN's `dispatchEvent` validates `event instanceof RNEvent` —
which failed because `event-target-shim` provides a different `Event`
class.

Replaced `event-target-shim` globals with React Native's own `Event`,
`EventTarget`, `CloseEvent`, and `MessageEvent` classes so all
`instanceof` checks pass consistently.

## **Changelog**

CHANGELOG entry: Fixed a crash caused by CloseEvent dispatch on
WebSocket failing instanceof validation

## **Related issues**

Fixes:
[TAT-3223](https://consensyssoftware.atlassian.net/browse/TAT-3223)

## **Manual testing steps**

```gherkin
Feature: CloseEvent dispatch on native WebSocket

  Scenario: CloseEvent is dispatched on native WebSocket without error
    Given the app is running with Hyperliquid SDK active

    When a WebSocket connection is closed while in CONNECTING state
    Then no TypeError is thrown
    And the CloseEvent is dispatched successfully
```

## **Screenshots/Recordings**

State-only fix: no visual evidence needed. Both ACs proven via CDP eval
(CloseEvent dispatch success) and lint:tsc (no TS errors).

## **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.

## **Validation Recipe**

<details>
<summary>recipe.json</summary>

```json
{
  "pr": "TAT-3223",
  "title": "CloseEvent dispatchEvent on native WebSocket must not throw TypeError",
  "jira": "TAT-3223",
  "acceptance_criteria": [
    "CloseEvent dispatched on native WebSocket must not throw TypeError",
    "No new TypeScript errors introduced by the fix"
  ],
  "validate": {
    "static": ["yarn lint:tsc"],
    "workflow": {
      "pre_conditions": ["wallet.unlocked"],
      "entry": "ac1-eval-closeevent-dispatch",
      "nodes": {
        "ac1-eval-closeevent-dispatch": {
          "action": "eval_sync",
          "expression": "(function() { try { var ws = new WebSocket('wss://echo.websocket.org'); var ce = new CloseEvent('close', {code: 1006, reason: '', wasClean: false}); ws.dispatchEvent(ce); ws.close(); return JSON.stringify({success: true, error: null}); } catch(e) { return JSON.stringify({success: false, error: e.message}); } })()",
          "assert": { "operator": "eq", "field": "success", "value": true },
          "next": "ac1-eval-closeevent-props"
        },
        "ac1-eval-closeevent-props": {
          "action": "eval_sync",
          "expression": "(function() { var ce = new CloseEvent('close', {code: 1006, reason: 'test', wasClean: true}); return JSON.stringify({type: ce.type, code: ce.code, reason: ce.reason, wasClean: ce.wasClean}); })()",
          "assert": {
            "all": [
              { "operator": "eq", "field": "code", "value": 1006 },
              { "operator": "eq", "field": "reason", "value": "test" },
              { "operator": "eq", "field": "wasClean", "value": true }
            ]
          },
          "next": "ac1-eval-messageevent-dispatch"
        },
        "ac1-eval-messageevent-dispatch": {
          "action": "eval_sync",
          "expression": "(function() { try { var ws = new WebSocket('wss://echo.websocket.org'); var me = new MessageEvent('message', {data: 'hello'}); ws.dispatchEvent(me); ws.close(); return JSON.stringify({success: true, error: null}); } catch(e) { return JSON.stringify({success: false, error: e.message}); } })()",
          "assert": { "operator": "eq", "field": "success", "value": true },
          "next": "setup-done"
        },
        "setup-done": {
          "action": "end",
          "status": "pass"
        }
      }
    }
  }
}
```

</details>

## **Recipe Workflow**

<details>
<summary>workflow.mmd</summary>

```mermaid
graph TD
    ac1-eval-closeevent-dispatch["ac1-eval-closeevent-dispatch<br/>eval_sync: CloseEvent dispatch on native WS"]
    ac1-eval-closeevent-props["ac1-eval-closeevent-props<br/>eval_sync: Verify CloseEvent properties"]
    ac1-eval-messageevent-dispatch["ac1-eval-messageevent-dispatch<br/>eval_sync: MessageEvent dispatch on native WS"]
    setup-done["setup-done<br/>end: pass"]

    ac1-eval-closeevent-dispatch --> ac1-eval-closeevent-props
    ac1-eval-closeevent-props --> ac1-eval-messageevent-dispatch
    ac1-eval-messageevent-dispatch --> setup-done
```

</details>


[TAT-3223]:

https://consensyssoftware.atlassian.net/browse/TAT-3223?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches app bootstrap polyfills used by Hyperliquid WebSockets; low
blast radius but wrong globals could break perps connectivity at
runtime.
> 
> **Overview**
> Fixes a **Hyperliquid / perps WebSocket crash** where `dispatchEvent`
rejected `CloseEvent` because polyfilled events did not pass React
Native’s `instanceof Event` check.
> 
> **`shim.js`** stops using **`event-target-shim`** and hand-rolled
`CloseEvent` / `MessageEvent` constructors. When globals are missing, it
assigns React Native’s own **`Event`**, **`EventTarget`**,
**`CloseEvent`**, and **`MessageEvent`** from RN private web API modules
so events dispatched by `@nktkas/rews` match what RN’s WebSocket
`EventTarget` expects.
> 
> **`event-target-shim`** is removed from **`package.json`** / lockfile.
**`shim.test.js`** adds unit coverage for RN `CloseEvent` and
`MessageEvent` properties and inheritance.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5d5cb89. 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?
-->

## **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.


[TAT-3223]:
https://consensyssoftware.atlassian.net/browse/TAT-3223?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[TAT-3223]:
https://consensyssoftware.atlassian.net/browse/TAT-3223?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
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.

@joaoloureirop joaoloureirop marked this pull request as ready for review May 27, 2026 17:46
@github-actions github-actions Bot added size-M and removed size-XS labels May 27, 2026
@metamaskbotv2 metamaskbotv2 Bot requested a review from a team as a code owner May 27, 2026 17:47
joaoloureirop
joaoloureirop previously approved these changes May 27, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 45.15%. Comparing base (5078ae1) to head (265546c).
⚠️ Report is 2503 commits behind head on stable.

Additional details and impacted files
@@             Coverage Diff             @@
##           stable   #30695       +/-   ##
===========================================
- Coverage   81.50%   45.15%   -36.36%     
===========================================
  Files        4621     5437      +816     
  Lines      121060   145059    +23999     
  Branches    26604    33146     +6542     
===========================================
- Hits        98671    65502    -33169     
- Misses      15451    73401    +57950     
+ Partials     6938     6156      -782     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

joaoloureirop
joaoloureirop previously approved these changes May 27, 2026
@sonarqubecloud

Copy link
Copy Markdown

<!--
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**

Add the `[7.78.1]` section to `CHANGELOG.md` for the `v7.78.1` OTA
hotfix.



## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:


<!--
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.

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
joaoloureirop
joaoloureirop previously approved these changes May 29, 2026
@joaoloureirop joaoloureirop removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 82%
click to see 🤖 AI reasoning details

E2E Test Selection:
This is a patch release (v7.78.1) with a targeted crash fix in shim.js. The core change replaces the event-target-shim package with React Native's own internal Event/EventTarget/CloseEvent/MessageEvent classes to fix a crash where CloseEvent dispatch on WebSocket failed instanceof validation. This was specifically caused by the Hyperliquid SDK WebSocket transport used by the Perps feature.

Key changes:

  1. shim.js: Replaced event-target-shim polyfills with RN's own internal event classes (react-native/src/private/webapis/...) - fixes WebSocket CloseEvent instanceof crash
  2. package.json: Removed event-target-shim dependency
  3. shim.test.js: New unit tests for the polyfills
  4. app/constants/ota.ts: Version bump to v7.78.1
  5. CHANGELOG.md: Release notes
  6. .yarnrc.yml: Added npm audit advisory suppressions

The shim.js is a global polyfill loaded at app startup, but the change is conservative and targeted - it uses RN's own classes which are more compatible with RN's internal WebSocket implementation. The primary affected feature is Perps (Hyperliquid SDK WebSocket).

Per tag dependencies: SmokePerps requires SmokeWalletPlatform (Trending section) and SmokeConfirmations (Add Funds deposits are on-chain transactions).

Performance Test Selection:
The changes are a crash fix for WebSocket event handling in the Perps feature. While shim.js is loaded globally, the change replaces one event polyfill with another - there's no meaningful performance impact expected. The fix is about correctness (instanceof compatibility), not performance. No performance tests are warranted.

View GitHub Actions results

@joaoloureirop joaoloureirop merged commit 6c60682 into stable May 29, 2026
442 of 468 checks passed
@joaoloureirop joaoloureirop deleted the release/7.78.1-ota branch May 29, 2026 14:33
@github-actions github-actions Bot locked and limited conversation to collaborators May 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

size-M team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants