zetrix_vc_flutter 0.0.9 copy "zetrix_vc_flutter: ^0.0.9" to clipboard
zetrix_vc_flutter: ^0.0.9 copied to clipboard

Zetrix flutter SDK for Verifiable Credential (Verifiable Presentation)

๐Ÿ“ฆ zetrix_vc_flutter Plugin #

A Flutter plugin that enables Verifiable Credential (VC) and Verifiable Presentation (VP) generation using BBS+ signatures, built on top of Zetrix blockchain specifications.

This implementation uses platform-specific native libraries (Rust-compiled via JNI/FFI) and exposes functionality to Dart via MethodChannel.


โœ… Features #

  • ๐Ÿง  BBS+ key generation (BLS12-381)
  • โœ๏ธ BBS+ signature creation
  • ๐Ÿ” Selective disclosure proofs
  • ๐Ÿ” Bulletproof Range Proofs: Zero-knowledge range proofs (prove value in range without revealing it)
  • ๐Ÿงฑ Works across Android and iOS (iOS soon)
  • ๐Ÿ“ฆ Built as a Flutter plugin (no manual linking for consumers)

๐Ÿงญ DCQL Presentation (Wallet Flow) #

This plugin includes helpers to produce Verifiable Presentations (VPs) in response to a DCQL (Digital Credentials Query Language) presentation request. Key points:

  • Create VP from DCQL: call ZetrixVpService().createVPFromDCQL(...) (or use your existing zetrixVpService instance) with the presentation request JSON (GET /v1/presentation/{id}), the holder's Verifiable Credential (VC) JSON, and the wallet key material.
  • Presentation submission body: the returned object serializes to the verifier's expected JSON with keys such as vp_token, presentation_id, presentation_submission, ed25519_public_key, and bbs_public_key.
  • Constraints vs filter: the request may use constraints (preferred) or the legacy filter key; both are supported. Range proofs are requested by minimum/maximum in the constraint and produce BulletProofs; other constraints (e.g. const, enum, pattern) are handled via BBS+ selective disclosure.
  • Path flexibility: presentation requests may use flat paths like ["credentialSubject","nationality"]. The service attempts an exact match and falls back to a deep-search for the requested final field within credentialSubject (e.g. credentialSubject.identityCardMalaysia.nationality).
  • Note on issuer signatures: the derived BBS+ proof is created from the original VC's flattened message list. If you change the VC structure you may need the issuer to re-issue the VC for verifier signature checks to succeed; the library will still locate nested fields when possible.

๐Ÿงน Project Structure #

zetrix_vc_flutter/
โ”œโ”€โ”€ android/
โ”‚   โ”œโ”€โ”€ src/main/java/.../MethodChannelHandler.java
โ”‚   โ”œโ”€โ”€ src/main/jniLibs/arm64-v8a/libbbs.so
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ ios/
โ”‚   โ””โ”€โ”€ (pending FFI integration)
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ bbs_bindings.dart
โ”‚   โ”œโ”€โ”€ bbs.dart
โ”‚   โ””โ”€โ”€ zetrix_vc_flutter.dart
โ”œโ”€โ”€ example/
โ””โ”€โ”€ pubspec.yaml

๐Ÿ”ง How We Integrated Using MethodChannel #

โœ… Step-by-step: #

1. Expose Native Methods via Java (Android)

We created a wrapper class in android/src/main/java/.../BbsMethodHandler.java that maps Dart calls to native Rust bindings via JNI.

Example:

methodChannel.setMethodCallHandler((call, result) -> {
    switch (call.method) {
        case "createBbsProof":
            // call Rust JNI wrapper
            byte[] proof = Bbs.createProof(...);
            result.success(proof);
            break;
        default:
            result.notImplemented();
    }
});

2. Implement Dart MethodChannel

In bbs.dart, we use Flutter's MethodChannel to call native methods:

const _channel = MethodChannel('zetrix_vc');

Future<Uint8List> createBbsProof(Map<String, dynamic> args) async {
  final result = await _channel.invokeMethod<Uint8List>('createBbsProof', args);
  return result!;
}

We placed libbbs.so in android/src/main/jniLibs/ so it is automatically bundled into the APK:

android/
โ””โ”€โ”€ src/main/jniLibs/
    โ””โ”€โ”€ arm64-v8a/
        โ””โ”€โ”€ libbbs.so

No manual linking needed from consumers.

4. Generate and Use JNI Headers

To link Java and Rust, we generated bbs_signatures_Bbs.h using javac -h. This header defines all native functions that the Rust/C side must implement.

javac -h . Bbs.java

๐Ÿ” Why MethodChannel? #

We chose MethodChannel over Dart FFI for Android because:

  • JNI is well-documented and stable for native Rust โ†” Java bindings.
  • Flutter Android's MethodChannel provides simple serialization and error propagation.
  • No need to handle cross-platform memory management at Dart-level.
  • Works well with .so libraries generated from Rust (cargo-ndk, jni crate).

๐Ÿš€ Usage in Flutter #

BBS+ Signatures #

final proof = await createBbsProof({
  "publicKey": [...],
  "signature": [...],
  "nonce": [...],
  "messages": [...],
});

Bulletproof Range Proofs #

import 'package:zetrix_vc_flutter/zetrix_vc_flutter.dart';
import 'package:zetrix_vc_flutter/frb_generated.dart';

// Initialize (once at app startup)
await RustLib.init();

// Create service
final service = BulletproofService();

// Prove age โ‰ฅ 18 without revealing actual age
final proof = await service.generateSingleMinRangeProof(
  value: 25,
  min: 18,
  domain: 'age-verification',
);

// Verify proof
bool isValid = await service.verifyMultipleRangeProof(proof: proof);
print('Valid: $isValid');  // true, actual age stays secret!

๐Ÿ“‹ TODOs #

  • โŒ iOS native integration (Obj-C/Swift + Rust static lib)
  • โŒ Fallback to Dart FFI for cross-platform consistency

๐Ÿ’ช Build Notes #

To rebuild the plugin after modifying native libs:

flutter clean
flutter pub get
flutter build apk

If your app uses this plugin as a dependency:

dependencies:
  zetrix_vc_flutter: <VERSION>

๐Ÿ™Œ Credits #