proto cleanup

This commit is contained in:
Christien Rioux 2023-09-26 18:46:02 -04:00
parent f951acd79a
commit a93c711d52
84 changed files with 2393 additions and 2087 deletions

View File

@ -1,6 +1,9 @@
#!/bin/bash
set -e
dart run build_runner build
pushd lib/entities > /dev/null
protoc --dart_out=proto veilidchat.proto
popd > /dev/null
pushd lib > /dev/null
protoc --dart_out=proto -I veilid_support/proto -I veilid_support/dht_support/proto -I proto veilidchat.proto
protoc --dart_out=proto -I veilid_support/proto -I veilid_support/dht_support/proto dht.proto
protoc --dart_out=proto -I veilid_support/proto veilid.proto
popd > /dev/null

View File

@ -7,12 +7,12 @@ import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:uuid/uuid.dart';
import '../../entities/proto.dart' as proto;
import '../entities/identity.dart';
import '../proto/proto.dart' as proto;
import '../providers/account.dart';
import '../providers/chat.dart';
import '../providers/conversation.dart';
import '../tools/tools.dart';
import '../veilid_init.dart';
import '../veilid_support/veilid_support.dart';
class ChatComponent extends ConsumerStatefulWidget {

View File

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:flutter_translate/flutter_translate.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../providers/account.dart';
import '../providers/chat.dart';
import '../tools/theme_service.dart';

View File

@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:searchable_listview/searchable_listview.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../tools/tools.dart';
import 'chat_single_contact_item_widget.dart';
import 'empty_chat_list_widget.dart';

View File

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:flutter_translate/flutter_translate.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../providers/account.dart';
import '../providers/contact_invite.dart';
import '../tools/tools.dart';

View File

@ -3,12 +3,12 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../tools/tools.dart';
import 'contact_invitation_item_widget.dart';
class ContactInvitationListWidget extends ConsumerStatefulWidget {
ContactInvitationListWidget({
const ContactInvitationListWidget({
required this.contactInvitationRecordList,
super.key,
});

View File

@ -4,7 +4,7 @@ import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:flutter_translate/flutter_translate.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../pages/main_pager/main_pager.dart';
import '../providers/account.dart';
import '../providers/chat.dart';

View File

@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:searchable_listview/searchable_listview.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../tools/tools.dart';
import 'contact_item_widget.dart';
import 'empty_contact_list_widget.dart';

View File

@ -15,7 +15,6 @@ class NoContactWidget extends ConsumerWidget {
color: Theme.of(context).primaryColor,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(

View File

@ -1,7 +1,6 @@
import 'dart:async';
import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
@ -340,9 +339,4 @@ class PasteInviteDialogState extends ConsumerState<PasteInviteDialog> {
),
);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
}
}

View File

@ -1,4 +1,3 @@
export 'identity.dart';
export 'local_account.dart';
export 'preferences.dart';
export 'user_login.dart';

View File

@ -1,184 +0,0 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../veilid_support/veilid_support.dart';
import 'proto.dart' as proto;
part 'identity.freezed.dart';
part 'identity.g.dart';
const String veilidChatAccountKey = 'com.veilid.veilidchat';
// AccountOwnerInfo is the key and owner info for the account dht key that is
// stored in the identity key
@freezed
class AccountRecordInfo with _$AccountRecordInfo {
const factory AccountRecordInfo({
// Top level account keys and secrets
required OwnedDHTRecordPointer accountRecord,
}) = _AccountRecordInfo;
factory AccountRecordInfo.fromJson(dynamic json) =>
_$AccountRecordInfoFromJson(json as Map<String, dynamic>);
}
// Identity Key points to accounts associated with this identity
// accounts field has a map of bundle id or uuid to account key pairs
// DHT Schema: DFLT(1)
// DHT Key (Private): identityRecordKey
// DHT Owner Key: identityPublicKey
// DHT Secret: identitySecretKey (stored encrypted
// with unlock code in local table store)
@freezed
class Identity with _$Identity {
const factory Identity({
// Top level account keys and secrets
required IMap<String, ISet<AccountRecordInfo>> accountRecords,
}) = _Identity;
factory Identity.fromJson(dynamic json) =>
_$IdentityFromJson(json as Map<String, dynamic>);
}
// Identity Master key structure for created account
// Master key allows for regeneration of identity DHT record
// Bidirectional Master<->Identity signature allows for
// chain of identity ownership for account recovery process
//
// Backed by a DHT key at masterRecordKey, the secret is kept
// completely offline and only written to upon account recovery
//
// DHT Schema: DFLT(1)
// DHT Record Key (Public): masterRecordKey
// DHT Owner Key: masterPublicKey
// DHT Owner Secret: masterSecretKey (kept offline)
// Encryption: None
@freezed
class IdentityMaster with _$IdentityMaster {
const factory IdentityMaster(
{
// Private DHT record storing identity account mapping
required TypedKey identityRecordKey,
// Public key of identity
required PublicKey identityPublicKey,
// Public DHT record storing this structure for account recovery
required TypedKey masterRecordKey,
// Public key of master identity used to sign identity keys for recovery
required PublicKey masterPublicKey,
// Signature of identityRecordKey and identityPublicKey by masterPublicKey
required Signature identitySignature,
// Signature of masterRecordKey and masterPublicKey by identityPublicKey
required Signature masterSignature}) = _IdentityMaster;
factory IdentityMaster.fromJson(dynamic json) =>
_$IdentityMasterFromJson(json as Map<String, dynamic>);
}
extension IdentityMasterExtension on IdentityMaster {
KeyPair identityWriter(SecretKey secret) =>
KeyPair(key: identityPublicKey, secret: secret);
KeyPair masterWriter(SecretKey secret) =>
KeyPair(key: masterPublicKey, secret: secret);
TypedKey identityPublicTypedKey() =>
TypedKey(kind: identityRecordKey.kind, value: identityPublicKey);
Future<AccountRecordInfo> readAccountFromIdentity(
{required SharedSecret identitySecret}) async {
// Read the identity key to get the account keys
final pool = await DHTRecordPool.instance();
final identityRecordCrypto = await DHTRecordCryptoPrivate.fromSecret(
identityRecordKey.kind, identitySecret);
late final AccountRecordInfo accountRecordInfo;
await (await pool.openRead(identityRecordKey,
parent: masterRecordKey, crypto: identityRecordCrypto))
.scope((identityRec) async {
final identity = await identityRec.getJson(Identity.fromJson);
if (identity == null) {
// Identity could not be read or decrypted from DHT
throw StateError('identity could not be read');
}
final accountRecords = IMapOfSets.from(identity.accountRecords);
final vcAccounts = accountRecords.get(veilidChatAccountKey);
if (vcAccounts.length != 1) {
// No veilidchat account, or multiple accounts
// somehow associated with identity
throw StateError('no single veilidchat account');
}
accountRecordInfo = vcAccounts.first;
});
return accountRecordInfo;
}
/// Creates a new Account associated with master identity and store it in the
/// identity key.
Future<void> newAccount({
required SharedSecret identitySecret,
required String name,
required String title,
}) async {
final pool = await DHTRecordPool.instance();
/////// Add account with profile to DHT
// Open identity key for writing
await (await pool.openWrite(
identityRecordKey, identityWriter(identitySecret),
parent: masterRecordKey))
.scope((identityRec) async {
// Create new account to insert into identity
await (await pool.create(parent: identityRec.key))
.deleteScope((accountRec) async {
// Make empty contact list
final contactList =
await (await DHTShortArray.create(parent: accountRec.key))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make empty contact invitation record list
final contactInvitationRecords =
await (await DHTShortArray.create(parent: accountRec.key))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make empty chat record list
final chatRecords =
await (await DHTShortArray.create(parent: accountRec.key))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make account object
final account = proto.Account()
..profile = (proto.Profile()
..name = name
..title = title)
..contactList = contactList.toProto()
..contactInvitationRecords = contactInvitationRecords.toProto()
..chatList = chatRecords.toProto();
// Write account key
await accountRec.eventualWriteProtobuf(account);
// Update identity key to include account
final newAccountRecordInfo = AccountRecordInfo(
accountRecord: OwnedDHTRecordPointer(
recordKey: accountRec.key, owner: accountRec.ownerKeyPair!));
await identityRec.eventualUpdateJson(Identity.fromJson,
(oldIdentity) async {
final oldAccountRecords = IMapOfSets.from(oldIdentity.accountRecords);
// Only allow one account per identity for veilidchat
if (oldAccountRecords.get(veilidChatAccountKey).isNotEmpty) {
throw StateError(
'Only one account per identity allowed for VeilidChat');
}
final accountRecords = oldAccountRecords
.add(veilidChatAccountKey, newAccountRecordInfo)
.asIMap();
return oldIdentity.copyWith(accountRecords: accountRecords);
});
});
});
}
}

View File

@ -3,9 +3,8 @@ import 'dart:typed_data';
import 'package:change_case/change_case.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../veilid_support/veilid_support.dart';
import 'identity.dart';
part 'local_account.freezed.dart';
part 'local_account.g.dart';

View File

@ -1,514 +0,0 @@
//
// Generated code. Do not modify.
// source: veilidchat.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use attachmentKindDescriptor instead')
const AttachmentKind$json = {
'1': 'AttachmentKind',
'2': [
{'1': 'ATTACHMENT_KIND_UNSPECIFIED', '2': 0},
{'1': 'ATTACHMENT_KIND_FILE', '2': 1},
{'1': 'ATTACHMENT_KIND_IMAGE', '2': 2},
],
};
/// Descriptor for `AttachmentKind`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List attachmentKindDescriptor = $convert.base64Decode(
'Cg5BdHRhY2htZW50S2luZBIfChtBVFRBQ0hNRU5UX0tJTkRfVU5TUEVDSUZJRUQQABIYChRBVF'
'RBQ0hNRU5UX0tJTkRfRklMRRABEhkKFUFUVEFDSE1FTlRfS0lORF9JTUFHRRAC');
@$core.Deprecated('Use availabilityDescriptor instead')
const Availability$json = {
'1': 'Availability',
'2': [
{'1': 'AVAILABILITY_UNSPECIFIED', '2': 0},
{'1': 'AVAILABILITY_OFFLINE', '2': 1},
{'1': 'AVAILABILITY_FREE', '2': 2},
{'1': 'AVAILABILITY_BUSY', '2': 3},
{'1': 'AVAILABILITY_AWAY', '2': 4},
],
};
/// Descriptor for `Availability`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List availabilityDescriptor = $convert.base64Decode(
'CgxBdmFpbGFiaWxpdHkSHAoYQVZBSUxBQklMSVRZX1VOU1BFQ0lGSUVEEAASGAoUQVZBSUxBQk'
'lMSVRZX09GRkxJTkUQARIVChFBVkFJTEFCSUxJVFlfRlJFRRACEhUKEUFWQUlMQUJJTElUWV9C'
'VVNZEAMSFQoRQVZBSUxBQklMSVRZX0FXQVkQBA==');
@$core.Deprecated('Use chatTypeDescriptor instead')
const ChatType$json = {
'1': 'ChatType',
'2': [
{'1': 'CHAT_TYPE_UNSPECIFIED', '2': 0},
{'1': 'SINGLE_CONTACT', '2': 1},
{'1': 'GROUP', '2': 2},
],
};
/// Descriptor for `ChatType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List chatTypeDescriptor = $convert.base64Decode(
'CghDaGF0VHlwZRIZChVDSEFUX1RZUEVfVU5TUEVDSUZJRUQQABISCg5TSU5HTEVfQ09OVEFDVB'
'ABEgkKBUdST1VQEAI=');
@$core.Deprecated('Use encryptionKeyTypeDescriptor instead')
const EncryptionKeyType$json = {
'1': 'EncryptionKeyType',
'2': [
{'1': 'ENCRYPTION_KEY_TYPE_UNSPECIFIED', '2': 0},
{'1': 'ENCRYPTION_KEY_TYPE_NONE', '2': 1},
{'1': 'ENCRYPTION_KEY_TYPE_PIN', '2': 2},
{'1': 'ENCRYPTION_KEY_TYPE_PASSWORD', '2': 3},
],
};
/// Descriptor for `EncryptionKeyType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List encryptionKeyTypeDescriptor = $convert.base64Decode(
'ChFFbmNyeXB0aW9uS2V5VHlwZRIjCh9FTkNSWVBUSU9OX0tFWV9UWVBFX1VOU1BFQ0lGSUVEEA'
'ASHAoYRU5DUllQVElPTl9LRVlfVFlQRV9OT05FEAESGwoXRU5DUllQVElPTl9LRVlfVFlQRV9Q'
'SU4QAhIgChxFTkNSWVBUSU9OX0tFWV9UWVBFX1BBU1NXT1JEEAM=');
@$core.Deprecated('Use cryptoKeyDescriptor instead')
const CryptoKey$json = {
'1': 'CryptoKey',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
{'1': 'u6', '3': 7, '4': 1, '5': 7, '10': 'u6'},
{'1': 'u7', '3': 8, '4': 1, '5': 7, '10': 'u7'},
],
};
/// Descriptor for `CryptoKey`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cryptoKeyDescriptor = $convert.base64Decode(
'CglDcnlwdG9LZXkSDgoCdTAYASABKAdSAnUwEg4KAnUxGAIgASgHUgJ1MRIOCgJ1MhgDIAEoB1'
'ICdTISDgoCdTMYBCABKAdSAnUzEg4KAnU0GAUgASgHUgJ1NBIOCgJ1NRgGIAEoB1ICdTUSDgoC'
'dTYYByABKAdSAnU2Eg4KAnU3GAggASgHUgJ1Nw==');
@$core.Deprecated('Use signatureDescriptor instead')
const Signature$json = {
'1': 'Signature',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
{'1': 'u6', '3': 7, '4': 1, '5': 7, '10': 'u6'},
{'1': 'u7', '3': 8, '4': 1, '5': 7, '10': 'u7'},
{'1': 'u8', '3': 9, '4': 1, '5': 7, '10': 'u8'},
{'1': 'u9', '3': 10, '4': 1, '5': 7, '10': 'u9'},
{'1': 'u10', '3': 11, '4': 1, '5': 7, '10': 'u10'},
{'1': 'u11', '3': 12, '4': 1, '5': 7, '10': 'u11'},
{'1': 'u12', '3': 13, '4': 1, '5': 7, '10': 'u12'},
{'1': 'u13', '3': 14, '4': 1, '5': 7, '10': 'u13'},
{'1': 'u14', '3': 15, '4': 1, '5': 7, '10': 'u14'},
{'1': 'u15', '3': 16, '4': 1, '5': 7, '10': 'u15'},
],
};
/// Descriptor for `Signature`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signatureDescriptor = $convert.base64Decode(
'CglTaWduYXR1cmUSDgoCdTAYASABKAdSAnUwEg4KAnUxGAIgASgHUgJ1MRIOCgJ1MhgDIAEoB1'
'ICdTISDgoCdTMYBCABKAdSAnUzEg4KAnU0GAUgASgHUgJ1NBIOCgJ1NRgGIAEoB1ICdTUSDgoC'
'dTYYByABKAdSAnU2Eg4KAnU3GAggASgHUgJ1NxIOCgJ1OBgJIAEoB1ICdTgSDgoCdTkYCiABKA'
'dSAnU5EhAKA3UxMBgLIAEoB1IDdTEwEhAKA3UxMRgMIAEoB1IDdTExEhAKA3UxMhgNIAEoB1ID'
'dTEyEhAKA3UxMxgOIAEoB1IDdTEzEhAKA3UxNBgPIAEoB1IDdTE0EhAKA3UxNRgQIAEoB1IDdT'
'E1');
@$core.Deprecated('Use nonceDescriptor instead')
const Nonce$json = {
'1': 'Nonce',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
],
};
/// Descriptor for `Nonce`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List nonceDescriptor = $convert.base64Decode(
'CgVOb25jZRIOCgJ1MBgBIAEoB1ICdTASDgoCdTEYAiABKAdSAnUxEg4KAnUyGAMgASgHUgJ1Mh'
'IOCgJ1MxgEIAEoB1ICdTMSDgoCdTQYBSABKAdSAnU0Eg4KAnU1GAYgASgHUgJ1NQ==');
@$core.Deprecated('Use typedKeyDescriptor instead')
const TypedKey$json = {
'1': 'TypedKey',
'2': [
{'1': 'kind', '3': 1, '4': 1, '5': 7, '10': 'kind'},
{'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'value'},
],
};
/// Descriptor for `TypedKey`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List typedKeyDescriptor = $convert.base64Decode(
'CghUeXBlZEtleRISCgRraW5kGAEgASgHUgRraW5kEiAKBXZhbHVlGAIgASgLMgouQ3J5cHRvS2'
'V5UgV2YWx1ZQ==');
@$core.Deprecated('Use keyPairDescriptor instead')
const KeyPair$json = {
'1': 'KeyPair',
'2': [
{'1': 'key', '3': 1, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'key'},
{'1': 'secret', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'secret'},
],
};
/// Descriptor for `KeyPair`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List keyPairDescriptor = $convert.base64Decode(
'CgdLZXlQYWlyEhwKA2tleRgBIAEoCzIKLkNyeXB0b0tleVIDa2V5EiIKBnNlY3JldBgCIAEoCz'
'IKLkNyeXB0b0tleVIGc2VjcmV0');
@$core.Deprecated('Use dHTDataDescriptor instead')
const DHTData$json = {
'1': 'DHTData',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.TypedKey', '10': 'keys'},
{'1': 'hash', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'hash'},
{'1': 'chunk', '3': 3, '4': 1, '5': 13, '10': 'chunk'},
{'1': 'size', '3': 4, '4': 1, '5': 13, '10': 'size'},
],
};
/// Descriptor for `DHTData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTDataDescriptor = $convert.base64Decode(
'CgdESFREYXRhEh0KBGtleXMYASADKAsyCS5UeXBlZEtleVIEa2V5cxIdCgRoYXNoGAIgASgLMg'
'kuVHlwZWRLZXlSBGhhc2gSFAoFY2h1bmsYAyABKA1SBWNodW5rEhIKBHNpemUYBCABKA1SBHNp'
'emU=');
@$core.Deprecated('Use dHTShortArrayDescriptor instead')
const DHTShortArray$json = {
'1': 'DHTShortArray',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.TypedKey', '10': 'keys'},
{'1': 'index', '3': 2, '4': 1, '5': 12, '10': 'index'},
],
};
/// Descriptor for `DHTShortArray`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTShortArrayDescriptor = $convert.base64Decode(
'Cg1ESFRTaG9ydEFycmF5Eh0KBGtleXMYASADKAsyCS5UeXBlZEtleVIEa2V5cxIUCgVpbmRleB'
'gCIAEoDFIFaW5kZXg=');
@$core.Deprecated('Use dHTLogDescriptor instead')
const DHTLog$json = {
'1': 'DHTLog',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.TypedKey', '10': 'keys'},
{'1': 'back', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'back'},
{'1': 'subkey_counts', '3': 3, '4': 3, '5': 13, '10': 'subkeyCounts'},
{'1': 'total_subkeys', '3': 4, '4': 1, '5': 13, '10': 'totalSubkeys'},
],
};
/// Descriptor for `DHTLog`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTLogDescriptor = $convert.base64Decode(
'CgZESFRMb2cSHQoEa2V5cxgBIAMoCzIJLlR5cGVkS2V5UgRrZXlzEh0KBGJhY2sYAiABKAsyCS'
'5UeXBlZEtleVIEYmFjaxIjCg1zdWJrZXlfY291bnRzGAMgAygNUgxzdWJrZXlDb3VudHMSIwoN'
'dG90YWxfc3Via2V5cxgEIAEoDVIMdG90YWxTdWJrZXlz');
@$core.Deprecated('Use dataReferenceDescriptor instead')
const DataReference$json = {
'1': 'DataReference',
'2': [
{'1': 'dht_data', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '9': 0, '10': 'dhtData'},
],
'8': [
{'1': 'kind'},
],
};
/// Descriptor for `DataReference`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dataReferenceDescriptor = $convert.base64Decode(
'Cg1EYXRhUmVmZXJlbmNlEiYKCGRodF9kYXRhGAEgASgLMgkuVHlwZWRLZXlIAFIHZGh0RGF0YU'
'IGCgRraW5k');
@$core.Deprecated('Use attachmentDescriptor instead')
const Attachment$json = {
'1': 'Attachment',
'2': [
{'1': 'kind', '3': 1, '4': 1, '5': 14, '6': '.AttachmentKind', '10': 'kind'},
{'1': 'mime', '3': 2, '4': 1, '5': 9, '10': 'mime'},
{'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
{'1': 'content', '3': 4, '4': 1, '5': 11, '6': '.DataReference', '10': 'content'},
{'1': 'signature', '3': 5, '4': 1, '5': 11, '6': '.Signature', '10': 'signature'},
],
};
/// Descriptor for `Attachment`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List attachmentDescriptor = $convert.base64Decode(
'CgpBdHRhY2htZW50EiMKBGtpbmQYASABKA4yDy5BdHRhY2htZW50S2luZFIEa2luZBISCgRtaW'
'1lGAIgASgJUgRtaW1lEhIKBG5hbWUYAyABKAlSBG5hbWUSKAoHY29udGVudBgEIAEoCzIOLkRh'
'dGFSZWZlcmVuY2VSB2NvbnRlbnQSKAoJc2lnbmF0dXJlGAUgASgLMgouU2lnbmF0dXJlUglzaW'
'duYXR1cmU=');
@$core.Deprecated('Use messageDescriptor instead')
const Message$json = {
'1': 'Message',
'2': [
{'1': 'author', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'author'},
{'1': 'timestamp', '3': 2, '4': 1, '5': 4, '10': 'timestamp'},
{'1': 'text', '3': 3, '4': 1, '5': 9, '10': 'text'},
{'1': 'signature', '3': 4, '4': 1, '5': 11, '6': '.Signature', '10': 'signature'},
{'1': 'attachments', '3': 5, '4': 3, '5': 11, '6': '.Attachment', '10': 'attachments'},
],
};
/// Descriptor for `Message`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List messageDescriptor = $convert.base64Decode(
'CgdNZXNzYWdlEiEKBmF1dGhvchgBIAEoCzIJLlR5cGVkS2V5UgZhdXRob3ISHAoJdGltZXN0YW'
'1wGAIgASgEUgl0aW1lc3RhbXASEgoEdGV4dBgDIAEoCVIEdGV4dBIoCglzaWduYXR1cmUYBCAB'
'KAsyCi5TaWduYXR1cmVSCXNpZ25hdHVyZRItCgthdHRhY2htZW50cxgFIAMoCzILLkF0dGFjaG'
'1lbnRSC2F0dGFjaG1lbnRz');
@$core.Deprecated('Use conversationDescriptor instead')
const Conversation$json = {
'1': 'Conversation',
'2': [
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
{'1': 'identity_master_json', '3': 2, '4': 1, '5': 9, '10': 'identityMasterJson'},
{'1': 'messages', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'messages'},
],
};
/// Descriptor for `Conversation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List conversationDescriptor = $convert.base64Decode(
'CgxDb252ZXJzYXRpb24SIgoHcHJvZmlsZRgBIAEoCzIILlByb2ZpbGVSB3Byb2ZpbGUSMAoUaW'
'RlbnRpdHlfbWFzdGVyX2pzb24YAiABKAlSEmlkZW50aXR5TWFzdGVySnNvbhIlCghtZXNzYWdl'
'cxgDIAEoCzIJLlR5cGVkS2V5UghtZXNzYWdlcw==');
@$core.Deprecated('Use contactDescriptor instead')
const Contact$json = {
'1': 'Contact',
'2': [
{'1': 'edited_profile', '3': 1, '4': 1, '5': 11, '6': '.Profile', '10': 'editedProfile'},
{'1': 'remote_profile', '3': 2, '4': 1, '5': 11, '6': '.Profile', '10': 'remoteProfile'},
{'1': 'identity_master_json', '3': 3, '4': 1, '5': 9, '10': 'identityMasterJson'},
{'1': 'identity_public_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'identityPublicKey'},
{'1': 'remote_conversation_record_key', '3': 5, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationRecordKey'},
{'1': 'local_conversation_record_key', '3': 6, '4': 1, '5': 11, '6': '.TypedKey', '10': 'localConversationRecordKey'},
{'1': 'show_availability', '3': 7, '4': 1, '5': 8, '10': 'showAvailability'},
],
};
/// Descriptor for `Contact`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactDescriptor = $convert.base64Decode(
'CgdDb250YWN0Ei8KDmVkaXRlZF9wcm9maWxlGAEgASgLMgguUHJvZmlsZVINZWRpdGVkUHJvZm'
'lsZRIvCg5yZW1vdGVfcHJvZmlsZRgCIAEoCzIILlByb2ZpbGVSDXJlbW90ZVByb2ZpbGUSMAoU'
'aWRlbnRpdHlfbWFzdGVyX2pzb24YAyABKAlSEmlkZW50aXR5TWFzdGVySnNvbhI5ChNpZGVudG'
'l0eV9wdWJsaWNfa2V5GAQgASgLMgkuVHlwZWRLZXlSEWlkZW50aXR5UHVibGljS2V5Ek4KHnJl'
'bW90ZV9jb252ZXJzYXRpb25fcmVjb3JkX2tleRgFIAEoCzIJLlR5cGVkS2V5UhtyZW1vdGVDb2'
'52ZXJzYXRpb25SZWNvcmRLZXkSTAodbG9jYWxfY29udmVyc2F0aW9uX3JlY29yZF9rZXkYBiAB'
'KAsyCS5UeXBlZEtleVIabG9jYWxDb252ZXJzYXRpb25SZWNvcmRLZXkSKwoRc2hvd19hdmFpbG'
'FiaWxpdHkYByABKAhSEHNob3dBdmFpbGFiaWxpdHk=');
@$core.Deprecated('Use profileDescriptor instead')
const Profile$json = {
'1': 'Profile',
'2': [
{'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
{'1': 'title', '3': 2, '4': 1, '5': 9, '10': 'title'},
{'1': 'status', '3': 3, '4': 1, '5': 9, '10': 'status'},
{'1': 'availability', '3': 4, '4': 1, '5': 14, '6': '.Availability', '10': 'availability'},
{'1': 'avatar', '3': 5, '4': 1, '5': 11, '6': '.TypedKey', '9': 0, '10': 'avatar', '17': true},
],
'8': [
{'1': '_avatar'},
],
};
/// Descriptor for `Profile`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List profileDescriptor = $convert.base64Decode(
'CgdQcm9maWxlEhIKBG5hbWUYASABKAlSBG5hbWUSFAoFdGl0bGUYAiABKAlSBXRpdGxlEhYKBn'
'N0YXR1cxgDIAEoCVIGc3RhdHVzEjEKDGF2YWlsYWJpbGl0eRgEIAEoDjINLkF2YWlsYWJpbGl0'
'eVIMYXZhaWxhYmlsaXR5EiYKBmF2YXRhchgFIAEoCzIJLlR5cGVkS2V5SABSBmF2YXRhcogBAU'
'IJCgdfYXZhdGFy');
@$core.Deprecated('Use ownedDHTRecordPointerDescriptor instead')
const OwnedDHTRecordPointer$json = {
'1': 'OwnedDHTRecordPointer',
'2': [
{'1': 'record_key', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'recordKey'},
{'1': 'owner', '3': 2, '4': 1, '5': 11, '6': '.KeyPair', '10': 'owner'},
],
};
/// Descriptor for `OwnedDHTRecordPointer`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List ownedDHTRecordPointerDescriptor = $convert.base64Decode(
'ChVPd25lZERIVFJlY29yZFBvaW50ZXISKAoKcmVjb3JkX2tleRgBIAEoCzIJLlR5cGVkS2V5Ug'
'lyZWNvcmRLZXkSHgoFb3duZXIYAiABKAsyCC5LZXlQYWlyUgVvd25lcg==');
@$core.Deprecated('Use chatDescriptor instead')
const Chat$json = {
'1': 'Chat',
'2': [
{'1': 'type', '3': 1, '4': 1, '5': 14, '6': '.ChatType', '10': 'type'},
{'1': 'remote_conversation_key', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationKey'},
],
};
/// Descriptor for `Chat`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List chatDescriptor = $convert.base64Decode(
'CgRDaGF0Eh0KBHR5cGUYASABKA4yCS5DaGF0VHlwZVIEdHlwZRJBChdyZW1vdGVfY29udmVyc2'
'F0aW9uX2tleRgCIAEoCzIJLlR5cGVkS2V5UhVyZW1vdGVDb252ZXJzYXRpb25LZXk=');
@$core.Deprecated('Use accountDescriptor instead')
const Account$json = {
'1': 'Account',
'2': [
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
{'1': 'invisible', '3': 2, '4': 1, '5': 8, '10': 'invisible'},
{'1': 'auto_away_timeout_sec', '3': 3, '4': 1, '5': 13, '10': 'autoAwayTimeoutSec'},
{'1': 'contact_list', '3': 4, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'contactList'},
{'1': 'contact_invitation_records', '3': 5, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'contactInvitationRecords'},
{'1': 'chat_list', '3': 6, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'chatList'},
],
};
/// Descriptor for `Account`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List accountDescriptor = $convert.base64Decode(
'CgdBY2NvdW50EiIKB3Byb2ZpbGUYASABKAsyCC5Qcm9maWxlUgdwcm9maWxlEhwKCWludmlzaW'
'JsZRgCIAEoCFIJaW52aXNpYmxlEjEKFWF1dG9fYXdheV90aW1lb3V0X3NlYxgDIAEoDVISYXV0'
'b0F3YXlUaW1lb3V0U2VjEjkKDGNvbnRhY3RfbGlzdBgEIAEoCzIWLk93bmVkREhUUmVjb3JkUG'
'9pbnRlclILY29udGFjdExpc3QSVAoaY29udGFjdF9pbnZpdGF0aW9uX3JlY29yZHMYBSABKAsy'
'Fi5Pd25lZERIVFJlY29yZFBvaW50ZXJSGGNvbnRhY3RJbnZpdGF0aW9uUmVjb3JkcxIzCgljaG'
'F0X2xpc3QYBiABKAsyFi5Pd25lZERIVFJlY29yZFBvaW50ZXJSCGNoYXRMaXN0');
@$core.Deprecated('Use contactInvitationDescriptor instead')
const ContactInvitation$json = {
'1': 'ContactInvitation',
'2': [
{'1': 'contact_request_inbox_key', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'contactRequestInboxKey'},
{'1': 'writer_secret', '3': 2, '4': 1, '5': 12, '10': 'writerSecret'},
],
};
/// Descriptor for `ContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactInvitationDescriptor = $convert.base64Decode(
'ChFDb250YWN0SW52aXRhdGlvbhJEChljb250YWN0X3JlcXVlc3RfaW5ib3hfa2V5GAEgASgLMg'
'kuVHlwZWRLZXlSFmNvbnRhY3RSZXF1ZXN0SW5ib3hLZXkSIwoNd3JpdGVyX3NlY3JldBgCIAEo'
'DFIMd3JpdGVyU2VjcmV0');
@$core.Deprecated('Use signedContactInvitationDescriptor instead')
const SignedContactInvitation$json = {
'1': 'SignedContactInvitation',
'2': [
{'1': 'contact_invitation', '3': 1, '4': 1, '5': 12, '10': 'contactInvitation'},
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.Signature', '10': 'identitySignature'},
],
};
/// Descriptor for `SignedContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signedContactInvitationDescriptor = $convert.base64Decode(
'ChdTaWduZWRDb250YWN0SW52aXRhdGlvbhItChJjb250YWN0X2ludml0YXRpb24YASABKAxSEW'
'NvbnRhY3RJbnZpdGF0aW9uEjkKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIKLlNpZ25hdHVy'
'ZVIRaWRlbnRpdHlTaWduYXR1cmU=');
@$core.Deprecated('Use contactRequestDescriptor instead')
const ContactRequest$json = {
'1': 'ContactRequest',
'2': [
{'1': 'encryption_key_type', '3': 1, '4': 1, '5': 14, '6': '.EncryptionKeyType', '10': 'encryptionKeyType'},
{'1': 'private', '3': 2, '4': 1, '5': 12, '10': 'private'},
],
};
/// Descriptor for `ContactRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactRequestDescriptor = $convert.base64Decode(
'Cg5Db250YWN0UmVxdWVzdBJCChNlbmNyeXB0aW9uX2tleV90eXBlGAEgASgOMhIuRW5jcnlwdG'
'lvbktleVR5cGVSEWVuY3J5cHRpb25LZXlUeXBlEhgKB3ByaXZhdGUYAiABKAxSB3ByaXZhdGU=');
@$core.Deprecated('Use contactRequestPrivateDescriptor instead')
const ContactRequestPrivate$json = {
'1': 'ContactRequestPrivate',
'2': [
{'1': 'writer_key', '3': 1, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerKey'},
{'1': 'profile', '3': 2, '4': 1, '5': 11, '6': '.Profile', '10': 'profile'},
{'1': 'identity_master_record_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'identityMasterRecordKey'},
{'1': 'chat_record_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'chatRecordKey'},
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
],
};
/// Descriptor for `ContactRequestPrivate`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactRequestPrivateDescriptor = $convert.base64Decode(
'ChVDb250YWN0UmVxdWVzdFByaXZhdGUSKQoKd3JpdGVyX2tleRgBIAEoCzIKLkNyeXB0b0tleV'
'IJd3JpdGVyS2V5EiIKB3Byb2ZpbGUYAiABKAsyCC5Qcm9maWxlUgdwcm9maWxlEkYKGmlkZW50'
'aXR5X21hc3Rlcl9yZWNvcmRfa2V5GAMgASgLMgkuVHlwZWRLZXlSF2lkZW50aXR5TWFzdGVyUm'
'Vjb3JkS2V5EjEKD2NoYXRfcmVjb3JkX2tleRgEIAEoCzIJLlR5cGVkS2V5Ug1jaGF0UmVjb3Jk'
'S2V5Eh4KCmV4cGlyYXRpb24YBSABKARSCmV4cGlyYXRpb24=');
@$core.Deprecated('Use contactResponseDescriptor instead')
const ContactResponse$json = {
'1': 'ContactResponse',
'2': [
{'1': 'accept', '3': 1, '4': 1, '5': 8, '10': 'accept'},
{'1': 'identity_master_record_key', '3': 2, '4': 1, '5': 11, '6': '.TypedKey', '10': 'identityMasterRecordKey'},
{'1': 'remote_conversation_record_key', '3': 3, '4': 1, '5': 11, '6': '.TypedKey', '10': 'remoteConversationRecordKey'},
],
};
/// Descriptor for `ContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactResponseDescriptor = $convert.base64Decode(
'Cg9Db250YWN0UmVzcG9uc2USFgoGYWNjZXB0GAEgASgIUgZhY2NlcHQSRgoaaWRlbnRpdHlfbW'
'FzdGVyX3JlY29yZF9rZXkYAiABKAsyCS5UeXBlZEtleVIXaWRlbnRpdHlNYXN0ZXJSZWNvcmRL'
'ZXkSTgoecmVtb3RlX2NvbnZlcnNhdGlvbl9yZWNvcmRfa2V5GAMgASgLMgkuVHlwZWRLZXlSG3'
'JlbW90ZUNvbnZlcnNhdGlvblJlY29yZEtleQ==');
@$core.Deprecated('Use signedContactResponseDescriptor instead')
const SignedContactResponse$json = {
'1': 'SignedContactResponse',
'2': [
{'1': 'contact_response', '3': 1, '4': 1, '5': 12, '10': 'contactResponse'},
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.Signature', '10': 'identitySignature'},
],
};
/// Descriptor for `SignedContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signedContactResponseDescriptor = $convert.base64Decode(
'ChVTaWduZWRDb250YWN0UmVzcG9uc2USKQoQY29udGFjdF9yZXNwb25zZRgBIAEoDFIPY29udG'
'FjdFJlc3BvbnNlEjkKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIKLlNpZ25hdHVyZVIRaWRl'
'bnRpdHlTaWduYXR1cmU=');
@$core.Deprecated('Use contactInvitationRecordDescriptor instead')
const ContactInvitationRecord$json = {
'1': 'ContactInvitationRecord',
'2': [
{'1': 'contact_request_inbox', '3': 1, '4': 1, '5': 11, '6': '.OwnedDHTRecordPointer', '10': 'contactRequestInbox'},
{'1': 'writer_key', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerKey'},
{'1': 'writer_secret', '3': 3, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'writerSecret'},
{'1': 'local_conversation_record_key', '3': 4, '4': 1, '5': 11, '6': '.TypedKey', '10': 'localConversationRecordKey'},
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
{'1': 'invitation', '3': 6, '4': 1, '5': 12, '10': 'invitation'},
{'1': 'message', '3': 7, '4': 1, '5': 9, '10': 'message'},
],
};
/// Descriptor for `ContactInvitationRecord`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactInvitationRecordDescriptor = $convert.base64Decode(
'ChdDb250YWN0SW52aXRhdGlvblJlY29yZBJKChVjb250YWN0X3JlcXVlc3RfaW5ib3gYASABKA'
'syFi5Pd25lZERIVFJlY29yZFBvaW50ZXJSE2NvbnRhY3RSZXF1ZXN0SW5ib3gSKQoKd3JpdGVy'
'X2tleRgCIAEoCzIKLkNyeXB0b0tleVIJd3JpdGVyS2V5Ei8KDXdyaXRlcl9zZWNyZXQYAyABKA'
'syCi5DcnlwdG9LZXlSDHdyaXRlclNlY3JldBJMCh1sb2NhbF9jb252ZXJzYXRpb25fcmVjb3Jk'
'X2tleRgEIAEoCzIJLlR5cGVkS2V5Uhpsb2NhbENvbnZlcnNhdGlvblJlY29yZEtleRIeCgpleH'
'BpcmF0aW9uGAUgASgEUgpleHBpcmF0aW9uEh4KCmludml0YXRpb24YBiABKAxSCmludml0YXRp'
'b24SGAoHbWVzc2FnZRgHIAEoCVIHbWVzc2FnZQ==');

View File

@ -2,7 +2,6 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../veilid_support/veilid_support.dart';
import 'identity.dart';
part 'user_login.freezed.dart';
part 'user_login.g.dart';

View File

@ -4,8 +4,7 @@ import 'package:ansicolor/ansicolor.dart';
import 'package:flutter/foundation.dart';
import 'package:loggy/loggy.dart';
// Loggy tools
const LogLevel traceLevel = LogLevel('Trace', 1);
import '../veilid_support/veilid_support.dart';
String wrapWithLogColor(LogLevel? level, String text) {
// XXX: https://github.com/flutter/flutter/issues/64491
@ -74,11 +73,6 @@ class CallbackPrinter extends LoggyPrinter {
CallbackPrinter globalTerminalPrinter = CallbackPrinter();
extension TraceLoggy on Loggy {
void trace(dynamic message, [Object? error, StackTrace? stackTrace]) =>
this.log(traceLevel, message, error, stackTrace);
}
LogOptions getLogOptions(LogLevel? level) => LogOptions(
level ?? LogLevel.all,
stackTraceLevel: LogLevel.error,

View File

@ -10,7 +10,7 @@ import 'app.dart';
import 'log/log.dart';
import 'providers/window_control.dart';
import 'tools/theme_service.dart';
import 'veilid_support/veilid_support.dart';
import 'veilid_init.dart';
void main() async {
// Disable all debugprints in release mode

View File

@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:go_router/go_router.dart';
import '../../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../components/chat_component.dart';
import '../components/empty_chat_widget.dart';
import '../components/profile_widget.dart';
@ -83,7 +83,7 @@ class HomePageState extends ConsumerState<HomePage>
// ignore: prefer_expression_function_bodies
Widget buildAccountList() {
return Column(children: [
return const Column(children: [
Center(child: Text("Small Profile")),
Center(child: Text("Contact invitations")),
Center(child: Text("Contacts"))
@ -95,7 +95,7 @@ class HomePageState extends ConsumerState<HomePage>
IList<LocalAccount> localAccounts,
// ignore: prefer_expression_function_bodies
) {
return Center(child: Text("unlock account"));
return const Center(child: Text("unlock account"));
}
/// We have an active, unlocked, user login

View File

@ -1,3 +1,5 @@
// ignore_for_file: prefer_const_constructors
import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
@ -7,7 +9,7 @@ import 'package:flutter_translate/flutter_translate.dart';
import '../../components/contact_invitation_list_widget.dart';
import '../../components/contact_list_widget.dart';
import '../../entities/local_account.dart';
import '../../entities/proto.dart' as proto;
import '../../proto/proto.dart' as proto;
import '../../providers/contact.dart';
import '../../providers/contact_invite.dart';
import '../../tools/theme_service.dart';

View File

@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../components/chat_single_contact_list_widget.dart';
import '../../components/empty_chat_list_widget.dart';
import '../../entities/local_account.dart';
import '../../entities/proto.dart' as proto;
import '../../proto/proto.dart' as proto;
import '../../providers/account.dart';
import '../../providers/chat.dart';
import '../../providers/contact.dart';

View File

@ -17,7 +17,7 @@ import '../../components/paste_invite_dialog.dart';
import '../../components/scan_invite_dialog.dart';
import '../../components/send_invite_dialog.dart';
import '../../entities/local_account.dart';
import '../../entities/proto.dart' as proto;
import '../../proto/proto.dart' as proto;
import '../../tools/tools.dart';
import '../../veilid_support/veilid_support.dart';
import 'account_page.dart';
@ -235,7 +235,7 @@ class MainPagerState extends ConsumerState<MainPager>
localAccounts: widget.localAccounts,
activeUserLogin: widget.activeUserLogin,
account: widget.account),
ChatsPage(),
const ChatsPage(),
])),
// appBar: AppBar(
// toolbarHeight: 24,

View File

@ -157,8 +157,10 @@ class NewAccountPageState extends ConsumerState<NewAccountPage> {
try {
await createAccount();
} on Exception catch (e) {
await showErrorModal(
context, translate('new_account_page.error'), 'Exception: $e');
if (context.mounted) {
await showErrorModal(context, translate('new_account_page.error'),
'Exception: $e');
}
}
},
).paddingSymmetric(horizontal: 24, vertical: 8),

View File

@ -2,10 +2,10 @@ import 'dart:async';
import 'package:veilid/veilid.dart';
import '../log/log.dart';
import '../providers/connection_state.dart';
import 'config.dart';
import 'veilid_log.dart';
import 'log/log.dart';
import 'providers/connection_state.dart';
import 'veilid_support/src/config.dart';
import 'veilid_support/src/veilid_log.dart';
class Processor {
Processor();

309
lib/proto/dht.pb.dart Normal file
View File

@ -0,0 +1,309 @@
//
// Generated code. Do not modify.
// source: dht.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
import 'veilid.pb.dart' as $0;
class DHTData extends $pb.GeneratedMessage {
factory DHTData() => create();
DHTData._() : super();
factory DHTData.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory DHTData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'DHTData', package: const $pb.PackageName(_omitMessageNames ? '' : 'dht'), createEmptyInstance: create)
..pc<$0.TypedKey>(1, _omitFieldNames ? '' : 'keys', $pb.PbFieldType.PM, subBuilder: $0.TypedKey.create)
..aOM<$0.TypedKey>(2, _omitFieldNames ? '' : 'hash', subBuilder: $0.TypedKey.create)
..a<$core.int>(3, _omitFieldNames ? '' : 'chunk', $pb.PbFieldType.OU3)
..a<$core.int>(4, _omitFieldNames ? '' : 'size', $pb.PbFieldType.OU3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
DHTData clone() => DHTData()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
DHTData copyWith(void Function(DHTData) updates) => super.copyWith((message) => updates(message as DHTData)) as DHTData;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static DHTData create() => DHTData._();
DHTData createEmptyInstance() => create();
static $pb.PbList<DHTData> createRepeated() => $pb.PbList<DHTData>();
@$core.pragma('dart2js:noInline')
static DHTData getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DHTData>(create);
static DHTData? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$0.TypedKey> get keys => $_getList(0);
@$pb.TagNumber(2)
$0.TypedKey get hash => $_getN(1);
@$pb.TagNumber(2)
set hash($0.TypedKey v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasHash() => $_has(1);
@$pb.TagNumber(2)
void clearHash() => clearField(2);
@$pb.TagNumber(2)
$0.TypedKey ensureHash() => $_ensure(1);
@$pb.TagNumber(3)
$core.int get chunk => $_getIZ(2);
@$pb.TagNumber(3)
set chunk($core.int v) { $_setUnsignedInt32(2, v); }
@$pb.TagNumber(3)
$core.bool hasChunk() => $_has(2);
@$pb.TagNumber(3)
void clearChunk() => clearField(3);
@$pb.TagNumber(4)
$core.int get size => $_getIZ(3);
@$pb.TagNumber(4)
set size($core.int v) { $_setUnsignedInt32(3, v); }
@$pb.TagNumber(4)
$core.bool hasSize() => $_has(3);
@$pb.TagNumber(4)
void clearSize() => clearField(4);
}
class DHTShortArray extends $pb.GeneratedMessage {
factory DHTShortArray() => create();
DHTShortArray._() : super();
factory DHTShortArray.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory DHTShortArray.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'DHTShortArray', package: const $pb.PackageName(_omitMessageNames ? '' : 'dht'), createEmptyInstance: create)
..pc<$0.TypedKey>(1, _omitFieldNames ? '' : 'keys', $pb.PbFieldType.PM, subBuilder: $0.TypedKey.create)
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'index', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
DHTShortArray clone() => DHTShortArray()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
DHTShortArray copyWith(void Function(DHTShortArray) updates) => super.copyWith((message) => updates(message as DHTShortArray)) as DHTShortArray;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static DHTShortArray create() => DHTShortArray._();
DHTShortArray createEmptyInstance() => create();
static $pb.PbList<DHTShortArray> createRepeated() => $pb.PbList<DHTShortArray>();
@$core.pragma('dart2js:noInline')
static DHTShortArray getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DHTShortArray>(create);
static DHTShortArray? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$0.TypedKey> get keys => $_getList(0);
@$pb.TagNumber(2)
$core.List<$core.int> get index => $_getN(1);
@$pb.TagNumber(2)
set index($core.List<$core.int> v) { $_setBytes(1, v); }
@$pb.TagNumber(2)
$core.bool hasIndex() => $_has(1);
@$pb.TagNumber(2)
void clearIndex() => clearField(2);
}
class DHTLog extends $pb.GeneratedMessage {
factory DHTLog() => create();
DHTLog._() : super();
factory DHTLog.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory DHTLog.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'DHTLog', package: const $pb.PackageName(_omitMessageNames ? '' : 'dht'), createEmptyInstance: create)
..pc<$0.TypedKey>(1, _omitFieldNames ? '' : 'keys', $pb.PbFieldType.PM, subBuilder: $0.TypedKey.create)
..aOM<$0.TypedKey>(2, _omitFieldNames ? '' : 'back', subBuilder: $0.TypedKey.create)
..p<$core.int>(3, _omitFieldNames ? '' : 'subkeyCounts', $pb.PbFieldType.KU3)
..a<$core.int>(4, _omitFieldNames ? '' : 'totalSubkeys', $pb.PbFieldType.OU3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
DHTLog clone() => DHTLog()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
DHTLog copyWith(void Function(DHTLog) updates) => super.copyWith((message) => updates(message as DHTLog)) as DHTLog;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static DHTLog create() => DHTLog._();
DHTLog createEmptyInstance() => create();
static $pb.PbList<DHTLog> createRepeated() => $pb.PbList<DHTLog>();
@$core.pragma('dart2js:noInline')
static DHTLog getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DHTLog>(create);
static DHTLog? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$0.TypedKey> get keys => $_getList(0);
@$pb.TagNumber(2)
$0.TypedKey get back => $_getN(1);
@$pb.TagNumber(2)
set back($0.TypedKey v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasBack() => $_has(1);
@$pb.TagNumber(2)
void clearBack() => clearField(2);
@$pb.TagNumber(2)
$0.TypedKey ensureBack() => $_ensure(1);
@$pb.TagNumber(3)
$core.List<$core.int> get subkeyCounts => $_getList(2);
@$pb.TagNumber(4)
$core.int get totalSubkeys => $_getIZ(3);
@$pb.TagNumber(4)
set totalSubkeys($core.int v) { $_setUnsignedInt32(3, v); }
@$pb.TagNumber(4)
$core.bool hasTotalSubkeys() => $_has(3);
@$pb.TagNumber(4)
void clearTotalSubkeys() => clearField(4);
}
enum DataReference_Kind {
dhtData,
notSet
}
class DataReference extends $pb.GeneratedMessage {
factory DataReference() => create();
DataReference._() : super();
factory DataReference.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory DataReference.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static const $core.Map<$core.int, DataReference_Kind> _DataReference_KindByTag = {
1 : DataReference_Kind.dhtData,
0 : DataReference_Kind.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'DataReference', package: const $pb.PackageName(_omitMessageNames ? '' : 'dht'), createEmptyInstance: create)
..oo(0, [1])
..aOM<$0.TypedKey>(1, _omitFieldNames ? '' : 'dhtData', subBuilder: $0.TypedKey.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
DataReference clone() => DataReference()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
DataReference copyWith(void Function(DataReference) updates) => super.copyWith((message) => updates(message as DataReference)) as DataReference;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static DataReference create() => DataReference._();
DataReference createEmptyInstance() => create();
static $pb.PbList<DataReference> createRepeated() => $pb.PbList<DataReference>();
@$core.pragma('dart2js:noInline')
static DataReference getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DataReference>(create);
static DataReference? _defaultInstance;
DataReference_Kind whichKind() => _DataReference_KindByTag[$_whichOneof(0)]!;
void clearKind() => clearField($_whichOneof(0));
@$pb.TagNumber(1)
$0.TypedKey get dhtData => $_getN(0);
@$pb.TagNumber(1)
set dhtData($0.TypedKey v) { setField(1, v); }
@$pb.TagNumber(1)
$core.bool hasDhtData() => $_has(0);
@$pb.TagNumber(1)
void clearDhtData() => clearField(1);
@$pb.TagNumber(1)
$0.TypedKey ensureDhtData() => $_ensure(0);
}
class OwnedDHTRecordPointer extends $pb.GeneratedMessage {
factory OwnedDHTRecordPointer() => create();
OwnedDHTRecordPointer._() : super();
factory OwnedDHTRecordPointer.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory OwnedDHTRecordPointer.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OwnedDHTRecordPointer', package: const $pb.PackageName(_omitMessageNames ? '' : 'dht'), createEmptyInstance: create)
..aOM<$0.TypedKey>(1, _omitFieldNames ? '' : 'recordKey', subBuilder: $0.TypedKey.create)
..aOM<$0.KeyPair>(2, _omitFieldNames ? '' : 'owner', subBuilder: $0.KeyPair.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
OwnedDHTRecordPointer clone() => OwnedDHTRecordPointer()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
OwnedDHTRecordPointer copyWith(void Function(OwnedDHTRecordPointer) updates) => super.copyWith((message) => updates(message as OwnedDHTRecordPointer)) as OwnedDHTRecordPointer;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static OwnedDHTRecordPointer create() => OwnedDHTRecordPointer._();
OwnedDHTRecordPointer createEmptyInstance() => create();
static $pb.PbList<OwnedDHTRecordPointer> createRepeated() => $pb.PbList<OwnedDHTRecordPointer>();
@$core.pragma('dart2js:noInline')
static OwnedDHTRecordPointer getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OwnedDHTRecordPointer>(create);
static OwnedDHTRecordPointer? _defaultInstance;
@$pb.TagNumber(1)
$0.TypedKey get recordKey => $_getN(0);
@$pb.TagNumber(1)
set recordKey($0.TypedKey v) { setField(1, v); }
@$pb.TagNumber(1)
$core.bool hasRecordKey() => $_has(0);
@$pb.TagNumber(1)
void clearRecordKey() => clearField(1);
@$pb.TagNumber(1)
$0.TypedKey ensureRecordKey() => $_ensure(0);
@$pb.TagNumber(2)
$0.KeyPair get owner => $_getN(1);
@$pb.TagNumber(2)
set owner($0.KeyPair v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasOwner() => $_has(1);
@$pb.TagNumber(2)
void clearOwner() => clearField(2);
@$pb.TagNumber(2)
$0.KeyPair ensureOwner() => $_ensure(1);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

11
lib/proto/dht.pbenum.dart Normal file
View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: dht.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

93
lib/proto/dht.pbjson.dart Normal file
View File

@ -0,0 +1,93 @@
//
// Generated code. Do not modify.
// source: dht.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use dHTDataDescriptor instead')
const DHTData$json = {
'1': 'DHTData',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.veilid.TypedKey', '10': 'keys'},
{'1': 'hash', '3': 2, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'hash'},
{'1': 'chunk', '3': 3, '4': 1, '5': 13, '10': 'chunk'},
{'1': 'size', '3': 4, '4': 1, '5': 13, '10': 'size'},
],
};
/// Descriptor for `DHTData`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTDataDescriptor = $convert.base64Decode(
'CgdESFREYXRhEiQKBGtleXMYASADKAsyEC52ZWlsaWQuVHlwZWRLZXlSBGtleXMSJAoEaGFzaB'
'gCIAEoCzIQLnZlaWxpZC5UeXBlZEtleVIEaGFzaBIUCgVjaHVuaxgDIAEoDVIFY2h1bmsSEgoE'
'c2l6ZRgEIAEoDVIEc2l6ZQ==');
@$core.Deprecated('Use dHTShortArrayDescriptor instead')
const DHTShortArray$json = {
'1': 'DHTShortArray',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.veilid.TypedKey', '10': 'keys'},
{'1': 'index', '3': 2, '4': 1, '5': 12, '10': 'index'},
],
};
/// Descriptor for `DHTShortArray`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTShortArrayDescriptor = $convert.base64Decode(
'Cg1ESFRTaG9ydEFycmF5EiQKBGtleXMYASADKAsyEC52ZWlsaWQuVHlwZWRLZXlSBGtleXMSFA'
'oFaW5kZXgYAiABKAxSBWluZGV4');
@$core.Deprecated('Use dHTLogDescriptor instead')
const DHTLog$json = {
'1': 'DHTLog',
'2': [
{'1': 'keys', '3': 1, '4': 3, '5': 11, '6': '.veilid.TypedKey', '10': 'keys'},
{'1': 'back', '3': 2, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'back'},
{'1': 'subkey_counts', '3': 3, '4': 3, '5': 13, '10': 'subkeyCounts'},
{'1': 'total_subkeys', '3': 4, '4': 1, '5': 13, '10': 'totalSubkeys'},
],
};
/// Descriptor for `DHTLog`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dHTLogDescriptor = $convert.base64Decode(
'CgZESFRMb2cSJAoEa2V5cxgBIAMoCzIQLnZlaWxpZC5UeXBlZEtleVIEa2V5cxIkCgRiYWNrGA'
'IgASgLMhAudmVpbGlkLlR5cGVkS2V5UgRiYWNrEiMKDXN1YmtleV9jb3VudHMYAyADKA1SDHN1'
'YmtleUNvdW50cxIjCg10b3RhbF9zdWJrZXlzGAQgASgNUgx0b3RhbFN1YmtleXM=');
@$core.Deprecated('Use dataReferenceDescriptor instead')
const DataReference$json = {
'1': 'DataReference',
'2': [
{'1': 'dht_data', '3': 1, '4': 1, '5': 11, '6': '.veilid.TypedKey', '9': 0, '10': 'dhtData'},
],
'8': [
{'1': 'kind'},
],
};
/// Descriptor for `DataReference`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List dataReferenceDescriptor = $convert.base64Decode(
'Cg1EYXRhUmVmZXJlbmNlEi0KCGRodF9kYXRhGAEgASgLMhAudmVpbGlkLlR5cGVkS2V5SABSB2'
'RodERhdGFCBgoEa2luZA==');
@$core.Deprecated('Use ownedDHTRecordPointerDescriptor instead')
const OwnedDHTRecordPointer$json = {
'1': 'OwnedDHTRecordPointer',
'2': [
{'1': 'record_key', '3': 1, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'recordKey'},
{'1': 'owner', '3': 2, '4': 1, '5': 11, '6': '.veilid.KeyPair', '10': 'owner'},
],
};
/// Descriptor for `OwnedDHTRecordPointer`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List ownedDHTRecordPointerDescriptor = $convert.base64Decode(
'ChVPd25lZERIVFJlY29yZFBvaW50ZXISLwoKcmVjb3JkX2tleRgBIAEoCzIQLnZlaWxpZC5UeX'
'BlZEtleVIJcmVjb3JkS2V5EiUKBW93bmVyGAIgASgLMg8udmVpbGlkLktleVBhaXJSBW93bmVy');

View File

@ -0,0 +1,14 @@
//
// Generated code. Do not modify.
// source: dht.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'dht.pb.dart';

6
lib/proto/proto.dart Normal file
View File

@ -0,0 +1,6 @@
export '../veilid_support/dht_support/proto/proto.dart';
export '../veilid_support/proto/proto.dart';
export 'veilidchat.pb.dart';
export 'veilidchat.pbenum.dart';
export 'veilidchat.pbjson.dart';
export 'veilidchat.pbserver.dart';

524
lib/proto/veilid.pb.dart Normal file
View File

@ -0,0 +1,524 @@
//
// Generated code. Do not modify.
// source: veilid.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
class CryptoKey extends $pb.GeneratedMessage {
factory CryptoKey() => create();
CryptoKey._() : super();
factory CryptoKey.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory CryptoKey.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'CryptoKey', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilid'), createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'u0', $pb.PbFieldType.OF3)
..a<$core.int>(2, _omitFieldNames ? '' : 'u1', $pb.PbFieldType.OF3)
..a<$core.int>(3, _omitFieldNames ? '' : 'u2', $pb.PbFieldType.OF3)
..a<$core.int>(4, _omitFieldNames ? '' : 'u3', $pb.PbFieldType.OF3)
..a<$core.int>(5, _omitFieldNames ? '' : 'u4', $pb.PbFieldType.OF3)
..a<$core.int>(6, _omitFieldNames ? '' : 'u5', $pb.PbFieldType.OF3)
..a<$core.int>(7, _omitFieldNames ? '' : 'u6', $pb.PbFieldType.OF3)
..a<$core.int>(8, _omitFieldNames ? '' : 'u7', $pb.PbFieldType.OF3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
CryptoKey clone() => CryptoKey()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
CryptoKey copyWith(void Function(CryptoKey) updates) => super.copyWith((message) => updates(message as CryptoKey)) as CryptoKey;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static CryptoKey create() => CryptoKey._();
CryptoKey createEmptyInstance() => create();
static $pb.PbList<CryptoKey> createRepeated() => $pb.PbList<CryptoKey>();
@$core.pragma('dart2js:noInline')
static CryptoKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CryptoKey>(create);
static CryptoKey? _defaultInstance;
@$pb.TagNumber(1)
$core.int get u0 => $_getIZ(0);
@$pb.TagNumber(1)
set u0($core.int v) { $_setUnsignedInt32(0, v); }
@$pb.TagNumber(1)
$core.bool hasU0() => $_has(0);
@$pb.TagNumber(1)
void clearU0() => clearField(1);
@$pb.TagNumber(2)
$core.int get u1 => $_getIZ(1);
@$pb.TagNumber(2)
set u1($core.int v) { $_setUnsignedInt32(1, v); }
@$pb.TagNumber(2)
$core.bool hasU1() => $_has(1);
@$pb.TagNumber(2)
void clearU1() => clearField(2);
@$pb.TagNumber(3)
$core.int get u2 => $_getIZ(2);
@$pb.TagNumber(3)
set u2($core.int v) { $_setUnsignedInt32(2, v); }
@$pb.TagNumber(3)
$core.bool hasU2() => $_has(2);
@$pb.TagNumber(3)
void clearU2() => clearField(3);
@$pb.TagNumber(4)
$core.int get u3 => $_getIZ(3);
@$pb.TagNumber(4)
set u3($core.int v) { $_setUnsignedInt32(3, v); }
@$pb.TagNumber(4)
$core.bool hasU3() => $_has(3);
@$pb.TagNumber(4)
void clearU3() => clearField(4);
@$pb.TagNumber(5)
$core.int get u4 => $_getIZ(4);
@$pb.TagNumber(5)
set u4($core.int v) { $_setUnsignedInt32(4, v); }
@$pb.TagNumber(5)
$core.bool hasU4() => $_has(4);
@$pb.TagNumber(5)
void clearU4() => clearField(5);
@$pb.TagNumber(6)
$core.int get u5 => $_getIZ(5);
@$pb.TagNumber(6)
set u5($core.int v) { $_setUnsignedInt32(5, v); }
@$pb.TagNumber(6)
$core.bool hasU5() => $_has(5);
@$pb.TagNumber(6)
void clearU5() => clearField(6);
@$pb.TagNumber(7)
$core.int get u6 => $_getIZ(6);
@$pb.TagNumber(7)
set u6($core.int v) { $_setUnsignedInt32(6, v); }
@$pb.TagNumber(7)
$core.bool hasU6() => $_has(6);
@$pb.TagNumber(7)
void clearU6() => clearField(7);
@$pb.TagNumber(8)
$core.int get u7 => $_getIZ(7);
@$pb.TagNumber(8)
set u7($core.int v) { $_setUnsignedInt32(7, v); }
@$pb.TagNumber(8)
$core.bool hasU7() => $_has(7);
@$pb.TagNumber(8)
void clearU7() => clearField(8);
}
class Signature extends $pb.GeneratedMessage {
factory Signature() => create();
Signature._() : super();
factory Signature.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Signature.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Signature', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilid'), createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'u0', $pb.PbFieldType.OF3)
..a<$core.int>(2, _omitFieldNames ? '' : 'u1', $pb.PbFieldType.OF3)
..a<$core.int>(3, _omitFieldNames ? '' : 'u2', $pb.PbFieldType.OF3)
..a<$core.int>(4, _omitFieldNames ? '' : 'u3', $pb.PbFieldType.OF3)
..a<$core.int>(5, _omitFieldNames ? '' : 'u4', $pb.PbFieldType.OF3)
..a<$core.int>(6, _omitFieldNames ? '' : 'u5', $pb.PbFieldType.OF3)
..a<$core.int>(7, _omitFieldNames ? '' : 'u6', $pb.PbFieldType.OF3)
..a<$core.int>(8, _omitFieldNames ? '' : 'u7', $pb.PbFieldType.OF3)
..a<$core.int>(9, _omitFieldNames ? '' : 'u8', $pb.PbFieldType.OF3)
..a<$core.int>(10, _omitFieldNames ? '' : 'u9', $pb.PbFieldType.OF3)
..a<$core.int>(11, _omitFieldNames ? '' : 'u10', $pb.PbFieldType.OF3)
..a<$core.int>(12, _omitFieldNames ? '' : 'u11', $pb.PbFieldType.OF3)
..a<$core.int>(13, _omitFieldNames ? '' : 'u12', $pb.PbFieldType.OF3)
..a<$core.int>(14, _omitFieldNames ? '' : 'u13', $pb.PbFieldType.OF3)
..a<$core.int>(15, _omitFieldNames ? '' : 'u14', $pb.PbFieldType.OF3)
..a<$core.int>(16, _omitFieldNames ? '' : 'u15', $pb.PbFieldType.OF3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Signature clone() => Signature()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Signature copyWith(void Function(Signature) updates) => super.copyWith((message) => updates(message as Signature)) as Signature;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Signature create() => Signature._();
Signature createEmptyInstance() => create();
static $pb.PbList<Signature> createRepeated() => $pb.PbList<Signature>();
@$core.pragma('dart2js:noInline')
static Signature getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Signature>(create);
static Signature? _defaultInstance;
@$pb.TagNumber(1)
$core.int get u0 => $_getIZ(0);
@$pb.TagNumber(1)
set u0($core.int v) { $_setUnsignedInt32(0, v); }
@$pb.TagNumber(1)
$core.bool hasU0() => $_has(0);
@$pb.TagNumber(1)
void clearU0() => clearField(1);
@$pb.TagNumber(2)
$core.int get u1 => $_getIZ(1);
@$pb.TagNumber(2)
set u1($core.int v) { $_setUnsignedInt32(1, v); }
@$pb.TagNumber(2)
$core.bool hasU1() => $_has(1);
@$pb.TagNumber(2)
void clearU1() => clearField(2);
@$pb.TagNumber(3)
$core.int get u2 => $_getIZ(2);
@$pb.TagNumber(3)
set u2($core.int v) { $_setUnsignedInt32(2, v); }
@$pb.TagNumber(3)
$core.bool hasU2() => $_has(2);
@$pb.TagNumber(3)
void clearU2() => clearField(3);
@$pb.TagNumber(4)
$core.int get u3 => $_getIZ(3);
@$pb.TagNumber(4)
set u3($core.int v) { $_setUnsignedInt32(3, v); }
@$pb.TagNumber(4)
$core.bool hasU3() => $_has(3);
@$pb.TagNumber(4)
void clearU3() => clearField(4);
@$pb.TagNumber(5)
$core.int get u4 => $_getIZ(4);
@$pb.TagNumber(5)
set u4($core.int v) { $_setUnsignedInt32(4, v); }
@$pb.TagNumber(5)
$core.bool hasU4() => $_has(4);
@$pb.TagNumber(5)
void clearU4() => clearField(5);
@$pb.TagNumber(6)
$core.int get u5 => $_getIZ(5);
@$pb.TagNumber(6)
set u5($core.int v) { $_setUnsignedInt32(5, v); }
@$pb.TagNumber(6)
$core.bool hasU5() => $_has(5);
@$pb.TagNumber(6)
void clearU5() => clearField(6);
@$pb.TagNumber(7)
$core.int get u6 => $_getIZ(6);
@$pb.TagNumber(7)
set u6($core.int v) { $_setUnsignedInt32(6, v); }
@$pb.TagNumber(7)
$core.bool hasU6() => $_has(6);
@$pb.TagNumber(7)
void clearU6() => clearField(7);
@$pb.TagNumber(8)
$core.int get u7 => $_getIZ(7);
@$pb.TagNumber(8)
set u7($core.int v) { $_setUnsignedInt32(7, v); }
@$pb.TagNumber(8)
$core.bool hasU7() => $_has(7);
@$pb.TagNumber(8)
void clearU7() => clearField(8);
@$pb.TagNumber(9)
$core.int get u8 => $_getIZ(8);
@$pb.TagNumber(9)
set u8($core.int v) { $_setUnsignedInt32(8, v); }
@$pb.TagNumber(9)
$core.bool hasU8() => $_has(8);
@$pb.TagNumber(9)
void clearU8() => clearField(9);
@$pb.TagNumber(10)
$core.int get u9 => $_getIZ(9);
@$pb.TagNumber(10)
set u9($core.int v) { $_setUnsignedInt32(9, v); }
@$pb.TagNumber(10)
$core.bool hasU9() => $_has(9);
@$pb.TagNumber(10)
void clearU9() => clearField(10);
@$pb.TagNumber(11)
$core.int get u10 => $_getIZ(10);
@$pb.TagNumber(11)
set u10($core.int v) { $_setUnsignedInt32(10, v); }
@$pb.TagNumber(11)
$core.bool hasU10() => $_has(10);
@$pb.TagNumber(11)
void clearU10() => clearField(11);
@$pb.TagNumber(12)
$core.int get u11 => $_getIZ(11);
@$pb.TagNumber(12)
set u11($core.int v) { $_setUnsignedInt32(11, v); }
@$pb.TagNumber(12)
$core.bool hasU11() => $_has(11);
@$pb.TagNumber(12)
void clearU11() => clearField(12);
@$pb.TagNumber(13)
$core.int get u12 => $_getIZ(12);
@$pb.TagNumber(13)
set u12($core.int v) { $_setUnsignedInt32(12, v); }
@$pb.TagNumber(13)
$core.bool hasU12() => $_has(12);
@$pb.TagNumber(13)
void clearU12() => clearField(13);
@$pb.TagNumber(14)
$core.int get u13 => $_getIZ(13);
@$pb.TagNumber(14)
set u13($core.int v) { $_setUnsignedInt32(13, v); }
@$pb.TagNumber(14)
$core.bool hasU13() => $_has(13);
@$pb.TagNumber(14)
void clearU13() => clearField(14);
@$pb.TagNumber(15)
$core.int get u14 => $_getIZ(14);
@$pb.TagNumber(15)
set u14($core.int v) { $_setUnsignedInt32(14, v); }
@$pb.TagNumber(15)
$core.bool hasU14() => $_has(14);
@$pb.TagNumber(15)
void clearU14() => clearField(15);
@$pb.TagNumber(16)
$core.int get u15 => $_getIZ(15);
@$pb.TagNumber(16)
set u15($core.int v) { $_setUnsignedInt32(15, v); }
@$pb.TagNumber(16)
$core.bool hasU15() => $_has(15);
@$pb.TagNumber(16)
void clearU15() => clearField(16);
}
class Nonce extends $pb.GeneratedMessage {
factory Nonce() => create();
Nonce._() : super();
factory Nonce.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Nonce.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Nonce', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilid'), createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'u0', $pb.PbFieldType.OF3)
..a<$core.int>(2, _omitFieldNames ? '' : 'u1', $pb.PbFieldType.OF3)
..a<$core.int>(3, _omitFieldNames ? '' : 'u2', $pb.PbFieldType.OF3)
..a<$core.int>(4, _omitFieldNames ? '' : 'u3', $pb.PbFieldType.OF3)
..a<$core.int>(5, _omitFieldNames ? '' : 'u4', $pb.PbFieldType.OF3)
..a<$core.int>(6, _omitFieldNames ? '' : 'u5', $pb.PbFieldType.OF3)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Nonce clone() => Nonce()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Nonce copyWith(void Function(Nonce) updates) => super.copyWith((message) => updates(message as Nonce)) as Nonce;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Nonce create() => Nonce._();
Nonce createEmptyInstance() => create();
static $pb.PbList<Nonce> createRepeated() => $pb.PbList<Nonce>();
@$core.pragma('dart2js:noInline')
static Nonce getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Nonce>(create);
static Nonce? _defaultInstance;
@$pb.TagNumber(1)
$core.int get u0 => $_getIZ(0);
@$pb.TagNumber(1)
set u0($core.int v) { $_setUnsignedInt32(0, v); }
@$pb.TagNumber(1)
$core.bool hasU0() => $_has(0);
@$pb.TagNumber(1)
void clearU0() => clearField(1);
@$pb.TagNumber(2)
$core.int get u1 => $_getIZ(1);
@$pb.TagNumber(2)
set u1($core.int v) { $_setUnsignedInt32(1, v); }
@$pb.TagNumber(2)
$core.bool hasU1() => $_has(1);
@$pb.TagNumber(2)
void clearU1() => clearField(2);
@$pb.TagNumber(3)
$core.int get u2 => $_getIZ(2);
@$pb.TagNumber(3)
set u2($core.int v) { $_setUnsignedInt32(2, v); }
@$pb.TagNumber(3)
$core.bool hasU2() => $_has(2);
@$pb.TagNumber(3)
void clearU2() => clearField(3);
@$pb.TagNumber(4)
$core.int get u3 => $_getIZ(3);
@$pb.TagNumber(4)
set u3($core.int v) { $_setUnsignedInt32(3, v); }
@$pb.TagNumber(4)
$core.bool hasU3() => $_has(3);
@$pb.TagNumber(4)
void clearU3() => clearField(4);
@$pb.TagNumber(5)
$core.int get u4 => $_getIZ(4);
@$pb.TagNumber(5)
set u4($core.int v) { $_setUnsignedInt32(4, v); }
@$pb.TagNumber(5)
$core.bool hasU4() => $_has(4);
@$pb.TagNumber(5)
void clearU4() => clearField(5);
@$pb.TagNumber(6)
$core.int get u5 => $_getIZ(5);
@$pb.TagNumber(6)
set u5($core.int v) { $_setUnsignedInt32(5, v); }
@$pb.TagNumber(6)
$core.bool hasU5() => $_has(5);
@$pb.TagNumber(6)
void clearU5() => clearField(6);
}
class TypedKey extends $pb.GeneratedMessage {
factory TypedKey() => create();
TypedKey._() : super();
factory TypedKey.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory TypedKey.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TypedKey', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilid'), createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'kind', $pb.PbFieldType.OF3)
..aOM<CryptoKey>(2, _omitFieldNames ? '' : 'value', subBuilder: CryptoKey.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
TypedKey clone() => TypedKey()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
TypedKey copyWith(void Function(TypedKey) updates) => super.copyWith((message) => updates(message as TypedKey)) as TypedKey;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static TypedKey create() => TypedKey._();
TypedKey createEmptyInstance() => create();
static $pb.PbList<TypedKey> createRepeated() => $pb.PbList<TypedKey>();
@$core.pragma('dart2js:noInline')
static TypedKey getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TypedKey>(create);
static TypedKey? _defaultInstance;
@$pb.TagNumber(1)
$core.int get kind => $_getIZ(0);
@$pb.TagNumber(1)
set kind($core.int v) { $_setUnsignedInt32(0, v); }
@$pb.TagNumber(1)
$core.bool hasKind() => $_has(0);
@$pb.TagNumber(1)
void clearKind() => clearField(1);
@$pb.TagNumber(2)
CryptoKey get value => $_getN(1);
@$pb.TagNumber(2)
set value(CryptoKey v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasValue() => $_has(1);
@$pb.TagNumber(2)
void clearValue() => clearField(2);
@$pb.TagNumber(2)
CryptoKey ensureValue() => $_ensure(1);
}
class KeyPair extends $pb.GeneratedMessage {
factory KeyPair() => create();
KeyPair._() : super();
factory KeyPair.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory KeyPair.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'KeyPair', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilid'), createEmptyInstance: create)
..aOM<CryptoKey>(1, _omitFieldNames ? '' : 'key', subBuilder: CryptoKey.create)
..aOM<CryptoKey>(2, _omitFieldNames ? '' : 'secret', subBuilder: CryptoKey.create)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
KeyPair clone() => KeyPair()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
KeyPair copyWith(void Function(KeyPair) updates) => super.copyWith((message) => updates(message as KeyPair)) as KeyPair;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static KeyPair create() => KeyPair._();
KeyPair createEmptyInstance() => create();
static $pb.PbList<KeyPair> createRepeated() => $pb.PbList<KeyPair>();
@$core.pragma('dart2js:noInline')
static KeyPair getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<KeyPair>(create);
static KeyPair? _defaultInstance;
@$pb.TagNumber(1)
CryptoKey get key => $_getN(0);
@$pb.TagNumber(1)
set key(CryptoKey v) { setField(1, v); }
@$pb.TagNumber(1)
$core.bool hasKey() => $_has(0);
@$pb.TagNumber(1)
void clearKey() => clearField(1);
@$pb.TagNumber(1)
CryptoKey ensureKey() => $_ensure(0);
@$pb.TagNumber(2)
CryptoKey get secret => $_getN(1);
@$pb.TagNumber(2)
set secret(CryptoKey v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasSecret() => $_has(1);
@$pb.TagNumber(2)
void clearSecret() => clearField(2);
@$pb.TagNumber(2)
CryptoKey ensureSecret() => $_ensure(1);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');

View File

@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: veilid.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import

View File

@ -0,0 +1,114 @@
//
// Generated code. Do not modify.
// source: veilid.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use cryptoKeyDescriptor instead')
const CryptoKey$json = {
'1': 'CryptoKey',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
{'1': 'u6', '3': 7, '4': 1, '5': 7, '10': 'u6'},
{'1': 'u7', '3': 8, '4': 1, '5': 7, '10': 'u7'},
],
};
/// Descriptor for `CryptoKey`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cryptoKeyDescriptor = $convert.base64Decode(
'CglDcnlwdG9LZXkSDgoCdTAYASABKAdSAnUwEg4KAnUxGAIgASgHUgJ1MRIOCgJ1MhgDIAEoB1'
'ICdTISDgoCdTMYBCABKAdSAnUzEg4KAnU0GAUgASgHUgJ1NBIOCgJ1NRgGIAEoB1ICdTUSDgoC'
'dTYYByABKAdSAnU2Eg4KAnU3GAggASgHUgJ1Nw==');
@$core.Deprecated('Use signatureDescriptor instead')
const Signature$json = {
'1': 'Signature',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
{'1': 'u6', '3': 7, '4': 1, '5': 7, '10': 'u6'},
{'1': 'u7', '3': 8, '4': 1, '5': 7, '10': 'u7'},
{'1': 'u8', '3': 9, '4': 1, '5': 7, '10': 'u8'},
{'1': 'u9', '3': 10, '4': 1, '5': 7, '10': 'u9'},
{'1': 'u10', '3': 11, '4': 1, '5': 7, '10': 'u10'},
{'1': 'u11', '3': 12, '4': 1, '5': 7, '10': 'u11'},
{'1': 'u12', '3': 13, '4': 1, '5': 7, '10': 'u12'},
{'1': 'u13', '3': 14, '4': 1, '5': 7, '10': 'u13'},
{'1': 'u14', '3': 15, '4': 1, '5': 7, '10': 'u14'},
{'1': 'u15', '3': 16, '4': 1, '5': 7, '10': 'u15'},
],
};
/// Descriptor for `Signature`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signatureDescriptor = $convert.base64Decode(
'CglTaWduYXR1cmUSDgoCdTAYASABKAdSAnUwEg4KAnUxGAIgASgHUgJ1MRIOCgJ1MhgDIAEoB1'
'ICdTISDgoCdTMYBCABKAdSAnUzEg4KAnU0GAUgASgHUgJ1NBIOCgJ1NRgGIAEoB1ICdTUSDgoC'
'dTYYByABKAdSAnU2Eg4KAnU3GAggASgHUgJ1NxIOCgJ1OBgJIAEoB1ICdTgSDgoCdTkYCiABKA'
'dSAnU5EhAKA3UxMBgLIAEoB1IDdTEwEhAKA3UxMRgMIAEoB1IDdTExEhAKA3UxMhgNIAEoB1ID'
'dTEyEhAKA3UxMxgOIAEoB1IDdTEzEhAKA3UxNBgPIAEoB1IDdTE0EhAKA3UxNRgQIAEoB1IDdT'
'E1');
@$core.Deprecated('Use nonceDescriptor instead')
const Nonce$json = {
'1': 'Nonce',
'2': [
{'1': 'u0', '3': 1, '4': 1, '5': 7, '10': 'u0'},
{'1': 'u1', '3': 2, '4': 1, '5': 7, '10': 'u1'},
{'1': 'u2', '3': 3, '4': 1, '5': 7, '10': 'u2'},
{'1': 'u3', '3': 4, '4': 1, '5': 7, '10': 'u3'},
{'1': 'u4', '3': 5, '4': 1, '5': 7, '10': 'u4'},
{'1': 'u5', '3': 6, '4': 1, '5': 7, '10': 'u5'},
],
};
/// Descriptor for `Nonce`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List nonceDescriptor = $convert.base64Decode(
'CgVOb25jZRIOCgJ1MBgBIAEoB1ICdTASDgoCdTEYAiABKAdSAnUxEg4KAnUyGAMgASgHUgJ1Mh'
'IOCgJ1MxgEIAEoB1ICdTMSDgoCdTQYBSABKAdSAnU0Eg4KAnU1GAYgASgHUgJ1NQ==');
@$core.Deprecated('Use typedKeyDescriptor instead')
const TypedKey$json = {
'1': 'TypedKey',
'2': [
{'1': 'kind', '3': 1, '4': 1, '5': 7, '10': 'kind'},
{'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'value'},
],
};
/// Descriptor for `TypedKey`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List typedKeyDescriptor = $convert.base64Decode(
'CghUeXBlZEtleRISCgRraW5kGAEgASgHUgRraW5kEicKBXZhbHVlGAIgASgLMhEudmVpbGlkLk'
'NyeXB0b0tleVIFdmFsdWU=');
@$core.Deprecated('Use keyPairDescriptor instead')
const KeyPair$json = {
'1': 'KeyPair',
'2': [
{'1': 'key', '3': 1, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'key'},
{'1': 'secret', '3': 2, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'secret'},
],
};
/// Descriptor for `KeyPair`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List keyPairDescriptor = $convert.base64Decode(
'CgdLZXlQYWlyEiMKA2tleRgBIAEoCzIRLnZlaWxpZC5DcnlwdG9LZXlSA2tleRIpCgZzZWNyZX'
'QYAiABKAsyES52ZWlsaWQuQ3J5cHRvS2V5UgZzZWNyZXQ=');

View File

@ -0,0 +1,14 @@
//
// Generated code. Do not modify.
// source: veilid.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'veilid.pb.dart';

View File

@ -0,0 +1,342 @@
//
// Generated code. Do not modify.
// source: veilidchat.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use attachmentKindDescriptor instead')
const AttachmentKind$json = {
'1': 'AttachmentKind',
'2': [
{'1': 'ATTACHMENT_KIND_UNSPECIFIED', '2': 0},
{'1': 'ATTACHMENT_KIND_FILE', '2': 1},
{'1': 'ATTACHMENT_KIND_IMAGE', '2': 2},
],
};
/// Descriptor for `AttachmentKind`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List attachmentKindDescriptor = $convert.base64Decode(
'Cg5BdHRhY2htZW50S2luZBIfChtBVFRBQ0hNRU5UX0tJTkRfVU5TUEVDSUZJRUQQABIYChRBVF'
'RBQ0hNRU5UX0tJTkRfRklMRRABEhkKFUFUVEFDSE1FTlRfS0lORF9JTUFHRRAC');
@$core.Deprecated('Use availabilityDescriptor instead')
const Availability$json = {
'1': 'Availability',
'2': [
{'1': 'AVAILABILITY_UNSPECIFIED', '2': 0},
{'1': 'AVAILABILITY_OFFLINE', '2': 1},
{'1': 'AVAILABILITY_FREE', '2': 2},
{'1': 'AVAILABILITY_BUSY', '2': 3},
{'1': 'AVAILABILITY_AWAY', '2': 4},
],
};
/// Descriptor for `Availability`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List availabilityDescriptor = $convert.base64Decode(
'CgxBdmFpbGFiaWxpdHkSHAoYQVZBSUxBQklMSVRZX1VOU1BFQ0lGSUVEEAASGAoUQVZBSUxBQk'
'lMSVRZX09GRkxJTkUQARIVChFBVkFJTEFCSUxJVFlfRlJFRRACEhUKEUFWQUlMQUJJTElUWV9C'
'VVNZEAMSFQoRQVZBSUxBQklMSVRZX0FXQVkQBA==');
@$core.Deprecated('Use chatTypeDescriptor instead')
const ChatType$json = {
'1': 'ChatType',
'2': [
{'1': 'CHAT_TYPE_UNSPECIFIED', '2': 0},
{'1': 'SINGLE_CONTACT', '2': 1},
{'1': 'GROUP', '2': 2},
],
};
/// Descriptor for `ChatType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List chatTypeDescriptor = $convert.base64Decode(
'CghDaGF0VHlwZRIZChVDSEFUX1RZUEVfVU5TUEVDSUZJRUQQABISCg5TSU5HTEVfQ09OVEFDVB'
'ABEgkKBUdST1VQEAI=');
@$core.Deprecated('Use encryptionKeyTypeDescriptor instead')
const EncryptionKeyType$json = {
'1': 'EncryptionKeyType',
'2': [
{'1': 'ENCRYPTION_KEY_TYPE_UNSPECIFIED', '2': 0},
{'1': 'ENCRYPTION_KEY_TYPE_NONE', '2': 1},
{'1': 'ENCRYPTION_KEY_TYPE_PIN', '2': 2},
{'1': 'ENCRYPTION_KEY_TYPE_PASSWORD', '2': 3},
],
};
/// Descriptor for `EncryptionKeyType`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List encryptionKeyTypeDescriptor = $convert.base64Decode(
'ChFFbmNyeXB0aW9uS2V5VHlwZRIjCh9FTkNSWVBUSU9OX0tFWV9UWVBFX1VOU1BFQ0lGSUVEEA'
'ASHAoYRU5DUllQVElPTl9LRVlfVFlQRV9OT05FEAESGwoXRU5DUllQVElPTl9LRVlfVFlQRV9Q'
'SU4QAhIgChxFTkNSWVBUSU9OX0tFWV9UWVBFX1BBU1NXT1JEEAM=');
@$core.Deprecated('Use attachmentDescriptor instead')
const Attachment$json = {
'1': 'Attachment',
'2': [
{'1': 'kind', '3': 1, '4': 1, '5': 14, '6': '.veilidchat.AttachmentKind', '10': 'kind'},
{'1': 'mime', '3': 2, '4': 1, '5': 9, '10': 'mime'},
{'1': 'name', '3': 3, '4': 1, '5': 9, '10': 'name'},
{'1': 'content', '3': 4, '4': 1, '5': 11, '6': '.dht.DataReference', '10': 'content'},
{'1': 'signature', '3': 5, '4': 1, '5': 11, '6': '.veilid.Signature', '10': 'signature'},
],
};
/// Descriptor for `Attachment`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List attachmentDescriptor = $convert.base64Decode(
'CgpBdHRhY2htZW50Ei4KBGtpbmQYASABKA4yGi52ZWlsaWRjaGF0LkF0dGFjaG1lbnRLaW5kUg'
'RraW5kEhIKBG1pbWUYAiABKAlSBG1pbWUSEgoEbmFtZRgDIAEoCVIEbmFtZRIsCgdjb250ZW50'
'GAQgASgLMhIuZGh0LkRhdGFSZWZlcmVuY2VSB2NvbnRlbnQSLwoJc2lnbmF0dXJlGAUgASgLMh'
'EudmVpbGlkLlNpZ25hdHVyZVIJc2lnbmF0dXJl');
@$core.Deprecated('Use messageDescriptor instead')
const Message$json = {
'1': 'Message',
'2': [
{'1': 'author', '3': 1, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'author'},
{'1': 'timestamp', '3': 2, '4': 1, '5': 4, '10': 'timestamp'},
{'1': 'text', '3': 3, '4': 1, '5': 9, '10': 'text'},
{'1': 'signature', '3': 4, '4': 1, '5': 11, '6': '.veilid.Signature', '10': 'signature'},
{'1': 'attachments', '3': 5, '4': 3, '5': 11, '6': '.veilidchat.Attachment', '10': 'attachments'},
],
};
/// Descriptor for `Message`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List messageDescriptor = $convert.base64Decode(
'CgdNZXNzYWdlEigKBmF1dGhvchgBIAEoCzIQLnZlaWxpZC5UeXBlZEtleVIGYXV0aG9yEhwKCX'
'RpbWVzdGFtcBgCIAEoBFIJdGltZXN0YW1wEhIKBHRleHQYAyABKAlSBHRleHQSLwoJc2lnbmF0'
'dXJlGAQgASgLMhEudmVpbGlkLlNpZ25hdHVyZVIJc2lnbmF0dXJlEjgKC2F0dGFjaG1lbnRzGA'
'UgAygLMhYudmVpbGlkY2hhdC5BdHRhY2htZW50UgthdHRhY2htZW50cw==');
@$core.Deprecated('Use conversationDescriptor instead')
const Conversation$json = {
'1': 'Conversation',
'2': [
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.veilidchat.Profile', '10': 'profile'},
{'1': 'identity_master_json', '3': 2, '4': 1, '5': 9, '10': 'identityMasterJson'},
{'1': 'messages', '3': 3, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'messages'},
],
};
/// Descriptor for `Conversation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List conversationDescriptor = $convert.base64Decode(
'CgxDb252ZXJzYXRpb24SLQoHcHJvZmlsZRgBIAEoCzITLnZlaWxpZGNoYXQuUHJvZmlsZVIHcH'
'JvZmlsZRIwChRpZGVudGl0eV9tYXN0ZXJfanNvbhgCIAEoCVISaWRlbnRpdHlNYXN0ZXJKc29u'
'EiwKCG1lc3NhZ2VzGAMgASgLMhAudmVpbGlkLlR5cGVkS2V5UghtZXNzYWdlcw==');
@$core.Deprecated('Use contactDescriptor instead')
const Contact$json = {
'1': 'Contact',
'2': [
{'1': 'edited_profile', '3': 1, '4': 1, '5': 11, '6': '.veilidchat.Profile', '10': 'editedProfile'},
{'1': 'remote_profile', '3': 2, '4': 1, '5': 11, '6': '.veilidchat.Profile', '10': 'remoteProfile'},
{'1': 'identity_master_json', '3': 3, '4': 1, '5': 9, '10': 'identityMasterJson'},
{'1': 'identity_public_key', '3': 4, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'identityPublicKey'},
{'1': 'remote_conversation_record_key', '3': 5, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'remoteConversationRecordKey'},
{'1': 'local_conversation_record_key', '3': 6, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'localConversationRecordKey'},
{'1': 'show_availability', '3': 7, '4': 1, '5': 8, '10': 'showAvailability'},
],
};
/// Descriptor for `Contact`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactDescriptor = $convert.base64Decode(
'CgdDb250YWN0EjoKDmVkaXRlZF9wcm9maWxlGAEgASgLMhMudmVpbGlkY2hhdC5Qcm9maWxlUg'
'1lZGl0ZWRQcm9maWxlEjoKDnJlbW90ZV9wcm9maWxlGAIgASgLMhMudmVpbGlkY2hhdC5Qcm9m'
'aWxlUg1yZW1vdGVQcm9maWxlEjAKFGlkZW50aXR5X21hc3Rlcl9qc29uGAMgASgJUhJpZGVudG'
'l0eU1hc3Rlckpzb24SQAoTaWRlbnRpdHlfcHVibGljX2tleRgEIAEoCzIQLnZlaWxpZC5UeXBl'
'ZEtleVIRaWRlbnRpdHlQdWJsaWNLZXkSVQoecmVtb3RlX2NvbnZlcnNhdGlvbl9yZWNvcmRfa2'
'V5GAUgASgLMhAudmVpbGlkLlR5cGVkS2V5UhtyZW1vdGVDb252ZXJzYXRpb25SZWNvcmRLZXkS'
'UwodbG9jYWxfY29udmVyc2F0aW9uX3JlY29yZF9rZXkYBiABKAsyEC52ZWlsaWQuVHlwZWRLZX'
'lSGmxvY2FsQ29udmVyc2F0aW9uUmVjb3JkS2V5EisKEXNob3dfYXZhaWxhYmlsaXR5GAcgASgI'
'UhBzaG93QXZhaWxhYmlsaXR5');
@$core.Deprecated('Use profileDescriptor instead')
const Profile$json = {
'1': 'Profile',
'2': [
{'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'},
{'1': 'title', '3': 2, '4': 1, '5': 9, '10': 'title'},
{'1': 'status', '3': 3, '4': 1, '5': 9, '10': 'status'},
{'1': 'availability', '3': 4, '4': 1, '5': 14, '6': '.veilidchat.Availability', '10': 'availability'},
{'1': 'avatar', '3': 5, '4': 1, '5': 11, '6': '.veilid.TypedKey', '9': 0, '10': 'avatar', '17': true},
],
'8': [
{'1': '_avatar'},
],
};
/// Descriptor for `Profile`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List profileDescriptor = $convert.base64Decode(
'CgdQcm9maWxlEhIKBG5hbWUYASABKAlSBG5hbWUSFAoFdGl0bGUYAiABKAlSBXRpdGxlEhYKBn'
'N0YXR1cxgDIAEoCVIGc3RhdHVzEjwKDGF2YWlsYWJpbGl0eRgEIAEoDjIYLnZlaWxpZGNoYXQu'
'QXZhaWxhYmlsaXR5UgxhdmFpbGFiaWxpdHkSLQoGYXZhdGFyGAUgASgLMhAudmVpbGlkLlR5cG'
'VkS2V5SABSBmF2YXRhcogBAUIJCgdfYXZhdGFy');
@$core.Deprecated('Use chatDescriptor instead')
const Chat$json = {
'1': 'Chat',
'2': [
{'1': 'type', '3': 1, '4': 1, '5': 14, '6': '.veilidchat.ChatType', '10': 'type'},
{'1': 'remote_conversation_key', '3': 2, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'remoteConversationKey'},
],
};
/// Descriptor for `Chat`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List chatDescriptor = $convert.base64Decode(
'CgRDaGF0EigKBHR5cGUYASABKA4yFC52ZWlsaWRjaGF0LkNoYXRUeXBlUgR0eXBlEkgKF3JlbW'
'90ZV9jb252ZXJzYXRpb25fa2V5GAIgASgLMhAudmVpbGlkLlR5cGVkS2V5UhVyZW1vdGVDb252'
'ZXJzYXRpb25LZXk=');
@$core.Deprecated('Use accountDescriptor instead')
const Account$json = {
'1': 'Account',
'2': [
{'1': 'profile', '3': 1, '4': 1, '5': 11, '6': '.veilidchat.Profile', '10': 'profile'},
{'1': 'invisible', '3': 2, '4': 1, '5': 8, '10': 'invisible'},
{'1': 'auto_away_timeout_sec', '3': 3, '4': 1, '5': 13, '10': 'autoAwayTimeoutSec'},
{'1': 'contact_list', '3': 4, '4': 1, '5': 11, '6': '.dht.OwnedDHTRecordPointer', '10': 'contactList'},
{'1': 'contact_invitation_records', '3': 5, '4': 1, '5': 11, '6': '.dht.OwnedDHTRecordPointer', '10': 'contactInvitationRecords'},
{'1': 'chat_list', '3': 6, '4': 1, '5': 11, '6': '.dht.OwnedDHTRecordPointer', '10': 'chatList'},
],
};
/// Descriptor for `Account`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List accountDescriptor = $convert.base64Decode(
'CgdBY2NvdW50Ei0KB3Byb2ZpbGUYASABKAsyEy52ZWlsaWRjaGF0LlByb2ZpbGVSB3Byb2ZpbG'
'USHAoJaW52aXNpYmxlGAIgASgIUglpbnZpc2libGUSMQoVYXV0b19hd2F5X3RpbWVvdXRfc2Vj'
'GAMgASgNUhJhdXRvQXdheVRpbWVvdXRTZWMSPQoMY29udGFjdF9saXN0GAQgASgLMhouZGh0Lk'
'93bmVkREhUUmVjb3JkUG9pbnRlclILY29udGFjdExpc3QSWAoaY29udGFjdF9pbnZpdGF0aW9u'
'X3JlY29yZHMYBSABKAsyGi5kaHQuT3duZWRESFRSZWNvcmRQb2ludGVyUhhjb250YWN0SW52aX'
'RhdGlvblJlY29yZHMSNwoJY2hhdF9saXN0GAYgASgLMhouZGh0Lk93bmVkREhUUmVjb3JkUG9p'
'bnRlclIIY2hhdExpc3Q=');
@$core.Deprecated('Use contactInvitationDescriptor instead')
const ContactInvitation$json = {
'1': 'ContactInvitation',
'2': [
{'1': 'contact_request_inbox_key', '3': 1, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'contactRequestInboxKey'},
{'1': 'writer_secret', '3': 2, '4': 1, '5': 12, '10': 'writerSecret'},
],
};
/// Descriptor for `ContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactInvitationDescriptor = $convert.base64Decode(
'ChFDb250YWN0SW52aXRhdGlvbhJLChljb250YWN0X3JlcXVlc3RfaW5ib3hfa2V5GAEgASgLMh'
'AudmVpbGlkLlR5cGVkS2V5UhZjb250YWN0UmVxdWVzdEluYm94S2V5EiMKDXdyaXRlcl9zZWNy'
'ZXQYAiABKAxSDHdyaXRlclNlY3JldA==');
@$core.Deprecated('Use signedContactInvitationDescriptor instead')
const SignedContactInvitation$json = {
'1': 'SignedContactInvitation',
'2': [
{'1': 'contact_invitation', '3': 1, '4': 1, '5': 12, '10': 'contactInvitation'},
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.veilid.Signature', '10': 'identitySignature'},
],
};
/// Descriptor for `SignedContactInvitation`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signedContactInvitationDescriptor = $convert.base64Decode(
'ChdTaWduZWRDb250YWN0SW52aXRhdGlvbhItChJjb250YWN0X2ludml0YXRpb24YASABKAxSEW'
'NvbnRhY3RJbnZpdGF0aW9uEkAKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIRLnZlaWxpZC5T'
'aWduYXR1cmVSEWlkZW50aXR5U2lnbmF0dXJl');
@$core.Deprecated('Use contactRequestDescriptor instead')
const ContactRequest$json = {
'1': 'ContactRequest',
'2': [
{'1': 'encryption_key_type', '3': 1, '4': 1, '5': 14, '6': '.veilidchat.EncryptionKeyType', '10': 'encryptionKeyType'},
{'1': 'private', '3': 2, '4': 1, '5': 12, '10': 'private'},
],
};
/// Descriptor for `ContactRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactRequestDescriptor = $convert.base64Decode(
'Cg5Db250YWN0UmVxdWVzdBJNChNlbmNyeXB0aW9uX2tleV90eXBlGAEgASgOMh0udmVpbGlkY2'
'hhdC5FbmNyeXB0aW9uS2V5VHlwZVIRZW5jcnlwdGlvbktleVR5cGUSGAoHcHJpdmF0ZRgCIAEo'
'DFIHcHJpdmF0ZQ==');
@$core.Deprecated('Use contactRequestPrivateDescriptor instead')
const ContactRequestPrivate$json = {
'1': 'ContactRequestPrivate',
'2': [
{'1': 'writer_key', '3': 1, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'writerKey'},
{'1': 'profile', '3': 2, '4': 1, '5': 11, '6': '.veilidchat.Profile', '10': 'profile'},
{'1': 'identity_master_record_key', '3': 3, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'identityMasterRecordKey'},
{'1': 'chat_record_key', '3': 4, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'chatRecordKey'},
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
],
};
/// Descriptor for `ContactRequestPrivate`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactRequestPrivateDescriptor = $convert.base64Decode(
'ChVDb250YWN0UmVxdWVzdFByaXZhdGUSMAoKd3JpdGVyX2tleRgBIAEoCzIRLnZlaWxpZC5Dcn'
'lwdG9LZXlSCXdyaXRlcktleRItCgdwcm9maWxlGAIgASgLMhMudmVpbGlkY2hhdC5Qcm9maWxl'
'Ugdwcm9maWxlEk0KGmlkZW50aXR5X21hc3Rlcl9yZWNvcmRfa2V5GAMgASgLMhAudmVpbGlkLl'
'R5cGVkS2V5UhdpZGVudGl0eU1hc3RlclJlY29yZEtleRI4Cg9jaGF0X3JlY29yZF9rZXkYBCAB'
'KAsyEC52ZWlsaWQuVHlwZWRLZXlSDWNoYXRSZWNvcmRLZXkSHgoKZXhwaXJhdGlvbhgFIAEoBF'
'IKZXhwaXJhdGlvbg==');
@$core.Deprecated('Use contactResponseDescriptor instead')
const ContactResponse$json = {
'1': 'ContactResponse',
'2': [
{'1': 'accept', '3': 1, '4': 1, '5': 8, '10': 'accept'},
{'1': 'identity_master_record_key', '3': 2, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'identityMasterRecordKey'},
{'1': 'remote_conversation_record_key', '3': 3, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'remoteConversationRecordKey'},
],
};
/// Descriptor for `ContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactResponseDescriptor = $convert.base64Decode(
'Cg9Db250YWN0UmVzcG9uc2USFgoGYWNjZXB0GAEgASgIUgZhY2NlcHQSTQoaaWRlbnRpdHlfbW'
'FzdGVyX3JlY29yZF9rZXkYAiABKAsyEC52ZWlsaWQuVHlwZWRLZXlSF2lkZW50aXR5TWFzdGVy'
'UmVjb3JkS2V5ElUKHnJlbW90ZV9jb252ZXJzYXRpb25fcmVjb3JkX2tleRgDIAEoCzIQLnZlaW'
'xpZC5UeXBlZEtleVIbcmVtb3RlQ29udmVyc2F0aW9uUmVjb3JkS2V5');
@$core.Deprecated('Use signedContactResponseDescriptor instead')
const SignedContactResponse$json = {
'1': 'SignedContactResponse',
'2': [
{'1': 'contact_response', '3': 1, '4': 1, '5': 12, '10': 'contactResponse'},
{'1': 'identity_signature', '3': 2, '4': 1, '5': 11, '6': '.veilid.Signature', '10': 'identitySignature'},
],
};
/// Descriptor for `SignedContactResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List signedContactResponseDescriptor = $convert.base64Decode(
'ChVTaWduZWRDb250YWN0UmVzcG9uc2USKQoQY29udGFjdF9yZXNwb25zZRgBIAEoDFIPY29udG'
'FjdFJlc3BvbnNlEkAKEmlkZW50aXR5X3NpZ25hdHVyZRgCIAEoCzIRLnZlaWxpZC5TaWduYXR1'
'cmVSEWlkZW50aXR5U2lnbmF0dXJl');
@$core.Deprecated('Use contactInvitationRecordDescriptor instead')
const ContactInvitationRecord$json = {
'1': 'ContactInvitationRecord',
'2': [
{'1': 'contact_request_inbox', '3': 1, '4': 1, '5': 11, '6': '.dht.OwnedDHTRecordPointer', '10': 'contactRequestInbox'},
{'1': 'writer_key', '3': 2, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'writerKey'},
{'1': 'writer_secret', '3': 3, '4': 1, '5': 11, '6': '.veilid.CryptoKey', '10': 'writerSecret'},
{'1': 'local_conversation_record_key', '3': 4, '4': 1, '5': 11, '6': '.veilid.TypedKey', '10': 'localConversationRecordKey'},
{'1': 'expiration', '3': 5, '4': 1, '5': 4, '10': 'expiration'},
{'1': 'invitation', '3': 6, '4': 1, '5': 12, '10': 'invitation'},
{'1': 'message', '3': 7, '4': 1, '5': 9, '10': 'message'},
],
};
/// Descriptor for `ContactInvitationRecord`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List contactInvitationRecordDescriptor = $convert.base64Decode(
'ChdDb250YWN0SW52aXRhdGlvblJlY29yZBJOChVjb250YWN0X3JlcXVlc3RfaW5ib3gYASABKA'
'syGi5kaHQuT3duZWRESFRSZWNvcmRQb2ludGVyUhNjb250YWN0UmVxdWVzdEluYm94EjAKCndy'
'aXRlcl9rZXkYAiABKAsyES52ZWlsaWQuQ3J5cHRvS2V5Ugl3cml0ZXJLZXkSNgoNd3JpdGVyX3'
'NlY3JldBgDIAEoCzIRLnZlaWxpZC5DcnlwdG9LZXlSDHdyaXRlclNlY3JldBJTCh1sb2NhbF9j'
'b252ZXJzYXRpb25fcmVjb3JkX2tleRgEIAEoCzIQLnZlaWxpZC5UeXBlZEtleVIabG9jYWxDb2'
'52ZXJzYXRpb25SZWNvcmRLZXkSHgoKZXhwaXJhdGlvbhgFIAEoBFIKZXhwaXJhdGlvbhIeCgpp'
'bnZpdGF0aW9uGAYgASgMUgppbnZpdGF0aW9uEhgKB21lc3NhZ2UYByABKAlSB21lc3NhZ2U=');

View File

@ -1,136 +1,8 @@
syntax = "proto3";
package veilidchat;
// 32-byte value in bigendian format
message CryptoKey {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
fixed32 u6 = 7;
fixed32 u7 = 8;
}
// 64-byte value in bigendian format
message Signature {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
fixed32 u6 = 7;
fixed32 u7 = 8;
fixed32 u8 = 9;
fixed32 u9 = 10;
fixed32 u10 = 11;
fixed32 u11 = 12;
fixed32 u12 = 13;
fixed32 u13 = 14;
fixed32 u14 = 15;
fixed32 u15 = 16;
}
// 24-byte value in bigendian format
message Nonce {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
}
// 36-byte typed crypto key
message TypedKey {
// CryptoKind FourCC in bigendian format
fixed32 kind = 1;
// Key value
CryptoKey value = 2;
}
// Key pair
message KeyPair {
// Public key
CryptoKey key = 1;
// Private key
CryptoKey secret = 2;
}
// DHTData - represents chunked blob data in the DHT
// Header in subkey 0 follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are concatenated chunks
// Subkeys 0..stride on the 'keys' keys are concatenated chunks
//
// Keys must use writable schema in order to make this data mutable
message DHTData {
// Other keys to concatenate
// Uses the same writer as this DHTList with SMPL schema
repeated TypedKey keys = 1;
// Hash of reassembled data to verify contents
TypedKey hash = 2;
// Chunk size per subkey
uint32 chunk = 3;
// Total data size
uint32 size = 4;
}
// DHTShortArray - represents a re-orderable collection of up to 256 individual elements
// Header in subkey 0 of first key follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are individual elements
// Subkeys 0..stride on the 'keys' keys are also individual elements
//
// Keys must use writable schema in order to make this list mutable
message DHTShortArray {
// Other keys to concatenate
// Uses the same writer as this DHTList with SMPL schema
repeated TypedKey keys = 1;
// Item position index (uint8[256])
// Actual item location is:
// idx = index[n] + 1 (offset for header at idx 0)
// key = idx / stride
// subkey = idx % stride
bytes index = 2;
// Free items are not represented in the list but can be
// calculated through iteration
}
// DHTLog - represents an appendable/truncatable log collection of individual elements
// Header in subkey 0 of first key follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are individual elements
// Subkeys 0..stride on the 'keys' keys are also individual elements
//
// Keys must use writable schema in order to make this list mutable
message DHTLog {
// Other keys to concatenate
repeated TypedKey keys = 1;
// Back link to another DHTLog further back
TypedKey back = 2;
// Count of subkeys in all keys in this DHTLog
repeated uint32 subkey_counts = 3;
// Total count of subkeys in all keys in this DHTLog including all backlogs
uint32 total_subkeys = 4;
}
// DataReference
// Pointer to data somewhere in Veilid
// Abstraction over DHTData and BlockStore
message DataReference {
oneof kind {
TypedKey dht_data = 1;
// TypedKey block = 2;
}
}
import "veilid.proto";
import "dht.proto";
// AttachmentKind
// Enumeration of well-known attachment types
@ -149,9 +21,9 @@ message Attachment {
// Title or filename
string name = 3;
// Pointer to the data content
DataReference content = 4;
dht.DataReference content = 4;
// Author signature over all attachment fields and content fields and bytes
Signature signature = 5;
veilid.Signature signature = 5;
}
// A single message as part of a series of messages
@ -159,13 +31,13 @@ message Attachment {
// DHT Schema: SMPL(0,1,[identityPublicKey])
message Message {
// Author of the message
TypedKey author = 1;
veilid.TypedKey author = 1;
// Time the message was sent (us since epoch)
uint64 timestamp = 2;
// Text of the message
string text = 3;
// Author signature over all of the fields and attachment signatures
Signature signature = 4;
veilid.Signature signature = 4;
// Attachments on the message
repeated Attachment attachments = 5;
}
@ -184,7 +56,7 @@ message Conversation {
// Identity master (JSON) to publish to friend
string identity_master_json = 2;
// Messages DHTLog (xxx for now DHTShortArray)
TypedKey messages = 3;
veilid.TypedKey messages = 3;
}
// A record of a contact that has accepted a contact invitation
@ -202,11 +74,11 @@ message Contact {
// Copy of friend's IdentityMaster in JSON from remote conversation
string identity_master_json = 3;
// Copy of friend's most recent identity public key from their identityMaster
TypedKey identity_public_key = 4;
veilid.TypedKey identity_public_key = 4;
// Remote conversation key to sync from friend
TypedKey remote_conversation_record_key = 5;
veilid.TypedKey remote_conversation_record_key = 5;
// Our conversation key for friend to sync
TypedKey local_conversation_record_key = 6;
veilid.TypedKey local_conversation_record_key = 6;
// Show availability
bool show_availability = 7;
}
@ -235,16 +107,9 @@ message Profile {
// Availability
Availability availability = 4;
// Avatar DHTData
optional TypedKey avatar = 5;
optional veilid.TypedKey avatar = 5;
}
// A pointer to an child DHT record
message OwnedDHTRecordPointer {
// DHT Record key
TypedKey record_key = 1;
// DHT record owner key
KeyPair owner = 2;
}
enum ChatType {
CHAT_TYPE_UNSPECIFIED = 0;
@ -257,7 +122,7 @@ message Chat {
// What kind of chat is this
ChatType type = 1;
// 1-1 Chat key
TypedKey remote_conversation_key = 2;
veilid.TypedKey remote_conversation_key = 2;
}
// A record of an individual account
@ -274,13 +139,13 @@ message Account {
uint32 auto_away_timeout_sec = 3;
// The contacts DHTList for this account
// DHT Private
OwnedDHTRecordPointer contact_list = 4;
dht.OwnedDHTRecordPointer contact_list = 4;
// The ContactInvitationRecord DHTShortArray for this account
// DHT Private
OwnedDHTRecordPointer contact_invitation_records = 5;
dht.OwnedDHTRecordPointer contact_invitation_records = 5;
// The chats DHTList for this account
// DHT Private
OwnedDHTRecordPointer chat_list = 6;
dht.OwnedDHTRecordPointer chat_list = 6;
}
@ -299,7 +164,7 @@ enum EncryptionKeyType {
// in the ContactRequestInbox subkey 0 DHT key
message ContactInvitation {
// Contact request DHT record key
TypedKey contact_request_inbox_key = 1;
veilid.TypedKey contact_request_inbox_key = 1;
// Writer secret key bytes possibly encrypted with nonce appended
bytes writer_secret = 2;
}
@ -309,7 +174,7 @@ message SignedContactInvitation {
// The serialized bytes for the contact invitation
bytes contact_invitation = 1;
// The signature of the contact_invitation bytes with the identity
Signature identity_signature = 2;
veilid.Signature identity_signature = 2;
}
// Contact request unicastinbox on the DHT
@ -325,13 +190,13 @@ message ContactRequest {
// Symmetrically encrypted with writer secret
message ContactRequestPrivate {
// Writer public key for signing writes to contact request unicastinbox
CryptoKey writer_key = 1;
veilid.CryptoKey writer_key = 1;
// Snapshot of profile
Profile profile = 2;
// Identity master DHT record key
TypedKey identity_master_record_key = 3;
veilid.TypedKey identity_master_record_key = 3;
// Local chat DHT record key
TypedKey chat_record_key = 4;
veilid.TypedKey chat_record_key = 4;
// Expiration timestamp
uint64 expiration = 5;
}
@ -341,9 +206,9 @@ message ContactResponse {
// Accept or reject
bool accept = 1;
// Remote identity master DHT record key
TypedKey identity_master_record_key = 2;
veilid.TypedKey identity_master_record_key = 2;
// Remote chat DHT record key if accepted
TypedKey remote_conversation_record_key = 3;
veilid.TypedKey remote_conversation_record_key = 3;
}
// Signature of response with identity
@ -352,19 +217,19 @@ message SignedContactResponse {
// Serialized bytes for ContactResponse
bytes contact_response = 1;
// Signature of the contact_accept bytes with the identity
Signature identity_signature = 2;
veilid.Signature identity_signature = 2;
}
// Contact request record kept in Account DHTList to keep track of extant contact invitations
message ContactInvitationRecord {
// Contact request unicastinbox DHT record key (parent is accountkey)
OwnedDHTRecordPointer contact_request_inbox = 1;
dht.OwnedDHTRecordPointer contact_request_inbox = 1;
// Writer key sent to contact for the contact_request_inbox smpl inbox subkey
CryptoKey writer_key = 2;
veilid.CryptoKey writer_key = 2;
// Writer secret sent encrypted in the invitation
CryptoKey writer_secret = 3;
veilid.CryptoKey writer_secret = 3;
// Local chat DHT record key (parent is accountkey, will be moved to Contact if accepted)
TypedKey local_conversation_record_key = 4;
veilid.TypedKey local_conversation_record_key = 4;
// Expiration timestamp
uint64 expiration = 5;
// A copy of the raw SignedContactInvitation invitation bytes post-encryption and signing

View File

@ -1,7 +1,7 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/local_account.dart';
import '../entities/proto.dart' as proto;
import '../proto/proto.dart' as proto;
import '../entities/user_login.dart';
import '../veilid_support/veilid_support.dart';

View File

@ -29,8 +29,6 @@ class _SystemHash {
}
}
typedef FetchAccountRef = AutoDisposeFutureProviderRef<AccountInfo>;
/// Get an account from the identity key and if it is logged in and we
/// have its secret available, return the account record contents
///
@ -95,10 +93,10 @@ class FetchAccountProvider extends AutoDisposeFutureProvider<AccountInfo> {
///
/// Copied from [fetchAccount].
FetchAccountProvider({
required this.accountMasterRecordKey,
}) : super.internal(
required Typed<FixedEncodedString43> accountMasterRecordKey,
}) : this._internal(
(ref) => fetchAccount(
ref,
ref as FetchAccountRef,
accountMasterRecordKey: accountMasterRecordKey,
),
from: fetchAccountProvider,
@ -110,10 +108,44 @@ class FetchAccountProvider extends AutoDisposeFutureProvider<AccountInfo> {
dependencies: FetchAccountFamily._dependencies,
allTransitiveDependencies:
FetchAccountFamily._allTransitiveDependencies,
accountMasterRecordKey: accountMasterRecordKey,
);
FetchAccountProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.accountMasterRecordKey,
}) : super.internal();
final Typed<FixedEncodedString43> accountMasterRecordKey;
@override
Override overrideWith(
FutureOr<AccountInfo> Function(FetchAccountRef provider) create,
) {
return ProviderOverride(
origin: this,
override: FetchAccountProvider._internal(
(ref) => create(ref as FetchAccountRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
accountMasterRecordKey: accountMasterRecordKey,
),
);
}
@override
AutoDisposeFutureProviderElement<AccountInfo> createElement() {
return _FetchAccountProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is FetchAccountProvider &&
@ -129,6 +161,20 @@ class FetchAccountProvider extends AutoDisposeFutureProvider<AccountInfo> {
}
}
mixin FetchAccountRef on AutoDisposeFutureProviderRef<AccountInfo> {
/// The parameter `accountMasterRecordKey` of this provider.
Typed<FixedEncodedString43> get accountMasterRecordKey;
}
class _FetchAccountProviderElement
extends AutoDisposeFutureProviderElement<AccountInfo> with FetchAccountRef {
_FetchAccountProviderElement(super.provider);
@override
Typed<FixedEncodedString43> get accountMasterRecordKey =>
(origin as FetchAccountProvider).accountMasterRecordKey;
}
String _$fetchActiveAccountHash() =>
r'd074ab2c160bab41ed3dd979b7054603b7d5b2b1';
@ -149,4 +195,5 @@ final fetchActiveAccountProvider =
typedef FetchActiveAccountRef
= AutoDisposeFutureProviderRef<ActiveAccountInfo?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -1,8 +1,8 @@
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/proto.dart' as proto;
import '../entities/proto.dart' show Chat, ChatType;
import '../proto/proto.dart' as proto;
import '../proto/proto.dart' show Chat, ChatType;
import '../tools/tools.dart';
import '../veilid_support/veilid_support.dart';

View File

@ -23,4 +23,5 @@ final fetchChatListProvider = AutoDisposeFutureProvider<IList<Chat>?>.internal(
);
typedef FetchChatListRef = AutoDisposeFutureProviderRef<IList<Chat>?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -3,9 +3,8 @@ import 'dart:convert';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/identity.dart';
import '../entities/proto.dart' as proto;
import '../entities/proto.dart' show Contact;
import '../proto/proto.dart' as proto;
import '../proto/proto.dart' show Contact;
import '../veilid_support/veilid_support.dart';
import 'account.dart';

View File

@ -24,4 +24,5 @@ final fetchContactListProvider =
);
typedef FetchContactListRef = AutoDisposeFutureProviderRef<IList<Contact>?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -4,10 +4,9 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:fixnum/fixnum.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/identity.dart';
import '../entities/local_account.dart';
import '../entities/proto.dart' as proto;
import '../entities/proto.dart'
import '../proto/proto.dart' as proto;
import '../proto/proto.dart'
show
ContactInvitation,
ContactInvitationRecord,
@ -16,7 +15,7 @@ import '../entities/proto.dart'
ContactResponse,
SignedContactInvitation,
SignedContactResponse;
import '../log/loggy.dart';
import '../log/log.dart';
import '../tools/tools.dart';
import '../veilid_support/veilid_support.dart';
import 'account.dart';
@ -60,13 +59,11 @@ Future<AcceptedOrRejectedContact?> checkAcceptRejectContact(
proto.CryptoKeyProto.fromProto(contactInvitationRecord.writerKey);
final writerSecret =
proto.CryptoKeyProto.fromProto(contactInvitationRecord.writerSecret);
final recordKey = proto.TypedKeyProto.fromProto(
contactInvitationRecord.contactRequestInbox.recordKey);
final writer = TypedKeyPair(
kind: contactInvitationRecord.contactRequestInbox.recordKey.kind,
key: writerKey,
secret: writerSecret);
final acceptReject = await (await pool.openRead(
proto.TypedKeyProto.fromProto(
contactInvitationRecord.contactRequestInbox.recordKey),
kind: recordKey.kind, key: writerKey, secret: writerSecret);
final acceptReject = await (await pool.openRead(recordKey,
crypto: await DHTRecordCryptoPrivate.fromTypedKeyPair(writer),
parent: accountRecordKey,
defaultSubkey: 1))
@ -83,8 +80,7 @@ Future<AcceptedOrRejectedContact?> checkAcceptRejectContact(
final contactResponse = ContactResponse.fromBuffer(contactResponseBytes);
final contactIdentityMasterRecordKey = proto.TypedKeyProto.fromProto(
contactResponse.identityMasterRecordKey);
final cs = await pool.veilid.getCryptoSystem(
contactInvitationRecord.contactRequestInbox.recordKey.kind);
final cs = await pool.veilid.getCryptoSystem(recordKey.kind);
// Fetch the remote contact's account master
final contactIdentityMaster = await openIdentityMaster(
@ -96,6 +92,11 @@ Future<AcceptedOrRejectedContact?> checkAcceptRejectContact(
await cs.verify(contactIdentityMaster.identityPublicKey,
contactResponseBytes, signature);
// Check for rejection
if (!contactResponse.accept) {
return AcceptedOrRejectedContact(acceptedContact: null);
}
// Pull profile from remote conversation key
final remoteConversationRecordKey = proto.TypedKeyProto.fromProto(
contactResponse.remoteConversationRecordKey);

View File

@ -26,4 +26,5 @@ final fetchContactInvitationRecordsProvider =
typedef FetchContactInvitationRecordsRef
= AutoDisposeFutureProviderRef<IList<ContactInvitationRecord>?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -3,10 +3,11 @@ import 'dart:convert';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/proto.dart' as proto;
import '../entities/proto.dart' show Conversation, Message;
import '../proto/proto.dart' as proto;
import '../proto/proto.dart' show Conversation, Message;
import '../log/loggy.dart';
import '../veilid_init.dart';
import '../veilid_support/veilid_support.dart';
import 'account.dart';
import 'chat.dart';
@ -332,6 +333,8 @@ class ActiveConversationMessages extends _$ActiveConversationMessages {
/// Get message for active converation
@override
FutureOr<IList<Message>?> build() async {
await eventualVeilid.future;
final activeChat = activeChatState.currentState;
if (activeChat == null) {
return null;

View File

@ -7,7 +7,7 @@ part of 'conversation.dart';
// **************************************************************************
String _$activeConversationMessagesHash() =>
r'd65cd8bf71122806320325e7f0e5f8e751d13b55';
r'1ec73644fd9b6c96c891487e3d027eb8834d25b6';
/// See also [ActiveConversationMessages].
@ProviderFor(ActiveConversationMessages)
@ -24,4 +24,5 @@ final activeConversationMessagesProvider = AutoDisposeAsyncNotifierProvider<
typedef _$ActiveConversationMessages
= AutoDisposeAsyncNotifier<IList<Message>?>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -4,13 +4,17 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/entities.dart';
import '../proto/proto.dart' as proto;
import '../log/loggy.dart';
import '../tools/tools.dart';
import '../veilid_init.dart';
import '../veilid_support/veilid_support.dart';
import 'logins.dart';
part 'local_accounts.g.dart';
const String veilidChatAccountKey = 'com.veilid.veilidchat';
// Local account manager
@riverpod
class LocalAccounts extends _$LocalAccounts
@ -34,6 +38,7 @@ class LocalAccounts extends _$LocalAccounts
@override
FutureOr<IList<LocalAccount>> build() async {
try {
await eventualVeilid.future;
return await load();
} on Exception catch (e) {
log.error('Failed to load LocalAccounts table: $e');
@ -66,12 +71,34 @@ class LocalAccounts extends _$LocalAccounts
String encryptionKey = ''}) async {
final localAccounts = state.requireValue;
/////// Add account with profile to DHT
await identityMaster.newAccount(
identitySecret: identitySecret,
name: name,
title: title,
);
// Add account with profile to DHT
await identityMaster.addAccountToIdentity(
identitySecret: identitySecret,
accountKey: veilidChatAccountKey,
createAccountCallback: (parent) async {
// Make empty contact list
final contactList = await (await DHTShortArray.create(parent: parent))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make empty contact invitation record list
final contactInvitationRecords =
await (await DHTShortArray.create(parent: parent))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make empty chat record list
final chatRecords = await (await DHTShortArray.create(parent: parent))
.scope((r) async => r.record.ownedDHTRecordPointer);
// Make account object
final account = proto.Account()
..profile = (proto.Profile()
..name = name
..title = title)
..contactList = contactList.toProto()
..contactInvitationRecords = contactInvitationRecords.toProto()
..chatList = chatRecords.toProto();
return account;
});
// Encrypt identitySecret with key
final identitySecretBytes = await encryptSecretToBytes(

View File

@ -29,8 +29,6 @@ class _SystemHash {
}
}
typedef FetchLocalAccountRef = AutoDisposeFutureProviderRef<LocalAccount?>;
/// See also [fetchLocalAccount].
@ProviderFor(fetchLocalAccount)
const fetchLocalAccountProvider = FetchLocalAccountFamily();
@ -78,10 +76,10 @@ class FetchLocalAccountProvider
extends AutoDisposeFutureProvider<LocalAccount?> {
/// See also [fetchLocalAccount].
FetchLocalAccountProvider({
required this.accountMasterRecordKey,
}) : super.internal(
required Typed<FixedEncodedString43> accountMasterRecordKey,
}) : this._internal(
(ref) => fetchLocalAccount(
ref,
ref as FetchLocalAccountRef,
accountMasterRecordKey: accountMasterRecordKey,
),
from: fetchLocalAccountProvider,
@ -93,10 +91,44 @@ class FetchLocalAccountProvider
dependencies: FetchLocalAccountFamily._dependencies,
allTransitiveDependencies:
FetchLocalAccountFamily._allTransitiveDependencies,
accountMasterRecordKey: accountMasterRecordKey,
);
FetchLocalAccountProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.accountMasterRecordKey,
}) : super.internal();
final Typed<FixedEncodedString43> accountMasterRecordKey;
@override
Override overrideWith(
FutureOr<LocalAccount?> Function(FetchLocalAccountRef provider) create,
) {
return ProviderOverride(
origin: this,
override: FetchLocalAccountProvider._internal(
(ref) => create(ref as FetchLocalAccountRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
accountMasterRecordKey: accountMasterRecordKey,
),
);
}
@override
AutoDisposeFutureProviderElement<LocalAccount?> createElement() {
return _FetchLocalAccountProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is FetchLocalAccountProvider &&
@ -112,7 +144,22 @@ class FetchLocalAccountProvider
}
}
String _$localAccountsHash() => r'3f532f7a6caf8e4eaa9f8636a632126a10b8b07f';
mixin FetchLocalAccountRef on AutoDisposeFutureProviderRef<LocalAccount?> {
/// The parameter `accountMasterRecordKey` of this provider.
Typed<FixedEncodedString43> get accountMasterRecordKey;
}
class _FetchLocalAccountProviderElement
extends AutoDisposeFutureProviderElement<LocalAccount?>
with FetchLocalAccountRef {
_FetchLocalAccountProviderElement(super.provider);
@override
Typed<FixedEncodedString43> get accountMasterRecordKey =>
(origin as FetchLocalAccountProvider).accountMasterRecordKey;
}
String _$localAccountsHash() => r'0ab9eca923cb9e15149f06d9edbb9de0cfed6790';
/// See also [LocalAccounts].
@ProviderFor(LocalAccounts)
@ -128,4 +175,5 @@ final localAccountsProvider = AutoDisposeAsyncNotifierProvider<LocalAccounts,
);
typedef _$LocalAccounts = AutoDisposeAsyncNotifier<IList<LocalAccount>>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -6,6 +6,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../entities/entities.dart';
import '../log/loggy.dart';
import '../tools/tools.dart';
import '../veilid_init.dart';
import '../veilid_support/veilid_support.dart';
import 'local_accounts.dart';
@ -31,6 +32,7 @@ class Logins extends _$Logins with AsyncTableDBBacked<ActiveLogins> {
@override
FutureOr<ActiveLogins> build() async {
try {
await eventualVeilid.future;
return await load();
} on Exception catch (e) {
log.error('Failed to load ActiveLogins table: $e');
@ -66,7 +68,7 @@ class Logins extends _$Logins with AsyncTableDBBacked<ActiveLogins> {
// Read the identity key to get the account keys
final accountRecordInfo = await identityMaster.readAccountFromIdentity(
identitySecret: identitySecret);
identitySecret: identitySecret, accountKey: veilidChatAccountKey);
// Add to user logins and select it
final current = state.requireValue;

View File

@ -29,8 +29,6 @@ class _SystemHash {
}
}
typedef FetchLoginRef = AutoDisposeFutureProviderRef<UserLogin?>;
/// See also [fetchLogin].
@ProviderFor(fetchLogin)
const fetchLoginProvider = FetchLoginFamily();
@ -77,10 +75,10 @@ class FetchLoginFamily extends Family<AsyncValue<UserLogin?>> {
class FetchLoginProvider extends AutoDisposeFutureProvider<UserLogin?> {
/// See also [fetchLogin].
FetchLoginProvider({
required this.accountMasterRecordKey,
}) : super.internal(
required Typed<FixedEncodedString43> accountMasterRecordKey,
}) : this._internal(
(ref) => fetchLogin(
ref,
ref as FetchLoginRef,
accountMasterRecordKey: accountMasterRecordKey,
),
from: fetchLoginProvider,
@ -92,10 +90,44 @@ class FetchLoginProvider extends AutoDisposeFutureProvider<UserLogin?> {
dependencies: FetchLoginFamily._dependencies,
allTransitiveDependencies:
FetchLoginFamily._allTransitiveDependencies,
accountMasterRecordKey: accountMasterRecordKey,
);
FetchLoginProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.accountMasterRecordKey,
}) : super.internal();
final Typed<FixedEncodedString43> accountMasterRecordKey;
@override
Override overrideWith(
FutureOr<UserLogin?> Function(FetchLoginRef provider) create,
) {
return ProviderOverride(
origin: this,
override: FetchLoginProvider._internal(
(ref) => create(ref as FetchLoginRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
accountMasterRecordKey: accountMasterRecordKey,
),
);
}
@override
AutoDisposeFutureProviderElement<UserLogin?> createElement() {
return _FetchLoginProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is FetchLoginProvider &&
@ -111,7 +143,21 @@ class FetchLoginProvider extends AutoDisposeFutureProvider<UserLogin?> {
}
}
String _$loginsHash() => r'b07a2fe61a8662dbeb5f12d823d49d3645b2b944';
mixin FetchLoginRef on AutoDisposeFutureProviderRef<UserLogin?> {
/// The parameter `accountMasterRecordKey` of this provider.
Typed<FixedEncodedString43> get accountMasterRecordKey;
}
class _FetchLoginProviderElement
extends AutoDisposeFutureProviderElement<UserLogin?> with FetchLoginRef {
_FetchLoginProviderElement(super.provider);
@override
Typed<FixedEncodedString43> get accountMasterRecordKey =>
(origin as FetchLoginProvider).accountMasterRecordKey;
}
String _$loginsHash() => r'41c4630869b474c409b2fb3461dd2a56d9350c7f';
/// See also [Logins].
@ProviderFor(Logins)
@ -126,4 +172,5 @@ final loginsProvider =
);
typedef _$Logins = AutoDisposeAsyncNotifier<ActiveLogins>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -1,9 +0,0 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../veilid_support/veilid_support.dart';
part 'veilid_instance.g.dart';
// Expose the Veilid instance as a FutureProvider
@riverpod
FutureOr<Veilid> veilidInstance(VeilidInstanceRef ref) async =>
await eventualVeilid.future;

View File

@ -22,4 +22,5 @@ final windowControlProvider =
);
typedef _$WindowControl = AutoDisposeAsyncNotifier<bool>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -22,4 +22,5 @@ final routerProvider = AutoDisposeProvider<GoRouter>.internal(
);
typedef RouterRef = AutoDisposeProviderRef<GoRouter>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -10,6 +10,7 @@ import '../pages/settings.dart';
import '../providers/chat.dart';
import '../providers/local_accounts.dart';
import '../tools/responsive.dart';
import '../veilid_init.dart';
part 'router_notifier.g.dart';
@ -46,9 +47,14 @@ class RouterNotifier extends _$RouterNotifier implements Listenable {
}
// No matter where we are, if there's not
switch (state.matchedLocation) {
case '/':
// Wait for veilid to be initialized
if (!eventualVeilid.isCompleted) {
return null;
}
return hasAnyAccount ? '/home' : '/new_account';
case '/new_account':
return hasAnyAccount ? '/home' : null;

View File

@ -6,7 +6,7 @@ part of 'router_notifier.dart';
// RiverpodGenerator
// **************************************************************************
String _$routerNotifierHash() => r'745bae688e8675c3046b95f29cbe0122bac3f189';
String _$routerNotifierHash() => r'8e636edc119d07296a95a5de8a6edadb119154cf';
/// See also [RouterNotifier].
@ProviderFor(RouterNotifier)
@ -22,4 +22,5 @@ final routerNotifierProvider =
);
typedef _$RouterNotifier = AutoDisposeAsyncNotifier<void>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -5,12 +5,13 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../entities/proto.dart' as proto;
import 'proto/proto.dart' as proto;
import 'providers/account.dart';
import 'providers/chat.dart';
import 'providers/contact.dart';
import 'providers/contact_invite.dart';
import 'providers/conversation.dart';
import 'veilid_init.dart';
const int ticksPerContactInvitationCheck = 5;
const int ticksPerNewMessageCheck = 5;
@ -57,6 +58,11 @@ class BackgroundTickerState extends ConsumerState<BackgroundTicker> {
}
Future<void> _onTick() async {
// Don't tick until veilid is started
if (!eventualVeilid.isCompleted) {
return;
}
_inTick = true;
try {
final unord = <Future<void>>[];

View File

@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:radix_colors/radix_colors.dart';
@ -527,7 +526,7 @@ ChatTheme makeChatTheme(ScaleScheme scale, TextTheme textTheme) =>
inputContainerDecoration: BoxDecoration(color: scale.primaryScale.border),
inputPadding: const EdgeInsets.all(9),
inputTextColor: scale.primaryScale.text,
attachmentButtonIcon: Icon(Icons.attach_file),
attachmentButtonIcon: const Icon(Icons.attach_file),
);
ThemeData radixGenerator(Brightness brightness, RadixThemeColor themeColor) {

View File

@ -1,5 +1,6 @@
import 'dart:typed_data';
import '../entities/local_account.dart';
import '../veilid_init.dart';
import '../veilid_support/veilid_support.dart';
Future<Uint8List> encryptSecretToBytes(

View File

@ -20,4 +20,5 @@ final themeServiceProvider = AutoDisposeFutureProvider<ThemeService>.internal(
);
typedef ThemeServiceRef = AutoDisposeFutureProviderRef<ThemeService>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -1,8 +1,6 @@
export 'animations.dart';
export 'external_stream_state.dart';
export 'json_tools.dart';
export 'phono_byte.dart';
export 'protobuf_tools.dart';
export 'radix_generator.dart';
export 'responsive.dart';
export 'secret_crypto.dart';

View File

@ -1,10 +1,12 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:veilid/veilid.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'processor.dart';
import 'veilid_log.dart';
import 'veilid_support/veilid_support.dart';
part 'veilid_init.g.dart';
Future<String> getVeilidVersion() async {
String veilidVersion;
@ -40,7 +42,7 @@ void _initVeilid() {
otlp: VeilidFFIConfigLoggingOtlp(
enabled: false,
level: VeilidConfigLogLevel.trace,
grpcEndpoint: '192.168.1.40:4317',
grpcEndpoint: '127.0.0.1:4317',
serviceName: 'VeilidChat'),
api: VeilidFFIConfigLoggingApi(
enabled: true, level: VeilidConfigLogLevel.info)));
@ -69,3 +71,8 @@ Future<void> initializeVeilid() async {
// Share the initialized veilid instance to the rest of the app
eventualVeilid.complete(Veilid.instance);
}
// Expose the Veilid instance as a FutureProvider
@riverpod
FutureOr<Veilid> veilidInstance(VeilidInstanceRef ref) async =>
await eventualVeilid.future;

View File

@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'veilid_instance.dart';
part of 'veilid_init.dart';
// **************************************************************************
// RiverpodGenerator
@ -21,4 +21,5 @@ final veilidInstanceProvider = AutoDisposeFutureProvider<Veilid>.internal(
);
typedef VeilidInstanceRef = AutoDisposeFutureProviderRef<Veilid>;
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View File

@ -1,4 +1,8 @@
export 'dht_record.dart';
export 'dht_record_crypto.dart';
export 'dht_record_pool.dart';
export 'dht_short_array.dart';
/// Support functions for Veilid DHT data structures
library dht_support;
export 'src/dht_record.dart';
export 'src/dht_record_crypto.dart';
export 'src/dht_record_pool.dart';
export 'src/dht_short_array.dart';

View File

@ -0,0 +1,84 @@
syntax = "proto3";
package dht;
import "veilid.proto";
// DHTData - represents chunked blob data in the DHT
// Header in subkey 0 follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are concatenated chunks
// Subkeys 0..stride on the 'keys' keys are concatenated chunks
//
// Keys must use writable schema in order to make this data mutable
message DHTData {
// Other keys to concatenate
// Uses the same writer as this DHTList with SMPL schema
repeated veilid.TypedKey keys = 1;
// Hash of reassembled data to verify contents
veilid.TypedKey hash = 2;
// Chunk size per subkey
uint32 chunk = 3;
// Total data size
uint32 size = 4;
}
// DHTShortArray - represents a re-orderable collection of up to 256 individual elements
// Header in subkey 0 of first key follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are individual elements
// Subkeys 0..stride on the 'keys' keys are also individual elements
//
// Keys must use writable schema in order to make this list mutable
message DHTShortArray {
// Other keys to concatenate
// Uses the same writer as this DHTList with SMPL schema
repeated veilid.TypedKey keys = 1;
// Item position index (uint8[256])
// Actual item location is:
// idx = index[n] + 1 (offset for header at idx 0)
// key = idx / stride
// subkey = idx % stride
bytes index = 2;
// Free items are not represented in the list but can be
// calculated through iteration
}
// DHTLog - represents an appendable/truncatable log collection of individual elements
// Header in subkey 0 of first key follows this structure
//
// stride = descriptor subkey count on first key - 1
// Subkeys 1..=stride on the first key are individual elements
// Subkeys 0..stride on the 'keys' keys are also individual elements
//
// Keys must use writable schema in order to make this list mutable
message DHTLog {
// Other keys to concatenate
repeated veilid.TypedKey keys = 1;
// Back link to another DHTLog further back
veilid.TypedKey back = 2;
// Count of subkeys in all keys in this DHTLog
repeated uint32 subkey_counts = 3;
// Total count of subkeys in all keys in this DHTLog including all backlogs
uint32 total_subkeys = 4;
}
// DataReference
// Pointer to data somewhere in Veilid
// Abstraction over DHTData and BlockStore
message DataReference {
oneof kind {
veilid.TypedKey dht_data = 1;
// TypedKey block = 2;
}
}
// A pointer to an child DHT record
message OwnedDHTRecordPointer {
// DHT Record key
veilid.TypedKey record_key = 1;
// DHT record owner key
veilid.KeyPair owner = 2;
}

View File

@ -0,0 +1,25 @@
import '../../../proto/dht.pb.dart' as dhtproto;
import '../../proto/proto.dart' as veilidproto;
import '../dht_support.dart';
export '../../../proto/dht.pb.dart';
export '../../../proto/dht.pbenum.dart';
export '../../../proto/dht.pbjson.dart';
export '../../../proto/dht.pbserver.dart';
export '../../proto/proto.dart';
/// OwnedDHTRecordPointer protobuf marshaling
///
extension OwnedDHTRecordPointerProto on OwnedDHTRecordPointer {
dhtproto.OwnedDHTRecordPointer toProto() {
final out = dhtproto.OwnedDHTRecordPointer()
..recordKey = recordKey.toProto()
..owner = owner.toProto();
return out;
}
static OwnedDHTRecordPointer fromProto(dhtproto.OwnedDHTRecordPointer p) =>
OwnedDHTRecordPointer(
recordKey: veilidproto.TypedKeyProto.fromProto(p.recordKey),
owner: veilidproto.KeyPairProto.fromProto(p.owner));
}

View File

@ -3,8 +3,7 @@ import 'dart:typed_data';
import 'package:protobuf/protobuf.dart';
import '../../tools/tools.dart';
import '../veilid_support.dart';
import '../../veilid_support.dart';
class DHTRecord {
DHTRecord(

View File

@ -1,9 +1,6 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:veilid/veilid.dart';
import '../veilid_init.dart';
import '../../veilid_support.dart';
abstract class DHTRecordCrypto {
FutureOr<Uint8List> encrypt(Uint8List data, int subkey);
@ -22,16 +19,15 @@ class DHTRecordCryptoPrivate implements DHTRecordCrypto {
static Future<DHTRecordCryptoPrivate> fromTypedKeyPair(
TypedKeyPair typedKeyPair) async {
final veilid = await eventualVeilid.future;
final cryptoSystem = await veilid.getCryptoSystem(typedKeyPair.kind);
final cryptoSystem =
await Veilid.instance.getCryptoSystem(typedKeyPair.kind);
final secretKey = typedKeyPair.secret;
return DHTRecordCryptoPrivate._(cryptoSystem, secretKey);
}
static Future<DHTRecordCryptoPrivate> fromSecret(
CryptoKind kind, SharedSecret secretKey) async {
final veilid = await eventualVeilid.future;
final cryptoSystem = await veilid.getCryptoSystem(kind);
final cryptoSystem = await Veilid.instance.getCryptoSystem(kind);
return DHTRecordCryptoPrivate._(cryptoSystem, secretKey);
}

View File

@ -2,8 +2,7 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mutex/mutex.dart';
import '../../log/loggy.dart';
import '../veilid_support.dart';
import '../../veilid_support.dart';
part 'dht_record_pool.freezed.dart';
part 'dht_record_pool.g.dart';
@ -78,17 +77,12 @@ class DHTRecordPool with AsyncTableDBBacked<DHTRecordPoolAllocations> {
static Future<DHTRecordPool> instance() async {
return instanceSetupMutex.protect(() async {
if (_singleton == null) {
final veilid = await eventualVeilid.future;
final routingContext = (await veilid.routingContext())
final routingContext = (await Veilid.instance.routingContext())
.withPrivacy()
.withSequencing(Sequencing.preferOrdered);
final globalPool = DHTRecordPool._(veilid, routingContext);
try {
globalPool._state = await globalPool.load();
} on Exception catch (e) {
log.error('Failed to load DHTRecordPool: $e');
}
final globalPool = DHTRecordPool._(Veilid.instance, routingContext);
globalPool._state = await globalPool.load();
_singleton = globalPool;
}
return _singleton!;
@ -208,12 +202,14 @@ class DHTRecordPool with AsyncTableDBBacked<DHTRecordPoolAllocations> {
///////////////////////////////////////////////////////////////////////
/// Create a root DHTRecord that has no dependent records
Future<DHTRecord> create(
{VeilidRoutingContext? routingContext,
TypedKey? parent,
DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
int defaultSubkey = 0,
DHTRecordCrypto? crypto}) async {
Future<DHTRecord> create({
VeilidRoutingContext? routingContext,
TypedKey? parent,
DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
int defaultSubkey = 0,
DHTRecordCrypto? crypto,
KeyPair? writer,
}) async {
final dhtctx = routingContext ?? _routingContext;
final recordDescriptor = await dhtctx.createDHTRecord(schema);
@ -221,7 +217,7 @@ class DHTRecordPool with AsyncTableDBBacked<DHTRecordPoolAllocations> {
routingContext: dhtctx,
recordDescriptor: recordDescriptor,
defaultSubkey: defaultSubkey,
writer: recordDescriptor.ownerKeyPair(),
writer: writer ?? recordDescriptor.ownerKeyPair(),
crypto: crypto ??
await DHTRecordCryptoPrivate.fromTypedKeyPair(
recordDescriptor.ownerTypedKeyPair()!));

View File

@ -3,9 +3,8 @@ import 'dart:typed_data';
import 'package:protobuf/protobuf.dart';
import '../../entities/proto.dart' as proto;
import '../../tools/tools.dart';
import '../veilid_support.dart';
import '../../veilid_support.dart';
import '../proto/proto.dart' as proto;
class _DHTShortArrayCache {
_DHTShortArrayCache()
@ -81,7 +80,8 @@ class DHTShortArray {
parent: parent,
routingContext: routingContext,
schema: schema,
crypto: crypto);
crypto: crypto,
writer: smplWriter);
// Reopen with SMPL writer
await dhtCreateRecord.close();
dhtRecord = await pool.openWrite(dhtCreateRecord.key, smplWriter,
@ -234,7 +234,8 @@ class DHTShortArray {
/// Validate a new head record
Future<void> _newHead(proto.DHTShortArray head) async {
// Get the set of new linked keys and validate it
final linkedKeys = head.keys.map(proto.TypedKeyProto.fromProto).toList();
final linkedKeys =
head.keys.map<TypedKey>(proto.TypedKeyProto.fromProto).toList();
final index = head.index;
final free = _validateHeadCacheData(linkedKeys, index);

View File

@ -1,130 +0,0 @@
// ignore_for_file: prefer_expression_function_bodies
import 'dart:typed_data';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import '../entities/identity.dart';
import 'veilid_support.dart';
// Identity Master with secrets
// Not freezed because we never persist this class in its entirety
class IdentityMasterWithSecrets {
IdentityMasterWithSecrets._(
{required this.identityMaster,
required this.masterSecret,
required this.identitySecret});
IdentityMaster identityMaster;
SecretKey masterSecret;
SecretKey identitySecret;
/// Creates a new master identity and returns it with its secrets
static Future<IdentityMasterWithSecrets> create() async {
final pool = await DHTRecordPool.instance();
// IdentityMaster DHT record is public/unencrypted
return (await pool.create(crypto: const DHTRecordCryptoPublic()))
.deleteScope((masterRec) async {
// Identity record is private
return (await pool.create(parent: masterRec.key))
.scope((identityRec) async {
// Make IdentityMaster
final masterRecordKey = masterRec.key;
final masterOwner = masterRec.ownerKeyPair!;
final masterSigBuf = BytesBuilder()
..add(masterRecordKey.decode())
..add(masterOwner.key.decode());
final identityRecordKey = identityRec.key;
final identityOwner = identityRec.ownerKeyPair!;
final identitySigBuf = BytesBuilder()
..add(identityRecordKey.decode())
..add(identityOwner.key.decode());
assert(masterRecordKey.kind == identityRecordKey.kind,
'new master and identity should have same cryptosystem');
final crypto = await pool.veilid.getCryptoSystem(masterRecordKey.kind);
final identitySignature =
await crypto.signWithKeyPair(masterOwner, identitySigBuf.toBytes());
final masterSignature =
await crypto.signWithKeyPair(identityOwner, masterSigBuf.toBytes());
final identityMaster = IdentityMaster(
identityRecordKey: identityRecordKey,
identityPublicKey: identityOwner.key,
masterRecordKey: masterRecordKey,
masterPublicKey: masterOwner.key,
identitySignature: identitySignature,
masterSignature: masterSignature);
// Write identity master to master dht key
await masterRec.eventualWriteJson(identityMaster);
// Make empty identity
const identity = Identity(accountRecords: IMapConst({}));
// Write empty identity to identity dht key
await identityRec.eventualWriteJson(identity);
return IdentityMasterWithSecrets._(
identityMaster: identityMaster,
masterSecret: masterOwner.secret,
identitySecret: identityOwner.secret);
});
});
}
/// Deletes a master identity and the identity record under it
Future<void> delete() async {
final pool = await DHTRecordPool.instance();
await (await pool.openRead(identityMaster.masterRecordKey)).delete();
}
}
/// Opens an existing master identity and validates it
Future<IdentityMaster> openIdentityMaster(
{required TypedKey identityMasterRecordKey}) async {
final pool = await DHTRecordPool.instance();
// IdentityMaster DHT record is public/unencrypted
return (await pool.openRead(identityMasterRecordKey))
.deleteScope((masterRec) async {
final identityMaster =
(await masterRec.getJson(IdentityMaster.fromJson, forceRefresh: true))!;
// Validate IdentityMaster
final masterRecordKey = masterRec.key;
final masterOwnerKey = masterRec.owner;
final masterSigBuf = BytesBuilder()
..add(masterRecordKey.decode())
..add(masterOwnerKey.decode());
final masterSignature = identityMaster.masterSignature;
final identityRecordKey = identityMaster.identityRecordKey;
final identityOwnerKey = identityMaster.identityPublicKey;
final identitySigBuf = BytesBuilder()
..add(identityRecordKey.decode())
..add(identityOwnerKey.decode());
final identitySignature = identityMaster.identitySignature;
assert(masterRecordKey.kind == identityRecordKey.kind,
'new master and identity should have same cryptosystem');
final crypto = await pool.veilid.getCryptoSystem(masterRecordKey.kind);
await crypto.verify(
masterOwnerKey, identitySigBuf.toBytes(), identitySignature);
await crypto.verify(
identityOwnerKey, masterSigBuf.toBytes(), masterSignature);
return identityMaster;
});
}
extension IdentityMasterX on IdentityMaster {
/// Deletes a master identity and the identity record under it
Future<void> delete() async {
final pool = await DHTRecordPool.instance();
await (await pool.openRead(masterRecordKey)).delete();
}
}

View File

@ -1,10 +1,12 @@
import 'dart:typed_data';
import '../veilid_support/veilid_support.dart';
import '../../proto/veilid.pb.dart' as proto;
import '../veilid_support.dart';
import 'proto/veilidchat.pb.dart' as proto;
export 'proto/veilidchat.pb.dart';
export '../../proto/veilid.pb.dart';
export '../../proto/veilid.pbenum.dart';
export '../../proto/veilid.pbjson.dart';
export '../../proto/veilid.pbserver.dart';
/// CryptoKey protobuf marshaling
///
@ -139,19 +141,3 @@ extension KeyPairProto on KeyPair {
key: CryptoKeyProto.fromProto(p.key),
secret: CryptoKeyProto.fromProto(p.secret));
}
/// OwnedDHTRecordPointer protobuf marshaling
///
extension OwnedDHTRecordPointerProto on OwnedDHTRecordPointer {
proto.OwnedDHTRecordPointer toProto() {
final out = proto.OwnedDHTRecordPointer()
..recordKey = recordKey.toProto()
..owner = owner.toProto();
return out;
}
static OwnedDHTRecordPointer fromProto(proto.OwnedDHTRecordPointer p) =>
OwnedDHTRecordPointer(
recordKey: TypedKeyProto.fromProto(p.recordKey),
owner: KeyPairProto.fromProto(p.owner));
}

View File

@ -0,0 +1,61 @@
syntax = "proto3";
package veilid;
// 32-byte value in bigendian format
message CryptoKey {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
fixed32 u6 = 7;
fixed32 u7 = 8;
}
// 64-byte value in bigendian format
message Signature {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
fixed32 u6 = 7;
fixed32 u7 = 8;
fixed32 u8 = 9;
fixed32 u9 = 10;
fixed32 u10 = 11;
fixed32 u11 = 12;
fixed32 u12 = 13;
fixed32 u13 = 14;
fixed32 u14 = 15;
fixed32 u15 = 16;
}
// 24-byte value in bigendian format
message Nonce {
fixed32 u0 = 1;
fixed32 u1 = 2;
fixed32 u2 = 3;
fixed32 u3 = 4;
fixed32 u4 = 5;
fixed32 u5 = 6;
}
// 36-byte typed crypto key
message TypedKey {
// CryptoKind FourCC in bigendian format
fixed32 kind = 1;
// Key value
CryptoKey value = 2;
}
// Key pair
message KeyPair {
// Public key
CryptoKey key = 1;
// Private key
CryptoKey secret = 2;
}

View File

@ -0,0 +1,281 @@
import 'dart:typed_data';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:protobuf/protobuf.dart';
import '../veilid_support.dart';
part 'identity.freezed.dart';
part 'identity.g.dart';
// AccountOwnerInfo is the key and owner info for the account dht key that is
// stored in the identity key
@freezed
class AccountRecordInfo with _$AccountRecordInfo {
const factory AccountRecordInfo({
// Top level account keys and secrets
required OwnedDHTRecordPointer accountRecord,
}) = _AccountRecordInfo;
factory AccountRecordInfo.fromJson(dynamic json) =>
_$AccountRecordInfoFromJson(json as Map<String, dynamic>);
}
// Identity Key points to accounts associated with this identity
// accounts field has a map of bundle id or uuid to account key pairs
// DHT Schema: DFLT(1)
// DHT Key (Private): identityRecordKey
// DHT Owner Key: identityPublicKey
// DHT Secret: identitySecretKey (stored encrypted
// with unlock code in local table store)
@freezed
class Identity with _$Identity {
const factory Identity({
// Top level account keys and secrets
required IMap<String, ISet<AccountRecordInfo>> accountRecords,
}) = _Identity;
factory Identity.fromJson(dynamic json) =>
_$IdentityFromJson(json as Map<String, dynamic>);
}
// Identity Master key structure for created account
// Master key allows for regeneration of identity DHT record
// Bidirectional Master<->Identity signature allows for
// chain of identity ownership for account recovery process
//
// Backed by a DHT key at masterRecordKey, the secret is kept
// completely offline and only written to upon account recovery
//
// DHT Schema: DFLT(1)
// DHT Record Key (Public): masterRecordKey
// DHT Owner Key: masterPublicKey
// DHT Owner Secret: masterSecretKey (kept offline)
// Encryption: None
@freezed
class IdentityMaster with _$IdentityMaster {
const factory IdentityMaster(
{
// Private DHT record storing identity account mapping
required TypedKey identityRecordKey,
// Public key of identity
required PublicKey identityPublicKey,
// Public DHT record storing this structure for account recovery
required TypedKey masterRecordKey,
// Public key of master identity used to sign identity keys for recovery
required PublicKey masterPublicKey,
// Signature of identityRecordKey and identityPublicKey by masterPublicKey
required Signature identitySignature,
// Signature of masterRecordKey and masterPublicKey by identityPublicKey
required Signature masterSignature}) = _IdentityMaster;
factory IdentityMaster.fromJson(dynamic json) =>
_$IdentityMasterFromJson(json as Map<String, dynamic>);
}
extension IdentityMasterExtension on IdentityMaster {
/// Deletes a master identity and the identity record under it
Future<void> delete() async {
final pool = await DHTRecordPool.instance();
await (await pool.openRead(masterRecordKey)).delete();
}
KeyPair identityWriter(SecretKey secret) =>
KeyPair(key: identityPublicKey, secret: secret);
KeyPair masterWriter(SecretKey secret) =>
KeyPair(key: masterPublicKey, secret: secret);
TypedKey identityPublicTypedKey() =>
TypedKey(kind: identityRecordKey.kind, value: identityPublicKey);
Future<AccountRecordInfo> readAccountFromIdentity(
{required SharedSecret identitySecret,
required String accountKey}) async {
// Read the identity key to get the account keys
final pool = await DHTRecordPool.instance();
final identityRecordCrypto = await DHTRecordCryptoPrivate.fromSecret(
identityRecordKey.kind, identitySecret);
late final AccountRecordInfo accountRecordInfo;
await (await pool.openRead(identityRecordKey,
parent: masterRecordKey, crypto: identityRecordCrypto))
.scope((identityRec) async {
final identity = await identityRec.getJson(Identity.fromJson);
if (identity == null) {
// Identity could not be read or decrypted from DHT
throw StateError('identity could not be read');
}
final accountRecords = IMapOfSets.from(identity.accountRecords);
final vcAccounts = accountRecords.get(accountKey);
if (vcAccounts.length != 1) {
// No account, or multiple accounts somehow associated with identity
throw StateError('no single account record info');
}
accountRecordInfo = vcAccounts.first;
});
return accountRecordInfo;
}
/// Creates a new Account associated with master identity and store it in the
/// identity key.
Future<AccountRecordInfo> addAccountToIdentity<T extends GeneratedMessage>({
required SharedSecret identitySecret,
required String accountKey,
required Future<T> Function(TypedKey parent) createAccountCallback,
}) async {
final pool = await DHTRecordPool.instance();
/////// Add account with profile to DHT
// Open identity key for writing
return (await pool.openWrite(
identityRecordKey, identityWriter(identitySecret),
parent: masterRecordKey))
.scope((identityRec) async =>
// Create new account to insert into identity
(await pool.create(parent: identityRec.key))
.deleteScope((accountRec) async {
final account = await createAccountCallback(accountRec.key);
// Write account key
await accountRec.eventualWriteProtobuf(account);
// Update identity key to include account
final newAccountRecordInfo = AccountRecordInfo(
accountRecord: OwnedDHTRecordPointer(
recordKey: accountRec.key,
owner: accountRec.ownerKeyPair!));
await identityRec.eventualUpdateJson(Identity.fromJson,
(oldIdentity) async {
final oldAccountRecords =
IMapOfSets.from(oldIdentity.accountRecords);
// Only allow one account per identity for veilidchat
if (oldAccountRecords.get(accountKey).isNotEmpty) {
throw StateError('Only one account per key in identity');
}
final accountRecords = oldAccountRecords
.add(accountKey, newAccountRecordInfo)
.asIMap();
return oldIdentity.copyWith(accountRecords: accountRecords);
});
return newAccountRecordInfo;
}));
}
}
// Identity Master with secrets
// Not freezed because we never persist this class in its entirety
class IdentityMasterWithSecrets {
IdentityMasterWithSecrets._(
{required this.identityMaster,
required this.masterSecret,
required this.identitySecret});
IdentityMaster identityMaster;
SecretKey masterSecret;
SecretKey identitySecret;
/// Delete a master identity with secrets
Future<void> delete() async => identityMaster.delete();
/// Creates a new master identity and returns it with its secrets
static Future<IdentityMasterWithSecrets> create() async {
final pool = await DHTRecordPool.instance();
// IdentityMaster DHT record is public/unencrypted
return (await pool.create(crypto: const DHTRecordCryptoPublic()))
.deleteScope((masterRec) async =>
// Identity record is private
(await pool.create(parent: masterRec.key))
.scope((identityRec) async {
// Make IdentityMaster
final masterRecordKey = masterRec.key;
final masterOwner = masterRec.ownerKeyPair!;
final masterSigBuf = BytesBuilder()
..add(masterRecordKey.decode())
..add(masterOwner.key.decode());
final identityRecordKey = identityRec.key;
final identityOwner = identityRec.ownerKeyPair!;
final identitySigBuf = BytesBuilder()
..add(identityRecordKey.decode())
..add(identityOwner.key.decode());
assert(masterRecordKey.kind == identityRecordKey.kind,
'new master and identity should have same cryptosystem');
final crypto =
await pool.veilid.getCryptoSystem(masterRecordKey.kind);
final identitySignature = await crypto.signWithKeyPair(
masterOwner, identitySigBuf.toBytes());
final masterSignature = await crypto.signWithKeyPair(
identityOwner, masterSigBuf.toBytes());
final identityMaster = IdentityMaster(
identityRecordKey: identityRecordKey,
identityPublicKey: identityOwner.key,
masterRecordKey: masterRecordKey,
masterPublicKey: masterOwner.key,
identitySignature: identitySignature,
masterSignature: masterSignature);
// Write identity master to master dht key
await masterRec.eventualWriteJson(identityMaster);
// Make empty identity
const identity = Identity(accountRecords: IMapConst({}));
// Write empty identity to identity dht key
await identityRec.eventualWriteJson(identity);
return IdentityMasterWithSecrets._(
identityMaster: identityMaster,
masterSecret: masterOwner.secret,
identitySecret: identityOwner.secret);
}));
}
}
/// Opens an existing master identity and validates it
Future<IdentityMaster> openIdentityMaster(
{required TypedKey identityMasterRecordKey}) async {
final pool = await DHTRecordPool.instance();
// IdentityMaster DHT record is public/unencrypted
return (await pool.openRead(identityMasterRecordKey))
.deleteScope((masterRec) async {
final identityMaster =
(await masterRec.getJson(IdentityMaster.fromJson, forceRefresh: true))!;
// Validate IdentityMaster
final masterRecordKey = masterRec.key;
final masterOwnerKey = masterRec.owner;
final masterSigBuf = BytesBuilder()
..add(masterRecordKey.decode())
..add(masterOwnerKey.decode());
final masterSignature = identityMaster.masterSignature;
final identityRecordKey = identityMaster.identityRecordKey;
final identityOwnerKey = identityMaster.identityPublicKey;
final identitySigBuf = BytesBuilder()
..add(identityRecordKey.decode())
..add(identityOwnerKey.decode());
final identitySignature = identityMaster.identitySignature;
assert(masterRecordKey.kind == identityRecordKey.kind,
'new master and identity should have same cryptosystem');
final crypto = await pool.veilid.getCryptoSystem(masterRecordKey.kind);
await crypto.verify(
masterOwnerKey, identitySigBuf.toBytes(), identitySignature);
await crypto.verify(
identityOwnerKey, masterSigBuf.toBytes(), masterSignature);
return identityMaster;
});
}

View File

@ -1,11 +1,9 @@
import 'package:veilid/veilid.dart';
import 'veilid_init.dart';
Future<T> tableScope<T>(
String name, Future<T> Function(VeilidTableDB tdb) callback,
{int columnCount = 1}) async {
final veilid = await eventualVeilid.future;
final tableDB = await veilid.openTableDB(name, columnCount);
final tableDB = await Veilid.instance.openTableDB(name, columnCount);
try {
return await callback(tableDB);
} finally {

View File

@ -2,7 +2,13 @@ import 'package:flutter/foundation.dart';
import 'package:loggy/loggy.dart';
import 'package:veilid/veilid.dart';
import '../log/loggy.dart';
// Loggy tools
const LogLevel traceLevel = LogLevel('Trace', 1);
extension TraceLoggy on Loggy {
void trace(dynamic message, [Object? error, StackTrace? stackTrace]) =>
log(traceLevel, message, error, stackTrace);
}
VeilidConfigLogLevel convertToVeilidConfigLogLevel(LogLevel? level) {
if (level == null) {

View File

@ -1,9 +1,14 @@
/// Dart Veilid Support Library
/// Common functionality for interfacing with Veilid
library veilid_support;
export 'package:veilid/veilid.dart';
export 'config.dart';
export 'dht_support/dht_support.dart';
export 'identity_master.dart';
export 'processor.dart';
export 'table_db.dart';
export 'veilid_init.dart';
export 'veilid_log.dart';
export 'src/config.dart';
export 'src/identity.dart';
export 'src/json_tools.dart';
export 'src/protobuf_tools.dart';
export 'src/table_db.dart';
export 'src/veilid_log.dart';