Native KYC SDK
Runs identity verification natively, inside your mobile app. The Web KYC SDK's two modes are preserved at the core; native adds NFC, device integrity and liveness modules on top.
| Platform | Package |
|---|---|
| Android | com.lunixi.kyc — Gradle modules |
| iOS | LunixiKyc — Swift Package |
Two modes
val kyc = LunixiKyc(
environment = env,
config = LunixiKycConfig(theme = MERCHANT, locale = "tr"),
)
kyc.start(activity = this, handoffToken = token, listener = this)The SDK renders the whole guided flow. iOS has an exact counterpart under the same name (LunixiKyc).
The pre-built UI is a thin layer over the core. Step derivation, signing, anti-replay and the verdict all live in the core — moving from Mode 1 to Mode 2 changes no behaviour, only who draws the screen.
The handoff token — your merchant token never reaches the device
The merchant bearer token is not given to the SDK. The only thing you pass in is a short-lived handoff token, which the SDK exchanges for a signed bootstrap.
So even if your app is compromised, the attacker does not hold your merchant credential — only a per-session handoff token that will expire.
The client does not author the verdict
There is no onVerified callback — deliberately. The terminal callback is onFinished, and it carries the status from the server (via watchStatus). The client cannot produce a verification outcome; it only carries one.
Even a fully compromised device cannot fake a verification, because it is not the thing that writes the outcome.
The headless client surface
| Method | What it does |
|---|---|
start() | Starts the session, returns a KycSessionSnapshot |
steps() | The step list derived by the server |
getCapturePolicy() | The capture policy (which document, what quality) |
setJurisdiction(...) · setPrimaryDocumentType(...) | Jurisdiction and document type |
submitProfileData(fields) | Profile fields |
submitConsent(consent) | Consent record |
uploadDocument(upload) | Document upload |
uploadLiveness(upload) | Liveness evidence |
submitNfcEvidence(evidence) | Evidence read from the NFC chip |
submitVerification() | Submits for verification |
requestManualReview() | Requests human review |
watchStatus() | Terminal status stream (Flow<KycTerminalStatus>) |
refreshSession() · getSession() | Refreshes the session / current snapshot |
The modules ship separately
Each capability is its own library; you link only what you use.
| Module | What it does |
|---|---|
KycCore | The headless core — session, signing, step derivation |
KycUI | The pre-built screens |
DocumentCapture | Document capture |
Nfc | Reading chipped identity documents |
Liveness | Liveness |
FaceQuality | Face-quality measurement |
DeviceIntegrity | Device integrity / attestation |
KycLiveVideo | Video verification (only pulled in if you link it) |
Video verification is kept separate. The headless core, capture and UI targets never pull it in — you take the live-video dependency only by linking that module explicitly. That keeps an app which does not use video from carrying its size and its permission surface.
How it relates to the Web KYC SDK
Same flow, same steps, same server contract. What native adds:
| Web | Native | |
|---|---|---|
| NFC chip reading | ✗ | ✓ |
| Device attestation | ✗ | ✓ |
| Hardware-bound signing | ✗ | ✓ |
| Capture-quality control | limited | FaceQuality + DocumentCapture |
For the browser side: Web KYC SDK
Related
- Mobile SDK Overview — the bridge/native split and the packages
- Mobile Threat SDK — transaction-time threat telemetry
- Web KYC SDK — the browser counterpart