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.