todolegal_identity

Embedded identity onboarding and redirected document signing for partner Flutter apps, backed by TodoLegal.

  • Onboarding runs inside your app — consent, ID document capture, optional eMRTD chip read (NFC), liveness check, and biometric comparison, all themed to match your app.
  • Signing hands off to the TodoLegal companion app over an app link — your app never holds a private key or certificate password.

The entire public surface is one class: TodoLegalIdentity.

Install

dependencies:
  todolegal_identity: ^0.1.0

Platform setup

Some of what this package does — camera, NFC, and detecting whether the TodoLegal companion app is installed — needs a few things added to your own app that no package can inject automatically. Read PERMISSIONS.md before your first test build — skipping it produces the same symptom every time: the relevant permission is denied silently, with no OS prompt ever shown, and no error pointing at the real cause.

Usage

1. Verify identity

import 'package:todolegal_identity/todolegal_identity.dart';

final outcome = await TodoLegalIdentity.startOnboarding(
  context,
  sessionToken: sessionToken, // minted by your backend, see below
  options: const OnboardingOptions(
    locale: 'es', // or 'en'
    sandboxMode: true, // false once you're ready to go live
  ),
);

switch (outcome) {
  case OnboardingSubmitted(:final sessionId, :final certificateIssued):
    // The device finished submitting. This is NOT proof verification
    // passed — confirm the authoritative result from your backend via
    // GET /sdk/sessions/{id} before treating the user as verified.
  case OnboardingReusedIdentity(:final sessionId):
    // The user already had a verified identity and reused it.
  case OnboardingCancelled():
    // The user abandoned the flow.
  case OnboardingFailed(:final error):
    // See OnboardingError for every possible reason.
}

2. Request a signature

final outcome = await TodoLegalIdentity.requestSignature(
  context,
  sessionToken: sessionToken,
  request: SignatureRequest(
    documentBytes: documentBytes,
    documentTitle: 'Loan agreement',
    returnUri: Uri.parse('yourapp://sign-return'),
    sandboxMode: true,
  ),
);

switch (outcome) {
  case SignatureCompleted(:final sessionId, :final documentId):
    // Signed and handed back to your app.
  case SignatureDeclined(:final sessionId):
  case SignatureCancelled():
  case SignatureCompanionAppRequired(:final sessionId):
    // The companion app isn't installed. The session is preserved, so you
    // can resume signing after the user installs it.
  case SignatureFailed(:final error):
}

returnUri is your own app's deep link — register it in your own Info.plist/AndroidManifest.xml (see PERMISSIONS.md), since the companion app redirects back to exactly that URI once signing finishes, with session, status, and nonce query parameters appended.

Session tokens

sessionToken is minted by your backend, not this package — it calls your TodoLegal partner API to create a session, then hands the resulting token to the client for these two calls. This keeps your partner credentials server-side, where they belong.

Theming

OnboardingOptions(
  theme: IdentitySdkThemeTokens(
    primary: Color(0xFF0043D3),
    surface: Colors.white,
    text: Color(0xFF1A1A1A),
    radius: 12,
    fontFamily: 'YourBrandFont',
    logo: Image.asset('assets/your_logo.png'),
  ),
)

Sandbox mode

Set sandboxMode: true on both OnboardingOptions and SignatureRequest while integrating — this runs the flow against TodoLegal's sandbox environment and test fixtures instead of live verification. Keep the two flags in sync for a given session.

Libraries

todolegal_identity
TodoLegal Identity SDK — embedded onboarding and redirected document signing for partner Flutter apps.