mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-05-02 14:26:12 -04:00
dht work
This commit is contained in:
parent
57c366ef91
commit
c35056f687
39 changed files with 1382 additions and 662 deletions
|
@ -1,18 +1,21 @@
|
|||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:veilid/veilid.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 TypedKey key,
|
||||
required KeyPair owner,
|
||||
required OwnedDHTRecordPointer accountRecord,
|
||||
}) = _AccountRecordInfo;
|
||||
|
||||
factory AccountRecordInfo.fromJson(dynamic json) =>
|
||||
|
@ -77,4 +80,89 @@ extension IdentityMasterExtension on IdentityMaster {
|
|||
|
||||
KeyPair masterWriter(SecretKey secret) =>
|
||||
KeyPair(key: masterPublicKey, secret: secret);
|
||||
|
||||
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 request list
|
||||
final contactRequests = await (await DHTShortArray.create())
|
||||
.scope((r) => r.record.ownedDHTRecordPointer);
|
||||
|
||||
// Make account object
|
||||
final account = proto.Account()
|
||||
..profile = (proto.Profile()
|
||||
..name = name
|
||||
..title = title)
|
||||
..contactRequests = contactRequests.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);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@ AccountRecordInfo _$AccountRecordInfoFromJson(Map<String, dynamic> json) {
|
|||
/// @nodoc
|
||||
mixin _$AccountRecordInfo {
|
||||
// Top level account keys and secrets
|
||||
Typed<FixedEncodedString43> get key => throw _privateConstructorUsedError;
|
||||
KeyPair get owner => throw _privateConstructorUsedError;
|
||||
OwnedDHTRecordPointer get accountRecord => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
|
@ -36,7 +35,9 @@ abstract class $AccountRecordInfoCopyWith<$Res> {
|
|||
AccountRecordInfo value, $Res Function(AccountRecordInfo) then) =
|
||||
_$AccountRecordInfoCopyWithImpl<$Res, AccountRecordInfo>;
|
||||
@useResult
|
||||
$Res call({Typed<FixedEncodedString43> key, KeyPair owner});
|
||||
$Res call({OwnedDHTRecordPointer accountRecord});
|
||||
|
||||
$OwnedDHTRecordPointerCopyWith<$Res> get accountRecord;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -52,20 +53,23 @@ class _$AccountRecordInfoCopyWithImpl<$Res, $Val extends AccountRecordInfo>
|
|||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? key = null,
|
||||
Object? owner = null,
|
||||
Object? accountRecord = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
key: null == key
|
||||
? _value.key
|
||||
: key // ignore: cast_nullable_to_non_nullable
|
||||
as Typed<FixedEncodedString43>,
|
||||
owner: null == owner
|
||||
? _value.owner
|
||||
: owner // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair,
|
||||
accountRecord: null == accountRecord
|
||||
? _value.accountRecord
|
||||
: accountRecord // ignore: cast_nullable_to_non_nullable
|
||||
as OwnedDHTRecordPointer,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$OwnedDHTRecordPointerCopyWith<$Res> get accountRecord {
|
||||
return $OwnedDHTRecordPointerCopyWith<$Res>(_value.accountRecord, (value) {
|
||||
return _then(_value.copyWith(accountRecord: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -76,7 +80,10 @@ abstract class _$$_AccountRecordInfoCopyWith<$Res>
|
|||
__$$_AccountRecordInfoCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({Typed<FixedEncodedString43> key, KeyPair owner});
|
||||
$Res call({OwnedDHTRecordPointer accountRecord});
|
||||
|
||||
@override
|
||||
$OwnedDHTRecordPointerCopyWith<$Res> get accountRecord;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -90,18 +97,13 @@ class __$$_AccountRecordInfoCopyWithImpl<$Res>
|
|||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? key = null,
|
||||
Object? owner = null,
|
||||
Object? accountRecord = null,
|
||||
}) {
|
||||
return _then(_$_AccountRecordInfo(
|
||||
key: null == key
|
||||
? _value.key
|
||||
: key // ignore: cast_nullable_to_non_nullable
|
||||
as Typed<FixedEncodedString43>,
|
||||
owner: null == owner
|
||||
? _value.owner
|
||||
: owner // ignore: cast_nullable_to_non_nullable
|
||||
as KeyPair,
|
||||
accountRecord: null == accountRecord
|
||||
? _value.accountRecord
|
||||
: accountRecord // ignore: cast_nullable_to_non_nullable
|
||||
as OwnedDHTRecordPointer,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -109,20 +111,18 @@ class __$$_AccountRecordInfoCopyWithImpl<$Res>
|
|||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$_AccountRecordInfo implements _AccountRecordInfo {
|
||||
const _$_AccountRecordInfo({required this.key, required this.owner});
|
||||
const _$_AccountRecordInfo({required this.accountRecord});
|
||||
|
||||
factory _$_AccountRecordInfo.fromJson(Map<String, dynamic> json) =>
|
||||
_$$_AccountRecordInfoFromJson(json);
|
||||
|
||||
// Top level account keys and secrets
|
||||
@override
|
||||
final Typed<FixedEncodedString43> key;
|
||||
@override
|
||||
final KeyPair owner;
|
||||
final OwnedDHTRecordPointer accountRecord;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AccountRecordInfo(key: $key, owner: $owner)';
|
||||
return 'AccountRecordInfo(accountRecord: $accountRecord)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -130,13 +130,13 @@ class _$_AccountRecordInfo implements _AccountRecordInfo {
|
|||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$_AccountRecordInfo &&
|
||||
(identical(other.key, key) || other.key == key) &&
|
||||
(identical(other.owner, owner) || other.owner == owner));
|
||||
(identical(other.accountRecord, accountRecord) ||
|
||||
other.accountRecord == accountRecord));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, key, owner);
|
||||
int get hashCode => Object.hash(runtimeType, accountRecord);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
|
@ -155,16 +155,14 @@ class _$_AccountRecordInfo implements _AccountRecordInfo {
|
|||
|
||||
abstract class _AccountRecordInfo implements AccountRecordInfo {
|
||||
const factory _AccountRecordInfo(
|
||||
{required final Typed<FixedEncodedString43> key,
|
||||
required final KeyPair owner}) = _$_AccountRecordInfo;
|
||||
{required final OwnedDHTRecordPointer accountRecord}) =
|
||||
_$_AccountRecordInfo;
|
||||
|
||||
factory _AccountRecordInfo.fromJson(Map<String, dynamic> json) =
|
||||
_$_AccountRecordInfo.fromJson;
|
||||
|
||||
@override // Top level account keys and secrets
|
||||
Typed<FixedEncodedString43> get key;
|
||||
@override
|
||||
KeyPair get owner;
|
||||
OwnedDHTRecordPointer get accountRecord;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$_AccountRecordInfoCopyWith<_$_AccountRecordInfo> get copyWith =>
|
||||
|
|
|
@ -8,15 +8,13 @@ part of 'identity.dart';
|
|||
|
||||
_$_AccountRecordInfo _$$_AccountRecordInfoFromJson(Map<String, dynamic> json) =>
|
||||
_$_AccountRecordInfo(
|
||||
key: Typed<FixedEncodedString43>.fromJson(json['key']),
|
||||
owner: KeyPair.fromJson(json['owner']),
|
||||
accountRecord: OwnedDHTRecordPointer.fromJson(json['account_record']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$_AccountRecordInfoToJson(
|
||||
_$_AccountRecordInfo instance) =>
|
||||
<String, dynamic>{
|
||||
'key': instance.key.toJson(),
|
||||
'owner': instance.owner.toJson(),
|
||||
'account_record': instance.accountRecord.toJson(),
|
||||
};
|
||||
|
||||
_$_Identity _$$_IdentityFromJson(Map<String, dynamic> json) => _$_Identity(
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:typed_data';
|
|||
import 'package:change_case/change_case.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'package:veilid/veilid.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'identity.dart';
|
||||
|
||||
part 'local_account.freezed.dart';
|
||||
|
@ -37,10 +37,9 @@ class LocalAccount with _$LocalAccount {
|
|||
const factory LocalAccount({
|
||||
// The master key record for the account, containing the identityPublicKey
|
||||
required IdentityMaster identityMaster,
|
||||
// The encrypted identity secret that goes with the identityPublicKey
|
||||
@Uint8ListJsonConverter() required Uint8List identitySecretKeyBytes,
|
||||
// The salt for the identity secret key encryption
|
||||
@Uint8ListJsonConverter() required Uint8List identitySecretSaltBytes,
|
||||
// The encrypted identity secret that goes with
|
||||
// the identityPublicKey with appended salt
|
||||
@Uint8ListJsonConverter() required Uint8List identitySecretBytes,
|
||||
// The kind of encryption input used on the account
|
||||
required EncryptionKeyType encryptionKeyType,
|
||||
// If account is not hidden, password can be retrieved via
|
||||
|
|
|
@ -22,12 +22,10 @@ LocalAccount _$LocalAccountFromJson(Map<String, dynamic> json) {
|
|||
mixin _$LocalAccount {
|
||||
// The master key record for the account, containing the identityPublicKey
|
||||
IdentityMaster get identityMaster =>
|
||||
throw _privateConstructorUsedError; // The encrypted identity secret that goes with the identityPublicKey
|
||||
throw _privateConstructorUsedError; // The encrypted identity secret that goes with
|
||||
// the identityPublicKey with appended salt
|
||||
@Uint8ListJsonConverter()
|
||||
Uint8List get identitySecretKeyBytes =>
|
||||
throw _privateConstructorUsedError; // The salt for the identity secret key encryption
|
||||
@Uint8ListJsonConverter()
|
||||
Uint8List get identitySecretSaltBytes =>
|
||||
Uint8List get identitySecretBytes =>
|
||||
throw _privateConstructorUsedError; // The kind of encryption input used on the account
|
||||
EncryptionKeyType get encryptionKeyType =>
|
||||
throw _privateConstructorUsedError; // If account is not hidden, password can be retrieved via
|
||||
|
@ -52,8 +50,7 @@ abstract class $LocalAccountCopyWith<$Res> {
|
|||
@useResult
|
||||
$Res call(
|
||||
{IdentityMaster identityMaster,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretSaltBytes,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretBytes,
|
||||
EncryptionKeyType encryptionKeyType,
|
||||
bool biometricsEnabled,
|
||||
bool hiddenAccount,
|
||||
|
@ -76,8 +73,7 @@ class _$LocalAccountCopyWithImpl<$Res, $Val extends LocalAccount>
|
|||
@override
|
||||
$Res call({
|
||||
Object? identityMaster = null,
|
||||
Object? identitySecretKeyBytes = null,
|
||||
Object? identitySecretSaltBytes = null,
|
||||
Object? identitySecretBytes = null,
|
||||
Object? encryptionKeyType = null,
|
||||
Object? biometricsEnabled = null,
|
||||
Object? hiddenAccount = null,
|
||||
|
@ -88,13 +84,9 @@ class _$LocalAccountCopyWithImpl<$Res, $Val extends LocalAccount>
|
|||
? _value.identityMaster
|
||||
: identityMaster // ignore: cast_nullable_to_non_nullable
|
||||
as IdentityMaster,
|
||||
identitySecretKeyBytes: null == identitySecretKeyBytes
|
||||
? _value.identitySecretKeyBytes
|
||||
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
||||
as Uint8List,
|
||||
identitySecretSaltBytes: null == identitySecretSaltBytes
|
||||
? _value.identitySecretSaltBytes
|
||||
: identitySecretSaltBytes // ignore: cast_nullable_to_non_nullable
|
||||
identitySecretBytes: null == identitySecretBytes
|
||||
? _value.identitySecretBytes
|
||||
: identitySecretBytes // ignore: cast_nullable_to_non_nullable
|
||||
as Uint8List,
|
||||
encryptionKeyType: null == encryptionKeyType
|
||||
? _value.encryptionKeyType
|
||||
|
@ -134,8 +126,7 @@ abstract class _$$_LocalAccountCopyWith<$Res>
|
|||
@useResult
|
||||
$Res call(
|
||||
{IdentityMaster identityMaster,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretKeyBytes,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretSaltBytes,
|
||||
@Uint8ListJsonConverter() Uint8List identitySecretBytes,
|
||||
EncryptionKeyType encryptionKeyType,
|
||||
bool biometricsEnabled,
|
||||
bool hiddenAccount,
|
||||
|
@ -157,8 +148,7 @@ class __$$_LocalAccountCopyWithImpl<$Res>
|
|||
@override
|
||||
$Res call({
|
||||
Object? identityMaster = null,
|
||||
Object? identitySecretKeyBytes = null,
|
||||
Object? identitySecretSaltBytes = null,
|
||||
Object? identitySecretBytes = null,
|
||||
Object? encryptionKeyType = null,
|
||||
Object? biometricsEnabled = null,
|
||||
Object? hiddenAccount = null,
|
||||
|
@ -169,13 +159,9 @@ class __$$_LocalAccountCopyWithImpl<$Res>
|
|||
? _value.identityMaster
|
||||
: identityMaster // ignore: cast_nullable_to_non_nullable
|
||||
as IdentityMaster,
|
||||
identitySecretKeyBytes: null == identitySecretKeyBytes
|
||||
? _value.identitySecretKeyBytes
|
||||
: identitySecretKeyBytes // ignore: cast_nullable_to_non_nullable
|
||||
as Uint8List,
|
||||
identitySecretSaltBytes: null == identitySecretSaltBytes
|
||||
? _value.identitySecretSaltBytes
|
||||
: identitySecretSaltBytes // ignore: cast_nullable_to_non_nullable
|
||||
identitySecretBytes: null == identitySecretBytes
|
||||
? _value.identitySecretBytes
|
||||
: identitySecretBytes // ignore: cast_nullable_to_non_nullable
|
||||
as Uint8List,
|
||||
encryptionKeyType: null == encryptionKeyType
|
||||
? _value.encryptionKeyType
|
||||
|
@ -202,8 +188,7 @@ class __$$_LocalAccountCopyWithImpl<$Res>
|
|||
class _$_LocalAccount implements _LocalAccount {
|
||||
const _$_LocalAccount(
|
||||
{required this.identityMaster,
|
||||
@Uint8ListJsonConverter() required this.identitySecretKeyBytes,
|
||||
@Uint8ListJsonConverter() required this.identitySecretSaltBytes,
|
||||
@Uint8ListJsonConverter() required this.identitySecretBytes,
|
||||
required this.encryptionKeyType,
|
||||
required this.biometricsEnabled,
|
||||
required this.hiddenAccount,
|
||||
|
@ -215,14 +200,11 @@ class _$_LocalAccount implements _LocalAccount {
|
|||
// The master key record for the account, containing the identityPublicKey
|
||||
@override
|
||||
final IdentityMaster identityMaster;
|
||||
// The encrypted identity secret that goes with the identityPublicKey
|
||||
// The encrypted identity secret that goes with
|
||||
// the identityPublicKey with appended salt
|
||||
@override
|
||||
@Uint8ListJsonConverter()
|
||||
final Uint8List identitySecretKeyBytes;
|
||||
// The salt for the identity secret key encryption
|
||||
@override
|
||||
@Uint8ListJsonConverter()
|
||||
final Uint8List identitySecretSaltBytes;
|
||||
final Uint8List identitySecretBytes;
|
||||
// The kind of encryption input used on the account
|
||||
@override
|
||||
final EncryptionKeyType encryptionKeyType;
|
||||
|
@ -239,7 +221,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LocalAccount(identityMaster: $identityMaster, identitySecretKeyBytes: $identitySecretKeyBytes, identitySecretSaltBytes: $identitySecretSaltBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount, name: $name)';
|
||||
return 'LocalAccount(identityMaster: $identityMaster, identitySecretBytes: $identitySecretBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount, name: $name)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -250,9 +232,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||
(identical(other.identityMaster, identityMaster) ||
|
||||
other.identityMaster == identityMaster) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.identitySecretKeyBytes, identitySecretKeyBytes) &&
|
||||
const DeepCollectionEquality().equals(
|
||||
other.identitySecretSaltBytes, identitySecretSaltBytes) &&
|
||||
.equals(other.identitySecretBytes, identitySecretBytes) &&
|
||||
(identical(other.encryptionKeyType, encryptionKeyType) ||
|
||||
other.encryptionKeyType == encryptionKeyType) &&
|
||||
(identical(other.biometricsEnabled, biometricsEnabled) ||
|
||||
|
@ -267,8 +247,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
identityMaster,
|
||||
const DeepCollectionEquality().hash(identitySecretKeyBytes),
|
||||
const DeepCollectionEquality().hash(identitySecretSaltBytes),
|
||||
const DeepCollectionEquality().hash(identitySecretBytes),
|
||||
encryptionKeyType,
|
||||
biometricsEnabled,
|
||||
hiddenAccount,
|
||||
|
@ -291,9 +270,7 @@ class _$_LocalAccount implements _LocalAccount {
|
|||
abstract class _LocalAccount implements LocalAccount {
|
||||
const factory _LocalAccount(
|
||||
{required final IdentityMaster identityMaster,
|
||||
@Uint8ListJsonConverter() required final Uint8List identitySecretKeyBytes,
|
||||
@Uint8ListJsonConverter()
|
||||
required final Uint8List identitySecretSaltBytes,
|
||||
@Uint8ListJsonConverter() required final Uint8List identitySecretBytes,
|
||||
required final EncryptionKeyType encryptionKeyType,
|
||||
required final bool biometricsEnabled,
|
||||
required final bool hiddenAccount,
|
||||
|
@ -304,12 +281,10 @@ abstract class _LocalAccount implements LocalAccount {
|
|||
|
||||
@override // The master key record for the account, containing the identityPublicKey
|
||||
IdentityMaster get identityMaster;
|
||||
@override // The encrypted identity secret that goes with the identityPublicKey
|
||||
@override // The encrypted identity secret that goes with
|
||||
// the identityPublicKey with appended salt
|
||||
@Uint8ListJsonConverter()
|
||||
Uint8List get identitySecretKeyBytes;
|
||||
@override // The salt for the identity secret key encryption
|
||||
@Uint8ListJsonConverter()
|
||||
Uint8List get identitySecretSaltBytes;
|
||||
Uint8List get identitySecretBytes;
|
||||
@override // The kind of encryption input used on the account
|
||||
EncryptionKeyType get encryptionKeyType;
|
||||
@override // If account is not hidden, password can be retrieved via
|
||||
|
|
|
@ -9,10 +9,8 @@ part of 'local_account.dart';
|
|||
_$_LocalAccount _$$_LocalAccountFromJson(Map<String, dynamic> json) =>
|
||||
_$_LocalAccount(
|
||||
identityMaster: IdentityMaster.fromJson(json['identity_master']),
|
||||
identitySecretKeyBytes: const Uint8ListJsonConverter()
|
||||
.fromJson(json['identity_secret_key_bytes'] as String),
|
||||
identitySecretSaltBytes: const Uint8ListJsonConverter()
|
||||
.fromJson(json['identity_secret_salt_bytes'] as String),
|
||||
identitySecretBytes: const Uint8ListJsonConverter()
|
||||
.fromJson(json['identity_secret_bytes'] as String),
|
||||
encryptionKeyType:
|
||||
EncryptionKeyType.fromJson(json['encryption_key_type']),
|
||||
biometricsEnabled: json['biometrics_enabled'] as bool,
|
||||
|
@ -23,10 +21,8 @@ _$_LocalAccount _$$_LocalAccountFromJson(Map<String, dynamic> json) =>
|
|||
Map<String, dynamic> _$$_LocalAccountToJson(_$_LocalAccount instance) =>
|
||||
<String, dynamic>{
|
||||
'identity_master': instance.identityMaster.toJson(),
|
||||
'identity_secret_key_bytes': const Uint8ListJsonConverter()
|
||||
.toJson(instance.identitySecretKeyBytes),
|
||||
'identity_secret_salt_bytes': const Uint8ListJsonConverter()
|
||||
.toJson(instance.identitySecretSaltBytes),
|
||||
'identity_secret_bytes':
|
||||
const Uint8ListJsonConverter().toJson(instance.identitySecretBytes),
|
||||
'encryption_key_type': instance.encryptionKeyType.toJson(),
|
||||
'biometrics_enabled': instance.biometricsEnabled,
|
||||
'hidden_account': instance.hiddenAccount,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:veilid/veilid.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
|
||||
import 'proto/veilidchat.pb.dart' as proto;
|
||||
|
||||
|
@ -124,3 +124,34 @@ extension TypedKeyProto on TypedKey {
|
|||
static TypedKey fromProto(proto.TypedKey p) =>
|
||||
TypedKey(kind: p.kind, value: CryptoKeyProto.fromProto(p.value));
|
||||
}
|
||||
|
||||
/// KeyPair protobuf marshaling
|
||||
///
|
||||
extension KeyPairProto on KeyPair {
|
||||
proto.KeyPair toProto() {
|
||||
final out = proto.KeyPair()
|
||||
..key = key.toProto()
|
||||
..secret = secret.toProto();
|
||||
return out;
|
||||
}
|
||||
|
||||
static KeyPair fromProto(proto.KeyPair p) => 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));
|
||||
}
|
||||
|
|
|
@ -468,6 +468,62 @@ class TypedKey extends $pb.GeneratedMessage {
|
|||
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', 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);
|
||||
}
|
||||
|
||||
class DHTData extends $pb.GeneratedMessage {
|
||||
factory DHTData() => create();
|
||||
DHTData._() : super();
|
||||
|
@ -1125,8 +1181,7 @@ class OwnedDHTRecordPointer extends $pb.GeneratedMessage {
|
|||
|
||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'OwnedDHTRecordPointer', createEmptyInstance: create)
|
||||
..aOM<TypedKey>(1, _omitFieldNames ? '' : 'recordKey', subBuilder: TypedKey.create)
|
||||
..aOM<CryptoKey>(2, _omitFieldNames ? '' : 'ownerKey', subBuilder: CryptoKey.create)
|
||||
..aOM<CryptoKey>(3, _omitFieldNames ? '' : 'ownerSecret', subBuilder: CryptoKey.create)
|
||||
..aOM<KeyPair>(2, _omitFieldNames ? '' : 'owner', subBuilder: KeyPair.create)
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
|
@ -1163,26 +1218,15 @@ class OwnedDHTRecordPointer extends $pb.GeneratedMessage {
|
|||
TypedKey ensureRecordKey() => $_ensure(0);
|
||||
|
||||
@$pb.TagNumber(2)
|
||||
CryptoKey get ownerKey => $_getN(1);
|
||||
KeyPair get owner => $_getN(1);
|
||||
@$pb.TagNumber(2)
|
||||
set ownerKey(CryptoKey v) { setField(2, v); }
|
||||
set owner(KeyPair v) { setField(2, v); }
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasOwnerKey() => $_has(1);
|
||||
$core.bool hasOwner() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearOwnerKey() => clearField(2);
|
||||
void clearOwner() => clearField(2);
|
||||
@$pb.TagNumber(2)
|
||||
CryptoKey ensureOwnerKey() => $_ensure(1);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
CryptoKey get ownerSecret => $_getN(2);
|
||||
@$pb.TagNumber(3)
|
||||
set ownerSecret(CryptoKey v) { setField(3, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasOwnerSecret() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearOwnerSecret() => clearField(3);
|
||||
@$pb.TagNumber(3)
|
||||
CryptoKey ensureOwnerSecret() => $_ensure(2);
|
||||
KeyPair ensureOwner() => $_ensure(1);
|
||||
}
|
||||
|
||||
class Account extends $pb.GeneratedMessage {
|
||||
|
|
|
@ -146,6 +146,20 @@ 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',
|
||||
|
@ -313,16 +327,14 @@ const OwnedDHTRecordPointer$json = {
|
|||
'1': 'OwnedDHTRecordPointer',
|
||||
'2': [
|
||||
{'1': 'record_key', '3': 1, '4': 1, '5': 11, '6': '.TypedKey', '10': 'recordKey'},
|
||||
{'1': 'owner_key', '3': 2, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'ownerKey'},
|
||||
{'1': 'owner_secret', '3': 3, '4': 1, '5': 11, '6': '.CryptoKey', '10': 'ownerSecret'},
|
||||
{'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'
|
||||
'lyZWNvcmRLZXkSJwoJb3duZXJfa2V5GAIgASgLMgouQ3J5cHRvS2V5Ughvd25lcktleRItCgxv'
|
||||
'd25lcl9zZWNyZXQYAyABKAsyCi5DcnlwdG9LZXlSC293bmVyU2VjcmV0');
|
||||
'lyZWNvcmRLZXkSHgoFb3duZXIYAiABKAsyCC5LZXlQYWlyUgVvd25lcg==');
|
||||
|
||||
@$core.Deprecated('Use accountDescriptor instead')
|
||||
const Account$json = {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'identity.dart';
|
||||
|
||||
part 'user_login.freezed.dart';
|
||||
part 'user_login.g.dart';
|
||||
|
@ -15,6 +17,9 @@ class UserLogin with _$UserLogin {
|
|||
required TypedKey accountMasterRecordKey,
|
||||
// The identity secret as unlocked from the local accounts table
|
||||
required TypedSecret identitySecret,
|
||||
// The account record key, owner key and secret pulled from the identity
|
||||
required AccountRecordInfo accountRecordInfo,
|
||||
|
||||
// The time this login was most recently used
|
||||
required Timestamp lastActive,
|
||||
}) = _UserLogin;
|
||||
|
|
|
@ -24,6 +24,8 @@ mixin _$UserLogin {
|
|||
Typed<FixedEncodedString43> get accountMasterRecordKey =>
|
||||
throw _privateConstructorUsedError; // The identity secret as unlocked from the local accounts table
|
||||
Typed<FixedEncodedString43> get identitySecret =>
|
||||
throw _privateConstructorUsedError; // The account record key, owner key and secret pulled from the identity
|
||||
AccountRecordInfo get accountRecordInfo =>
|
||||
throw _privateConstructorUsedError; // The time this login was most recently used
|
||||
Timestamp get lastActive => throw _privateConstructorUsedError;
|
||||
|
||||
|
@ -41,7 +43,10 @@ abstract class $UserLoginCopyWith<$Res> {
|
|||
$Res call(
|
||||
{Typed<FixedEncodedString43> accountMasterRecordKey,
|
||||
Typed<FixedEncodedString43> identitySecret,
|
||||
AccountRecordInfo accountRecordInfo,
|
||||
Timestamp lastActive});
|
||||
|
||||
$AccountRecordInfoCopyWith<$Res> get accountRecordInfo;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -59,6 +64,7 @@ class _$UserLoginCopyWithImpl<$Res, $Val extends UserLogin>
|
|||
$Res call({
|
||||
Object? accountMasterRecordKey = null,
|
||||
Object? identitySecret = null,
|
||||
Object? accountRecordInfo = null,
|
||||
Object? lastActive = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
|
@ -70,12 +76,24 @@ class _$UserLoginCopyWithImpl<$Res, $Val extends UserLogin>
|
|||
? _value.identitySecret
|
||||
: identitySecret // ignore: cast_nullable_to_non_nullable
|
||||
as Typed<FixedEncodedString43>,
|
||||
accountRecordInfo: null == accountRecordInfo
|
||||
? _value.accountRecordInfo
|
||||
: accountRecordInfo // ignore: cast_nullable_to_non_nullable
|
||||
as AccountRecordInfo,
|
||||
lastActive: null == lastActive
|
||||
? _value.lastActive
|
||||
: lastActive // ignore: cast_nullable_to_non_nullable
|
||||
as Timestamp,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$AccountRecordInfoCopyWith<$Res> get accountRecordInfo {
|
||||
return $AccountRecordInfoCopyWith<$Res>(_value.accountRecordInfo, (value) {
|
||||
return _then(_value.copyWith(accountRecordInfo: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -88,7 +106,11 @@ abstract class _$$_UserLoginCopyWith<$Res> implements $UserLoginCopyWith<$Res> {
|
|||
$Res call(
|
||||
{Typed<FixedEncodedString43> accountMasterRecordKey,
|
||||
Typed<FixedEncodedString43> identitySecret,
|
||||
AccountRecordInfo accountRecordInfo,
|
||||
Timestamp lastActive});
|
||||
|
||||
@override
|
||||
$AccountRecordInfoCopyWith<$Res> get accountRecordInfo;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
@ -104,6 +126,7 @@ class __$$_UserLoginCopyWithImpl<$Res>
|
|||
$Res call({
|
||||
Object? accountMasterRecordKey = null,
|
||||
Object? identitySecret = null,
|
||||
Object? accountRecordInfo = null,
|
||||
Object? lastActive = null,
|
||||
}) {
|
||||
return _then(_$_UserLogin(
|
||||
|
@ -115,6 +138,10 @@ class __$$_UserLoginCopyWithImpl<$Res>
|
|||
? _value.identitySecret
|
||||
: identitySecret // ignore: cast_nullable_to_non_nullable
|
||||
as Typed<FixedEncodedString43>,
|
||||
accountRecordInfo: null == accountRecordInfo
|
||||
? _value.accountRecordInfo
|
||||
: accountRecordInfo // ignore: cast_nullable_to_non_nullable
|
||||
as AccountRecordInfo,
|
||||
lastActive: null == lastActive
|
||||
? _value.lastActive
|
||||
: lastActive // ignore: cast_nullable_to_non_nullable
|
||||
|
@ -129,6 +156,7 @@ class _$_UserLogin implements _UserLogin {
|
|||
const _$_UserLogin(
|
||||
{required this.accountMasterRecordKey,
|
||||
required this.identitySecret,
|
||||
required this.accountRecordInfo,
|
||||
required this.lastActive});
|
||||
|
||||
factory _$_UserLogin.fromJson(Map<String, dynamic> json) =>
|
||||
|
@ -140,13 +168,16 @@ class _$_UserLogin implements _UserLogin {
|
|||
// The identity secret as unlocked from the local accounts table
|
||||
@override
|
||||
final Typed<FixedEncodedString43> identitySecret;
|
||||
// The account record key, owner key and secret pulled from the identity
|
||||
@override
|
||||
final AccountRecordInfo accountRecordInfo;
|
||||
// The time this login was most recently used
|
||||
@override
|
||||
final Timestamp lastActive;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'UserLogin(accountMasterRecordKey: $accountMasterRecordKey, identitySecret: $identitySecret, lastActive: $lastActive)';
|
||||
return 'UserLogin(accountMasterRecordKey: $accountMasterRecordKey, identitySecret: $identitySecret, accountRecordInfo: $accountRecordInfo, lastActive: $lastActive)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -158,14 +189,16 @@ class _$_UserLogin implements _UserLogin {
|
|||
other.accountMasterRecordKey == accountMasterRecordKey) &&
|
||||
(identical(other.identitySecret, identitySecret) ||
|
||||
other.identitySecret == identitySecret) &&
|
||||
(identical(other.accountRecordInfo, accountRecordInfo) ||
|
||||
other.accountRecordInfo == accountRecordInfo) &&
|
||||
(identical(other.lastActive, lastActive) ||
|
||||
other.lastActive == lastActive));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, accountMasterRecordKey, identitySecret, lastActive);
|
||||
int get hashCode => Object.hash(runtimeType, accountMasterRecordKey,
|
||||
identitySecret, accountRecordInfo, lastActive);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
|
@ -185,6 +218,7 @@ abstract class _UserLogin implements UserLogin {
|
|||
const factory _UserLogin(
|
||||
{required final Typed<FixedEncodedString43> accountMasterRecordKey,
|
||||
required final Typed<FixedEncodedString43> identitySecret,
|
||||
required final AccountRecordInfo accountRecordInfo,
|
||||
required final Timestamp lastActive}) = _$_UserLogin;
|
||||
|
||||
factory _UserLogin.fromJson(Map<String, dynamic> json) =
|
||||
|
@ -194,6 +228,8 @@ abstract class _UserLogin implements UserLogin {
|
|||
Typed<FixedEncodedString43> get accountMasterRecordKey;
|
||||
@override // The identity secret as unlocked from the local accounts table
|
||||
Typed<FixedEncodedString43> get identitySecret;
|
||||
@override // The account record key, owner key and secret pulled from the identity
|
||||
AccountRecordInfo get accountRecordInfo;
|
||||
@override // The time this login was most recently used
|
||||
Timestamp get lastActive;
|
||||
@override
|
||||
|
|
|
@ -11,6 +11,8 @@ _$_UserLogin _$$_UserLoginFromJson(Map<String, dynamic> json) => _$_UserLogin(
|
|||
json['account_master_record_key']),
|
||||
identitySecret:
|
||||
Typed<FixedEncodedString43>.fromJson(json['identity_secret']),
|
||||
accountRecordInfo:
|
||||
AccountRecordInfo.fromJson(json['account_record_info']),
|
||||
lastActive: Timestamp.fromJson(json['last_active']),
|
||||
);
|
||||
|
||||
|
@ -18,6 +20,7 @@ Map<String, dynamic> _$$_UserLoginToJson(_$_UserLogin instance) =>
|
|||
<String, dynamic>{
|
||||
'account_master_record_key': instance.accountMasterRecordKey.toJson(),
|
||||
'identity_secret': instance.identitySecret.toJson(),
|
||||
'account_record_info': instance.accountRecordInfo.toJson(),
|
||||
'last_active': instance.lastActive.toJson(),
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ message Nonce {
|
|||
fixed32 u5 = 6;
|
||||
}
|
||||
|
||||
// 36-byte typed crpyto key
|
||||
// 36-byte typed crypto key
|
||||
message TypedKey {
|
||||
// CryptoKind FourCC in bigendian format
|
||||
fixed32 kind = 1;
|
||||
|
@ -50,6 +50,15 @@ message TypedKey {
|
|||
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
|
||||
//
|
||||
|
@ -226,14 +235,12 @@ message Profile {
|
|||
optional TypedKey avatar = 5;
|
||||
}
|
||||
|
||||
// A pointer to an owned DHT record
|
||||
// A pointer to an child DHT record
|
||||
message OwnedDHTRecordPointer {
|
||||
// DHT Record key
|
||||
TypedKey record_key = 1;
|
||||
// DHT record owner key
|
||||
CryptoKey owner_key = 2;
|
||||
// DHT record owner secret
|
||||
CryptoKey owner_secret = 3;
|
||||
KeyPair owner = 2;
|
||||
}
|
||||
|
||||
// A record of an individual account
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue