Vault

Libraries to integrate Affinidi Vault into your Flutter/Dart applications.

Affinidi Vault TDK for Dart provides the libraries and tools to integrate Affinidi Vault into your Flutter/Dart application for implementing Decentralised Identity solution to securely manage Decentralised Identifiers (DIDs), Verifiable Credentials, and other data that represents the user’s identity based on different context, for example, you can create an identity for shopping, personal finance, and work.

Create and Initialise Vault

Initialise vault with wallet, storage, and profile interface. To create a wallet, you must generate a Seed and store it on the selected storage layer. The profile is initialised using the VFS option which is the cloud profile supported by Affinidi Vault.

Refer to the published SSI Dart package to know more about different types of wallet supported.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Initialise InMemory storage final accountIndex = 32; final vaultStore = InMemoryVaultStore(); await vaultStore.writeAccountIndex(accountIndex); // Generate seed from the storage layer final seed = vaultStore.getRandomSeed(); // Initialise profile interface const vfsRepositoryId = 'vfs'; final profileRepositories = <String, ProfileRepository>{ vfsRepositoryId: VfsProfileRepository(vfsRepositoryId), }; // Create a wallet // In this example, we are using Bip32 type wallet from SSI package final wallet = await Bip32Wallet.fromSeed(seed, vaultStore); final vault = Vault( wallet: wallet, vaultStore: vaultStore, profileRepositories: profileRepositories, defaultProfileRepositoryId: vfsRepositoryId, ); // Ensure vault is initialised before being able to access any of the repositories await vault.ensureInitialized();

Manage Vault Profiles

Create and manage profiles associated with the vault.

Create Vault Profile

Create a profile to store credentials and documents. A profile represents a user’s identity.

Currently, vault only supports cloud profile from Affinidi Vault.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Create Profile try { final profileRepository = vault.defaultProfileRepository; // alternatively can be accessed via profile repository identifier // final ProfileRepository profileRepository = vault.profileRepositories[vfsRepositoryId]; await profileRepository.createProfile(name: 'Work Profile'); } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }

List Vault Profiles

Retrieve list of profiles associated with the vault.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Retrieve list of profiles from the vault var profiles = await vault.listProfiles(); // Check if we have list of profiles if (!profiles.isEmpty) { profiles.forEach((profile) { print('${profile.id} : ${profile.name}'); }); } else { print('Vault profiles is empty.'); }

Update Vault Profile

Update a profile associated with the vault.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Update profile name profile.name = 'Test Profile 123'; // Update profile await profileRepository.updateProfile(profile); } else { print('Profile not found.'); }

Delete Vault Profile

Delete a profile associated with the vault.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Delete profile await profileRepository.deleteProfile(profile); } else { print('Profile not found.'); }

Manage Vault Files

Create folders and upload files to manage documents associated with the vault.

Create Folder

Create a folder in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // We'll create a folder under a profile (root folder) final rootFolderId = profile.id; await profile.defaultFileStorage!.createFolder( folderName: '<Folder_Name>', parentFolderId: rootFolderId, ); } else { print('Profile not found.'); }

Get Folder

Get the folder in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // We'll retrieve the folders under a profile (root folder) final rootFolderId = profile.id; // List folders final files = await profile.defaultFileStorage?.getFolder(folderId: rootFolderId); files?.forEach((file) { print('${file.id} : ${file.name}'); }); } else { print('Profile not found.'); }

Rename Folder

Rename a folder in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Rename the file object await profile.defaultFileStorage!.renameFolder( folderId: '<File_ID>', newName: '<File_Name>' ); } else { print('Profile not found.'); }

Delete Folder

Delete a folder in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { try { // We'll retrieve the folders under a profile (root folder) final rootFolderId = profile.id; // List folders await profile.defaultFileStorage?.deleteFolder(folderId: '<Folder_ID>'); } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); } } else { print('Profile not found.'); }

Create File

Create a file in a folder in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // We'll retrieve the folders under a profile (root folder) final rootFolderId = profile.id; // Create a dummy file final fileContent = Uint8List.fromList([1, 2, 3]); try { // create a file, we'll create a file in the root folder, instead of subfolder. await profile.defaultFileStorage!.createFile( fileName: 'Doc Test File 1', data: fileContent, parentFolderId: rootFolderId, ); } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); } } else { print('Profile not found.'); }

Get File

Get the file in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Retrieve the file object final file = await profile.defaultFileStorage!.getFile( fileId: '<File_ID>' ); print(file.name); } else { print('Profile not found.'); }

Get File Content

Get the content of the file in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Retrieve the file content final fileData = await profile.defaultFileStorage!.getFileContent( fileId: '<File_ID>' ); print(fileData); } else { print('Profile not found.'); }

Rename File

Rename a file in the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { // Rename the file object await profile.defaultFileStorage!.renameFile( fileId: '<File_ID>', newName: '<File_Name>' ); } else { print('Profile not found.'); }

Delete File

Delete a file from the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:ssi/ssi.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; if (profile != null) { try { // Rename the file object await profile.defaultFileStorage!.deleteFile( fileId: '<File_ID>' ); } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); } } else { print('Profile not found.'); }

Manage Vault Credentials

Manage credentials claimed from credential issuers into the vault.

Claim Credential

Claim the credential from the issuer.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_claim_verifiable_credential/oid4vci_claim_verifiable_credential.dart'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart'; import 'package:ssi/ssi.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); try { final keyDerivationPath = "m/44'/60'/0'/0/0"; final keyPair = await wallet.deriveKey(derivationPath: keyDerivationPath); final didDocument = DidKey.generateDocument(keyPair.publicKey); final signer = DidSigner( didDocument: didDocument, didKeyId: didDocument.verificationMethod.first.id, keyPair: keyPair, signatureScheme: SignatureScheme.ecdsa_secp256k1_sha256, ); // Create a new instance of ClaimVerifiableCredentialService final claimVerifiableCredentialService = OID4VCIClaimVerifiableCredentialService( didSigner: signer, ); final uri = Uri.parse( 'https://example.com/callback?credential_offer_uri=https://issuer.example.com/offer/123', ); final context = await claimVerifiableCredentialService.loadCredentialOffer(uri); VerifiableCredential? credential; String? txCode = '<TX_CODE_FROM_ISSER>'; // Check if the credential offer is issued with Transaction Code if (context.credentialOffer.isTxCodeRequired) { // Claim credential with Transaction Code // Transaction Code is generated and must be provided by the issuer credential = await claimVerifiableCredentialService.claimCredential( claimContext: context, txCode: txCode, ); } else { // Claim credential without Transaction Code credential = await claimVerifiableCredentialService.claimCredential( claimContext: context, ); } print('Credential: $credential'); } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }

Save Credential

Store a claimed credential into the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_claim_verifiable_credential/oid4vci_claim_verifiable_credential.dart'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart'; import 'package:ssi/ssi.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); try { final keyDerivationPath = "m/44'/60'/0'/0/0"; final keyPair = await wallet.deriveKey(derivationPath: keyDerivationPath); final didDocument = DidKey.generateDocument(keyPair.publicKey); final signer = DidSigner( didDocument: didDocument, didKeyId: didDocument.verificationMethod.first.id, keyPair: keyPair, signatureScheme: SignatureScheme.ecdsa_secp256k1_sha256, ); // Create a new instance of ClaimVerifiableCredentialService final claimVerifiableCredentialService = OID4VCIClaimVerifiableCredentialService( didSigner: signer, ); final uri = Uri.parse( 'https://example.com/callback?credential_offer_uri=https://issuer.example.com/offer/123', ); final context = await claimVerifiableCredentialService.loadCredentialOffer(uri); VerifiableCredential? credential; String? txCode = '<TX_CODE_FROM_ISSER>'; // Check if the credential offer is issued with Transaction Code if (context.credentialOffer.isTxCodeRequired) { // Claim credential with Transaction Code // Transaction Code is generated and must be provided by the issuer credential = await claimVerifiableCredentialService.claimCredential( claimContext: context, txCode: txCode, ); } else { // Claim credential without Transaction Code credential = await claimVerifiableCredentialService.claimCredential( claimContext: context, ); } // Did we claim successfully the credential from the issuer? if (credential.id != null) { // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; // do we have a profile selected? if (profile != null) { // Save credential on the selected vault profile await profile.defaultCredentialStorage?.saveCredential( verifiableCredential: credential, ); } } } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }

List Credentials

List credentials from the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_claim_verifiable_credential/oid4vci_claim_verifiable_credential.dart'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart'; import 'package:ssi/ssi.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); try { // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; // do we have a profile selected? if (profile != null) { // List credentials from the selected vault profile final credentials = await profile.defaultCredentialStorage?.listCredentials(); print('Credentials: $credentials'); } } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }

Get Credential

Get a credential from the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_claim_verifiable_credential/oid4vci_claim_verifiable_credential.dart'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart'; import 'package:ssi/ssi.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); try { // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; // do we have a profile selected? if (profile != null) { // Get credential from the selected vault profile final credential = await profile.defaultCredentialStorage?.getCredential( digitalCredentialId: '<Credential_ID>' ); print('Credential: $credential'); } } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }

Delete Credential

Delete a credential from the vault’s profile.

Import
import 'dart:typed_data'; import 'package:affinidi_tdk_claim_verifiable_credential/oid4vci_claim_verifiable_credential.dart'; import 'package:affinidi_tdk_vault_storages/affinidi_tdk_vault_storages.dart'; import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart'; import 'package:ssi/ssi.dart';
Example
// Must initialize vault before being able to access any of the repositories await vault.ensureInitialized(); try { // Get the list of available profiles from the vault var profiles = await vault.listProfiles(); // For demonstration purposes, we always get the last profile from the list var profile = profiles.lastOrNull; // do we have a profile selected? if (profile != null) { // Delete credential from the selected vault profile await profile.defaultCredentialStorage?.deleteCredential( digitalCredentialId: '<Credential_ID>' ); } } on TdkException catch (error) { print([error.code, error.message, error.originalMessage].join('\n')); } catch (e) { print('Error: $e'); }