✨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.
logoReclaim Protocol Docs

Fullstack Example

This guide demonstrates how to integrate the Reclaim Protocol Flutter SDK into a fullstack application. We'll focus on the frontend implementation and how it interacts with a backend.

Backend Implementation

For a detailed backend implementation using Node.js and Express, please refer to the Backend Example.

The backend example provides a comprehensive guide on setting up a server that generates the SDK configuration and handles proof verification.

Frontend Implementation

Prerequisites

  • Flutter development environment set up
  • Basic understanding of async operations in Dart
  • The following packages installed in your pubspec.yaml:
    • reclaim_sdk
    • url_launcher
    • http

Implementation Overview

Below is a complete implementation showing how to integrate the Reclaim SDK into your Flutter application. This example demonstrates fetching the SDK configuration from your backend and handling the verification process:

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';
import 'package:http/http.dart' as http;
import 'dart:convert';
 
class ReclaimExample extends StatefulWidget {
  @override
  _ReclaimExampleState createState() => _ReclaimExampleState();
}
 
class _ReclaimExampleState extends State<ReclaimExample> {
  String _status = '';
  String _proofData = '';
 
  Future<ReclaimProofRequest> _fetchReclaimConfig() async {
    final response = await http.get(Uri.parse('https://your-backend.com/reclaim/generate-config'));
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final reclaimProofRequest = await ReclaimProofRequest.fromJsonString(jsonData['reclaimProofRequestConfig']);
      return reclaimProofRequest;
    } else {
      throw Exception('Failed to fetch Reclaim configuration');
    }
  }     
 
  Future<void> _startVerificationSession(ReclaimProofRequest request) async {
    await request.startSession(
      onSuccess: _handleProofSuccess,
      onError: _handleProofError,
    );
  }
 
  void _handleProofSuccess(Proof 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<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 _fetchReclaimConfig();
      final requestUrl = await reclaimProofRequest.getRequestUrl();
      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),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

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

This implementation provides a streamlined approach to integrating Reclaim SDK. It handles configuration fetching, initialization, and basic error management while maintaining a clean user interface.

Implementation Steps

  1. Backend Setup

    • Configure your backend server following the Backend Example
    • Ensure your endpoints are properly secured and accessible
  2. Frontend Integration

    • Copy the provided code into your Flutter application
    • Update the backend URL in _fetchReclaimConfig() to match your server
    • Implement any additional error handling specific to your use case
  3. Testing

    • Test the integration in both development and production environments
    • Verify error handling and edge cases
    • Ensure proper handling of network connectivity issues

Replace 'https://your-backend.com/reclaim/generate-config' with your actual backend endpoint URL before deploying.

Enhancement Suggestions

  1. User Experience Improvements

    • Add loading indicators during network operations
    • Implement retry mechanisms for failed operations
    • Add clear error messages for users
  2. Security Considerations

    • Implement proper authentication mechanisms
    • Secure your backend endpoints
    • Handle sensitive data appropriately
  3. Performance Optimization

    • Cache configuration where appropriate
    • Implement proper state management
    • Optimize network requests

By following this implementation guide, you'll have a robust integration of the Reclaim Protocol in your Flutter application. For additional support or advanced configurations, refer to our documentation sections.

On this page