✨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(Proof proof) {
  print('Proof received: $proof');
  setState(() {
    _status = 'Proof received!';
    _proofData = 'Extracted data: ${proof.claimData.context}\n\nFull proof: ${proof.toString()}';
  });
}
 
void _handleProofError(Exception error) {
  _handleError('Error in proof generation', error);
}

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(Proof proof) {
    print('Proof received: $proof');
    setState(() {
      _status = 'Proof received!';
      _proofData =
          'Extracted data: ${proof.claimData.context}\n\nFull proof: ${proof.toString()}';
    });
  }
 
  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),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

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.

Next Steps

Now that you've learned the basics, you can:

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

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!