Thanks to visit codestin.com
Credit goes to github.com

Skip to content

FIX: patch react-native-tcp-socket onConnect crash; stabilize iOS e2e#8576

Merged
Overtorment merged 1 commit into
masterfrom
e2e-stability-ios
May 21, 2026
Merged

FIX: patch react-native-tcp-socket onConnect crash; stabilize iOS e2e#8576
Overtorment merged 1 commit into
masterfrom
e2e-stability-ios

Conversation

@limpbrains

@limpbrains limpbrains commented May 20, 2026

Copy link
Copy Markdown
Collaborator

Stabilizes the iOS Detox e2e suite and fixes a real app crash surfaced by it. Verified against debug and release builds (full suite passes 10× in a row).

App crash fix — react-native-tcp-socket

TcpSockets.m onConnect: builds an NSDictionary literal from [socket localHost] / [socket connectedHost]. The socket can disconnect between the connect callback being queued on the (main) delegate queue and that callback running, in which case those getters read closed file descriptors and return nil. A dictionary literal with a nil value throws an uncaught NSInvalidArgumentException and aborts the whole app (SIGABRT).

NSInvalidArgumentException — attempt to insert nil object from objects[0]
  -[TcpSockets onConnect:]  ->  -[TcpSocketClient socketDidSecure:]
→ Signal 6 (abort)

It is intermittent in production (reported via Crashlytics on the library's tracker) and hit a random e2e test on nearly every full release-build suite run.

Fix: when the addresses are nil, emit an error event for the client instead of the connect event — the connection genuinely failed, so the JS side should fail fast and retry rather than crash or hang. Shipped as patches/react-native-tcp-socket+6.4.1.patch (patch-package, already wired into postinstall).

Upstream: Rapsssito/react-native-tcp-socket#197

e2e test stabilization

  • helperz.jssetCustomFeeRate: type the fee with a trailing newline (typeText(value + '\n')) so onSubmitEditing closes the fee sheet uniformly. Replaces a brittle, platform-branched "tap the keyboard Done accessory" workaround (the iOS numeric keypad has no Return key).
  • helperz.jshelperImportWallet: wait for SpeedMnemonicInput after the backdoor taps; the ImportSpeed screen is lazy-loaded and wasn't mounted yet on cold start.
  • bluewallet.spec.js — wait for AddressInput before interacting with the send screen; it is lazy-loaded and the assertions raced its mount.

Docs

  • patches/README.md — documents both local patches (this one + the existing react-native-notifications New-Architecture fix) with upstream issue links.
  • CLAUDE.md — notes the patches/ convention.

@GladosBlueWallet GladosBlueWallet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The blur path now disagrees with the submit path. >= 0 became > 0, so a zero fee gets accepted in one branch and marooned in the other. A lovely little split-brain bug for the iOS Done flow.

Comment thread screen/SelectFeeScreen.tsx Outdated
@limpbrains limpbrains force-pushed the e2e-stability-ios branch 2 times, most recently from 8a6c7bc to e0a4543 Compare May 21, 2026 08:41
@limpbrains limpbrains changed the title TST: stabilize iOS e2e — fee modal blur, lazy-mount waits FIX: patch react-native-tcp-socket onConnect crash; stabilize iOS e2e May 21, 2026
@limpbrains limpbrains force-pushed the e2e-stability-ios branch from e0a4543 to 881a06a Compare May 21, 2026 08:44
@GladosBlueWallet

Copy link
Copy Markdown
Collaborator

Wake the fuck up samurai, we have PRs to merge

image

[all PRs for @GladosBlueWallet] https://github.com/BlueWallet/BlueWallet/pulls/review-requested/GladosBlueWallet

@limpbrains limpbrains requested a review from Overtorment May 21, 2026 12:07
@limpbrains limpbrains marked this pull request as ready for review May 21, 2026 12:07

@Overtorment Overtorment left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm. YOLO

@GladosBlueWallet GladosBlueWallet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One regression risk in the e2e helper: submitting the custom fee by typing newline is less deterministic than the previous explicit return-key action. Detox/backends can treat that newline differently, so this can become flaky on one platform while appearing fine on another.

Comment thread tests/e2e/helperz.js
await waitForId('feeCustom');
await element(by.id('feeCustom')).replaceText(String(feeRate));
await element(by.id('feeCustom')).tapReturnKey();
await element(by.id('feeCustom')).typeText(String(feeRate) + '\n');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Using typeText(String(feeRate) + "\n") to submit the field is brittle. The previous tapReturnKey path was explicit about committing the value and closing the keyboard; here the newline may be interpreted inconsistently by Detox on iOS/Android. If the intent is just to submit the fee, keep the text entry and return-key action separate.

@Overtorment Overtorment merged commit a5a7d34 into master May 21, 2026
16 checks passed
@Overtorment Overtorment deleted the e2e-stability-ios branch May 21, 2026 15:33
TaprootFreak pushed a commit to DFXswiss/btc-wallet that referenced this pull request Jul 9, 2026
… guards, Electrum connect resilience (#200)

* fix(ios): patch react-native-tcp-socket onConnect nil-address crash

GCDAsyncSocket's localHost/connectedHost return nil once a socket has
disconnected. If the connection drops between the TLS handshake
completing and the connect event being built, onConnect: inserts nil
into the event dictionary, throwing an uncaught
NSInvalidArgumentException on the module queue and aborting the app.
This is the top field crash on 2.0.x (Electrum connections during
import/discovery are the main trigger).

Ports BlueWallet's patch-package fix 1:1 (BlueWallet#8576)
against the same pinned 6.4.1; upstream library bug is still open
(Rapsssito/react-native-tcp-socket#197). The guard emits an error
event instead of skipping silently so the JS side doesn't hang.

* fix: crash focusing amount input via stale ref access

The component mixed two ref styles: a createRef object and a callback
ref that replaced it with the raw node on mount. Depending on timing,
one of the two focus paths always dereferenced the wrong shape
(.current on a raw node, or .focus() on an unmounted ref) and threw,
which is a fatal crash in release builds.

Uses the createRef object consistently and focuses via .current?.
Same defect class as BlueWallet#7572; equivalent fix
adapted to this component's older class-based shape.

* fix: guard multisig xpub lookup and address-list derivation

An undefined or unregistered cosigner entry reached
isXprvString(undefined) inside address derivation, throwing a cryptic
TypeError; on the addresses screen a single failing derivation killed
the whole list.

Throw a clear error from _getXpubFromCosigner and derive each address
in the list behind try/catch so one bad entry degrades gracefully.
Equivalent of BlueWallet#7893 adapted to this fork's
value-based cosigner lookup.

* fix: keep Electrum connect alive when app-group preferences fail

DefaultPreference.setName was the one call in _initConnection outside
the try/catch that guards the other preference writes. If the app
group is unavailable it rejects, the connection attempt dies before
reaching the Electrum client, and fire-and-forget callers (settings
screen, internal retry loop) surface it as an unhandled rejection.

Scoped equivalent of BlueWallet#7594 for this fork's older
BlueElectrum.js. Their BlueWallet#8597 (optional confirmations on mempool txs)
needs no port: this code base already normalizes confirmations at
ingestion and null-checks the comparisons.

* fix: reset pending-payment state when switching wallets on receive screen

The receive screen's pending-payment watcher (showPendingBalance /
showConfirmedBalance / initial balance baselines / eta / poll cadence)
was left untouched by the wallet selector, and the view flags render
stacked rather than exclusively. After a payment arrived and the user
switched to another onchain wallet, the new wallet's address rendered
together with the previous wallet's pending widget; the stale baselines
could also make the poller misreport a received amount for the new
wallet, and the stale bip21 string kept the poller checking the old
address during the switch.

Reset the whole watcher state machine in onWalletChange. The wallet
selector on this screen is fork-specific, so there is no upstream
BlueWallet fix to port.

* fix: release camera when leaving the multisig cosigner-scan screen

The cosigner scanner on add-multisig step 2 rendered its Camera
unconditionally. After Create navigates to the wallet, the screen stays
mounted in the stack underneath, so the camera session stayed open
(camera-in-use indicator) and onReadCode kept firing — scanning any QR
from an unrelated screen popped the not-a-cosigner validation alert.

Gate the Camera on useIsFocused, the same pattern every other scanner
screen in the repo already uses (ScanQRCode, ScanCodeSend,
importMultisignature).

* fix: remove LayoutAnimation, deprecated and unreliable on the new architecture

LayoutAnimation.configureNext arms a GLOBAL animation for whatever
layout commit happens next. Several call sites here fire at
network-dependent moments (send-screen fee fetch, exchange-rate
refresh), so the armed animation can collide with unrelated commits —
on Fabric this intermittently leaves views with a layout frame but no
drawing. Prime suspect for the field report of the send screen's
amount/recipient inputs rendering as blank space while the rest of the
screen stays intact (width, scroll-offset and empty-data explanations
were each ruled out by on-device injection tests).

Ports BlueWallet#8541, which removed every LayoutAnimation
call after their RN 83 upgrade for the same reason. Only cosmetic
easing on unit switches and fee/discovery loads is lost.

* fix: clear amount and label inputs when switching wallets on receive screen

The watcher-state reset left the custom amount and label fields
populated, so after a wallet switch the form showed the previous
wallet's values while the QR encoded the plain new address. Clear the
label and reset the amount via the hook's existing resetInput, as the
boltcard and cashier screens already do.
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.

3 participants