iOS app #7

Merged
backmeupplz merged 4 commits from ios into main 2026-10-05 20:12:51 +00:00
backmeupplz commented 2026-09-29 21:42:42 +00:00 (Migrated from github.com)

The Android app on iPhone: the same wallet page and provider (entrypoints/android*) in a small Swift wrapper, ios/PlainWallet/PlainWallet.swift, which follows MainActivity.java. Submitted to the App Store as 0.3.0 (build 1).

  • Isolation: the browser gets a website data store of its own, so WebKit gives sites their own web content process and storage. The wallet page is served from the bundle under a plainwallet:// scheme that only the wallet web view knows.
  • Origins and replies: a request's origin comes from WKScriptMessage.frameInfo.securityOrigin, top-level http(s) frames only, up to 1 MB. Each answer goes back through the asking page's reply handler, and only while the browser still shows that origin. chainChanged / accountsChanged are pushed the same way.
  • Face ID / Touch ID unlock:
    • The vault key sits in the Keychain as WhenPasscodeSetThisDeviceOnly + biometryCurrentSet.
    • The app runs an LAContext evaluation first and passes that context to the Keychain read.
    • Changing Face ID or removing the passcode turns it off. The password keeps working, and export still asks for it.
  • Hiding the wallet: a cover goes over the wallet in the app switcher and while the screen is recorded or mirrored (release builds; iOS can't block screenshots). Third-party keyboards are off in the app.
  • Carried over from Android: the lock after 60 s away (on CLOCK_MONOTONIC, which counts sleep), the seed-phrase guard in the address bar, and no JS dialogs.
  • iOS-only differences: no Megapot, because App Store rules don't allow lotteries (extras.megapot). Plain-http sites don't load (ATS).
  • Web changes that also reach Android:
    • The fingerprint UI takes its name ("Face ID", …) from the app.
    • The wallet page's viewport has maximum-scale=1, viewport-fit=cover (stops iOS zooming into inputs).
    • The body keeps clear of the home indicator with env(safe-area-inset-bottom).
  • Also in this PR:
    • Version 0.3.0 for all platforms.
    • README and CONTRIBUTING describe the iOS app.
    • PRIVACY.md covers the iOS app.
    • ios/web, ios/build and a local debug file are ignored and kept out of the Firefox sources zip.

Checked

  • Builds and tests: npm test (all four self-checks) and tsc --noEmit pass. Debug builds succeed for the iOS 27 Simulator (Xcode 27), and the Release archive exports with cloud signing and uploads.
  • Simulator, driven over a local debug-only port (not in this PR):
    • Setup and import of the synthetic test … junk seed; the vault survives relaunch.
    • Connect and personal_sign from app.uniswap.org / example.com, with the origin shown correctly.
    • Leaving the wallet rejects the pending request (4001).
    • chainChanged reaches the page.
    • Favorites with favicons.
    • The seed-phrase guard alert.
    • The 60 s background lock.
    • Face ID turned on, then unlock with a simulated match.
    • Screenshots at 1320×2868.

Not checked

  • Keychain enforcement on a device: the Simulator doesn't enforce the Keychain item's biometric access control, so biometryCurrentSet enforcement needs checking on a real iPhone (TestFlight, disposable wallet).
  • Recording cover: the cover during screen recording only applies to release builds, which haven't run on a device yet.
  • Android: the Android wallet page with the new viewport and padding changes hasn't been re-checked on a phone.
  • Security review: none. These changes need human review; no claim that they're secure.

🤖 Generated with Claude Code

The Android app on iPhone: the same wallet page and provider (`entrypoints/android*`) in a small Swift wrapper, `ios/PlainWallet/PlainWallet.swift`, which follows `MainActivity.java`. Submitted to the App Store as 0.3.0 (build 1). - **Isolation:** the browser gets a website data store of its own, so WebKit gives sites their own web content process and storage. The wallet page is served from the bundle under a `plainwallet://` scheme that only the wallet web view knows. - **Origins and replies:** a request's origin comes from `WKScriptMessage.frameInfo.securityOrigin`, top-level http(s) frames only, up to 1 MB. Each answer goes back through the asking page's reply handler, and only while the browser still shows that origin. `chainChanged` / `accountsChanged` are pushed the same way. - **Face ID / Touch ID unlock:** - The vault key sits in the Keychain as `WhenPasscodeSetThisDeviceOnly` + `biometryCurrentSet`. - The app runs an `LAContext` evaluation first and passes that context to the Keychain read. - Changing Face ID or removing the passcode turns it off. The password keeps working, and export still asks for it. - **Hiding the wallet:** a cover goes over the wallet in the app switcher and while the screen is recorded or mirrored (release builds; iOS can't block screenshots). Third-party keyboards are off in the app. - **Carried over from Android:** the lock after 60 s away (on `CLOCK_MONOTONIC`, which counts sleep), the seed-phrase guard in the address bar, and no JS dialogs. - **iOS-only differences:** no Megapot, because App Store rules don't allow lotteries (`extras.megapot`). Plain-http sites don't load (ATS). - **Web changes that also reach Android:** - The fingerprint UI takes its name ("Face ID", …) from the app. - The wallet page's viewport has `maximum-scale=1, viewport-fit=cover` (stops iOS zooming into inputs). - The body keeps clear of the home indicator with `env(safe-area-inset-bottom)`. - **Also in this PR:** - Version 0.3.0 for all platforms. - README and CONTRIBUTING describe the iOS app. - PRIVACY.md covers the iOS app. - `ios/web`, `ios/build` and a local debug file are ignored and kept out of the Firefox sources zip. ## Checked - **Builds and tests:** `npm test` (all four self-checks) and `tsc --noEmit` pass. Debug builds succeed for the iOS 27 Simulator (Xcode 27), and the Release archive exports with cloud signing and uploads. - **Simulator, driven over a local debug-only port (not in this PR):** - Setup and import of the synthetic `test … junk` seed; the vault survives relaunch. - Connect and `personal_sign` from app.uniswap.org / example.com, with the origin shown correctly. - Leaving the wallet rejects the pending request (4001). - `chainChanged` reaches the page. - Favorites with favicons. - The seed-phrase guard alert. - The 60 s background lock. - Face ID turned on, then unlock with a simulated match. - Screenshots at 1320×2868. ## Not checked - **Keychain enforcement on a device:** the Simulator doesn't enforce the Keychain item's biometric access control, so `biometryCurrentSet` enforcement needs checking on a real iPhone (TestFlight, disposable wallet). - **Recording cover:** the cover during screen recording only applies to release builds, which haven't run on a device yet. - **Android:** the Android wallet page with the new viewport and padding changes hasn't been re-checked on a phone. - **Security review:** none. These changes need human review; no claim that they're secure. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No description provided.