Integration Guide

A reference architecture for building a verifier app using the Verifier React Native SDK. This guide shows which screens your app owns, which the SDK renders, and how they connect.

Thin Client Pattern

The verifier app is intentionally thin. Your app handles navigation, authentication, and VIN acquisition. The SDK handles all verification UI, NFC/BLE communication, and backend polling. Most screens are just wrappers around an SDK component with navigation callbacks.

App Architecture

App.tsx
├── SafeAreaProvider
├── AuthProvider (your auth)
└── VerifierSDKProvider (SDK context)
    └── Stack.Navigator
        ├── HomeScreen              ← App (entry point)
        ├── CameraScanScreen        ← App (VIN acquisition)
        ├── ImagePickerScreen       ← App (VIN acquisition)
        ├── ManualEntryScreen       ← App (VIN acquisition)
        └── VerificationScreen      ← App wrapper → SDK VerificationView

Screen Responsibilities

Screens Your App Owns (100% app code)

These screens have no SDK components — your app renders all UI and handles all logic.

ScreenPurposeNavigates To
HomeScreenAction cards for different verification methodsCameraScan, ImagePicker, ManualEntry
CameraScanScreenLive camera OCR to detect VIN from vehicle dashboardVerification (with detected VIN)
ImagePickerScreenGallery photo selection + ML Kit text recognitionVerification (with extracted VIN)
ManualEntryScreen17-character VIN text input with validationVerification (with entered VIN)

Screens That Wrap SDK Components

These screens are thin wrappers — typically under 80 lines. Your app provides a SafeAreaView, passes the SDK instance, and wires up navigation callbacks. The SDK renders all visible UI.

ScreenSDK ComponentWhat the SDK Renders
VerificationScreenVerificationViewQR code, countdown timer, NFC delivery badge, and built-in result states by default. Set hostHandlesResults if your app should render approved / denied / expired itself.

SDK Provider Setup

Wrap your navigation in VerifierSDKProvider so all screens can access the SDK via useVerifierSDKContext():

import { VerifierSDKProvider } from '@vecu/verifier-react-native-sdk';
import { createVerifierSDK } from '@vecu/verifier-react-native-sdk';

const config = {
  stage: 'production',
  bearerToken: authToken,
};

function App() {
  return (
    <VerifierSDKProvider config={config}>
      <NavigationContainer>
        <Stack.Navigator>{/* your screens */}</Stack.Navigator>
      </NavigationContainer>
    </VerifierSDKProvider>
  );
}

Screens then access the SDK without creating their own instance:

import { useVerifierSDKContext } from '@vecu/verifier-react-native-sdk';

function VerificationScreen() {
  const sdk = useVerifierSDKContext();
  // pass sdk to VerificationView
}

Writing a Wrapper Screen

A typical wrapper screen follows this pattern:

import {
  VerificationView,
  useVerifierSDKContext,
} from '@vecu/verifier-react-native-sdk';

function VerificationScreen({ route, navigation }) {
  const sdk = useVerifierSDKContext();
  const { vin } = route.params;

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <VerificationView
        sdk={sdk}
        vin={vin}
        proximity={{ thresholdMiles: 5.0 }}
        // Navigation callbacks — SDK says "what happened", app decides "where to go"
        onApproved={result => {
          Alert.alert('Approved', `Verified for VIN: ${vin}`);
          navigation.popToTop();
        }}
        onDenied={() => {
          Alert.alert('Denied', 'DO NOT release the vehicle.');
          navigation.goBack();
        }}
        onExpired={() => {
          Alert.alert('Expired', 'Try again.');
          navigation.goBack();
        }}
        onError={error => console.error(error.code, error.message)}
      />
    </SafeAreaView>
  );
}

The SDK has zero knowledge of your navigation structure. It communicates via callbacks — your app decides where to navigate.

Callback-Based Integration

For screen-based integrations, use the callback props as your app boundary:

  • onApproved
  • onDenied
  • onExpired
  • onError

These are plain functions that your wrapper screen passes into VerificationView. Internally, the SDK listens to its own event emitter and then invokes those callbacks for you.

VerificationView also supports hostHandlesResults. With hostHandlesResults={true}, the SDK still runs the full verification flow and still invokes onApproved, onDenied, and onExpired, but it suppresses its built-in approved / denied / expired screens so the host app can render its own result UI.

Verification Flow

The verifier acquires a VIN first, then shows a QR code for the driver to scan with their wallet.

HomeScreen
├── CameraScanScreen ──► VIN ──► VerificationScreen (SDK: QR + polling)
├── ImagePickerScreen ──► VIN ──► VerificationScreen
└── ManualEntryScreen ──► VIN ──► VerificationScreen

Your app's job: Acquire the VIN (camera, gallery, or keyboard). SDK's job: Create presentation request, display QR, poll for result.

What Your App Does NOT Need to Manage

The SDK handles all of the following internally:

  • Presentation request creation and QR code generation
  • Verification status polling and timeout
  • All in-flow UI states (loading, QR, waiting, approved, denied, expired, error)
  • Optional NFC delivery of the request via Android HCE (see Permissions)

Next Steps

  • Overview — Quick start with VerificationView and useVerification
  • Permissions — Native setup for NFC delivery and entitlements
  • API Reference — Full SDK configuration, hooks, events, and types