api work
This commit is contained in:
		| @@ -5,98 +5,120 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: ansicolor | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "607f8fa9786f392043f169898923e6c59b4518242b68b8862eb8a8b7d9c30b4a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.1" | ||||
|   async: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: async | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.9.0" | ||||
|     version: "2.10.0" | ||||
|   boolean_selector: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: boolean_selector | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|     version: "2.1.1" | ||||
|   change_case: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: change_case | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "2757d850a43d333fd12d6cce49e2f1248ac89a16ae10ce4ca34d4c7d73286f3c" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.2" | ||||
|   characters: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: characters | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.2.1" | ||||
|   charcode: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: charcode | ||||
|       sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.1" | ||||
|   clock: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: clock | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|   collection: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: collection | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.16.0" | ||||
|     version: "1.17.0" | ||||
|   convert: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: convert | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.1" | ||||
|   cupertino_icons: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: cupertino_icons | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.5" | ||||
|   equatable: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: equatable | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.5" | ||||
|   fake_async: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: fake_async | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.1" | ||||
|   ffi: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: ffi | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.1" | ||||
|   file: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: file | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.1.4" | ||||
|   file_utils: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: file_utils | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: d1e64389a22649095c8405c9e177272caf05139255931c9ff30d53b5c9bcaa34 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.1" | ||||
|   flutter: | ||||
| @@ -108,14 +130,16 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: flutter_acrylic | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "646200d98e8dd2bd4ab931d4ba4f6b4cb899475d6401414017ba5d71b0fac42b" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.0+2" | ||||
|   flutter_lints: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: flutter_lints | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.1" | ||||
|   flutter_test: | ||||
| @@ -132,140 +156,160 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: globbing | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.0.0" | ||||
|   js: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: js | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.6.4" | ||||
|     version: "0.6.5" | ||||
|   lints: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: lints | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.1" | ||||
|   loggy: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: loggy | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "981e03162bbd3a5a843026f75f73d26e4a0d8aa035ae060456ca7b30dfd1e339" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.3" | ||||
|   matcher: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: matcher | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.12.12" | ||||
|     version: "0.12.13" | ||||
|   material_color_utilities: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: material_color_utilities | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.1.5" | ||||
|     version: "0.2.0" | ||||
|   meta: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: meta | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.8.0" | ||||
|   path: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: path | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.8.2" | ||||
|   path_provider: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: path_provider | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.11" | ||||
|   path_provider_android: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_android | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.22" | ||||
|   path_provider_ios: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_ios | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.11" | ||||
|   path_provider_linux: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_linux | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.7" | ||||
|   path_provider_macos: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_macos | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.6" | ||||
|   path_provider_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_platform_interface | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.5" | ||||
|   path_provider_windows: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: path_provider_windows | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.3" | ||||
|   platform: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: platform | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.0" | ||||
|   platform_info: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: platform_info | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "012e73712166cf0b56d3eb95c0d33491f56b428c169eca385f036448474147e4" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.2.0" | ||||
|   plugin_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: plugin_platform_interface | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.3" | ||||
|   process: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: process | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.2.4" | ||||
|   quiver: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: quiver | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "93982981971e812c94d4a6fa3a57b89f9ec12b38b6380cd3c1370c3b01e4580e" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.0" | ||||
|   sky_engine: | ||||
| @@ -277,65 +321,74 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: source_span | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.9.0" | ||||
|     version: "1.9.1" | ||||
|   stack_trace: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: stack_trace | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.10.0" | ||||
|     version: "1.11.0" | ||||
|   stream_channel: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: stream_channel | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.0" | ||||
|     version: "2.1.1" | ||||
|   string_scanner: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: string_scanner | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.1.1" | ||||
|     version: "1.2.0" | ||||
|   system_info2: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: system_info2 | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: af2f948e3f31a3367a049932a8ad59faf0063ecf836a020d975b9f41566d8bc9 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.0.2" | ||||
|   term_glyph: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: term_glyph | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.2.1" | ||||
|   test_api: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: test_api | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.4.12" | ||||
|     version: "0.4.16" | ||||
|   typed_data: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: typed_data | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.1" | ||||
|   vector_math: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: vector_math | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.1.2" | ||||
|     version: "2.1.4" | ||||
|   veilid: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -347,21 +400,24 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: win32 | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: ca121dbbadb3e43b449053feab0cdf3f2bff93b107cacf0290e3d29f717374b6 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.1.2" | ||||
|   xdg_directories: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: xdg_directories | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.2.0+2" | ||||
|   xterm: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: xterm | ||||
|       url: "https://pub.dartlang.org" | ||||
|       sha256: "990286eead883ff5ad9b8ea7674183dced2fe5421771e95ce32cbaa9117d24d8" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.4.0" | ||||
| sdks: | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| import 'dart:convert'; | ||||
| import 'dart:typed_data'; | ||||
|  | ||||
| String base64UrlNoPadEncode(List<int> bytes) { | ||||
|   var x = base64Url.encode(bytes); | ||||
|   while (x.endsWith('=')) { | ||||
|     x = x.substring(0, x.length - 1); | ||||
|   } | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| Uint8List base64UrlNoPadDecode(String source) { | ||||
|   source = base64.normalize(source); | ||||
|   return base64.decode(source); | ||||
| } | ||||
							
								
								
									
										277
									
								
								veilid-flutter/lib/routing_context.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								veilid-flutter/lib/routing_context.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,277 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:typed_data'; | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:change_case/change_case.dart'; | ||||
|  | ||||
| import 'base64url_no_pad.dart'; | ||||
| import 'veilid.dart'; | ||||
|  | ||||
| ////////////////////////////////////// | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// DHT Schema | ||||
|  | ||||
| abstract class DHTSchema { | ||||
|   factory DHTSchema.fromJson(dynamic json) { | ||||
|     switch (json["kind"]) { | ||||
|       case "DFLT": | ||||
|         { | ||||
|           return DHTSchemaDFLT(oCnt: json["o_cnt"]); | ||||
|         } | ||||
|       case "SMPL": | ||||
|         { | ||||
|           return DHTSchemaSMPL( | ||||
|               oCnt: json["o_cnt"], | ||||
|               members: List<DHTSchemaMember>.from( | ||||
|                   json['members'].map((j) => DHTSchemaMember.fromJson(j)))); | ||||
|         } | ||||
|       default: | ||||
|         { | ||||
|           throw VeilidAPIExceptionInternal( | ||||
|               "Invalid VeilidAPIException type: ${json['kind']}"); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|   Map<String, dynamic> get json; | ||||
| } | ||||
|  | ||||
| class DHTSchemaDFLT implements DHTSchema { | ||||
|   final int oCnt; | ||||
|   // | ||||
|   DHTSchemaDFLT({ | ||||
|     required this.oCnt, | ||||
|   }) { | ||||
|     if (oCnt < 0 || oCnt > 65535) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "value out of range", "oCnt", oCnt.toString()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'kind': "DFLT", | ||||
|       'o_cnt': oCnt, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class DHTSchemaMember { | ||||
|   Key mKey; | ||||
|   int mCnt; | ||||
|  | ||||
|   DHTSchemaMember({ | ||||
|     required this.mKey, | ||||
|     required this.mCnt, | ||||
|   }) { | ||||
|     if (mCnt < 0 || mCnt > 65535) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "value out of range", "mCnt", mCnt.toString()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'm_key': mKey, | ||||
|       'm_cnt': mCnt, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   DHTSchemaMember.fromJson(dynamic json) | ||||
|       : mKey = json['m_key'], | ||||
|         mCnt = json['m_cnt']; | ||||
| } | ||||
|  | ||||
| class DHTSchemaSMPL implements DHTSchema { | ||||
|   final int oCnt; | ||||
|   final List<DHTSchemaMember> members; | ||||
|   // | ||||
|   DHTSchemaSMPL({ | ||||
|     required this.oCnt, | ||||
|     required this.members, | ||||
|   }) { | ||||
|     if (oCnt < 0 || oCnt > 65535) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "value out of range", "oCnt", oCnt.toString()); | ||||
|     } | ||||
|   } | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'kind': "SMPL", | ||||
|       'o_cnt': oCnt, | ||||
|       'members': members.map((p) => p.json).toList(), | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// DHTRecordDescriptor | ||||
|  | ||||
| class DHTRecordDescriptor { | ||||
|   TypedKey key; | ||||
|   Key owner; | ||||
|   Key? ownerSecret; | ||||
|   DHTSchema schema; | ||||
|  | ||||
|   DHTRecordDescriptor({ | ||||
|     required this.key, | ||||
|     required this.owner, | ||||
|     this.ownerSecret, | ||||
|     required this.schema, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'key': key.toString(), | ||||
|       'owner': owner, | ||||
|       'owner_secret': ownerSecret, | ||||
|       'schema': schema.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   DHTRecordDescriptor.fromJson(dynamic json) | ||||
|       : key = TypedKey.fromString(json['key']), | ||||
|         owner = json['owner'], | ||||
|         ownerSecret = json['owner_secret'], | ||||
|         schema = DHTSchema.fromJson(json['schema']); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// ValueSubkeyRange | ||||
|  | ||||
| class ValueSubkeyRange { | ||||
|   final int low; | ||||
|   final int high; | ||||
|  | ||||
|   ValueSubkeyRange({ | ||||
|     required this.low, | ||||
|     required this.high, | ||||
|   }) { | ||||
|     if (low < 0 || low > high) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "invalid range", "low", low.toString()); | ||||
|     } | ||||
|     if (high < 0) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "invalid range", "high", high.toString()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ValueSubkeyRange.fromJson(dynamic json) | ||||
|       : low = json[0], | ||||
|         high = json[1] { | ||||
|     if ((json as List<int>).length != 2) { | ||||
|       throw VeilidAPIExceptionInvalidArgument( | ||||
|           "not a pair of integers", "json", json.toString()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   List<dynamic> get json { | ||||
|     return [low, high]; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// ValueData | ||||
|  | ||||
| class ValueData { | ||||
|   final int seq; | ||||
|   final Uint8List data; | ||||
|   final Key writer; | ||||
|  | ||||
|   ValueData({ | ||||
|     required this.seq, | ||||
|     required this.data, | ||||
|     required this.writer, | ||||
|   }); | ||||
|  | ||||
|   ValueData.fromJson(dynamic json) | ||||
|       : seq = json['seq'], | ||||
|         data = base64UrlNoPadDecode(json['data']), | ||||
|         writer = json['writer']; | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return {'seq': seq, 'data': base64UrlNoPadEncode(data), 'writer': writer}; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// Stability | ||||
|  | ||||
| enum Stability { | ||||
|   lowLatency, | ||||
|   reliable, | ||||
| } | ||||
|  | ||||
| extension StabilityExt on Stability { | ||||
|   String get json { | ||||
|     return name.toPascalCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Stability stabilityFromJson(String j) { | ||||
|   return Stability.values.byName(j.toCamelCase()); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// Sequencing | ||||
|  | ||||
| enum Sequencing { | ||||
|   noPreference, | ||||
|   preferOrdered, | ||||
|   ensureOrdered, | ||||
| } | ||||
|  | ||||
| extension SequencingExt on Sequencing { | ||||
|   String get json { | ||||
|     return name.toPascalCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| Sequencing sequencingFromJson(String j) { | ||||
|   return Sequencing.values.byName(j.toCamelCase()); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// RouteBlob | ||||
| class RouteBlob { | ||||
|   final String routeId; | ||||
|   final Uint8List blob; | ||||
|  | ||||
|   RouteBlob(this.routeId, this.blob); | ||||
|  | ||||
|   RouteBlob.fromJson(dynamic json) | ||||
|       : routeId = json['route_id'], | ||||
|         blob = base64UrlNoPadDecode(json['blob']); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return {'route_id': routeId, 'blob': base64UrlNoPadEncode(blob)}; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidRoutingContext | ||||
|  | ||||
| abstract class VeilidRoutingContext { | ||||
|   // Modifiers | ||||
|   VeilidRoutingContext withPrivacy(); | ||||
|   VeilidRoutingContext withCustomPrivacy(Stability stability); | ||||
|   VeilidRoutingContext withSequencing(Sequencing sequencing); | ||||
|  | ||||
|   // App call/message | ||||
|   Future<Uint8List> appCall(String target, Uint8List request); | ||||
|   Future<void> appMessage(String target, Uint8List message); | ||||
|  | ||||
|   // DHT Operations | ||||
|   Future<DHTRecordDescriptor> createDHTRecord( | ||||
|       CryptoKind kind, DHTSchema schema); | ||||
|   Future<DHTRecordDescriptor> openDHTRecord(TypedKey key, KeyPair? writer); | ||||
|   Future<void> closeDHTRecord(TypedKey key); | ||||
|   Future<void> deleteDHTRecord(TypedKey key); | ||||
|   Future<ValueData?> getDHTValue(TypedKey key, int subkey, bool forceRefresh); | ||||
|   Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data); | ||||
|   Future<Timestamp> watchDHTValues( | ||||
|       TypedKey key, ValueSubkeyRange subkeys, Timestamp expiration, int count); | ||||
|   Future<bool> cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										286
									
								
								veilid-flutter/lib/veilid_api_exception.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								veilid-flutter/lib/veilid_api_exception.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| ////////////////////////////////////// | ||||
| /// VeilidAPIException | ||||
|  | ||||
| abstract class VeilidAPIException implements Exception { | ||||
|   factory VeilidAPIException.fromJson(dynamic json) { | ||||
|     switch (json["kind"]) { | ||||
|       case "NotInitialized": | ||||
|         { | ||||
|           return VeilidAPIExceptionNotInitialized(); | ||||
|         } | ||||
|       case "AlreadyInitialized": | ||||
|         { | ||||
|           return VeilidAPIExceptionAlreadyInitialized(); | ||||
|         } | ||||
|       case "Timeout": | ||||
|         { | ||||
|           return VeilidAPIExceptionTimeout(); | ||||
|         } | ||||
|       case "TryAgain": | ||||
|         { | ||||
|           return VeilidAPIExceptionTryAgain(); | ||||
|         } | ||||
|       case "Shutdown": | ||||
|         { | ||||
|           return VeilidAPIExceptionShutdown(); | ||||
|         } | ||||
|       case "InvalidTarget": | ||||
|         { | ||||
|           return VeilidAPIExceptionInvalidTarget(); | ||||
|         } | ||||
|       case "NoConnection": | ||||
|         { | ||||
|           return VeilidAPIExceptionNoConnection(json["message"]); | ||||
|         } | ||||
|       case "KeyNotFound": | ||||
|         { | ||||
|           return VeilidAPIExceptionKeyNotFound(json["key"]); | ||||
|         } | ||||
|       case "Internal": | ||||
|         { | ||||
|           return VeilidAPIExceptionInternal(json["message"]); | ||||
|         } | ||||
|       case "Unimplemented": | ||||
|         { | ||||
|           return VeilidAPIExceptionUnimplemented(json["unimplemented"]); | ||||
|         } | ||||
|       case "ParseError": | ||||
|         { | ||||
|           return VeilidAPIExceptionParseError(json["message"], json["value"]); | ||||
|         } | ||||
|       case "InvalidArgument": | ||||
|         { | ||||
|           return VeilidAPIExceptionInvalidArgument( | ||||
|               json["context"], json["argument"], json["value"]); | ||||
|         } | ||||
|       case "MissingArgument": | ||||
|         { | ||||
|           return VeilidAPIExceptionMissingArgument( | ||||
|               json["context"], json["argument"]); | ||||
|         } | ||||
|       case "Generic": | ||||
|         { | ||||
|           return VeilidAPIExceptionGeneric(json["message"]); | ||||
|         } | ||||
|       default: | ||||
|         { | ||||
|           throw VeilidAPIExceptionInternal( | ||||
|               "Invalid VeilidAPIException type: ${json['kind']}"); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   String toDisplayError(); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionNotInitialized implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: NotInitialized"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Not initialized"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionAlreadyInitialized implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: AlreadyInitialized"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Already initialized"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionTimeout implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: Timeout"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Timeout"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionTryAgain implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: TryAgain"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Try again"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionShutdown implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: Shutdown"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Currently shut down"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionInvalidTarget implements VeilidAPIException { | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: InvalidTarget"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Invalid target"; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionNoConnection implements VeilidAPIException { | ||||
|   final String message; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: NoConnection (message: $message)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "No connection: $message"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionNoConnection(this.message); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionKeyNotFound implements VeilidAPIException { | ||||
|   final String key; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: KeyNotFound (key: $key)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Key not found: $key"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionKeyNotFound(this.key); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionInternal implements VeilidAPIException { | ||||
|   final String message; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: Internal ($message)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Internal error: $message"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionInternal(this.message); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionUnimplemented implements VeilidAPIException { | ||||
|   final String message; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: Unimplemented ($message)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Unimplemented: $message"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionUnimplemented(this.message); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionParseError implements VeilidAPIException { | ||||
|   final String message; | ||||
|   final String value; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: ParseError ($message)\n    value: $value"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Parse error: $message"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionParseError(this.message, this.value); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionInvalidArgument implements VeilidAPIException { | ||||
|   final String context; | ||||
|   final String argument; | ||||
|   final String value; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: InvalidArgument ($context:$argument)\n    value: $value"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Invalid argument for $context: $argument"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionInvalidArgument(this.context, this.argument, this.value); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionMissingArgument implements VeilidAPIException { | ||||
|   final String context; | ||||
|   final String argument; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: MissingArgument ($context:$argument)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return "Missing argument for $context: $argument"; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionMissingArgument(this.context, this.argument); | ||||
| } | ||||
|  | ||||
| class VeilidAPIExceptionGeneric implements VeilidAPIException { | ||||
|   final String message; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "VeilidAPIException: Generic (message: $message)"; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toDisplayError() { | ||||
|     return message; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   VeilidAPIExceptionGeneric(this.message); | ||||
| } | ||||
							
								
								
									
										744
									
								
								veilid-flutter/lib/veilid_config.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										744
									
								
								veilid-flutter/lib/veilid_config.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,744 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:typed_data'; | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:change_case/change_case.dart'; | ||||
|  | ||||
| import 'veilid_encoding.dart'; | ||||
| import 'veilid.dart'; | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidConfigLogLevel | ||||
|  | ||||
| enum VeilidConfigLogLevel { | ||||
|   off, | ||||
|   error, | ||||
|   warn, | ||||
|   info, | ||||
|   debug, | ||||
|   trace, | ||||
| } | ||||
|  | ||||
| extension VeilidConfigLogLevelExt on VeilidConfigLogLevel { | ||||
|   String get json { | ||||
|     return name.toPascalCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| VeilidConfigLogLevel veilidConfigLogLevelFromJson(String j) { | ||||
|   return VeilidConfigLogLevel.values.byName(j.toCamelCase()); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidConfig | ||||
|  | ||||
| class VeilidConfigHTTPS { | ||||
|   bool enabled; | ||||
|   String listenAddress; | ||||
|   String path; | ||||
|   String? url; | ||||
|  | ||||
|   VeilidConfigHTTPS({ | ||||
|     required this.enabled, | ||||
|     required this.listenAddress, | ||||
|     required this.path, | ||||
|     this.url, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'listen_address': listenAddress, | ||||
|       'path': path, | ||||
|       'url': url | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigHTTPS.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         path = json['path'], | ||||
|         url = json['url']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigHTTP { | ||||
|   bool enabled; | ||||
|   String listenAddress; | ||||
|   String path; | ||||
|   String? url; | ||||
|  | ||||
|   VeilidConfigHTTP({ | ||||
|     required this.enabled, | ||||
|     required this.listenAddress, | ||||
|     required this.path, | ||||
|     this.url, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'listen_address': listenAddress, | ||||
|       'path': path, | ||||
|       'url': url | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigHTTP.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         path = json['path'], | ||||
|         url = json['url']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigApplication { | ||||
|   VeilidConfigHTTPS https; | ||||
|   VeilidConfigHTTP http; | ||||
|  | ||||
|   VeilidConfigApplication({ | ||||
|     required this.https, | ||||
|     required this.http, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'https': https.json, | ||||
|       'http': http.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigApplication.fromJson(dynamic json) | ||||
|       : https = VeilidConfigHTTPS.fromJson(json['https']), | ||||
|         http = VeilidConfigHTTP.fromJson(json['http']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigUDP { | ||||
|   bool enabled; | ||||
|   int socketPoolSize; | ||||
|   String listenAddress; | ||||
|   String? publicAddress; | ||||
|  | ||||
|   VeilidConfigUDP( | ||||
|       {required this.enabled, | ||||
|       required this.socketPoolSize, | ||||
|       required this.listenAddress, | ||||
|       this.publicAddress}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'socket_pool_size': socketPoolSize, | ||||
|       'listen_address': listenAddress, | ||||
|       'public_address': publicAddress, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigUDP.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         socketPoolSize = json['socket_pool_size'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         publicAddress = json['publicAddress']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigTCP { | ||||
|   bool connect; | ||||
|   bool listen; | ||||
|   int maxConnections; | ||||
|   String listenAddress; | ||||
|   String? publicAddress; | ||||
|  | ||||
|   VeilidConfigTCP( | ||||
|       {required this.connect, | ||||
|       required this.listen, | ||||
|       required this.maxConnections, | ||||
|       required this.listenAddress, | ||||
|       this.publicAddress}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'connect': connect, | ||||
|       'listen': listen, | ||||
|       'max_connections': maxConnections, | ||||
|       'listen_address': listenAddress, | ||||
|       'public_address': publicAddress, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigTCP.fromJson(dynamic json) | ||||
|       : connect = json['connect'], | ||||
|         listen = json['listen'], | ||||
|         maxConnections = json['max_connections'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         publicAddress = json['publicAddress']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigWS { | ||||
|   bool connect; | ||||
|   bool listen; | ||||
|   int maxConnections; | ||||
|   String listenAddress; | ||||
|   String path; | ||||
|   String? url; | ||||
|  | ||||
|   VeilidConfigWS( | ||||
|       {required this.connect, | ||||
|       required this.listen, | ||||
|       required this.maxConnections, | ||||
|       required this.listenAddress, | ||||
|       required this.path, | ||||
|       this.url}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'connect': connect, | ||||
|       'listen': listen, | ||||
|       'max_connections': maxConnections, | ||||
|       'listen_address': listenAddress, | ||||
|       'path': path, | ||||
|       'url': url, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigWS.fromJson(dynamic json) | ||||
|       : connect = json['connect'], | ||||
|         listen = json['listen'], | ||||
|         maxConnections = json['max_connections'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         path = json['path'], | ||||
|         url = json['url']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigWSS { | ||||
|   bool connect; | ||||
|   bool listen; | ||||
|   int maxConnections; | ||||
|   String listenAddress; | ||||
|   String path; | ||||
|   String? url; | ||||
|  | ||||
|   VeilidConfigWSS( | ||||
|       {required this.connect, | ||||
|       required this.listen, | ||||
|       required this.maxConnections, | ||||
|       required this.listenAddress, | ||||
|       required this.path, | ||||
|       this.url}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'connect': connect, | ||||
|       'listen': listen, | ||||
|       'max_connections': maxConnections, | ||||
|       'listen_address': listenAddress, | ||||
|       'path': path, | ||||
|       'url': url, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigWSS.fromJson(dynamic json) | ||||
|       : connect = json['connect'], | ||||
|         listen = json['listen'], | ||||
|         maxConnections = json['max_connections'], | ||||
|         listenAddress = json['listen_address'], | ||||
|         path = json['path'], | ||||
|         url = json['url']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigProtocol { | ||||
|   VeilidConfigUDP udp; | ||||
|   VeilidConfigTCP tcp; | ||||
|   VeilidConfigWS ws; | ||||
|   VeilidConfigWSS wss; | ||||
|  | ||||
|   VeilidConfigProtocol({ | ||||
|     required this.udp, | ||||
|     required this.tcp, | ||||
|     required this.ws, | ||||
|     required this.wss, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'udp': udp.json, | ||||
|       'tcp': tcp.json, | ||||
|       'ws': ws.json, | ||||
|       'wss': wss.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigProtocol.fromJson(dynamic json) | ||||
|       : udp = VeilidConfigUDP.fromJson(json['udp']), | ||||
|         tcp = VeilidConfigTCP.fromJson(json['tcp']), | ||||
|         ws = VeilidConfigWS.fromJson(json['ws']), | ||||
|         wss = VeilidConfigWSS.fromJson(json['wss']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigTLS { | ||||
|   String certificatePath; | ||||
|   String privateKeyPath; | ||||
|   int connectionInitialTimeoutMs; | ||||
|  | ||||
|   VeilidConfigTLS({ | ||||
|     required this.certificatePath, | ||||
|     required this.privateKeyPath, | ||||
|     required this.connectionInitialTimeoutMs, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'certificate_path': certificatePath, | ||||
|       'private_key_path': privateKeyPath, | ||||
|       'connection_initial_timeout_ms': connectionInitialTimeoutMs, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigTLS.fromJson(dynamic json) | ||||
|       : certificatePath = json['certificate_path'], | ||||
|         privateKeyPath = json['private_key_path'], | ||||
|         connectionInitialTimeoutMs = json['connection_initial_timeout_ms']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigDHT { | ||||
|   int resolveNodeTimeoutMs; | ||||
|   int resolveNodeCount; | ||||
|   int resolveNodeFanout; | ||||
|   int maxFindNodeCount; | ||||
|   int getValueTimeoutMs; | ||||
|   int getValueCount; | ||||
|   int getValueFanout; | ||||
|   int setValueTimeoutMs; | ||||
|   int setValueCount; | ||||
|   int setValueFanout; | ||||
|   int minPeerCount; | ||||
|   int minPeerRefreshTimeMs; | ||||
|   int validateDialInfoReceiptTimeMs; | ||||
|   int localSubkeyCacheSize; | ||||
|   int localMaxSubkeyCacheMemoryMb; | ||||
|   int remoteSubkeyCacheSize; | ||||
|   int remoteMaxRecords; | ||||
|   int remoteMaxSubkeyCacheMemoryMb; | ||||
|   int remoteMaxStorageSpaceMb; | ||||
|  | ||||
|   VeilidConfigDHT( | ||||
|       {required this.resolveNodeTimeoutMs, | ||||
|       required this.resolveNodeCount, | ||||
|       required this.resolveNodeFanout, | ||||
|       required this.maxFindNodeCount, | ||||
|       required this.getValueTimeoutMs, | ||||
|       required this.getValueCount, | ||||
|       required this.getValueFanout, | ||||
|       required this.setValueTimeoutMs, | ||||
|       required this.setValueCount, | ||||
|       required this.setValueFanout, | ||||
|       required this.minPeerCount, | ||||
|       required this.minPeerRefreshTimeMs, | ||||
|       required this.validateDialInfoReceiptTimeMs, | ||||
|       required this.localSubkeyCacheSize, | ||||
|       required this.localMaxSubkeyCacheMemoryMb, | ||||
|       required this.remoteSubkeyCacheSize, | ||||
|       required this.remoteMaxRecords, | ||||
|       required this.remoteMaxSubkeyCacheMemoryMb, | ||||
|       required this.remoteMaxStorageSpaceMb}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'max_find_node_count': maxFindNodeCount, | ||||
|       'resolve_node_timeout_ms': resolveNodeTimeoutMs, | ||||
|       'resolve_node_count': resolveNodeCount, | ||||
|       'resolve_node_fanout': resolveNodeFanout, | ||||
|       'get_value_timeout_ms': getValueTimeoutMs, | ||||
|       'get_value_count': getValueCount, | ||||
|       'get_value_fanout': getValueFanout, | ||||
|       'set_value_timeout_ms': setValueTimeoutMs, | ||||
|       'set_value_count': setValueCount, | ||||
|       'set_value_fanout': setValueFanout, | ||||
|       'min_peer_count': minPeerCount, | ||||
|       'min_peer_refresh_time_ms': minPeerRefreshTimeMs, | ||||
|       'validate_dial_info_receipt_time_ms': validateDialInfoReceiptTimeMs, | ||||
|       'local_subkey_cache_size: 128': localSubkeyCacheSize, | ||||
|       'local_max_subkey_cache_memory_mb': localMaxSubkeyCacheMemoryMb, | ||||
|       'remote_subkey_cache_size': remoteSubkeyCacheSize, | ||||
|       'remote_max_records': remoteMaxRecords, | ||||
|       'remote_max_subkey_cache_memory_mb': remoteMaxSubkeyCacheMemoryMb, | ||||
|       'remote_max_storage_space_mb': remoteMaxStorageSpaceMb, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigDHT.fromJson(dynamic json) | ||||
|       : resolveNodeTimeoutMs = json['resolve_node_timeout_ms'], | ||||
|         resolveNodeCount = json['resolve_node_count'], | ||||
|         resolveNodeFanout = json['resolve_node_fanout'], | ||||
|         maxFindNodeCount = json['max_find_node_count'], | ||||
|         getValueTimeoutMs = json['get_value_timeout_ms'], | ||||
|         getValueCount = json['get_value_count'], | ||||
|         getValueFanout = json['get_value_fanout'], | ||||
|         setValueTimeoutMs = json['set_value_timeout_ms'], | ||||
|         setValueCount = json['set_value_count'], | ||||
|         setValueFanout = json['set_value_fanout'], | ||||
|         minPeerCount = json['min_peer_count'], | ||||
|         minPeerRefreshTimeMs = json['min_peer_refresh_time_ms'], | ||||
|         validateDialInfoReceiptTimeMs = | ||||
|             json['validate_dial_info_receipt_time_ms'], | ||||
|         localSubkeyCacheSize = json['local_subkey_cache_size'], | ||||
|         localMaxSubkeyCacheMemoryMb = json['local_max_subkey_cache_memory_mb'], | ||||
|         remoteSubkeyCacheSize = json['remote_subkey_cache_size'], | ||||
|         remoteMaxRecords = json['remote_max_records'], | ||||
|         remoteMaxSubkeyCacheMemoryMb = | ||||
|             json['remote_max_subkey_cache_memory_mb'], | ||||
|         remoteMaxStorageSpaceMb = json['remote_max_storage_space_mb']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigRPC { | ||||
|   int concurrency; | ||||
|   int queueSize; | ||||
|   int? maxTimestampBehindMs; | ||||
|   int? maxTimestampAheadMs; | ||||
|   int timeoutMs; | ||||
|   int maxRouteHopCount; | ||||
|   int defaultRouteHopCount; | ||||
|  | ||||
|   VeilidConfigRPC( | ||||
|       {required this.concurrency, | ||||
|       required this.queueSize, | ||||
|       this.maxTimestampBehindMs, | ||||
|       this.maxTimestampAheadMs, | ||||
|       required this.timeoutMs, | ||||
|       required this.maxRouteHopCount, | ||||
|       required this.defaultRouteHopCount}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'concurrency': concurrency, | ||||
|       'queue_size': queueSize, | ||||
|       'max_timestamp_behind_ms': maxTimestampBehindMs, | ||||
|       'max_timestamp_ahead_ms': maxTimestampAheadMs, | ||||
|       'timeout_ms': timeoutMs, | ||||
|       'max_route_hop_count': maxRouteHopCount, | ||||
|       'default_route_hop_count': defaultRouteHopCount, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigRPC.fromJson(dynamic json) | ||||
|       : concurrency = json['concurrency'], | ||||
|         queueSize = json['queue_size'], | ||||
|         maxTimestampBehindMs = json['max_timestamp_behind_ms'], | ||||
|         maxTimestampAheadMs = json['max_timestamp_ahead_ms'], | ||||
|         timeoutMs = json['timeout_ms'], | ||||
|         maxRouteHopCount = json['max_route_hop_count'], | ||||
|         defaultRouteHopCount = json['default_route_hop_count']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigRoutingTable { | ||||
|   List<Key> nodeId; | ||||
|   List<Key> nodeIdSecret; | ||||
|   List<String> bootstrap; | ||||
|   int limitOverAttached; | ||||
|   int limitFullyAttached; | ||||
|   int limitAttachedStrong; | ||||
|   int limitAttachedGood; | ||||
|   int limitAttachedWeak; | ||||
|  | ||||
|   VeilidConfigRoutingTable({ | ||||
|     required this.nodeId, | ||||
|     required this.nodeIdSecret, | ||||
|     required this.bootstrap, | ||||
|     required this.limitOverAttached, | ||||
|     required this.limitFullyAttached, | ||||
|     required this.limitAttachedStrong, | ||||
|     required this.limitAttachedGood, | ||||
|     required this.limitAttachedWeak, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'node_id': nodeId.map((p) => p.json).toList(), | ||||
|       'node_id_secret': nodeIdSecret.map((p) => p.json).toList(), | ||||
|       'bootstrap': bootstrap.map((p) => p).toList(), | ||||
|       'limit_over_attached': limitOverAttached, | ||||
|       'limit_fully_attached': limitFullyAttached, | ||||
|       'limit_attached_strong': limitAttachedStrong, | ||||
|       'limit_attached_good': limitAttachedGood, | ||||
|       'limit_attached_weak': limitAttachedWeak, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigRoutingTable.fromJson(dynamic json) | ||||
|       : nodeId = List<Key>.from(json['node_id'].map((j) => Key.fromJson(j))), | ||||
|         nodeIdSecret = | ||||
|             List<Key>.from(json['node_id_secret'].map((j) => Key.fromJson(j))), | ||||
|         bootstrap = List<String>.from(json['bootstrap'].map((j) => j)), | ||||
|         limitOverAttached = json['limit_over_attached'], | ||||
|         limitFullyAttached = json['limit_fully_attached'], | ||||
|         limitAttachedStrong = json['limit_attached_strong'], | ||||
|         limitAttachedGood = json['limit_attached_good'], | ||||
|         limitAttachedWeak = json['limit_attached_weak']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigNetwork { | ||||
|   int connectionInitialTimeoutMs; | ||||
|   int connectionInactivityTimeoutMs; | ||||
|   int maxConnectionsPerIp4; | ||||
|   int maxConnectionsPerIp6Prefix; | ||||
|   int maxConnectionsPerIp6PrefixSize; | ||||
|   int maxConnectionFrequencyPerMin; | ||||
|   int clientWhitelistTimeoutMs; | ||||
|   int reverseConnectionReceiptTimeMs; | ||||
|   int holePunchReceiptTimeMs; | ||||
|   VeilidConfigRoutingTable routingTable; | ||||
|   VeilidConfigRPC rpc; | ||||
|   VeilidConfigDHT dht; | ||||
|   bool upnp; | ||||
|   bool detectAddressChanges; | ||||
|   int restrictedNatRetries; | ||||
|   VeilidConfigTLS tls; | ||||
|   VeilidConfigApplication application; | ||||
|   VeilidConfigProtocol protocol; | ||||
|  | ||||
|   VeilidConfigNetwork({ | ||||
|     required this.connectionInitialTimeoutMs, | ||||
|     required this.connectionInactivityTimeoutMs, | ||||
|     required this.maxConnectionsPerIp4, | ||||
|     required this.maxConnectionsPerIp6Prefix, | ||||
|     required this.maxConnectionsPerIp6PrefixSize, | ||||
|     required this.maxConnectionFrequencyPerMin, | ||||
|     required this.clientWhitelistTimeoutMs, | ||||
|     required this.reverseConnectionReceiptTimeMs, | ||||
|     required this.holePunchReceiptTimeMs, | ||||
|     required this.routingTable, | ||||
|     required this.rpc, | ||||
|     required this.dht, | ||||
|     required this.upnp, | ||||
|     required this.detectAddressChanges, | ||||
|     required this.restrictedNatRetries, | ||||
|     required this.tls, | ||||
|     required this.application, | ||||
|     required this.protocol, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'connection_initial_timeout_ms': connectionInitialTimeoutMs, | ||||
|       'connection_inactivity_timeout_ms': connectionInactivityTimeoutMs, | ||||
|       'max_connections_per_ip4': maxConnectionsPerIp4, | ||||
|       'max_connections_per_ip6_prefix': maxConnectionsPerIp6Prefix, | ||||
|       'max_connections_per_ip6_prefix_size': maxConnectionsPerIp6PrefixSize, | ||||
|       'max_connection_frequency_per_min': maxConnectionFrequencyPerMin, | ||||
|       'client_whitelist_timeout_ms': clientWhitelistTimeoutMs, | ||||
|       'reverse_connection_receipt_time_ms': reverseConnectionReceiptTimeMs, | ||||
|       'hole_punch_receipt_time_ms': holePunchReceiptTimeMs, | ||||
|       'routing_table': routingTable.json, | ||||
|       'rpc': rpc.json, | ||||
|       'dht': dht.json, | ||||
|       'upnp': upnp, | ||||
|       'detect_address_changes': detectAddressChanges, | ||||
|       'restricted_nat_retries': restrictedNatRetries, | ||||
|       'tls': tls.json, | ||||
|       'application': application.json, | ||||
|       'protocol': protocol.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigNetwork.fromJson(dynamic json) | ||||
|       : connectionInitialTimeoutMs = json['connection_initial_timeout_ms'], | ||||
|         connectionInactivityTimeoutMs = | ||||
|             json['connection_inactivity_timeout_ms'], | ||||
|         maxConnectionsPerIp4 = json['max_connections_per_ip4'], | ||||
|         maxConnectionsPerIp6Prefix = json['max_connections_per_ip6_prefix'], | ||||
|         maxConnectionsPerIp6PrefixSize = | ||||
|             json['max_connections_per_ip6_prefix_size'], | ||||
|         maxConnectionFrequencyPerMin = json['max_connection_frequency_per_min'], | ||||
|         clientWhitelistTimeoutMs = json['client_whitelist_timeout_ms'], | ||||
|         reverseConnectionReceiptTimeMs = | ||||
|             json['reverse_connection_receipt_time_ms'], | ||||
|         holePunchReceiptTimeMs = json['hole_punch_receipt_time_ms'], | ||||
|         routingTable = VeilidConfigRoutingTable.fromJson(json['routing_table']), | ||||
|         rpc = VeilidConfigRPC.fromJson(json['rpc']), | ||||
|         dht = VeilidConfigDHT.fromJson(json['dht']), | ||||
|         upnp = json['upnp'], | ||||
|         detectAddressChanges = json['detect_address_changes'], | ||||
|         restrictedNatRetries = json['restricted_nat_retries'], | ||||
|         tls = VeilidConfigTLS.fromJson(json['tls']), | ||||
|         application = VeilidConfigApplication.fromJson(json['application']), | ||||
|         protocol = VeilidConfigProtocol.fromJson(json['protocol']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigTableStore { | ||||
|   String directory; | ||||
|   bool delete; | ||||
|  | ||||
|   VeilidConfigTableStore({ | ||||
|     required this.directory, | ||||
|     required this.delete, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return {'directory': directory, 'delete': delete}; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigTableStore.fromJson(dynamic json) | ||||
|       : directory = json['directory'], | ||||
|         delete = json['delete']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigBlockStore { | ||||
|   String directory; | ||||
|   bool delete; | ||||
|  | ||||
|   VeilidConfigBlockStore({ | ||||
|     required this.directory, | ||||
|     required this.delete, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return {'directory': directory, 'delete': delete}; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigBlockStore.fromJson(dynamic json) | ||||
|       : directory = json['directory'], | ||||
|         delete = json['delete']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigProtectedStore { | ||||
|   bool allowInsecureFallback; | ||||
|   bool alwaysUseInsecureStorage; | ||||
|   String insecureFallbackDirectory; | ||||
|   bool delete; | ||||
|  | ||||
|   VeilidConfigProtectedStore({ | ||||
|     required this.allowInsecureFallback, | ||||
|     required this.alwaysUseInsecureStorage, | ||||
|     required this.insecureFallbackDirectory, | ||||
|     required this.delete, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'allow_insecure_fallback': allowInsecureFallback, | ||||
|       'always_use_insecure_storage': alwaysUseInsecureStorage, | ||||
|       'insecure_fallback_directory': insecureFallbackDirectory, | ||||
|       'delete': delete, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigProtectedStore.fromJson(dynamic json) | ||||
|       : allowInsecureFallback = json['allow_insecure_fallback'], | ||||
|         alwaysUseInsecureStorage = json['always_use_insecure_storage'], | ||||
|         insecureFallbackDirectory = json['insecure_fallback_directory'], | ||||
|         delete = json['delete']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfigCapabilities { | ||||
|   bool protocolUDP; | ||||
|   bool protocolConnectTCP; | ||||
|   bool protocolAcceptTCP; | ||||
|   bool protocolConnectWS; | ||||
|   bool protocolAcceptWS; | ||||
|   bool protocolConnectWSS; | ||||
|   bool protocolAcceptWSS; | ||||
|  | ||||
|   VeilidConfigCapabilities({ | ||||
|     required this.protocolUDP, | ||||
|     required this.protocolConnectTCP, | ||||
|     required this.protocolAcceptTCP, | ||||
|     required this.protocolConnectWS, | ||||
|     required this.protocolAcceptWS, | ||||
|     required this.protocolConnectWSS, | ||||
|     required this.protocolAcceptWSS, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'protocol_udp': protocolUDP, | ||||
|       'protocol_connect_tcp': protocolConnectTCP, | ||||
|       'protocol_accept_tcp': protocolAcceptTCP, | ||||
|       'protocol_connect_ws': protocolConnectWS, | ||||
|       'protocol_accept_ws': protocolAcceptWS, | ||||
|       'protocol_connect_wss': protocolConnectWSS, | ||||
|       'protocol_accept_wss': protocolAcceptWSS, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfigCapabilities.fromJson(dynamic json) | ||||
|       : protocolUDP = json['protocol_udp'], | ||||
|         protocolConnectTCP = json['protocol_connect_tcp'], | ||||
|         protocolAcceptTCP = json['protocol_accept_tcp'], | ||||
|         protocolConnectWS = json['protocol_connect_ws'], | ||||
|         protocolAcceptWS = json['protocol_accept_ws'], | ||||
|         protocolConnectWSS = json['protocol_connect_wss'], | ||||
|         protocolAcceptWSS = json['protocol_accept_wss']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class VeilidConfig { | ||||
|   String programName; | ||||
|   String namespace; | ||||
|   VeilidConfigCapabilities capabilities; | ||||
|   VeilidConfigProtectedStore protectedStore; | ||||
|   VeilidConfigTableStore tableStore; | ||||
|   VeilidConfigBlockStore blockStore; | ||||
|   VeilidConfigNetwork network; | ||||
|  | ||||
|   VeilidConfig({ | ||||
|     required this.programName, | ||||
|     required this.namespace, | ||||
|     required this.capabilities, | ||||
|     required this.protectedStore, | ||||
|     required this.tableStore, | ||||
|     required this.blockStore, | ||||
|     required this.network, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'program_name': programName, | ||||
|       'namespace': namespace, | ||||
|       'capabilities': capabilities.json, | ||||
|       'protected_store': protectedStore.json, | ||||
|       'table_store': tableStore.json, | ||||
|       'block_store': blockStore.json, | ||||
|       'network': network.json | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidConfig.fromJson(dynamic json) | ||||
|       : programName = json['program_name'], | ||||
|         namespace = json['namespace'], | ||||
|         capabilities = VeilidConfigCapabilities.fromJson(json['capabilities']), | ||||
|         protectedStore = | ||||
|             VeilidConfigProtectedStore.fromJson(json['protected_store']), | ||||
|         tableStore = VeilidConfigTableStore.fromJson(json['table_store']), | ||||
|         blockStore = VeilidConfigBlockStore.fromJson(json['block_store']), | ||||
|         network = VeilidConfigNetwork.fromJson(json['network']); | ||||
| } | ||||
							
								
								
									
										155
									
								
								veilid-flutter/lib/veilid_crypto.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								veilid-flutter/lib/veilid_crypto.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:typed_data'; | ||||
|  | ||||
| import 'package:charcode/charcode.dart'; | ||||
|  | ||||
| import 'veilid_encoding.dart'; | ||||
| import 'veilid.dart'; | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// CryptoKind | ||||
|  | ||||
| typedef CryptoKind = int; | ||||
| const CryptoKind cryptoKindVLD0 = | ||||
|     $V << 0 | $L << 8 | $D << 16 | $0 << 24; // "VLD0" | ||||
| const CryptoKind cryptoKindNONE = | ||||
|     $N << 0 | $O << 8 | $N << 16 | $E << 24; // "NONE" | ||||
|  | ||||
| String cryptoKindToString(CryptoKind kind) { | ||||
|   return "${String.fromCharCode(kind & 0xFF)}${String.fromCharCode((kind >> 8) & 0xFF)}${String.fromCharCode((kind >> 16) & 0xFF)}${String.fromCharCode((kind >> 24) & 0xFF)}"; | ||||
| } | ||||
|  | ||||
| CryptoKind cryptoKindFromString(String s) { | ||||
|   if (s.codeUnits.length != 4) { | ||||
|     throw const FormatException("malformed string"); | ||||
|   } | ||||
|   CryptoKind kind = s.codeUnits[0] | | ||||
|       s.codeUnits[1] << 8 | | ||||
|       s.codeUnits[2] << 16 | | ||||
|       s.codeUnits[3] << 24; | ||||
|   return kind; | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// Types | ||||
|  | ||||
| class Typed<V extends EncodedString> { | ||||
|   late CryptoKind kind; | ||||
|   late V value; | ||||
|   Typed({required this.kind, required this.value}); | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "${cryptoKindToString(kind)}:$value"; | ||||
|   } | ||||
|  | ||||
|   Typed.fromString(String s) { | ||||
|     var parts = s.split(":"); | ||||
|     if (parts.length < 2 || parts[0].codeUnits.length != 4) { | ||||
|       throw const FormatException("malformed string"); | ||||
|     } | ||||
|     kind = parts[0].codeUnits[0] | | ||||
|         parts[0].codeUnits[1] << 8 | | ||||
|         parts[0].codeUnits[2] << 16 | | ||||
|         parts[0].codeUnits[3] << 24; | ||||
|     value = EncodedString.fromString<V>(parts.sublist(1).join(":")); | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   Typed.fromJson(dynamic json) : this.fromString(json as String); | ||||
| } | ||||
|  | ||||
| class KeyPair { | ||||
|   late Key key; | ||||
|   late Key secret; | ||||
|   KeyPair({required this.key, required this.secret}); | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "${key.toString()}:${secret.toString()}"; | ||||
|   } | ||||
|  | ||||
|   KeyPair.fromString(String s) { | ||||
|     var parts = s.split(":"); | ||||
|     if (parts.length != 2 || | ||||
|         parts[0].codeUnits.length != 43 || | ||||
|         parts[1].codeUnits.length != 43) { | ||||
|       throw const FormatException("malformed string"); | ||||
|     } | ||||
|     key = Key(parts[0]); | ||||
|     secret = Key(parts[1]); | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   KeyPair.fromJson(dynamic json) : this.fromString(json as String); | ||||
| } | ||||
|  | ||||
| class TypedKeyPair { | ||||
|   late CryptoKind kind; | ||||
|   late Key key; | ||||
|   late Key secret; | ||||
|   TypedKeyPair({required this.kind, required this.key, required this.secret}); | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "${cryptoKindToString(kind)}:${key.toString()}:${secret.toString()}"; | ||||
|   } | ||||
|  | ||||
|   TypedKeyPair.fromString(String s) { | ||||
|     var parts = s.split(":"); | ||||
|     if (parts.length != 3 || | ||||
|         parts[0].codeUnits.length != 4 || | ||||
|         parts[1].codeUnits.length != 43 || | ||||
|         parts[2].codeUnits.length != 43) { | ||||
|       throw VeilidAPIExceptionInvalidArgument("malformed string", "s", s); | ||||
|     } | ||||
|     kind = cryptoKindFromString(parts[0]); | ||||
|     key = Key(parts[1]); | ||||
|     secret = Key(parts[2]); | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   TypedKeyPair.fromJson(dynamic json) : this.fromString(json as String); | ||||
| } | ||||
|  | ||||
| typedef Key = FixedEncodedString43; | ||||
| typedef Signature = FixedEncodedString86; | ||||
| typedef Nonce = FixedEncodedString32; | ||||
|  | ||||
| typedef TypedKey = Typed<Key>; | ||||
| typedef TypedSignature = Typed<Signature>; | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidCryptoSystem | ||||
|  | ||||
| abstract class VeilidCryptoSystem { | ||||
|   CryptoKind kind(); | ||||
|   Key cachedDH(Key key, Key secret); | ||||
|   Key computeDH(Key key, Key secret); | ||||
|   Nonce randomNonce(); | ||||
|   Key randomSharedSecret(); | ||||
|   KeyPair generateKeyPair(); | ||||
|   Key generateHash(Uint8List data); | ||||
|   Key generateHashReader(Stream<List<int>> reader); | ||||
|   bool validateKeyPair(Key key, Key secret); | ||||
|   bool validateHash(Uint8List data, Key hash); | ||||
|   bool validateHashReader(Stream<List<int>> reader, Key hash); | ||||
|   Key distance(Key key1, Key key2); | ||||
|   Signature sign(Key key, Key secret, Uint8List data); | ||||
|   void verify(Key key, Uint8List data, Signature signature); | ||||
|   BigInt aeadOverhead(); | ||||
|   Uint8List decryptAead( | ||||
|       Uint8List body, Nonce nonce, Key sharedSecret, Uint8List? associatedData); | ||||
|   Uint8List encryptAead( | ||||
|       Uint8List body, Nonce nonce, Key sharedSecret, Uint8List? associatedData); | ||||
|   Uint8List cryptNoAuth(Uint8List body, Nonce nonce, Key sharedSecret); | ||||
| } | ||||
							
								
								
									
										116
									
								
								veilid-flutter/lib/veilid_encoding.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								veilid-flutter/lib/veilid_encoding.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| import 'dart:convert'; | ||||
| import 'dart:typed_data'; | ||||
|  | ||||
| String base64UrlNoPadEncode(List<int> bytes) { | ||||
|   var x = base64Url.encode(bytes); | ||||
|   while (x.endsWith('=')) { | ||||
|     x = x.substring(0, x.length - 1); | ||||
|   } | ||||
|   return x; | ||||
| } | ||||
|  | ||||
| Uint8List base64UrlNoPadDecode(String source) { | ||||
|   source = base64.normalize(source); | ||||
|   return base64.decode(source); | ||||
| } | ||||
|  | ||||
| abstract class EncodedString { | ||||
|   late String contents; | ||||
|   EncodedString(String s) { | ||||
|     validate(s); | ||||
|     contents = s; | ||||
|   } | ||||
|   EncodedString.encode(List<int> b) { | ||||
|     var s = base64UrlNoPadEncode(b); | ||||
|     validate(s); | ||||
|     contents = s; | ||||
|   } | ||||
|  | ||||
|   int encodedLength(); | ||||
|   int decodedLength(); | ||||
|   void validate(String s) { | ||||
|     var d = base64UrlNoPadDecode(s); | ||||
|     if (d.length != decodedLength()) { | ||||
|       throw Exception("length ${s.length} should be ${encodedLength()}"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Uint8List decode() { | ||||
|     return base64UrlNoPadDecode(contents); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return contents; | ||||
|   } | ||||
|  | ||||
|   static T fromString<T extends EncodedString>(String s) { | ||||
|     switch (T) { | ||||
|       case FixedEncodedString32: | ||||
|         return FixedEncodedString32(s) as T; | ||||
|       case FixedEncodedString43: | ||||
|         return FixedEncodedString43(s) as T; | ||||
|       case FixedEncodedString86: | ||||
|         return FixedEncodedString86(s) as T; | ||||
|       default: | ||||
|         throw UnimplementedError(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| class FixedEncodedString32 extends EncodedString { | ||||
|   FixedEncodedString32(String s) : super(s); | ||||
|   @override | ||||
|   int encodedLength() { | ||||
|     return 32; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   int decodedLength() { | ||||
|     return 24; | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   FixedEncodedString32.fromJson(dynamic json) : this(json as String); | ||||
| } | ||||
|  | ||||
| class FixedEncodedString43 extends EncodedString { | ||||
|   FixedEncodedString43(String s) : super(s); | ||||
|   @override | ||||
|   int encodedLength() { | ||||
|     return 43; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   int decodedLength() { | ||||
|     return 32; | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   FixedEncodedString43.fromJson(dynamic json) : this(json as String); | ||||
| } | ||||
|  | ||||
| class FixedEncodedString86 extends EncodedString { | ||||
|   FixedEncodedString86(String s) : super(s); | ||||
|   @override | ||||
|   int encodedLength() { | ||||
|     return 86; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   int decodedLength() { | ||||
|     return 64; | ||||
|   } | ||||
|  | ||||
|   String get json { | ||||
|     return toString(); | ||||
|   } | ||||
|  | ||||
|   FixedEncodedString86.fromJson(dynamic json) : this(json as String); | ||||
| } | ||||
| @@ -10,6 +10,119 @@ import 'package:ffi/ffi.dart'; | ||||
| import 'veilid.dart'; | ||||
| import 'base64url_no_pad.dart'; | ||||
|  | ||||
| ////////////////////////////////////////////////////////// | ||||
| // FFI Platform-specific config | ||||
|  | ||||
| class VeilidFFIConfigLoggingTerminal { | ||||
|   bool enabled; | ||||
|   VeilidConfigLogLevel level; | ||||
|  | ||||
|   VeilidFFIConfigLoggingTerminal({ | ||||
|     required this.enabled, | ||||
|     required this.level, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'level': level.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidFFIConfigLoggingTerminal.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         level = veilidConfigLogLevelFromJson(json['level']); | ||||
| } | ||||
|  | ||||
| class VeilidFFIConfigLoggingOtlp { | ||||
|   bool enabled; | ||||
|   VeilidConfigLogLevel level; | ||||
|   String grpcEndpoint; | ||||
|   String serviceName; | ||||
|  | ||||
|   VeilidFFIConfigLoggingOtlp({ | ||||
|     required this.enabled, | ||||
|     required this.level, | ||||
|     required this.grpcEndpoint, | ||||
|     required this.serviceName, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'level': level.json, | ||||
|       'grpc_endpoint': grpcEndpoint, | ||||
|       'service_name': serviceName, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidFFIConfigLoggingOtlp.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         level = veilidConfigLogLevelFromJson(json['level']), | ||||
|         grpcEndpoint = json['grpc_endpoint'], | ||||
|         serviceName = json['service_name']; | ||||
| } | ||||
|  | ||||
| class VeilidFFIConfigLoggingApi { | ||||
|   bool enabled; | ||||
|   VeilidConfigLogLevel level; | ||||
|  | ||||
|   VeilidFFIConfigLoggingApi({ | ||||
|     required this.enabled, | ||||
|     required this.level, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'level': level.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidFFIConfigLoggingApi.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         level = veilidConfigLogLevelFromJson(json['level']); | ||||
| } | ||||
|  | ||||
| class VeilidFFIConfigLogging { | ||||
|   VeilidFFIConfigLoggingTerminal terminal; | ||||
|   VeilidFFIConfigLoggingOtlp otlp; | ||||
|   VeilidFFIConfigLoggingApi api; | ||||
|  | ||||
|   VeilidFFIConfigLogging( | ||||
|       {required this.terminal, required this.otlp, required this.api}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'terminal': terminal.json, | ||||
|       'otlp': otlp.json, | ||||
|       'api': api.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidFFIConfigLogging.fromJson(dynamic json) | ||||
|       : terminal = VeilidFFIConfigLoggingTerminal.fromJson(json['terminal']), | ||||
|         otlp = VeilidFFIConfigLoggingOtlp.fromJson(json['otlp']), | ||||
|         api = VeilidFFIConfigLoggingApi.fromJson(json['api']); | ||||
| } | ||||
|  | ||||
| class VeilidFFIConfig { | ||||
|   VeilidFFIConfigLogging logging; | ||||
|  | ||||
|   VeilidFFIConfig({ | ||||
|     required this.logging, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'logging': logging.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidFFIConfig.fromJson(Map<String, dynamic> json) | ||||
|       : logging = VeilidFFIConfigLogging.fromJson(json['logging']); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Load the veilid_flutter library once | ||||
| @@ -603,7 +716,7 @@ class VeilidTableDBFFI extends VeilidTableDB { | ||||
|  | ||||
|     final recvPort = ReceivePort("veilid_table_db_delete"); | ||||
|     final sendPort = recvPort.sendPort; | ||||
|     _tdb.ffi._tableDbLoad( | ||||
|     _tdb.ffi._tableDbDelete( | ||||
|       sendPort.nativePort, | ||||
|       _tdb.id, | ||||
|       col, | ||||
| @@ -635,6 +748,14 @@ class VeilidFFI implements Veilid { | ||||
|   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; | ||||
| @@ -658,6 +779,32 @@ class VeilidFFI implements Veilid { | ||||
|   final _TableDbTransactionStoreDart _tableDbTransactionStore; | ||||
|   final _TableDbTransactionDeleteDart _tableDbTransactionDelete; | ||||
|  | ||||
|   final _ValidCryptoKindsDart _validCryptoKinds; | ||||
|   final _GetCryptoSystemDart _getCryptoSystem; | ||||
|   final _BestCryptoSystemDart _bestCryptoSystem; | ||||
|   final _VerifySignaturesDart _verifySignatures; | ||||
|   final _GenerateSignaturesDart _generateSignatures; | ||||
|   final _GenerateKeyPairDart _generateKeyPair; | ||||
|  | ||||
|   final _CryptoCachedDHDart _cryptoCachedDH; | ||||
|   final _CryptoComputeDHDart _cryptoComputeDH; | ||||
|   final _CryptoRandomNonceDart _cryptoRandomNonce; | ||||
|   final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; | ||||
|   final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; | ||||
|   final _CryptoGenerateHashDart _cryptoGenerateHash; | ||||
|   final _CryptoGenerateHashReaderDart _cryptoGenerateHashReader; | ||||
|   final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; | ||||
|   final _CryptoValidateHashDart _cryptoValidateHash; | ||||
|   final _CryptoValidateHashReaderDart _cryptoValidateHashReader; | ||||
|   final _CryptoDistanceDart _cryptoDistance; | ||||
|   final _CryptoSignDart _cryptoSign; | ||||
|   final _CryptoVerifyDart _cryptoVerify; | ||||
|   final _CryptoAaedOverheadDart _cryptoAeadOverhead; | ||||
|   final _CryptoDecryptAeadDart _cryptoDecryptAead; | ||||
|   final _CryptoEncryptAeadDart _cryptoEncryptAead; | ||||
|   final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; | ||||
|  | ||||
|   final _NowDart _now; | ||||
|   final _DebugDart _debug; | ||||
|   final _VeilidVersionStringDart _veilidVersionString; | ||||
|   final _VeilidVersionDart _veilidVersion; | ||||
|   | ||||
| @@ -9,6 +9,95 @@ import 'dart:typed_data'; | ||||
|  | ||||
| import 'base64url_no_pad.dart'; | ||||
|  | ||||
| ////////////////////////////////////////////////////////// | ||||
| // WASM Platform-specific config | ||||
|  | ||||
| class VeilidWASMConfigLoggingPerformance { | ||||
|   bool enabled; | ||||
|   VeilidConfigLogLevel level; | ||||
|   bool logsInTimings; | ||||
|   bool logsInConsole; | ||||
|  | ||||
|   VeilidWASMConfigLoggingPerformance({ | ||||
|     required this.enabled, | ||||
|     required this.level, | ||||
|     required this.logsInTimings, | ||||
|     required this.logsInConsole, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'level': level.json, | ||||
|       'logs_in_timings': logsInTimings, | ||||
|       'logs_in_console': logsInConsole, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidWASMConfigLoggingPerformance.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         level = veilidConfigLogLevelFromJson(json['level']), | ||||
|         logsInTimings = json['logs_in_timings'], | ||||
|         logsInConsole = json['logs_in_console']; | ||||
| } | ||||
|  | ||||
| class VeilidWASMConfigLoggingApi { | ||||
|   bool enabled; | ||||
|   VeilidConfigLogLevel level; | ||||
|  | ||||
|   VeilidWASMConfigLoggingApi({ | ||||
|     required this.enabled, | ||||
|     required this.level, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'enabled': enabled, | ||||
|       'level': level.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidWASMConfigLoggingApi.fromJson(dynamic json) | ||||
|       : enabled = json['enabled'], | ||||
|         level = veilidConfigLogLevelFromJson(json['level']); | ||||
| } | ||||
|  | ||||
| class VeilidWASMConfigLogging { | ||||
|   VeilidWASMConfigLoggingPerformance performance; | ||||
|   VeilidWASMConfigLoggingApi api; | ||||
|  | ||||
|   VeilidWASMConfigLogging({required this.performance, required this.api}); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'performance': performance.json, | ||||
|       'api': api.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidWASMConfigLogging.fromJson(dynamic json) | ||||
|       : performance = | ||||
|             VeilidWASMConfigLoggingPerformance.fromJson(json['performance']), | ||||
|         api = VeilidWASMConfigLoggingApi.fromJson(json['api']); | ||||
| } | ||||
|  | ||||
| class VeilidWASMConfig { | ||||
|   VeilidWASMConfigLogging logging; | ||||
|  | ||||
|   VeilidWASMConfig({ | ||||
|     required this.logging, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'logging': logging.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   VeilidWASMConfig.fromJson(dynamic json) | ||||
|       : logging = VeilidWASMConfigLogging.fromJson(json['logging']); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////////////////////////// | ||||
|  | ||||
| Veilid getVeilid() => VeilidJS(); | ||||
|   | ||||
							
								
								
									
										594
									
								
								veilid-flutter/lib/veilid_state.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										594
									
								
								veilid-flutter/lib/veilid_state.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,594 @@ | ||||
| import 'dart:typed_data'; | ||||
|  | ||||
| import 'package:change_case/change_case.dart'; | ||||
|  | ||||
| import 'veilid_encoding.dart'; | ||||
| import 'veilid.dart'; | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// AttachmentState | ||||
|  | ||||
| enum AttachmentState { | ||||
|   detached, | ||||
|   attaching, | ||||
|   attachedWeak, | ||||
|   attachedGood, | ||||
|   attachedStrong, | ||||
|   fullyAttached, | ||||
|   overAttached, | ||||
|   detaching, | ||||
| } | ||||
|  | ||||
| extension AttachmentStateExt on AttachmentState { | ||||
|   String get json { | ||||
|     return name.toPascalCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| AttachmentState attachmentStateFromJson(String j) { | ||||
|   return AttachmentState.values.byName(j.toCamelCase()); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidLogLevel | ||||
|  | ||||
| enum VeilidLogLevel { | ||||
|   error, | ||||
|   warn, | ||||
|   info, | ||||
|   debug, | ||||
|   trace, | ||||
| } | ||||
|  | ||||
| extension VeilidLogLevelExt on VeilidLogLevel { | ||||
|   String get json { | ||||
|     return name.toPascalCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| VeilidLogLevel veilidLogLevelFromJson(String j) { | ||||
|   return VeilidLogLevel.values.byName(j.toCamelCase()); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class LatencyStats { | ||||
|   TimestampDuration fastest; | ||||
|   TimestampDuration average; | ||||
|   TimestampDuration slowest; | ||||
|  | ||||
|   LatencyStats({ | ||||
|     required this.fastest, | ||||
|     required this.average, | ||||
|     required this.slowest, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'fastest': fastest.json, | ||||
|       'average': average.json, | ||||
|       'slowest': slowest.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   LatencyStats.fromJson(dynamic json) | ||||
|       : fastest = TimestampDuration.fromJson(json['fastest']), | ||||
|         average = TimestampDuration.fromJson(json['average']), | ||||
|         slowest = TimestampDuration.fromJson(json['slowest']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class TransferStats { | ||||
|   BigInt total; | ||||
|   BigInt maximum; | ||||
|   BigInt average; | ||||
|   BigInt minimum; | ||||
|  | ||||
|   TransferStats({ | ||||
|     required this.total, | ||||
|     required this.maximum, | ||||
|     required this.average, | ||||
|     required this.minimum, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'total': total.toString(), | ||||
|       'maximum': maximum.toString(), | ||||
|       'average': average.toString(), | ||||
|       'minimum': minimum.toString(), | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   TransferStats.fromJson(dynamic json) | ||||
|       : total = BigInt.parse(json['total']), | ||||
|         maximum = BigInt.parse(json['maximum']), | ||||
|         average = BigInt.parse(json['average']), | ||||
|         minimum = BigInt.parse(json['minimum']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class TransferStatsDownUp { | ||||
|   TransferStats down; | ||||
|   TransferStats up; | ||||
|  | ||||
|   TransferStatsDownUp({ | ||||
|     required this.down, | ||||
|     required this.up, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'down': down.json, | ||||
|       'up': up.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   TransferStatsDownUp.fromJson(dynamic json) | ||||
|       : down = TransferStats.fromJson(json['down']), | ||||
|         up = TransferStats.fromJson(json['up']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class RPCStats { | ||||
|   int messagesSent; | ||||
|   int messagesRcvd; | ||||
|   int questionsInFlight; | ||||
|   Timestamp? lastQuestion; | ||||
|   Timestamp? lastSeenTs; | ||||
|   Timestamp? firstConsecutiveSeenTs; | ||||
|   int recentLostAnswers; | ||||
|   int failedToSend; | ||||
|  | ||||
|   RPCStats({ | ||||
|     required this.messagesSent, | ||||
|     required this.messagesRcvd, | ||||
|     required this.questionsInFlight, | ||||
|     required this.lastQuestion, | ||||
|     required this.lastSeenTs, | ||||
|     required this.firstConsecutiveSeenTs, | ||||
|     required this.recentLostAnswers, | ||||
|     required this.failedToSend, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'messages_sent': messagesSent, | ||||
|       'messages_rcvd': messagesRcvd, | ||||
|       'questions_in_flight': questionsInFlight, | ||||
|       'last_question': lastQuestion?.json, | ||||
|       'last_seen_ts': lastSeenTs?.json, | ||||
|       'first_consecutive_seen_ts': firstConsecutiveSeenTs?.json, | ||||
|       'recent_lost_answers': recentLostAnswers, | ||||
|       'failed_to_send': failedToSend, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   RPCStats.fromJson(dynamic json) | ||||
|       : messagesSent = json['messages_sent'], | ||||
|         messagesRcvd = json['messages_rcvd'], | ||||
|         questionsInFlight = json['questions_in_flight'], | ||||
|         lastQuestion = json['last_question'] != null | ||||
|             ? Timestamp.fromJson(json['last_question']) | ||||
|             : null, | ||||
|         lastSeenTs = json['last_seen_ts'] != null | ||||
|             ? Timestamp.fromJson(json['last_seen_ts']) | ||||
|             : null, | ||||
|         firstConsecutiveSeenTs = json['first_consecutive_seen_ts'] != null | ||||
|             ? Timestamp.fromJson(json['first_consecutive_seen_ts']) | ||||
|             : null, | ||||
|         recentLostAnswers = json['recent_lost_answers'], | ||||
|         failedToSend = json['failed_to_send']; | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class PeerStats { | ||||
|   Timestamp timeAdded; | ||||
|   RPCStats rpcStats; | ||||
|   LatencyStats? latency; | ||||
|   TransferStatsDownUp transfer; | ||||
|  | ||||
|   PeerStats({ | ||||
|     required this.timeAdded, | ||||
|     required this.rpcStats, | ||||
|     required this.latency, | ||||
|     required this.transfer, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'time_added': timeAdded.json, | ||||
|       'rpc_stats': rpcStats.json, | ||||
|       'latency': latency?.json, | ||||
|       'transfer': transfer.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   PeerStats.fromJson(dynamic json) | ||||
|       : timeAdded = Timestamp.fromJson(json['time_added']), | ||||
|         rpcStats = RPCStats.fromJson(json['rpc_stats']), | ||||
|         latency = json['latency'] != null | ||||
|             ? LatencyStats.fromJson(json['latency']) | ||||
|             : null, | ||||
|         transfer = TransferStatsDownUp.fromJson(json['transfer']); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class PeerTableData { | ||||
|   List<TypedKey> nodeIds; | ||||
|   PeerAddress peerAddress; | ||||
|   PeerStats peerStats; | ||||
|  | ||||
|   PeerTableData({ | ||||
|     required this.nodeIds, | ||||
|     required this.peerAddress, | ||||
|     required this.peerStats, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'node_ids': nodeIds.map((p) => p.json).toList(), | ||||
|       'peer_address': peerAddress.json, | ||||
|       'peer_stats': peerStats.json, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   PeerTableData.fromJson(dynamic json) | ||||
|       : nodeIds = List<TypedKey>.from( | ||||
|             json['node_ids'].map((j) => TypedKey.fromJson(j))), | ||||
|         peerAddress = PeerAddress.fromJson(json['peer_address']), | ||||
|         peerStats = PeerStats.fromJson(json['peer_stats']); | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// AttachmentState | ||||
|  | ||||
| enum ProtocolType { | ||||
|   udp, | ||||
|   tcp, | ||||
|   ws, | ||||
|   wss, | ||||
| } | ||||
|  | ||||
| extension ProtocolTypeExt on ProtocolType { | ||||
|   String get json { | ||||
|     return name.toUpperCase(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| ProtocolType protocolTypeFromJson(String j) { | ||||
|   return ProtocolType.values.byName(j.toLowerCase()); | ||||
| } | ||||
|  | ||||
| //////////// | ||||
|  | ||||
| class PeerAddress { | ||||
|   ProtocolType protocolType; | ||||
|   String socketAddress; | ||||
|  | ||||
|   PeerAddress({ | ||||
|     required this.protocolType, | ||||
|     required this.socketAddress, | ||||
|   }); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'protocol_type': protocolType.json, | ||||
|       'socket_address': socketAddress, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   PeerAddress.fromJson(dynamic json) | ||||
|       : protocolType = protocolTypeFromJson(json['protocol_type']), | ||||
|         socketAddress = json['socket_address']; | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidUpdate | ||||
|  | ||||
| abstract class VeilidUpdate { | ||||
|   factory VeilidUpdate.fromJson(dynamic json) { | ||||
|     switch (json["kind"]) { | ||||
|       case "Log": | ||||
|         { | ||||
|           return VeilidLog( | ||||
|               logLevel: veilidLogLevelFromJson(json["log_level"]), | ||||
|               message: json["message"], | ||||
|               backtrace: json["backtrace"]); | ||||
|         } | ||||
|       case "AppMessage": | ||||
|         { | ||||
|           return VeilidAppMessage( | ||||
|               sender: json["sender"], message: json["message"]); | ||||
|         } | ||||
|       case "AppCall": | ||||
|         { | ||||
|           return VeilidAppCall( | ||||
|               sender: json["sender"], message: json["message"], id: json["id"]); | ||||
|         } | ||||
|       case "Attachment": | ||||
|         { | ||||
|           return VeilidUpdateAttachment( | ||||
|               state: VeilidStateAttachment.fromJson(json)); | ||||
|         } | ||||
|       case "Network": | ||||
|         { | ||||
|           return VeilidUpdateNetwork(state: VeilidStateNetwork.fromJson(json)); | ||||
|         } | ||||
|       case "Config": | ||||
|         { | ||||
|           return VeilidUpdateConfig(state: VeilidStateConfig.fromJson(json)); | ||||
|         } | ||||
|       case "RouteChange": | ||||
|         { | ||||
|           return VeilidUpdateRouteChange( | ||||
|               deadRoutes: List<String>.from(json['dead_routes'].map((j) => j)), | ||||
|               deadRemoteRoutes: | ||||
|                   List<String>.from(json['dead_remote_routes'].map((j) => j))); | ||||
|         } | ||||
|       case "ValueChange": | ||||
|         { | ||||
|           return VeilidUpdateValueChange( | ||||
|               key: TypedKey.fromJson(json['key']), | ||||
|               subkeys: List<ValueSubkeyRange>.from( | ||||
|                   json['subkeys'].map((j) => ValueSubkeyRange.fromJson(j))), | ||||
|               count: json['count'], | ||||
|               valueData: ValueData.fromJson(json['value_data'])); | ||||
|         } | ||||
|       default: | ||||
|         { | ||||
|           throw VeilidAPIExceptionInternal( | ||||
|               "Invalid VeilidAPIException type: ${json['kind']}"); | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|   Map<String, dynamic> get json; | ||||
| } | ||||
|  | ||||
| class VeilidLog implements VeilidUpdate { | ||||
|   final VeilidLogLevel logLevel; | ||||
|   final String message; | ||||
|   final String? backtrace; | ||||
|   // | ||||
|   VeilidLog({ | ||||
|     required this.logLevel, | ||||
|     required this.message, | ||||
|     required this.backtrace, | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'kind': "Log", | ||||
|       'log_level': logLevel.json, | ||||
|       'message': message, | ||||
|       'backtrace': backtrace | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAppMessage implements VeilidUpdate { | ||||
|   final String? sender; | ||||
|   final Uint8List message; | ||||
|  | ||||
|   // | ||||
|   VeilidAppMessage({ | ||||
|     required this.sender, | ||||
|     required this.message, | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'kind': "AppMessage", | ||||
|       'sender': sender, | ||||
|       'message': base64UrlNoPadEncode(message) | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidAppCall implements VeilidUpdate { | ||||
|   final String? sender; | ||||
|   final Uint8List message; | ||||
|   final String id; | ||||
|  | ||||
|   // | ||||
|   VeilidAppCall({ | ||||
|     required this.sender, | ||||
|     required this.message, | ||||
|     required this.id, | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'kind': "AppMessage", | ||||
|       'sender': sender, | ||||
|       'message': base64UrlNoPadEncode(message), | ||||
|       'id': id, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidUpdateAttachment implements VeilidUpdate { | ||||
|   final VeilidStateAttachment state; | ||||
|   // | ||||
|   VeilidUpdateAttachment({required this.state}); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     var jsonRep = state.json; | ||||
|     jsonRep['kind'] = "Attachment"; | ||||
|     return jsonRep; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidUpdateNetwork implements VeilidUpdate { | ||||
|   final VeilidStateNetwork state; | ||||
|   // | ||||
|   VeilidUpdateNetwork({required this.state}); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     var jsonRep = state.json; | ||||
|     jsonRep['kind'] = "Network"; | ||||
|     return jsonRep; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidUpdateConfig implements VeilidUpdate { | ||||
|   final VeilidStateConfig state; | ||||
|   // | ||||
|   VeilidUpdateConfig({required this.state}); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     var jsonRep = state.json; | ||||
|     jsonRep['kind'] = "Config"; | ||||
|     return jsonRep; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidUpdateRouteChange implements VeilidUpdate { | ||||
|   final List<String> deadRoutes; | ||||
|   final List<String> deadRemoteRoutes; | ||||
|   // | ||||
|   VeilidUpdateRouteChange({ | ||||
|     required this.deadRoutes, | ||||
|     required this.deadRemoteRoutes, | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'dead_routes': deadRoutes.map((p) => p).toList(), | ||||
|       'dead_remote_routes': deadRemoteRoutes.map((p) => p).toList() | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VeilidUpdateValueChange implements VeilidUpdate { | ||||
|   final TypedKey key; | ||||
|   final List<ValueSubkeyRange> subkeys; | ||||
|   final int count; | ||||
|   final ValueData valueData; | ||||
|  | ||||
|   // | ||||
|   VeilidUpdateValueChange({ | ||||
|     required this.key, | ||||
|     required this.subkeys, | ||||
|     required this.count, | ||||
|     required this.valueData, | ||||
|   }); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'key': key.json, | ||||
|       'subkeys': subkeys.map((p) => p.json).toList(), | ||||
|       'count': count, | ||||
|       'value_data': valueData.json, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidStateAttachment | ||||
|  | ||||
| class VeilidStateAttachment { | ||||
|   final AttachmentState state; | ||||
|   final bool publicInternetReady; | ||||
|   final bool localNetworkReady; | ||||
|  | ||||
|   VeilidStateAttachment( | ||||
|       this.state, this.publicInternetReady, this.localNetworkReady); | ||||
|  | ||||
|   VeilidStateAttachment.fromJson(dynamic json) | ||||
|       : state = attachmentStateFromJson(json['state']), | ||||
|         publicInternetReady = json['public_internet_ready'], | ||||
|         localNetworkReady = json['local_network_ready']; | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'state': state.json, | ||||
|       'public_internet_ready': publicInternetReady, | ||||
|       'local_network_ready': localNetworkReady, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidStateNetwork | ||||
|  | ||||
| class VeilidStateNetwork { | ||||
|   final bool started; | ||||
|   final BigInt bpsDown; | ||||
|   final BigInt bpsUp; | ||||
|   final List<PeerTableData> peers; | ||||
|  | ||||
|   VeilidStateNetwork( | ||||
|       {required this.started, | ||||
|       required this.bpsDown, | ||||
|       required this.bpsUp, | ||||
|       required this.peers}); | ||||
|  | ||||
|   VeilidStateNetwork.fromJson(dynamic json) | ||||
|       : started = json['started'], | ||||
|         bpsDown = BigInt.parse(json['bps_down']), | ||||
|         bpsUp = BigInt.parse(json['bps_up']), | ||||
|         peers = List<PeerTableData>.from( | ||||
|             json['peers'].map((j) => PeerTableData.fromJson(j))); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'started': started, | ||||
|       'bps_down': bpsDown.toString(), | ||||
|       'bps_up': bpsUp.toString(), | ||||
|       'peers': peers.map((p) => p.json).toList(), | ||||
|     }; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidStateConfig | ||||
|  | ||||
| class VeilidStateConfig { | ||||
|   final Map<String, dynamic> config; | ||||
|  | ||||
|   VeilidStateConfig({ | ||||
|     required this.config, | ||||
|   }); | ||||
|  | ||||
|   VeilidStateConfig.fromJson(dynamic json) : config = json['config']; | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return {'config': config}; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ////////////////////////////////////// | ||||
| /// VeilidState | ||||
|  | ||||
| class VeilidState { | ||||
|   final VeilidStateAttachment attachment; | ||||
|   final VeilidStateNetwork network; | ||||
|   final VeilidStateConfig config; | ||||
|  | ||||
|   VeilidState.fromJson(dynamic json) | ||||
|       : attachment = VeilidStateAttachment.fromJson(json['attachment']), | ||||
|         network = VeilidStateNetwork.fromJson(json['network']), | ||||
|         config = VeilidStateConfig.fromJson(json['config']); | ||||
|  | ||||
|   Map<String, dynamic> get json { | ||||
|     return { | ||||
|       'attachment': attachment.json, | ||||
|       'network': network.json, | ||||
|       'config': config.json | ||||
|     }; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										59
									
								
								veilid-flutter/lib/veilid_table_db.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								veilid-flutter/lib/veilid_table_db.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| import 'dart:async'; | ||||
| import 'dart:typed_data'; | ||||
| import 'dart:convert'; | ||||
|  | ||||
| ///////////////////////////////////// | ||||
| /// VeilidTableDB | ||||
| abstract class VeilidTableDBTransaction { | ||||
|   Future<void> commit(); | ||||
|   Future<void> rollback(); | ||||
|   Future<void> store(int col, Uint8List key, Uint8List value); | ||||
|   Future<bool> delete(int col, Uint8List key); | ||||
|  | ||||
|   Future<void> storeJson(int col, Uint8List key, Object? object, | ||||
|       {Object? Function(Object? nonEncodable)? toEncodable}) async { | ||||
|     return store(col, key, | ||||
|         utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable))); | ||||
|   } | ||||
|  | ||||
|   Future<void> storeStringJson(int col, String key, Object? object, | ||||
|       {Object? Function(Object? nonEncodable)? toEncodable}) { | ||||
|     return storeJson(col, utf8.encoder.convert(key), object, | ||||
|         toEncodable: toEncodable); | ||||
|   } | ||||
| } | ||||
|  | ||||
| abstract class VeilidTableDB { | ||||
|   int getColumnCount(); | ||||
|   List<Uint8List> getKeys(int col); | ||||
|   VeilidTableDBTransaction transact(); | ||||
|   Future<void> store(int col, Uint8List key, Uint8List value); | ||||
|   Future<Uint8List?> load(int col, Uint8List key); | ||||
|   Future<bool> delete(int col, Uint8List key); | ||||
|  | ||||
|   Future<void> storeJson(int col, Uint8List key, Object? object, | ||||
|       {Object? Function(Object? nonEncodable)? toEncodable}) { | ||||
|     return store(col, key, | ||||
|         utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable))); | ||||
|   } | ||||
|  | ||||
|   Future<void> storeStringJson(int col, String key, Object? object, | ||||
|       {Object? Function(Object? nonEncodable)? toEncodable}) { | ||||
|     return storeJson(col, utf8.encoder.convert(key), object, | ||||
|         toEncodable: toEncodable); | ||||
|   } | ||||
|  | ||||
|   Future<Object?> loadJson(int col, Uint8List key, | ||||
|       {Object? Function(Object? key, Object? value)? reviver}) async { | ||||
|     var s = await load(col, key); | ||||
|     if (s == null) { | ||||
|       return null; | ||||
|     } | ||||
|     return jsonDecode(utf8.decode(s, allowMalformed: false), reviver: reviver); | ||||
|   } | ||||
|  | ||||
|   Future<Object?> loadStringJson(int col, String key, | ||||
|       {Object? Function(Object? key, Object? value)? reviver}) { | ||||
|     return loadJson(col, utf8.encoder.convert(key), reviver: reviver); | ||||
|   } | ||||
| } | ||||
| @@ -18,6 +18,7 @@ dependencies: | ||||
|   path_provider: ^2.0.9 | ||||
|   path: ^1.8.0 | ||||
|   system_info2: ^3.0.2 | ||||
|   charcode: ^1.3.1 | ||||
|  | ||||
| dev_dependencies: | ||||
|   flutter_test: | ||||
|   | ||||
| @@ -481,7 +481,7 @@ pub extern "C" fn routing_context_app_message(port: i64, id: u32, target: FfiStr | ||||
|         let routing_context = { | ||||
|             let rc = ROUTING_CONTEXTS.lock(); | ||||
|             let Some(routing_context) = rc.get(&id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_app_call", "id", id)); | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_app_message", "id", id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
| @@ -492,6 +492,65 @@ pub extern "C" fn routing_context_app_message(port: i64, id: u32, target: FfiStr | ||||
|     }); | ||||
| } | ||||
|  | ||||
| #[no_mangle] | ||||
| pub extern "C" fn routing_context_create_dht_record(port: i64, id: u32, kind: u32, schema: FfiStr) { | ||||
|     let crypto_kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind.to_be_bytes()); | ||||
|     let schema: veilid_core::DHTSchema = veilid_core::deserialize_opt_json(schema.into_opt_string()).unwrap(); | ||||
|  | ||||
|     DartIsolateWrapper::new(port).spawn_result(async move {         | ||||
|         let routing_context = { | ||||
|             let rc = ROUTING_CONTEXTS.lock(); | ||||
|             let Some(routing_context) = rc.get(&id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_create_dht_record", "id", id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|          | ||||
|         let dht_record_descriptor = routing_context.create_dht_record(crypto_kind, schema).await?; | ||||
|         let out = veilid_core::serialize_json(dht_record_descriptor); | ||||
|         APIResult::Ok(out) | ||||
|     }); | ||||
| } | ||||
|  | ||||
| #[no_mangle] | ||||
| pub extern "C" fn routing_context_open_dht_record(port: i64, id: u32, key: FfiStr, writer: FfiStr) { | ||||
|     let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); | ||||
|     let writer: Option<KeyPair> = writer.into_opt_string().map(|s| veilid_core::deserialize_json(&s).unwrap()); | ||||
|     DartIsolateWrapper::new(port).spawn_result(async move {         | ||||
|         let routing_context = { | ||||
|             let rc = ROUTING_CONTEXTS.lock(); | ||||
|             let Some(routing_context) = rc.get(&id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_open_dht_record", "id", id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         let writer = match writer { | ||||
|             Some(w) => w.to_key_pair(key.kind)?, | ||||
|             None => None | ||||
|         }; | ||||
|         let dht_record_descriptor = routing_context.open_dht_record(key, writer).await?; | ||||
|         let out = veilid_core::serialize_json(dht_record_descriptor); | ||||
|         APIResult::Ok(out) | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| // final _RoutingContextCloseDHTRecordDart _RoutingContextCloseDHTRecord; | ||||
| // final _RoutingContextDeleteDHTRecordDart _RoutingContextDeleteDHTRecord; | ||||
| // final _RoutingContextGetDHTValueDart _RoutingContextGetDHTValue; | ||||
| // final _RoutingContextSetDHTValueDart _RoutingContextSetDHTValue; | ||||
| // final _RoutingContextWatchDHTValuesDart _RoutingContextWatchDHTValues; | ||||
| // final _RoutingContextCancelDHTWatchDart _RoutingContextCancelDHTWatch; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| #[no_mangle] | ||||
| pub extern "C" fn new_private_route(port: i64) { | ||||
|     DartIsolateWrapper::new(port).spawn_result_json(async move { | ||||
| @@ -834,6 +893,36 @@ pub extern "C" fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr) { | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| final _ValidCryptoKindsDart _validCryptoKinds; | ||||
| final _GetCryptoSystemDart _getCryptoSystem; | ||||
| final _BestCryptoSystemDart _bestCryptoSystem; | ||||
| final _VerifySignaturesDart _verifySignatures; | ||||
| final _GenerateSignaturesDart _generateSignatures; | ||||
| final _GenerateKeyPairDart _generateKeyPair; | ||||
|  | ||||
| final _CryptoCachedDHDart _cryptoCachedDH; | ||||
| final _CryptoComputeDHDart _cryptoComputeDH; | ||||
| final _CryptoRandomNonceDart _cryptoRandomNonce; | ||||
| final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; | ||||
| final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; | ||||
| final _CryptoGenerateHashDart _cryptoGenerateHash; | ||||
| final _CryptoGenerateHashReaderDart _cryptoGenerateHashReader; | ||||
| final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; | ||||
| final _CryptoValidateHashDart _cryptoValidateHash; | ||||
| final _CryptoValidateHashReaderDart _cryptoValidateHashReader; | ||||
| final _CryptoDistanceDart _cryptoDistance; | ||||
| final _CryptoSignDart _cryptoSign; | ||||
| final _CryptoVerifyDart _cryptoVerify; | ||||
| final _CryptoAaedOverheadDart _cryptoAeadOverhead; | ||||
| final _CryptoDecryptAeadDart _cryptoDecryptAead; | ||||
| final _CryptoEncryptAeadDart _cryptoEncryptAead; | ||||
| final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; | ||||
|  | ||||
| final _NowDart _now; | ||||
|  | ||||
|  | ||||
| #[no_mangle] | ||||
| pub extern "C" fn debug(port: i64, command: FfiStr) { | ||||
|     let command = command.into_opt_string().unwrap_or_default(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user