lint work

This commit is contained in:
Christien Rioux 2023-07-26 14:20:17 -04:00
parent 91fab6ce5a
commit f91a350bfc
16 changed files with 791 additions and 1123 deletions

View File

@ -1,5 +1,4 @@
include: package:flutter_lints/flutter.yaml
include: package:lint_hard/all.yaml
analyzer:
errors:
invalid_annotation_target: ignore

View File

@ -3,3 +3,7 @@ include: package:flutter_lints/flutter.yaml
analyzer:
errors:
invalid_annotation_target: ignore
linter:
rules:
- unawaited_futures

View File

@ -1,10 +1,11 @@
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:system_info2/system_info2.dart' as sysinfo;
import 'package:system_info_plus/system_info_plus.dart';
import 'veilid.dart';
const int megaByte = 1024 * 1024;
@ -57,31 +58,29 @@ int getRemoteMaxStorageSpaceMb() {
return 256;
}
Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
return VeilidConfig(
Future<VeilidConfig> getDefaultVeilidConfig(String programName) async => VeilidConfig(
programName: programName,
namespace: "",
namespace: '',
capabilities: const VeilidConfigCapabilities(disable: []),
protectedStore: const VeilidConfigProtectedStore(
allowInsecureFallback: false,
alwaysUseInsecureStorage: false,
directory: "",
directory: '',
delete: false,
deviceEncryptionKeyPassword: "",
newDeviceEncryptionKeyPassword: null,
deviceEncryptionKeyPassword: '',
),
tableStore: VeilidConfigTableStore(
directory: kIsWeb
? ""
? ''
: p.join((await getApplicationSupportDirectory()).absolute.path,
"table_store"),
'table_store'),
delete: false,
),
blockStore: VeilidConfigBlockStore(
directory: kIsWeb
? ""
? ''
: p.join((await getApplicationSupportDirectory()).absolute.path,
"block_store"),
'block_store'),
delete: false,
),
network: VeilidConfigNetwork(
@ -98,8 +97,8 @@ Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
nodeId: [],
nodeIdSecret: [],
bootstrap: kIsWeb
? ["ws://bootstrap.veilid.net:5150/ws"]
: ["bootstrap.veilid.net"],
? ['ws://bootstrap.veilid.net:5150/ws']
: ['bootstrap.veilid.net'],
limitOverAttached: 64,
limitFullyAttached: 32,
limitAttachedStrong: 16,
@ -139,54 +138,47 @@ Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
detectAddressChanges: true,
restrictedNatRetries: 0,
tls: const VeilidConfigTLS(
certificatePath: "",
privateKeyPath: "",
certificatePath: '',
privateKeyPath: '',
connectionInitialTimeoutMs: 2000,
),
application: const VeilidConfigApplication(
https: VeilidConfigHTTPS(
enabled: false,
listenAddress: "",
path: "",
url: null,
listenAddress: '',
path: '',
),
http: VeilidConfigHTTP(
enabled: false,
listenAddress: "",
path: "",
url: null,
listenAddress: '',
path: '',
)),
protocol: const VeilidConfigProtocol(
udp: VeilidConfigUDP(
enabled: !kIsWeb,
socketPoolSize: 0,
listenAddress: "",
publicAddress: null,
listenAddress: '',
),
tcp: VeilidConfigTCP(
connect: !kIsWeb,
listen: !kIsWeb,
maxConnections: 32,
listenAddress: "",
publicAddress: null,
listenAddress: '',
),
ws: VeilidConfigWS(
connect: true,
listen: !kIsWeb,
maxConnections: 16,
listenAddress: "",
path: "ws",
url: null,
listenAddress: '',
path: 'ws',
),
wss: VeilidConfigWSS(
connect: true,
listen: false,
maxConnections: 16,
listenAddress: "",
path: "ws",
url: null,
listenAddress: '',
path: 'ws',
),
),
),
);
}

View File

@ -26,7 +26,7 @@ extension ValidateDFLT on DHTSchemaDFLT {
extension ValidateSMPL on DHTSchemaSMPL {
bool validate() {
final totalsv = members.fold(0, (acc, v) => (acc + v.mCnt)) + oCnt;
final totalsv = members.fold(0, (acc, v) => acc + v.mCnt) + oCnt;
if (totalsv > 65535) {
return false;
}
@ -76,8 +76,7 @@ class DHTRecordDescriptor with _$DHTRecordDescriptor {
const factory DHTRecordDescriptor({
required TypedKey key,
required PublicKey owner,
PublicKey? ownerSecret,
required DHTSchema schema,
required DHTSchema schema, PublicKey? ownerSecret,
}) = _DHTRecordDescriptor;
factory DHTRecordDescriptor.fromJson(dynamic json) =>
_$DHTRecordDescriptorFromJson(json as Map<String, dynamic>);
@ -163,13 +162,13 @@ enum Sequencing {
abstract class SafetySelection extends Equatable {
factory SafetySelection.fromJson(dynamic jsond) {
final json = jsond as Map<String, dynamic>;
if (json.containsKey("Unsafe")) {
if (json.containsKey('Unsafe')) {
return SafetySelectionUnsafe(
sequencing: Sequencing.fromJson(json["Unsafe"]));
} else if (json.containsKey("Safe")) {
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(json["Safe"]));
sequencing: Sequencing.fromJson(json['Unsafe']));
} else if (json.containsKey('Safe')) {
return SafetySelectionSafe(safetySpec: SafetySpec.fromJson(json['Safe']));
} else {
throw const VeilidAPIExceptionInternal("Invalid SafetySelection");
throw const VeilidAPIExceptionInternal('Invalid SafetySelection');
}
}
Map<String, dynamic> toJson();
@ -177,50 +176,43 @@ abstract class SafetySelection extends Equatable {
@immutable
class SafetySelectionUnsafe implements SafetySelection {
//
const SafetySelectionUnsafe({
required this.sequencing,
});
final Sequencing sequencing;
@override
List<Object> get props => [sequencing];
@override
bool? get stringify => null;
//
const SafetySelectionUnsafe({
required this.sequencing,
});
@override
Map<String, dynamic> toJson() {
return {'Unsafe': sequencing.toJson()};
}
Map<String, dynamic> toJson() => {'Unsafe': sequencing.toJson()};
}
@immutable
class SafetySelectionSafe implements SafetySelection {
//
const SafetySelectionSafe({
required this.safetySpec,
});
final SafetySpec safetySpec;
@override
List<Object> get props => [safetySpec];
@override
bool? get stringify => null;
//
const SafetySelectionSafe({
required this.safetySpec,
});
@override
Map<String, dynamic> toJson() {
return {'Safe': safetySpec.toJson()};
}
Map<String, dynamic> toJson() => {'Safe': safetySpec.toJson()};
}
/// Options for safety routes (sender privacy)
@freezed
class SafetySpec with _$SafetySpec {
const factory SafetySpec({
String? preferredRoute,
required int hopCount,
required Stability stability,
required Sequencing sequencing,
required int hopCount, required Stability stability, required Sequencing sequencing, String? preferredRoute,
}) = _SafetySpec;
factory SafetySpec.fromJson(dynamic json) =>

View File

@ -4,28 +4,26 @@ import 'dart:typed_data';
import 'package:equatable/equatable.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'veilid_stub.dart'
if (dart.library.io) 'veilid_ffi.dart'
if (dart.library.js) 'veilid_js.dart';
//////////////////////////////////////////////////////////
import 'routing_context.dart';
import 'veilid_config.dart';
import 'veilid_crypto.dart';
import 'veilid_table_db.dart';
import 'veilid_state.dart';
import 'veilid_stub.dart'
if (dart.library.io) 'veilid_ffi.dart'
if (dart.library.js) 'veilid_js.dart';
import 'veilid_table_db.dart';
export 'default_config.dart';
export 'routing_context.dart';
export 'veilid_encoding.dart';
export 'veilid.dart';
export 'veilid_api_exception.dart';
export 'veilid_config.dart';
export 'veilid_crypto.dart';
export 'veilid_table_db.dart';
export 'veilid_api_exception.dart';
export 'veilid_encoding.dart';
export 'veilid_state.dart';
export 'veilid.dart';
export 'veilid_table_db.dart';
//////////////////////////////////////
/// JSON Encode Helper
@ -42,56 +40,50 @@ Object? veilidApiToEncodable(Object? value) {
}
T? Function(dynamic) optFromJson<T>(
T Function(Map<String, dynamic>) jsonConstructor) {
return (dynamic j) {
T Function(Map<String, dynamic>) jsonConstructor) => (dynamic j) {
if (j == null) {
return null;
} else {
return jsonConstructor(j);
}
};
}
List<T> Function(dynamic) jsonListConstructor<T>(
T Function(Map<String, dynamic>) jsonConstructor) {
return (dynamic j) {
return (j as List<Map<String, dynamic>>)
T Function(Map<String, dynamic>) jsonConstructor) => (dynamic j) => (j as List<Map<String, dynamic>>)
.map((e) => jsonConstructor(e))
.toList();
};
}
//////////////////////////////////////
/// VeilidVersion
@immutable
class VeilidVersion extends Equatable {
const VeilidVersion(this.major, this.minor, this.patch);
final int major;
final int minor;
final int patch;
@override
List<Object> get props => [major, minor, patch];
const VeilidVersion(this.major, this.minor, this.patch);
}
//////////////////////////////////////
/// Timestamp
@immutable
class Timestamp extends Equatable {
const Timestamp({required this.value});
factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s));
factory Timestamp.fromJson(dynamic json) =>
Timestamp.fromString(json as String);
final BigInt value;
@override
List<Object> get props => [value];
const Timestamp({required this.value});
@override
String toString() => value.toString();
factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s));
String toJson() => toString();
factory Timestamp.fromJson(dynamic json) =>
Timestamp.fromString(json as String);
TimestampDuration diff(Timestamp other) =>
TimestampDuration(value: value - other.value);
@ -102,20 +94,20 @@ class Timestamp extends Equatable {
@immutable
class TimestampDuration extends Equatable {
const TimestampDuration({required this.value});
factory TimestampDuration.fromString(String s) =>
TimestampDuration(value: BigInt.parse(s));
factory TimestampDuration.fromJson(dynamic json) =>
TimestampDuration.fromString(json as String);
final BigInt value;
@override
List<Object> get props => [value];
const TimestampDuration({required this.value});
@override
String toString() => value.toString();
factory TimestampDuration.fromString(String s) =>
TimestampDuration(value: BigInt.parse(s));
String toJson() => toString();
factory TimestampDuration.fromJson(dynamic json) =>
TimestampDuration.fromString(json as String);
int toMillis() => (value ~/ BigInt.from(1000)).toInt();
BigInt toMicros() => value;

View File

@ -6,64 +6,64 @@ import 'package:freezed_annotation/freezed_annotation.dart';
@immutable
abstract class VeilidAPIException implements Exception {
factory VeilidAPIException.fromJson(dynamic json) {
switch (json["kind"]) {
case "NotInitialized":
switch (json['kind']) {
case 'NotInitialized':
{
return VeilidAPIExceptionNotInitialized();
}
case "AlreadyInitialized":
case 'AlreadyInitialized':
{
return VeilidAPIExceptionAlreadyInitialized();
}
case "Timeout":
case 'Timeout':
{
return VeilidAPIExceptionTimeout();
}
case "TryAgain":
case 'TryAgain':
{
return VeilidAPIExceptionTryAgain();
}
case "Shutdown":
case 'Shutdown':
{
return VeilidAPIExceptionShutdown();
}
case "InvalidTarget":
case 'InvalidTarget':
{
return VeilidAPIExceptionInvalidTarget();
}
case "NoConnection":
case 'NoConnection':
{
return VeilidAPIExceptionNoConnection(json["message"]);
return VeilidAPIExceptionNoConnection(json['message']);
}
case "KeyNotFound":
case 'KeyNotFound':
{
return VeilidAPIExceptionKeyNotFound(json["key"]);
return VeilidAPIExceptionKeyNotFound(json['key']);
}
case "Internal":
case 'Internal':
{
return VeilidAPIExceptionInternal(json["message"]);
return VeilidAPIExceptionInternal(json['message']);
}
case "Unimplemented":
case 'Unimplemented':
{
return VeilidAPIExceptionUnimplemented(json["unimplemented"]);
return VeilidAPIExceptionUnimplemented(json['unimplemented']);
}
case "ParseError":
case 'ParseError':
{
return VeilidAPIExceptionParseError(json["message"], json["value"]);
return VeilidAPIExceptionParseError(json['message'], json['value']);
}
case "InvalidArgument":
case 'InvalidArgument':
{
return VeilidAPIExceptionInvalidArgument(
json["context"], json["argument"], json["value"]);
json['context'], json['argument'], json['value']);
}
case "MissingArgument":
case 'MissingArgument':
{
return VeilidAPIExceptionMissingArgument(
json["context"], json["argument"]);
json['context'], json['argument']);
}
case "Generic":
case 'Generic':
{
return VeilidAPIExceptionGeneric(json["message"]);
return VeilidAPIExceptionGeneric(json['message']);
}
default:
{
@ -79,224 +79,168 @@ abstract class VeilidAPIException implements Exception {
@immutable
class VeilidAPIExceptionNotInitialized implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: NotInitialized";
}
String toString() => 'VeilidAPIException: NotInitialized';
@override
String toDisplayError() {
return "Not initialized";
}
String toDisplayError() => 'Not initialized';
}
@immutable
class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: AlreadyInitialized";
}
String toString() => 'VeilidAPIException: AlreadyInitialized';
@override
String toDisplayError() {
return "Already initialized";
}
String toDisplayError() => 'Already initialized';
}
@immutable
class VeilidAPIExceptionTimeout implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: Timeout";
}
String toString() => 'VeilidAPIException: Timeout';
@override
String toDisplayError() {
return "Timeout";
}
String toDisplayError() => 'Timeout';
}
@immutable
class VeilidAPIExceptionTryAgain implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: TryAgain";
}
String toString() => 'VeilidAPIException: TryAgain';
@override
String toDisplayError() {
return "Try again";
}
String toDisplayError() => 'Try again';
}
@immutable
class VeilidAPIExceptionShutdown implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: Shutdown";
}
String toString() => 'VeilidAPIException: Shutdown';
@override
String toDisplayError() {
return "Currently shut down";
}
String toDisplayError() => 'Currently shut down';
}
@immutable
class VeilidAPIExceptionInvalidTarget implements VeilidAPIException {
@override
String toString() {
return "VeilidAPIException: InvalidTarget";
}
String toString() => 'VeilidAPIException: InvalidTarget';
@override
String toDisplayError() {
return "Invalid target";
}
String toDisplayError() => 'Invalid target';
}
@immutable
class VeilidAPIExceptionNoConnection implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: NoConnection (message: $message)";
}
@override
String toDisplayError() {
return "No connection: $message";
}
//
const VeilidAPIExceptionNoConnection(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: NoConnection (message: $message)';
@override
String toDisplayError() => 'No connection: $message';
}
@immutable
class VeilidAPIExceptionKeyNotFound implements VeilidAPIException {
final String key;
@override
String toString() {
return "VeilidAPIException: KeyNotFound (key: $key)";
}
@override
String toDisplayError() {
return "Key not found: $key";
}
//
const VeilidAPIExceptionKeyNotFound(this.key);
final String key;
@override
String toString() => 'VeilidAPIException: KeyNotFound (key: $key)';
@override
String toDisplayError() => 'Key not found: $key';
}
@immutable
class VeilidAPIExceptionInternal implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: Internal ($message)";
}
@override
String toDisplayError() {
return "Internal error: $message";
}
//
const VeilidAPIExceptionInternal(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: Internal ($message)';
@override
String toDisplayError() => 'Internal error: $message';
}
@immutable
class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: Unimplemented ($message)";
}
@override
String toDisplayError() {
return "Unimplemented: $message";
}
//
const VeilidAPIExceptionUnimplemented(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: Unimplemented ($message)';
@override
String toDisplayError() => 'Unimplemented: $message';
}
@immutable
class VeilidAPIExceptionParseError implements VeilidAPIException {
//
const VeilidAPIExceptionParseError(this.message, this.value);
final String message;
final String value;
@override
String toString() {
return "VeilidAPIException: ParseError ($message)\n value: $value";
}
String toString() => 'VeilidAPIException: ParseError ($message)\n value: $value';
@override
String toDisplayError() {
return "Parse error: $message";
}
//
const VeilidAPIExceptionParseError(this.message, this.value);
String toDisplayError() => 'Parse error: $message';
}
@immutable
class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
//
const VeilidAPIExceptionInvalidArgument(
this.context, this.argument, this.value);
final String context;
final String argument;
final String value;
@override
String toString() {
return "VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value";
}
String toString() => 'VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value';
@override
String toDisplayError() {
return "Invalid argument for $context: $argument";
}
//
const VeilidAPIExceptionInvalidArgument(
this.context, this.argument, this.value);
String toDisplayError() => 'Invalid argument for $context: $argument';
}
@immutable
class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
//
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
final String context;
final String argument;
@override
String toString() {
return "VeilidAPIException: MissingArgument ($context:$argument)";
}
String toString() => 'VeilidAPIException: MissingArgument ($context:$argument)';
@override
String toDisplayError() {
return "Missing argument for $context: $argument";
}
//
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
String toDisplayError() => 'Missing argument for $context: $argument';
}
@immutable
class VeilidAPIExceptionGeneric implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: Generic (message: $message)";
}
@override
String toDisplayError() {
return message;
}
//
const VeilidAPIExceptionGeneric(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: Generic (message: $message)';
@override
String toDisplayError() => message;
}

View File

@ -1,9 +1,8 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
import 'package:change_case/change_case.dart';
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'veilid.dart';
import 'veilid_encoding.dart';
import 'veilid_crypto.dart';
part 'veilid_config.freezed.dart';
part 'veilid_config.g.dart';
@ -126,13 +125,9 @@ enum VeilidConfigLogLevel {
debug,
trace;
String toJson() {
return name.toPascalCase();
}
String toJson() => name.toPascalCase();
factory VeilidConfigLogLevel.fromJson(dynamic j) {
return VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
}
factory VeilidConfigLogLevel.fromJson(dynamic j) => VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
}
//////////////////////////////////////
@ -300,11 +295,8 @@ class VeilidConfigRPC with _$VeilidConfigRPC {
const factory VeilidConfigRPC(
{required int concurrency,
required int queueSize,
int? maxTimestampBehindMs,
int? maxTimestampAheadMs,
required int timeoutMs,
required int maxRouteHopCount,
required int defaultRouteHopCount}) = _VeilidConfigRPC;
required int timeoutMs, required int maxRouteHopCount, required int defaultRouteHopCount, int? maxTimestampBehindMs,
int? maxTimestampAheadMs}) = _VeilidConfigRPC;
factory VeilidConfigRPC.fromJson(dynamic json) =>
_$VeilidConfigRPCFromJson(json as Map<String, dynamic>);
@ -343,16 +335,7 @@ class VeilidConfigNetwork with _$VeilidConfigNetwork {
required int clientWhitelistTimeoutMs,
required int reverseConnectionReceiptTimeMs,
required int holePunchReceiptTimeMs,
String? networkKeyPassword,
required VeilidConfigRoutingTable routingTable,
required VeilidConfigRPC rpc,
required VeilidConfigDHT dht,
required bool upnp,
required bool detectAddressChanges,
required int restrictedNatRetries,
required VeilidConfigTLS tls,
required VeilidConfigApplication application,
required VeilidConfigProtocol protocol,
required VeilidConfigRoutingTable routingTable, required VeilidConfigRPC rpc, required VeilidConfigDHT dht, required bool upnp, required bool detectAddressChanges, required int restrictedNatRetries, required VeilidConfigTLS tls, required VeilidConfigApplication application, required VeilidConfigProtocol protocol, String? networkKeyPassword,
}) = _VeilidConfigNetwork;
factory VeilidConfigNetwork.fromJson(dynamic json) =>

View File

@ -5,7 +5,6 @@ import 'package:charcode/charcode.dart';
import 'package:equatable/equatable.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'veilid_encoding.dart';
import 'veilid.dart';
//////////////////////////////////////
@ -17,24 +16,22 @@ const CryptoKind cryptoKindVLD0 =
const CryptoKind cryptoKindNONE =
$N << 0 | $O << 8 | $N << 16 | $E << 24; // "NONE"
String cryptoKindToString(CryptoKind kind) {
return cryptoKindToBytes(kind).map((c) => String.fromCharCode(c)).join();
}
String cryptoKindToString(CryptoKind kind) => cryptoKindToBytes(kind).map(String.fromCharCode).join();
const CryptoKind bestCryptoKind = cryptoKindVLD0;
Uint8List cryptoKindToBytes(CryptoKind kind) {
var b = Uint8List(4);
ByteData.sublistView(b).setUint32(0, kind, Endian.big);
final b = Uint8List(4);
ByteData.sublistView(b).setUint32(0, kind);
return b;
}
CryptoKind cryptoKindFromString(String s) {
if (s.codeUnits.length != 4) {
throw const FormatException("malformed string");
throw const FormatException('malformed string');
}
CryptoKind kind = ByteData.sublistView(Uint8List.fromList(s.codeUnits))
.getUint32(0, Endian.big);
final kind = ByteData.sublistView(Uint8List.fromList(s.codeUnits))
.getUint32(0);
return kind;
}
@ -43,103 +40,99 @@ CryptoKind cryptoKindFromString(String s) {
@immutable
class Typed<V extends EncodedString> extends Equatable {
const Typed({required this.kind, required this.value});
factory Typed.fromString(String s) {
final parts = s.split(':');
if (parts.length < 2 || parts[0].codeUnits.length != 4) {
throw const FormatException('malformed string');
}
final kind = cryptoKindFromString(parts[0]);
final value = EncodedString.fromString<V>(parts.sublist(1).join(':'));
return Typed(kind: kind, value: value);
}
factory Typed.fromJson(dynamic json) => Typed.fromString(json as String);
final CryptoKind kind;
final V value;
@override
List<Object> get props => [kind, value];
const Typed({required this.kind, required this.value});
@override
String toString() {
return "${cryptoKindToString(kind)}:$value";
}
factory Typed.fromString(String s) {
final parts = s.split(":");
if (parts.length < 2 || parts[0].codeUnits.length != 4) {
throw const FormatException("malformed string");
}
final kind = cryptoKindFromString(parts[0]);
final value = EncodedString.fromString<V>(parts.sublist(1).join(":"));
return Typed(kind: kind, value: value);
}
String toString() => '${cryptoKindToString(kind)}:$value';
Uint8List decode() {
var b = BytesBuilder();
final b = BytesBuilder();
b.add(cryptoKindToBytes(kind));
b.add(value.decode());
return b.toBytes();
}
String toJson() => toString();
factory Typed.fromJson(dynamic json) => Typed.fromString(json as String);
}
@immutable
class KeyPair extends Equatable {
final PublicKey key;
final PublicKey secret;
@override
List<Object> get props => [key, secret];
const KeyPair({required this.key, required this.secret});
@override
String toString() {
return "${key.toString()}:${secret.toString()}";
}
factory KeyPair.fromString(String s) {
final parts = s.split(":");
final parts = s.split(':');
if (parts.length != 2 ||
parts[0].codeUnits.length != 43 ||
parts[1].codeUnits.length != 43) {
throw const FormatException("malformed string");
throw const FormatException('malformed string');
}
final key = PublicKey.fromString(parts[0]);
final secret = PublicKey.fromString(parts[1]);
return KeyPair(key: key, secret: secret);
}
factory KeyPair.fromJson(dynamic json) => KeyPair.fromString(json as String);
final PublicKey key;
final PublicKey secret;
@override
List<Object> get props => [key, secret];
@override
String toString() => '$key:$secret';
String toJson() => toString();
factory KeyPair.fromJson(dynamic json) => KeyPair.fromString(json as String);
}
@immutable
class TypedKeyPair extends Equatable {
final CryptoKind kind;
final PublicKey key;
final PublicKey secret;
@override
List<Object> get props => [kind, key, secret];
const TypedKeyPair(
{required this.kind, required this.key, required this.secret});
@override
String toString() =>
"${cryptoKindToString(kind)}:${key.toString()}:${secret.toString()}";
factory TypedKeyPair.fromString(String s) {
final parts = s.split(":");
final parts = s.split(':');
if (parts.length != 3 ||
parts[0].codeUnits.length != 4 ||
parts[1].codeUnits.length != 43 ||
parts[2].codeUnits.length != 43) {
throw VeilidAPIExceptionInvalidArgument("malformed string", "s", s);
throw VeilidAPIExceptionInvalidArgument('malformed string', 's', s);
}
final kind = cryptoKindFromString(parts[0]);
final key = PublicKey.fromString(parts[1]);
final secret = PublicKey.fromString(parts[2]);
return TypedKeyPair(kind: kind, key: key, secret: secret);
}
String toJson() => toString();
factory TypedKeyPair.fromJson(dynamic json) =>
TypedKeyPair.fromString(json as String);
factory TypedKeyPair.fromKeyPair(CryptoKind kind, KeyPair keyPair) =>
TypedKeyPair(kind: kind, key: keyPair.key, secret: keyPair.secret);
final CryptoKind kind;
final PublicKey key;
final PublicKey secret;
@override
List<Object> get props => [kind, key, secret];
@override
String toString() =>
'${cryptoKindToString(kind)}:$key:$secret';
String toJson() => toString();
}
typedef CryptoKey = FixedEncodedString43;
@ -176,17 +169,13 @@ abstract class VeilidCryptoSystem {
Future<HashDigest> generateHash(Uint8List data);
//Future<HashDigest> generateHashReader(Stream<List<int>> reader);
Future<bool> validateKeyPair(PublicKey key, SecretKey secret);
Future<bool> validateKeyPairWithKeyPair(KeyPair keyPair) {
return validateKeyPair(keyPair.key, keyPair.secret);
}
Future<bool> validateKeyPairWithKeyPair(KeyPair keyPair) => validateKeyPair(keyPair.key, keyPair.secret);
Future<bool> validateHash(Uint8List data, HashDigest hash);
//Future<bool> validateHashReader(Stream<List<int>> reader, HashDigest hash);
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2);
Future<Signature> sign(PublicKey key, SecretKey secret, Uint8List data);
Future<Signature> signWithKeyPair(KeyPair keyPair, Uint8List data) {
return sign(keyPair.key, keyPair.secret, data);
}
Future<Signature> signWithKeyPair(KeyPair keyPair, Uint8List data) => sign(keyPair.key, keyPair.secret, data);
Future<void> verify(PublicKey key, Uint8List data, Signature signature);
Future<int> aeadOverhead();

View File

@ -34,15 +34,13 @@ class Uint8ListJsonConverter implements JsonConverter<Uint8List, String> {
@immutable
abstract class EncodedString extends Equatable {
const EncodedString(String s) : contents = s;
final String contents;
@override
List<Object> get props => [contents];
const EncodedString(String s) : contents = s;
Uint8List decode() {
return base64UrlNoPadDecode(contents);
}
Uint8List decode() => base64UrlNoPadDecode(contents);
@override
String toString() => contents;
@ -76,96 +74,82 @@ abstract class EncodedString extends Equatable {
@immutable
class FixedEncodedString32 extends EncodedString {
const FixedEncodedString32._(String s) : super(s);
static int encodedLength() {
return 32;
}
static int decodedLength() {
return 24;
}
factory FixedEncodedString32.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}");
throw Exception('length ${bytes.length} should be ${decodedLength()}');
}
return FixedEncodedString32._(base64UrlNoPadEncode(bytes));
}
factory FixedEncodedString32.fromString(String s) {
var d = base64UrlNoPadDecode(s);
final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}");
throw Exception('length ${s.length} should be ${encodedLength()}');
}
return FixedEncodedString32._(s);
}
String toJson() => toString();
factory FixedEncodedString32.fromJson(dynamic json) =>
FixedEncodedString32.fromString(json as String);
const FixedEncodedString32._(super.s);
static int encodedLength() => 32;
static int decodedLength() => 24;
String toJson() => toString();
}
@immutable
class FixedEncodedString43 extends EncodedString {
const FixedEncodedString43._(String s) : super(s);
static int encodedLength() {
return 43;
}
static int decodedLength() {
return 32;
}
factory FixedEncodedString43.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}");
throw Exception('length ${bytes.length} should be ${decodedLength()}');
}
return FixedEncodedString43._(base64UrlNoPadEncode(bytes));
}
factory FixedEncodedString43.fromString(String s) {
var d = base64UrlNoPadDecode(s);
final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}");
throw Exception('length ${s.length} should be ${encodedLength()}');
}
return FixedEncodedString43._(s);
}
String toJson() => toString();
factory FixedEncodedString43.fromJson(dynamic json) =>
FixedEncodedString43.fromString(json as String);
const FixedEncodedString43._(super.s);
static int encodedLength() => 43;
static int decodedLength() => 32;
String toJson() => toString();
}
@immutable
class FixedEncodedString86 extends EncodedString {
const FixedEncodedString86._(String s) : super(s);
static int encodedLength() {
return 86;
}
static int decodedLength() {
return 64;
}
String toJson() {
return toString();
}
factory FixedEncodedString86.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}");
throw Exception('length ${bytes.length} should be ${decodedLength()}');
}
return FixedEncodedString86._(base64UrlNoPadEncode(bytes));
}
factory FixedEncodedString86.fromString(String s) {
var d = base64UrlNoPadDecode(s);
final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}");
throw Exception('length ${s.length} should be ${encodedLength()}');
}
return FixedEncodedString86._(s);
}
factory FixedEncodedString86.fromJson(dynamic json) =>
FixedEncodedString86.fromString(json as String);
const FixedEncodedString86._(super.s);
static int encodedLength() => 86;
static int decodedLength() => 64;
String toJson() => toString();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,26 @@
import 'veilid.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js_util' as js_util;
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'veilid_encoding.dart';
import 'veilid.dart';
//////////////////////////////////////////////////////////
Veilid getVeilid() => VeilidJS();
Object wasm = js_util.getProperty(html.window, "veilid_wasm");
Object wasm = js_util.getProperty(html.window, 'veilid_wasm');
Future<T> _wrapApiPromise<T>(Object p) {
return js_util.promiseToFuture(p).then((value) => value as T).catchError(
Future<T> _wrapApiPromise<T>(Object p) => js_util.promiseToFuture(p).then((value) => value as T).catchError(
(error) => Future<T>.error(
VeilidAPIException.fromJson(jsonDecode(error as String))));
}
class _Ctx {
_Ctx(int this.id, this.js);
int? id;
final VeilidJS js;
_Ctx(int this.id, this.js);
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
@ -33,7 +29,7 @@ class _Ctx {
void close() {
if (id != null) {
js_util.callMethod(wasm, "release_routing_context", [id!]);
js_util.callMethod(wasm, 'release_routing_context', [id!]);
id = null;
}
}
@ -41,12 +37,12 @@ class _Ctx {
// JS implementation of VeilidRoutingContext
class VeilidRoutingContextJS extends VeilidRoutingContext {
final _Ctx _ctx;
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
VeilidRoutingContextJS._(this._ctx) {
_finalizer.attach(this, _ctx, detach: this);
}
final _Ctx _ctx;
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
@override
void close() {
@ -56,8 +52,8 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override
VeilidRoutingContextJS withPrivacy() {
_ctx.ensureValid();
int newId =
js_util.callMethod(wasm, "routing_context_with_privacy", [_ctx.id!]);
final int newId =
js_util.callMethod(wasm, 'routing_context_with_privacy', [_ctx.id!]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
}
@ -66,7 +62,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid();
final newId = js_util.callMethod(
wasm,
"routing_context_with_custom_privacy",
'routing_context_with_custom_privacy',
[_ctx.id!, jsonEncode(safetySelection)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
@ -75,7 +71,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override
VeilidRoutingContextJS withSequencing(Sequencing sequencing) {
_ctx.ensureValid();
final newId = js_util.callMethod(wasm, "routing_context_with_sequencing",
final newId = js_util.callMethod(wasm, 'routing_context_with_sequencing',
[_ctx.id!, jsonEncode(sequencing)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
}
@ -83,19 +79,19 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override
Future<Uint8List> appCall(String target, Uint8List request) async {
_ctx.ensureValid();
var encodedRequest = base64UrlNoPadEncode(request);
final encodedRequest = base64UrlNoPadEncode(request);
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
wasm, "routing_context_app_call", [_ctx.id!, target, encodedRequest])));
wasm, 'routing_context_app_call', [_ctx.id!, target, encodedRequest])));
}
@override
Future<void> appMessage(String target, Uint8List message) {
_ctx.ensureValid();
var encodedMessage = base64UrlNoPadEncode(message);
final encodedMessage = base64UrlNoPadEncode(message);
return _wrapApiPromise(js_util.callMethod(wasm,
"routing_context_app_message", [_ctx.id!, target, encodedMessage]));
'routing_context_app_message', [_ctx.id!, target, encodedMessage]));
}
@override
@ -103,7 +99,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
{CryptoKind kind = 0}) async {
_ctx.ensureValid();
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "routing_context_create_dht_record",
.callMethod(wasm, 'routing_context_create_dht_record',
[_ctx.id!, jsonEncode(schema), kind]))));
}
@ -112,10 +108,10 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
TypedKey key, KeyPair? writer) async {
_ctx.ensureValid();
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "routing_context_open_dht_record", [
.callMethod(wasm, 'routing_context_open_dht_record', [
_ctx.id!,
jsonEncode(key),
writer != null ? jsonEncode(writer) : null
if (writer != null) jsonEncode(writer) else null
]))));
}
@ -123,14 +119,14 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
Future<void> closeDHTRecord(TypedKey key) {
_ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod(
wasm, "routing_context_close_dht_record", [_ctx.id!, jsonEncode(key)]));
wasm, 'routing_context_close_dht_record', [_ctx.id!, jsonEncode(key)]));
}
@override
Future<void> deleteDHTRecord(TypedKey key) {
_ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod(wasm,
"routing_context_delete_dht_record", [_ctx.id!, jsonEncode(key)]));
'routing_context_delete_dht_record', [_ctx.id!, jsonEncode(key)]));
}
@override
@ -139,7 +135,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod(
wasm,
"routing_context_get_dht_value",
'routing_context_get_dht_value',
[_ctx.id!, jsonEncode(key), subkey, forceRefresh]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
}
@ -150,7 +146,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod(
wasm,
"routing_context_set_dht_value",
'routing_context_set_dht_value',
[_ctx.id!, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
}
@ -160,7 +156,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
Timestamp expiration, int count) async {
_ctx.ensureValid();
final ts = await _wrapApiPromise(js_util.callMethod(
wasm, "routing_context_watch_dht_values", [
wasm, 'routing_context_watch_dht_values', [
_ctx.id!,
jsonEncode(key),
jsonEncode(subkeys),
@ -175,192 +171,150 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod(
wasm,
"routing_context_cancel_dht_watch",
'routing_context_cancel_dht_watch',
[_ctx.id!, jsonEncode(key), jsonEncode(subkeys)]));
}
}
// JS implementation of VeilidCryptoSystem
class VeilidCryptoSystemJS extends VeilidCryptoSystem {
final CryptoKind _kind;
final VeilidJS _js;
VeilidCryptoSystemJS._(this._js, this._kind) {
// Keep the reference
_js;
}
final CryptoKind _kind;
final VeilidJS _js;
@override
CryptoKind kind() {
return _kind;
}
CryptoKind kind() => _kind;
@override
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async {
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_cached_dh",
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_cached_dh',
[_kind, jsonEncode(key), jsonEncode(secret)]))));
}
@override
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async {
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_compute_dh",
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_compute_dh',
[_kind, jsonEncode(key), jsonEncode(secret)]))));
}
@override
Future<Uint8List> randomBytes(int len) async {
return base64UrlNoPadDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "crypto_random_bytes", [_kind, len])));
}
Future<Uint8List> randomBytes(int len) async => base64UrlNoPadDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_bytes', [_kind, len])));
@override
Future<int> defaultSaltLength() {
return _wrapApiPromise(
js_util.callMethod(wasm, "crypto_default_salt_length", [_kind]));
}
Future<int> defaultSaltLength() => _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_default_salt_length', [_kind]));
@override
Future<String> hashPassword(Uint8List password, Uint8List salt) {
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_hash_password",
Future<String> hashPassword(Uint8List password, Uint8List salt) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_hash_password',
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
}
@override
Future<bool> verifyPassword(Uint8List password, String passwordHash) {
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify_password",
Future<bool> verifyPassword(Uint8List password, String passwordHash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify_password',
[_kind, base64UrlNoPadEncode(password), passwordHash]));
}
@override
Future<SharedSecret> deriveSharedSecret(
Uint8List password, Uint8List salt) async {
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_derive_shared_secret", [
Uint8List password, Uint8List salt) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_derive_shared_secret', [
_kind,
base64UrlNoPadEncode(password),
base64UrlNoPadEncode(salt)
]))));
}
@override
Future<Nonce> randomNonce() async {
return Nonce.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "crypto_random_nonce", [_kind]))));
}
Future<Nonce> randomNonce() async => Nonce.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_nonce', [_kind]))));
@override
Future<SharedSecret> randomSharedSecret() async {
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "crypto_random_shared_secret", [_kind]))));
}
Future<SharedSecret> randomSharedSecret() async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_shared_secret', [_kind]))));
@override
Future<KeyPair> generateKeyPair() async {
return KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "crypto_generate_key_pair", [_kind]))));
}
Future<KeyPair> generateKeyPair() async => KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_generate_key_pair', [_kind]))));
@override
Future<HashDigest> generateHash(Uint8List data) async {
return HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_generate_hash",
Future<HashDigest> generateHash(Uint8List data) async => HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_generate_hash',
[_kind, base64UrlNoPadEncode(data)]))));
}
@override
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) {
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_key_pair",
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_key_pair',
[_kind, jsonEncode(key), jsonEncode(secret)]));
}
@override
Future<bool> validateHash(Uint8List data, HashDigest hash) {
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_hash",
Future<bool> validateHash(Uint8List data, HashDigest hash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_hash',
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
}
@override
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async {
return CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_distance",
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async => CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_distance',
[_kind, jsonEncode(key1), jsonEncode(key2)]))));
}
@override
Future<Signature> sign(
PublicKey key, SecretKey secret, Uint8List data) async {
return Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "crypto_sign", [
PublicKey key, SecretKey secret, Uint8List data) async => Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_sign', [
_kind,
jsonEncode(key),
jsonEncode(secret),
base64UrlNoPadEncode(data)
]))));
}
@override
Future<void> verify(PublicKey key, Uint8List data, Signature signature) {
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify", [
Future<void> verify(PublicKey key, Uint8List data, Signature signature) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [
_kind,
jsonEncode(key),
base64UrlNoPadEncode(data),
jsonEncode(signature),
]));
}
@override
Future<int> aeadOverhead() {
return _wrapApiPromise(
js_util.callMethod(wasm, "crypto_aead_overhead", [_kind]));
}
Future<int> aeadOverhead() => _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_aead_overhead', [_kind]));
@override
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async {
return base64UrlNoPadDecode(
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_decrypt_aead", [
SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode(
await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_decrypt_aead', [
_kind,
base64UrlNoPadEncode(body),
jsonEncode(nonce),
jsonEncode(sharedSecret),
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
if (associatedData != null) base64UrlNoPadEncode(associatedData) else null
])));
}
@override
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async {
return base64UrlNoPadDecode(
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_encrypt_aead", [
SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode(
await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_encrypt_aead', [
_kind,
base64UrlNoPadEncode(body),
jsonEncode(nonce),
jsonEncode(sharedSecret),
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
if (associatedData != null) base64UrlNoPadEncode(associatedData) else null
])));
}
@override
Future<Uint8List> cryptNoAuth(
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async {
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
wasm, "crypto_crypt_no_auth", [
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async => base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
wasm, 'crypto_crypt_no_auth', [
_kind,
base64UrlNoPadEncode(body),
jsonEncode(nonce),
jsonEncode(sharedSecret)
])));
}
}
class _TDBT {
_TDBT(this.id, this.tdbjs, this.js);
int? id;
final VeilidTableDBJS tdbjs;
final VeilidJS js;
_TDBT(this.id, this.tdbjs, this.js);
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
@ -369,7 +323,7 @@ class _TDBT {
void close() {
if (id != null) {
js_util.callMethod(wasm, "release_table_db_transaction", [id!]);
js_util.callMethod(wasm, 'release_table_db_transaction', [id!]);
id = null;
}
}
@ -377,23 +331,21 @@ class _TDBT {
// JS implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
VeilidTableDBTransactionJS._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this);
}
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
@override
bool isDone() {
return _tdbt.id == null;
}
bool isDone() => _tdbt.id == null;
@override
Future<void> commit() async {
_tdbt.ensureValid();
await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_transaction_commit", [_tdbt.id!]));
js_util.callMethod(wasm, 'table_db_transaction_commit', [_tdbt.id!]));
_tdbt.close();
}
@ -401,7 +353,7 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
Future<void> rollback() async {
_tdbt.ensureValid();
await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_transaction_rollback", [_tdbt.id!]));
js_util.callMethod(wasm, 'table_db_transaction_rollback', [_tdbt.id!]));
_tdbt.close();
}
@ -411,7 +363,7 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final encodedKey = base64UrlNoPadEncode(key);
final encodedValue = base64UrlNoPadEncode(value);
await _wrapApiPromise(js_util.callMethod(wasm, "table_db_transaction_store",
await _wrapApiPromise(js_util.callMethod(wasm, 'table_db_transaction_store',
[_tdbt.id!, col, encodedKey, encodedValue]));
}
@ -421,15 +373,15 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final encodedKey = base64UrlNoPadEncode(key);
await _wrapApiPromise(js_util.callMethod(
wasm, "table_db_transaction_delete", [_tdbt.id!, col, encodedKey]));
wasm, 'table_db_transaction_delete', [_tdbt.id!, col, encodedKey]));
}
}
class _TDB {
int? id;
final VeilidJS js;
_TDB(int this.id, this.js);
int? id;
final VeilidJS js;
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
@ -438,7 +390,7 @@ class _TDB {
void close() {
if (id != null) {
js_util.callMethod(wasm, "release_table_db", [id!]);
js_util.callMethod(wasm, 'release_table_db', [id!]);
id = null;
}
}
@ -446,12 +398,12 @@ class _TDB {
// JS implementation of VeilidTableDB
class VeilidTableDBJS extends VeilidTableDB {
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
VeilidTableDBJS._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this);
}
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
@override
void close() {
@ -461,20 +413,20 @@ class VeilidTableDBJS extends VeilidTableDB {
@override
int getColumnCount() {
_tdb.ensureValid();
return js_util.callMethod(wasm, "table_db_get_column_count", [_tdb.id!]);
return js_util.callMethod(wasm, 'table_db_get_column_count', [_tdb.id!]);
}
@override
Future<List<Uint8List>> getKeys(int col) async {
_tdb.ensureValid();
return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode(
await js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id!, col])));
await js_util.callMethod(wasm, 'table_db_get_keys', [_tdb.id!, col])));
}
@override
VeilidTableDBTransaction transact() {
_tdb.ensureValid();
final id = js_util.callMethod(wasm, "table_db_transact", [_tdb.id!]);
final id = js_util.callMethod(wasm, 'table_db_transact', [_tdb.id!]);
return VeilidTableDBTransactionJS._(_TDBT(id, this, _tdb.js));
}
@ -486,7 +438,7 @@ class VeilidTableDBJS extends VeilidTableDB {
final encodedValue = base64UrlNoPadEncode(value);
return _wrapApiPromise(js_util.callMethod(
wasm, "table_db_store", [_tdb.id!, col, encodedKey, encodedValue]));
wasm, 'table_db_store', [_tdb.id!, col, encodedKey, encodedValue]));
}
@override
@ -494,8 +446,8 @@ class VeilidTableDBJS extends VeilidTableDB {
_tdb.ensureValid();
final encodedKey = base64UrlNoPadEncode(key);
String? out = await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_load", [_tdb.id!, col, encodedKey]));
final out = await _wrapApiPromise(
js_util.callMethod(wasm, 'table_db_load', [_tdb.id!, col, encodedKey]));
if (out == null) {
return null;
}
@ -508,7 +460,7 @@ class VeilidTableDBJS extends VeilidTableDB {
final encodedKey = base64UrlNoPadEncode(key);
return _wrapApiPromise(js_util
.callMethod(wasm, "table_db_delete", [_tdb.id!, col, encodedKey]));
.callMethod(wasm, 'table_db_delete', [_tdb.id!, col, encodedKey]));
}
}
@ -517,61 +469,53 @@ class VeilidTableDBJS extends VeilidTableDB {
class VeilidJS extends Veilid {
@override
void initializeVeilidCore(Map<String, dynamic> platformConfigJson) {
var platformConfigJsonString = jsonEncode(platformConfigJson);
final platformConfigJsonString = jsonEncode(platformConfigJson);
js_util
.callMethod(wasm, "initialize_veilid_core", [platformConfigJsonString]);
.callMethod(wasm, 'initialize_veilid_core', [platformConfigJsonString]);
}
@override
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) {
var logLevelJsonString = jsonEncode(logLevel);
js_util.callMethod(wasm, "change_log_level", [layer, logLevelJsonString]);
final logLevelJsonString = jsonEncode(logLevel);
js_util.callMethod(wasm, 'change_log_level', [layer, logLevelJsonString]);
}
@override
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
var streamController = StreamController<VeilidUpdate>();
final streamController = StreamController<VeilidUpdate>();
updateCallback(String update) {
var updateJson = jsonDecode(update);
if (updateJson["kind"] == "Shutdown") {
final updateJson = jsonDecode(update);
if (updateJson['kind'] == 'Shutdown') {
streamController.close();
} else {
var update = VeilidUpdate.fromJson(updateJson);
final update = VeilidUpdate.fromJson(updateJson);
streamController.add(update);
}
}
await _wrapApiPromise(js_util.callMethod(wasm, "startup_veilid_core",
await _wrapApiPromise(js_util.callMethod(wasm, 'startup_veilid_core',
[js.allowInterop(updateCallback), jsonEncode(config)]));
return streamController.stream;
}
@override
Future<VeilidState> getVeilidState() async {
return VeilidState.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "get_veilid_state", []))));
}
Future<VeilidState> getVeilidState() async => VeilidState.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'get_veilid_state', []))));
@override
Future<void> attach() {
return _wrapApiPromise(js_util.callMethod(wasm, "attach", []));
}
Future<void> attach() => _wrapApiPromise(js_util.callMethod(wasm, 'attach', []));
@override
Future<void> detach() {
return _wrapApiPromise(js_util.callMethod(wasm, "detach", []));
}
Future<void> detach() => _wrapApiPromise(js_util.callMethod(wasm, 'detach', []));
@override
Future<void> shutdownVeilidCore() {
return _wrapApiPromise(
js_util.callMethod(wasm, "shutdown_veilid_core", []));
}
Future<void> shutdownVeilidCore() => _wrapApiPromise(
js_util.callMethod(wasm, 'shutdown_veilid_core', []));
@override
List<CryptoKind> validCryptoKinds() {
final vck = jsonDecode(js_util.callMethod(wasm, "valid_crypto_kinds", []))
final vck = jsonDecode(js_util.callMethod(wasm, 'valid_crypto_kinds', []))
as List<dynamic>;
return vck.map((v) => v as CryptoKind).toList();
}
@ -579,118 +523,98 @@ class VeilidJS extends Veilid {
@override
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async {
if (!validCryptoKinds().contains(kind)) {
throw const VeilidAPIExceptionGeneric("unsupported cryptosystem");
throw const VeilidAPIExceptionGeneric('unsupported cryptosystem');
}
return VeilidCryptoSystemJS._(this, kind);
}
@override
Future<VeilidCryptoSystem> bestCryptoSystem() async {
return VeilidCryptoSystemJS._(
this, js_util.callMethod(wasm, "best_crypto_kind", []));
}
Future<VeilidCryptoSystem> bestCryptoSystem() async => VeilidCryptoSystemJS._(
this, js_util.callMethod(wasm, 'best_crypto_kind', []));
@override
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
Uint8List data, List<TypedSignature> signatures) async {
return jsonListConstructor(TypedKey.fromJson)(jsonDecode(
await _wrapApiPromise(js_util.callMethod(wasm, "verify_signatures", [
Uint8List data, List<TypedSignature> signatures) async => jsonListConstructor(TypedKey.fromJson)(jsonDecode(
await _wrapApiPromise(js_util.callMethod(wasm, 'verify_signatures', [
jsonEncode(nodeIds),
base64UrlNoPadEncode(data),
jsonEncode(signatures)
]))));
}
@override
Future<List<TypedSignature>> generateSignatures(
Uint8List data, List<TypedKeyPair> keyPairs) async {
return jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
await _wrapApiPromise(js_util.callMethod(wasm, "generate_signatures",
Uint8List data, List<TypedKeyPair> keyPairs) async => jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
await _wrapApiPromise(js_util.callMethod(wasm, 'generate_signatures',
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
}
@override
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async {
return TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "generate_key_pair", [kind]))));
}
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async => TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'generate_key_pair', [kind]))));
@override
Future<VeilidRoutingContext> routingContext() async {
int id =
await _wrapApiPromise(js_util.callMethod(wasm, "routing_context", []));
final var id =
await _wrapApiPromise(js_util.callMethod(wasm, 'routing_context', []));
return VeilidRoutingContextJS._(_Ctx(id, this));
}
@override
Future<RouteBlob> newPrivateRoute() async {
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, "new_private_route", []))));
}
Future<RouteBlob> newPrivateRoute() async => RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'new_private_route', []))));
@override
Future<RouteBlob> newCustomPrivateRoute(
Stability stability, Sequencing sequencing) async {
var stabilityString = jsonEncode(stability);
var sequencingString = jsonEncode(sequencing);
final stabilityString = jsonEncode(stability);
final sequencingString = jsonEncode(sequencing);
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(
wasm, "new_private_route", [stabilityString, sequencingString]))));
wasm, 'new_private_route', [stabilityString, sequencingString]))));
}
@override
Future<String> importRemotePrivateRoute(Uint8List blob) {
var encodedBlob = base64UrlNoPadEncode(blob);
final encodedBlob = base64UrlNoPadEncode(blob);
return _wrapApiPromise(
js_util.callMethod(wasm, "import_remote_private_route", [encodedBlob]));
js_util.callMethod(wasm, 'import_remote_private_route', [encodedBlob]));
}
@override
Future<void> releasePrivateRoute(String key) {
return _wrapApiPromise(
js_util.callMethod(wasm, "release_private_route", [key]));
}
Future<void> releasePrivateRoute(String key) => _wrapApiPromise(
js_util.callMethod(wasm, 'release_private_route', [key]));
@override
Future<void> appCallReply(String callId, Uint8List message) {
var encodedMessage = base64UrlNoPadEncode(message);
final encodedMessage = base64UrlNoPadEncode(message);
return _wrapApiPromise(
js_util.callMethod(wasm, "app_call_reply", [callId, encodedMessage]));
js_util.callMethod(wasm, 'app_call_reply', [callId, encodedMessage]));
}
@override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
int id = await _wrapApiPromise(
js_util.callMethod(wasm, "open_table_db", [name, columnCount]));
final id = await _wrapApiPromise(
js_util.callMethod(wasm, 'open_table_db', [name, columnCount]));
return VeilidTableDBJS._(_TDB(id, this));
}
@override
Future<bool> deleteTableDB(String name) {
return _wrapApiPromise(js_util.callMethod(wasm, "delete_table_db", [name]));
}
Future<bool> deleteTableDB(String name) => _wrapApiPromise(js_util.callMethod(wasm, 'delete_table_db', [name]));
@override
Timestamp now() {
return Timestamp.fromString(js_util.callMethod(wasm, "now", []));
}
Timestamp now() => Timestamp.fromString(js_util.callMethod(wasm, 'now', []));
@override
Future<String> debug(String command) async {
return await _wrapApiPromise(js_util.callMethod(wasm, "debug", [command]));
}
Future<String> debug(String command) async => await _wrapApiPromise(js_util.callMethod(wasm, 'debug', [command]));
@override
String veilidVersionString() {
return js_util.callMethod(wasm, "veilid_version_string", []);
}
String veilidVersionString() => js_util.callMethod(wasm, 'veilid_version_string', []);
@override
VeilidVersion veilidVersion() {
Map<String, dynamic> jsonVersion =
jsonDecode(js_util.callMethod(wasm, "veilid_version", []));
jsonDecode(js_util.callMethod(wasm, 'veilid_version', []));
return VeilidVersion(
jsonVersion["major"], jsonVersion["minor"], jsonVersion["patch"]);
jsonVersion['major'], jsonVersion['minor'], jsonVersion['patch']);
}
}

View File

@ -11,7 +11,7 @@ class VeilidPluginStubWeb {
Future<dynamic> handleMethodCall(MethodCall call) async {
throw PlatformException(
code: 'Unimplemented',
details: 'Veilid for Web doesn\'t implement \'${call.method}\'',
details: "Veilid for Web doesn't implement '${call.method}'",
);
}
}

View File

@ -109,8 +109,7 @@ class PeerStats with _$PeerStats {
const factory PeerStats({
required Timestamp timeAdded,
required RPCStats rpcStats,
LatencyStats? latency,
required TransferStatsDownUp transfer,
required TransferStatsDownUp transfer, LatencyStats? latency,
}) = _PeerStats;
factory PeerStats.fromJson(dynamic json) =>
@ -142,13 +141,10 @@ sealed class VeilidUpdate with _$VeilidUpdate {
String? backtrace,
}) = VeilidLog;
const factory VeilidUpdate.appMessage({
TypedKey? sender,
@Uint8ListJsonConverter() required Uint8List message,
@Uint8ListJsonConverter() required Uint8List message, TypedKey? sender,
}) = VeilidAppMessage;
const factory VeilidUpdate.appCall({
TypedKey? sender,
@Uint8ListJsonConverter() required Uint8List message,
required String callId,
@Uint8ListJsonConverter() required Uint8List message, required String callId, TypedKey? sender,
}) = VeilidAppCall;
const factory VeilidUpdate.attachment(
{required AttachmentState state,

View File

@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:convert';
import 'dart:typed_data';
/////////////////////////////////////
/// VeilidTableDB
@ -12,17 +12,13 @@ abstract class VeilidTableDBTransaction {
Future<void> delete(int col, Uint8List key);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) async {
return store(col, key,
{Object? Function(Object? nonEncodable)? toEncodable}) async => store(col, key,
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
}
Future<void> storeStringJson(int col, String key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) {
return storeJson(col, utf8.encoder.convert(key), object,
{Object? Function(Object? nonEncodable)? toEncodable}) => storeJson(col, utf8.encoder.convert(key), object,
toEncodable: toEncodable);
}
}
abstract class VeilidTableDB {
void close();
@ -34,20 +30,16 @@ abstract class VeilidTableDB {
Future<Uint8List?> delete(int col, Uint8List key);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) {
return store(col, key,
{Object? Function(Object? nonEncodable)? toEncodable}) => store(col, key,
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
}
Future<void> storeStringJson(int col, String key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) {
return storeJson(col, utf8.encoder.convert(key), object,
{Object? Function(Object? nonEncodable)? toEncodable}) => storeJson(col, utf8.encoder.convert(key), object,
toEncodable: toEncodable);
}
Future<Object?> loadJson(int col, Uint8List key,
{Object? Function(Object? key, Object? value)? reviver}) async {
var s = await load(col, key);
final s = await load(col, key);
if (s == null) {
return null;
}
@ -55,13 +47,11 @@ abstract class VeilidTableDB {
}
Future<Object?> loadStringJson(int col, String key,
{Object? Function(Object? key, Object? value)? reviver}) {
return loadJson(col, utf8.encoder.convert(key), reviver: reviver);
}
{Object? Function(Object? key, Object? value)? reviver}) => loadJson(col, utf8.encoder.convert(key), reviver: reviver);
Future<Object?> deleteJson(int col, Uint8List key,
{Object? Function(Object? key, Object? value)? reviver}) async {
var s = await delete(col, key);
final s = await delete(col, key);
if (s == null) {
return null;
}
@ -69,7 +59,5 @@ abstract class VeilidTableDB {
}
Future<Object?> deleteStringJson(int col, String key,
{Object? Function(Object? key, Object? value)? reviver}) {
return deleteJson(col, utf8.encoder.convert(key), reviver: reviver);
}
{Object? Function(Object? key, Object? value)? reviver}) => deleteJson(col, utf8.encoder.convert(key), reviver: reviver);
}

View File

@ -8,28 +8,28 @@ environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
change_case: ^1.0.1
charcode: ^1.3.1
equatable: ^2.0.5
ffi: ^2.0.0
flutter:
sdk: flutter
flutter_web_plugins:
sdk: flutter
ffi: ^2.0.0
change_case: ^1.0.1
freezed_annotation: ^2.2.0
json_annotation: ^4.8.1
path_provider: ^2.0.9
path: ^1.8.0
system_info2: ^3.0.2
system_info_plus: ^0.0.5
charcode: ^1.3.1
freezed_annotation: ^2.2.0
json_annotation: ^4.8.1
equatable: ^2.0.5
dev_dependencies:
build_runner: ^2.4.6
flutter_test:
sdk: flutter
flutter_lints: ^2.0.1
build_runner: ^2.4.6
freezed: ^2.3.5
json_serializable: ^6.7.1
lint_hard: ^4.0.0
# The following section is specific to Flutter.
flutter:

View File

@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:veilid/veilid.dart';
void main() {
Veilid api = Veilid.instance;
final api = Veilid.instance;
TestWidgetsFlutterBinding.ensureInitialized();