affinidi_tdk_vault 1.6.0 copy "affinidi_tdk_vault: ^1.6.0" to clipboard
affinidi_tdk_vault: ^1.6.0 copied to clipboard

The Affinidi TDK Vault package provides libraries and tools for embedding Affinidi Vault into your existing Dart applications.

example/main.dart

import 'dart:typed_data';

import 'package:affinidi_tdk_vault/affinidi_tdk_vault.dart';
import 'package:affinidi_tdk_vault_data_manager/affinidi_tdk_vault_data_manager.dart';

void main() async {
  print('[Demo] Initializing Vault ...');
  // KeyStorage
  final vaultStore = InMemoryVaultStore();
  var accountIndex = 42;
  await vaultStore.setAccountIndex(accountIndex);

  // seed storage
  final seed = Uint8List.fromList(List.generate(32, (idx) => idx + 1));
  await vaultStore.setSeed(seed);

  // initialization
  const vfsRepositoryId = 'vfs';
  final profileRepositories = <String, ProfileRepository>{
    vfsRepositoryId: VfsProfileRepository(vfsRepositoryId),
  };

  // Create vault from vault store
  final vault = await Vault.fromVaultStore(
    vaultStore,
    profileRepositories: profileRepositories,
    defaultProfileRepositoryId: vfsRepositoryId,
  );

  // Must initialize vault before being able to access any of the repositories
  await vault.ensureInitialized();

  print('[Demo] Retrieving Profiles ...');

  //
  // Retrieve profiles
  //

  var profiles = await vault.listProfiles();
  print(
      '[Demo] ${profiles.isEmpty ? 'No profiles found' : 'Available profiles: ${profiles.length}'}');
  _listProfileNames(profiles, label: 'Initial profile names');

  print('[Demo] Adding new profile ...');

  // Delete all existing profiles
  await Future.wait(profiles.map((profile) => _deleteProfile(vault, profile)));

  profiles = await vault.listProfiles();
  _listProfileNames(profiles, label: 'Cleared profiles');

  //
  // Add a new profile
  //

  try {
    final profileRepository = vault.defaultProfileRepository;
    // alternatively can be accessed via profile repository identifier
    // final ProfileRepository profileRepository = vault.profileRepositories[vfsRepositoryId];
    await profileRepository.createProfile(name: 'Test ${accountIndex + 1}');
  } on TdkException catch (error) {
    print([error.code, '[Demo] ${error.message}', error.originalMessage]
        .join('\n'));
    rethrow;
  }

  _listProfileNames(profiles, label: 'Names after adding a new profiles');

  profiles = await vault.listProfiles();
  print(
      '[Demo] ${profiles.isEmpty ? 'No profiles found' : 'Available profiles: ${profiles.length}'}');
  _listProfileNames(profiles, label: 'Initial profile names');

  //
  // Update an existing profile
  //
  var profile = profiles.lastOrNull;

  if (profile == null) {
    throw UnsupportedError('Profile not available');
  }

  print('[Demo] Amending profile name ...');

  // Change the profile name

  profile.name = _makeNewName(profile);

  // Update data on repository
  // Option 1
  final profileRepository1 = vault.defaultProfileRepository;
  await profileRepository1.updateProfile(profile);
  // // Option 2
  // final profileRepository2 = vault.profileRepositories[vfsRepositoryId]!;
  // await profileRepository2.updateProfile(profile);

  // List profile names to verify change
  profiles = await vault.listProfiles();
  _listProfileNames(profiles, label: 'Names after updating added profile');

  final rootFolderId = profile.id;

  //
  // Create a file
  //
  final fileContent = Uint8List.fromList([1, 2, 3]);
  try {
    await profile.defaultFileStorage!.createFile(
      fileName: 'filename',
      data: fileContent,
      parentFolderId: rootFolderId,
    );
  } on TdkException catch (error) {
    print([error.code, error.message, error.originalMessage].join('\n'));
  }

  await Future.delayed(const Duration(seconds: 2), () {});

  print('[Demo] Listing profile files ...');

  //
  // List folder content for profile
  //

  // Option 1
  final page =
      await profile.defaultFileStorage?.getFolder(folderId: rootFolderId);
  // Option 2
  // final page = await profile.fileStorages['vfs']!.getFolder(folderId: rootFolderId);
  print('[Demo] Files available on profile: ${page?.items.length ?? 0}');

  await Future.delayed(const Duration(seconds: 2), () {});

  final fileToDownload = page?.items.firstOrNull;
  if (fileToDownload != null) {
    final retrievedFileData = await profile.defaultFileStorage
        ?.getFileContent(fileId: fileToDownload.id);
    print('[Demo] File: \n$retrievedFileData\n$fileContent');

    //
    // Delete last added file
    //

    await profile.defaultFileStorage?.deleteFile(fileId: fileToDownload.id);
    final remainingPage =
        await profile.defaultFileStorage?.getFolder(folderId: rootFolderId);
    print('Files: ${remainingPage?.items.length ?? 0}');
  } else {
    print('[Demo] Could not find any files');
  }

  //
  // Delete a profile
  //

  profile = profiles.lastOrNull;
  if (profile == null) {
    throw UnsupportedError('Profile not available');
  }

  print('[Demo] Deleting profile ...');

  // Option 1
  final profileRepository3 = vault.defaultProfileRepository;
  await profileRepository3.deleteProfile(profile);
  // // Option 3
  // final profileRepository4 = vault.profileRepositories[vfsRepositoryId]!;
  // await profileRepository4.deleteProfile(profile);

  profiles = await vault.listProfiles();
  _listProfileNames(profiles, label: 'Names after deleting profile');
}

String _makeNewName(Profile profile) {
  final separator = ' ';
  final nameParts = profile.name.split(separator);
  final originalName = nameParts.firstOrNull ?? '';
  final changeCount = int.tryParse(nameParts.lastOrNull ?? '') ?? 0;
  return '$originalName$separator${changeCount + 1}';
}

void _listProfileNames(
  List<Profile> profiles, {
  required String label,
}) {
  if (profiles.isEmpty) {
    print('[Demo] List of profiles is empty');
    return;
  }

  final names = profiles.map((profile) => profile.name).join(', ');
  print('[Demo] $label: $names');
}

Future<void> _deleteProfile(Vault vault, Profile profile) async {
  // Delete folders recursively
  await _deleteFolder(vault: vault, profile: profile, folderId: profile.id);

  // Check if profile has credentials...
  final credentials = await profile.defaultCredentialStorage!.listCredentials();
  // and delete them
  await Future.wait(credentials.items.map((item) => profile
      .defaultCredentialStorage!
      .deleteCredential(digitalCredentialId: item.id)));

  await vault.defaultProfileRepository.deleteProfile(profile);
}

Future<void> _deleteFolder({
  required Vault vault,
  required Profile profile,
  required String folderId,
}) async {
  print('Deleting folderId: $folderId');
  String? exclusiveStartItemId;

  try {
    do {
      final page = await profile.defaultFileStorage!.getFolder(
        folderId: folderId,
        limit: 20,
        exclusiveStartItemId: exclusiveStartItemId,
      );

      for (final item in page.items) {
        if (item is Folder) {
          await _deleteFolder(
              vault: vault, profile: profile, folderId: item.id);
        } else if (item is File) {
          await profile.defaultFileStorage!.deleteFile(fileId: item.id);
        }
      }

      exclusiveStartItemId = page.lastEvaluatedItemId;
    } while (exclusiveStartItemId != null);
  } catch (e) {
    print('[Demo] Error getting folder contents for $folderId: $e');
  }

  // skip root folder
  if (folderId != profile.id) {
    await profile.defaultFileStorage!.deleteFolder(folderId: folderId);
  }
}
4
likes
0
points
454
downloads

Publisher

verified publisheraffinidi.com

Weekly Downloads

The Affinidi TDK Vault package provides libraries and tools for embedding Affinidi Vault into your existing Dart applications.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

affinidi_tdk_common, ssi

More

Packages that depend on affinidi_tdk_vault