Update agents.md files to protect against out of memory tests (#1395)

* memory and test reminders

* clean up migration docs

* format
This commit is contained in:
Justin Hernandez
2025-11-11 15:53:38 -08:00
committed by GitHub
parent d86ee9e03f
commit 6c28bbd576
9 changed files with 407 additions and 547 deletions

View File

@@ -1,291 +0,0 @@
---
description: Comprehensive migration strategy and testing-first approach for porting identity verification logic from app to mobile-sdk-alpha package
version: 1.0.0
status: active
owners:
- team: mobile-identity
- team: sdk-platform
lastUpdated: 2025-01-12
specId: mobile-sdk-migration
importanceScore: 90
importanceJustification: Critical framework for systematically migrating core identity verification functionality to a partner-consumable SDK while maintaining quality and testing coverage.
contextUsageNote: If this file is used to add in-context notes, include a single italicized line stating what specific information was used from this file in sentence case.
---
# Mobile SDK Migration Context
## Migration Strategy Overview
### Testing-First Approach
- **Create tests BEFORE migrating logic** to verify functionality works correctly
- **Dual testing environment**: Jest (app) + Vitest (mobile-sdk-alpha)
- **Validation commands**: `yarn test:build` in both app and mobile-sdk-alpha directories
- **Incremental migration**: One checklist item at a time with thorough validation
### Test Environment Differences
#### App (Jest)
- **Location**: `app/` directory
- **Config**: `jest.config.cjs` with React Native preset
- **Setup**: `jest.setup.js` with comprehensive mocks
- **Module mapping**: `@/` → `src/`, `@tests/` → `tests/src/`
- **Test command**: `yarn test:build` (builds deps + types + bundle analysis + tests)
#### Mobile SDK Alpha (Vitest)
- **Location**: `packages/mobile-sdk-alpha/` directory
- **Config**: `vitest.config.ts` with Node environment
- **Setup**: `tests/setup.ts` with console noise suppression
- **Test command**: `yarn test:build` (build + test + types + lint)
### Migration Validation Workflow
1. **Pre-migration**: Create comprehensive tests in mobile-sdk-alpha for target functionality
2. **Migration**: Port logic from app to mobile-sdk-alpha
3. **Validation**: Run `yarn test:build` in both directories
4. **Integration**: Update app to consume mobile-sdk-alpha
5. **Final validation**: Ensure app tests pass with new SDK consumption
## Migration Checklist Items
### 1. Processing Helpers (MRZ)
**Current Location**: `app/src/utils/` (MRZ utilities)
**Target Location**: `packages/mobile-sdk-alpha/src/processing/`
**Testing Strategy**:
- Create MRZ parsing tests with sample passport data
- Test cross-platform compatibility (React Native vs Web)
### 2. Validation Module
**Current Location**: `app/src/utils/` (document validation logic)
**Target Location**: `packages/mobile-sdk-alpha/src/validation/`
**Testing Strategy**:
- Unit tests for each validation rule
- Test with valid/invalid document data
- Test edge cases and error conditions
### 3. Proof Input Generation
**Current Location**: `app/src/utils/proving/`
**Target Location**: `packages/mobile-sdk-alpha/src/proving/`
**Testing Strategy**:
- Test register input generation with mock data
- Test disclose input generation with various scenarios
- Validate TEE input format compliance
### 4. Crypto Adapters
**Current Location**: `app/src/utils/` (crypto utilities)
**Target Location**: `packages/mobile-sdk-alpha/src/crypto/`
**Testing Strategy**:
- Test WebCrypto vs @noble/* fallback detection
- Test CSPRNG generation across platforms
- Test timing-safe comparison functions
- Parity tests between implementations
### 5. TEE Session Management
**Current Location**: `app/src/utils/` (WebSocket handling)
**Target Location**: `packages/mobile-sdk-alpha/src/tee/`
**Testing Strategy**:
- Test WebSocket wrapper with mock server
- Test abort, timeout, and progress events
- Test connection lifecycle management
### 6. Attestation Verification
**Current Location**: `app/src/utils/` (certificate validation)
**Target Location**: `packages/mobile-sdk-alpha/src/attestation/`
**Testing Strategy**:
- Test PCR0 validation with sample data
- Test public key extraction
- Test certificate chain validation
### 7. Protocol Synchronization
**Current Location**: `app/src/utils/` (protocol tree handling)
**Target Location**: `packages/mobile-sdk-alpha/src/protocol/`
**Testing Strategy**:
- Test protocol tree fetching with pagination
- Test TTL cache behavior
- Test rate limiting and exponential backoff
- Test memory bounds enforcement
### 8. Artifact Management
**Current Location**: `app/src/utils/` (manifest handling)
**Target Location**: `packages/mobile-sdk-alpha/src/artifacts/`
**Testing Strategy**:
- Test manifest schema validation
- Test CDN download with caching
- Test signature verification
- Test storage adapter integration
### 9. Sample Applications
**Target Location**: `packages/mobile-sdk-alpha/samples/`
**Testing Strategy**:
- Create React Native demo with MRZ → proof flow
- Create web demo with browser-based MRZ input
- Test iOS `OpenPassport` URL scheme
### 10. SDK Integration into App
**Migration Strategy**:
- Replace existing modules with SDK imports
- Update import paths throughout app
- Validate all existing functionality works
- Ensure no regression in app behavior
### 11. In-SDK Lightweight Demo
**Target Location**: `packages/mobile-sdk-alpha/demo/`
**Testing Strategy**:
- Embedded React Native demo using MRZ → proof flow
- Test theming hooks integration
- Validate build and run instructions
## Testing Best Practices
### Test Data Management
- **Mock data**: Create comprehensive test fixtures for each module
- **Sensitive data**: Never log PII, credentials, or private keys
- **Redaction**: Use consistent patterns for sensitive field masking
- **Environment flags**: Use `DEBUG_SECRETS_TOKEN` for debug-level secrets
### Cross-Platform Testing
- **React Native**: Test on both iOS and Android simulators
- **Web**: Test with browser adapters
- **Platform detection**: Test platform-specific code paths
- **Native modules**: Mock native dependencies appropriately
### Performance Testing
- **Bundle size**: Monitor SDK bundle size impact
- **Memory usage**: Test memory bounds for large operations
- **Network efficiency**: Test rate limiting and caching
- **Startup time**: Measure SDK initialization impact
### Integration Testing
- **End-to-end flows**: Test complete user journeys
- **Error handling**: Test graceful degradation
- **Recovery mechanisms**: Test error recovery and retry logic
- **Backward compatibility**: Ensure existing app functionality works
## Migration Validation Checklist
### Pre-Migration
- [ ] Create comprehensive test suite in mobile-sdk-alpha
- [ ] Define test fixtures and mock data
- [ ] Set up cross-platform testing environment
- [ ] Document current functionality and edge cases
### During Migration
- [ ] Port logic incrementally (one checklist item at a time)
- [ ] Run `yarn test:build` in mobile-sdk-alpha after each item
- [ ] Validate functionality matches original implementation
- [ ] Update documentation and type definitions
- [ ] Re-export new modules via `packages/mobile-sdk-alpha/src/index.ts` and document them in `packages/mobile-sdk-alpha/README.md`
### Post-Migration
- [ ] Update app to consume mobile-sdk-alpha
- [ ] Run `yarn test:build` in app directory
- [ ] Validate all existing app tests pass
- [ ] Test integration with existing app functionality
- [ ] Performance validation and bundle size analysis
### Final Validation
- [ ] End-to-end testing of complete flows
- [ ] Cross-platform compatibility verification
- [ ] Partner SDK consumption testing
- [ ] Documentation and example updates
- [ ] Release preparation and versioning
## Common Migration Patterns
### Module Structure
```typescript
// Before (app/src/utils/module.ts)
export function processData(data: InputType): OutputType {
// Implementation
}
// After (packages/mobile-sdk-alpha/src/module/index.ts)
export function processData(data: InputType): OutputType {
// Same implementation with enhanced error handling
}
// Test (packages/mobile-sdk-alpha/tests/module.test.ts)
describe('processData', () => {
it('should process valid data correctly', () => {
// Test implementation
});
});
```
### Adapter Pattern
```typescript
// Cross-platform adapter interface
export interface ScannerAdapter {
scan(): Promise<ScanResult>;
isSupported(): boolean;
}
// Platform-specific implementations
export class ReactNativeScannerAdapter implements ScannerAdapter {
// React Native implementation
}
export class WebScannerAdapter implements ScannerAdapter {
// Web implementation
}
```
### Error Handling
```typescript
// Consistent error types across SDK
export class SDKError extends Error {
constructor(
message: string,
public code: string,
public details?: Record<string, unknown>
) {
super(message);
this.name = 'SDKError';
}
}
```
## Security & Privacy Considerations
### Data Protection
- **Sensitive data**: Never log PII, credentials, or private keys in production
- **Secure storage**: Use appropriate storage mechanisms for sensitive data
- **Cleanup**: Properly clean up sensitive data after use
- **Validation**: Validate all inputs and outputs for security
### Privacy Features
- **Zero-knowledge proofs**: Ensure privacy-preserving verification
- **Selective disclosure**: Support minimal necessary attribute revelation
- **Identity commitments**: Maintain privacy of identity data
- **Audit trails**: Log access to sensitive operations without exposing data
## Performance Optimization
### Bundle Size
- **Tree shaking**: Ensure all exports support tree shaking
- **Code splitting**: Split large modules into smaller chunks
- **Dependency analysis**: Monitor and optimize dependencies
- **Bundle analysis**: Regular bundle size monitoring
### Runtime Performance
- **Lazy loading**: Load modules only when needed
- **Caching**: Implement appropriate caching strategies
- **Memory management**: Prevent memory leaks in long-running operations
- **Async operations**: Use proper async patterns for non-blocking operations
## Partner SDK Requirements
### API Design
- **Consistent interfaces**: Maintain consistent API patterns
- **Type safety**: Provide comprehensive TypeScript definitions
- **Error handling**: Clear error messages and error codes
- **Documentation**: Comprehensive API documentation
### Integration Support
- **Branding**: Support for partner branding and theming
- **Callbacks**: Async operation callbacks for integration
- **Configuration**: Flexible configuration options
- **Examples**: Comprehensive integration examples
This context provides a comprehensive framework for executing the migration checklist with a testing-first approach, ensuring quality and reliability throughout the migration process.
$END$

View File

@@ -0,0 +1,146 @@
---
description: Critical rules for avoiding out-of-memory issues in tests, specifically preventing nested require() calls that cause pipeline failures
version: 1.0.0
status: active
owners:
- team: mobile-identity
- team: platform-infrastructure
lastUpdated: 2025-01-12
specId: test-memory-optimization
importanceScore: 100
importanceJustification: Prevents catastrophic pipeline failures due to out-of-memory errors caused by nested require() calls, especially with react-native modules in test environments.
contextUsageNote: If this file is used to add in-context notes, include a single italicized line stating what specific information was used from this file in sentence case.
---
# Test Memory Optimization Rules
## Critical: Never Nest require() Calls
### The Problem
Nested `require('react-native')` calls within tests cause **out-of-memory (OOM) errors** in CI/CD pipelines. This happens because:
1. **Module Resolution Loops**: Each nested require can trigger additional module resolution and initialization
2. **Memory Accumulation**: React Native modules are large and complex; nested requires multiply memory usage
3. **Test Environment Overhead**: Jest/Vitest test runners already load modules; nested requires create duplicate module instances
4. **Hermes Parser Issues**: Nested requires can trigger WASM memory issues with hermes-parser
### The Rule
**NEVER create nested `require('react-native')` calls within test files or test setup files.**
### Examples of FORBIDDEN Patterns
#### ❌ FORBIDDEN: Nested require in test files
```typescript
// BAD - This will cause OOM issues
describe('MyComponent', () => {
beforeEach(() => {
const RN = require('react-native');
const Component = require('./MyComponent');
// Component internally does: require('react-native') again
// This creates nested requires = OOM
});
});
```
#### ❌ FORBIDDEN: require() inside module that's required in tests
```typescript
// BAD - If this module is required in tests, it creates nested requires
// app/src/utils/myUtil.ts
export function myFunction() {
const RN = require('react-native'); // Nested if called from test
return RN.Platform.OS;
}
```
#### ❌ FORBIDDEN: Dynamic requires in test hooks
```typescript
// BAD - Dynamic requires in beforeEach/afterEach create nested requires
beforeEach(() => {
jest.resetModules();
const RN = require('react-native'); // First require
const service = require('@/utils/service'); // May internally require RN again
});
```
### Examples of CORRECT Patterns
#### ✅ CORRECT: Use ES6 imports at top level
```typescript
// GOOD - Single import at top level
import { Platform } from 'react-native';
describe('MyComponent', () => {
it('should work', () => {
expect(Platform.OS).toBe('ios');
});
});
```
**Key Rule**: Use `import` statements, not `require()`. React Native is already mocked in setup files (`jest.setup.js` for Jest, `tests/setup.ts` for Vitest), so imports work correctly.
## React Native Module Handling in Tests
### Jest Setup Pattern (app/jest.setup.js)
The project uses a custom require override in `jest.setup.js` to handle React Native mocks:
```javascript
// This is OK - it's in setup file, runs once
const Module = require('module');
const originalRequire = Module.prototype.require;
Module.prototype.require = function (id) {
if (id === 'react-native') {
const RN = originalRequire.apply(this, arguments);
// Add mocks if needed
return RN;
}
return originalRequire.apply(this, arguments);
};
```
**Key Point**: This override runs ONCE during test setup. Tests should NOT create additional require() calls that would trigger this override multiple times.
### Vitest Setup Pattern (packages/mobile-sdk-alpha/tests/setup.ts)
Vitest uses `vi.mock()` to mock React Native:
```typescript
// This is OK - runs once during setup
vi.mock('react-native', () => ({
Platform: { OS: 'web' },
// ... other mocks
}));
```
**Key Point**: Tests should use `import` statements, not `require()`, after mocks are set up.
## Best Practices
1. **Always use ES6 `import` statements** - Never use `require('react-native')` in test files
2. **Put all imports at the top of the file** - No dynamic imports in hooks
3. **Avoid `jest.resetModules()`** - Only use when absolutely necessary for module initialization tests
4. **Use setup file mocks** - React Native is already mocked in `jest.setup.js` (Jest) or `tests/setup.ts` (Vitest)
## Quick Checklist
Before committing test changes:
- [ ] No `require('react-native')` calls in test files (use `import` instead)
- [ ] All imports at top of file (not in hooks)
- [ ] Search for nested patterns: `grep -r "require('react-native')" app/tests/`
## Detection
**Signs of nested require issues**: CI OOM errors, test timeouts, memory spikes, "Call stack size exceeded" errors
**Fix**: Search for `require('react-native')` in tests → Replace with `import` statements
## Related Files
- `app/jest.setup.js` - Jest setup with React Native mocks
- `packages/mobile-sdk-alpha/tests/setup.ts` - Vitest setup with React Native mocks
- `app/jest.config.cjs` - Jest configuration
- `packages/mobile-sdk-alpha/vitest.config.ts` - Vitest configuration
$END$

View File

@@ -130,6 +130,20 @@ yarn types # Verify type checking
- For Noir circuits, run `nargo test -p <crate>` in each `noir/crates/*` directory.
- Tests for `@selfxyz/contracts` are currently disabled in CI and may be skipped.
- E2E tests (mobile app) - **Run automatically in CI/CD, not required locally**:
- E2E tests execute automatically in GitHub Actions on PRs and main branch
- Local E2E testing is optional (see `app/AGENTS.md` for local setup if needed)
- Commands available: `yarn workspace @selfxyz/mobile-app test:e2e:ios` / `test:e2e:android`
#### Test Memory Optimization
**CRITICAL**: Never create nested `require('react-native')` calls in tests. This causes out-of-memory (OOM) errors in CI/CD pipelines.
- Use ES6 `import` statements instead of `require()` when possible
- Avoid dynamic `require()` calls in `beforeEach`/`afterEach` hooks
- Prefer top-level imports over nested requires
- See `.cursor/rules/test-memory-optimization.mdc` for detailed guidelines
### CI Caching
Use the shared composite actions in `.github/actions` when caching dependencies in GitHub workflows. They provide consistent cache paths and keys:
@@ -151,6 +165,43 @@ Each action accepts an optional `cache-version` input (often combined with `GH_C
- Write short, imperative commit messages (e.g. `Fix address validation`).
- The pull request body should summarize the changes and mention test results.
## Workspace-Specific Instructions
Some workspaces have additional instructions in their own `AGENTS.md` files:
- `app/AGENTS.md` - Mobile app development, E2E testing, deployment
- `packages/mobile-sdk-alpha/AGENTS.md` - SDK development, testing guidelines, package validation
- `noir/AGENTS.md` - Noir circuit development
These workspace-specific files override or extend the root instructions for their respective areas.
## Troubleshooting
### Common Issues
#### Yarn Install Fails
- Ensure Node.js 22.x is installed: `nvm use`
- Clear Yarn cache: `yarn cache clean`
- Remove `node_modules` and reinstall: `rm -rf node_modules && yarn install`
#### Build Failures
- Run `yarn build:deps` in affected workspace first
- Check workspace-specific `AGENTS.md` for platform requirements
- For mobile app: ensure iOS/Android prerequisites are met (see `app/AGENTS.md`)
#### Test Failures
- Check workspace-specific test setup requirements
- For mobile app tests: ensure native modules are properly mocked
- See `.cursor/rules/test-memory-optimization.mdc` for test memory issues
#### Type Errors
- Run `yarn types` to see all type errors across workspaces
- Some packages may need to be built first: `yarn build:deps`
## Scope
These instructions apply to the entire repository unless overridden by a nested `AGENTS.md`.

View File

@@ -18,6 +18,7 @@ Before creating a PR for the mobile app:
- [ ] `yarn nice` passes (fixes linting and formatting)
- [ ] `yarn types` passes (TypeScript validation)
- [ ] `yarn test` passes (unit tests)
- [ ] No nested `require('react-native')` calls in tests (causes OOM in CI) - check with `grep -r "require('react-native')" app/tests/` and verify no nested patterns
- [ ] App builds successfully on target platforms
### Mobile-Specific Validation
@@ -25,12 +26,14 @@ Before creating a PR for the mobile app:
- [ ] Android build succeeds: `yarn android` (emulator/device)
- [ ] Web build succeeds: `yarn web`
- [ ] No sensitive data in logs (PII, credentials, tokens)
- [ ] Environment variables properly configured (check `.env` setup)
- [ ] E2E tests run in CI (not required locally - CI will run E2E tests automatically)
### AI Review Preparation
- [ ] Complex native module changes documented
- [ ] Platform-specific code paths explained
- [ ] Security-sensitive operations flagged
- [ ] Performance implications noted
- [ ] Performance implications noted (including test memory patterns if tests were modified)
## Post-PR Validation
@@ -45,8 +48,11 @@ After PR creation:
### Mobile-Specific Checks
- [ ] App launches without crashes
- [ ] Core functionality works on target platforms
- [ ] No memory leaks introduced
- [ ] No memory leaks introduced (including test memory patterns - see Test Memory Optimization section)
- [ ] Bundle size within acceptable limits
- [ ] No nested `require('react-native')` calls in tests (causes OOM in CI)
- [ ] Native modules work correctly (if native code was modified)
- [ ] Platform-specific code paths tested (iOS/Android/Web)
### Review Integration
- [ ] Address CodeRabbitAI feedback
@@ -92,4 +98,133 @@ yarn types # Verify type checking
## Running the App
- `yarn ios`
- `yarn ios` - Run on iOS simulator (builds dependencies automatically)
- `yarn android` - Run on Android emulator/device (builds dependencies automatically)
- `yarn web` - Run web version
### Development Tips
- Use `yarn build:deps` to build all workspace dependencies before running the app
- For iOS: Ensure Xcode scheme is set to "OpenPassport" (see memory)
- For Android: Ensure emulator is running or device is connected before `yarn android`
- Metro bundler starts automatically; use `yarn start` to run it separately
## E2E Testing
The app uses Maestro for end-to-end testing. **E2E tests run automatically in CI/CD pipelines - they are not required to run locally.**
### CI/CD E2E Testing
- E2E tests run automatically in GitHub Actions workflows
- iOS and Android E2E tests run on PRs and main branch
- No local setup required - CI handles all E2E test execution
### Local E2E Testing (Optional)
If you need to run E2E tests locally for debugging:
**Prerequisites:**
- Maestro CLI installed: `curl -Ls "https://get.maestro.mobile.dev" | bash`
- iOS: Simulator running or device connected
- Android: Emulator running or device connected
- App built and installed on target device/simulator
**Running Locally:**
```bash
# iOS E2E tests
yarn test:e2e:ios
# Android E2E tests
yarn test:e2e:android
# Or use the local test script (handles setup automatically)
./scripts/test-e2e-local.sh ios
./scripts/test-e2e-local.sh android
```
**E2E Test Files:**
- iOS: `tests/e2e/launch.ios.flow.yaml`
- Android: `tests/e2e/launch.android.flow.yaml`
## Environment Variables
The app uses `react-native-dotenv` for environment configuration.
### Setup
- Create `.env` file in `app/` directory (see `.env.example` if available)
- Environment variables are loaded via `@env` import
- For secrets: Use `.env.secrets` (gitignored) for local development
- In CI: Environment variables are set in workflow files
### Common Environment Variables
- `GOOGLE_SIGNIN_ANDROID_CLIENT_ID` - Google Sign-In configuration
- Various API endpoints and keys (check `app/env.ts` for full list)
### Testing with Environment Variables
- Tests use mocked environment variables (see `jest.setup.js`)
- E2E tests use actual environment configuration
- Never commit `.env.secrets` or sensitive values
## Deployment
### Mobile Deployment
The app uses Fastlane for iOS and Android deployment.
### Deployment Commands
```bash
# Deploy both platforms (requires confirmation)
yarn mobile-deploy
# Deploy iOS only
yarn mobile-deploy:ios
# Deploy Android only
yarn mobile-deploy:android
# Force local deployment (for testing deployment scripts)
yarn mobile-local-deploy
```
### Deployment Prerequisites
- See `app/docs/MOBILE_DEPLOYMENT.md` for detailed deployment guide
- Required secrets configured in CI/CD or `.env.secrets` for local
- iOS: App Store Connect API keys, certificates, provisioning profiles
- Android: Play Store service account, keystore
### Deployment Checklist
- [ ] Version bumped in `package.json` and `app.json`
- [ ] Changelog updated
- [ ] All unit tests pass (`yarn test`)
- [ ] Build succeeds for target platform
- [ ] Required secrets/environment variables configured
- [ ] Fastlane configuration verified
- [ ] CI E2E tests pass (automatically run in CI, no local action needed)
## Test Memory Optimization
**CRITICAL**: Never create nested `require('react-native')` calls in tests. This causes out-of-memory (OOM) errors in CI/CD pipelines.
### Quick Check
Before committing, verify no nested requires:
```bash
# Check for require('react-native') in test files
grep -r "require('react-native')" app/tests/
# Review results - ensure no nested patterns (require inside beforeEach/afterEach or inside modules that are required in tests)
```
### Best Practices
- Use ES6 `import` statements instead of `require()` when possible
- Avoid dynamic `require()` calls in `beforeEach`/`afterEach` hooks
- Prefer top-level imports over nested requires
- React Native is already mocked in `jest.setup.js` - use imports in test files
### Detailed Guidelines
See `.cursor/rules/test-memory-optimization.mdc` for comprehensive guidelines, examples, and anti-patterns.

View File

@@ -75,11 +75,13 @@ Before creating a PR for the mobile-sdk-alpha package:
### SDK-Specific Validation
- [ ] Exports are properly configured
- [ ] Package conditions are valid
- [ ] Exports are properly configured (`yarn validate:exports`)
- [ ] Package conditions are valid (`yarn validate:pkg`)
- [ ] No breaking changes to public API (or properly documented)
- [ ] Migration guide updated (if applicable)
- [ ] Integration tests pass
- [ ] SDK integration with main app verified (if API changed)
- [ ] Cross-platform compatibility verified (React Native + Web)
### AI Review Preparation
@@ -102,9 +104,12 @@ After PR creation:
### SDK-Specific Checks
- [ ] Package exports validation passes
- [ ] Integration with main app still works
- [ ] Integration with main app still works (tested in `@selfxyz/mobile-app`)
- [ ] No circular dependencies introduced
- [ ] Bundle size impact acceptable
- [ ] No nested `require('react-native')` calls in tests (causes OOM in CI)
- [ ] Cross-platform compatibility maintained (React Native + Web)
- [ ] Type definitions are complete and accurate
### Review Integration
@@ -144,6 +149,28 @@ yarn build # Confirm build still works
- Prettier is used for code formatting
- The `yarn nice` command is the recommended way to fix code quality issues
- Use the root Prettier and EditorConfig settings for consistency
- Uses Vitest for testing (not Jest) - see `tests/setup.ts` for configuration
- React Native is mocked for web compatibility in tests
## Integration Testing
### Testing SDK Integration with Main App
When making changes to the SDK API, verify integration:
```bash
# From app directory
cd ../../app
yarn build:deps # Ensures latest SDK is built
yarn test # Run app tests that use SDK
```
### Cross-Platform Considerations
- SDK must work in both React Native and Web environments
- Use platform detection when needed: `Platform.OS === 'web'`
- Test both environments when adding platform-specific code
- Vitest tests run in Node.js environment (mocked React Native)
## Testing Guidelines
@@ -184,3 +211,44 @@ describe('Real SDK Integration', () => {
```
**⚠️ CRITICAL: Never use real user PII in tests. Use only synthetic, anonymized, or approved test vectors.**
## Test Memory Optimization
**CRITICAL**: Never create nested `require('react-native')` calls in tests. This causes out-of-memory (OOM) errors in CI/CD pipelines.
### Key Rules
- Use ES6 `import` statements instead of `require()` when possible
- Avoid dynamic `require()` calls in `beforeEach`/`afterEach` hooks
- Prefer top-level imports over nested requires
- This package uses Vitest (not Jest), but the same principles apply
- React Native is already mocked in `tests/setup.ts` using `vi.mock()` - use imports in test files
### Example Patterns
#### ✅ CORRECT: Use ES6 imports
```ts
// GOOD - Single import at top level
import { Platform } from 'react-native';
describe('MyComponent', () => {
it('should work', () => {
expect(Platform.OS).toBe('web');
});
});
```
#### ❌ FORBIDDEN: Nested requires
```ts
// BAD - This will cause OOM issues
describe('MyComponent', () => {
beforeEach(() => {
const RN = require('react-native'); // First require
const Component = require('./MyComponent'); // May internally require RN again = nested = OOM
});
});
```
See `.cursor/rules/test-memory-optimization.mdc` for detailed guidelines and more examples.

View File

@@ -251,19 +251,11 @@ The SDK surfaces typed errors for clearer diagnostics:
All errors extend `SdkError`, which includes a `code`, `category`, and `retryable` flag.
## Migration plan
Track remaining tasks in [MIGRATION_PLAN.md](./docs/MIGRATION_PLAN.md) and see completed work in [MIGRATION_COMPLETED.md](./docs/MIGRATION_COMPLETED.md).
## Architecture
Migration and architecture prompts live in [PROMPTS.md](./docs/PROMPTS.md).
## Testing
**IMPORTANT: Do NOT mock this package in tests!**
The purpose of the mobile-sdk-alpha migration is to test the REAL package methods, not mocked versions. When integrating this package into your application:
Use the REAL package methods, not mocked versions. When integrating this package into your application:
### ✅ DO: Use Real Package Methods (PII-safe)

View File

@@ -1,39 +0,0 @@
# Completed Mobile SDK Migration Tasks
This log captures whats already landed. Everything still in flight lives in [MIGRATION_PLAN.md](./MIGRATION_PLAN.md).
## Migration
### 1. MRZ processing helpers
- MRZ utilities are in place and reexported through the SDK.
- The code now lives under `src/mrz/` and `src/qr/`.
- `notImplemented` guards unfinished paths.
- Type aliases keep things lean.
### 2. Validation module
- Stateless document checks were ported and covered by unit tests.
### 3. Integrate SDK into `/app`
- The `app` workspace consumes `@selfxyz/mobile-sdk-alpha`.
- Screens are wired to SDK processing and validation helpers.
## Architecture
### 1. Modular feature directories
- New capabilities sit in dedicated folders and are reexported via `src/index.ts`.
- Error paths use `notImplemented`.
- Type aliases replaced empty interfaces.
### 2. Bridge layer for native events
- `NativeModules` and `NativeEventEmitter` are wrapped in a shared adapter.
- Platforms share a unified event interface.
### 3. Exception classes
- Added typed errors (`InitError`, `LivenessError`, `NfcParseError`, `MrzParseError`).
- The SDK now surfaces these instead of generic `Error`.

View File

@@ -1,92 +0,0 @@
# Mobile SDK Migration Plan
This is the running todo list for the mobile SDK. When you wrap up a task, move it to [MIGRATION_COMPLETED.md](./MIGRATION_COMPLETED.md) so we keep a record.
## Migration tasks
### 3. Bring the SDK into `/app`
- [ ] Swap the MRZ modules for the SDKs adapters
- [ ] Make sure the app still builds and the unit tests pass
### 4. Generate proof inputs
- [ ] Port helpers that prep register and disclose inputs for the TEE
### 5. Crypto adapters
- [ ] Pick WebCrypto or noble at runtime
- [ ] Crosscheck outputs between the two
- [ ] Detect WebCrypto support when running on React Native/Hermes
- [ ] Guarantee random bytes come from a CSPRNG
- [ ] Compare secrets with a timing-safe helper
### 6. TEE session management
- [ ] Wrap WebSockets so we can handle aborts, timeouts, and progress events
### 7. Attestation verification
- [ ] Check PCR0 and extract the public key
- [ ] Add a lightweight certificate chain check
### 8. Protocol synchronization
- [ ] Fetch protocol trees with pagination and a short TTL cache
- [ ] Verify computed roots against server data
- [ ] Ratelimit with exponential backoff and jitter
- [ ] Cap memory use and honor `RetryAfter` headers
### 9. React Native providers and hooks
- [ ] Decouple context providers and hooks from adapter implementations
- [ ] Move `SelfClientProvider` and its adapters into the SDK, exposing adapter props
- [ ] Accept adapter instances via props to avoid tight coupling
- [ ] Map provider boundaries to the architecture tasks for crypto, sessions, attestation, protocol sync, and artifacts
### 10. Batteriesincluded components
- [ ] Ship minimal components (e.g., scanners, buttons) that compose existing hooks and providers
- [ ] Expose configuration props for custom adapters while keeping sensible defaults
- [ ] Link component usage to architecture guidelines and adapter tasks
### 11. Sample applications
- [ ] React Native and web demos showcasing core flows
- [ ] iOS `OpenPassport` URL scheme
### 12. InSDK lightweight demo
- [ ] Embed a small React Native demo inside the SDK with theming hooks
- [ ] Provide build and run instructions
## Architecture tasks
### 4. Manage the SDK lifecycle
- [ ] Turn `createSelfClient` into a class
- [ ] Add `initialize()` and `deinitialize()` hooks
- [ ] Keep config on the instance instead of globals
### 5. Package targets
- [ ] Keep the React Native build first
- [ ] Add entry points for web builds
- [ ] Lay groundwork for future targets like Capacitor or Cordova
### 6. Dogfood in `/app`
- [ ] Validate real flows
- [ ] Replace MRZ modules with SDK adapters
### 7. Android demo app
- [ ] Ship a minimal React Native Android project
- [ ] Demonstrate MRZ → proof generation flow
- [ ] Provide build and run instructions
## Consolidation toward `@selfxyz/common`
- [ ] Pull document catalog helpers and keychain wrappers out of the app and into `@selfxyz/common`
- [ ] Share analytics and auth adapters through a common or dedicated package
- [ ] Re-export storage types so other apps can reuse them without the mobile app context

View File

@@ -1,110 +0,0 @@
# Task Prompts
This file offers quick pointers for anyone picking up work from the [migration plan](./MIGRATION_PLAN.md). Use it to get oriented, then dive into the code.
## Pre-flight checks
Run these before opening a PR:
```bash
yarn workspace @selfxyz/mobile-sdk-alpha nice
yarn workspace @selfxyz/mobile-sdk-alpha types
yarn workspace @selfxyz/mobile-sdk-alpha test
yarn workspace @selfxyz/mobile-sdk-alpha build
yarn lint
yarn build
```
## Migration tasks
### 3. Integrate SDK into `/app`
- In `app/src/providers/passportDataProvider.tsx` replace local MRZ helpers with `extractMRZInfo` from `@selfxyz/mobile-sdk-alpha/mrz` and `parseNFCResponse` from `@selfxyz/mobile-sdk-alpha/nfc`.
- Update `app/src/components/native/PassportCamera.tsx` and `app/src/utils/nfcScanner.ts` to use the SDK exports.
- Run `yarn workspace @selfxyz/mobile-app build && yarn workspace @selfxyz/mobile-app test`.
### 4. Proof input generation
- Move `generateTEEInputsRegister` and `generateTEEInputsDisclose` from `app/src/utils/proving/provingInputs.ts` into new files under `packages/mobile-sdk-alpha/src/proving/register.ts` and `packages/mobile-sdk-alpha/src/proving/disclose.ts`.
- Replace `useProtocolStore` with a `getTree(document, kind)` callback so helpers are stateless.
- Add tests in `packages/mobile-sdk-alpha/tests/proving.{register,disclose}.test.ts`.
### 5. Crypto adapters
- Create `src/adapters/crypto/index.ts` exporting a `CryptoAdapter` interface with `getRandomValues`, `digest` and `timingSafeEqual`.
- Implement `src/adapters/crypto/webcrypto.ts` and `src/adapters/crypto/noble.ts` and wire runtime detection in `src/adapters/crypto/index.ts`.
- Add parity tests in `tests/crypto.test.ts` ensuring both adapters produce identical results.
### 6. TEE session management
- Implement `WsAdapter` in `src/adapters/ws/websocket.ts` wrapping `WebSocket` with abort, timeout, and progress callbacks.
- Export the adapter through `src/adapters/index.ts`.
- Add tests under `tests/ws.test.ts` using a mocked server in `tests/ws.server.ts`.
### 7. Attestation verification
- Port `parseCertificateSimple` and PCR0 utilities from `common/src/utils/certificate_parsing/` into `src/attestation/verify.ts`.
- Expose `verifyAttestation(cert: ArrayBuffer, quote: ArrayBuffer)` that returns the public key.
- Cover the verifier with unit tests in `tests/attestation.test.ts`.
### 8. Protocol synchronization
- Add `src/protocol/sync.ts` with `fetchProtocolTrees(fetchPage, cache)` to paginate and cache trees.
- Verify roots against `@selfxyz/common/utils/proving` and honor `Retry-After` headers.
- Write tests in `tests/protocol.test.ts` with a fake server.
### 9. React Native providers and hooks
- Move `app/src/providers/selfClientProvider.tsx` into `src/context.tsx` and expose a `SelfClientProvider` that accepts adapter instances (`crypto`, `ws`, `storage`, `logger`).
- Add hooks like `useSelfClient` and `useDocuments` in `src/hooks/`.
- Remove the wrapper from the app and import the provider directly from the SDK.
### 10. Batteries-included components
- Create `src/components/Scanner.tsx` using `useScanner` and `SelfClientProvider`.
- Add `src/components/ScanButton.tsx` that triggers MRZ and NFC flows with optional adapter props.
- Document usage in `docs/components.md`.
### 11. Sample applications
- Scaffold `examples/react-native/` and `examples/web/` showcasing scan → proof flows.
- Include iOS `OpenPassport` URL scheme setup in `examples/react-native/README.md`.
- Ensure both samples use the published SDK rather than local files.
### 12. In-SDK lightweight demo
- Add `demo/` inside the package with `App.tsx` using `SelfClientProvider` and theming hooks.
- Provide run instructions in `demo/README.md` for `yarn demo ios` and `yarn demo android`.
- Wire demo entry in `package.json` scripts.
## Architecture tasks
### 4. SDK lifecycle management
- Refactor `src/client.ts` so `createSelfClient` becomes `class SelfClient` with `initialize()` and `deinitialize()` methods.
- Persist configuration on the instance rather than module globals.
- Update exports in `src/index.ts`.
### 5. Package targets
- Add a `"./web"` entry to `package.json#exports` pointing to `dist/web/index.js` while keeping React Native as the default.
- Update `tsup.config.ts` to produce a web build target.
- Note possible future targets (Capacitor, Cordova) in comments.
### 6. Dogfood in `/app`
- Update `app/src/utils/proving/provingMachine.ts` and screens in `app/src/screens/prove/` to consume SDK methods.
- Remove deprecated MRZ utilities from the app and import from `@selfxyz/mobile-sdk-alpha`.
- Confirm flows via `yarn workspace @selfxyz/mobile-app test`.
### 7. Android demo app
- Create `examples/android-demo/` with React Native CLI, wiring scanning and proof generation through the SDK.
- Provide setup instructions in `examples/android-demo/README.md`.
- Link the demo in the main `README.md`.
## Consolidation toward `@selfxyz/common`
- Move `calculateContentHash` and related catalog helpers from `app/src/providers/passportDataProvider.tsx` to `common/src/utils/documents/` and re-export via `@selfxyz/common`.
- Pull keychain wrappers like `storeDocument` into `common/src/utils/storage/passport.ts`.
- Publish shared analytics/auth adapters (currently in `app/src/utils/analytics.ts` and `app/src/providers/authProvider.tsx`) through a new package and re-export types from `@selfxyz/common`.