Mobile & Web SDKs · v1.1.0

Flutter SDK

One Dart package, two native bridges. Material widgets shipped in the box. Phone OTP, WhatsApp OTP, marketing attribution — all driving the same backend as the rest of QuickAuth.

Requirements

  • Flutter 3.16+
  • Dart SDK ≥ 3.0.0
  • iOS 12.0+, Android minSdk 21

Install

flutter pub add quickauth

Initialize

main.dart
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:quickauth/quickauth.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await QuickAuth.init(
    // Returns a fresh session JWT from your backend.
    onTokenExpiry: () async {
      final response = await myApi.fetchQuickAuthSessionToken();
      return response.sessionToken;
    },
    // Single typed event stream — switch on the sealed AuthEvent subtypes.
    onAuthEvent: (event) {
      switch (event) {
        case OtpSentEvent():     showOtpInput();
        case OtpAutoReadEvent(): prefillInput(event.code);
        case VerifiedEvent():    finishLogin(event.requestId);
        case OtpFailedEvent():   showError(event.message);
        case AuthErrorEvent():   showError(event.message);
      }
    },
  );

  runApp(const MyApp());
}

Consent

dart
await QuickAuth.instance.consent.set(true);
final granted = await QuickAuth.instance.consent.get();

Headless flow

Two methods. initiate kicks off the auth attempt; submitOtp hands back the user-typed code. All outcomes arrive on the onAuthEvent handler — including the OneTap silent re-auth path, where the backend emits VerifiedEvent directly without sending an SMS.

dart
// Step 1 — kick off the attempt. Events arrive via onAuthEvent.
await QuickAuth.auth.initiate(
  phone:   '+919876543210',
  channel: OtpChannel.auto,
);
// → onAuthEvent fires with one of:
//     OtpSentEvent(sessionId, channel, expiresIn)
//     VerifiedEvent(requestId, message)            // OneTap fired
//     AuthErrorEvent(code, message)

// Step 2 — when OtpSentEvent fires and the user types a code:
await QuickAuth.auth.submitOtp('123456');
// → onAuthEvent fires with VerifiedEvent / OtpFailedEvent / AuthErrorEvent

// On user-initiated logout, drop the OneTap trust token:
await QuickAuth.auth.reset(forgetDevice: true);

Pre-built widgets

import 'package:quickauth/quickauth.dart';

QuickAuthLoginButton(
  phone:    '+919876543210',
  onSuccess: (jwt) => saveJwt(jwt),
  onError:   (err) => debugPrint(err.toString()),
)

Auto-fill is native

iOS auto-fill is wired via UITextContentType.oneTimeCode in the native bridge. Android uses SMS Retriever (no permission prompt) — the bridge listens for the matching message and pushes the code into the Flutter widget via a platform stream.

WhatsApp OTP

dart
await QuickAuth.instance.auth.startWhatsAppLogin(
  businessNumber: '+919574980048',
  returnURL:      'https://app.example.com/wa-return',
);

// Handle the return in your route observer or app_links callback:
await QuickAuth.instance.attribution.captureLaunch(uri);

Attribution

dart
// On cold launch (inside initState of your root widget):
await QuickAuth.instance.attribution.captureLaunch();

// Track a conversion later:
await QuickAuth.instance.attribution.trackConversion(
  event:    'signup',
  value:    0,
  currency: 'INR',
);

API reference

SymbolDescription
QuickAuth.instance.initialize(...)Async init in main().
.consent.set / getConsent gate.
.auth.initiate(phone:channel:)Begin an auth attempt. Emits OtpSentEvent or VerifiedEvent.
.auth.submitOtp(code)Submit the user-typed code. Emits VerifiedEvent or OtpFailedEvent.
.auth.reset(forgetDevice:)Reset the state machine. Pass forgetDevice: true on logout.
.auth.observeOTP()Stream<String> of inbound OTPs.
QuickAuthLoginButtonMaterial login widget.
QuickAuthOtpFieldMaterial OTP input widget.
.attribution.captureLaunch / trackConversionAttribution APIs.

Source & changelog

Source: github.com/quickauthin/quickauth-sdk-flutter. Package: quickauth on pub.dev.