* add ios swift handlers
* Add lifecycle completion and optional relay listener
* agent feedback
* save wip
* fix compiling
* finalize feedback
* agent feedback
* fix ci
* udpate specs
* feat: implement React Native adapters for authentication, documents, and networking
- Added new adapters for authentication, document management, and network communication tailored for React Native.
- Introduced `createAuthAdapter`, `createDocumentsAdapter`, and `createNetworkAdapter` to streamline integration with React Native's capabilities.
- Updated `SelfClientProvider` to utilize the new adapter factory for improved modularity and maintainability.
- Enhanced package dependencies to include necessary libraries for secure storage and hashing.
This update enhances the SDK's functionality and prepares it for better cross-platform compatibility.
* refactor: update specs to streamline documentation and remove obsolete entries
- Removed the "Keep / Modify / Delete" section from the specs to simplify the document structure.
- Updated the remaining specifications to reflect the current architecture and integration paths, including the introduction of the new `SPEC-RN-SDK.md` for the `<SelfVerification />` RN WebView wrapper component.
- This change enhances clarity and aligns the documentation with recent architectural decisions.
* prettier
* update gitignore to include swift build paths
* update gems
* address pr feedback and pipeline errors
* agent feedback. also include follow up work items
* add spec guide rules
* add markdown files to prettier formatting and update
* add status line update spec guide
* add new specs
* formatting
* format all markdown files
* more formatting
* consolidate into overview
* update spec and template guidelines
* refactor specs
* save wip
* move status up
* feat: add biometrics and camera bridge adapters
Create biometrics adapter (authenticate, isAvailable, getBiometryType) and camera adapter (scanMRZ, isAvailable) matching the native KMP handler response shapes. Wire both into webview-app SelfClientProvider. Includes 6 new tests (50 total, all passing).
* feat: add web fallback adapters and wire in SelfClientProvider
- Create IndexedDB documents adapter and console/fetch
analytics adapter in webview-bridge (documents-web.ts,
analytics-web.ts) per Person 1 spec Section 4
- Create equivalent browser adapters in mobile-sdk-alpha
per Person 4 Chunk 4F (documents, crypto, analytics,
haptic)
- Wire web fallbacks into SelfClientProvider — documents
and analytics no longer cross the bridge
- 32 new tests across both packages, all passing
- fake-indexeddb added as devDep to both packages
* feat: remove 4 Android web-fallback handlers
- Delete DocumentsBridgeHandler (146 LOC)
- Delete CryptoBridgeHandler (177 LOC)
- Delete AnalyticsBridgeHandler (94 LOC)
- Delete HapticBridgeHandler (94 LOC)
- Remove registrations from SelfVerificationActivity
- Android now registers 5 handlers: NFC, Camera,
Biometrics, SecureStorage, Lifecycle
- Documents, crypto, analytics, and haptic are now
handled by web fallback adapters in the WebView
* style: align DocumentsBridgeHandler param extraction
Standardize iOS DocumentsBridgeHandler to use
?.jsonPrimitive?.content for parameter extraction,
matching the convention used by all other iOS handlers.
* feat: add MiniPay sample app
Create Compose Multiplatform sample app showing how
third-party integrators embed Self identity verification
via SelfSdk.launch(). Two native screens (Home, Result);
all verification logic runs in the SDK's WebView.
Shared Kotlin (commonMain):
- App.kt: NavHost with home/result navigation
- MainViewModel.kt: SDK launch + callback routing
- HomeScreen.kt: status card + "Verify Identity" button
- ResultScreen.kt: success/failure with error mapping
- Theme.kt: MiniPay-style Material 3 colors
Android:
- MainApplication.kt: SelfSdk.configure() in onCreate
- MainActivity.kt: passes SDK instance to Compose
- AndroidManifest.xml: NFC, Camera, Biometric, Internet
permissions + NFC TECH_DISCOVERED intent filter
- res/xml/nfc_tech_filter.xml: IsoDep for passport NFC
iOS Kotlin:
- MainViewController.kt: ComposeUIViewController entry
iOS Swift (iosApp/):
- iOSApp.swift: provider registration with
SdkProviderRegistry (same pattern as kmp-test-app)
- ContentView.swift: UIViewControllerRepresentable
- Xcode project with NFC/Camera entitlements
Spec deviation — single-module vs two-module:
The spec directory diagram (lines 88-120) shows a
separate androidApp/ module, but the spec's own build
config (lines 384-447) has composeApp using the
androidApplication plugin — meaning composeApp IS the
Android app. These contradict: you cannot have two
androidApplication modules. The existing kmp-test-app
uses the same single composeApp pattern. We follow the
build config + test app precedent.
Build verified on all targets:
- compileDebugKotlinAndroid: BUILD SUCCESSFUL
- compileKotlinIosArm64: BUILD SUCCESSFUL
- compileKotlinIosSimulatorArm64: BUILD SUCCESSFUL
* style: Rename webAnalyticsAdapter to consoleAnalyticsAdapter
Align web analytics adapter naming with updated spec
(specs/person1-webview/SPEC.md section 4c).
- Rename webAnalyticsAdapter → consoleAnalyticsAdapter
- Rename WebAnalyticsOptions → ConsoleAnalyticsOptions
- Update barrel export in adapters/index.ts
- Update import in SelfClientProvider.tsx
- Update all references in analytics-web.test.ts
The new name better describes the adapter's purpose: a
console-logging (+ optional HTTP endpoint) fallback for
environments without a native bridge.
Verified: webview-bridge build clean, 63/63 tests pass,
webview-app type-check clean.
* refactor: Align Person 4 adapters with updated spec
Rename haptic + fix crypto algo normalization per updated
specs/person4-sdk-core/SPEC.md (Chunk 4F).
Haptic:
- createNoOpHapticFeedback → createNoOpHapticAdapter
- Updated barrel export, re-export, and test references
Crypto:
- Replace static ALGO_MAP lookup with regex normalization:
algo.toUpperCase().replace(/^SHA(\d)/, 'SHA-$1')
- Handles all variants: sha256, SHA256, sha-256, SHA-256
- Add tests for already-hyphenated and uppercase inputs
Verified: 20/20 browser adapter tests pass, tsc clean.
* fix: resolve 7 Android device testing bugs in SDK + MiniPay
Fix issues found during physical device testing (Pixel 8
Pro) of the MiniPay sample app end-to-end flow.
SDK fixes (kmp-sdk):
- Use activityResultRegistry.register() instead of
activity.registerForActivityResult() to avoid
IllegalStateException when registering after onStart
- Replace FragmentActivity with ComponentActivity
(AndroidX 1.9.x changed the class hierarchy)
- Change SelfVerificationActivity theme to
Theme.AppCompat.NoActionBar (AppCompatActivity
requires an AppCompat theme)
- Rewrite AndroidWebViewHost to use WebViewAssetLoader
with custom PathHandler, serving bundled Vite assets
under https://appassets.androidplatform.net/ to fix
CORS, history.replaceState, and asset path resolution
- Add runtime permission requests for Camera + NFC in
SelfVerificationActivity.onCreate()
MiniPay fixes (kmp-minipay-sample):
- Create expect/actual platformLaunch to thread Android
Activity to SDK without leaking platform types into
commonMain
- Set debug = false to load bundled assets instead of
emulator dev server URL
Tested on Pixel 8 Pro: app launches, verification
WebView opens, camera scans for MRZ. Full passport
scan untested (no document available).
* feat: implement @selfxyz/rn-sdk React Native SDK
Thin <SelfVerification /> component wrapping react-native-webview
that embeds Self's identity verification flow. Bridges NFC, camera,
biometrics, keychain, and lifecycle to native via MessageRouter.
- MessageRouter: routes WebView bridge messages to domain handlers
- 5 handlers: lifecycle, biometrics, secureStorage, nfc, camera
- Platform.select asset loading (Android file://, iOS RNFS bundle)
- 59 unit tests, build + typecheck clean
- ReactNativeWebView transport detection added to webview-bridge
* fix: Remove dead code and persist verification state
Claude identified some gaps in the spec. Fixed to match:
- Delete unused onVerificationSuccess/Failure/Cancelled methods
from MainViewModel (sdkCallback handles all cases)
- Add expect/actual AppStorage (SharedPreferences / NSUserDefaults)
to persist HomeState across app restarts
- Update homeState eagerly in sdkCallback.onSuccess() so Android
system back button shows correct state on HomeScreen
* refactor: migrate webview-app from Tamagui to @selfxyz/euclid-web
Replace Tamagui + react-native-web UI framework with Self's
official euclid-web component library across all 10 screens.
Simplify Vite config, remove RN aliases, and fix country flag
emoji rendering with proper ISO 3166-1 alpha-3 to alpha-2
conversion.
- Remove tamagui, @tamagui/config, react-native-web deps
- Add @selfxyz/euclid-web and @selfxyz/euclid-core
- Rewrite 6 screens as euclid direct replacements
- Compose 4 screens from euclid primitives
- Fix fonts.css for euclid font family names
- Add shared countryFlags utility (alpha-3 → alpha-2 lookup)
- Clean up tsconfig.json and stale .tamagui cache
* fix pipeline
* formatting
* fix tests
* fix type error
* address feedback
* fix formatting
* update specs and create handoff doc for new pull request
---------
Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>
Co-authored-by: Tranquil-Flow <tranquil_flow@protonmail.com>
Monorepo for Self.
Self is an identity wallet that lets users generate privacy-preserving proofs from government-issued IDs such as passports, ID cards, and Aadhaar cards. By scanning the NFC chip in their ID document, users can prove their validity while only revealing specific attributes such as age, nationality or simply humanity. Under the hood, Self uses zk-SNARKs to make sure personal data is redacted, but the document is verified.
Use cases unlocked include:
- Airdrop protection: Protect a token distribution from bots
- Social media: Add humanity checks to user's profiles
- Quadratic funding: Prevent farmers from skewing rewards
- Wallet recovery: Safeguard assets using IDs as recovery sources
- Compliance: Check a user is not part of a sanctioned entity list
Currently, Self supports electronic passports, biometric ID cards following the ICAO standards, and Aadhaar cards. Support for new identity documents is on the way!
Checkout the docs to add Self to your project.
FAQ
Is my document supported?
Passports: Biometric passports have the biometric passport logo on their front cover.
Aadhaar: Indian Aadhaar cards are supported for privacy-preserving identity verification. Use the mAadhaar app to generate a QR code and import it into Self.
Coverage: Checkout our coverage map here to see supported documents and countries.
What can I request/prove with Self?
When a country issues a passport or a compliant ID document, they sign datagroups that include at least:
- First and last name
- Nationality
- Date of birth
- Gender
- Expiration date
- Passport number
- Photo
Applications are able to request each of those data points.
What is the signature algorithm ?
Countries use different signature algorithms to sign ID documents. Check out our coverage map to see which.
Where can I find the countries' public keys ?
The main list of public keys can be downloaded from the ICAO website. We use multiple lists published by different ICAO members.
What's the ICAO ?
The International Civil Aviation Organization (ICAO) is a specialized agency of the United Nations. Among other things, they establish the specifications for passports, that have to be followed by all countries. The full passport specs are available here.
Project Ideas
- Combine Self with other identification mechanisms as in Vitalik's pluralistic identity regime.
- Help adding support for other identity documents to Self, such as Japan's my number cards or Taiwan DID.
- Build a social network/anonymous message board for people from one specific country.
- Create a sybil-resistance tool to protect social networks against spambots.
- Build an airdrop farming protection tool.
- Allow DeFi protocols to check if the nationality of a user is included in a set of forbidden states.
- Gate an adult content website to a specific age.
- Create a petition system or a survey portal.
- Passport Wallet: use active authentication to build a wallet, a multisig or a recovery module using passport signatures
We provide bounties for new and interesting applications using Self.
Development Setup
This project requires Node.js 22.x. Use the included .nvmrc to match the version.
Run yarn install to bootstrap dependencies and husky hooks.
Gitleaks will scan staged changes on each commit via yarn gitleaks.
Development Documentation
Note: We do not accept text-only pull request changes. While we appreciate the feedback, we will not merge external pull requests that only modify markdown files or code comments (e.g., typo fixes in documentation or comments). Pull requests must include functional code changes.
For detailed development patterns and conventions, see:
- Development Patterns - React Native architecture, navigation, state management, and code organization
- Testing Guide - Jest configuration, mock patterns, testing strategies, and E2E testing
- SDK Specs - Architecture specs, implementation guides, and wave plan for the SDK refactor (WebView engine + native shells)
These guides provide comprehensive context for AI-assisted development with ChatGPT Codex, Cursor, and CodeRabbit AI.
Contributing
We are actively looking for contributors. Please check the open issues if you don't know where to start! We offer bounties for significant contributions.
Important: Please read and follow the guidelines in contribute.md when opening your pull request.
Contact us
- Discord for technical support or reporting a bug.
- Telegram's Self builder channel for technical questions about the sdk implementation.
- Telegram's Self public group for general questions and updates.
Thanks Rémi, Florent, Ayman, Justin, Seshanth, Nico and all other contributors for building Self.
Thanks Aayush, Vivek, Andy and Vitalik for contributing ideas and inspiring us to build this technology, and PSE for supporting the initial work through grants!