Skip to content

Upgrade to React Native 0.86 / Expo SDK 57 (new architecture) - #6064

Merged
peachbits merged 34 commits into
developfrom
phase2-rn-upgrade
Oct 27, 2026
Merged

peachbits merged 34 commits into
developfrom
phase2-rn-upgrade

Conversation

@peachbits

@peachbits peachbits commented Jun 29, 2026 •

Copy link
Copy Markdown
Contributor

iOS blur root cause (found with a physical iPhone X, iOS 16.7): React Native 0.86
removed StyleSheet.absoluteFillObject; spreading the now-undefined value yields an
empty style, so any absolutely positioned layer that spread it collapsed to nothing.
edge-login-ui-rn spread it in six places (its modal blur sheet - the "grey modal" with
the scene sharp behind it - plus EdgeButton, EdgeCard and ChallengeModal backgrounds),
fixed in PR #301 and carried here through the patch. The same collapse hit
@react-navigation/drawer's overlay (side menu no longer dimmed or closed on outside
tap) - fixed via the drawer patch. Two blur libraries failed identically before the
fix, which is how the library was ruled out; iOS now unifies on expo-blur and
rn-id-blurview is dropped. Verified: login-ui and GUI modals blur on simulator and
device; side-menu overlay dims and closes.



Note

High Risk
Full-stack platform upgrade (new architecture, native toolchains, Firebase, and rendering) touches every screen; regressions in blur, navigation overlays, scrolling, and native crashes are plausible despite targeted flag and library mitigations.

Overview
Upgrades the app to React Native 0.86 and Expo SDK 57 with the new architecture enabled on Android and iOS, including Gradle 9 / compileSdk 36, Expo’s unified autolinking, Hermes V1 with React-Core built from source on iOS (min deployment 16.4), and bumped native deps (Firebase 12, Reanimated 4.5, etc.).

Android startup drops ReactNativeHostWrapper and, after new-arch load(), resets React Native feature flags to enable ShadowTree commit-exhaustion protection and keep view recycling disabled so recycled views don’t leave stale dimmed buttons or font sizes. Release lint is turned off to avoid OOM; Gradle JVM heap is increased.

UI stack migrations replace legacy blur/gradient/keyboard libraries with expo-blur, expo-linear-gradient, and react-native-keyboard-controller; rn-id-blurview and react-native-linear-gradient are removed from pods. Babel now always uses react-native-worklets/plugin (no Android-specific Reanimated path).

The CHANGELOG records follow-on fixes for new-arch behavior: side-menu overlay tap-to-close, modal/header blur (solid fallbacks on older Android), keyboard/modal/amount-field/accessibility issues, minimumFontScale via a small RN patch, deduped airship/patina installs, and measured Android scroll performance gains in release benchmarks.

Reviewed by Cursor Bugbot for commit bb41a87. Bugbot is set up for automated code reviews on this repo. Configure here.

@socket-security

socket-security Bot commented Jun 29, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedjest@​30.0.0 ⏵ 29.7.010010068 -191 -1100
Updated@​react-native/​metro-config@​0.79.2 ⏵ 0.86.0100 +11007297 +1100
Updated@​babel/​preset-typescript@​7.27.1 ⏵ 7.29.71001007292100
Updated@​react-native/​typescript-config@​0.79.2 ⏵ 0.86.010010073 +1097 +1100
Updated@​react-native-community/​cli@​18.0.0 ⏵ 20.1.097100 +7575 +194100
Addedexpo-linear-gradient@​57.0.1751008399100
Added@​react-native/​jest-preset@​0.86.0761008297100
Updatedexpo@​53.0.20 ⏵ 57.0.777100100 +23100 +1100
Updatedreact-native-safe-area-context@​5.6.1 ⏵ 5.7.0991007891 +4100
Updated@​types/​react@​19.1.9 ⏵ 19.2.1710010079 -190 -5100
Updated@​babel/​core@​7.28.0 ⏵ 7.29.797100 +179 +197100
Updatededge-login-ui-rn@​3.37.3 ⏵ 4.0.080 +1100100 +197 +1100
Updated@​react-native-firebase/​app@​20.5.0 ⏵ 25.1.010010089 +197 -180
Updated@​react-native-firebase/​messaging@​20.5.0 ⏵ 25.1.010010090 +197 -180
Updatedreact-native-performance@​5.1.4 ⏵ 6.0.0100 +110010081100
Updated@​react-native/​babel-preset@​0.79.5 ⏵ 0.86.098 +110081 +197100
Updated@​react-native-picker/​picker@​2.11.2 ⏵ 2.11.410010010081 -1100
Updatedreact-native-haptic-feedback@​1.14.0 ⏵ 3.0.0100100100 +183100
Addedexpo-blur@​57.0.21001008399100
Updatedreact@​19.0.0 ⏵ 19.2.31001008497100
Updated@​react-native-async-storage/​async-storage@​1.19.4 ⏵ 2.2.010010087 +1685 -6100
Updatedreact-native-worklets@​0.6.1 ⏵ 0.10.099 +110085 +398100
Updatedreact-test-renderer@​19.0.0 ⏵ 19.2.3100 +211008698100
Updatedreact-native-sound@​0.12.0 ⏵ 0.13.010010010086100
Updated@​react-native-community/​netinfo@​11.4.1 ⏵ 12.0.19910010086100
Updatedreact-native-keyboard-controller@​1.19.0 ⏵ 1.22.29910087 +196 +3100
Updatedreact-native-webview@​13.15.0 ⏵ 13.16.11001009588 -7100
Updatedreact-native-bootsplash@​6.3.8 ⏵ 6.3.1288 -1010010090100
Updatedreact-native-svg@​15.14.0 ⏵ 15.15.499 +110010089 +2100
Updatedreact-native-reanimated@​3.19.5 ⏵ 4.5.3100 +110090 +198100
Updatedtypescript@​5.0.4 ⏵ 5.8.3100 +110090 +1100 +590
Updated@​react-native-community/​datetimepicker@​8.4.2 ⏵ 9.1.09910010090 -4100
See 7 more rows in the dashboard

View full report

@socket-security

socket-security Bot commented Jun 29, 2026 •

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Priority Alert  (click "▶" to expand/collapse) Action
Medium priority
Obfuscated code: npm react-native-bootsplash is 75.0% likely obfuscated

Confidence: 0.75

Location: Package overview

From: package-lock.json → npm/react-native-bootsplash@6.3.12

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/react-native-bootsplash@6.3.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

@peachbits

Copy link
Copy Markdown
Contributor Author

History cleanup after a review question: commit 2 ("Upgrade to React Native 0.85.3") previously contained a spurious newArchEnabled true→false flip that commit 3 flipped back — an artifact of how the upgrade commit was reconstructed during the re-split, not a real setting change. Fixed: the flag now changes exactly once, in commit 1 (false→true), and commits 2–5 don't touch it. The Android commit keeps its legitimate jvmargs bump.

Audited the whole series for more of the same (blob-level revert detection across all commits + exact-line added-then-removed scan, lockfile excluded): this was the only instance. Final tree is bit-identical to the previously validated one, and all 5 commits re-passed the per-commit precommit gate (521/521 tests on commit 1's RN 0.79 base; 517/517 on 0.85).

@peachbits
peachbits force-pushed the phase2-rn-upgrade branch from 0a46981 to 30638ca Compare July 3, 2026 19:39
@peachbits

Copy link
Copy Markdown
Contributor Author

🔴→✅ Regression found in review and fixed: the PR was accidentally reverting develop PR #6044 ("Deprecate Botanix to keys-only mode on July 9, 2026") — the keysOnlyMode functions in WalletAndCurrencyConstants.ts, their test, the keys-only wiring in WalletListMenuModal/WalletListModal, and the CHANGELOG entries. Root cause: when this branch was originally rebuilt onto a newer develop base, the upgrade commit carried file-wholesale content from an older tree, stomping develop changes in files both change-sets touched.

Fixed by restoring develop's versions of all 5 files into the upgrade commit — the upgrade legitimately changed zero lines in them, so they now drop out of the PR diff entirely. Verification:

  • keysOnlyMode intact at every commit in the chain
  • Full sweep of every develop change in the base window vs the PR tip: no remaining reverts or divergences (test: add testIDs to wallet options menu for maestro selectors #6060 and the maestro-testID commit were never affected)
  • All 5 commits re-passed the per-commit precommit gate — now 521/521 tests at every commit (the previous 517-vs-521 gap between commits was itself the stomped Botanix test file)

The Botanix July 9 deprecation survives this PR.

@peachbits
peachbits force-pushed the phase2-rn-upgrade branch from 30638ca to 83b07b2 Compare July 7, 2026 18:07
@peachbits

Copy link
Copy Markdown
Contributor Author

🐛 On-device Android testing found (and fixed) a blocking crash — new commit 12195ddb1.

Symptom: release build on a physical device (OnePlus 5T) crashed the moment the password login scene mounted (tap "Sign in" from the welcome carousel).

Root cause: RN 0.85's Android Fabric text measurement throws IllegalArgumentException: FontSize should be a positive value for any Text with font size 0 — TextLayoutManager's letterSpacing.isNaN() check unconditionally invokes a getter that validates fontSize > 0 (the old architecture silently tolerated 0, which is why this never crashed pre-upgrade). FilledTextInput animates its side-icon sizes to exactly 0 (clear icon on an empty input), and those feed AnimatedFontIcon's fontSize — so any scene with a text input crashed on Android, most visibly login via edge-login-ui-rn (same component pattern).

Fix: clamp animated font sizes to ≥1 (visually identical — the icon containers already collapse to zero width) in the GUI's AnimatedFontIcon + FilledTextInput, plus a 1-line patches/edge-login-ui-rn+3.36.0.patch until the fix lands upstream in edge-login-ui-rn. The 9 snapshot updates in the commit are the fix's signature (fontSize: 0 → 1 on at-rest icons — the old snapshots had captured the crash-causing zero).

Verified: rebuilt release APK on the same device — password login scene renders, inputs + eye icon work, zero fatal exceptions. Commit gated: localize/warnings clean, tsc clean, eslint 0 errors, 521/521 tests.

Follow-up: edge-login-ui-rn needs the same clamp in its own repo (src/components/icons/ThemedIcons.tsx) so the patch can be dropped.

@peachbits
peachbits force-pushed the phase2-rn-upgrade branch from 12195dd to 5a23fed Compare July 21, 2026 19:15
@peachbits

Copy link
Copy Markdown
Contributor Author

♻️ Rebased onto current develop (was 67 commits behind and conflicting; now conflict-free). Same 6 commits, same content — mechanical notes:

  • Two conflicts, both in generated/dependency files: package.json (union: develop's react-native-piratechain ^0.6.1 + this branch's react-native-reanimated 4.3.1) and the lockfiles — regenerated, not hand-merged (npm install --package-lock-only for npm; a fresh pod install on the merged tree transplanted into the iOS commit).
  • Post-rebase audits all clean: 0 develop-window stomps (every file develop changed in the 67-commit window verified intact at the tip — includes the piratechain/monero/edge-core/accountbased/exchange-plugins bumps and the maestro testID work), 0 within-series reverts, newArchEnabled flips exactly once (commit 1).
  • Full per-commit precommit gate re-run: 6/6 PASS at 557/557 tests (suite grew with develop; every commit green under its own dependency set).

Also: the edge-login-ui-rn fontSize fix now exists as a proper branch in that repo (matthew/fabric-fontsize-clamp) pending review/PR — once released, the patches/edge-login-ui-rn+3.36.0.patch here can be dropped in favor of a version bump.

@peachbits
peachbits force-pushed the phase2-rn-upgrade branch from 5a23fed to a6c3123 Compare July 21, 2026 20:31
@peachbits peachbits changed the title Upgrade to React Native 0.85.3 / Expo SDK 56 (new architecture) Upgrade to React Native 0.86 / Expo SDK 57 (new architecture) Jul 21, 2026
@peachbits

Copy link
Copy Markdown
Contributor Author

🔁 Retargeted to React Native 0.86.0 / Expo SDK 57 — same 6-commit structure, now a single hop from 0.79.2 to current stable (no intermediate 0.85 in history).

What changed in the retarget:

  • Upgrade commit now pins RN 0.86.0 + Expo ^57.0.7 with the SDK 57 set (reanimated 4.5.0, worklets 0.10.0, gesture-handler ~2.32.0, keyboard-controller 1.21.9). TypeScript deliberately held at ~5.8.3 (SDK 57 suggests TS 6 — a major bump that belongs in its own PR).
  • reanimated 4.5 typing break fixed in EdgeAnim.tsx (ComplexAnimationBuilder went generic; presets' static delay declares the base-builder return — matched their declared signature with one documented cast).
  • Expo 57 factory-delegate change: customize now receives the new-arch UIView (was RCTRootView).
  • Podfile now pins the engine pairing (RCT_HERMES_V1_ENABLED=1, RCT_USE_PREBUILT_RNCORE=0): the 0.86.0 prebuilt React-Core binary is built against the non-V1 jsi ABI (jsi::Runtime vs V1's jsi::IRuntime) and dyld-crashes at launch when paired with the default V1 hermesvm — React-Core from source is the coherent pairing for the V1 engine Edge already ships. Deterministic regardless of shell environment.
  • ShadowTree patch regenerated as patches/react-native+0.86.0.patch (flag still default-off in 0.86; verified present).

Verification: audits clean (0 develop-window stomps, 0 within-series reverts, coherent prebuilt-free lock); per-commit gates 6/6 at 557/557 (JS surface; post-sweep amendments were iOS-native only, covered by builds); Android release APK builds; iOS builds from source and boots to login on the simulator. On-device Android smoke pending device reconnect.

edge-login-ui-rn's clamp branch (matthew/fabric-fontsize-clamp) is unaffected by the retarget.

@peachbits
peachbits force-pushed the phase2-rn-upgrade branch 6 times, most recently from c4e6ae9 to 224c2e7 Compare September 3, 2026 04:51
@peachbits
peachbits force-pushed the phase2-rn-upgrade branch 4 times, most recently from 57ee1e1 to bb41a87 Compare September 14, 2026 20:51
@peachbits
peachbits marked this pull request as ready for review September 17, 2026 17:32

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bb41a87. Configure here.

Comment thread ios/Podfile.lock Resolved
Comment thread src/components/modals/EdgeModal.tsx Resolved
Comment thread src/components/common/EdgeAnim.tsx Resolved
Android ran reanimated 3 via the local `r3-hack` package on the old
architecture while iOS ran reanimated 4 on Fabric. Reanimated 4 requires the
new architecture, so route both platforms through reanimated 4 / worklets and
enable the new architecture on Android:

- babel.config.js: always use react-native-worklets/plugin; add api.cache(true)
  now that the config is static (no platform branch configuring the cache).
- metro.config.js: drop the r3-hack Android resolver.
- react-native.config.js: drop the reanimated sourceDir override and the
  worklets Android disable.
- package.json: remove the r3-hack dependency; delete scripts/r3-hack.
- android/gradle.properties: newArchEnabled=true.
- useCarouselGesture: unify the withSpring config to the reanimated-4 algorithm
  on both platforms (Android previously used the reanimated-3 damping).

Also dedupe yaob to ^0.4.0, fixing the nativeIo collision that crashed
ZEC/Pirate wallet creation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Jenkins iOS agents' Xcode upgrade broke expo-modules-jsi 57.0.3 twice
over. First, `abs(milliseconds)` in JavaScriptCodable+Date.swift became
ambiguous (expo/expo#47957); upstream fixed it in 57.0.5 with
`milliseconds.magnitude`, and the existing ~57.0.3 range already allows it,
so the lockfile pin moves to 57.0.6 along with the matching pod.

Second, the newer Swift rejects SWIFT_RETURNS_RETAINED on the two
RuntimeScheduler constructors because the type is not imported as a shared
reference. Upstream removed both annotations on their SDK 58 line; the
patch mirrors that change exactly and is droppable once a 57.x release
picks it up (57.0.6 is currently the newest).
The Jenkins agent's newer Swift rejects EventEmitter's
`nonisolated(unsafe) weak let` captures being sent into the JavaScript
actor ("sending 'emitter' risks causing data races"). Upstream's SDK 58
line already fixed this by boxing the weak reference in the
NonisolatedUnsafeWeakVar wrapper that 57.0.6 ships but does not yet use
here; this patch mirrors that change exactly. No 57.x release carries it
(57.0.14 is byte-identical in this file), so the patch is droppable when
one does.
`deprecated-react-native-prop-types` exists to shim libraries that import
PropTypes from react-native; RN 0.86 removed those exports entirely and
nothing in the app imports it. `@types/react-native` is stale at 0.71 and
obsolete since react-native ships its own types.

`react-native-email-link` looks equally unused — it appears in no source
file — but it stays: edge-login-ui-rn imports it in PasswordRecoveryActions
while declaring it only as a devDependency, so the app has to supply it.
Removing it breaks the bundle at password recovery. Fourteen other packages
reach us the same way; `react-native-linear-gradient`, `rn-id-blurview`,
`react-native-vector-icons` and `react-native-permissions` are the ones that
matter for any future dependency cleanup.
react-native-linear-gradient has no codegen spec, so every gradient in the
app - cards, buttons, the header, the tab bar, the scene background - was
drawn through Fabric's legacy view-manager interop. expo-linear-gradient is
a real Fabric component and Expo is already a dependency, so this swap
removes a native dependency rather than adding one: edge-login-ui-rn's six
gradient scenes migrate through the regenerated patch, which lets
react-native-linear-gradient leave package.json entirely (verified on
device that removing it beforehand left PinLoginScene throwing "View config
not found for component BVLinearGradient"), and the BVLinearGradient pod
gives way to ExpoLinearGradient.

The props are the same (`colors`, `start`, `end`, `locations`); nothing
uses `useAngle`, the one prop Expo lacks. What differs is the typing: Expo
wants the color and location arrays to be tuples of two or more, since a
gradient with fewer stops has nothing to interpolate. The theme's gradient
fields become `GradientColors` to match, and the six scenes that darken the
first stop of the asset background build a new tuple instead of mutating a
copy.

react-native-gifted-charts also reaches for a gradient, but it tries
react-native-linear-gradient and falls back to expo-linear-gradient, with
both declared optional; the bundle builds and resolves to the Expo one.

expo-linear-gradient is mocked in jestSetup because importing it pulls in
expo-modules-core, which expects native globals the react-native jest
preset doesn't provide. Snapshots move from BVLinearGradient to that mock.
Touching these files takes them off the ESLint warnings list, so their
pre-existing lint errors are fixed here too.
edge-login-ui-rn asked for react-native-airship ^0.2.9 and patina ^0.1.6
while this app asks for ^0.3.0 and ^0.2.0, so npm installed both — nested
copies under edge-login-ui-rn alongside ours. Both packages are UI-layer
singletons: airship owns the portal host every modal mounts into, and
patina caches themed styles. Two module instances of either is the same
class of problem as the duplicate yaob that once cross-wired native IO.

edge-login-ui-rn now asks for the same versions, but npm resolves the
dependency tree from its published manifest, so that alone won't collapse
the duplicates until a release goes out. The overrides make it true today
and stay correct afterwards.

Both are pure JavaScript, so no native rebuild is involved. Verified the
auto-logoff modal still mounts and dismisses through the portal host.
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

peachbits and others added 12 commits October 27, 2026 12:01
react-native-keyboard-aware-scroll-view has had no release since 2022. It
is pure JavaScript, so it never appeared in a codegen audit, but it drives
its scrolling with findNodeHandle, UIManager.measureInWindow and
UIManager.viewIsDescendantOf - the legacy measurement APIs the new
architecture only serves through a compatibility shim. We already depend on
react-native-keyboard-controller, which ships an equivalent component.

`extraScrollHeight` becomes `bottomOffset`, and the `enableOnAndroid` /
`enableAutomaticScroll` opt-ins go away because the replacement always does
both. Everything else is plain ScrollView props. SendScene2 keeps a ref to
scroll to the end, which is now a plain `ref` rather than `innerRef`, and
takes React Native's `scrollToEnd({ animated })` signature instead of the
old library's positional one.

SurveyModal is the one behavior change: it passed an extraScrollHeight of
-16rem on iOS against +9rem on Android, a hack around the old library
measuring the two platforms differently. bottomOffset means the same thing
on both, so both now pass the 2.75rem every other scene uses.

SendScene2 docks its slider above the keyboard, so its offset is worked out
rather than carried over. The hidden PIN input is pinned to the bottom of
the PIN row, and the offset covers the dock, the card's padding and margin
below that row, and the rem(0.5) gap the content keeps above the slider.
Checked with the keyboard up on an iPhone 17 Pro and on an iPhone SE, which
has no home indicator: the whole PIN card clears the slider on both.

edge-login-ui-rn makes the same migration in its three keyboard scenes, so
its patch is regenerated here - and renamed to 3.37.2, the version npm
actually resolves, silencing the version-mismatch warning every install
printed. Verified on Android: the address form scrolls a field near the
bottom clear of the keyboard on focus and accepts input. Touching these
files takes them off the ESLint warnings list, so their pre-existing lint
errors are fixed too.
LoginScene has published `global.ReactNativeBlurView` since 2020, when
edge-login-ui-rn could not add a native dependency without a breaking
release and instead feature-detected a blur component the host snuck to it
at runtime (falling back to a dim underlay without one).

The reading side was deleted from login-ui in September 2023 (v2.15.0),
when its modals started importing rn-id-blurview directly. Nothing in this
app, in the installed login-ui lib, or anywhere else in node_modules reads
the global today, so the assignment has been write-only for almost three
years. The rn-id-blurview import here existed only to feed it.
Under the new architecture the old blur path (rn-id-blurview, Dimezis 2)
snapshots the window with a software canvas that renders empty on every
Android version - the API < 31 grey wash and a silently transparent sheet
on 12+ are the same disease with different symptoms. Modal sheets were
see-through over busy scenes, and the chrome tint had been impersonating
blur all along. Dimezis 3 fixed the snapshot in hardware but changed the
contract: content must be wrapped in an explicit blur target, and
whole-window sampling is gone. expo-blur ships that backend as a
Fabric-native component, so this adds expo-blur (and its pod) rather than
another native dependency.

Two targets cover the two kinds of blur surface, shaped by one hard
constraint: a blur view must never sit inside its own target, or the
renderer recurses computing transforms and overflows the stack (a native
libhwui crash).

- Modals: the app tree gains one BlurTarget wrapping Main, inside the
  Airship layer, so ModalBlurBackground (EdgeModal) and the QR modal
  underlay sample the app content from outside it. login-ui mounts the
  equivalent target in LoginUiProvider for its own modals, delivered
  through the regenerated patch.
- Chrome: the header, scene footer, tab bar, and notification cards
  overlay the scene and live inside the app-level target, so each
  SceneWrapper wraps its content (background dots plus children, excluding
  the absolutely-positioned footer overlay) in its own target and
  publishes the ref through a registry while focused. ChromeBlurBackground
  samples whichever scene is focused, retargeting as navigation changes,
  and falls back to the long-standing tint when no scene publishes one
  (login, scenes outside SceneWrapper). The scene footer needs no special
  casing: with tabs it portals into MenuTabs and without them it is
  absolutely positioned, so it never sits inside what it samples.

Modal backgrounds return to translucent-over-blur on 12+, keeping the
solid color below API 31 where no blur implementation can render. Those
solid colors are theme keys (modalBackgroundNoBlur, chromeBackgroundNoBlur)
rather than literals, so a server themeOverride reaches those devices too. iOS
keeps its existing whole-window blur, unchanged. Verified on device:
the sort modal frosts the wallet list, the security-alerts modal is
opaque and legible, the tab bar softly blurs list content scrolling
beneath it, and no recursion crash across cold start, tab switches, and
stack navigation.

Co-authored-by: Jonathan Tzeng <jnthntzng@gmail.com>
Edge-to-edge draws the window under the status bar, and the Airship layer's
safe-area measurement is iOS-only (it measures through React Native's
SafeAreaView, a no-op on Android), so dropdown notifications - received
transactions, error alerts - slid in underneath the status bar and camera
cutout instead of below them.

Add the top inset to the dropdown's own padding on Android. iOS already
receives it from the Airship layer, so it is excluded there to avoid a
doubled gap. login-ui's error dropdown gets the same fix through the
regenerated patch.
Two fixes in 6.0.0 target exactly this app's setup: new-architecture
detection on React Native 0.77+ and an Android soft exception when the
event emitter is touched before initialization (plus Android listener-leak
fixes). The breaking changes do not reach us - Flipper support removal
(React Native itself dropped Flipper), Flow-to-TypeScript codegen
internals, and renames of old-bridge lifecycle APIs the app never calls.
Our entire usage is the standard performance mark/measure API in perf.ts.
Both upgrades take the module from bridge interop to codegen under the new
architecture. Sound 0.13.0 changes nothing in the API we touch
(setCategory, load, play). Haptic-feedback 3.0.0 keeps the default-export
trigger() call both this app and edge-login-ui-rn use; its breaking changes
are additions (hooks, patterns) and the TurboModule conversion, which is
why jest now needs a mock - the import itself demands a native binding.

login-ui pins ^1.14.0 until its next release, so an npm override keeps the
tree at one copy, the same arrangement airship and patina already use; the
login-ui branch bumps its own range in lockstep.
The disable animation's shared value always started at 0 (enabled), and a
mount effect then animated it toward the actual disabled prop. An input
mounted with disabled=true therefore flashed its enabled look for ~300ms
every time its scene appeared - most visibly the spending-limit amount
field, whose scene mounts it disabled whenever the limit is switched off.
Seed the shared value with the mounted state so the first frame is
already correct; later prop changes still animate as before.

Fix the same pattern in edge-login-ui-rn's copies of these inputs via the
login-ui patch, mirroring an identical commit in that repo.
Regenerate patches/edge-login-ui-rn+3.37.2.patch from the edge-login-ui-rn
branch (PR #301) so the app picks up the fixes mirrored there: EdgeText
truncating instead of shrinking on Android, EdgeModal dropping its bottom
overhang while the keyboard is open (seeded from Keyboard.isVisible), and
the animated font-size clamps in both text inputs.

This lands as one commit rather than fixups to the matching feature
commits because the 3.37.2 patch file postdates them - it was created by
the keyboard-controller commit and evolves forward from there. The patch
disappears entirely once login-ui releases and the dependency bumps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@react-navigation/drawer's Overlay spreads StyleSheet.absoluteFillObject,
which React Native 0.86 removed; spreading the now-undefined value yields
an empty style, so the side menu's dimming overlay had no geometry on both
platforms - the scene stayed undimmed and tapping outside the menu no
longer closed it. Spread absoluteFill instead, in both drawer
implementations, via the existing drawer patch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerate the login-ui patch from the edge-login-ui-rn branch (PR #301),
renaming it to +3.37.3 to match the version develop installs: the
absolute-fill literal that restores the modal blur sheet and the
EdgeButton, EdgeCard and ChallengeModal backgrounds on React Native 0.86,
the expo-blur backend on iOS, the removal of the dead common/BlurBackground
module, and the modalBackgroundNoBlur theme key that the app theme now
fills in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Android 12+ already blurs through expo-blur. Use it for every iOS blur
surface as well - modals, header, tab bar, scene footer, notification cards
and the QR underlay - and drop rn-id-blurview: an old-architecture
RCTViewManager with no codegen spec, so it only reaches the new architecture
through the legacy interop layer, and the same class of library that could
not render at all on Android. Removes the pod and the module declaration;
snapshots follow the component rename.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@j0ntz
j0ntz force-pushed the phase2-rn-upgrade branch from abeec0b to 0309ec9 Compare October 27, 2026 19:14
@j0ntz
j0ntz enabled auto-merge October 27, 2026 19:15
@j0ntz
j0ntz disabled auto-merge October 27, 2026 19:31
4.0.0 is the release of edge-login-ui-rn #301, the library half of this
upgrade, so patches/edge-login-ui-rn+3.37.3.patch goes away. The published
lib/ is byte-identical to what that patch produced on top of 3.37.3, and
the native code and podspec match 3.37.3, so nothing changes at runtime.
The pod only moves its version.

The release no longer depends on react-native-keyboard-aware-scroll-view,
so that package and react-native-iphone-x-helper leave the install. The
airship, patina and haptic-feedback overrides stay: 4.0.0 asks for the
same versions, so they no longer change the tree but still guard it.

Verified: tsc, eslint and jest (141 suites) pass, the 14 remaining patches
apply, and on an iOS 26.5 simulator the app logs in and shows login-ui's
notification-permission modal over a working blur.
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@peachbits

Copy link
Copy Markdown
Contributor Author

@j0ntz heads-up: I force-pushed phase2-rn-upgrade over your rebase (0309ec9 → eca4eaf). Nothing of yours is lost:

  • Your rebase onto develop e39bc7314 matched ours commit for commit. From it I took the CHANGELOG layout (ours had parked develop's unreleased entries under a stale 4.52.0 (staging) heading), one blank line in eslint.config.mjs, and develop's COCOAPODS: 1.16.2 line, each folded into the matching commit.
  • This version also fixes the three things Travis failed on in your push: the unnecessary assertion in paybisRampPlugin.test.ts (lint), and the TS 5.8 props error in SendScene2.recipientNetwork.ui.test.tsx plus the KeyboardAwareScrollView comparison in SendScene2.ui.test.tsx (tsc). jestSetup.js mocks KeyboardAwareScrollView as a real ScrollView, so develop's new test runs unchanged.
  • Your four fixups from this morning are in. 23e4c1425 (no-blur theme keys) is squashed into "Blur modals and chrome again on Android 12+" with you as Co-authored-by. The EdgeAnim cast, the orphaned BlurBackground comment and the webview patch rename were already in the series; the webview patch also keeps develop's newer Android isTopFrame hunks. The "Fixed in" SHAs in your replies now resolve only through the force-push history.

New since your review:

  • edge-login-ui-rn 4.0.0 (New-architecture fixes and dependency modernization edge-login-ui-rn#301, released today) replaces the login-ui patch in a new last commit. Its lib/ is byte-identical to what the patch produced.
  • SendScene2: with the keyboard up, the PIN row now clears the docked slider on phones without a home indicator (it overlapped by 7pt on an iPhone SE). Folded into "Scroll around the keyboard with keyboard-controller".

Your rebase is still reachable at 0309ec9 if you want to compare.

@peachbits
peachbits enabled auto-merge October 27, 2026 20:34
@peachbits
peachbits merged commit 10d3df7 into develop Oct 27, 2026
5 checks passed
@peachbits
peachbits deleted the phase2-rn-upgrade branch October 27, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants