Repository navigation
Conversation
…apps react-native-webview sent any link that isn't http(s) to the OS itself, before Discover's navigation handler saw it, wherever it loaded, so a frame embedded in a page could open a pairing link or another app without the user doing anything. Discover now asks the WebView for every URL and decides itself: pages and about:blank load; a link to another app loaded into the page itself still goes to the OS, so pairing from Discover is unchanged; the same link loaded into a frame inside the page is blocked. A background tab loads pages only. Android doesn't say which frame a URL loads into, so there every navigation counts as the page's own, as before. A link that can't be opened is logged with its scheme only, since it can carry a pairing URI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-986879272efa54463db5 |
Contributor
|
Android Emulator preview APK is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-893a02cd23a8c17dfeb7 |
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
TL;DR
Stacked on #1064. In Discover, a frame embedded in a page can no longer open a link to another app on its own, our own pairing links included. A link that loads into the page itself still opens, as before.
react-native-webview sends any link that isn't http(s) straight to the OS, before our navigation handler sees it, wherever it loads. So a frame inside a page could open a pairing link or another app without the user doing anything. Discover now asks the WebView about every URL and decides itself:
about:blankfor empty frames, load as before.Limits:
target="_top", which the user has to tap, therefore counts as the page's own. On the iPhone SE simulator, such a link and a frame'swindow.openopened nothing either before or after this change. That check is inconclusive, though: by then even a plain page link wasn't pairing on that simulator (see the verification notes).isForMainFrame()and sends noisTopFrame, so on Android every navigation still counts as the page's own. On the emulator, a frame's pairing link still starts pairing, as before. Closing that needs a small native patch to react-native-webview, or an upstream change, so that the event carriesrequest.isForMainFrame(). That's left out of this PR.Lines changed
Only this PR's own changes, not those of the PRs it's stacked on.
Screenshots (iPhone SE simulator on iOS 27.2, Pixel 10 Pro emulator)
A local test page, opened in Discover, carries a real pairing link from a local WalletConnect test client. One button points an embedded frame at the link, another is the link itself, and a third runs five
alert()calls.Implementation details (for agents)
What changed:
src/helpers/browser.ts:getDiscoverNavigationAction({ url, isTopFrame, pairingLink })returnsload,openOutsideorblock.openLinkOutsideDiscover(url)does what react-native-webview did:Linking.canOpenURL, thenLinking.openURL. A failure is logged with the link's scheme only, since React Native's error message repeats the whole link.src/components/screens/DiscoveryScreen/components/WebViewContainer.tsx:originWhitelist={["*"]}, so every URL reachesonShouldStartLoadWithRequest. A background tab's handler allowsloadonly.src/components/screens/DiscoveryScreen/DiscoveryScreen.tsx: the handler asks the helper and opensopenOutsidelinks throughopenLinkOutsideDiscover. A frame's blocked link is logged with its scheme only.freighter-mobile/src/helpers/browser.ts
Lines 32 to 99 in 76df6af
freighter-mobile/src/components/screens/DiscoveryScreen/DiscoveryScreen.tsx
Lines 240 to 269 in 76df6af
Verification:
yarn test: 356 suites pass, 5,327 tests pass and 6 are skipped. New tests cover:about:blankload in the page or a frame; code-running schemes and a page URL carrying the pairing link are blocked; other schemes go to the OS when they load into the page itself (or when the platform doesn't say), and are blocked in a frame;yarn lint:tspasses, and ESLint and Prettier pass on every changed file.window.openandtarget="_blank"link, and a cross-origin frame'swindow.openandtarget="_top"link, with and without this change. None opened anything, but by then a plain page link, which paired in the first run, didn't pair either. Outside deep links kept pairing, and the same happened without this PR's code. So the cause on that simulator is still open.alert()orconfirm()covers the whole app until it's dismissed, so the tab bar can't be reached. Discover keeps its tabs across launches, so a page that loops alerts without end needs a force-quit and comes back on the next visit to Discover. Not changed here.🤖 Generated with Claude Code