removing dev branch, many changes
This commit is contained in:
@@ -7,7 +7,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'base64url_no_pad.dart';
|
||||
import 'veilid_encoding.dart';
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
@@ -30,9 +30,8 @@ class _Ctx {
|
||||
// JS implementation of VeilidRoutingContext
|
||||
class VeilidRoutingContextJS implements VeilidRoutingContext {
|
||||
final _Ctx _ctx;
|
||||
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => {
|
||||
js_util.callMethod(wasm, "release_routing_context", [ctx.id])
|
||||
});
|
||||
static final Finalizer<_Ctx> _finalizer = Finalizer(
|
||||
(ctx) => js_util.callMethod(wasm, "release_routing_context", [ctx.id]));
|
||||
|
||||
VeilidRoutingContextJS._(this._ctx) {
|
||||
_finalizer.attach(this, _ctx, detach: this);
|
||||
@@ -48,15 +47,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));
|
||||
}
|
||||
|
||||
@@ -75,6 +76,254 @@ class VeilidRoutingContextJS implements VeilidRoutingContext {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm,
|
||||
"routing_context_app_message", [_ctx.id, target, encodedMessage]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DHTRecordDescriptor> createDHTRecord(
|
||||
CryptoKind kind, DHTSchema schema) async {
|
||||
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "routing_context_create_dht_record",
|
||||
[_ctx.id, kind, jsonEncode(schema)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DHTRecordDescriptor> openDHTRecord(
|
||||
TypedKey key, KeyPair? writer) async {
|
||||
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "routing_context_open_dht_record", [
|
||||
_ctx.id,
|
||||
jsonEncode(key),
|
||||
writer != null ? jsonEncode(writer) : null
|
||||
]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> closeDHTRecord(TypedKey key) {
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_close_dht_record", [_ctx.id, jsonEncode(key)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteDHTRecord(TypedKey key) {
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_delete_dht_record", [_ctx.id, jsonEncode(key)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ValueData?> getDHTValue(
|
||||
TypedKey key, int subkey, bool forceRefresh) async {
|
||||
final opt = await _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_get_dht_value",
|
||||
[_ctx.id, jsonEncode(key), subkey, forceRefresh]));
|
||||
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ValueData?> setDHTValue(
|
||||
TypedKey key, int subkey, Uint8List data) async {
|
||||
final opt = await _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_set_dht_value",
|
||||
[_ctx.id, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
|
||||
return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Timestamp> watchDHTValues(TypedKey key, ValueSubkeyRange subkeys,
|
||||
Timestamp expiration, int count) async {
|
||||
final ts = await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_watch_dht_values", [
|
||||
_ctx.id,
|
||||
jsonEncode(key),
|
||||
jsonEncode(subkeys),
|
||||
expiration.toString(),
|
||||
count
|
||||
]));
|
||||
return Timestamp.fromString(ts);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys) {
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm,
|
||||
"routing_context_cancel_dht_watch",
|
||||
[_ctx.id, jsonEncode(key), jsonEncode(subkeys)]));
|
||||
}
|
||||
}
|
||||
|
||||
// JS implementation of VeilidCryptoSystem
|
||||
class VeilidCryptoSystemJS implements VeilidCryptoSystem {
|
||||
final CryptoKind _kind;
|
||||
final VeilidJS _js;
|
||||
|
||||
VeilidCryptoSystemJS._(this._js, this._kind) {
|
||||
// Keep the reference
|
||||
_js;
|
||||
}
|
||||
|
||||
@override
|
||||
CryptoKind kind() {
|
||||
return _kind;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_cached_dh",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_compute_dh",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> randomBytes(int len) async {
|
||||
return base64UrlNoPadDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_bytes", [_kind, len])));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> defaultSaltLength() {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_default_salt_length", [_kind]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> hashPassword(Uint8List password, Uint8List salt) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_hash_password",
|
||||
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> verifyPassword(Uint8List password, String passwordHash) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify_password",
|
||||
[_kind, base64UrlNoPadEncode(password), passwordHash]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SharedSecret> deriveSharedSecret(
|
||||
Uint8List password, Uint8List salt) async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_derive_shared_secret", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(password),
|
||||
base64UrlNoPadEncode(salt)
|
||||
]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Nonce> randomNonce() async {
|
||||
return Nonce.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_nonce", [_kind]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SharedSecret> randomSharedSecret() async {
|
||||
return SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_random_shared_secret", [_kind]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<KeyPair> generateKeyPair() async {
|
||||
return KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_generate_key_pair", [_kind]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<HashDigest> generateHash(Uint8List data) async {
|
||||
return HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_generate_hash",
|
||||
[_kind, base64UrlNoPadEncode(data)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_key_pair",
|
||||
[_kind, jsonEncode(key), jsonEncode(secret)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> validateHash(Uint8List data, HashDigest hash) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_validate_hash",
|
||||
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async {
|
||||
return CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_distance",
|
||||
[_kind, jsonEncode(key1), jsonEncode(key2)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Signature> sign(
|
||||
PublicKey key, SecretKey secret, Uint8List data) async {
|
||||
return Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(wasm, "crypto_sign", [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
jsonEncode(secret),
|
||||
base64UrlNoPadEncode(data)
|
||||
]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "crypto_verify", [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signature),
|
||||
]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> aeadOverhead() {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "crypto_aead_overhead", [_kind]));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async {
|
||||
return base64UrlNoPadDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_decrypt_aead", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
|
||||
])));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
|
||||
SharedSecret sharedSecret, Uint8List? associatedData) async {
|
||||
return base64UrlNoPadDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "crypto_encrypt_aead", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret),
|
||||
associatedData != null ? base64UrlNoPadEncode(associatedData) : null
|
||||
])));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> cryptNoAuth(
|
||||
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async {
|
||||
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "crypto_crypt_no_auth", [
|
||||
_kind,
|
||||
base64UrlNoPadEncode(body),
|
||||
jsonEncode(nonce),
|
||||
jsonEncode(sharedSecret)
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
||||
class _TDBT {
|
||||
@@ -88,9 +337,8 @@ class _TDBT {
|
||||
// JS implementation of VeilidTableDBTransaction
|
||||
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
|
||||
final _TDBT _tdbt;
|
||||
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => {
|
||||
js_util.callMethod(wasm, "release_table_db_transaction", [tdbt.id])
|
||||
});
|
||||
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) =>
|
||||
js_util.callMethod(wasm, "release_table_db_transaction", [tdbt.id]));
|
||||
|
||||
VeilidTableDBTransactionJS._(this._tdbt) {
|
||||
_finalizer.attach(this, _tdbt, detach: this);
|
||||
@@ -138,9 +386,8 @@ class _TDB {
|
||||
// JS implementation of VeilidTableDB
|
||||
class VeilidTableDBJS extends VeilidTableDB {
|
||||
final _TDB _tdb;
|
||||
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => {
|
||||
js_util.callMethod(wasm, "release_table_db", [tdb.id])
|
||||
});
|
||||
static final Finalizer<_TDB> _finalizer = Finalizer(
|
||||
(tdb) => js_util.callMethod(wasm, "release_table_db", [tdb.id]));
|
||||
|
||||
VeilidTableDBJS._(this._tdb) {
|
||||
_finalizer.attach(this, _tdb, detach: this);
|
||||
@@ -152,13 +399,9 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
}
|
||||
|
||||
@override
|
||||
List<Uint8List> getKeys(int col) {
|
||||
String? s = js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id, col]);
|
||||
if (s == null) {
|
||||
throw VeilidAPIExceptionInternal("No db for id");
|
||||
}
|
||||
List<dynamic> jarr = jsonDecode(s);
|
||||
return jarr.map((e) => base64UrlNoPadDecode(e)).toList();
|
||||
Future<List<Uint8List>> getKeys(int col) async {
|
||||
return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode(
|
||||
await js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id, col])));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -190,7 +433,7 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> delete(int col, Uint8List key) {
|
||||
Future<Uint8List?> delete(int col, Uint8List key) {
|
||||
final encodedKey = base64UrlNoPadEncode(key);
|
||||
|
||||
return _wrapApiPromise(js_util
|
||||
@@ -203,16 +446,14 @@ class VeilidTableDBJS extends VeilidTableDB {
|
||||
class VeilidJS implements Veilid {
|
||||
@override
|
||||
void initializeVeilidCore(Map<String, dynamic> 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]);
|
||||
}
|
||||
|
||||
@@ -229,10 +470,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;
|
||||
}
|
||||
@@ -259,6 +498,50 @@ class VeilidJS implements Veilid {
|
||||
js_util.callMethod(wasm, "shutdown_veilid_core", []));
|
||||
}
|
||||
|
||||
@override
|
||||
List<CryptoKind> validCryptoKinds() {
|
||||
return jsonDecode(js_util.callMethod(wasm, "valid_crypto_kinds", []));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind) async {
|
||||
if (!validCryptoKinds().contains(kind)) {
|
||||
throw VeilidAPIExceptionGeneric("unsupported cryptosystem");
|
||||
}
|
||||
return VeilidCryptoSystemJS._(this, kind);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidCryptoSystem> bestCryptoSystem() async {
|
||||
return VeilidCryptoSystemJS._(
|
||||
this, js_util.callMethod(wasm, "best_crypto_kind", []));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
|
||||
Uint8List data, List<TypedSignature> signatures) async {
|
||||
return jsonListConstructor(TypedKey.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "verify_signatures", [
|
||||
jsonEncode(nodeIds),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signatures)
|
||||
]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<TypedSignature>> generateSignatures(
|
||||
Uint8List data, List<TypedKeyPair> keyPairs) async {
|
||||
return jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "generate_signatures",
|
||||
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async {
|
||||
return TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "generate_key_pair", [kind]))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<VeilidRoutingContext> routingContext() async {
|
||||
int id =
|
||||
@@ -268,23 +551,19 @@ class VeilidJS implements Veilid {
|
||||
|
||||
@override
|
||||
Future<RouteBlob> newPrivateRoute() async {
|
||||
Map<String, dynamic> blobJson = jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "new_private_route", [])));
|
||||
return RouteBlob.fromJson(blobJson);
|
||||
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "new_private_route", []))));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<RouteBlob> newCustomPrivateRoute(
|
||||
Stability stability, Sequencing sequencing) async {
|
||||
var stabilityString =
|
||||
jsonEncode(stability, toEncodable: veilidApiToEncodable);
|
||||
var sequencingString =
|
||||
jsonEncode(sequencing, toEncodable: veilidApiToEncodable);
|
||||
var stabilityString = jsonEncode(stability);
|
||||
var sequencingString = jsonEncode(sequencing);
|
||||
|
||||
Map<String, dynamic> blobJson = jsonDecode(await _wrapApiPromise(js_util
|
||||
return RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(
|
||||
wasm, "new_private_route", [stabilityString, sequencingString])));
|
||||
return RouteBlob.fromJson(blobJson);
|
||||
wasm, "new_private_route", [stabilityString, sequencingString]))));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -319,6 +598,11 @@ class VeilidJS implements Veilid {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "delete_table_db", [name]));
|
||||
}
|
||||
|
||||
@override
|
||||
Timestamp now() {
|
||||
return Timestamp.fromString(js_util.callMethod(wasm, "now", []));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> debug(String command) async {
|
||||
return await _wrapApiPromise(js_util.callMethod(wasm, "debug", [command]));
|
||||
|
Reference in New Issue
Block a user