Dart SDK
A Dart implementation of the Veriglob decentralized identity protocol. This library provides core functionality for creating and managing Decentralized Identifiers (DIDs), Verifiable Credentials (VCs), and Verifiable Presentations (VPs).
Features
Section titled “Features”- DID Operations: Create and resolve
did:keyidentifiers using Ed25519 keys - Verifiable Credentials: Issue and verify W3C-compliant verifiable credentials
- Verifiable Presentations: Create and verify presentations for selective disclosure
- Encrypted Wallet: Secure storage for keys and credentials using AES-256-GCM
- Revocation Registry: Track credential revocation status
- Mnemonic Support: Derive keys from BIP39 mnemonic phrases
Installation
Section titled “Installation”Add the dependency to your pubspec.yaml:
dependencies: veriglob: ^1.0.0Generate Keys and Create a DID
Section titled “Generate Keys and Create a DID”import 'package:veriglob/veriglob.dart';
// Generate a new key pairfinal keyPair = generateEd25519KeyPair();
// Create a DID from the public keyfinal did = createDIDKey(keyPair.publicKey);print('DID: ${did.did}');// Output: did:key:z6Mk...Derive Keys from Mnemonic
Section titled “Derive Keys from Mnemonic”const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
final derivedKeys = deriveKeysFromMnemonic(mnemonic);final did = createDIDKey(derivedKeys.publicKey);Issue a Verifiable Credential
Section titled “Issue a Verifiable Credential”// Create a credential subjectfinal subject = IdentitySubject( id: holderDid, givenName: 'Alice', familyName: 'Smith', dateOfBirth: '1990-01-15', nationality: 'US',);
// Issue the credentialfinal vcToken = issueVC( issuerDid.did, // Issuer's DID holderDid, // Subject's DID issuerKeys.privateKey, subject, credentialId: generateCredentialId(),);Verify a Credential
Section titled “Verify a Credential”try { final claims = verifyVC(vcToken, issuerPublicKey); print('Issuer: ${claims.issuer}'); print('Subject: ${claims.vc.credentialSubject}');} on VerificationException catch (e) { print('Verification failed: $e');}Create a Verifiable Presentation
Section titled “Create a Verifiable Presentation”// Generate a nonce for the verifier challengefinal nonce = generateNonce();
// Create a presentation containing one or more credentialsfinal vpToken = createPresentation( holderDid.did, holderKeys.privateKey, [vcToken], // List of VC tokens 'did:key:verifier123', // Verifier's DID (audience) nonce,);Verify a Presentation
Section titled “Verify a Presentation”final vpClaims = verifyPresentation( vpToken, holderPublicKey, expectedAudience: 'did:key:verifier123', expectedNonce: nonce,);
print('Holder: ${vpClaims.vp.holder}');print('Credentials: ${vpClaims.vp.verifiableCredential.length}');Wallet Management
Section titled “Wallet Management”// Create a new walletfinal wallet = await Wallet.create('/path/to/wallet.json', mnemonic);
// Store keysawait wallet.setKeys(keyPair.publicKey, keyPair.privateKey, did.did);
// Add a credentialawait wallet.addCredential(StoredCredential( id: credentialId, type: 'IdentityCredential', issuerDid: issuerDid, token: vcToken, issuedAt: DateTime.now(), expiresAt: DateTime.now().add(Duration(days: 365)), storedAt: DateTime.now(),));
// Open an existing walletfinal existingWallet = await Wallet.open('/path/to/wallet.json', mnemonic);
// Export wallet for backupfinal backupJson = wallet.export();Wallet Recovery
Section titled “Wallet Recovery”The library provides multiple ways to recover a wallet:
// Check if wallet existsfinal exists = await Wallet.exists('/path/to/wallet.json');
// Recover wallet from mnemonic (DID and keys only)// Use this when you've lost the wallet file but have your mnemonicfinal recoveredWallet = await Wallet.recover('/path/to/new-wallet.json', mnemonic);
// Recover wallet from backup (includes credentials)// Use this when you have a backup created via wallet.export()final restoredWallet = await Wallet.recoverFromBackup( '/path/to/new-wallet.json', mnemonic, backupJson,);
// Open or recover (tries to open first, recovers if not found)// Convenient for app startupfinal wallet = await Wallet.openOrRecover('/path/to/wallet.json', mnemonic);Revocation Registry
Section titled “Revocation Registry”// Create a registryfinal registry = RevocationRegistry();
// Register a credentialawait registry.register(credentialId, issuerDid, subjectDid);
// Check if revokedfinal isRevoked = registry.isRevoked(credentialId);
// Revoke a credentialawait registry.revoke(credentialId, 'Credential compromised');Credential Subject Types
Section titled “Credential Subject Types”The library includes four predefined credential subject types:
| Type | Description |
|---|---|
IdentitySubject | KYC/identity verification credentials |
EducationSubject | Educational credentials (degrees, certificates) |
EmploymentSubject | Employment verification credentials |
MembershipSubject | Organization membership credentials |
Enterprise Features
Section titled “Enterprise Features”Verification Request Widgets
Section titled “Verification Request Widgets”These Flutter widgets enable enterprise verification flows where verifiers can request credential presentations from holders via QR codes.
VerificationQrDisplay
Section titled “VerificationQrDisplay”Displays a QR code containing a verification request. Used by verifiers (enterprises) to request credentials from holders.
import 'package:veriglob/veriglob.dart';
// Create a verification requestfinal request = VerificationRequest( requestId: generateUuid(), verifierDid: verifierDid, verifierName: 'Acme Corporation', claimDemands: [ ClaimDemand( claimType: ClaimType.identity, required: true, fields: ['givenName', 'familyName', 'dateOfBirth'], ), ], callbackUrl: 'https://api.acme.com/verify', expiresAt: DateTime.now().add(Duration(minutes: 5)),);
// Display the QR codeVerificationQrDisplay( request: request, size: 280, title: 'Scan to Verify Identity', subtitle: 'Present your identity credential', onExpired: () { // Handle expiration - regenerate request },);VerificationScanner
Section titled “VerificationScanner”Scans verification request QR codes. Used by credential holders to receive verification requests.
VerificationScanner( onRequestScanned: (VerificationRequest request) { // Handle the scanned verification request print('Verifier: ${request.verifierName}'); print('Requesting: ${request.claimDemands.length} credentials'); }, onError: (String error) { // Handle scan errors print('Scan error: $error'); }, overlayText: 'Scan verification QR code',);CredentialPresentationSheet
Section titled “CredentialPresentationSheet”A bottom sheet that allows users to select which credentials to present in response to a verification request.
// Show the presentation sheetshowModalBottomSheet( context: context, isScrollControlled: true, builder: (context) => CredentialPresentationSheet( request: verificationRequest, availableCredentials: userCredentials, // List<StoredCredential> holderDid: holderDid, holderPrivateKey: holderPrivateKey, onPresentationCreated: (String vpToken) async { // Send the presentation to the verifier's callback URL await sendPresentation(vpToken, verificationRequest.callbackUrl); }, onCancel: () => Navigator.pop(context), ),);Complete Verification Flow
Section titled “Complete Verification Flow”// 1. VERIFIER: Create and display verification requestfinal request = VerificationRequest( requestId: generateUuid(), verifierDid: enterpriseDid, verifierName: 'Enterprise Name', claimDemands: [ ClaimDemand(claimType: ClaimType.identity, required: true), ], callbackUrl: 'https://api.enterprise.com/verify', expiresAt: DateTime.now().add(Duration(minutes: 5)),);
// Display QR code widget...
// 2. HOLDER: Scan the QR codeVerificationScanner( onRequestScanned: (request) { // Show credential selection sheet showCredentialSheet(request); },);
// 3. HOLDER: Select and present credentialsCredentialPresentationSheet( request: request, availableCredentials: myCredentials, holderDid: myDid, holderPrivateKey: myPrivateKey, onPresentationCreated: (vpToken) async { // Send to verifier await http.post( Uri.parse(request.callbackUrl!), body: jsonEncode(VerificationResponse( requestId: request.requestId, presentationToken: vpToken, holderDid: myDid, ).toJson()), ); },);
// 4. VERIFIER: Verify the presentation on backendfinal vpClaims = verifyPresentation( vpToken, holderPublicKey, expectedAudience: enterpriseDid, expectedNonce: request.nonce,);API Reference
Section titled “API Reference”Crypto
Section titled “Crypto”| Function | Description |
|---|---|
generateEd25519KeyPair() | Generate a new Ed25519 key pair |
generateEd25519KeyPairFromSeed(seed) | Generate keys from a 32-byte seed |
deriveKeysFromMnemonic(mnemonic) | Derive keys from a BIP39 mnemonic |
signEd25519(message, privateKey) | Sign a message |
verifyEd25519(message, signature, publicKey) | Verify a signature |
| Function | Description |
|---|---|
createDIDKey(publicKey) | Create a did:key from a public key |
resolveDID(did) | Resolve a DID to its public key |
Credentials
Section titled “Credentials”| Function | Description |
|---|---|
issueVC(issuerDid, subjectDid, privateKey, subject, {credentialId}) | Issue a VC |
verifyVC(token, publicKey) | Verify a VC token |
Presentations
Section titled “Presentations”| Function | Description |
|---|---|
createPresentation(holderDid, privateKey, credentials, audience, nonce) | Create a VP |
verifyPresentation(token, publicKey, {expectedAudience, expectedNonce}) | Verify a VP |
generateNonce() | Generate a random challenge nonce |
Storage
Section titled “Storage”| Function | Description |
|---|---|
Wallet.create(path, mnemonic) | Create a new encrypted wallet |
Wallet.open(path, mnemonic) | Open an existing wallet |
Wallet.exists(path) | Check if a wallet exists at the given path |
Wallet.recover(path, mnemonic) | Recover wallet from mnemonic (DID/keys only) |
Wallet.recoverFromBackup(path, mnemonic, backupJson) | Recover from exported backup |
Wallet.openOrRecover(path, mnemonic) | Open if exists, otherwise recover |
wallet.export() | Export wallet data as JSON for backup |
Revocation
Section titled “Revocation”| Function | Description |
|---|---|
RevocationRegistry() | Create an in-memory registry |
RevocationRegistry.withFile(path) | Create a file-backed registry |
generateCredentialId() | Generate a unique credential ID |
Source Code
Section titled “Source Code”The Dart SDK source code is available on GitHub.
License
Section titled “License”MIT License - see LICENSE file for details.