Repository navigation
fix: open Keyring from the same device with its keyring:// scheme - #120
Merged
Merged
Conversation
On a phone, "Open in Keyring" navigated to the VTI trigger link as is, an https URL on link.trustoverip.org. That host has no public DNS yet, and Keyring does not claim it as a Universal Link or App Link, so the browser showed ERR_NAME_NOT_RESOLVED instead of launching the app. Keyring registers its own `keyring` URL scheme on iOS (CFBundleURLSchemes) and Android (a BROWSABLE intent filter), and its trigger-link reader accepts that scheme as an alias for https, routing an accepted vta-claim flow to the agent setup screen. Rewriting the prefix is enough; the host and fragment must stay verbatim. - src/lib/utils.ts: add keyringSameDeviceLink, which swaps a leading https:// for keyring:// and leaves any other link unchanged. - src/pages/portal/ConnectionMethodUi.tsx: use that link for both "Open in Keyring" buttons and for the anchor around the QR image, which also led to the dead page when tapped on a phone. The QR code still encodes the https:// link: Keyring's scanner reads both forms, but a phone camera cannot open a custom scheme. No Android intent:// wrapper is added, since Keyring has no https intent filter for this host and the fragment handling of that form is unverified. Signed-off-by: Geoff Turk <geoff@ic3.dev>
vthwang
approved these changes
Oct 24, 2026
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.
Problem
On a phone, tapping Open in Keyring navigated to the VTI trigger link as is, an
https://link.trustoverip.org/t#…URL. That host has no public DNS yet, and Keyring does not claim it as a Universal Link or App Link (its associated domains and autoVerify intent filters only coverwallet.asml.berkmancenter.organdwitness.asml.berkmancenter.org), so the browser showedERR_NAME_NOT_RESOLVEDinstead of launching the app.Fix
Keyring registers its own
keyringURL scheme on iOS (CFBundleURLSchemesinkeyring-wallet/app/ios/AriesBifold/Info.plist) and Android (aBROWSABLEintent filter inAndroidManifest.xml). Its trigger-link reader (triggerLink.tsandvtiLinks.tsinkeyring-bifold) acceptskeyringas an alias scheme forhttps, resolves_typeagainsthttps://and the link's own host, and routes an acceptedvta-claimflow to the agent setup screen. Rewriting the prefix is enough; the host and fragment must stay verbatim.src/lib/utils.ts: addkeyringSameDeviceLink, which swaps a leadinghttps://forkeyring://and returns any other link unchanged.src/pages/portal/ConnectionMethodUi.tsx: use that link for both Open in Keyring buttons and for the anchor around the QR image, which also led to the dead page when tapped on a phone.The QR code still encodes the unmodified
https://link. Keyring's scanner reads both forms, but a phone camera cannot open a custom scheme.Not included
intent://wrapper with a Play Store fallback. Keyring has nohttpsintent filter for this host, so it would needscheme=keyring, and how Chrome passes the fragment through that form is unverified. The plainkeyring://link is handled by Chrome and Brave through the existingBROWSABLEfilter.Testing
Type check and ESLint pass (run in a
node:24-alpinecontainer). Manual test on a phone: open the portal in Brave or Safari and tap Open in Keyring. iOS should prompt "Open in Keyring?" and land on the agent setup screen. Typing thekeyring://link into the address bar is not a valid test, since Brave and Chrome treat an unknown scheme as a search query; only a page navigation is handed to the OS. If the installed TestFlight build predatesvta-claimsupport inkeyring-bifold(the wallet pins commite2677d4from 2026-10-23), Keyring opens but reports that the code needs a newer app version.