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: analyzer:
errors: errors:
invalid_annotation_target: ignore invalid_annotation_target: ignore

View File

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

View File

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

View File

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

View File

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

View File

@ -6,64 +6,64 @@ import 'package:freezed_annotation/freezed_annotation.dart';
@immutable @immutable
abstract class VeilidAPIException implements Exception { abstract class VeilidAPIException implements Exception {
factory VeilidAPIException.fromJson(dynamic json) { factory VeilidAPIException.fromJson(dynamic json) {
switch (json["kind"]) { switch (json['kind']) {
case "NotInitialized": case 'NotInitialized':
{ {
return VeilidAPIExceptionNotInitialized(); return VeilidAPIExceptionNotInitialized();
} }
case "AlreadyInitialized": case 'AlreadyInitialized':
{ {
return VeilidAPIExceptionAlreadyInitialized(); return VeilidAPIExceptionAlreadyInitialized();
} }
case "Timeout": case 'Timeout':
{ {
return VeilidAPIExceptionTimeout(); return VeilidAPIExceptionTimeout();
} }
case "TryAgain": case 'TryAgain':
{ {
return VeilidAPIExceptionTryAgain(); return VeilidAPIExceptionTryAgain();
} }
case "Shutdown": case 'Shutdown':
{ {
return VeilidAPIExceptionShutdown(); return VeilidAPIExceptionShutdown();
} }
case "InvalidTarget": case 'InvalidTarget':
{ {
return VeilidAPIExceptionInvalidTarget(); 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( return VeilidAPIExceptionInvalidArgument(
json["context"], json["argument"], json["value"]); json['context'], json['argument'], json['value']);
} }
case "MissingArgument": case 'MissingArgument':
{ {
return VeilidAPIExceptionMissingArgument( return VeilidAPIExceptionMissingArgument(
json["context"], json["argument"]); json['context'], json['argument']);
} }
case "Generic": case 'Generic':
{ {
return VeilidAPIExceptionGeneric(json["message"]); return VeilidAPIExceptionGeneric(json['message']);
} }
default: default:
{ {
@ -79,224 +79,168 @@ abstract class VeilidAPIException implements Exception {
@immutable @immutable
class VeilidAPIExceptionNotInitialized implements VeilidAPIException { class VeilidAPIExceptionNotInitialized implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: NotInitialized';
return "VeilidAPIException: NotInitialized";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Not initialized';
return "Not initialized";
}
} }
@immutable @immutable
class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException { class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: AlreadyInitialized';
return "VeilidAPIException: AlreadyInitialized";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Already initialized';
return "Already initialized";
}
} }
@immutable @immutable
class VeilidAPIExceptionTimeout implements VeilidAPIException { class VeilidAPIExceptionTimeout implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: Timeout';
return "VeilidAPIException: Timeout";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Timeout';
return "Timeout";
}
} }
@immutable @immutable
class VeilidAPIExceptionTryAgain implements VeilidAPIException { class VeilidAPIExceptionTryAgain implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: TryAgain';
return "VeilidAPIException: TryAgain";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Try again';
return "Try again";
}
} }
@immutable @immutable
class VeilidAPIExceptionShutdown implements VeilidAPIException { class VeilidAPIExceptionShutdown implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: Shutdown';
return "VeilidAPIException: Shutdown";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Currently shut down';
return "Currently shut down";
}
} }
@immutable @immutable
class VeilidAPIExceptionInvalidTarget implements VeilidAPIException { class VeilidAPIExceptionInvalidTarget implements VeilidAPIException {
@override @override
String toString() { String toString() => 'VeilidAPIException: InvalidTarget';
return "VeilidAPIException: InvalidTarget";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Invalid target';
return "Invalid target";
}
} }
@immutable @immutable
class VeilidAPIExceptionNoConnection implements VeilidAPIException { 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); const VeilidAPIExceptionNoConnection(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: NoConnection (message: $message)';
@override
String toDisplayError() => 'No connection: $message';
} }
@immutable @immutable
class VeilidAPIExceptionKeyNotFound implements VeilidAPIException { 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); const VeilidAPIExceptionKeyNotFound(this.key);
final String key;
@override
String toString() => 'VeilidAPIException: KeyNotFound (key: $key)';
@override
String toDisplayError() => 'Key not found: $key';
} }
@immutable @immutable
class VeilidAPIExceptionInternal implements VeilidAPIException { 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); const VeilidAPIExceptionInternal(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: Internal ($message)';
@override
String toDisplayError() => 'Internal error: $message';
} }
@immutable @immutable
class VeilidAPIExceptionUnimplemented implements VeilidAPIException { class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: Unimplemented ($message)";
}
@override
String toDisplayError() {
return "Unimplemented: $message";
}
// //
const VeilidAPIExceptionUnimplemented(this.message); const VeilidAPIExceptionUnimplemented(this.message);
final String message;
@override
String toString() => 'VeilidAPIException: Unimplemented ($message)';
@override
String toDisplayError() => 'Unimplemented: $message';
} }
@immutable @immutable
class VeilidAPIExceptionParseError implements VeilidAPIException { class VeilidAPIExceptionParseError implements VeilidAPIException {
//
const VeilidAPIExceptionParseError(this.message, this.value);
final String message; final String message;
final String value; final String value;
@override @override
String toString() { String toString() => 'VeilidAPIException: ParseError ($message)\n value: $value';
return "VeilidAPIException: ParseError ($message)\n value: $value";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Parse error: $message';
return "Parse error: $message";
}
//
const VeilidAPIExceptionParseError(this.message, this.value);
} }
@immutable @immutable
class VeilidAPIExceptionInvalidArgument implements VeilidAPIException { class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
//
const VeilidAPIExceptionInvalidArgument(
this.context, this.argument, this.value);
final String context; final String context;
final String argument; final String argument;
final String value; final String value;
@override @override
String toString() { String toString() => 'VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value';
return "VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Invalid argument for $context: $argument';
return "Invalid argument for $context: $argument";
}
//
const VeilidAPIExceptionInvalidArgument(
this.context, this.argument, this.value);
} }
@immutable @immutable
class VeilidAPIExceptionMissingArgument implements VeilidAPIException { class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
//
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
final String context; final String context;
final String argument; final String argument;
@override @override
String toString() { String toString() => 'VeilidAPIException: MissingArgument ($context:$argument)';
return "VeilidAPIException: MissingArgument ($context:$argument)";
}
@override @override
String toDisplayError() { String toDisplayError() => 'Missing argument for $context: $argument';
return "Missing argument for $context: $argument";
}
//
const VeilidAPIExceptionMissingArgument(this.context, this.argument);
} }
@immutable @immutable
class VeilidAPIExceptionGeneric implements VeilidAPIException { class VeilidAPIExceptionGeneric implements VeilidAPIException {
final String message;
@override
String toString() {
return "VeilidAPIException: Generic (message: $message)";
}
@override
String toDisplayError() {
return message;
}
// //
const VeilidAPIExceptionGeneric(this.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:change_case/change_case.dart';
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'veilid.dart'; import 'veilid.dart';
import 'veilid_encoding.dart';
import 'veilid_crypto.dart';
part 'veilid_config.freezed.dart'; part 'veilid_config.freezed.dart';
part 'veilid_config.g.dart'; part 'veilid_config.g.dart';
@ -126,13 +125,9 @@ enum VeilidConfigLogLevel {
debug, debug,
trace; trace;
String toJson() { String toJson() => name.toPascalCase();
return name.toPascalCase();
}
factory VeilidConfigLogLevel.fromJson(dynamic j) { factory VeilidConfigLogLevel.fromJson(dynamic j) => VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
return VeilidConfigLogLevel.values.byName((j as String).toCamelCase());
}
} }
////////////////////////////////////// //////////////////////////////////////
@ -300,11 +295,8 @@ class VeilidConfigRPC with _$VeilidConfigRPC {
const factory VeilidConfigRPC( const factory VeilidConfigRPC(
{required int concurrency, {required int concurrency,
required int queueSize, required int queueSize,
int? maxTimestampBehindMs, required int timeoutMs, required int maxRouteHopCount, required int defaultRouteHopCount, int? maxTimestampBehindMs,
int? maxTimestampAheadMs, int? maxTimestampAheadMs}) = _VeilidConfigRPC;
required int timeoutMs,
required int maxRouteHopCount,
required int defaultRouteHopCount}) = _VeilidConfigRPC;
factory VeilidConfigRPC.fromJson(dynamic json) => factory VeilidConfigRPC.fromJson(dynamic json) =>
_$VeilidConfigRPCFromJson(json as Map<String, dynamic>); _$VeilidConfigRPCFromJson(json as Map<String, dynamic>);
@ -343,16 +335,7 @@ class VeilidConfigNetwork with _$VeilidConfigNetwork {
required int clientWhitelistTimeoutMs, required int clientWhitelistTimeoutMs,
required int reverseConnectionReceiptTimeMs, required int reverseConnectionReceiptTimeMs,
required int holePunchReceiptTimeMs, 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, 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,
}) = _VeilidConfigNetwork; }) = _VeilidConfigNetwork;
factory VeilidConfigNetwork.fromJson(dynamic json) => factory VeilidConfigNetwork.fromJson(dynamic json) =>

View File

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

View File

@ -34,15 +34,13 @@ class Uint8ListJsonConverter implements JsonConverter<Uint8List, String> {
@immutable @immutable
abstract class EncodedString extends Equatable { abstract class EncodedString extends Equatable {
const EncodedString(String s) : contents = s;
final String contents; final String contents;
@override @override
List<Object> get props => [contents]; List<Object> get props => [contents];
const EncodedString(String s) : contents = s; Uint8List decode() => base64UrlNoPadDecode(contents);
Uint8List decode() {
return base64UrlNoPadDecode(contents);
}
@override @override
String toString() => contents; String toString() => contents;
@ -76,96 +74,82 @@ abstract class EncodedString extends Equatable {
@immutable @immutable
class FixedEncodedString32 extends EncodedString { 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) { factory FixedEncodedString32.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) { if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}"); throw Exception('length ${bytes.length} should be ${decodedLength()}');
} }
return FixedEncodedString32._(base64UrlNoPadEncode(bytes)); return FixedEncodedString32._(base64UrlNoPadEncode(bytes));
} }
factory FixedEncodedString32.fromString(String s) { factory FixedEncodedString32.fromString(String s) {
var d = base64UrlNoPadDecode(s); final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) { if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}"); throw Exception('length ${s.length} should be ${encodedLength()}');
} }
return FixedEncodedString32._(s); return FixedEncodedString32._(s);
} }
String toJson() => toString();
factory FixedEncodedString32.fromJson(dynamic json) => factory FixedEncodedString32.fromJson(dynamic json) =>
FixedEncodedString32.fromString(json as String); FixedEncodedString32.fromString(json as String);
const FixedEncodedString32._(super.s);
static int encodedLength() => 32;
static int decodedLength() => 24;
String toJson() => toString();
} }
@immutable @immutable
class FixedEncodedString43 extends EncodedString { 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) { factory FixedEncodedString43.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) { if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}"); throw Exception('length ${bytes.length} should be ${decodedLength()}');
} }
return FixedEncodedString43._(base64UrlNoPadEncode(bytes)); return FixedEncodedString43._(base64UrlNoPadEncode(bytes));
} }
factory FixedEncodedString43.fromString(String s) { factory FixedEncodedString43.fromString(String s) {
var d = base64UrlNoPadDecode(s); final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) { if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}"); throw Exception('length ${s.length} should be ${encodedLength()}');
} }
return FixedEncodedString43._(s); return FixedEncodedString43._(s);
} }
String toJson() => toString();
factory FixedEncodedString43.fromJson(dynamic json) => factory FixedEncodedString43.fromJson(dynamic json) =>
FixedEncodedString43.fromString(json as String); FixedEncodedString43.fromString(json as String);
const FixedEncodedString43._(super.s);
static int encodedLength() => 43;
static int decodedLength() => 32;
String toJson() => toString();
} }
@immutable @immutable
class FixedEncodedString86 extends EncodedString { 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) { factory FixedEncodedString86.fromBytes(Uint8List bytes) {
if (bytes.length != decodedLength()) { if (bytes.length != decodedLength()) {
throw Exception("length ${bytes.length} should be ${decodedLength()}"); throw Exception('length ${bytes.length} should be ${decodedLength()}');
} }
return FixedEncodedString86._(base64UrlNoPadEncode(bytes)); return FixedEncodedString86._(base64UrlNoPadEncode(bytes));
} }
factory FixedEncodedString86.fromString(String s) { factory FixedEncodedString86.fromString(String s) {
var d = base64UrlNoPadDecode(s); final d = base64UrlNoPadDecode(s);
if (d.length != decodedLength()) { if (d.length != decodedLength()) {
throw Exception("length ${s.length} should be ${encodedLength()}"); throw Exception('length ${s.length} should be ${encodedLength()}');
} }
return FixedEncodedString86._(s); return FixedEncodedString86._(s);
} }
factory FixedEncodedString86.fromJson(dynamic json) => factory FixedEncodedString86.fromJson(dynamic json) =>
FixedEncodedString86.fromString(json as String); 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:html' as html;
import 'dart:js' as js; import 'dart:js' as js;
import 'dart:js_util' as js_util; import 'dart:js_util' as js_util;
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'veilid_encoding.dart'; import 'veilid.dart';
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
Veilid getVeilid() => VeilidJS(); 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) { Future<T> _wrapApiPromise<T>(Object p) => js_util.promiseToFuture(p).then((value) => value as T).catchError(
return js_util.promiseToFuture(p).then((value) => value as T).catchError(
(error) => Future<T>.error( (error) => Future<T>.error(
VeilidAPIException.fromJson(jsonDecode(error as String)))); VeilidAPIException.fromJson(jsonDecode(error as String))));
}
class _Ctx { class _Ctx {
_Ctx(int this.id, this.js);
int? id; int? id;
final VeilidJS js; final VeilidJS js;
_Ctx(int this.id, this.js);
void ensureValid() { void ensureValid() {
if (id == null) { if (id == null) {
throw VeilidAPIExceptionNotInitialized(); throw VeilidAPIExceptionNotInitialized();
@ -33,7 +29,7 @@ class _Ctx {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, "release_routing_context", [id!]); js_util.callMethod(wasm, 'release_routing_context', [id!]);
id = null; id = null;
} }
} }
@ -41,12 +37,12 @@ class _Ctx {
// JS implementation of VeilidRoutingContext // JS implementation of VeilidRoutingContext
class VeilidRoutingContextJS extends VeilidRoutingContext { class VeilidRoutingContextJS extends VeilidRoutingContext {
final _Ctx _ctx;
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
VeilidRoutingContextJS._(this._ctx) { VeilidRoutingContextJS._(this._ctx) {
_finalizer.attach(this, _ctx, detach: this); _finalizer.attach(this, _ctx, detach: this);
} }
final _Ctx _ctx;
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
@override @override
void close() { void close() {
@ -56,8 +52,8 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
VeilidRoutingContextJS withPrivacy() { VeilidRoutingContextJS withPrivacy() {
_ctx.ensureValid(); _ctx.ensureValid();
int newId = final int newId =
js_util.callMethod(wasm, "routing_context_with_privacy", [_ctx.id!]); js_util.callMethod(wasm, 'routing_context_with_privacy', [_ctx.id!]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
} }
@ -66,7 +62,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid(); _ctx.ensureValid();
final newId = js_util.callMethod( final newId = js_util.callMethod(
wasm, wasm,
"routing_context_with_custom_privacy", 'routing_context_with_custom_privacy',
[_ctx.id!, jsonEncode(safetySelection)]); [_ctx.id!, jsonEncode(safetySelection)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
@ -75,7 +71,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
VeilidRoutingContextJS withSequencing(Sequencing sequencing) { VeilidRoutingContextJS withSequencing(Sequencing sequencing) {
_ctx.ensureValid(); _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)]); [_ctx.id!, jsonEncode(sequencing)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
} }
@ -83,19 +79,19 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
Future<Uint8List> appCall(String target, Uint8List request) async { Future<Uint8List> appCall(String target, Uint8List request) async {
_ctx.ensureValid(); _ctx.ensureValid();
var encodedRequest = base64UrlNoPadEncode(request); final encodedRequest = base64UrlNoPadEncode(request);
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod( 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 @override
Future<void> appMessage(String target, Uint8List message) { Future<void> appMessage(String target, Uint8List message) {
_ctx.ensureValid(); _ctx.ensureValid();
var encodedMessage = base64UrlNoPadEncode(message); final encodedMessage = base64UrlNoPadEncode(message);
return _wrapApiPromise(js_util.callMethod(wasm, return _wrapApiPromise(js_util.callMethod(wasm,
"routing_context_app_message", [_ctx.id!, target, encodedMessage])); 'routing_context_app_message', [_ctx.id!, target, encodedMessage]));
} }
@override @override
@ -103,7 +99,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
{CryptoKind kind = 0}) async { {CryptoKind kind = 0}) async {
_ctx.ensureValid(); _ctx.ensureValid();
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util 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])))); [_ctx.id!, jsonEncode(schema), kind]))));
} }
@ -112,10 +108,10 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
TypedKey key, KeyPair? writer) async { TypedKey key, KeyPair? writer) async {
_ctx.ensureValid(); _ctx.ensureValid();
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, "routing_context_open_dht_record", [ .callMethod(wasm, 'routing_context_open_dht_record', [
_ctx.id!, _ctx.id!,
jsonEncode(key), 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) { Future<void> closeDHTRecord(TypedKey key) {
_ctx.ensureValid(); _ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod( 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 @override
Future<void> deleteDHTRecord(TypedKey key) { Future<void> deleteDHTRecord(TypedKey key) {
_ctx.ensureValid(); _ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod(wasm, 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 @override
@ -139,7 +135,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid(); _ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod( final opt = await _wrapApiPromise(js_util.callMethod(
wasm, wasm,
"routing_context_get_dht_value", 'routing_context_get_dht_value',
[_ctx.id!, jsonEncode(key), subkey, forceRefresh])); [_ctx.id!, jsonEncode(key), subkey, forceRefresh]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
} }
@ -150,7 +146,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid(); _ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod( final opt = await _wrapApiPromise(js_util.callMethod(
wasm, wasm,
"routing_context_set_dht_value", 'routing_context_set_dht_value',
[_ctx.id!, jsonEncode(key), subkey, base64UrlNoPadEncode(data)])); [_ctx.id!, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
} }
@ -160,7 +156,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
Timestamp expiration, int count) async { Timestamp expiration, int count) async {
_ctx.ensureValid(); _ctx.ensureValid();
final ts = await _wrapApiPromise(js_util.callMethod( final ts = await _wrapApiPromise(js_util.callMethod(
wasm, "routing_context_watch_dht_values", [ wasm, 'routing_context_watch_dht_values', [
_ctx.id!, _ctx.id!,
jsonEncode(key), jsonEncode(key),
jsonEncode(subkeys), jsonEncode(subkeys),
@ -175,192 +171,150 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
_ctx.ensureValid(); _ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod( return _wrapApiPromise(js_util.callMethod(
wasm, wasm,
"routing_context_cancel_dht_watch", 'routing_context_cancel_dht_watch',
[_ctx.id!, jsonEncode(key), jsonEncode(subkeys)])); [_ctx.id!, jsonEncode(key), jsonEncode(subkeys)]));
} }
} }
// JS implementation of VeilidCryptoSystem // JS implementation of VeilidCryptoSystem
class VeilidCryptoSystemJS extends VeilidCryptoSystem { class VeilidCryptoSystemJS extends VeilidCryptoSystem {
final CryptoKind _kind;
final VeilidJS _js;
VeilidCryptoSystemJS._(this._js, this._kind) { VeilidCryptoSystemJS._(this._js, this._kind) {
// Keep the reference // Keep the reference
_js; _js;
} }
final CryptoKind _kind;
final VeilidJS _js;
@override @override
CryptoKind kind() { CryptoKind kind() => _kind;
return _kind;
}
@override @override
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async { Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_cached_dh',
.callMethod(wasm, "crypto_cached_dh",
[_kind, jsonEncode(key), jsonEncode(secret)])))); [_kind, jsonEncode(key), jsonEncode(secret)]))));
}
@override @override
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async { Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_compute_dh',
.callMethod(wasm, "crypto_compute_dh",
[_kind, jsonEncode(key), jsonEncode(secret)])))); [_kind, jsonEncode(key), jsonEncode(secret)]))));
}
@override @override
Future<Uint8List> randomBytes(int len) async { Future<Uint8List> randomBytes(int len) async => base64UrlNoPadDecode(await _wrapApiPromise(
return base64UrlNoPadDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'crypto_random_bytes', [_kind, len])));
js_util.callMethod(wasm, "crypto_random_bytes", [_kind, len])));
}
@override @override
Future<int> defaultSaltLength() { Future<int> defaultSaltLength() => _wrapApiPromise(
return _wrapApiPromise( js_util.callMethod(wasm, 'crypto_default_salt_length', [_kind]));
js_util.callMethod(wasm, "crypto_default_salt_length", [_kind]));
}
@override @override
Future<String> hashPassword(Uint8List password, Uint8List salt) { Future<String> hashPassword(Uint8List password, Uint8List salt) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_hash_password',
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_hash_password",
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)])); [_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
}
@override @override
Future<bool> verifyPassword(Uint8List password, String passwordHash) { Future<bool> verifyPassword(Uint8List password, String passwordHash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify_password',
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify_password",
[_kind, base64UrlNoPadEncode(password), passwordHash])); [_kind, base64UrlNoPadEncode(password), passwordHash]));
}
@override @override
Future<SharedSecret> deriveSharedSecret( Future<SharedSecret> deriveSharedSecret(
Uint8List password, Uint8List salt) async { Uint8List password, Uint8List salt) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_derive_shared_secret', [
.callMethod(wasm, "crypto_derive_shared_secret", [
_kind, _kind,
base64UrlNoPadEncode(password), base64UrlNoPadEncode(password),
base64UrlNoPadEncode(salt) base64UrlNoPadEncode(salt)
])))); ]))));
}
@override @override
Future<Nonce> randomNonce() async { Future<Nonce> randomNonce() async => Nonce.fromJson(jsonDecode(await _wrapApiPromise(
return Nonce.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'crypto_random_nonce', [_kind]))));
js_util.callMethod(wasm, "crypto_random_nonce", [_kind]))));
}
@override @override
Future<SharedSecret> randomSharedSecret() async { Future<SharedSecret> randomSharedSecret() async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'crypto_random_shared_secret', [_kind]))));
js_util.callMethod(wasm, "crypto_random_shared_secret", [_kind]))));
}
@override @override
Future<KeyPair> generateKeyPair() async { Future<KeyPair> generateKeyPair() async => KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
return KeyPair.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'crypto_generate_key_pair', [_kind]))));
js_util.callMethod(wasm, "crypto_generate_key_pair", [_kind]))));
}
@override @override
Future<HashDigest> generateHash(Uint8List data) async { Future<HashDigest> generateHash(Uint8List data) async => HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util
return HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_generate_hash',
.callMethod(wasm, "crypto_generate_hash",
[_kind, base64UrlNoPadEncode(data)])))); [_kind, base64UrlNoPadEncode(data)]))));
}
@override @override
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) { Future<bool> validateKeyPair(PublicKey key, SecretKey secret) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_key_pair',
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_key_pair",
[_kind, jsonEncode(key), jsonEncode(secret)])); [_kind, jsonEncode(key), jsonEncode(secret)]));
}
@override @override
Future<bool> validateHash(Uint8List data, HashDigest hash) { Future<bool> validateHash(Uint8List data, HashDigest hash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_hash',
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_hash",
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)])); [_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
}
@override @override
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async { Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async => CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
return CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_distance',
.callMethod(wasm, "crypto_distance",
[_kind, jsonEncode(key1), jsonEncode(key2)])))); [_kind, jsonEncode(key1), jsonEncode(key2)]))));
}
@override @override
Future<Signature> sign( Future<Signature> sign(
PublicKey key, SecretKey secret, Uint8List data) async { PublicKey key, SecretKey secret, Uint8List data) async => Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util
return Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util .callMethod(wasm, 'crypto_sign', [
.callMethod(wasm, "crypto_sign", [
_kind, _kind,
jsonEncode(key), jsonEncode(key),
jsonEncode(secret), jsonEncode(secret),
base64UrlNoPadEncode(data) base64UrlNoPadEncode(data)
])))); ]))));
}
@override @override
Future<void> verify(PublicKey key, Uint8List data, Signature signature) { Future<void> verify(PublicKey key, Uint8List data, Signature signature) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify", [
_kind, _kind,
jsonEncode(key), jsonEncode(key),
base64UrlNoPadEncode(data), base64UrlNoPadEncode(data),
jsonEncode(signature), jsonEncode(signature),
])); ]));
}
@override @override
Future<int> aeadOverhead() { Future<int> aeadOverhead() => _wrapApiPromise(
return _wrapApiPromise( js_util.callMethod(wasm, 'crypto_aead_overhead', [_kind]));
js_util.callMethod(wasm, "crypto_aead_overhead", [_kind]));
}
@override @override
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce, Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async { SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode(
return base64UrlNoPadDecode( await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_decrypt_aead', [
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_decrypt_aead", [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
jsonEncode(nonce), jsonEncode(nonce),
jsonEncode(sharedSecret), jsonEncode(sharedSecret),
associatedData != null ? base64UrlNoPadEncode(associatedData) : null if (associatedData != null) base64UrlNoPadEncode(associatedData) else null
]))); ])));
}
@override @override
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce, Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async { SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode(
return base64UrlNoPadDecode( await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_encrypt_aead', [
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_encrypt_aead", [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
jsonEncode(nonce), jsonEncode(nonce),
jsonEncode(sharedSecret), jsonEncode(sharedSecret),
associatedData != null ? base64UrlNoPadEncode(associatedData) : null if (associatedData != null) base64UrlNoPadEncode(associatedData) else null
]))); ])));
}
@override @override
Future<Uint8List> cryptNoAuth( Future<Uint8List> cryptNoAuth(
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async { Uint8List body, Nonce nonce, SharedSecret sharedSecret) async => base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod( wasm, 'crypto_crypt_no_auth', [
wasm, "crypto_crypt_no_auth", [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
jsonEncode(nonce), jsonEncode(nonce),
jsonEncode(sharedSecret) jsonEncode(sharedSecret)
]))); ])));
}
} }
class _TDBT { class _TDBT {
_TDBT(this.id, this.tdbjs, this.js);
int? id; int? id;
final VeilidTableDBJS tdbjs; final VeilidTableDBJS tdbjs;
final VeilidJS js; final VeilidJS js;
_TDBT(this.id, this.tdbjs, this.js);
void ensureValid() { void ensureValid() {
if (id == null) { if (id == null) {
throw VeilidAPIExceptionNotInitialized(); throw VeilidAPIExceptionNotInitialized();
@ -369,7 +323,7 @@ class _TDBT {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, "release_table_db_transaction", [id!]); js_util.callMethod(wasm, 'release_table_db_transaction', [id!]);
id = null; id = null;
} }
} }
@ -377,23 +331,21 @@ class _TDBT {
// JS implementation of VeilidTableDBTransaction // JS implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction { class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
VeilidTableDBTransactionJS._(this._tdbt) { VeilidTableDBTransactionJS._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this); _finalizer.attach(this, _tdbt, detach: this);
} }
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
@override @override
bool isDone() { bool isDone() => _tdbt.id == null;
return _tdbt.id == null;
}
@override @override
Future<void> commit() async { Future<void> commit() async {
_tdbt.ensureValid(); _tdbt.ensureValid();
await _wrapApiPromise( await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_transaction_commit", [_tdbt.id!])); js_util.callMethod(wasm, 'table_db_transaction_commit', [_tdbt.id!]));
_tdbt.close(); _tdbt.close();
} }
@ -401,7 +353,7 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
Future<void> rollback() async { Future<void> rollback() async {
_tdbt.ensureValid(); _tdbt.ensureValid();
await _wrapApiPromise( await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_transaction_rollback", [_tdbt.id!])); js_util.callMethod(wasm, 'table_db_transaction_rollback', [_tdbt.id!]));
_tdbt.close(); _tdbt.close();
} }
@ -411,7 +363,7 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
final encodedValue = base64UrlNoPadEncode(value); 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])); [_tdbt.id!, col, encodedKey, encodedValue]));
} }
@ -421,15 +373,15 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
await _wrapApiPromise(js_util.callMethod( 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 { class _TDB {
int? id;
final VeilidJS js;
_TDB(int this.id, this.js); _TDB(int this.id, this.js);
int? id;
final VeilidJS js;
void ensureValid() { void ensureValid() {
if (id == null) { if (id == null) {
throw VeilidAPIExceptionNotInitialized(); throw VeilidAPIExceptionNotInitialized();
@ -438,7 +390,7 @@ class _TDB {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, "release_table_db", [id!]); js_util.callMethod(wasm, 'release_table_db', [id!]);
id = null; id = null;
} }
} }
@ -446,12 +398,12 @@ class _TDB {
// JS implementation of VeilidTableDB // JS implementation of VeilidTableDB
class VeilidTableDBJS extends VeilidTableDB { class VeilidTableDBJS extends VeilidTableDB {
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
VeilidTableDBJS._(this._tdb) { VeilidTableDBJS._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this); _finalizer.attach(this, _tdb, detach: this);
} }
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
@override @override
void close() { void close() {
@ -461,20 +413,20 @@ class VeilidTableDBJS extends VeilidTableDB {
@override @override
int getColumnCount() { int getColumnCount() {
_tdb.ensureValid(); _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 @override
Future<List<Uint8List>> getKeys(int col) async { Future<List<Uint8List>> getKeys(int col) async {
_tdb.ensureValid(); _tdb.ensureValid();
return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode( 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 @override
VeilidTableDBTransaction transact() { VeilidTableDBTransaction transact() {
_tdb.ensureValid(); _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)); return VeilidTableDBTransactionJS._(_TDBT(id, this, _tdb.js));
} }
@ -486,7 +438,7 @@ class VeilidTableDBJS extends VeilidTableDB {
final encodedValue = base64UrlNoPadEncode(value); final encodedValue = base64UrlNoPadEncode(value);
return _wrapApiPromise(js_util.callMethod( return _wrapApiPromise(js_util.callMethod(
wasm, "table_db_store", [_tdb.id!, col, encodedKey, encodedValue])); wasm, 'table_db_store', [_tdb.id!, col, encodedKey, encodedValue]));
} }
@override @override
@ -494,8 +446,8 @@ class VeilidTableDBJS extends VeilidTableDB {
_tdb.ensureValid(); _tdb.ensureValid();
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
String? out = await _wrapApiPromise( final out = await _wrapApiPromise(
js_util.callMethod(wasm, "table_db_load", [_tdb.id!, col, encodedKey])); js_util.callMethod(wasm, 'table_db_load', [_tdb.id!, col, encodedKey]));
if (out == null) { if (out == null) {
return null; return null;
} }
@ -508,7 +460,7 @@ class VeilidTableDBJS extends VeilidTableDB {
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
return _wrapApiPromise(js_util 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 { class VeilidJS extends Veilid {
@override @override
void initializeVeilidCore(Map<String, dynamic> platformConfigJson) { void initializeVeilidCore(Map<String, dynamic> platformConfigJson) {
var platformConfigJsonString = jsonEncode(platformConfigJson); final platformConfigJsonString = jsonEncode(platformConfigJson);
js_util js_util
.callMethod(wasm, "initialize_veilid_core", [platformConfigJsonString]); .callMethod(wasm, 'initialize_veilid_core', [platformConfigJsonString]);
} }
@override @override
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) { void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) {
var logLevelJsonString = jsonEncode(logLevel); final logLevelJsonString = jsonEncode(logLevel);
js_util.callMethod(wasm, "change_log_level", [layer, logLevelJsonString]); js_util.callMethod(wasm, 'change_log_level', [layer, logLevelJsonString]);
} }
@override @override
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async { Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
var streamController = StreamController<VeilidUpdate>(); final streamController = StreamController<VeilidUpdate>();
updateCallback(String update) { updateCallback(String update) {
var updateJson = jsonDecode(update); final updateJson = jsonDecode(update);
if (updateJson["kind"] == "Shutdown") { if (updateJson['kind'] == 'Shutdown') {
streamController.close(); streamController.close();
} else { } else {
var update = VeilidUpdate.fromJson(updateJson); final update = VeilidUpdate.fromJson(updateJson);
streamController.add(update); 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)])); [js.allowInterop(updateCallback), jsonEncode(config)]));
return streamController.stream; return streamController.stream;
} }
@override @override
Future<VeilidState> getVeilidState() async { Future<VeilidState> getVeilidState() async => VeilidState.fromJson(jsonDecode(await _wrapApiPromise(
return VeilidState.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'get_veilid_state', []))));
js_util.callMethod(wasm, "get_veilid_state", []))));
}
@override @override
Future<void> attach() { Future<void> attach() => _wrapApiPromise(js_util.callMethod(wasm, 'attach', []));
return _wrapApiPromise(js_util.callMethod(wasm, "attach", []));
}
@override @override
Future<void> detach() { Future<void> detach() => _wrapApiPromise(js_util.callMethod(wasm, 'detach', []));
return _wrapApiPromise(js_util.callMethod(wasm, "detach", []));
}
@override @override
Future<void> shutdownVeilidCore() { Future<void> shutdownVeilidCore() => _wrapApiPromise(
return _wrapApiPromise( js_util.callMethod(wasm, 'shutdown_veilid_core', []));
js_util.callMethod(wasm, "shutdown_veilid_core", []));
}
@override @override
List<CryptoKind> validCryptoKinds() { 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>; as List<dynamic>;
return vck.map((v) => v as CryptoKind).toList(); return vck.map((v) => v as CryptoKind).toList();
} }
@ -579,118 +523,98 @@ class VeilidJS extends Veilid {
@override @override
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async { Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async {
if (!validCryptoKinds().contains(kind)) { if (!validCryptoKinds().contains(kind)) {
throw const VeilidAPIExceptionGeneric("unsupported cryptosystem"); throw const VeilidAPIExceptionGeneric('unsupported cryptosystem');
} }
return VeilidCryptoSystemJS._(this, kind); return VeilidCryptoSystemJS._(this, kind);
} }
@override @override
Future<VeilidCryptoSystem> bestCryptoSystem() async { Future<VeilidCryptoSystem> bestCryptoSystem() async => VeilidCryptoSystemJS._(
return VeilidCryptoSystemJS._( this, js_util.callMethod(wasm, 'best_crypto_kind', []));
this, js_util.callMethod(wasm, "best_crypto_kind", []));
}
@override @override
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds, Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
Uint8List data, List<TypedSignature> signatures) async { Uint8List data, List<TypedSignature> signatures) async => jsonListConstructor(TypedKey.fromJson)(jsonDecode(
return jsonListConstructor(TypedKey.fromJson)(jsonDecode( await _wrapApiPromise(js_util.callMethod(wasm, 'verify_signatures', [
await _wrapApiPromise(js_util.callMethod(wasm, "verify_signatures", [
jsonEncode(nodeIds), jsonEncode(nodeIds),
base64UrlNoPadEncode(data), base64UrlNoPadEncode(data),
jsonEncode(signatures) jsonEncode(signatures)
])))); ]))));
}
@override @override
Future<List<TypedSignature>> generateSignatures( Future<List<TypedSignature>> generateSignatures(
Uint8List data, List<TypedKeyPair> keyPairs) async { Uint8List data, List<TypedKeyPair> keyPairs) async => jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
return jsonListConstructor(TypedSignature.fromJson)(jsonDecode( await _wrapApiPromise(js_util.callMethod(wasm, 'generate_signatures',
await _wrapApiPromise(js_util.callMethod(wasm, "generate_signatures",
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)])))); [base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
}
@override @override
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async { Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async => TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
return TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'generate_key_pair', [kind]))));
js_util.callMethod(wasm, "generate_key_pair", [kind]))));
}
@override @override
Future<VeilidRoutingContext> routingContext() async { Future<VeilidRoutingContext> routingContext() async {
int id = final var id =
await _wrapApiPromise(js_util.callMethod(wasm, "routing_context", [])); await _wrapApiPromise(js_util.callMethod(wasm, 'routing_context', []));
return VeilidRoutingContextJS._(_Ctx(id, this)); return VeilidRoutingContextJS._(_Ctx(id, this));
} }
@override @override
Future<RouteBlob> newPrivateRoute() async { Future<RouteBlob> newPrivateRoute() async => RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'new_private_route', []))));
js_util.callMethod(wasm, "new_private_route", []))));
}
@override @override
Future<RouteBlob> newCustomPrivateRoute( Future<RouteBlob> newCustomPrivateRoute(
Stability stability, Sequencing sequencing) async { Stability stability, Sequencing sequencing) async {
var stabilityString = jsonEncode(stability); final stabilityString = jsonEncode(stability);
var sequencingString = jsonEncode(sequencing); final sequencingString = jsonEncode(sequencing);
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(js_util return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod( .callMethod(
wasm, "new_private_route", [stabilityString, sequencingString])))); wasm, 'new_private_route', [stabilityString, sequencingString]))));
} }
@override @override
Future<String> importRemotePrivateRoute(Uint8List blob) { Future<String> importRemotePrivateRoute(Uint8List blob) {
var encodedBlob = base64UrlNoPadEncode(blob); final encodedBlob = base64UrlNoPadEncode(blob);
return _wrapApiPromise( return _wrapApiPromise(
js_util.callMethod(wasm, "import_remote_private_route", [encodedBlob])); js_util.callMethod(wasm, 'import_remote_private_route', [encodedBlob]));
} }
@override @override
Future<void> releasePrivateRoute(String key) { Future<void> releasePrivateRoute(String key) => _wrapApiPromise(
return _wrapApiPromise( js_util.callMethod(wasm, 'release_private_route', [key]));
js_util.callMethod(wasm, "release_private_route", [key]));
}
@override @override
Future<void> appCallReply(String callId, Uint8List message) { Future<void> appCallReply(String callId, Uint8List message) {
var encodedMessage = base64UrlNoPadEncode(message); final encodedMessage = base64UrlNoPadEncode(message);
return _wrapApiPromise( return _wrapApiPromise(
js_util.callMethod(wasm, "app_call_reply", [callId, encodedMessage])); js_util.callMethod(wasm, 'app_call_reply', [callId, encodedMessage]));
} }
@override @override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async { Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
int id = await _wrapApiPromise( final id = await _wrapApiPromise(
js_util.callMethod(wasm, "open_table_db", [name, columnCount])); js_util.callMethod(wasm, 'open_table_db', [name, columnCount]));
return VeilidTableDBJS._(_TDB(id, this)); return VeilidTableDBJS._(_TDB(id, this));
} }
@override @override
Future<bool> deleteTableDB(String name) { Future<bool> deleteTableDB(String name) => _wrapApiPromise(js_util.callMethod(wasm, 'delete_table_db', [name]));
return _wrapApiPromise(js_util.callMethod(wasm, "delete_table_db", [name]));
}
@override @override
Timestamp now() { Timestamp now() => Timestamp.fromString(js_util.callMethod(wasm, 'now', []));
return Timestamp.fromString(js_util.callMethod(wasm, "now", []));
}
@override @override
Future<String> debug(String command) async { Future<String> debug(String command) async => await _wrapApiPromise(js_util.callMethod(wasm, 'debug', [command]));
return await _wrapApiPromise(js_util.callMethod(wasm, "debug", [command]));
}
@override @override
String veilidVersionString() { String veilidVersionString() => js_util.callMethod(wasm, 'veilid_version_string', []);
return js_util.callMethod(wasm, "veilid_version_string", []);
}
@override @override
VeilidVersion veilidVersion() { VeilidVersion veilidVersion() {
Map<String, dynamic> jsonVersion = Map<String, dynamic> jsonVersion =
jsonDecode(js_util.callMethod(wasm, "veilid_version", [])); jsonDecode(js_util.callMethod(wasm, 'veilid_version', []));
return VeilidVersion( 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 { Future<dynamic> handleMethodCall(MethodCall call) async {
throw PlatformException( throw PlatformException(
code: 'Unimplemented', 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({ const factory PeerStats({
required Timestamp timeAdded, required Timestamp timeAdded,
required RPCStats rpcStats, required RPCStats rpcStats,
LatencyStats? latency, required TransferStatsDownUp transfer, LatencyStats? latency,
required TransferStatsDownUp transfer,
}) = _PeerStats; }) = _PeerStats;
factory PeerStats.fromJson(dynamic json) => factory PeerStats.fromJson(dynamic json) =>
@ -142,13 +141,10 @@ sealed class VeilidUpdate with _$VeilidUpdate {
String? backtrace, String? backtrace,
}) = VeilidLog; }) = VeilidLog;
const factory VeilidUpdate.appMessage({ const factory VeilidUpdate.appMessage({
TypedKey? sender, @Uint8ListJsonConverter() required Uint8List message, TypedKey? sender,
@Uint8ListJsonConverter() required Uint8List message,
}) = VeilidAppMessage; }) = VeilidAppMessage;
const factory VeilidUpdate.appCall({ const factory VeilidUpdate.appCall({
TypedKey? sender, @Uint8ListJsonConverter() required Uint8List message, required String callId, TypedKey? sender,
@Uint8ListJsonConverter() required Uint8List message,
required String callId,
}) = VeilidAppCall; }) = VeilidAppCall;
const factory VeilidUpdate.attachment( const factory VeilidUpdate.attachment(
{required AttachmentState state, {required AttachmentState state,

View File

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

View File

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

View File

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