✨Works out of the box guarantee. If you face any issue at all, hit us up on Telegram and we will write the integration for you.

Flutter
Flutter Example

Basic Usage of the Reclaim Protocol Flutter SDK

This guide will walk you through the fundamental steps to integrate Reclaim's proof verification system into your Flutter application.

Prerequisites

Before you begin, ensure you have:

⚠️

Keep your Application Secret secure and never expose it in client-side code.

Step-by-Step Guide

1. Import the SDK

First, import the necessary components from the SDK in your Dart file:

import 'package:flutter/material.dart';
import 'package:reclaim_sdk/reclaim.dart';
import 'package:reclaim_sdk/utils/interfaces.dart';
import 'package:reclaim_sdk/utils/types.dart';
import 'package:url_launcher/url_launcher.dart';

2. Initialize the SDK

Set up your credentials and initialize the SDK:

Future<ReclaimProofRequest> _initializeProofRequest() async {
  final reclaimProofRequest = await ReclaimProofRequest.init(
    "YOUR_APP_ID", // Replace with your actual Application ID
    "YOUR_APP_SECRET", // Replace with your actual Application Secret
    "YOUR_PROVIDER_ID", // Replace with your actual Provider ID
  );
 
  return reclaimProofRequest;
}

Replace 'YOUR_APP_ID', 'YOUR_APP_SECRET', and 'YOUR_PROVIDER_ID' with your actual credentials.

3. Generate a Request URL

Request URL is the URL that users will visit to initiate the proof request process. It redirects the user to the app clip or instant app flow for Reclaim Verifier App. You can generate it using the following method:

Future<String> _generateRequestUrl(ReclaimProofRequest request) async {
  final requestUrl = await request.getRequestUrl();
  print('Request URL: $requestUrl');
  return requestUrl;
}

4. Launch the URL

We recommend using the url_launcher package to open the request URL. Ensure you have added the url_launcher package to your pubspec.yaml file:

dependencies:
  url_launcher: ^6.0.20

We use this method to open the request URL in an external browser. User is navigated to the Request URL from your app.

Future<void> _launchUrl(String url) async {
  if (await canLaunchUrl(Uri.parse(url))) {
    final launched = await launchUrl(
      Uri.parse(url),
      mode: LaunchMode.externalApplication,
    );
    if (launched) {
      setState(() => _status = 'Session started. Waiting for proof...');
    } else {
      throw 'Could not launch $url';
    }
  } else {
    throw 'Could not launch $url';
  }
}

5. Start the Verification Session

Begin listening for proofs:

Future<void> _startVerificationSession(ReclaimProofRequest request) async {
  await request.startSession(
    onSuccess: _handleProofSuccess,
    onError: _handleProofError,
  );
}
 
void _handleProofSuccess(dynamic proof) {
  print('Proof received: $proof');
  // check if proof is of type String
  var proofDataValue = '';
  if (proof is String) {
    // For custom callback URL, the proof is a just a string message suggesting the proof is successfully sent and the user should check their backend for the proof
    proofDataValue = proof;
  } else {
    proofDataValue =
        'Extracted data: ${proof.claimData.context}\n\nFull proof: ${proof.toString()}';
  }
  setState(() {
    _status = 'Proof received!';
    _proofData = proofDataValue;
  });
}
 
void _handleProofError(Exception error) {
  _handleError('Error in proof generation', error);
}

For detailed information about the proof object, refer to the Advance Configuration section.

Complete Basic Example

Here's a full example putting all the steps together in a Flutter widget:

import 'package:flutter/material.dart';
import 'package:reclaim_sdk/reclaim.dart';
import 'package:reclaim_sdk/utils/interfaces.dart';
import 'package:url_launcher/url_launcher.dart';
 
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(home: ReclaimExample()));
}
 
class ReclaimExample extends StatefulWidget {
  @override
  _ReclaimExampleState createState() => _ReclaimExampleState();
}
 
class _ReclaimExampleState extends State<ReclaimExample> {
  String _status = '';
  String _proofData = '';
 
  Future<void> _startVerificationSession(ReclaimProofRequest request) async {
    await request.startSession(
      onSuccess: _handleProofSuccess,
      onError: _handleProofError,
    );
  }
 
  void _handleProofSuccess(dynamic proof) {
    print('Proof received: $proof');
    // check if proof is of type String
    var proofDataValue = '';
    if (proof is String) {
      // For custom callback URL, the proof is a just a string message suggesting the proof is successfully sent and the user should check their backend for the proof
      proofDataValue = proof;
    } else {
      proofDataValue =
          'Extracted data: ${proof.claimData.context}\n\nFull proof: ${proof.toString()}';
    }
    setState(() {
      _status = 'Proof received!';
      _proofData = proofDataValue;
    });
  }
 
  void _handleProofError(Exception error) {
    _handleError('Error in proof generation', error);
  }
 
  void _handleError(String message, dynamic error) {
    print('$message: $error');
    setState(() => _status = '$message: ${error.toString()}');
  }
 
  Future<ReclaimProofRequest> _initializeProofRequest() async {
    final reclaimProofRequest = await ReclaimProofRequest.init(
      "YOUR_APP_ID", // Replace with your actual Application ID
      "YOUR_APP_SECRET", // Replace with your actual Application Secret
      "YOUR_PROVIDER_ID", // Replace with your actual Provider ID
    );
    return reclaimProofRequest;
  }
 
  Future<String> _generateRequestUrl(ReclaimProofRequest request) async {
    final requestUrl = await request.getRequestUrl();
    print('Request URL: $requestUrl');
    return requestUrl;
  }
 
  Future<void> _launchUrl(String url) async {
    if (await canLaunchUrl(Uri.parse(url))) {
      final launched = await launchUrl(
        Uri.parse(url),
        mode: LaunchMode.externalApplication,
      );
      if (launched) {
        setState(() => _status = 'Session started. Waiting for proof...');
      } else {
        throw 'Could not launch $url';
      }
    }
  }
 
  Future<void> startReclaimSession() async {
    try {
      print('Starting Reclaim session');
      final reclaimProofRequest = await _initializeProofRequest();
      final requestUrl = await _generateRequestUrl(reclaimProofRequest);
      await _launchUrl(requestUrl);
      await _startVerificationSession(reclaimProofRequest);
    } catch (error) {
      _handleError('Error starting Reclaim session', error);
    }
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Reclaim SDK Demo')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            ElevatedButton(
              onPressed: startReclaimSession,
              child: const Text('Start Reclaim Session'),
            ),
            const SizedBox(height: 20),
            Text(_status, style: const TextStyle(fontWeight: FontWeight.bold)),
            const SizedBox(height: 20),
            if (_proofData.isNotEmpty)
              Expanded(
                child: SingleChildScrollView(
                  child: Text(_proofData),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
⚠️

🚨 Safety First! 🚨

For real-world apps, don't put sensitive info like APP_SECRET in your frontend code. It's not safe!

Instead, do this:

  1. Store sensitive info like APP_SECRET on your backend
  2. Get the ReclaimProofRequestConfig from your backend
  3. Use fromJsonString(reclaimProofRequestConfig) on the frontend to get the reclaimProofRequest object and then generate the request URL.

This keeps your application secure and your secrets... well, secret! 🔒

Check out the Fullstack Example to see how to do this.

How It Works

  1. We initialize the SDK with your app credentials.
  2. We generate a request URL for the verification process.
  3. When the user presses the button, it opens the request URL.
  4. The SDK listens for the verification result and updates the status.

Next Steps

  1. Learn about Advanced Configuration options to customize the SDK for your specific needs.
  2. Review Best Practices for optimizing your Reclaim integration.

This example demonstrates a basic implementation. In a real application, you'd need to handle errors more robustly, manage state more efficiently, and integrate this flow into your broader application logic.

If you have any questions, don't hesitate to join our Telegram community (opens in a new tab) for support.

Happy coding with Reclaim Protocol in Flutter!