feat(mobile): react-native-passkey + expo-dev-client + EAS build config - #514
Conversation
|
@collinsezedike is attempting to deploy a commit to the miracle656's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@collinsezedike Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Miracle656
left a comment
There was a problem hiding this comment.
This is the right foundational piece and I want it in — expo-dev-client plus an EAS config is exactly what unblocks passkeys, since react-native-passkey can't run in Expo Go at all. The development / device build profile split is sensible, and pinning appVersionSource: local avoids the remote-versioning surprise.
Two blockers, and the first one is genuinely my call to make, not yours.
🚨 1. Bundle identifier and domain collide with #508
You declare:
"bundleIdentifier": "app.veil.mobile",
"package": "app.veil.mobile",
"associatedDomains": ["webcredentials:veil.app", "webcredentials:veil.app?mode=developer"]#508 (deep-linking config, open right now) declares a different identity for the same app:
BUNDLE_IDENTIFIER = 'xyz.veil.wallet'
ASSOCIATED_DOMAINS = ['app.veil.xyz']
and hardcodes that into the association files it serves from the web app:
// frontend/wallet/public/.well-known/apple-app-site-association
"appIDs": ["APPLE_TEAM_ID.xyz.veil.wallet"]
// frontend/wallet/public/.well-known/assetlinks.json
"package_name": "xyz.veil.wallet"#510's Maestro flows also target appId: xyz.veil.wallet.
These cannot both be right, and this matters more than a normal merge conflict: a bundle identifier is permanent once the app is published to the App Store or Play Store. It also has to match the webcredentials: domain for passkey assertions to verify, and the .well-known files have to be served from that same domain.
Hold off on changing anything here until I confirm the canonical values. I'm deciding between the two and will comment with the answer — I don't want you renaming twice.
2. app.json is being removed by #508
You're editing frontend/mobile/app.json, but #508 deletes it (0+/42-) and replaces it with app.config.ts, so your changes would be dropped on merge.
I'm keeping the app.config.ts migration — the argument in #508 is sound: the deep-link surface has to agree with the resolver that parses links at runtime, and static JSON can't express or document that relationship. Once the identifier question above is settled, please move your additions (bundleIdentifier / package, associatedDomains, the expo-dev-client plugin registration, icon) into app.config.ts instead.
Note that #508's config already sets bundleIdentifier and associatedDomains — but for applinks (universal links), whereas you need webcredentials (passkey RP). Those are different entries and the app needs both:
associatedDomains: [
...ASSOCIATED_DOMAINS.map((d) => `applinks:${d}`),
...ASSOCIATED_DOMAINS.map((d) => `webcredentials:${d}`),
],That's worth coordinating with @Olorunfemi20 directly on #508 rather than resolving it as a conflict afterwards.
Note on #512
Your #512 (swap execute screen) independently adds react-native-passkey ^3.0.0 to package.json. Once this PR lands that becomes a duplicate entry — worth dropping from #512 and letting it depend on this.
Minor
eas.json has no production profile, only development and device. Fine for now given we're pre-release, but worth a follow-up before any store submission.
Sorry to park this one on a decision rather than a code fix — the identifier really does need to be settled before anyone writes it down in three places.
|
Thanks for the detailed review. Bundle identifier / domain: understood - will not change anything here until you confirm the canonical values. Once confirmed, I will rename in one pass.
|
Reconcile the dev-client/EAS setup with the config work that landed since: - app.json no longer exists (Miracle656#508 moved to app.config.ts). Port the expo-dev-client plugin across, and add webcredentials: alongside the existing applinks: entry — iOS will not offer a passkey for a domain that is not claimed as a webcredentials service. - Keep main's xyz.veil.wallet identifier and app.veil.xyz domain rather than this branch's app.veil.mobile / veil.app, so the config stays consistent with the .well-known files already served by the wallet. - Drop react-native-passkey ^3.0.0. main already ships react-native-passkeys ^0.4.1, which is what lib/passkey.ts uses; adding the other package would put two WebAuthn implementations in the same app. - expo-dev-client ~5.2.5 does not exist on the SDK 57 line (npm notarget). Pinned to ~57.0.10. - Replace the personal Apple ID in eas.json with a placeholder alongside the other REPLACE_WITH_* values. Cover the new webcredentials entry in appConfig.test.ts. tsc clean; jest 8 suites / 157 tests; expo lint clean.
|
Merging. The dev-client and EAS setup was a genuine gap — A fair amount had to be reconciled, so flagging all of it:
Added Kept Dropped Version fix. That version is from an older SDK. Pinned to
Verified: The acceptance criterion — |
Summary
react-native-passkey ^3.0.0andexpo-dev-client ~5.2.5tofrontend/mobile/package.jsonapp.jsonwithbundleIdentifier(iOS) andpackage(Android), both required forexpo prebuildto generate native projectsassociatedDomainsto the iOS section (webcredentials:veil.app+?mode=developervariant) so the OS trusts the app as an RP for passkey assertionsexpo-dev-clientin the plugins array so prebuild wires in the dev launchereas.jsonwith four profiles:development(simulator),device(physical device dev client),preview(internal distribution),production(app store)Next steps after merge
Run locally to generate native projects and trigger the first dev-client build:
The generated
ios/andandroid/dirs are gitignored; EAS runs prebuild in the cloud for subsequent builds.Vercel CI checks
The three Vercel checks are failing because the Vercel integration needs authorization from the repo owner - this is unrelated to the changes in this PR.
Test plan
Passkey.isSupported()in a debug console or a temporary screen - expecttrueResolves #444