Skip to content

Conversation

@transphorm
Copy link
Member

@transphorm transphorm commented Aug 20, 2025

Summary

  • wrap app with SelfClientProvider to configure SDK adapters
  • parse MRZ data via useSelfClient hook in native and web passport cameras

Testing

  • yarn install (fails: network errors)
  • yarn workspace @selfxyz/mobile-app nice (fails: Couldn't find the node_modules state file)
  • yarn workspace @selfxyz/mobile-app lint (fails: Couldn't find the node_modules state file)
  • yarn workspace @selfxyz/mobile-app types (fails: Couldn't find the node_modules state file)
  • yarn workspace @selfxyz/mobile-app test (fails: Couldn't find the node_modules state file)
  • yarn workspace @selfxyz/mobile-app build (fails: Couldn't find the node_modules state file)

https://chatgpt.com/codex/tasks/task_b_68a531b0f6d4832d8e8f99633c7c08a5

Summary by CodeRabbit

  • New Features
    • Added a global Self client provider to centralize MRZ parsing and SDK adapters.
  • Refactor
    • PassportCamera (native and web) now uses the shared client for MRZ extraction.
  • Tests
    • Added unit/tests for PassportCamera, the Self client provider, and MRZ parsing/validation flows.
  • Chores
    • Overhauled mobile CI to newer macOS runner with improved caching and Node/Ruby/iOS workflows; added license-header checks and header-fix tooling.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 20, 2025

Walkthrough

Adds a SelfClientProvider and switches PassportCamera to call SelfClient.extractMRZInfo; introduces provider and unit tests; adds license-header checking/fixing scripts and lint script updates; expands mobile CI workflow and caching and updates macOS runner to macos-latest.

Changes

Cohort / File(s) Summary of changes
CI workflow
.github/workflows/mobile-ci.yml
Migrates macOS runner from macos-14 to macos-latest, adds CI env vars, improves Node/Ruby/Pods/Xcode/Gradle caching and Node/Ruby handling, and introduces IOS project env vars.
App root integration
app/App.tsx
Wraps existing provider tree with new SelfClientProvider as the outermost provider.
New provider
app/src/providers/selfClientProvider.tsx
Adds SelfClientProvider wiring SDK client with adapters (scanner shim, fetch-based HTTP, WebSocket wrapper, Web Crypto hash, stubbed sign); exports named & default.
PassportCamera (native & web)
app/src/components/native/PassportCamera.tsx, app/src/components/native/PassportCamera.web.tsx
Replaces direct extractMRZInfo import with useSelfClient() and selfClient.extractMRZInfo(...); updates onPassportRead/mrzData types; web stub schedules a delayed error callback.
Tests — PassportCamera
app/tests/src/components/PassportCamera.test.tsx
Adds tests for native/web flows, mocks useSelfClient, verifies MRZ extraction for string payloads and object payload handling, and asserts web stub error behavior.
Tests — SelfClientProvider
app/tests/src/providers/selfClientProvider.test.tsx
Adds provider/hook tests verifying memoization, Web Crypto hashing, fetch adapter, and WebSocket stub behavior.
Tests — MRZ / proving utils
app/tests/src/utils/proving/validateDocument.test.ts
Introduces createTestClient, MRZ test vectors, and tests exercising extractMRZInfo via test client; retains existing passport validation assertion.
Lint & license tooling
app/.eslintrc.cjs, app/package.json, app/scripts/check-duplicate-headers.cjs, app/scripts/check-license-headers.mjs
Allows one leading blank line for license header, updates lint scripts to add header check/fix flows, expands duplicate-header scanning to scripts/, and adds a new license header checker with --check/--fix modes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App
  participant SelfClientProvider
  participant AuthProvider
  participant PassportProvider
  participant OtherProviders

  User->>App: Launch
  App->>SelfClientProvider: Mount (create adapters: scanner, http, ws, crypto)
  SelfClientProvider->>AuthProvider: Render children
  AuthProvider->>PassportProvider: Render
  PassportProvider->>OtherProviders: Render downstream providers/navigation
Loading
sequenceDiagram
  autonumber
  participant PassportCamera
  participant SelfClient as SelfClient (from Provider)
  participant onPassportRead as Callback (prop)

  PassportCamera->>PassportCamera: receive MRZ (string or object)
  alt MRZ is string
    PassportCamera->>SelfClient: extractMRZInfo(mrzString)
    SelfClient-->>PassportCamera: parsedMRZ
    PassportCamera-->>onPassportRead: (null, parsedMRZ)
  else MRZ is object
    PassportCamera-->>onPassportRead: (null, mappedObject)
  end
  opt Web stub
    Note right of PassportCamera: on mount, schedules error after 100ms
    PassportCamera-->>onPassportRead: (Error, undefined)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • remicolin
  • aaronmgdr
  • motemotech

Poem

A client appears with adapters bright,
MRZ now parsed beneath provider light.
Tests sing softly, CI caches hum,
Headers fixed and linters come.
Small gears turned — the build marches on. 🚀

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/create-shared-client-instance-and-update-imports

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@transphorm transphorm marked this pull request as ready for review August 20, 2025 03:39
jobs:
lint:
runs-on: macos-14
runs-on: macos-latest
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixes the failing 16.4 error. missed it from earlier

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/mobile-ci.yml (1)

235-238: Don’t delete Podfile.lock; it undermines reproducible iOS builds

Removing Podfile.lock during cleanup forces a fresh dependency resolution, leading to non-deterministic builds and flaky CI. Keep Podfile.lock to ensure reproducibility.

Apply this diff:

-            echo "Cleaning empty/corrupted Pods directory..."
-            rm -rf Pods Podfile.lock
+            echo "Cleaning empty/corrupted Pods directory (preserving Podfile.lock for reproducible installs)..."
+            rm -rf Pods
app/src/components/native/PassportCamera.tsx (1)

93-99: Handle MRZ parsing failures to avoid runtime crashes

selfClient.extractMRZInfo may throw on malformed MRZ input. Catch and surface the error via onPassportRead.

Apply this diff:

       if (typeof event.nativeEvent.data === 'string') {
-        onPassportRead(null, selfClient.extractMRZInfo(event.nativeEvent.data));
+        try {
+          const parsed = selfClient.extractMRZInfo(event.nativeEvent.data);
+          onPassportRead(null, parsed);
+        } catch (err) {
+          const e = err instanceof Error ? err : new Error(String(err));
+          onPassportRead(e);
+        }
       } else {
🧹 Nitpick comments (2)
.github/workflows/mobile-ci.yml (2)

130-136: Avoid brittle manual xcode-select; rely on setup-xcode to manage DEVELOPER_DIR

Manually switching to /Applications/Xcode_${{ env.XCODE_VERSION }}.app is fragile and can break if the image path changes. setup-xcode sets DEVELOPER_DIR for the chosen version; prefer relying on it and keep only diagnostics.

Apply this diff to remove the manual switch:

           echo "🔧 Configuring Xcode path to fix iOS SDK issues..."
-          # Fix for macOS 15 runner iOS SDK issues
-          # See: https://github.com/actions/runner-images/issues/12758
-          sudo xcode-select --switch /Applications/Xcode_${{ env.XCODE_VERSION }}.app
-          echo "✅ Xcode path configured"
+          # Using setup-xcode to set DEVELOPER_DIR; no manual xcode-select required
+          echo "✅ Xcode path configured by setup-xcode"

22-22: Ensure Xcode 16.4 is always available on your macOS runners

macos-latest is currently rolling from macos-14 → macos-15 (Aug 4–Sep 1, 2025). On macos-14 images Xcode 16.4 may be absent, causing your actions/setup-xcode step to fail.

• Files & lines to update:
– .github/workflows/mobile-ci.yml @ lines 22, 65, 105

• Options to guarantee Xcode 16.4:
– Pin the runner explicitly:
yaml runs-on: macos-15
– Or verify before switching:
yaml - name: Verify Xcode 16.4 run: | xcodebuild -version ls /Applications | grep Xcode_16.4.app
• Leverage actions/setup-xcode to select the version and remove any manual xcode-select invocations.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d34ce43 and 4eec728.

📒 Files selected for processing (8)
  • .github/workflows/mobile-ci.yml (3 hunks)
  • app/App.tsx (2 hunks)
  • app/src/components/native/PassportCamera.tsx (3 hunks)
  • app/src/components/native/PassportCamera.web.tsx (3 hunks)
  • app/src/providers/selfClientProvider.tsx (1 hunks)
  • app/tests/src/components/PassportCamera.test.tsx (1 hunks)
  • app/tests/src/providers/selfClientProvider.test.tsx (1 hunks)
  • app/tests/src/utils/proving/validateDocument.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{test,spec}.{ts,js,tsx,jsx}

⚙️ CodeRabbit Configuration File

**/*.{test,spec}.{ts,js,tsx,jsx}: Review test files for:

  • Test coverage completeness
  • Test case quality and edge cases
  • Mock usage appropriateness
  • Test readability and maintainability

Files:

  • app/tests/src/components/PassportCamera.test.tsx
  • app/tests/src/utils/proving/validateDocument.test.ts
  • app/tests/src/providers/selfClientProvider.test.tsx
app/src/**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit Configuration File

app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:

  • Component architecture and reusability
  • State management patterns
  • Performance optimizations
  • TypeScript type safety
  • React hooks usage and dependencies
  • Navigation patterns

Files:

  • app/src/providers/selfClientProvider.tsx
  • app/src/components/native/PassportCamera.tsx
  • app/src/components/native/PassportCamera.web.tsx
🧠 Learnings (1)
📚 Learning: 2025-07-14T09:03:08.292Z
Learnt from: aaronmgdr
PR: selfxyz/self#763
File: app/.github/workflows/test-coverage.yml:0-0
Timestamp: 2025-07-14T09:03:08.292Z
Learning: Node.js 22 is supported by actions/setup-nodev4 and has been in Active LTS since October 2024. It works on Linux, macOS, and Windows runners (Windows issues were resolved after version 22.8.0).

Applied to files:

  • .github/workflows/mobile-ci.yml
🧬 Code Graph Analysis (5)
app/App.tsx (1)
app/src/providers/selfClientProvider.tsx (1)
  • SelfClientProvider (18-70)
app/tests/src/utils/proving/validateDocument.test.ts (2)
packages/mobile-sdk-alpha/src/browser.ts (1)
  • createSelfClient (46-46)
packages/mobile-sdk-alpha/src/index.ts (1)
  • createSelfClient (75-75)
app/tests/src/providers/selfClientProvider.test.tsx (1)
app/src/providers/selfClientProvider.tsx (1)
  • SelfClientProvider (18-70)
app/src/components/native/PassportCamera.tsx (4)
packages/mobile-sdk-alpha/src/types/public.ts (1)
  • SelfClient (119-135)
app/src/components/native/PassportCamera.web.tsx (2)
  • PassportCamera (17-76)
  • PassportCameraProps (9-15)
app/android/app/src/main/java/com/proofofpassportapp/ui/PassportOCRViewManager.kt (1)
  • onPassportRead (131-137)
app/android/app/src/main/java/com/proofofpassportapp/ui/CameraMLKitFragment.kt (2)
  • onPassportRead (404-407)
  • onPassportRead (405-405)
app/src/components/native/PassportCamera.web.tsx (2)
app/src/components/native/PassportCamera.tsx (2)
  • PassportCameraProps (46-52)
  • PassportCamera (54-158)
packages/mobile-sdk-alpha/src/types/public.ts (1)
  • SelfClient (119-135)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e-ios
  • GitHub Check: analyze-android
🔇 Additional comments (5)
app/App.tsx (1)

29-39: Provider placement looks correct

Wrapping the app with SelfClientProvider above Auth/Passport/DB providers ensures hook availability across the tree.

app/src/components/native/PassportCamera.tsx (1)

46-51: Type alignment with SelfClient is correct

Updating mrzData to ReturnType<SelfClient['extractMRZInfo']> keeps the prop in sync with SDK types.

app/tests/src/utils/proving/validateDocument.test.ts (3)

54-81: Solid test client scaffolding; adapters are sufficiently stubbed for MRZ parsing.

The minimal adapters are adequate for exercising extractMRZInfo without leaking network/crypto side effects. No blockers here.


175-180: Good positive-path MRZ assertion.

Verifies both field extraction and validation, aligned with the SDK’s expected behavior for the ICAO sample.


182-185: Good negative-path coverage.

Ensures malformed input surfaces an error from the SDK parser.

* Ensures there's a newline after license headers
*/

// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes issue with header license eslint fix not working

@transphorm transphorm changed the title feat: use Self SDK hook for MRZ parsing feat: use SelfClient for MRZ parsing Aug 20, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
app/package.json (1)

38-41: Minor duplication: lint:headers:fix runs twice in “nice”.

nice runs lint:headers:fix and then lint:fix, which itself runs lint:headers:fix. You can drop the first call to speed up CI/local runs.

-    "nice": "yarn imports:fix && yarn lint:headers:fix && yarn lint:fix && yarn fmt:fix",
+    "nice": "yarn imports:fix && yarn lint:fix && yarn fmt:fix",

Also applies to: 47-47

app/tests/src/utils/proving/validateDocument.test.ts (1)

55-83: Strengthen the WsConn mock to match the callback signatures

The ws.connect mock returns jest.fn placeholders for onMessage/onError/onClose without accepting callbacks. If future tests rely on these registrations, they’ll silently pass without actually wiring handlers. Prefer no-op implementations that accept and discard callbacks so signature drift is caught.

Apply this diff:

       ws: {
         connect: jest.fn(() => ({
           send: jest.fn(),
           close: jest.fn(),
-          onMessage: jest.fn(),
-          onError: jest.fn(),
-          onClose: jest.fn(),
+          onMessage: jest.fn((_cb: (data: unknown) => void) => {}),
+          onError: jest.fn((_cb: (err: unknown) => void) => {}),
+          onClose: jest.fn((_cb: () => void) => {}),
         })),
       },
app/src/providers/selfClientProvider.tsx (1)

29-47: Harden WebSocket adapter: set binaryType and normalize error payloads

Two robustness tweaks will prevent subtle runtime issues:

  • Without setting binaryType, browsers may deliver Blob payloads; downstream code often expects string or ArrayBuffer.
  • The error event listener forwards a generic Event. Converting to an Error improves downstream error handling.

Apply this diff:

           connect: (url: string): WsConn => {
             const socket = new WebSocket(url);
+            // Prefer ArrayBuffer for binary frames; avoids Blob handling downstream
+            try {
+              socket.binaryType = 'arraybuffer';
+            } catch {}
             return {
               send: (data: string | ArrayBufferView | ArrayBuffer) =>
                 socket.send(data),
               close: () => socket.close(),
               onMessage: cb => {
                 socket.addEventListener('message', ev =>
                   cb((ev as MessageEvent).data),
                 );
               },
               onError: cb => {
-                socket.addEventListener('error', e => cb(e));
+                socket.addEventListener('error', ev => {
+                  const anyEv = ev as any;
+                  const err =
+                    anyEv?.error instanceof Error
+                      ? anyEv.error
+                      : new Error('WebSocket error');
+                  cb(err as unknown as Error);
+                });
               },
               onClose: cb => {
                 socket.addEventListener('close', () => cb());
               },
             };
           },
app/tests/src/providers/selfClientProvider.test.tsx (1)

21-56: Good isolation and cleanup; consider exercising adapters via the client

The test safely stubs and restores globals. Note that it currently verifies environment primitives (crypto/fetch/WebSocket) rather than the SDK using the provided adapters. If feasible, add a lightweight assertion that a client operation routes through these adapters (e.g., a method that invokes network/crypto) to catch integration regressions.

app/src/components/native/PassportCamera.web.tsx (1)

22-29: Guard MRZ parsing with try/catch to avoid unhandled exceptions in UI callbacks

If extractMRZInfo throws, the error will bubble out of the React event/callback and potentially crash the component. Route parsing errors to onPassportRead(error) so consumers can handle failure gracefully.

Apply this diff:

   const _onPassportRead = useCallback(
     (mrz: string) => {
       if (!isMounted) {
         return;
       }
-      onPassportRead(null, selfClient.extractMRZInfo(mrz));
+      try {
+        const info = selfClient.extractMRZInfo(mrz);
+        onPassportRead(null, info);
+      } catch (err) {
+        const e = err instanceof Error ? err : new Error(String(err));
+        onPassportRead(e);
+      }
     },
     [onPassportRead, isMounted, selfClient],
   );
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4eec728 and 9117bb9.

📒 Files selected for processing (10)
  • app/.eslintrc.cjs (1 hunks)
  • app/package.json (1 hunks)
  • app/scripts/check-duplicate-headers.cjs (1 hunks)
  • app/scripts/check-license-headers.mjs (1 hunks)
  • app/src/components/native/PassportCamera.tsx (4 hunks)
  • app/src/components/native/PassportCamera.web.tsx (3 hunks)
  • app/src/providers/selfClientProvider.tsx (1 hunks)
  • app/tests/src/components/PassportCamera.test.tsx (1 hunks)
  • app/tests/src/providers/selfClientProvider.test.tsx (1 hunks)
  • app/tests/src/utils/proving/validateDocument.test.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/components/native/PassportCamera.tsx
  • app/tests/src/components/PassportCamera.test.tsx
🧰 Additional context used
📓 Path-based instructions (2)
app/src/**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit Configuration File

app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:

  • Component architecture and reusability
  • State management patterns
  • Performance optimizations
  • TypeScript type safety
  • React hooks usage and dependencies
  • Navigation patterns

Files:

  • app/src/providers/selfClientProvider.tsx
  • app/src/components/native/PassportCamera.web.tsx
**/*.{test,spec}.{ts,js,tsx,jsx}

⚙️ CodeRabbit Configuration File

**/*.{test,spec}.{ts,js,tsx,jsx}: Review test files for:

  • Test coverage completeness
  • Test case quality and edge cases
  • Mock usage appropriateness
  • Test readability and maintainability

Files:

  • app/tests/src/providers/selfClientProvider.test.tsx
  • app/tests/src/utils/proving/validateDocument.test.ts
🧬 Code Graph Analysis (4)
app/tests/src/providers/selfClientProvider.test.tsx (1)
app/src/providers/selfClientProvider.tsx (1)
  • SelfClientProvider (19-81)
app/scripts/check-license-headers.mjs (2)
app/scripts/check-duplicate-headers.cjs (5)
  • path (5-5)
  • files (40-42)
  • fs (4-4)
  • content (12-12)
  • lines (13-13)
app/scripts/analyze-tree-shaking.cjs (2)
  • findFiles (278-291)
  • filePath (43-43)
app/src/components/native/PassportCamera.web.tsx (2)
app/src/components/native/PassportCamera.tsx (2)
  • PassportCameraProps (46-52)
  • PassportCamera (54-158)
packages/mobile-sdk-alpha/src/types/public.ts (1)
  • SelfClient (119-135)
app/tests/src/utils/proving/validateDocument.test.ts (2)
packages/mobile-sdk-alpha/src/browser.ts (1)
  • createSelfClient (46-46)
packages/mobile-sdk-alpha/src/index.ts (1)
  • createSelfClient (75-75)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e-ios
  • GitHub Check: build
🔇 Additional comments (7)
app/.eslintrc.cjs (1)

96-104: LGTM: BOF allowance aligns with header-newline policy.

Allowing maxBOF: 1 complements the dedicated newline-after-header script and avoids spurious ESLint violations after the license line.

Also applies to: 106-116

app/tests/src/utils/proving/validateDocument.test.ts (2)

84-89: Good MRZ fixtures; positive and negative paths covered

The ICAO sample (validMrz) and malformed case (invalidMrz) are appropriate for exercising parse success and failure paths.


171-186: Verify no stray extractMRZInfo imports or calls remain

Our initial grep found no direct imports of extractMRZInfo from @selfxyz/mobile-sdk-alpha, but the bare-call search was inconclusive. To complete the migration and avoid mixed usage patterns:

• Manually search all .ts/.tsx (and any .js if you use JS) for

  • import { extractMRZInfo } from '@selfxyz/mobile-sdk-alpha'
  • bare calls like extractMRZInfo(...) without a client. receiver
    • Ensure every MRZ parse is invoked via client.extractMRZInfo only

This will safeguard against hidden direct usages and keep the codebase consistent.

app/src/providers/selfClientProvider.tsx (2)

51-66: WebCrypto hashing adapter is resilient to RN/web environments

The subtle.digest availability guard and algorithm mapping are sensible. Given upstream callers may vary the casing/hyphenation, consider normalizing more broadly if you start accepting other identifiers, but as-is this is fine.


76-81: Provider wiring looks correct and minimal

Config/adapters memoization and passing through SDKSelfClientProvider are clean. No concerns.

app/tests/src/providers/selfClientProvider.test.tsx (1)

10-19: Memoization test is effective and concise

The instance reference check across rerenders validates stable client provisioning.

app/src/components/native/PassportCamera.web.tsx (1)

39-51: Web stub behavior is explicit and predictable

The delayed error signaling makes the “not implemented” state obvious to callers. Dependencies are correct and avoid stale closures.

transphorm and others added 5 commits August 19, 2025 21:54
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
.github/workflows/mobile-ci.yml (3)

247-270: Use correct workspace path relative to working-directory in Verify iOS Workspace.

This step runs in ./app/ios, but sets WORKSPACE_PATH="app/ios/...". That results in app/ios/app/ios/... and causes false “workspace not found” and scheme checks to fail.

Apply this diff:

-          WORKSPACE_PATH="app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace"
+          WORKSPACE_PATH="${{ env.IOS_PROJECT_NAME }}.xcworkspace"
           if [ ! -d "$WORKSPACE_PATH" ]; then
             echo "❌ Workspace not found at: $WORKSPACE_PATH"
             echo "Available workspaces:"
-            find app/ios -name "*.xcworkspace" -type d
+            find . -name "*.xcworkspace" -type d
             exit 1
           fi
@@
-          AVAILABLE_SCHEMES=$(xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | xargs)
+          AVAILABLE_SCHEMES=$(xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | xargs)
           echo "Available schemes (first 20): $(echo $AVAILABLE_SCHEMES | cut -d' ' -f1-20)..."
 
-          if [[ ! "$AVAILABLE_SCHEMES" =~ ${{ env.IOS_PROJECT_SCHEME }} ]]; then
+          if [[ ! "$AVAILABLE_SCHEMES" =~ ${{ env.IOS_PROJECT_SCHEME }} ]]; then
             echo "❌ Scheme '${{ env.IOS_PROJECT_SCHEME }}' not found"
             echo "Full scheme list:"
-            xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | head -50
+            xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | head -50
             exit 1
           fi

49-58: Align Node modules cache key with the app’s lockfile.

The linter caches depend on yarn.lock at repo root, but installs run under ./app. If the real lockfile is app/yarn.lock, your cache key won’t invalidate on dependency changes.

       - name: Cache Node Modules
         uses: actions/cache@v4
         with:
           path: |
             .yarn/cache
             node_modules
             app/node_modules
-          key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }}
+          key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('app/yarn.lock') }}
           restore-keys: |
             ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-

92-101: Use app/yarn.lock for test job cache key as well.

Same concern as lint job: ensure cache invalidates when app dependencies change.

       - name: Cache Node Modules
         uses: actions/cache@v4
         with:
           path: |
             .yarn/cache
             node_modules
             app/node_modules
-          key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }}
+          key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('app/yarn.lock') }}
           restore-keys: |
             ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-
♻️ Duplicate comments (2)
app/scripts/check-license-headers.mjs (2)

50-67: Header check misses files with a shebang and breaks on CRLF; preserves neither index nor EOL.

Current logic only matches when the license is the very first line and splits on LF. Files with a shebang or CRLF endings will be false negatives; fixes will also clobber EOL style.

Apply this robust, cross-platform fix:

 function checkLicenseHeader(filePath) {
-  const content = fs.readFileSync(filePath, 'utf8');
-  const lines = content.split('\n');
-
-  // Check if first line is license header
-  if (lines[0] === LICENSE_HEADER) {
-    // Check if second line is empty (has newline after license header)
-    if (lines[1] !== '') {
-      return {
-        file: filePath,
-        issue: 'Missing newline after license header',
-        fixed: false,
-      };
-    }
-  }
-
-  return null;
+  const content = fs.readFileSync(filePath, 'utf8');
+  // Preserve original EOLs and compare robustly
+  const eol = content.includes('\r\n') ? '\r\n' : '\n';
+  const lines = content.split(eol);
+
+  // License should follow an optional shebang
+  let idx = 0;
+  if (lines[0]?.startsWith('#!')) idx = 1;
+
+  const normalize = s => (typeof s === 'string' ? s.replace(/\r$/, '') : s);
+  if (normalize(lines[idx]) === LICENSE_HEADER) {
+    if (normalize(lines[idx + 1]) !== '') {
+      return {
+        file: filePath,
+        issue: 'Missing newline after license header',
+        fixed: false,
+      };
+    }
+  }
+  return null;
 }

To quickly surface affected files in the repo (missing blank line after SPDX when a shebang is present), run:

#!/bin/bash
set -euo pipefail
# Scan code files, skipping heavy/build dirs
fd -e ts -e tsx -e js -e jsx -e mjs -e cjs -E node_modules -E dist -E build -E coverage \
| while IFS= read -r f; do
  # Only consider files with a shebang followed by SPDX on the next line
  awk 'NR==1{sheb=($0 ~ /^#!/)}
       NR==2{spdx=($0 ~ /^\/\/ SPDX-License-Identifier:/); empty2=($0 ~ /^$/)}
       NR==3{empty3=($0 ~ /^$/)}
       END{ if (sheb && spdx && !empty3) print FILENAME }' "$f"
done

69-82: Fixer will corrupt line endings and fails on shebang-indexed headers.

It only inserts after line 0 and always rewrites with LF. This both misses valid cases and changes file EOLs.

Apply this fix to respect shebang placement and preserve EOL style:

 function fixLicenseHeader(filePath) {
-  const content = fs.readFileSync(filePath, 'utf8');
-  const lines = content.split('\n');
-
-  if (lines[0] === LICENSE_HEADER && lines[1] !== '') {
-    // Insert empty line after license header
-    lines.splice(1, 0, '');
-    const fixedContent = lines.join('\n');
-    fs.writeFileSync(filePath, fixedContent, 'utf8');
-    return true;
-  }
-
-  return false;
+  const content = fs.readFileSync(filePath, 'utf8');
+  const eol = content.includes('\r\n') ? '\r\n' : '\n';
+  const lines = content.split(eol);
+
+  let idx = 0;
+  if (lines[0]?.startsWith('#!')) idx = 1;
+  const normalize = s => (typeof s === 'string' ? s.replace(/\r$/, '') : s);
+
+  if (normalize(lines[idx]) === LICENSE_HEADER && normalize(lines[idx + 1]) !== '') {
+    // Insert a blank line immediately after the license header, preserving EOL
+    lines.splice(idx + 1, 0, '');
+    const fixedContent = lines.join(eol);
+    fs.writeFileSync(filePath, fixedContent, 'utf8');
+    return true;
+  }
+  return false;
 }
🧹 Nitpick comments (1)
.github/workflows/mobile-ci.yml (1)

160-167: Add Yarn cache to build job for network resilience and speed.

Build job only caches app/node_modules; missing .yarn/cache leads to frequent network pulls and flakiness. Lint/test jobs already cache .yarn/cache.

-      - name: Cache Node modules
+      - name: Cache Node modules
         uses: actions/cache@v4
         with:
-          path: app/node_modules
+          path: |
+            .yarn/cache
+            app/node_modules
           key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('app/yarn.lock') }}
           restore-keys: |
             ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9117bb9 and ae65a47.

⛔ Files ignored due to path filters (1)
  • app/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/mobile-ci.yml (8 hunks)
  • app/package.json (1 hunks)
  • app/scripts/check-license-headers.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/package.json
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-14T09:03:08.292Z
Learnt from: aaronmgdr
PR: selfxyz/self#763
File: app/.github/workflows/test-coverage.yml:0-0
Timestamp: 2025-07-14T09:03:08.292Z
Learning: Node.js 22 is supported by actions/setup-nodev4 and has been in Active LTS since October 2024. It works on Linux, macOS, and Windows runners (Windows issues were resolved after version 22.8.0).

Applied to files:

  • .github/workflows/mobile-ci.yml
🧬 Code Graph Analysis (1)
app/scripts/check-license-headers.mjs (2)
app/scripts/check-duplicate-headers.cjs (5)
  • path (5-5)
  • files (40-42)
  • fs (4-4)
  • content (12-12)
  • lines (13-13)
app/scripts/analyze-tree-shaking.cjs (2)
  • findFiles (278-291)
  • filePath (43-43)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e-ios
  • GitHub Check: analyze-android
🔇 Additional comments (3)
.github/workflows/mobile-ci.yml (1)

28-28: Confirm Xcode 16.4 availability on macos-latest or pin the runner.

You hard-pin Xcode to 16.4 and run on macos-latest. If the image rotation ever drops 16.4, builds will break. Consider pinning to macos-15 or adding a fallback strategy.

If you want to keep macos-latest, a pragmatic safeguard is to allow an alternate 16.x:

-      - name: Set up Xcode
+      - name: Set up Xcode
         uses: maxim-lobanov/setup-xcode@v1
         with:
-          xcode-version: ${{ env.XCODE_VERSION }}
+          xcode-version: ^${{ env.XCODE_VERSION }} # any compatible 16.x if 16.4 is unavailable

Alternatively, pin the runner:

-    runs-on: macos-latest
+    runs-on: macos-15

Also applies to: 71-71, 111-111

app/scripts/check-license-headers.mjs (2)

3-9: SPDX header placement looks correct after the shebang.

This should satisfy eslint-plugin-header’s “line” mode.


20-23: Good catch including .mjs and .cjs.

This ensures the checker covers Node ESM/CommonJS scripts as well.

Comment on lines +181 to 188
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Cache key won’t include workspace hash due to unevaluated expression inside hashFiles().

hashFiles() won’t expand ${{ env.IOS_PROJECT_NAME }} when it’s inside the quoted path literal. The call will likely return an empty hash, reducing cache uniqueness.

Use a glob that doesn’t require expression interpolation:

-          key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
+          key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/*.xcworkspace/contents.xcworkspacedata') }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/*.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
🤖 Prompt for AI Agents
In .github/workflows/mobile-ci.yml around lines 181-188, the hashFiles() call
embeds the env expression inside a quoted path so ${{ env.IOS_PROJECT_NAME }}
won’t be expanded, making the workspace hash empty; fix by using a glob that
doesn’t require interpolation (e.g.
hashFiles('app/ios/**/contents.xcworkspacedata')) and include the
IOS_PROJECT_NAME separately in the cache key (e.g. ...-${{ env.IOS_PROJECT_NAME
}}), or alternatively compute the workspace path before using hashFiles so the
path string passed to hashFiles contains no unevaluated expressions.

Comment on lines 238 to 243
run: |
echo "Installing iOS dependencies..."
# Clean Pods directory if it's corrupted or empty
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "Cleaning empty/corrupted Pods directory..."
rm -rf Pods Podfile.lock
fi
# Install pods
bundle exec pod install --silent || { echo "❌ Pod install failed"; exit 1; }
(cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"
# Verify installation
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "❌ Pods directory is still empty after installation"
exit 1
fi
echo "Pods directory contents:"
ls -la Pods/ | head -10
# Verify key files exist
if [ ! -f "Pods/Target Support Files/Pods-Self/Pods-Self.debug.xcconfig" ]; then
echo "❌ Key CocoaPods configuration file missing"
exit 1
fi
echo "✅ iOS dependencies installed successfully"
working-directory: ./app/ios
- name: Verify iOS Workspace
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix double-directory traversal in Pods install (cd into app/ios twice).

The step’s working-directory is already ./app/ios. The subshell cd app/ios causes path resolution to ./app/ios/app/ios, breaking pod install.

Apply this diff:

-      - name: Install iOS Dependencies
+      - name: Install iOS Dependencies
         run: |
           echo "Installing iOS dependencies..."
-          (cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
+          pod install --silent || { echo "❌ Pod install failed"; exit 1; }
           echo "✅ Pods installed successfully"
         working-directory: ./app/ios
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: |
echo "Installing iOS dependencies..."
# Clean Pods directory if it's corrupted or empty
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "Cleaning empty/corrupted Pods directory..."
rm -rf Pods Podfile.lock
fi
# Install pods
bundle exec pod install --silent || { echo "❌ Pod install failed"; exit 1; }
(cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"
# Verify installation
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "❌ Pods directory is still empty after installation"
exit 1
fi
echo "Pods directory contents:"
ls -la Pods/ | head -10
# Verify key files exist
if [ ! -f "Pods/Target Support Files/Pods-Self/Pods-Self.debug.xcconfig" ]; then
echo "❌ Key CocoaPods configuration file missing"
exit 1
fi
echo "✅ iOS dependencies installed successfully"
working-directory: ./app/ios
- name: Verify iOS Workspace
- name: Install iOS Dependencies
run: |
echo "Installing iOS dependencies..."
pod install --silent || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"
working-directory: ./app/ios
🤖 Prompt for AI Agents
.github/workflows/mobile-ci.yml around lines 238 to 243: the run step currently
cds into app/ios even though the job already sets working-directory: ./app/ios,
causing a double traversal to ./app/ios/app/ios and breaking pod install; remove
the subshell cd and run pod install --silent directly (e.g., run: echo
"Installing iOS dependencies..." ; pod install --silent || { echo "❌ Pod install
failed"; exit 1; } ; echo "✅ Pods installed successfully") so the command
executes in the declared working-directory.

@transphorm transphorm merged commit cc628a7 into dev Aug 20, 2025
12 checks passed
@transphorm transphorm deleted the codex/create-shared-client-instance-and-update-imports branch August 20, 2025 05:30
This was referenced Aug 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants