veilid/veilid-flutter/lib/veilid_ffi.dart

1653 lines
64 KiB
Dart
Raw Normal View History

2022-02-06 21:18:42 -05:00
import 'dart:async';
2023-07-26 14:20:17 -04:00
import 'dart:convert';
2022-02-09 09:47:36 -05:00
import 'dart:ffi';
2022-02-06 21:18:42 -05:00
import 'dart:io';
2022-02-09 09:47:36 -05:00
import 'dart:isolate';
2022-09-30 22:37:55 -04:00
import 'dart:typed_data';
2022-02-06 21:18:42 -05:00
import 'package:ffi/ffi.dart';
2022-02-09 09:47:36 -05:00
import 'veilid.dart';
2022-02-06 21:18:42 -05:00
//////////////////////////////////////////////////////////
// Load the veilid_flutter library once
const _base = 'veilid_flutter';
final _path = Platform.isWindows
? '$_base.dll'
: Platform.isMacOS
2022-12-03 20:10:33 -05:00
? 'lib$_base.dylib'
2022-02-06 21:18:42 -05:00
: 'lib$_base.so';
2022-11-16 12:49:53 -05:00
final _dylib =
2022-02-09 09:47:36 -05:00
Platform.isIOS ? DynamicLibrary.process() : DynamicLibrary.open(_path);
2022-02-06 21:18:42 -05:00
// Linkage for initialization
2022-02-13 21:09:43 -05:00
typedef _DartPostCObject
2022-02-09 09:47:36 -05:00
= NativeFunction<Int8 Function(Int64, Pointer<Dart_CObject>)>;
2022-02-06 21:18:42 -05:00
// fn free_string(s: *mut std::os::raw::c_char)
2022-02-13 21:09:43 -05:00
typedef _FreeStringDart = void Function(Pointer<Utf8>);
2022-02-06 21:18:42 -05:00
// fn initialize_veilid_flutter(dart_post_c_object_ptr: ffi::DartPostCObjectFnType)
2022-07-01 16:20:43 -04:00
// fn initialize_veilid_core(platform_config: FfiStr)
typedef _InitializeVeilidCoreDart = void Function(Pointer<Utf8>);
2022-07-01 12:13:52 -04:00
// fn change_log_level(layer: FfiStr, log_level: FfiStr)
typedef _ChangeLogLevelDart = void Function(Pointer<Utf8>, Pointer<Utf8>);
2022-02-06 21:18:42 -05:00
// fn startup_veilid_core(port: i64, config: FfiStr)
2022-09-09 16:27:13 -04:00
typedef _StartupVeilidCoreDart = void Function(int, int, Pointer<Utf8>);
2022-02-06 21:18:42 -05:00
// fn get_veilid_state(port: i64)
2022-02-13 21:09:43 -05:00
typedef _GetVeilidStateDart = void Function(int);
2022-09-06 18:59:41 -04:00
// fn attach(port: i64)
typedef _AttachDart = void Function(int);
// fn detach(port: i64)
typedef _DetachDart = void Function(int);
2022-11-26 14:16:02 -05:00
// fn routing_context(port: i64)
typedef _RoutingContextDart = void Function(int);
// fn release_routing_context(id: u32)
typedef _ReleaseRoutingContextDart = int Function(int);
// fn routing_context_with_privacy(id: u32) -> u32
typedef _RoutingContextWithPrivacyDart = int Function(int);
// fn routing_context_with_custom_privacy(id: u32, stability: FfiStr)
typedef _RoutingContextWithCustomPrivacyDart = int Function(int, Pointer<Utf8>);
// fn routing_context_with_sequencing(id: u32, sequencing: FfiStr)
typedef _RoutingContextWithSequencingDart = int Function(int, Pointer<Utf8>);
// fn routing_context_app_call(port: i64, id: u32, target: FfiStr, request: FfiStr)
typedef _RoutingContextAppCallDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn routing_context_app_message(port: i64, id: u32, target: FfiStr, request: FfiStr)
typedef _RoutingContextAppMessageDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
2023-05-29 15:24:57 -04:00
// fn routing_context_create_dht_record(port: i64, id: u32, kind: u32, schema: FfiStr)
typedef _RoutingContextCreateDHTRecordDart = void Function(
2023-07-08 22:50:44 -04:00
int, int, Pointer<Utf8>, int);
2023-05-29 15:24:57 -04:00
// fn routing_context_open_dht_record(port: i64, id: u32, key: FfiStr, writer: FfiStr)
typedef _RoutingContextOpenDHTRecordDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn routing_context_close_dht_record(port: i64, id: u32, key: FfiStr)
typedef _RoutingContextCloseDHTRecordDart = void Function(
int, int, Pointer<Utf8>);
// fn routing_context_delete_dht_record(port: i64, id: u32, key: FfiStr)
typedef _RoutingContextDeleteDHTRecordDart = void Function(
int, int, Pointer<Utf8>);
// fn routing_context_get_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, force_refresh: bool)
typedef _RoutingContextGetDHTValueDart = void Function(
int, int, Pointer<Utf8>, int, bool);
// fn routing_context_set_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, data: FfiStr)
typedef _RoutingContextSetDHTValueDart = void Function(
int, int, Pointer<Utf8>, int, Pointer<Utf8>);
// fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: FfiStr, count: u32)
typedef _RoutingContextWatchDHTValuesDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, int, int);
// fn routing_context_cancel_dht_watch(port: i64, id: u32, key: FfiStr, subkeys: FfiStr)
typedef _RoutingContextCancelDHTWatchDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
2022-11-26 14:16:02 -05:00
// fn new_private_route(port: i64)
typedef _NewPrivateRouteDart = void Function(int);
// fn new_custom_private_route(port: i64, stability: FfiStr, sequencing: FfiStr)
typedef _NewCustomPrivateRouteDart = void Function(
int, Pointer<Utf8>, Pointer<Utf8>);
// fn import_remote_private_route(port: i64, blob: FfiStr)
typedef _ImportRemotePrivateRouteDart = void Function(int, Pointer<Utf8>);
// fn release_private_route(port:i64, key: FfiStr)
typedef _ReleasePrivateRouteDart = void Function(int, Pointer<Utf8>);
2022-09-30 22:37:55 -04:00
// fn app_call_reply(port: i64, id: FfiStr, message: FfiStr)
typedef _AppCallReplyDart = void Function(int, Pointer<Utf8>, Pointer<Utf8>);
2022-12-28 22:53:58 -05:00
// fn open_table_db(port: i64, name: FfiStr, column_count: u32)
typedef _OpenTableDbDart = void Function(int, Pointer<Utf8>, int);
// fn release_table_db(id: u32) -> i32
typedef _ReleaseTableDbDart = int Function(int);
// fn delete_table_db(port: i64, name: FfiStr)
typedef _DeleteTableDbDart = void Function(int, Pointer<Utf8>);
// fn table_db_get_column_count(id: u32) -> u32
typedef _TableDbGetColumnCountDart = int Function(int);
2023-05-29 15:24:57 -04:00
// fn table_db_get_keys(port: i64, id: u32, col: u32)
typedef _TableDbGetKeysDart = Pointer<Utf8> Function(int, int, int);
2022-12-28 22:53:58 -05:00
// fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr)
typedef _TableDbStoreDart = void Function(
int, int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbLoadDart = void Function(int, int, int, Pointer<Utf8>);
// fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbDeleteDart = void Function(int, int, int, Pointer<Utf8>);
// fn table_db_transact(id: u32) -> u32
typedef _TableDbTransactDart = int Function(int);
// fn release_table_db_transaction(id: u32) -> i32
typedef _ReleaseTableDbTransactionDart = int Function(int);
// fn table_db_transaction_commit(port: i64, id: u32)
typedef _TableDbTransactionCommitDart = void Function(int, int);
// fn table_db_transaction_rollback(port: i64, id: u32)
typedef _TableDbTransactionRollbackDart = void Function(int, int);
// fn table_db_transaction_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr)
typedef _TableDbTransactionStoreDart = void Function(
int, int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn table_db_transaction_delete(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbTransactionDeleteDart = void Function(
int, int, int, Pointer<Utf8>);
2023-05-29 15:24:57 -04:00
// fn valid_crypto_kinds() -> *mut c_char
typedef _ValidCryptoKindsDart = Pointer<Utf8> Function();
// fn best_crypto_kind() -> u32
typedef _BestCryptoKindDart = int Function();
// fn verify_signatures(port: i64, node_ids: FfiStr, data: FfiStr, signatures: FfiStr)
typedef _VerifySignaturesDart = void Function(
int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn generate_signatures(port: i64, data: FfiStr, key_pairs: FfiStr)
typedef _GenerateSignaturesDart = void Function(
int, Pointer<Utf8>, Pointer<Utf8>);
// fn generate_key_pair(port: i64, kind: u32) {
typedef _GenerateKeyPairDart = void Function(int, int);
// fn crypto_cached_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr)
typedef _CryptoCachedDHDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_compute_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr)
typedef _CryptoComputeDHDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_random_bytes(port: i64, kind: u32, len: u32)
typedef _CryptoRandomBytesDart = void Function(int, int, int);
// fn crypto_default_salt_length(port: i64, kind: u32)
typedef _CryptoDefaultSaltLengthDart = void Function(int, int);
// fn crypto_hash_password(port: i64, kind: u32, password: FfiStr, salt: FfiStr )
typedef _CryptoHashPasswordDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_verify_password(port: i64, kind: u32, password: FfiStr, password_hash: FfiStr )
typedef _CryptoVerifyPasswordDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_derive_shared_secret(port: i64, kind: u32, password: FfiStr, salt: FfiStr )
2022-12-28 22:53:58 -05:00
2023-05-29 15:24:57 -04:00
// fn crypto_random_nonce(port: i64, kind: u32)
typedef _CryptoRandomNonceDart = void Function(int, int);
// fn crypto_random_shared_secret(port: i64, kind: u32)
typedef _CryptoRandomSharedSecretDart = void Function(int, int);
// fn crypto_generate_key_pair(port: i64, kind: u32)
typedef _CryptoGenerateKeyPairDart = void Function(int, int);
// fn crypto_generate_hash(port: i64, kind: u32, data: FfiStr)
typedef _CryptoGenerateHashDart = void Function(int, int, Pointer<Utf8>);
// fn crypto_validate_key_pair(port: i64, kind: u32, key: FfiStr, secret: FfiStr)
typedef _CryptoValidateKeyPairDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_validate_hash(port: i64, kind: u32, data: FfiStr, hash: FfiStr)
typedef _CryptoValidateHashDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_distance(port: i64, kind: u32, key1: FfiStr, key2: FfiStr)
typedef _CryptoDistanceDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_sign(port: i64, kind: u32, key: FfiStr, secret: FfiStr, data: FfiStr)
typedef _CryptoSignDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_verify(port: i64, kind: u32, key: FfiStr, data: FfiStr, signature: FfiStr)
typedef _CryptoVerifyDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_aead_overhead(port: i64, kind: u32)
typedef _CryptoAeadOverheadDart = void Function(int, int);
// fn crypto_decrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr)
typedef _CryptoDecryptAeadDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_encrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr)
typedef _CryptoEncryptAeadDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn crypto_crypt_no_auth(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr)
typedef _CryptoCryptNoAuthDart = void Function(
int, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>);
// fn now() -> u64
typedef _NowDart = int Function();
2022-11-26 14:16:02 -05:00
// fn debug(port: i64, log_level: FfiStr)
typedef _DebugDart = void Function(int, Pointer<Utf8>);
2022-02-06 21:18:42 -05:00
// fn shutdown_veilid_core(port: i64)
2022-02-13 21:09:43 -05:00
typedef _ShutdownVeilidCoreDart = void Function(int);
2022-02-06 21:18:42 -05:00
// fn veilid_version_string() -> *mut c_char
2022-02-13 21:09:43 -05:00
typedef _VeilidVersionStringDart = Pointer<Utf8> Function();
2022-02-09 09:47:36 -05:00
2022-02-06 21:18:42 -05:00
// fn veilid_version() -> VeilidVersion
2023-05-29 15:24:57 -04:00
final class VeilidVersionFFI extends Struct {
2022-02-06 21:18:42 -05:00
@Uint32()
external int major;
@Uint32()
external int minor;
@Uint32()
external int patch;
}
2022-02-09 09:47:36 -05:00
2022-02-13 21:09:43 -05:00
typedef _VeilidVersionDart = VeilidVersionFFI Function();
2022-02-09 09:47:36 -05:00
// Async message types
2022-02-13 21:09:43 -05:00
const int messageOk = 0;
const int messageErr = 1;
const int messageOkJson = 2;
const int messageErrJson = 3;
const int messageStreamItem = 4;
const int messageStreamItemJson = 5;
const int messageStreamAbort = 6;
const int messageStreamAbortJson = 7;
const int messageStreamClose = 8;
2022-02-06 21:18:42 -05:00
// Interface factory for high level Veilid API
Veilid getVeilid() => VeilidFFI(_dylib);
2022-02-09 09:47:36 -05:00
// Parse handle async returns
2023-07-26 14:20:17 -04:00
Future<T> processFuturePlain<T>(Future<dynamic> future) async => future.then((value) {
2022-02-09 09:47:36 -05:00
final list = value as List<dynamic>;
switch (list[0] as int) {
2022-02-13 21:09:43 -05:00
case messageOk:
2022-02-09 09:47:36 -05:00
{
2023-07-22 13:35:03 -04:00
if (list[1] == null && null is! T) {
throw const VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Null MESSAGE_OK value on non-nullable type');
2022-02-09 09:47:36 -05:00
}
return list[1] as T;
}
2022-02-13 21:09:43 -05:00
case messageErr:
2022-02-09 09:47:36 -05:00
{
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2022-02-09 21:40:01 -05:00
}
2022-02-13 21:09:43 -05:00
case messageErrJson:
2022-02-09 21:40:01 -05:00
{
throw VeilidAPIException.fromJson(jsonDecode(list[1]));
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2022-02-09 21:40:01 -05:00
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
Future<T> processFutureJson<T>(
2023-07-26 14:20:17 -04:00
T Function(dynamic) jsonConstructor, Future<dynamic> future) async => future.then((value) {
2022-02-09 21:40:01 -05:00
final list = value as List<dynamic>;
switch (list[0] as int) {
2022-02-13 21:09:43 -05:00
case messageErr:
2022-02-09 21:40:01 -05:00
{
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2022-02-09 09:47:36 -05:00
}
2022-02-13 21:09:43 -05:00
case messageOkJson:
2022-02-09 09:47:36 -05:00
{
2023-07-22 13:35:03 -04:00
if (list[1] is! String) {
throw const VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Non-string MESSAGE_OK_JSON value');
2022-02-09 09:47:36 -05:00
}
2023-07-26 14:20:17 -04:00
final ret = jsonDecode(list[1] as String);
2023-07-22 13:35:03 -04:00
if (ret == null) {
throw const VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Null JSON object on non nullable type');
2023-07-22 13:35:03 -04:00
}
2022-02-09 21:40:01 -05:00
return jsonConstructor(ret);
2022-02-09 09:47:36 -05:00
}
2022-02-13 21:09:43 -05:00
case messageErrJson:
2022-02-09 09:47:36 -05:00
{
2022-02-09 21:40:01 -05:00
throw VeilidAPIException.fromJson(jsonDecode(list[1]));
2022-02-09 09:47:36 -05:00
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2022-02-09 09:47:36 -05:00
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
2023-05-29 15:24:57 -04:00
Future<T?> processFutureOptJson<T>(
2023-07-26 14:20:17 -04:00
T Function(dynamic) jsonConstructor, Future<dynamic> future) async => future.then((value) {
2023-05-29 15:24:57 -04:00
final list = value as List<dynamic>;
switch (list[0] as int) {
case messageErr:
{
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2023-05-29 15:24:57 -04:00
}
case messageOkJson:
{
if (list[1] == null) {
return null;
}
2023-07-22 13:35:03 -04:00
if (list[1] is! String) {
throw const VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Non-string MESSAGE_OK_JSON optional value');
2023-07-22 13:35:03 -04:00
}
2023-07-26 14:20:17 -04:00
final ret = jsonDecode(list[1] as String);
2023-07-22 13:35:03 -04:00
if (ret == null) {
return null;
}
2023-05-29 15:24:57 -04:00
return jsonConstructor(ret);
}
case messageErrJson:
{
throw VeilidAPIException.fromJson(jsonDecode(list[1]));
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2023-05-29 15:24:57 -04:00
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
2023-07-26 14:20:17 -04:00
Future<void> processFutureVoid(Future<dynamic> future) async => future.then((value) {
2022-02-09 09:47:36 -05:00
final list = value as List<dynamic>;
switch (list[0] as int) {
2022-02-13 21:09:43 -05:00
case messageOk:
2022-02-09 09:47:36 -05:00
{
if (list[1] != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK value '${list[1]}' where null expected");
}
return;
}
2022-02-13 21:09:43 -05:00
case messageErr:
2022-02-09 09:47:36 -05:00
{
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2022-02-09 09:47:36 -05:00
}
2022-02-13 21:09:43 -05:00
case messageOkJson:
2022-02-09 09:47:36 -05:00
{
2023-07-26 14:20:17 -04:00
final ret = jsonDecode(list[1] as String);
2022-02-09 09:47:36 -05:00
if (ret != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK_JSON value '$ret' where null expected");
}
return;
}
2022-02-13 21:09:43 -05:00
case messageErrJson:
2022-02-09 09:47:36 -05:00
{
2022-02-09 21:40:01 -05:00
throw VeilidAPIException.fromJson(jsonDecode(list[1] as String));
2022-02-09 09:47:36 -05:00
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2022-02-09 09:47:36 -05:00
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
2022-09-09 16:27:13 -04:00
Future<Stream<T>> processFutureStream<T>(
2023-07-26 14:20:17 -04:00
Stream<T> returnStream, Future<dynamic> future) async => future.then((value) {
2022-09-09 16:27:13 -04:00
final list = value as List<dynamic>;
switch (list[0] as int) {
case messageOk:
{
if (list[1] != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK value '${list[1]}' where null expected");
}
return returnStream;
}
case messageErr:
{
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2022-09-09 16:27:13 -04:00
}
case messageOkJson:
{
2023-07-26 14:20:17 -04:00
final ret = jsonDecode(list[1] as String);
2022-09-09 16:27:13 -04:00
if (ret != null) {
throw VeilidAPIExceptionInternal(
"Unexpected MESSAGE_OK_JSON value '$ret' where null expected");
}
return returnStream;
}
case messageErrJson:
{
throw VeilidAPIException.fromJson(jsonDecode(list[1] as String));
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2022-09-09 16:27:13 -04:00
}
}
}).catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}, test: (e) {
// Pass errors that are already VeilidAPIException through without wrapping
return e is! VeilidAPIException;
});
2022-02-13 21:09:43 -05:00
Stream<T> processStreamJson<T>(
2023-07-25 01:04:22 -04:00
T Function(dynamic) jsonConstructor, ReceivePort port) async* {
2022-03-08 22:32:12 -05:00
try {
2023-07-26 14:20:17 -04:00
await for (final value in port) {
2022-03-08 22:32:12 -05:00
final list = value as List<dynamic>;
switch (list[0] as int) {
case messageStreamItemJson:
{
if (list[1] == null) {
2023-07-19 10:07:51 -04:00
throw const VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Null MESSAGE_STREAM_ITEM_JSON value');
2022-03-08 22:32:12 -05:00
}
2023-07-26 14:20:17 -04:00
final ret = jsonDecode(list[1] as String);
2022-03-08 22:32:12 -05:00
yield jsonConstructor(ret);
break;
2022-02-13 21:09:43 -05:00
}
2022-03-08 22:32:12 -05:00
case messageStreamAbort:
{
port.close();
2023-07-26 14:20:17 -04:00
throw VeilidAPIExceptionInternal('Internal API Error: ${list[1]}');
2022-03-08 22:32:12 -05:00
}
case messageStreamAbortJson:
{
port.close();
throw VeilidAPIException.fromJson(jsonDecode(list[1]));
}
case messageStreamClose:
{
port.close();
break;
}
default:
{
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'Unexpected async return message type: ${list[0]}');
2022-03-08 22:32:12 -05:00
}
}
2022-02-13 21:09:43 -05:00
}
2022-06-15 21:51:38 -04:00
} catch (e, s) {
2022-02-13 21:09:43 -05:00
// Wrap all other errors in VeilidAPIExceptionInternal
2022-06-15 21:51:38 -04:00
throw VeilidAPIExceptionInternal(
2023-07-26 14:20:17 -04:00
'$e\nStack Trace:\n$s');
2022-03-08 22:32:12 -05:00
}
2022-02-13 21:09:43 -05:00
}
2022-12-02 22:52:03 -05:00
class _Ctx {
2023-07-26 14:20:17 -04:00
_Ctx(int this.id, this.ffi);
2023-07-19 10:07:51 -04:00
int? id;
2022-12-02 22:52:03 -05:00
final VeilidFFI ffi;
2023-07-19 10:07:51 -04:00
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
}
}
void close() {
if (id != null) {
ffi._releaseRoutingContext(id!);
id = null;
}
}
2022-12-02 22:52:03 -05:00
}
2022-11-26 14:16:02 -05:00
// FFI implementation of VeilidRoutingContext
2023-07-19 10:07:51 -04:00
class VeilidRoutingContextFFI extends VeilidRoutingContext {
2022-12-02 22:52:03 -05:00
VeilidRoutingContextFFI._(this._ctx) {
_finalizer.attach(this, _ctx, detach: this);
}
2023-07-26 14:20:17 -04:00
final _Ctx _ctx;
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => ctx.close());
2022-11-26 14:16:02 -05:00
2023-07-19 10:07:51 -04:00
@override
void close() {
_ctx.close();
}
2022-11-26 14:16:02 -05:00
@override
VeilidRoutingContextFFI withPrivacy() {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
final newId = _ctx.ffi._routingContextWithPrivacy(_ctx.id!);
2022-12-02 22:52:03 -05:00
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
2022-11-26 14:16:02 -05:00
}
@override
VeilidRoutingContextFFI withCustomPrivacy(SafetySelection safetySelection) {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2022-12-02 22:52:03 -05:00
final newId = _ctx.ffi._routingContextWithCustomPrivacy(
2023-07-19 10:07:51 -04:00
_ctx.id!, jsonEncode(safetySelection).toNativeUtf8());
2022-12-02 22:52:03 -05:00
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
2022-11-26 14:16:02 -05:00
}
@override
VeilidRoutingContextFFI withSequencing(Sequencing sequencing) {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final newId = _ctx.ffi._routingContextWithSequencing(
2023-07-19 10:07:51 -04:00
_ctx.id!, jsonEncode(sequencing).toNativeUtf8());
2022-12-02 22:52:03 -05:00
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
2022-11-26 14:16:02 -05:00
}
@override
Future<Uint8List> appCall(String target, Uint8List request) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-07-26 14:20:17 -04:00
final nativeEncodedTarget = target.toNativeUtf8();
final nativeEncodedRequest = base64UrlNoPadEncode(request).toNativeUtf8();
2022-11-26 14:16:02 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_app_call');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
2023-07-19 10:07:51 -04:00
_ctx.ffi._routingContextAppCall(sendPort.nativePort, _ctx.id!,
2022-12-02 22:52:03 -05:00
nativeEncodedTarget, nativeEncodedRequest);
2022-11-26 14:16:02 -05:00
final out = await processFuturePlain(recvPort.first);
2023-01-04 17:02:45 -05:00
return base64UrlNoPadDecode(out);
2022-11-26 14:16:02 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> appMessage(String target, Uint8List message) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2022-12-28 22:53:58 -05:00
final nativeEncodedTarget = target.toNativeUtf8();
2023-01-04 17:02:45 -05:00
final nativeEncodedMessage = base64UrlNoPadEncode(message).toNativeUtf8();
2022-11-26 14:16:02 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_app_message');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
2023-07-19 10:07:51 -04:00
_ctx.ffi._routingContextAppMessage(sendPort.nativePort, _ctx.id!,
2022-12-02 22:52:03 -05:00
nativeEncodedTarget, nativeEncodedMessage);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-11-26 14:16:02 -05:00
}
2023-05-29 15:24:57 -04:00
@override
2023-07-08 22:50:44 -04:00
Future<DHTRecordDescriptor> createDHTRecord(DHTSchema schema,
{CryptoKind kind = 0}) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeSchema = jsonEncode(schema).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_create_dht_record');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextCreateDHTRecord(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeSchema, kind);
2023-05-29 15:24:57 -04:00
final dhtRecordDescriptor =
await processFutureJson(DHTRecordDescriptor.fromJson, recvPort.first);
return dhtRecordDescriptor;
}
@override
Future<DHTRecordDescriptor> openDHTRecord(
TypedKey key, KeyPair? writer) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeWriter =
2023-07-25 01:16:09 -04:00
writer != null ? jsonEncode(writer).toNativeUtf8() : nullptr;
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_open_dht_record');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextOpenDHTRecord(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeKey, nativeWriter);
2023-05-29 15:24:57 -04:00
final dhtRecordDescriptor =
await processFutureJson(DHTRecordDescriptor.fromJson, recvPort.first);
return dhtRecordDescriptor;
}
@override
2023-07-26 14:20:17 -04:00
Future<void> closeDHTRecord(TypedKey key) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_close_dht_record');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
2023-07-19 10:07:51 -04:00
_ctx.ffi._routingContextCloseDHTRecord(
sendPort.nativePort, _ctx.id!, nativeKey);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> deleteDHTRecord(TypedKey key) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_delete_dht_record');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextDeleteDHTRecord(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeKey);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
Future<ValueData?> getDHTValue(
TypedKey key, int subkey, bool forceRefresh) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_get_dht_value');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextGetDHTValue(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeKey, subkey, forceRefresh);
2023-07-25 01:04:22 -04:00
final valueData = await processFutureOptJson(
2023-05-29 15:24:57 -04:00
optFromJson(ValueData.fromJson), recvPort.first);
return valueData;
}
@override
Future<ValueData?> setDHTValue(
TypedKey key, int subkey, Uint8List data) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_set_dht_value');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextSetDHTValue(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeKey, subkey, nativeData);
2023-07-25 01:04:22 -04:00
final valueData = await processFutureOptJson(
2023-05-29 15:24:57 -04:00
optFromJson(ValueData.fromJson), recvPort.first);
return valueData;
}
@override
2023-06-27 18:26:53 -04:00
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
2023-05-29 15:24:57 -04:00
Timestamp expiration, int count) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
final nativeExpiration = expiration.value.toInt();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_watch_dht_values');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
2023-07-19 10:07:51 -04:00
_ctx.ffi._routingContextWatchDHTValues(sendPort.nativePort, _ctx.id!,
2023-05-29 15:24:57 -04:00
nativeKey, nativeSubkeys, nativeExpiration, count);
final actualExpiration = Timestamp(
value: BigInt.from(await processFuturePlain<int>(recvPort.first)));
return actualExpiration;
}
@override
2023-06-27 18:26:53 -04:00
Future<bool> cancelDHTWatch(
TypedKey key, List<ValueSubkeyRange> subkeys) async {
2023-07-19 10:07:51 -04:00
_ctx.ensureValid();
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context_cancel_dht_watch');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ctx.ffi._routingContextCancelDHTWatch(
2023-07-19 10:07:51 -04:00
sendPort.nativePort, _ctx.id!, nativeKey, nativeSubkeys);
2023-05-29 15:24:57 -04:00
final cancelled = await processFuturePlain<bool>(recvPort.first);
return cancelled;
}
2022-11-26 14:16:02 -05:00
}
2022-12-28 22:53:58 -05:00
class _TDBT {
2023-07-26 14:20:17 -04:00
_TDBT(int this.id, this.tdbffi, this.ffi);
2023-07-19 10:07:51 -04:00
int? id;
final VeilidTableDBFFI tdbffi;
final VeilidFFI ffi;
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
}
}
2022-12-28 22:53:58 -05:00
2023-07-19 10:07:51 -04:00
void close() {
if (id != null) {
ffi._releaseTableDbTransaction(id!);
id = null;
}
}
2022-12-28 22:53:58 -05:00
}
// FFI implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionFFI extends VeilidTableDBTransaction {
VeilidTableDBTransactionFFI._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this);
}
2023-07-26 14:20:17 -04:00
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => tdbt.close());
2022-12-28 22:53:58 -05:00
@override
2023-07-26 14:20:17 -04:00
bool isDone() => _tdbt.id == null;
2023-07-19 10:07:51 -04:00
@override
Future<void> commit() async {
_tdbt.ensureValid();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_transaction_commit');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionCommit(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdbt.id!,
2022-12-28 22:53:58 -05:00
);
2023-07-19 10:07:51 -04:00
await processFutureVoid(recvPort.first);
_tdbt.close();
2022-12-28 22:53:58 -05:00
}
@override
2023-07-19 10:07:51 -04:00
Future<void> rollback() async {
_tdbt.ensureValid();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_transaction_rollback');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionRollback(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdbt.id!,
2022-12-28 22:53:58 -05:00
);
2023-07-19 10:07:51 -04:00
await processFutureVoid(recvPort.first);
_tdbt.close();
2022-12-28 22:53:58 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> store(int col, Uint8List key, Uint8List value) async {
2023-07-19 10:07:51 -04:00
_tdbt.ensureValid();
2023-01-04 17:02:45 -05:00
final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8();
final nativeEncodedValue = base64UrlNoPadEncode(value).toNativeUtf8();
2022-12-28 22:53:58 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_transaction_store');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionStore(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdbt.id!,
2022-12-28 22:53:58 -05:00
col,
nativeEncodedKey,
nativeEncodedValue,
);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-12-28 22:53:58 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> delete(int col, Uint8List key) async {
2023-07-19 10:07:51 -04:00
_tdbt.ensureValid();
2023-01-04 17:02:45 -05:00
final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8();
2022-12-28 22:53:58 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_transaction_delete');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionDelete(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdbt.id!,
2022-12-28 22:53:58 -05:00
col,
nativeEncodedKey,
);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2022-12-28 22:53:58 -05:00
}
}
class _TDB {
2023-07-26 14:20:17 -04:00
_TDB(int this.id, this.ffi);
2023-07-19 10:07:51 -04:00
int? id;
final VeilidFFI ffi;
void ensureValid() {
if (id == null) {
throw VeilidAPIExceptionNotInitialized();
}
}
void close() {
if (id != null) {
ffi._releaseTableDb(id!);
id = null;
}
}
2022-12-28 22:53:58 -05:00
}
// FFI implementation of VeilidTableDB
class VeilidTableDBFFI extends VeilidTableDB {
VeilidTableDBFFI._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this);
}
2023-07-26 14:20:17 -04:00
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => tdb.close());
2022-12-28 22:53:58 -05:00
2023-07-19 10:07:51 -04:00
@override
void close() {
_tdb.close();
}
2022-12-28 22:53:58 -05:00
@override
int getColumnCount() {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
return _tdb.ffi._tableDbGetColumnCount(_tdb.id!);
2022-12-28 22:53:58 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<List<Uint8List>> getKeys(int col) async {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_get_keys');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
2023-07-19 10:07:51 -04:00
_tdb.ffi._tableDbGetKeys(sendPort.nativePort, _tdb.id!, col);
2023-05-29 15:24:57 -04:00
2023-07-26 14:20:17 -04:00
return await processFutureJson(
2023-05-29 15:24:57 -04:00
jsonListConstructor<Uint8List>(base64UrlNoPadDecodeDynamic),
recvPort.first);
2022-12-28 22:53:58 -05:00
}
@override
VeilidTableDBTransaction transact() {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
final id = _tdb.ffi._tableDbTransact(_tdb.id!);
2022-12-28 22:53:58 -05:00
return VeilidTableDBTransactionFFI._(_TDBT(id, this, _tdb.ffi));
}
@override
2023-07-26 14:20:17 -04:00
Future<void> store(int col, Uint8List key, Uint8List value) async {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
2023-01-04 17:02:45 -05:00
final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8();
final nativeEncodedValue = base64UrlNoPadEncode(value).toNativeUtf8();
2022-12-28 22:53:58 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_store');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdb.ffi._tableDbStore(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdb.id!,
2022-12-28 22:53:58 -05:00
col,
nativeEncodedKey,
nativeEncodedValue,
);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-12-28 22:53:58 -05:00
}
@override
Future<Uint8List?> load(int col, Uint8List key) async {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
2023-01-04 17:02:45 -05:00
final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8();
2022-12-28 22:53:58 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_load');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_tdb.ffi._tableDbLoad(
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdb.id!,
2022-12-28 22:53:58 -05:00
col,
nativeEncodedKey,
);
2023-07-26 14:20:17 -04:00
final out = await processFuturePlain(recvPort.first);
2022-12-28 22:53:58 -05:00
if (out == null) {
return null;
}
2023-01-04 17:02:45 -05:00
return base64UrlNoPadDecode(out);
2022-12-28 22:53:58 -05:00
}
@override
2023-06-04 22:08:46 -04:00
Future<Uint8List?> delete(int col, Uint8List key) async {
2023-07-19 10:07:51 -04:00
_tdb.ensureValid();
2023-01-04 17:02:45 -05:00
final nativeEncodedKey = base64UrlNoPadEncode(key).toNativeUtf8();
2022-12-28 22:53:58 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('veilid_table_db_delete');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
2023-05-29 15:24:57 -04:00
_tdb.ffi._tableDbDelete(
2022-12-28 22:53:58 -05:00
sendPort.nativePort,
2023-07-19 10:07:51 -04:00
_tdb.id!,
2022-12-28 22:53:58 -05:00
col,
nativeEncodedKey,
);
2023-07-26 14:20:17 -04:00
final out = await processFuturePlain(recvPort.first);
2023-06-04 22:08:46 -04:00
if (out == null) {
return null;
}
return base64UrlNoPadDecode(out);
2022-12-28 22:53:58 -05:00
}
}
2023-05-29 15:24:57 -04:00
// FFI implementation of VeilidCryptoSystem
2023-07-19 10:07:51 -04:00
class VeilidCryptoSystemFFI extends VeilidCryptoSystem {
2023-05-29 15:24:57 -04:00
VeilidCryptoSystemFFI._(this._ffi, this._kind);
2023-07-26 14:20:17 -04:00
final CryptoKind _kind;
final VeilidFFI _ffi;
2023-05-29 15:24:57 -04:00
@override
2023-07-26 14:20:17 -04:00
CryptoKind kind() => _kind;
2023-05-29 15:24:57 -04:00
@override
2023-07-26 14:20:17 -04:00
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async {
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSecret = jsonEncode(secret).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_cached_dh');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoCachedDH(sendPort.nativePort, _kind, nativeKey, nativeSecret);
2023-07-26 14:20:17 -04:00
return await processFutureJson(SharedSecret.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async {
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSecret = jsonEncode(secret).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_compute_dh');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoComputeDH(sendPort.nativePort, _kind, nativeKey, nativeSecret);
2023-07-26 14:20:17 -04:00
return await processFutureJson(SharedSecret.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
Future<Uint8List> randomBytes(int len) async {
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_random_bytes');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoRandomBytes(sendPort.nativePort, _kind, len);
final out = await processFuturePlain(recvPort.first);
return base64UrlNoPadDecode(out);
}
@override
2023-07-26 14:20:17 -04:00
Future<int> defaultSaltLength() async {
final recvPort = ReceivePort('crypto_default_salt_length');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoDefaultSaltLength(sendPort.nativePort, _kind);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<String> hashPassword(Uint8List password, Uint8List salt) async {
2023-05-29 15:24:57 -04:00
final nativeEncodedPassword = base64UrlNoPadEncode(password).toNativeUtf8();
final nativeEncodedSalt = base64UrlNoPadEncode(salt).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_hash_password');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoHashPassword(
sendPort.nativePort, _kind, nativeEncodedPassword, nativeEncodedSalt);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<bool> verifyPassword(Uint8List password, String passwordHash) async {
2023-05-29 15:24:57 -04:00
final nativeEncodedPassword = base64UrlNoPadEncode(password).toNativeUtf8();
final nativeEncodedPasswordHash = passwordHash.toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_verify_password');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoVerifyPassword(sendPort.nativePort, _kind,
nativeEncodedPassword, nativeEncodedPasswordHash);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<SharedSecret> deriveSharedSecret(
Uint8List password, Uint8List salt) async {
2023-05-29 15:24:57 -04:00
final nativeEncodedPassword = base64UrlNoPadEncode(password).toNativeUtf8();
final nativeEncodedSalt = base64UrlNoPadEncode(salt).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_derive_shared_secret');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoDeriveSharedSecret(
sendPort.nativePort, _kind, nativeEncodedPassword, nativeEncodedSalt);
2023-07-26 14:20:17 -04:00
return await processFutureJson(SharedSecret.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<Nonce> randomNonce() async {
final recvPort = ReceivePort('crypto_random_nonce');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoRandomNonce(sendPort.nativePort, _kind);
2023-07-26 14:20:17 -04:00
return await processFutureJson(Nonce.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<SharedSecret> randomSharedSecret() async {
final recvPort = ReceivePort('crypto_random_shared_secret');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoRandomSharedSecret(sendPort.nativePort, _kind);
2023-07-26 14:20:17 -04:00
return await processFutureJson(SharedSecret.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<KeyPair> generateKeyPair() async {
final recvPort = ReceivePort('crypto_generate_key_pair');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoGenerateKeyPair(sendPort.nativePort, _kind);
2023-07-26 14:20:17 -04:00
return await processFutureJson(KeyPair.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<HashDigest> generateHash(Uint8List data) async {
2023-05-29 15:24:57 -04:00
final nativeEncodedData = base64UrlNoPadEncode(data).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_generate_hash');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoGenerateHash(sendPort.nativePort, _kind, nativeEncodedData);
2023-07-26 14:20:17 -04:00
return await processFutureJson(HashDigest.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) async {
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSecret = jsonEncode(secret).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_validate_key_pair');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoValidateKeyPair(
sendPort.nativePort, _kind, nativeKey, nativeSecret);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<bool> validateHash(Uint8List data, HashDigest hash) async {
2023-05-29 15:24:57 -04:00
final nativeEncodedData = base64UrlNoPadEncode(data).toNativeUtf8();
final nativeHash = jsonEncode(hash).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_validate_hash');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoValidateHash(
sendPort.nativePort, _kind, nativeEncodedData, nativeHash);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async {
2023-05-29 15:24:57 -04:00
final nativeKey1 = jsonEncode(key1).toNativeUtf8();
final nativeKey2 = jsonEncode(key2).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_distance');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoDistance(sendPort.nativePort, _kind, nativeKey1, nativeKey2);
2023-07-26 14:20:17 -04:00
return await processFutureJson(CryptoKeyDistance.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<Signature> sign(
PublicKey key, SecretKey secret, Uint8List data) async {
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeSecret = jsonEncode(secret).toNativeUtf8();
final nativeEncodedData = base64UrlNoPadEncode(data).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_sign');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoSign(
sendPort.nativePort, _kind, nativeKey, nativeSecret, nativeEncodedData);
2023-07-26 14:20:17 -04:00
return await processFutureJson(Signature.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> verify(
PublicKey key, Uint8List data, Signature signature) async {
2023-05-29 15:24:57 -04:00
final nativeKey = jsonEncode(key).toNativeUtf8();
final nativeEncodedData = base64UrlNoPadEncode(data).toNativeUtf8();
final nativeSignature = jsonEncode(signature).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_verify');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoVerify(sendPort.nativePort, _kind, nativeKey, nativeEncodedData,
nativeSignature);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<int> aeadOverhead() async {
final recvPort = ReceivePort('crypto_aead_overhead');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoAeadOverhead(
sendPort.nativePort,
_kind,
);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2023-05-29 15:24:57 -04:00
}
@override
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async {
final nativeEncodedBody = base64UrlNoPadEncode(body).toNativeUtf8();
final nativeNonce = jsonEncode(nonce).toNativeUtf8();
final nativeSharedSecret = jsonEncode(sharedSecret).toNativeUtf8();
final nativeSignature = (associatedData != null)
? jsonEncode(associatedData).toNativeUtf8()
: nullptr;
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_decrypt_aead');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoDecryptAead(sendPort.nativePort, _kind, nativeEncodedBody,
nativeNonce, nativeSharedSecret, nativeSignature);
final out = await processFuturePlain(recvPort.first);
return base64UrlNoPadDecode(out);
}
@override
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async {
final nativeEncodedBody = base64UrlNoPadEncode(body).toNativeUtf8();
final nativeNonce = jsonEncode(nonce).toNativeUtf8();
final nativeSharedSecret = jsonEncode(sharedSecret).toNativeUtf8();
final nativeSignature = (associatedData != null)
? jsonEncode(associatedData).toNativeUtf8()
: nullptr;
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_encrypt_aead');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoEncryptAead(sendPort.nativePort, _kind, nativeEncodedBody,
nativeNonce, nativeSharedSecret, nativeSignature);
final out = await processFuturePlain(recvPort.first);
return base64UrlNoPadDecode(out);
}
@override
Future<Uint8List> cryptNoAuth(
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async {
final nativeEncodedBody = base64UrlNoPadEncode(body).toNativeUtf8();
final nativeNonce = jsonEncode(nonce).toNativeUtf8();
final nativeSharedSecret = jsonEncode(sharedSecret).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('crypto_crypt_no_auth');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_ffi._cryptoCryptNoAuth(sendPort.nativePort, _kind, nativeEncodedBody,
nativeNonce, nativeSharedSecret);
final out = await processFuturePlain(recvPort.first);
return base64UrlNoPadDecode(out);
}
}
2022-02-06 21:18:42 -05:00
// FFI implementation of high level Veilid API
2023-07-19 10:07:51 -04:00
class VeilidFFI extends Veilid {
2022-02-06 21:18:42 -05:00
2022-02-09 09:47:36 -05:00
VeilidFFI(DynamicLibrary dylib)
: _dylib = dylib,
2022-02-13 21:09:43 -05:00
_freeString =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Pointer<Utf8>), _FreeStringDart>('free_string'),
_initializeVeilidCore = dylib.lookupFunction<Void Function(Pointer<Utf8>),
2022-07-01 16:20:43 -04:00
_InitializeVeilidCoreDart>('initialize_veilid_core'),
2022-07-01 12:13:52 -04:00
_changeLogLevel =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Pointer<Utf8>, Pointer<Utf8>), _ChangeLogLevelDart>(
2022-07-01 12:13:52 -04:00
'change_log_level'),
2022-02-13 21:09:43 -05:00
_startupVeilidCore =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Int64, Pointer<Utf8>), _StartupVeilidCoreDart>(
2022-02-13 21:09:43 -05:00
'startup_veilid_core'),
2022-02-09 09:47:36 -05:00
_getVeilidState =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64), _GetVeilidStateDart>(
2022-02-09 09:47:36 -05:00
'get_veilid_state'),
2023-07-26 14:20:17 -04:00
_attach = dylib.lookupFunction<Void Function(Int64), _AttachDart>('attach'),
_detach = dylib.lookupFunction<Void Function(Int64), _DetachDart>('detach'),
2022-02-13 21:09:43 -05:00
_shutdownVeilidCore =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64), _ShutdownVeilidCoreDart>(
2022-02-13 21:09:43 -05:00
'shutdown_veilid_core'),
2022-11-26 14:16:02 -05:00
_routingContext =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64), _RoutingContextDart>(
2022-11-26 14:16:02 -05:00
'routing_context'),
2023-07-26 14:20:17 -04:00
_releaseRoutingContext = dylib.lookupFunction<Int32 Function(Uint32),
2022-11-26 14:16:02 -05:00
_ReleaseRoutingContextDart>('release_routing_context'),
_routingContextWithPrivacy = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Uint32 Function(Uint32),
2022-11-26 14:16:02 -05:00
_RoutingContextWithPrivacyDart>('routing_context_with_privacy'),
_routingContextWithCustomPrivacy = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Uint32 Function(Uint32, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_RoutingContextWithCustomPrivacyDart>(
'routing_context_with_custom_privacy'),
_routingContextWithSequencing = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Uint32 Function(Uint32, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_RoutingContextWithSequencingDart>(
'routing_context_with_sequencing'),
2023-07-26 14:20:17 -04:00
_routingContextAppCall = dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_RoutingContextAppCallDart>('routing_context_app_call'),
_routingContextAppMessage = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_RoutingContextAppMessageDart>('routing_context_app_message'),
2023-05-29 15:24:57 -04:00
_routingContextCreateDHTRecord = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Uint32),
2023-05-29 15:24:57 -04:00
_RoutingContextCreateDHTRecordDart>(
'routing_context_create_dht_record'),
_routingContextOpenDHTRecord = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_RoutingContextOpenDHTRecordDart>(
'routing_context_open_dht_record'),
_routingContextCloseDHTRecord = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_RoutingContextCloseDHTRecordDart>(
'routing_context_close_dht_record'),
_routingContextDeleteDHTRecord = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_RoutingContextDeleteDHTRecordDart>(
'routing_context_delete_dht_record'),
_routingContextGetDHTValue = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Uint32, Bool),
2023-05-29 15:24:57 -04:00
_RoutingContextGetDHTValueDart>('routing_context_get_dht_value'),
_routingContextSetDHTValue = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Uint32, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_RoutingContextSetDHTValueDart>('routing_context_set_dht_value'),
_routingContextWatchDHTValues = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Uint64, Uint32),
2023-05-29 15:24:57 -04:00
_RoutingContextWatchDHTValuesDart>(
'routing_context_watch_dht_values'),
_routingContextCancelDHTWatch = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_RoutingContextCancelDHTWatchDart>(
'routing_context_cancel_dht_watch'),
2022-11-26 14:16:02 -05:00
_newPrivateRoute =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64), _NewPrivateRouteDart>(
2022-11-26 14:16:02 -05:00
'new_private_route'),
2023-07-26 14:20:17 -04:00
_newCustomPrivateRoute = dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_NewCustomPrivateRouteDart>('new_custom_private_route'),
_importRemotePrivateRoute = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_ImportRemotePrivateRouteDart>('import_remote_private_route'),
2023-07-26 14:20:17 -04:00
_releasePrivateRoute = dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>),
2022-11-26 14:16:02 -05:00
_ReleasePrivateRouteDart>('release_private_route'),
2023-07-26 14:20:17 -04:00
_appCallReply = dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>), _AppCallReplyDart>(
2022-09-30 22:37:55 -04:00
'app_call_reply'),
2022-12-28 22:53:58 -05:00
_openTableDb = dylib
2023-07-26 14:20:17 -04:00
.lookupFunction<Void Function(Int64, Pointer<Utf8>, Uint32), _OpenTableDbDart>('open_table_db'),
2022-12-28 22:53:58 -05:00
_releaseTableDb =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Int32 Function(Uint32), _ReleaseTableDbDart>(
2022-12-28 22:53:58 -05:00
'release_table_db'),
_deleteTableDb =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>), _DeleteTableDbDart>(
2022-12-28 22:53:58 -05:00
'delete_table_db'),
2023-07-26 14:20:17 -04:00
_tableDbGetColumnCount = dylib.lookupFunction<Uint32 Function(Uint32),
2022-12-28 22:53:58 -05:00
_TableDbGetColumnCountDart>('table_db_get_column_count'),
_tableDbGetKeys =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Pointer<Utf8> Function(Uint64, Uint32, Uint32), _TableDbGetKeysDart>(
2022-12-28 22:53:58 -05:00
'table_db_get_keys'),
2023-07-26 14:20:17 -04:00
_tableDbStore = dylib.lookupFunction<Void Function(Int64, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>), _TableDbStoreDart>(
2022-12-28 22:53:58 -05:00
'table_db_store'),
_tableDbLoad = dylib
2023-07-26 14:20:17 -04:00
.lookupFunction<Void Function(Int64, Uint32, Uint32, Pointer<Utf8>), _TableDbLoadDart>('table_db_load'),
2022-12-28 22:53:58 -05:00
_tableDbDelete =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Uint32, Pointer<Utf8>), _TableDbDeleteDart>(
2022-12-28 22:53:58 -05:00
'table_db_delete'),
_tableDbTransact =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Uint32 Function(Uint32), _TableDbTransactDart>(
2022-12-28 22:53:58 -05:00
'table_db_transact'),
_releaseTableDbTransaction = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Int32 Function(Uint32),
2022-12-28 22:53:58 -05:00
_ReleaseTableDbTransactionDart>('release_table_db_transaction'),
_tableDbTransactionCommit = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Uint64, Uint32),
2022-12-28 22:53:58 -05:00
_TableDbTransactionCommitDart>('table_db_transaction_commit'),
_tableDbTransactionRollback = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Uint64, Uint32),
2022-12-28 22:53:58 -05:00
_TableDbTransactionRollbackDart>('table_db_transaction_rollback'),
_tableDbTransactionStore = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2022-12-28 22:53:58 -05:00
_TableDbTransactionStoreDart>('table_db_transaction_store'),
_tableDbTransactionDelete = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Uint32, Pointer<Utf8>),
2022-12-28 22:53:58 -05:00
_TableDbTransactionDeleteDart>('table_db_transaction_delete'),
2023-05-29 15:24:57 -04:00
_validCryptoKinds =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Pointer<Utf8> Function(), _ValidCryptoKindsDart>(
2023-05-29 15:24:57 -04:00
'valid_crypto_kinds'),
_bestCryptoKind =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Uint32 Function(), _BestCryptoKindDart>(
2023-05-29 15:24:57 -04:00
'best_crypto_kind'),
_verifySignatures =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _VerifySignaturesDart>(
2023-05-29 15:24:57 -04:00
'verify_signatures'),
_generateSignatures =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>), _GenerateSignaturesDart>(
2023-05-29 15:24:57 -04:00
'generate_signatures'),
_generateKeyPair =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32), _GenerateKeyPairDart>(
2023-05-29 15:24:57 -04:00
'generate_key_pair'),
_cryptoCachedDH =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>), _CryptoCachedDHDart>(
2023-05-29 15:24:57 -04:00
'crypto_cached_dh'),
_cryptoComputeDH =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>), _CryptoComputeDHDart>(
2023-05-29 15:24:57 -04:00
'crypto_compute_dh'),
_cryptoRandomBytes =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Uint32), _CryptoRandomBytesDart>(
2023-05-29 15:24:57 -04:00
'crypto_random_bytes'),
_cryptoDefaultSaltLength = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32),
2023-05-29 15:24:57 -04:00
_CryptoDefaultSaltLengthDart>('crypto_default_salt_length'),
_cryptoHashPassword =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>), _CryptoHashPasswordDart>(
2023-05-29 15:24:57 -04:00
'crypto_hash_password'),
2023-07-26 14:20:17 -04:00
_cryptoVerifyPassword = dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_CryptoVerifyPasswordDart>('crypto_verify_password'),
_cryptoDeriveSharedSecret = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_CryptoVerifyPasswordDart>('crypto_derive_shared_secret'),
_cryptoRandomNonce =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32), _CryptoRandomNonceDart>(
2023-05-29 15:24:57 -04:00
'crypto_random_nonce'),
_cryptoRandomSharedSecret = dylib.lookupFunction<
2023-07-26 14:20:17 -04:00
Void Function(Int64, Uint32),
2023-05-29 15:24:57 -04:00
_CryptoRandomSharedSecretDart>('crypto_random_shared_secret'),
2023-07-26 14:20:17 -04:00
_cryptoGenerateKeyPair = dylib.lookupFunction<Void Function(Int64, Uint32),
2023-05-29 15:24:57 -04:00
_CryptoGenerateKeyPairDart>('crypto_generate_key_pair'),
_cryptoGenerateHash =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>), _CryptoGenerateHashDart>(
2023-05-29 15:24:57 -04:00
'crypto_generate_hash'),
2023-07-26 14:20:17 -04:00
_cryptoValidateKeyPair = dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
2023-05-29 15:24:57 -04:00
_CryptoValidateKeyPairDart>('crypto_validate_key_pair'),
_cryptoValidateHash =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>), _CryptoValidateHashDart>(
2023-05-29 15:24:57 -04:00
'crypto_validate_hash'),
_cryptoDistance =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>), _CryptoDistanceDart>(
2023-05-29 15:24:57 -04:00
'crypto_distance'),
_cryptoSign =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _CryptoSignDart>('crypto_sign'),
2023-05-29 15:24:57 -04:00
_cryptoVerify = dylib
2023-07-26 14:20:17 -04:00
.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _CryptoVerifyDart>('crypto_verify'),
2023-05-29 15:24:57 -04:00
_cryptoAeadOverhead =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32), _CryptoAeadOverheadDart>(
2023-05-29 15:24:57 -04:00
'crypto_aead_overhead'),
_cryptoDecryptAead =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _CryptoDecryptAeadDart>(
2023-05-29 15:24:57 -04:00
'crypto_decrypt_aead'),
_cryptoEncryptAead =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _CryptoEncryptAeadDart>(
2023-05-29 15:24:57 -04:00
'crypto_encrypt_aead'),
_cryptoCryptNoAuth =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>), _CryptoCryptNoAuthDart>(
2023-05-29 15:24:57 -04:00
'crypto_crypt_no_auth'),
2023-07-26 14:20:17 -04:00
_now = dylib.lookupFunction<Uint64 Function(), _NowDart>('now'),
_debug = dylib.lookupFunction<Void Function(Int64, Pointer<Utf8>), _DebugDart>('debug'),
_veilidVersionString = dylib.lookupFunction<Pointer<Utf8> Function(),
2022-02-13 21:09:43 -05:00
_VeilidVersionStringDart>('veilid_version_string'),
2022-02-09 09:47:36 -05:00
_veilidVersion =
2023-07-26 14:20:17 -04:00
dylib.lookupFunction<VeilidVersionFFI Function(), _VeilidVersionDart>(
2022-02-09 09:47:36 -05:00
'veilid_version') {
// Get veilid_flutter initializer
2023-07-26 14:20:17 -04:00
final initializeVeilidFlutter = _dylib.lookupFunction<
Void Function(Pointer<_DartPostCObject>),
void Function(Pointer<_DartPostCObject>)>('initialize_veilid_flutter');
2022-02-06 21:18:42 -05:00
initializeVeilidFlutter(NativeApi.postCObject);
2022-02-09 09:47:36 -05:00
}
2023-07-26 14:20:17 -04:00
// veilid_core shared library
final DynamicLibrary _dylib;
// Shared library functions
final _FreeStringDart _freeString;
final _InitializeVeilidCoreDart _initializeVeilidCore;
final _ChangeLogLevelDart _changeLogLevel;
final _StartupVeilidCoreDart _startupVeilidCore;
final _GetVeilidStateDart _getVeilidState;
final _AttachDart _attach;
final _DetachDart _detach;
final _ShutdownVeilidCoreDart _shutdownVeilidCore;
final _RoutingContextDart _routingContext;
final _ReleaseRoutingContextDart _releaseRoutingContext;
final _RoutingContextWithPrivacyDart _routingContextWithPrivacy;
final _RoutingContextWithCustomPrivacyDart _routingContextWithCustomPrivacy;
final _RoutingContextWithSequencingDart _routingContextWithSequencing;
final _RoutingContextAppCallDart _routingContextAppCall;
final _RoutingContextAppMessageDart _routingContextAppMessage;
final _RoutingContextCreateDHTRecordDart _routingContextCreateDHTRecord;
final _RoutingContextOpenDHTRecordDart _routingContextOpenDHTRecord;
final _RoutingContextCloseDHTRecordDart _routingContextCloseDHTRecord;
final _RoutingContextDeleteDHTRecordDart _routingContextDeleteDHTRecord;
final _RoutingContextGetDHTValueDart _routingContextGetDHTValue;
final _RoutingContextSetDHTValueDart _routingContextSetDHTValue;
final _RoutingContextWatchDHTValuesDart _routingContextWatchDHTValues;
final _RoutingContextCancelDHTWatchDart _routingContextCancelDHTWatch;
final _NewPrivateRouteDart _newPrivateRoute;
final _NewCustomPrivateRouteDart _newCustomPrivateRoute;
final _ImportRemotePrivateRouteDart _importRemotePrivateRoute;
final _ReleasePrivateRouteDart _releasePrivateRoute;
final _AppCallReplyDart _appCallReply;
final _OpenTableDbDart _openTableDb;
final _ReleaseTableDbDart _releaseTableDb;
final _DeleteTableDbDart _deleteTableDb;
final _TableDbGetColumnCountDart _tableDbGetColumnCount;
final _TableDbGetKeysDart _tableDbGetKeys;
final _TableDbStoreDart _tableDbStore;
final _TableDbLoadDart _tableDbLoad;
final _TableDbDeleteDart _tableDbDelete;
final _TableDbTransactDart _tableDbTransact;
final _ReleaseTableDbTransactionDart _releaseTableDbTransaction;
final _TableDbTransactionCommitDart _tableDbTransactionCommit;
final _TableDbTransactionRollbackDart _tableDbTransactionRollback;
final _TableDbTransactionStoreDart _tableDbTransactionStore;
final _TableDbTransactionDeleteDart _tableDbTransactionDelete;
final _ValidCryptoKindsDart _validCryptoKinds;
final _BestCryptoKindDart _bestCryptoKind;
final _VerifySignaturesDart _verifySignatures;
final _GenerateSignaturesDart _generateSignatures;
final _GenerateKeyPairDart _generateKeyPair;
final _CryptoCachedDHDart _cryptoCachedDH;
final _CryptoComputeDHDart _cryptoComputeDH;
final _CryptoRandomBytesDart _cryptoRandomBytes;
final _CryptoDefaultSaltLengthDart _cryptoDefaultSaltLength;
final _CryptoHashPasswordDart _cryptoHashPassword;
final _CryptoVerifyPasswordDart _cryptoVerifyPassword;
final void Function(int, int, Pointer<Utf8>, Pointer<Utf8>) _cryptoDeriveSharedSecret;
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;
final _NowDart _now;
final _DebugDart _debug;
final _VeilidVersionStringDart _veilidVersionString;
final _VeilidVersionDart _veilidVersion;
2022-02-09 09:47:36 -05:00
2022-06-15 21:51:38 -04:00
@override
2022-07-01 16:20:43 -04:00
void initializeVeilidCore(Map<String, dynamic> platformConfigJson) {
2023-07-26 14:20:17 -04:00
final nativePlatformConfig = jsonEncode(platformConfigJson).toNativeUtf8();
2022-06-15 21:51:38 -04:00
2022-07-01 16:20:43 -04:00
_initializeVeilidCore(nativePlatformConfig);
2022-06-15 21:51:38 -04:00
malloc.free(nativePlatformConfig);
}
2022-07-01 12:13:52 -04:00
@override
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) {
2023-07-26 14:20:17 -04:00
final nativeLogLevel = jsonEncode(logLevel).toNativeUtf8();
final nativeLayer = layer.toNativeUtf8();
2022-07-01 12:13:52 -04:00
_changeLogLevel(nativeLayer, nativeLogLevel);
malloc.free(nativeLayer);
malloc.free(nativeLogLevel);
}
2022-02-09 09:47:36 -05:00
@override
2023-07-26 14:20:17 -04:00
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
final nativeConfig = jsonEncode(config).toNativeUtf8();
final recvStreamPort = ReceivePort('veilid_api_stream');
2022-09-09 16:27:13 -04:00
final sendStreamPort = recvStreamPort.sendPort;
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('startup_veilid_core');
2022-02-09 21:40:01 -05:00
final sendPort = recvPort.sendPort;
2022-09-09 16:27:13 -04:00
_startupVeilidCore(
sendPort.nativePort, sendStreamPort.nativePort, nativeConfig);
2022-02-09 21:40:01 -05:00
malloc.free(nativeConfig);
2023-07-26 14:20:17 -04:00
return await processFutureStream(
2022-09-09 16:27:13 -04:00
processStreamJson(VeilidUpdate.fromJson, recvStreamPort),
recvPort.first);
2022-02-09 21:40:01 -05:00
}
2022-02-06 21:18:42 -05:00
2022-02-09 09:47:36 -05:00
@override
2023-07-26 14:20:17 -04:00
Future<VeilidState> getVeilidState() async {
final recvPort = ReceivePort('get_veilid_state');
2022-02-09 21:40:01 -05:00
final sendPort = recvPort.sendPort;
2022-02-13 21:09:43 -05:00
_getVeilidState(sendPort.nativePort);
2023-07-26 14:20:17 -04:00
return await processFutureJson(VeilidState.fromJson, recvPort.first);
2022-02-06 21:18:42 -05:00
}
2022-09-06 18:59:41 -04:00
@override
2023-07-26 14:20:17 -04:00
Future<void> attach() async {
final recvPort = ReceivePort('attach');
2022-09-06 18:59:41 -04:00
final sendPort = recvPort.sendPort;
_attach(sendPort.nativePort);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-09-06 18:59:41 -04:00
}
@override
2023-07-26 14:20:17 -04:00
Future<void> detach() async {
final recvPort = ReceivePort('detach');
2022-09-06 18:59:41 -04:00
final sendPort = recvPort.sendPort;
_detach(sendPort.nativePort);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-09-06 18:59:41 -04:00
}
2022-02-09 09:47:36 -05:00
@override
2023-07-26 14:20:17 -04:00
Future<void> shutdownVeilidCore() async {
final recvPort = ReceivePort('shutdown_veilid_core');
2022-02-09 21:40:01 -05:00
final sendPort = recvPort.sendPort;
_shutdownVeilidCore(sendPort.nativePort);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-02-09 09:47:36 -05:00
}
2022-03-03 20:45:39 -05:00
@override
2022-11-26 14:16:02 -05:00
Future<VeilidRoutingContext> routingContext() async {
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('routing_context');
2022-03-03 20:45:39 -05:00
final sendPort = recvPort.sendPort;
2022-11-26 14:16:02 -05:00
_routingContext(sendPort.nativePort);
final id = await processFuturePlain(recvPort.first);
2022-12-02 22:52:03 -05:00
return VeilidRoutingContextFFI._(_Ctx(id, this));
2022-11-26 14:16:02 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<RouteBlob> newPrivateRoute() async {
final recvPort = ReceivePort('new_private_route');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
_newPrivateRoute(sendPort.nativePort);
2023-07-26 14:20:17 -04:00
return await processFutureJson(RouteBlob.fromJson, recvPort.first);
2022-11-26 14:16:02 -05:00
}
@override
2023-03-01 15:50:30 -05:00
Future<RouteBlob> newCustomPrivateRoute(
2023-07-26 14:20:17 -04:00
Stability stability, Sequencing sequencing) async {
final recvPort = ReceivePort('new_custom_private_route');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
2023-05-29 15:24:57 -04:00
_newCustomPrivateRoute(
sendPort.nativePort,
jsonEncode(stability).toNativeUtf8(),
jsonEncode(sequencing).toNativeUtf8());
2023-07-26 14:20:17 -04:00
return await processFutureJson(RouteBlob.fromJson, recvPort.first);
2022-11-26 14:16:02 -05:00
}
@override
2023-07-26 14:20:17 -04:00
Future<String> importRemotePrivateRoute(Uint8List blob) async {
2023-01-04 17:02:45 -05:00
final nativeEncodedBlob = base64UrlNoPadEncode(blob).toNativeUtf8();
2022-11-26 14:16:02 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('import_remote_private_route');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
_importRemotePrivateRoute(sendPort.nativePort, nativeEncodedBlob);
2023-07-26 14:20:17 -04:00
return await processFuturePlain(recvPort.first);
2022-03-03 20:45:39 -05:00
}
2022-11-26 14:16:02 -05:00
@override
2023-07-26 14:20:17 -04:00
Future<void> releasePrivateRoute(String key) async {
2022-12-28 22:53:58 -05:00
final nativeEncodedKey = key.toNativeUtf8();
2022-11-26 14:16:02 -05:00
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('release_private_route');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
_releasePrivateRoute(sendPort.nativePort, nativeEncodedKey);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-11-26 14:16:02 -05:00
}
2022-09-30 22:37:55 -04:00
@override
2023-07-26 14:20:17 -04:00
Future<void> appCallReply(String callId, Uint8List message) async {
2023-07-25 01:04:22 -04:00
final nativeCallId = callId.toNativeUtf8();
2023-01-04 17:02:45 -05:00
final nativeEncodedMessage = base64UrlNoPadEncode(message).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('app_call_reply');
2022-09-30 22:37:55 -04:00
final sendPort = recvPort.sendPort;
2023-06-16 11:57:55 -04:00
_appCallReply(sendPort.nativePort, nativeCallId, nativeEncodedMessage);
2023-07-26 14:20:17 -04:00
return await processFutureVoid(recvPort.first);
2022-09-30 22:37:55 -04:00
}
2022-12-28 22:53:58 -05:00
@override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('open_table_db');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_openTableDb(sendPort.nativePort, name.toNativeUtf8(), columnCount);
final id = await processFuturePlain(recvPort.first);
return VeilidTableDBFFI._(_TDB(id, this));
}
@override
Future<bool> deleteTableDB(String name) async {
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('delete_table_db');
2022-12-28 22:53:58 -05:00
final sendPort = recvPort.sendPort;
_deleteTableDb(sendPort.nativePort, name.toNativeUtf8());
final deleted = await processFuturePlain(recvPort.first);
return deleted;
}
2023-05-29 15:24:57 -04:00
@override
List<CryptoKind> validCryptoKinds() {
final vckString = _validCryptoKinds();
2023-07-25 01:04:22 -04:00
final vck = jsonDecode(vckString.toDartString()) as List<dynamic>;
2023-05-29 15:24:57 -04:00
_freeString(vckString);
2023-07-25 01:04:22 -04:00
return vck.map((v) => v as CryptoKind).toList();
2023-05-29 15:24:57 -04:00
}
@override
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async {
if (!validCryptoKinds().contains(kind)) {
2023-07-26 14:20:17 -04:00
throw const VeilidAPIExceptionGeneric('unsupported cryptosystem');
2023-05-29 15:24:57 -04:00
}
return VeilidCryptoSystemFFI._(this, kind);
}
@override
2023-07-26 14:20:17 -04:00
Future<VeilidCryptoSystem> bestCryptoSystem() async => VeilidCryptoSystemFFI._(this, _bestCryptoKind());
2023-05-29 15:24:57 -04:00
@override
2023-07-26 14:20:17 -04:00
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
Uint8List data, List<TypedSignature> signatures) async {
2023-05-29 15:24:57 -04:00
final nativeNodeIds = jsonEncode(nodeIds).toNativeUtf8();
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
final nativeSignatures = jsonEncode(signatures).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('verify_signatures');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_verifySignatures(
sendPort.nativePort, nativeNodeIds, nativeData, nativeSignatures);
2023-07-26 14:20:17 -04:00
return await processFutureJson(
2023-05-29 15:24:57 -04:00
jsonListConstructor<TypedKey>(TypedKey.fromJson), recvPort.first);
}
@override
Future<List<TypedSignature>> generateSignatures(
2023-07-26 14:20:17 -04:00
Uint8List data, List<TypedKeyPair> keyPairs) async {
2023-05-29 15:24:57 -04:00
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
final nativeKeyPairs = jsonEncode(keyPairs).toNativeUtf8();
2023-07-26 14:20:17 -04:00
final recvPort = ReceivePort('generate_signatures');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_generateSignatures(sendPort.nativePort, nativeData, nativeKeyPairs);
2023-07-26 14:20:17 -04:00
return await processFutureJson(
2023-05-29 15:24:57 -04:00
jsonListConstructor<TypedSignature>(TypedSignature.fromJson),
recvPort.first);
}
@override
Timestamp now() {
final ts = _now();
return Timestamp(value: BigInt.from(ts));
}
@override
2023-07-26 14:20:17 -04:00
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async {
final recvPort = ReceivePort('generate_key_pair');
2023-05-29 15:24:57 -04:00
final sendPort = recvPort.sendPort;
_generateKeyPair(sendPort.nativePort, kind);
2023-07-26 14:20:17 -04:00
return await processFutureJson(TypedKeyPair.fromJson, recvPort.first);
2023-05-29 15:24:57 -04:00
}
2022-11-26 14:16:02 -05:00
@override
Future<String> debug(String command) async {
2023-07-26 14:20:17 -04:00
final nativeCommand = command.toNativeUtf8();
final recvPort = ReceivePort('debug');
2022-11-26 14:16:02 -05:00
final sendPort = recvPort.sendPort;
_debug(sendPort.nativePort, nativeCommand);
return processFuturePlain(recvPort.first);
}
2022-02-09 09:47:36 -05:00
@override
2022-03-17 10:31:10 -04:00
String veilidVersionString() {
2022-02-09 09:47:36 -05:00
final versionString = _veilidVersionString();
2023-07-26 14:20:17 -04:00
final ret = versionString.toDartString();
2022-02-09 09:47:36 -05:00
_freeString(versionString);
return ret;
2022-02-06 21:18:42 -05:00
}
2022-02-09 09:47:36 -05:00
@override
2022-03-17 10:31:10 -04:00
VeilidVersion veilidVersion() {
2022-02-09 09:47:36 -05:00
final version = _veilidVersion();
return VeilidVersion(
version.major,
version.minor,
version.patch,
);
2022-02-06 21:18:42 -05:00
}
}