kyvshield_lite 0.0.3 copy "kyvshield_lite: ^0.0.3" to clipboard
kyvshield_lite: ^0.0.3 copied to clipboard

KyvShield KYC SDK — WebView wrapper. Same public API as the native SDK, powered by the KyvShield Web SDK loaded from the API server.

kyvshield_lite #

KyvShield Lite — Flutter KYC SDK powered by WebView. Same API as the native kyvshield SDK, zero native ML dependencies.

pub package

Ideal for MVPs and cross-platform apps that want identity verification without heavy native camera/ML packages.

How it works #

  1. Kyvshield.initKyc() opens a full-screen WebView.
  2. The WebView loads the KyvShield Web SDK from your API server.
  3. The entire KYC flow runs inside the WebView (camera, liveness, OCR, face match).
  4. The result is sent back to Flutter via a JS bridge and parsed into typed Dart objects.

Installation #

dependencies:
  kyvshield_lite: ^0.0.3

Full Example #

All possible enum values listed. Code is copy-paste ready.

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:kyvshield_lite/kyvshield_lite.dart';

// ── Possible values ───────────────────────────────────────────────────
// CaptureStep        : selfie, recto, verso
// ChallengeMode      : minimal, standard, strict
// SelfieDisplayMode  : standard, compact, immersive, neonHud
// DocumentDisplayMode: standard, compact, immersive, neonHud
// ChallengeAudioRepeat: once, twice, thrice
// Brightness         : light, dark

// ── Fetch available documents from API ────────────────────────────────
// See https://kyvshield.innolink.sn/developer for full API docs

final res = await http.get(
  Uri.parse('https://kyvshield.innolink.sn/api/v1/documents'),
  headers: {'X-API-Key': 'YOUR_API_KEY'},
);
final docs = (jsonDecode(res.body)['documents'] as List)
    .map((d) => KyvshieldDocument.fromJson(d))
    .toList();
final selectedDoc = docs.first; // or let user pick

// ── Request camera permission ─────────────────────────────────────────

final granted = await Kyvshield.requestCameraPermission();
if (!granted) {
  final denied = await Kyvshield.isCameraPermissionPermanentlyDenied();
  if (denied) await Kyvshield.openSettings();
  return;
}

// ── Start KYC ─────────────────────────────────────────────────────────

final result = await Kyvshield.initKyc(
  context: context,
  config: KyvshieldConfig(
    baseUrl: 'https://kyvshield.innolink.sn',
    apiKey: 'YOUR_API_KEY',
    enableLog: true,
    theme: KyvshieldThemeConfig(
      primaryColor: Color(0xFFEF8352),
      brightness: Brightness.light,
    ),
  ),
  flow: KyvshieldFlowConfig(
    steps: [CaptureStep.selfie, CaptureStep.recto, CaptureStep.verso],
    language: 'fr',
    showIntroPage: true,
    showInstructionPages: true,
    showResultPage: true,
    showSuccessPerStep: true,
    selfieDisplayMode: SelfieDisplayMode.standard,
    documentDisplayMode: DocumentDisplayMode.standard,
    challengeMode: ChallengeMode.minimal,
    requireFaceMatch: true,
    playChallengeAudio: true,
    maxChallengeAudioPlay: ChallengeAudioRepeat.once,
    pauseBetweenAudioPlay: Duration(seconds: 1),
    stepChallengeModes: {
      CaptureStep.selfie: ChallengeMode.minimal,
      CaptureStep.recto: ChallengeMode.standard,
      CaptureStep.verso: ChallengeMode.minimal,
    },
    target: selectedDoc,
    kycIdentifier: 'user-12345',
  ),
);

// ── Start KYC ─────────────────────────────────────────────────────────

final result = await Kyvshield.initKyc(
  context: context,
  config: config,
  flow: flow,
);

// ── Handle result ─────────────────────────────────────────────────────

print('Success: ${result.success}');
print('Status: ${result.overallStatus}');   // pass, review, reject, error
print('Session: ${result.sessionId}');

// Selfie
if (result.selfieResult != null) {
  print('Live: ${result.selfieResult!.isLive}');
  print('Image: ${result.selfieResult!.capturedImage?.length} bytes');
}

// Recto
if (result.rectoResult != null) {
  print('Recto score: ${result.rectoResult!.score}');
  print('Aligned doc: ${result.rectoResult!.alignedDocument?.length} bytes');
  print('Photos: ${result.rectoResult!.extractedPhotos.length}');
  print('Fields: ${result.rectoResult!.extraction?.fields.length}');
  // Face match (attached to recto)
  if (result.rectoResult!.faceVerification != null) {
    print('Face match: ${result.rectoResult!.faceVerification!.isMatch}');
    print('Similarity: ${result.rectoResult!.faceVerification!.similarityScore}');
  }
}

// Verso
if (result.versoResult != null) {
  print('Verso score: ${result.versoResult!.score}');
  print('Fields: ${result.versoResult!.extraction?.fields.length}');
}

// Extracted data (searches recto + verso)
print('Nom: ${result.getExtractedValue("nom")}');
print('NIN: ${result.getExtractedValue("nin")}');

// Loop all fields sorted by priority
for (final field in result.rectoResult?.extraction?.sortedFields ?? []) {
  print('${field.label}: ${field.stringValue}');
}

Configuration #

KyvshieldConfig #

KyvshieldConfig(
  baseUrl: 'https://kyvshield.innolink.sn',  // API server URL
  apiKey: 'your-api-key',                     // API key from dashboard
  apiVersion: 'v1',                            // API version (default: v1)
  enableLog: true,                             // Debug logs (default: false)
  timeoutSeconds: 60,                          // Request timeout
  theme: KyvshieldThemeConfig(
    primaryColor: Color(0xFFEF8352),           // Brand color
    successColor: Colors.green,
    warningColor: Colors.orange,
    errorColor: Colors.red,
    brightness: Brightness.light,              // Light or dark mode
  ),
)

KyvshieldFlowConfig #

KyvshieldFlowConfig(
  // Steps to perform
  steps: [CaptureStep.selfie, CaptureStep.recto, CaptureStep.verso],

  // Language ('fr', 'en', 'wo')
  language: 'fr',

  // UI pages
  showIntroPage: true,           // Welcome screen
  showInstructionPages: true,    // Per-step instruction pages
  showResultPage: true,          // Final result summary
  showSuccessPerStep: true,      // Success animation after each step

  // Display modes
  selfieDisplayMode: SelfieDisplayMode.standard,     // standard, compact, immersive, neonHud
  documentDisplayMode: DocumentDisplayMode.standard,  // standard, compact, immersive, neonHud

  // Verification options
  challengeMode: ChallengeMode.normal,  // easy, normal, hard
  requireFaceMatch: true,               // Selfie vs document face comparison

  // Audio
  playChallengeAudio: true,
  maxChallengeAudioPlay: ChallengeAudioRepeat.once,  // once, twice, thrice
  pauseBetweenAudioPlay: Duration(seconds: 1),

  // Document target
  target: KyvshieldDocument(
    docType: 'SN-CIN',
    name: "Carte Nationale d'Identite",
    category: 'identity_card',
    country: 'SN',
    countryName: 'Senegal',
  ),

  // Optional: per-step challenge modes
  stepChallengeModes: {
    CaptureStep.selfie: ChallengeMode.hard,
    CaptureStep.recto: ChallengeMode.normal,
  },

  // Optional: webhook correlation ID
  kycIdentifier: 'user-12345',
)

Display Modes #

Mode Description
standard Classic layout with header, camera, and instructions below
compact Camera fills screen, instructions overlay at bottom
immersive Full-screen camera with glass-effect overlays
neonHud Futuristic dark theme with glow effects and monospace font

Result Structure #

final result = await Kyvshield.initKyc(...);

// Overall result
result.success;              // bool
result.overallStatus;        // VerificationStatus (pass, review, reject, error)
result.sessionId;            // String?
result.errorMessage;         // String? (if error)
result.totalProcessingTimeMs; // int

// Selfie result
result.selfieResult?.isLive;           // bool
result.selfieResult?.confidence;       // double
result.selfieResult?.capturedImage;    // Uint8List? (JPEG bytes)

// Document results (recto / verso)
result.rectoResult?.status;                          // VerificationStatus
result.rectoResult?.alignedDocument;                 // Uint8List? (aligned JPEG)
result.rectoResult?.extraction?.fields;              // List<ExtractedField>
result.rectoResult?.extraction?.sortedFields;        // Sorted by displayPriority
result.rectoResult?.extractedPhotos;                 // List<ExtractedPhoto>
result.rectoResult?.faceVerification?.isMatch;       // bool?
result.rectoResult?.faceVerification?.similarityScore; // double?

// Convenience getters
result.getExtractedValue('nom');       // Search across recto + verso
result.mainPhoto;                      // First extracted face photo
result.faceMatches;                    // Face match boolean
result.selfieImage;                    // Uint8List?
result.rectoImage;                     // Uint8List?
result.versoImage;                     // Uint8List?
result.authenticityScore;              // Average document score

ExtractedField #

Each OCR field has rich metadata for display:

for (final field in result.rectoResult?.extraction?.sortedFields ?? []) {
  print('${field.label}: ${field.stringValue}');
  // field.key           — generic key (e.g. "first_name")
  // field.documentKey   — document-specific key (e.g. "prenoms")
  // field.label         — localized label (e.g. "Prénoms")
  // field.value         — extracted value
  // field.displayPriority — sort order (lower = first)
  // field.icon          — icon name (e.g. "user", "calendar")
}

Permission Helpers #

await Kyvshield.checkCameraPermission();                // bool
await Kyvshield.requestCameraPermission();              // bool
await Kyvshield.isCameraPermissionPermanentlyDenied();  // bool
await Kyvshield.openSettings();                         // Opens app settings

Platform Setup #

Android #

android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />

android/app/build.gradle — minimum SDK 21:

minSdkVersion 21

iOS #

ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>Camera access is required for identity verification.</string>

API Documentation #

Full documentation and developer dashboard: https://kyvshield.innolink.sn/developer

License #

BSD 3-Clause License. See LICENSE.

0
likes
90
points
99
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

KyvShield KYC SDK — WebView wrapper. Same public API as the native SDK, powered by the KyvShield Web SDK loaded from the API server.

Homepage
Repository (GitHub)
View/report issues

Topics

#kyc #identity-verification #document-scanning #liveness-detection #webview

License

BSD-3-Clause (license)

Dependencies

flutter, permission_handler, webview_flutter, webview_flutter_android, webview_flutter_wkwebview

More

Packages that depend on kyvshield_lite