diff --git a/veilid-flutter/example/lib/app.dart b/veilid-flutter/example/lib/app.dart index 00e6600a..06576424 100644 --- a/veilid-flutter/example/lib/app.dart +++ b/veilid-flutter/example/lib/app.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -97,11 +98,11 @@ class _MyAppState extends State with UiLoggy { if (update is VeilidLog) { await processLog(update); } else if (update is VeilidAppMessage) { - loggy.info("AppMessage: ${update.json}"); + loggy.info("AppMessage: ${jsonEncode(update)}"); } else if (update is VeilidAppCall) { - loggy.info("AppCall: ${update.json}"); + loggy.info("AppCall: ${jsonEncode(update)}"); } else { - loggy.trace("Update: ${update.json}"); + loggy.trace("Update: ${jsonEncode(update)}"); } } } diff --git a/veilid-flutter/example/lib/veilid_init.dart b/veilid-flutter/example/lib/veilid_init.dart index 7d0f8fb3..a7d6b5b7 100644 --- a/veilid-flutter/example/lib/veilid_init.dart +++ b/veilid-flutter/example/lib/veilid_init.dart @@ -14,7 +14,7 @@ void veilidInit() { logsInConsole: false), api: VeilidWASMConfigLoggingApi( enabled: true, level: VeilidConfigLogLevel.info))); - Veilid.instance.initializeVeilidCore(platformConfig.json); + Veilid.instance.initializeVeilidCore(platformConfig.toJson()); } else { var platformConfig = VeilidFFIConfig( logging: VeilidFFIConfigLogging( @@ -29,6 +29,6 @@ void veilidInit() { serviceName: "VeilidExample"), api: VeilidFFIConfigLoggingApi( enabled: true, level: VeilidConfigLogLevel.info))); - Veilid.instance.initializeVeilidCore(platformConfig.json); + Veilid.instance.initializeVeilidCore(platformConfig.toJson()); } } diff --git a/veilid-flutter/lib/routing_context.dart b/veilid-flutter/lib/routing_context.dart index 7fc15526..6d7345b4 100644 --- a/veilid-flutter/lib/routing_context.dart +++ b/veilid-flutter/lib/routing_context.dart @@ -33,7 +33,7 @@ abstract class DHTSchema { } } } - Map get json; + Map toJson(); } class DHTSchemaDFLT implements DHTSchema { @@ -49,7 +49,7 @@ class DHTSchemaDFLT implements DHTSchema { } @override - Map get json { + Map toJson() { return { 'kind': "DFLT", 'o_cnt': oCnt, @@ -71,7 +71,7 @@ class DHTSchemaMember { } } - Map get json { + Map toJson() { return { 'm_key': mKey, 'm_cnt': mCnt, @@ -97,11 +97,11 @@ class DHTSchemaSMPL implements DHTSchema { } } @override - Map get json { + Map toJson() { return { 'kind': "SMPL", 'o_cnt': oCnt, - 'members': members.map((p) => p.json).toList(), + 'members': members.map((p) => p.toJson()).toList(), }; } } @@ -122,12 +122,12 @@ class DHTRecordDescriptor { required this.schema, }); - Map get json { + Map toJson() { return { 'key': key.toString(), 'owner': owner, 'owner_secret': ownerSecret, - 'schema': schema.json, + 'schema': schema.toJson(), }; } @@ -168,7 +168,7 @@ class ValueSubkeyRange { } } - List get json { + List toJson() { return [low, high]; } } @@ -192,7 +192,7 @@ class ValueData { data = base64UrlNoPadDecode(json['data']), writer = json['writer']; - Map get json { + Map toJson() { return {'seq': seq, 'data': base64UrlNoPadEncode(data), 'writer': writer}; } } @@ -205,7 +205,7 @@ enum Stability { } extension StabilityExt on Stability { - String get json { + String toJson() { return name.toPascalCase(); } } @@ -224,7 +224,7 @@ enum Sequencing { } extension SequencingExt on Sequencing { - String get json { + String toJson() { return name.toPascalCase(); } } @@ -245,7 +245,7 @@ class RouteBlob { : routeId = json['route_id'], blob = base64UrlNoPadDecode(json['blob']); - Map get json { + Map toJson() { return {'route_id': routeId, 'blob': base64UrlNoPadEncode(blob)}; } } diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index e716b22b..f6e1e78d 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -36,16 +36,29 @@ Object? veilidApiToEncodable(Object? value) { return value; } switch (value.runtimeType) { - case AttachmentState: - return (value as AttachmentState).json; - case VeilidLogLevel: - return (value as VeilidLogLevel).json; - case VeilidConfigLogLevel: - return (value as VeilidConfigLogLevel).json; + // case KeyPair: + // return (value as KeyPair).json; } throw UnsupportedError('Cannot convert to JSON: $value'); } +T? Function(dynamic) optFromJson(T Function(dynamic) jsonConstructor) { + return (dynamic j) { + if (j == null) { + return null; + } else { + return jsonConstructor(j); + } + }; +} + +List Function(dynamic) jsonListConstructor( + T Function(dynamic) jsonConstructor) { + return (dynamic j) { + return (j as List).map((e) => jsonConstructor(e)).toList(); + }; +} + ////////////////////////////////////// /// VeilidVersion @@ -71,8 +84,7 @@ class Timestamp { Timestamp.fromString(String s) : value = BigInt.parse(s); Timestamp.fromJson(dynamic json) : this.fromString(json as String); - - String get json { + String toJson() { return toString(); } @@ -97,8 +109,7 @@ class TimestampDuration { TimestampDuration.fromString(String s) : value = BigInt.parse(s); TimestampDuration.fromJson(dynamic json) : this.fromString(json as String); - - String get json { + String toJson() { return toString(); } diff --git a/veilid-flutter/lib/veilid_config.dart b/veilid-flutter/lib/veilid_config.dart index 7f5d0787..176fe2b3 100644 --- a/veilid-flutter/lib/veilid_config.dart +++ b/veilid-flutter/lib/veilid_config.dart @@ -20,7 +20,7 @@ enum VeilidConfigLogLevel { } extension VeilidConfigLogLevelExt on VeilidConfigLogLevel { - String get json { + String toJson() { return name.toPascalCase(); } } @@ -45,7 +45,7 @@ class VeilidConfigHTTPS { this.url, }); - Map get json { + Map toJson() { return { 'enabled': enabled, 'listen_address': listenAddress, @@ -76,7 +76,7 @@ class VeilidConfigHTTP { this.url, }); - Map get json { + Map toJson() { return { 'enabled': enabled, 'listen_address': listenAddress, @@ -103,10 +103,10 @@ class VeilidConfigApplication { required this.http, }); - Map get json { + Map toJson() { return { - 'https': https.json, - 'http': http.json, + 'https': https.toJson(), + 'http': http.toJson(), }; } @@ -129,7 +129,7 @@ class VeilidConfigUDP { required this.listenAddress, this.publicAddress}); - Map get json { + Map toJson() { return { 'enabled': enabled, 'socket_pool_size': socketPoolSize, @@ -161,7 +161,7 @@ class VeilidConfigTCP { required this.listenAddress, this.publicAddress}); - Map get json { + Map toJson() { return { 'connect': connect, 'listen': listen, @@ -197,7 +197,7 @@ class VeilidConfigWS { required this.path, this.url}); - Map get json { + Map toJson() { return { 'connect': connect, 'listen': listen, @@ -235,7 +235,7 @@ class VeilidConfigWSS { required this.path, this.url}); - Map get json { + Map toJson() { return { 'connect': connect, 'listen': listen, @@ -270,12 +270,12 @@ class VeilidConfigProtocol { required this.wss, }); - Map get json { + Map toJson() { return { - 'udp': udp.json, - 'tcp': tcp.json, - 'ws': ws.json, - 'wss': wss.json, + 'udp': udp.toJson(), + 'tcp': tcp.toJson(), + 'ws': ws.toJson(), + 'wss': wss.toJson(), }; } @@ -299,7 +299,7 @@ class VeilidConfigTLS { required this.connectionInitialTimeoutMs, }); - Map get json { + Map toJson() { return { 'certificate_path': certificatePath, 'private_key_path': privateKeyPath, @@ -357,7 +357,7 @@ class VeilidConfigDHT { required this.remoteMaxSubkeyCacheMemoryMb, required this.remoteMaxStorageSpaceMb}); - Map get json { + Map toJson() { return { 'max_find_node_count': maxFindNodeCount, 'resolve_node_timeout_ms': resolveNodeTimeoutMs, @@ -425,7 +425,7 @@ class VeilidConfigRPC { required this.maxRouteHopCount, required this.defaultRouteHopCount}); - Map get json { + Map toJson() { return { 'concurrency': concurrency, 'queue_size': queueSize, @@ -470,10 +470,10 @@ class VeilidConfigRoutingTable { required this.limitAttachedWeak, }); - Map get json { + Map toJson() { return { - 'node_id': nodeId.map((p) => p.json).toList(), - 'node_id_secret': nodeIdSecret.map((p) => p.json).toList(), + 'node_id': nodeId.map((p) => p.toJson()).toList(), + 'node_id_secret': nodeIdSecret.map((p) => p.toJson()).toList(), 'bootstrap': bootstrap.map((p) => p).toList(), 'limit_over_attached': limitOverAttached, 'limit_fully_attached': limitFullyAttached, @@ -539,7 +539,7 @@ class VeilidConfigNetwork { required this.protocol, }); - Map get json { + Map toJson() { return { 'connection_initial_timeout_ms': connectionInitialTimeoutMs, 'connection_inactivity_timeout_ms': connectionInactivityTimeoutMs, @@ -550,15 +550,15 @@ class VeilidConfigNetwork { 'client_whitelist_timeout_ms': clientWhitelistTimeoutMs, 'reverse_connection_receipt_time_ms': reverseConnectionReceiptTimeMs, 'hole_punch_receipt_time_ms': holePunchReceiptTimeMs, - 'routing_table': routingTable.json, - 'rpc': rpc.json, - 'dht': dht.json, + 'routing_table': routingTable.toJson(), + 'rpc': rpc.toJson(), + 'dht': dht.toJson(), 'upnp': upnp, 'detect_address_changes': detectAddressChanges, 'restricted_nat_retries': restrictedNatRetries, - 'tls': tls.json, - 'application': application.json, - 'protocol': protocol.json, + 'tls': tls.toJson(), + 'application': application.toJson(), + 'protocol': protocol.toJson(), }; } @@ -597,7 +597,7 @@ class VeilidConfigTableStore { required this.delete, }); - Map get json { + Map toJson() { return {'directory': directory, 'delete': delete}; } @@ -617,7 +617,7 @@ class VeilidConfigBlockStore { required this.delete, }); - Map get json { + Map toJson() { return {'directory': directory, 'delete': delete}; } @@ -641,7 +641,7 @@ class VeilidConfigProtectedStore { required this.delete, }); - Map get json { + Map toJson() { return { 'allow_insecure_fallback': allowInsecureFallback, 'always_use_insecure_storage': alwaysUseInsecureStorage, @@ -678,7 +678,7 @@ class VeilidConfigCapabilities { required this.protocolAcceptWSS, }); - Map get json { + Map toJson() { return { 'protocol_udp': protocolUDP, 'protocol_connect_tcp': protocolConnectTCP, @@ -721,15 +721,15 @@ class VeilidConfig { required this.network, }); - Map get json { + Map toJson() { return { 'program_name': programName, 'namespace': namespace, - 'capabilities': capabilities.json, - 'protected_store': protectedStore.json, - 'table_store': tableStore.json, - 'block_store': blockStore.json, - 'network': network.json + 'capabilities': capabilities.toJson(), + 'protected_store': protectedStore.toJson(), + 'table_store': tableStore.toJson(), + 'block_store': blockStore.toJson(), + 'network': network.toJson() }; } diff --git a/veilid-flutter/lib/veilid_crypto.dart b/veilid-flutter/lib/veilid_crypto.dart index 40be7f74..9f90ed39 100644 --- a/veilid-flutter/lib/veilid_crypto.dart +++ b/veilid-flutter/lib/veilid_crypto.dart @@ -55,7 +55,7 @@ class Typed { value = EncodedString.fromString(parts.sublist(1).join(":")); } - String get json { + String toJson() { return toString(); } @@ -83,7 +83,7 @@ class KeyPair { secret = PublicKey(parts[1]); } - String get json { + String toJson() { return toString(); } @@ -114,7 +114,7 @@ class TypedKeyPair { secret = PublicKey(parts[2]); } - String get json { + String toJson() { return toString(); } diff --git a/veilid-flutter/lib/veilid_encoding.dart b/veilid-flutter/lib/veilid_encoding.dart index f2746da9..9d56b58d 100644 --- a/veilid-flutter/lib/veilid_encoding.dart +++ b/veilid-flutter/lib/veilid_encoding.dart @@ -70,7 +70,7 @@ class FixedEncodedString32 extends EncodedString { return 24; } - String get json { + String toJson() { return toString(); } @@ -89,7 +89,7 @@ class FixedEncodedString43 extends EncodedString { return 32; } - String get json { + String toJson() { return toString(); } @@ -108,7 +108,7 @@ class FixedEncodedString86 extends EncodedString { return 64; } - String get json { + String toJson() { return toString(); } diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index a1c352ca..1ad56fa4 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -22,10 +22,10 @@ class VeilidFFIConfigLoggingTerminal { required this.level, }); - Map get json { + Map toJson() { return { 'enabled': enabled, - 'level': level.json, + 'level': level.toJson(), }; } @@ -47,10 +47,10 @@ class VeilidFFIConfigLoggingOtlp { required this.serviceName, }); - Map get json { + Map toJson() { return { 'enabled': enabled, - 'level': level.json, + 'level': level.toJson(), 'grpc_endpoint': grpcEndpoint, 'service_name': serviceName, }; @@ -72,10 +72,10 @@ class VeilidFFIConfigLoggingApi { required this.level, }); - Map get json { + Map toJson() { return { 'enabled': enabled, - 'level': level.json, + 'level': level.toJson(), }; } @@ -92,11 +92,11 @@ class VeilidFFIConfigLogging { VeilidFFIConfigLogging( {required this.terminal, required this.otlp, required this.api}); - Map get json { + Map toJson() { return { - 'terminal': terminal.json, - 'otlp': otlp.json, - 'api': api.json, + 'terminal': terminal.toJson(), + 'otlp': otlp.toJson(), + 'api': api.toJson(), }; } @@ -113,9 +113,9 @@ class VeilidFFIConfig { required this.logging, }); - Map get json { + Map toJson() { return { - 'logging': logging.json, + 'logging': logging.toJson(), }; } @@ -221,9 +221,9 @@ typedef _RoutingContextSetDHTValueDart = void Function( int, int, Pointer, int, Pointer); // fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: FfiStr, count: u32) typedef _RoutingContextWatchDHTValuesC = Void Function( - Int64, Uint32, Pointer, Pointer, Pointer, Uint32); + Int64, Uint32, Pointer, Pointer, Uint64, Uint32); typedef _RoutingContextWatchDHTValuesDart = void Function( - int, int, Pointer, Pointer, Pointer, int); + int, int, Pointer, Pointer, int, int); // fn routing_context_cancel_dht_watch(port: i64, id: u32, key: FfiStr, subkeys: FfiStr) typedef _RoutingContextCancelDHTWatchC = Void Function( Int64, Uint32, Pointer, Pointer); @@ -652,14 +652,14 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext { @override VeilidRoutingContextFFI withCustomPrivacy(Stability stability) { final newId = _ctx.ffi._routingContextWithCustomPrivacy( - _ctx.id, stability.json.toNativeUtf8()); + _ctx.id, jsonEncode(stability).toNativeUtf8()); return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi)); } @override VeilidRoutingContextFFI withSequencing(Sequencing sequencing) { - final newId = _ctx.ffi - ._routingContextWithSequencing(_ctx.id, sequencing.json.toNativeUtf8()); + final newId = _ctx.ffi._routingContextWithSequencing( + _ctx.id, jsonEncode(sequencing).toNativeUtf8()); return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi)); } @@ -677,7 +677,7 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext { } @override - Future appMessage(String target, Uint8List message) async { + Future appMessage(String target, Uint8List message) { final nativeEncodedTarget = target.toNativeUtf8(); final nativeEncodedMessage = base64UrlNoPadEncode(message).toNativeUtf8(); @@ -687,6 +687,111 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext { nativeEncodedTarget, nativeEncodedMessage); return processFutureVoid(recvPort.first); } + + @override + Future createDHTRecord( + CryptoKind kind, DHTSchema schema) async { + final nativeSchema = jsonEncode(schema).toNativeUtf8(); + final recvPort = ReceivePort("routing_context_create_dht_record"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextCreateDHTRecord( + sendPort.nativePort, _ctx.id, kind, nativeSchema); + final dhtRecordDescriptor = + await processFutureJson(DHTRecordDescriptor.fromJson, recvPort.first); + return dhtRecordDescriptor; + } + + @override + Future openDHTRecord( + TypedKey key, KeyPair? writer) async { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final nativeWriter = + writer != null ? jsonEncode(key).toNativeUtf8() : nullptr; + final recvPort = ReceivePort("routing_context_open_dht_record"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextOpenDHTRecord( + sendPort.nativePort, _ctx.id, nativeKey, nativeWriter); + final dhtRecordDescriptor = + await processFutureJson(DHTRecordDescriptor.fromJson, recvPort.first); + return dhtRecordDescriptor; + } + + @override + Future closeDHTRecord(TypedKey key) { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final recvPort = ReceivePort("routing_context_close_dht_record"); + final sendPort = recvPort.sendPort; + _ctx.ffi + ._routingContextCloseDHTRecord(sendPort.nativePort, _ctx.id, nativeKey); + return processFutureVoid(recvPort.first); + } + + @override + Future deleteDHTRecord(TypedKey key) { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final recvPort = ReceivePort("routing_context_delete_dht_record"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextDeleteDHTRecord( + sendPort.nativePort, _ctx.id, nativeKey); + return processFutureVoid(recvPort.first); + } + + @override + Future getDHTValue( + TypedKey key, int subkey, bool forceRefresh) async { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final recvPort = ReceivePort("routing_context_get_dht_value"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextGetDHTValue( + sendPort.nativePort, _ctx.id, nativeKey, subkey, forceRefresh); + final valueData = await processFutureJson( + optFromJson(ValueData.fromJson), recvPort.first); + return valueData; + } + + @override + Future setDHTValue( + TypedKey key, int subkey, Uint8List data) async { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final nativeData = base64UrlNoPadEncode(data).toNativeUtf8(); + + final recvPort = ReceivePort("routing_context_set_dht_value"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextSetDHTValue( + sendPort.nativePort, _ctx.id, nativeKey, subkey, nativeData); + final valueData = await processFutureJson( + optFromJson(ValueData.fromJson), recvPort.first); + return valueData; + } + + @override + Future watchDHTValues(TypedKey key, ValueSubkeyRange subkeys, + Timestamp expiration, int count) async { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8(); + final nativeExpiration = expiration.value.toInt(); + + final recvPort = ReceivePort("routing_context_watch_dht_values"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextWatchDHTValues(sendPort.nativePort, _ctx.id, + nativeKey, nativeSubkeys, nativeExpiration, count); + final actualExpiration = Timestamp( + value: BigInt.from(await processFuturePlain(recvPort.first))); + return actualExpiration; + } + + @override + Future cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys) async { + final nativeKey = jsonEncode(key).toNativeUtf8(); + final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8(); + + final recvPort = ReceivePort("routing_context_cancel_dht_watch"); + final sendPort = recvPort.sendPort; + _ctx.ffi._routingContextCancelDHTWatch( + sendPort.nativePort, _ctx.id, nativeKey, nativeSubkeys); + final cancelled = await processFuturePlain(recvPort.first); + return cancelled; + } } class _TDBT { @@ -853,6 +958,56 @@ class VeilidTableDBFFI extends VeilidTableDB { } } +// FFI implementation of VeilidCryptoSystem +class VeilidCryptoSystemFFI implements VeilidCryptoSystem { + final CryptoKind _kind; + + VeilidCryptoSystemFFI._(this._kind); + + @override + CryptoKind kind() { + return _kind; + } + + @override + Future cachedDH(PublicKey key, SecretKey secret) {} + @override + Future computeDH(PublicKey key, SecretKey secret) {} + @override + Future randomNonce() {} + @override + Future randomSharedSecret() {} + @override + Future generateKeyPair() {} + @override + Future generateHash(Uint8List data) {} + @override + Future generateHashReader(Stream> reader) {} + @override + Future validateKeyPair(PublicKey key, SecretKey secret) {} + @override + Future validateHash(Uint8List data, HashDigest hash) {} + @override + Future validateHashReader(Stream> reader, HashDigest hash) {} + @override + Future distance(CryptoKey key1, CryptoKey key2) {} + @override + Future sign(PublicKey key, SecretKey secret, Uint8List data) {} + @override + Future verify(PublicKey key, Uint8List data, Signature signature) {} + @override + Future aeadOverhead() {} + @override + Future decryptAead(Uint8List body, Nonce nonce, + SharedSecret sharedSecret, Uint8List? associatedData) {} + @override + Future encryptAead(Uint8List body, Nonce nonce, + SharedSecret sharedSecret, Uint8List? associatedData) {} + @override + Future cryptNoAuth( + Uint8List body, Nonce nonce, SharedSecret sharedSecret) {} +} + // FFI implementation of high level Veilid API class VeilidFFI implements Veilid { // veilid_core shared library @@ -1054,31 +1209,63 @@ class VeilidFFI implements Veilid { _tableDbTransactionDelete = dylib.lookupFunction< _TableDbTransactionDeleteC, _TableDbTransactionDeleteDart>('table_db_transaction_delete'), - -xxx - final _ValidCryptoKindsDart _validCryptoKinds; - final _BestCryptoKindDart _bestCryptoKind; - final _VerifySignaturesDart _verifySignatures; - final _GenerateSignaturesDart _generateSignatures; - final _GenerateKeyPairDart _generateKeyPair; - - final _CryptoCachedDHDart _cryptoCachedDH; - final _CryptoComputeDHDart _cryptoComputeDH; - final _CryptoRandomNonceDart _cryptoRandomNonce; - final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; - final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; - final _CryptoGenerateHashDart _cryptoGenerateHash; - final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; - final _CryptoValidateHashDart _cryptoValidateHash; - final _CryptoDistanceDart _cryptoDistance; - final _CryptoSignDart _cryptoSign; - final _CryptoVerifyDart _cryptoVerify; - final _CryptoAeadOverheadDart _cryptoAeadOverhead; - final _CryptoDecryptAeadDart _cryptoDecryptAead; - final _CryptoEncryptAeadDart _cryptoEncryptAead; - final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; - - + _validCryptoKinds = + dylib.lookupFunction<_ValidCryptoKindsC, _ValidCryptoKindsDart>( + 'valid_crypto_kinds'), + _bestCryptoKind = + dylib.lookupFunction<_BestCryptoKindC, _BestCryptoKindDart>( + 'best_crypto_kind'), + _verifySignatures = + dylib.lookupFunction<_VerifySignaturesC, _VerifySignaturesDart>( + 'verify_signatures'), + _generateSignatures = + dylib.lookupFunction<_GenerateSignaturesC, _GenerateSignaturesDart>( + 'generate_signatures'), + _generateKeyPair = + dylib.lookupFunction<_GenerateKeyPairC, _GenerateKeyPairDart>( + 'generate_key_pair'), + _cryptoCachedDH = + dylib.lookupFunction<_CryptoCachedDHC, _CryptoCachedDHDart>( + 'crypto_cached_dh'), + _cryptoComputeDH = + dylib.lookupFunction<_CryptoComputeDHC, _CryptoComputeDHDart>( + 'crypto_compute_dh'), + _cryptoRandomNonce = + dylib.lookupFunction<_CryptoRandomNonceC, _CryptoRandomNonceDart>( + 'crypto_random_nonce'), + _cryptoRandomSharedSecret = dylib.lookupFunction< + _CryptoRandomSharedSecretC, + _CryptoRandomSharedSecretDart>('crypto_random_shared_secret'), + _cryptoGenerateKeyPair = dylib.lookupFunction<_CryptoGenerateKeyPairC, + _CryptoGenerateKeyPairDart>('crypto_generate_key_pair'), + _cryptoGenerateHash = + dylib.lookupFunction<_CryptoGenerateHashC, _CryptoGenerateHashDart>( + 'crypto_generate_hash'), + _cryptoValidateKeyPair = dylib.lookupFunction<_CryptoValidateKeyPairC, + _CryptoValidateKeyPairDart>('crypto_validate_key_pair'), + _cryptoValidateHash = + dylib.lookupFunction<_CryptoValidateHashC, _CryptoValidateHashDart>( + 'crypto_validate_hash'), + _cryptoDistance = + dylib.lookupFunction<_CryptoDistanceC, _CryptoDistanceDart>( + 'crypto_distance'), + _cryptoSign = + dylib.lookupFunction<_CryptoSignC, _CryptoSignDart>('crypto_sign'), + _cryptoVerify = dylib + .lookupFunction<_CryptoVerifyC, _CryptoVerifyDart>('crypto_verify'), + _cryptoAeadOverhead = + dylib.lookupFunction<_CryptoAeadOverheadC, _CryptoAeadOverheadDart>( + 'crypto_aead_overhead'), + _cryptoDecryptAead = + dylib.lookupFunction<_CryptoDecryptAeadC, _CryptoDecryptAeadDart>( + 'crypto_decrypt_aead'), + _cryptoEncryptAead = + dylib.lookupFunction<_CryptoEncryptAeadC, _CryptoEncryptAeadDart>( + 'crypto_encrypt_aead'), + _cryptoCryptNoAuth = + dylib.lookupFunction<_CryptoCryptNoAuthC, _CryptoCryptNoAuthDart>( + 'crypto_crypt_no_auth'), + _now = dylib.lookupFunction<_NowC, _NowDart>('now'), _debug = dylib.lookupFunction<_DebugC, _DebugDart>('debug'), _veilidVersionString = dylib.lookupFunction<_VeilidVersionStringC, _VeilidVersionStringDart>('veilid_version_string'), @@ -1094,9 +1281,7 @@ xxx @override void initializeVeilidCore(Map platformConfigJson) { - var nativePlatformConfig = - jsonEncode(platformConfigJson, toEncodable: veilidApiToEncodable) - .toNativeUtf8(); + var nativePlatformConfig = jsonEncode(platformConfigJson).toNativeUtf8(); _initializeVeilidCore(nativePlatformConfig); @@ -1105,9 +1290,7 @@ xxx @override void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) { - var nativeLogLevel = - jsonEncode(logLevel.json, toEncodable: veilidApiToEncodable) - .toNativeUtf8(); + var nativeLogLevel = jsonEncode(logLevel).toNativeUtf8(); var nativeLayer = layer.toNativeUtf8(); _changeLogLevel(nativeLayer, nativeLogLevel); malloc.free(nativeLayer); @@ -1116,9 +1299,7 @@ xxx @override Future> startupVeilidCore(VeilidConfig config) { - var nativeConfig = - jsonEncode(config.json, toEncodable: veilidApiToEncodable) - .toNativeUtf8(); + var nativeConfig = jsonEncode(config).toNativeUtf8(); final recvStreamPort = ReceivePort("veilid_api_stream"); final sendStreamPort = recvStreamPort.sendPort; final recvPort = ReceivePort("startup_veilid_core"); @@ -1185,8 +1366,10 @@ xxx Stability stability, Sequencing sequencing) async { final recvPort = ReceivePort("new_custom_private_route"); final sendPort = recvPort.sendPort; - _newCustomPrivateRoute(sendPort.nativePort, stability.json.toNativeUtf8(), - sequencing.json.toNativeUtf8()); + _newCustomPrivateRoute( + sendPort.nativePort, + jsonEncode(stability).toNativeUtf8(), + jsonEncode(sequencing).toNativeUtf8()); final routeBlob = await processFutureJson(RouteBlob.fromJson, recvPort.first); return routeBlob; @@ -1240,6 +1423,48 @@ xxx return deleted; } + @override + List validCryptoKinds() { + final vckString = _validCryptoKinds(); + final vck = jsonDecode(vckString.toDartString()); + _freeString(vckString); + return vck; + } + + @override + Future getCryptoSystem(CryptoKind kind) async { + if (!validCryptoKinds().contains(kind)) { + throw VeilidAPIExceptionGeneric("unsupported cryptosystem"); + } + return VeilidCryptoSystemFFI._(kind); + } + + @override + Future bestCryptoSystem() async { + return VeilidCryptoSystemFFI._(_bestCryptoKind()); + } + + @override + Future> verifySignatures( + List nodeIds, Uint8List data, List signatures) { + final nativeNodeIds = jsonEncode(nodeIds).toNativeUtf8(); + final nativeData = base64UrlNoPadEncode(data).toNativeUtf8(); + final nativeSignatures = jsonEncode(signatures).toNativeUtf8(); + + final recvPort = ReceivePort("app_call_reply"); + final sendPort = recvPort.sendPort; + _verifySignatures( + sendPort.nativePort, nativeNodeIds, nativeData, nativeSignatures); + return processFutureJson( + jsonListConstructor(TypedKey.fromJson), recvPort.first); + } +xxx + @override + Future> generateSignatures( + Uint8List data, List keyPairs) {} + @override + Future generateKeyPair(CryptoKind kind) {} + @override Future debug(String command) async { var nativeCommand = command.toNativeUtf8(); diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index 0125236a..3cc9efc1 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -25,10 +25,10 @@ class VeilidWASMConfigLoggingPerformance { required this.logsInConsole, }); - Map get json { + Map toJson() { return { 'enabled': enabled, - 'level': level.json, + 'level': level.toJson(), 'logs_in_timings': logsInTimings, 'logs_in_console': logsInConsole, }; @@ -50,10 +50,10 @@ class VeilidWASMConfigLoggingApi { required this.level, }); - Map get json { + Map toJson() { return { 'enabled': enabled, - 'level': level.json, + 'level': level.toJson(), }; } @@ -68,10 +68,10 @@ class VeilidWASMConfigLogging { VeilidWASMConfigLogging({required this.performance, required this.api}); - Map get json { + Map toJson() { return { - 'performance': performance.json, - 'api': api.json, + 'performance': performance.toJson(), + 'api': api.toJson(), }; } @@ -88,9 +88,9 @@ class VeilidWASMConfig { required this.logging, }); - Map get json { + Map toJson() { return { - 'logging': logging.json, + 'logging': logging.toJson(), }; } @@ -137,15 +137,17 @@ class VeilidRoutingContextJS implements VeilidRoutingContext { @override VeilidRoutingContextJS withCustomPrivacy(Stability stability) { final newId = js_util.callMethod( - wasm, "routing_context_with_custom_privacy", [_ctx.id, stability.json]); + wasm, + "routing_context_with_custom_privacy", + [_ctx.id, jsonEncode(stability)]); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); } @override VeilidRoutingContextJS withSequencing(Sequencing sequencing) { - final newId = js_util.callMethod( - wasm, "routing_context_with_sequencing", [_ctx.id, sequencing.json]); + final newId = js_util.callMethod(wasm, "routing_context_with_sequencing", + [_ctx.id, jsonEncode(sequencing)]); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); } @@ -292,16 +294,14 @@ class VeilidTableDBJS extends VeilidTableDB { class VeilidJS implements Veilid { @override void initializeVeilidCore(Map platformConfigJson) { - var platformConfigJsonString = - jsonEncode(platformConfigJson, toEncodable: veilidApiToEncodable); + var platformConfigJsonString = jsonEncode(platformConfigJson); js_util .callMethod(wasm, "initialize_veilid_core", [platformConfigJsonString]); } @override void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) { - var logLevelJsonString = - jsonEncode(logLevel.json, toEncodable: veilidApiToEncodable); + var logLevelJsonString = jsonEncode(logLevel); js_util.callMethod(wasm, "change_log_level", [layer, logLevelJsonString]); } @@ -318,10 +318,8 @@ class VeilidJS implements Veilid { } } - await _wrapApiPromise(js_util.callMethod(wasm, "startup_veilid_core", [ - js.allowInterop(updateCallback), - jsonEncode(config.json, toEncodable: veilidApiToEncodable) - ])); + await _wrapApiPromise(js_util.callMethod(wasm, "startup_veilid_core", + [js.allowInterop(updateCallback), jsonEncode(config)])); return streamController.stream; } @@ -365,10 +363,8 @@ class VeilidJS implements Veilid { @override Future newCustomPrivateRoute( Stability stability, Sequencing sequencing) async { - var stabilityString = - jsonEncode(stability, toEncodable: veilidApiToEncodable); - var sequencingString = - jsonEncode(sequencing, toEncodable: veilidApiToEncodable); + var stabilityString = jsonEncode(stability); + var sequencingString = jsonEncode(sequencing); Map blobJson = jsonDecode(await _wrapApiPromise(js_util .callMethod( diff --git a/veilid-flutter/lib/veilid_state.dart b/veilid-flutter/lib/veilid_state.dart index a1248f3f..39142d20 100644 --- a/veilid-flutter/lib/veilid_state.dart +++ b/veilid-flutter/lib/veilid_state.dart @@ -20,7 +20,7 @@ enum AttachmentState { } extension AttachmentStateExt on AttachmentState { - String get json { + String toJson() { return name.toPascalCase(); } } @@ -41,7 +41,7 @@ enum VeilidLogLevel { } extension VeilidLogLevelExt on VeilidLogLevel { - String get json { + String toJson() { return name.toPascalCase(); } } @@ -63,11 +63,11 @@ class LatencyStats { required this.slowest, }); - Map get json { + Map toJson() { return { - 'fastest': fastest.json, - 'average': average.json, - 'slowest': slowest.json, + 'fastest': fastest.toJson(), + 'average': average.toJson(), + 'slowest': slowest.toJson(), }; } @@ -92,7 +92,7 @@ class TransferStats { required this.minimum, }); - Map get json { + Map toJson() { return { 'total': total.toString(), 'maximum': maximum.toString(), @@ -119,10 +119,10 @@ class TransferStatsDownUp { required this.up, }); - Map get json { + Map toJson() { return { - 'down': down.json, - 'up': up.json, + 'down': down.toJson(), + 'up': up.toJson(), }; } @@ -154,14 +154,14 @@ class RPCStats { required this.failedToSend, }); - Map get json { + Map toJson() { return { 'messages_sent': messagesSent, 'messages_rcvd': messagesRcvd, 'questions_in_flight': questionsInFlight, - 'last_question': lastQuestion?.json, - 'last_seen_ts': lastSeenTs?.json, - 'first_consecutive_seen_ts': firstConsecutiveSeenTs?.json, + 'last_question': lastQuestion?.toJson(), + 'last_seen_ts': lastSeenTs?.toJson(), + 'first_consecutive_seen_ts': firstConsecutiveSeenTs?.toJson(), 'recent_lost_answers': recentLostAnswers, 'failed_to_send': failedToSend, }; @@ -199,12 +199,12 @@ class PeerStats { required this.transfer, }); - Map get json { + Map toJson() { return { - 'time_added': timeAdded.json, - 'rpc_stats': rpcStats.json, - 'latency': latency?.json, - 'transfer': transfer.json, + 'time_added': timeAdded.toJson(), + 'rpc_stats': rpcStats.toJson(), + 'latency': latency?.toJson(), + 'transfer': transfer.toJson(), }; } @@ -230,11 +230,11 @@ class PeerTableData { required this.peerStats, }); - Map get json { + Map toJson() { return { - 'node_ids': nodeIds.map((p) => p.json).toList(), - 'peer_address': peerAddress.json, - 'peer_stats': peerStats.json, + 'node_ids': nodeIds.map((p) => p.toJson()).toList(), + 'peer_address': peerAddress.toJson(), + 'peer_stats': peerStats.toJson(), }; } @@ -256,7 +256,7 @@ enum ProtocolType { } extension ProtocolTypeExt on ProtocolType { - String get json { + String toJson() { return name.toUpperCase(); } } @@ -276,9 +276,9 @@ class PeerAddress { required this.socketAddress, }); - Map get json { + Map toJson() { return { - 'protocol_type': protocolType.json, + 'protocol_type': protocolType.toJson(), 'socket_address': socketAddress, }; } @@ -347,7 +347,7 @@ abstract class VeilidUpdate { } } } - Map get json; + Map toJson(); } class VeilidLog implements VeilidUpdate { @@ -362,10 +362,10 @@ class VeilidLog implements VeilidUpdate { }); @override - Map get json { + Map toJson() { return { 'kind': "Log", - 'log_level': logLevel.json, + 'log_level': logLevel.toJson(), 'message': message, 'backtrace': backtrace }; @@ -383,7 +383,7 @@ class VeilidAppMessage implements VeilidUpdate { }); @override - Map get json { + Map toJson() { return { 'kind': "AppMessage", 'sender': sender, @@ -405,7 +405,7 @@ class VeilidAppCall implements VeilidUpdate { }); @override - Map get json { + Map toJson() { return { 'kind': "AppMessage", 'sender': sender, @@ -421,8 +421,8 @@ class VeilidUpdateAttachment implements VeilidUpdate { VeilidUpdateAttachment({required this.state}); @override - Map get json { - var jsonRep = state.json; + Map toJson() { + var jsonRep = state.toJson(); jsonRep['kind'] = "Attachment"; return jsonRep; } @@ -434,8 +434,8 @@ class VeilidUpdateNetwork implements VeilidUpdate { VeilidUpdateNetwork({required this.state}); @override - Map get json { - var jsonRep = state.json; + Map toJson() { + var jsonRep = state.toJson(); jsonRep['kind'] = "Network"; return jsonRep; } @@ -447,8 +447,8 @@ class VeilidUpdateConfig implements VeilidUpdate { VeilidUpdateConfig({required this.state}); @override - Map get json { - var jsonRep = state.json; + Map toJson() { + var jsonRep = state.toJson(); jsonRep['kind'] = "Config"; return jsonRep; } @@ -464,7 +464,7 @@ class VeilidUpdateRouteChange implements VeilidUpdate { }); @override - Map get json { + Map toJson() { return { 'dead_routes': deadRoutes.map((p) => p).toList(), 'dead_remote_routes': deadRemoteRoutes.map((p) => p).toList() @@ -487,12 +487,12 @@ class VeilidUpdateValueChange implements VeilidUpdate { }); @override - Map get json { + Map toJson() { return { - 'key': key.json, - 'subkeys': subkeys.map((p) => p.json).toList(), + 'key': key.toJson(), + 'subkeys': subkeys.map((p) => p.toJson()).toList(), 'count': count, - 'value_data': valueData.json, + 'value_data': valueData.toJson(), }; } } @@ -513,9 +513,9 @@ class VeilidStateAttachment { publicInternetReady = json['public_internet_ready'], localNetworkReady = json['local_network_ready']; - Map get json { + Map toJson() { return { - 'state': state.json, + 'state': state.toJson(), 'public_internet_ready': publicInternetReady, 'local_network_ready': localNetworkReady, }; @@ -544,12 +544,12 @@ class VeilidStateNetwork { peers = List.from( json['peers'].map((j) => PeerTableData.fromJson(j))); - Map get json { + Map toJson() { return { 'started': started, 'bps_down': bpsDown.toString(), 'bps_up': bpsUp.toString(), - 'peers': peers.map((p) => p.json).toList(), + 'peers': peers.map((p) => p.toJson()).toList(), }; } } @@ -566,7 +566,7 @@ class VeilidStateConfig { VeilidStateConfig.fromJson(dynamic json) : config = json['config']; - Map get json { + Map toJson() { return {'config': config}; } } @@ -584,11 +584,11 @@ class VeilidState { network = VeilidStateNetwork.fromJson(json['network']), config = VeilidStateConfig.fromJson(json['config']); - Map get json { + Map toJson() { return { - 'attachment': attachment.json, - 'network': network.json, - 'config': config.json + 'attachment': attachment.toJson(), + 'network': network.toJson(), + 'config': config.toJson() }; } } diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index 3f341912..cd44552d 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -606,10 +606,10 @@ pub extern "C" fn routing_context_set_dht_value(port: i64, id: u32, key: FfiStr, #[no_mangle] -pub extern "C" fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: FfiStr, count: u32) { +pub extern "C" fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: u64, count: u32) { let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); let subkeys: veilid_core::ValueSubkeyRangeSet = veilid_core::deserialize_opt_json(subkeys.into_opt_string()).unwrap(); - let expiration = veilid_core::Timestamp::from_str(expiration.as_opt_str().unwrap()).unwrap(); + let expiration = veilid_core::Timestamp::from(expiration); DartIsolateWrapper::new(port).spawn_result(async move { let routing_context = { @@ -620,7 +620,7 @@ pub extern "C" fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiS routing_context.clone() }; let res = routing_context.watch_dht_values(key, subkeys, expiration, count).await?; - APIResult::Ok(res.to_string()) + APIResult::Ok(res.as_u64()) }); }