Flutter Guide

Flutter / Dart integration

For mobile banking & wallet apps. Uses the official http and crypto packages (add via flutter pub add http crypto).

1. Set up the client

import 'dart:convert';
import 'package:http/http.dart' as http;

class EthioLink {
  static const _base = 'https://api.ethiolink-consent.et';
  final String apiKey;

  EthioLink(this.apiKey);

  Future> call(String method, String path,
      [Map? body]) async {
    final res = await http.Request(method, Uri.parse(_base + path))
        ..headers['Authorization'] = 'Bearer $apiKey'
        ..headers['Content-Type'] = 'application/json'
        ..body = body == null ? '' : jsonEncode(body)
        .send()
        .then((r) => http.Response.fromStream(r));
    final json = jsonDecode(res.body) as Map;
    if (res.statusCode >= 400) {
      throw Exception(json['error']?['message'] ?? 'HTTP ${res.statusCode}');
    }
    return json;
  }
}

2. Request consent

final el = EthioLink(await _loadKey());
final res = await el.call('POST', '/api/consent/request', {
  'user_fayda_id': 'FAYDA-847291',
  'purpose': 'Loan eligibility assessment',
  'data_categories_requested': ['transaction_history', 'mobile_money'],
  'duration_days': 30,
  // 'involves_automation': true,
  // 'automation_description': 'A scoring model estimates eligibility.',
});
final consentId = res['request']['public_id']; // cr_...

3. Verify a token before touching data

final verdict = await el.call('GET',
    '/api/consent/active?token=${Uri.encodeComponent(token)}&reason=loan_application');

if (verdict['active'] != true) {
  throw Exception('Consent not usable: ${verdict['status']}');
}
final objected = verdict['automation']?['objection'] == true;
// objected == true -> show "under human review" state in the app

4. Retrieve encrypted data

final data = await el.call('GET',
    '/api/data/retrieve?token=${Uri.encodeComponent(token)}&reason=loan_application');
for (final t in data['transfers'] as List) {
  final blob = t['encrypted_data'] as String; // decrypt client-side
}

5. Webhook signature verification

import 'package:crypto/crypto.dart';

bool verifyWebhook(String payload, String signature, String timestamp, String secret) {
  final expected = Hmac(sha256, utf8.encode(secret))
      .convert(utf8.encode('$timestamp.$payload'))
      .toString();
  return constantTimeEquals(expected, signature);
}

← All guides