fix: prevent dapp deeplinks opening twice on Android (#29475)#31665
fix: prevent dapp deeplinks opening twice on Android (#29475)#31665joaoloureirop wants to merge 2 commits into
Conversation
On Android, when the app is resumed from the background, a single deeplink click is delivered to JS twice: once via React Native `Linking` (`url` event) and once via the Branch SDK (`branch.subscribe`). With no de-duplication, both deliveries are processed and a dapp link opens two browser tabs. iOS routes external URL opens through Branch only, so it is unaffected. De-duplicate at the earliest shared JS entry point (`handleDeeplink`) by ignoring an identical URI received within a short 3s window, which collapses the back-to-back duplicate delivery without affecting genuine repeat navigations.
|
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. |
PR template — items to address before "Ready for review"Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: The only E2E test file that directly exercises deeplink navigation is The deduplication logic is an early-return guard: if the same URI arrives within 3 seconds, the second call is dropped. This is a behavioral change that could affect any deeplink-triggered flow. The No other Detox E2E smoke test files reference deeplinks or SmokeSwap and SmokeConfirmations are not selected because the deeplink-navigation spec itself is tagged only with SmokeWalletPlatform, and the change is to the deduplication guard rather than the swap/confirmation logic itself. Performance Test Selection: |
Description
When a dapp deeplink is tapped while the MetaMask app is open in the background on Android, the dapp opens twice in the in-app browser (two tabs).
Reason for the change: On Android, a single deeplink click is delivered to the JS layer twice when the app is resumed from the background — once through React Native's
Linking(urlevent) and once through the Branch SDK (branch.subscribe). Both deliveries flow throughhandleDeeplink→checkForDeeplink→ the deeplink saga →handleBrowserUrl→newTab, with no de-duplication anywhere in the chain. Each pass generates a fresh timestamp, so the Browser view opens a new tab for each one. iOS routes external URL opens through Branch only, so it is unaffected (matching the bug report: not reproducible on iOS, and not reproducible when the app is closed/cold-started).Solution: De-duplicate at the earliest shared JS entry point (
handleDeeplink). An identical URI received within a short 3s window is ignored, which collapses the back-to-back duplicate delivery into a single handling without interfering with genuine repeat navigations (the same link can still be re-opened once the window elapses). The change is platform-agnostic and also guards any cold-startgetInitialURL/Branch duplicate delivery.Changelog
CHANGELOG entry: Fixed a bug on Android where opening a dapp deep link while the app was in the background opened the dapp in two browser tabs.
Related issues
Fixes: #29475
Manual testing steps
Screenshots/Recordings
Before
Screen.Recording.2026-06-12.at.20.07.59.mov
After
Screen.Recording.2026-06-12.at.20.10.29.mov
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an examplePre-merge reviewer checklist