import 'dart:convert'; import 'dart:typed_data'; import 'package:fast_immutable_collections/fast_immutable_collections.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:veilid/veilid.dart'; import '../entities/entities.dart'; import '../entities/proto.dart' as proto; part 'local_account_manager.g.dart'; // Local account manager class LocalAccountManager { final VeilidTableDB _localAccountsTable; final IList _localAccounts; const LocalAccountManager( {required VeilidTableDB localAccountsTable, required IList localAccounts}) : _localAccountsTable = localAccountsTable, _localAccounts = localAccounts; /// Gets or creates a local account manager static Future open() async { final localAccountsTable = await Veilid.instance.openTableDB("local_account_manager", 1); final localAccounts = (await localAccountsTable.loadStringJson(0, "local_accounts") ?? const IListConst([])) as IList; return LocalAccountManager( localAccountsTable: localAccountsTable, localAccounts: localAccounts); } /// Flush things to storage Future flush() async {} /// Creates a new master identity and returns it with its secrets Future newIdentityMaster() async { final dhtctx = (await Veilid.instance.routingContext()) .withPrivacy() .withSequencing(Sequencing.ensureOrdered); final masterRec = await dhtctx.createDHTRecord(const DHTSchema.dflt(oCnt: 1)); final identityRec = await dhtctx.createDHTRecord(const DHTSchema.dflt(oCnt: 1)); final crypto = await Veilid.instance.bestCryptoSystem(); assert(masterRec.key.kind == crypto.kind()); assert(identityRec.key.kind == crypto.kind()); // IdentityMaster final masterRecordKey = masterRec.key; final masterPublicKey = masterRec.owner; final masterSecret = masterRec.ownerSecret!; final masterSigBuf = masterRecordKey.decode() ..addAll(masterPublicKey.decode()); final identityRecordKey = identityRec.key; final identityPublicKey = identityRec.owner; final identitySecret = identityRec.ownerSecret!; final identitySigBuf = identityRecordKey.decode() ..addAll(identityPublicKey.decode()); final identitySignature = await crypto.sign(masterPublicKey, masterSecret, identitySigBuf); final masterSignature = await crypto.sign(identityPublicKey, identitySecret, masterSigBuf); final identityMaster = IdentityMaster( identityRecordKey: identityRecordKey, identityPublicKey: identityPublicKey, masterRecordKey: masterRecordKey, masterPublicKey: masterPublicKey, identitySignature: identitySignature, masterSignature: masterSignature); // Write identity master to master dht key final identityMasterBytes = Uint8List.fromList(utf8.encode(jsonEncode(identityMaster))); await dhtctx.setDHTValue(masterRecordKey, 0, identityMasterBytes); return IdentityMasterWithSecrets( identityMaster: identityMaster, masterSecret: masterSecret, identitySecret: identitySecret); } /// Creates a new account associated with master identity Future newAccount( IdentityMaster identityMaster, SecretKey identitySecret, EncryptionKeyType encryptionKeyType, String encryptionKey) async { // return LocalAccount( identityMaster: identityMaster, identitySecretKeyBytes: identitySecretBytes, encryptionKeyType: encryptionKeyType, biometricsEnabled: false, hiddenAccount: false, ); } } @riverpod Future localAccountManager(LocalAccountManagerRef ref) { return LocalAccountManager.open(); }