mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-02-17 13:02:50 -05:00
api work
This commit is contained in:
parent
cb899b44ea
commit
5eb2ea656c
@ -1562,7 +1562,7 @@ impl NetworkManager {
|
|||||||
if let Some(nr) = routing_table.lookup_node_ref(k) {
|
if let Some(nr) = routing_table.lookup_node_ref(k) {
|
||||||
let peer_stats = nr.peer_stats();
|
let peer_stats = nr.peer_stats();
|
||||||
let peer = PeerTableData {
|
let peer = PeerTableData {
|
||||||
node_ids: nr.node_ids().iter().map(|x| x.to_string()).collect(),
|
node_ids: nr.node_ids().iter().copied().collect(),
|
||||||
peer_address: v.last_connection.remote().to_string(),
|
peer_address: v.last_connection.remote().to_string(),
|
||||||
peer_stats,
|
peer_stats,
|
||||||
};
|
};
|
||||||
|
@ -8,18 +8,18 @@ use super::*;
|
|||||||
pub struct VeilidAppMessage {
|
pub struct VeilidAppMessage {
|
||||||
/// Some(sender) if the message was sent directly, None if received via a private/safety route
|
/// Some(sender) if the message was sent directly, None if received via a private/safety route
|
||||||
#[serde(with = "opt_json_as_string")]
|
#[serde(with = "opt_json_as_string")]
|
||||||
sender: Option<PublicKey>,
|
sender: Option<TypedKey>, xxx continue propagating this publickey->typedkey and get all the FFI done
|
||||||
/// The content of the message to deliver to the application
|
/// The content of the message to deliver to the application
|
||||||
#[serde(with = "json_as_base64")]
|
#[serde(with = "json_as_base64")]
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VeilidAppMessage {
|
impl VeilidAppMessage {
|
||||||
pub fn new(sender: Option<PublicKey>, message: Vec<u8>) -> Self {
|
pub fn new(sender: Option<TypedKey>, message: Vec<u8>) -> Self {
|
||||||
Self { sender, message }
|
Self { sender, message }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sender(&self) -> Option<&PublicKey> {
|
pub fn sender(&self) -> Option<&TypedKey> {
|
||||||
self.sender.as_ref()
|
self.sender.as_ref()
|
||||||
}
|
}
|
||||||
pub fn message(&self) -> &[u8] {
|
pub fn message(&self) -> &[u8] {
|
||||||
@ -35,7 +35,7 @@ impl VeilidAppMessage {
|
|||||||
pub struct VeilidAppCall {
|
pub struct VeilidAppCall {
|
||||||
/// Some(sender) if the request was sent directly, None if received via a private/safety route
|
/// Some(sender) if the request was sent directly, None if received via a private/safety route
|
||||||
#[serde(with = "opt_json_as_string")]
|
#[serde(with = "opt_json_as_string")]
|
||||||
sender: Option<PublicKey>,
|
sender: Option<TypedKey>,
|
||||||
/// The content of the request to deliver to the application
|
/// The content of the request to deliver to the application
|
||||||
#[serde(with = "json_as_base64")]
|
#[serde(with = "json_as_base64")]
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
@ -45,7 +45,7 @@ pub struct VeilidAppCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VeilidAppCall {
|
impl VeilidAppCall {
|
||||||
pub fn new(sender: Option<PublicKey>, message: Vec<u8>, id: OperationId) -> Self {
|
pub fn new(sender: Option<TypedKey>, message: Vec<u8>, id: OperationId) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sender,
|
sender,
|
||||||
message,
|
message,
|
||||||
@ -53,7 +53,7 @@ impl VeilidAppCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sender(&self) -> Option<&PublicKey> {
|
pub fn sender(&self) -> Option<&TypedKey> {
|
||||||
self.sender.as_ref()
|
self.sender.as_ref()
|
||||||
}
|
}
|
||||||
pub fn message(&self) -> &[u8] {
|
pub fn message(&self) -> &[u8] {
|
||||||
|
@ -74,7 +74,7 @@ pub struct VeilidStateAttachment {
|
|||||||
)]
|
)]
|
||||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct PeerTableData {
|
pub struct PeerTableData {
|
||||||
pub node_ids: Vec<String>,
|
pub node_ids: Vec<TypedKey>,
|
||||||
pub peer_address: String,
|
pub peer_address: String,
|
||||||
pub peer_stats: PeerStats,
|
pub peer_stats: PeerStats,
|
||||||
}
|
}
|
||||||
|
@ -5,98 +5,120 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: ansicolor
|
name: ansicolor
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "607f8fa9786f392043f169898923e6c59b4518242b68b8862eb8a8b7d9c30b4a"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.9.0"
|
version: "2.10.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
change_case:
|
change_case:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: change_case
|
name: change_case
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "2757d850a43d333fd12d6cce49e2f1248ac89a16ae10ce4ca34d4c7d73286f3c"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.1"
|
||||||
|
charcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: charcode
|
||||||
|
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.17.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.dartlang.org"
|
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: equatable
|
name: equatable
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.4"
|
version: "6.1.4"
|
||||||
file_utils:
|
file_utils:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file_utils
|
name: file_utils
|
||||||
url: "https://pub.dartlang.org"
|
sha256: d1e64389a22649095c8405c9e177272caf05139255931c9ff30d53b5c9bcaa34
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
flutter:
|
flutter:
|
||||||
@ -108,14 +130,16 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_acrylic
|
name: flutter_acrylic
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "646200d98e8dd2bd4ab931d4ba4f6b4cb899475d6401414017ba5d71b0fac42b"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+2"
|
version: "1.0.0+2"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -132,140 +156,160 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: globbing
|
name: globbing
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.4"
|
version: "0.6.5"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
loggy:
|
loggy:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: loggy
|
name: loggy
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "981e03162bbd3a5a843026f75f73d26e4a0d8aa035ae060456ca7b30dfd1e339"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.12"
|
version: "0.12.13"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
url: "https://pub.dartlang.org"
|
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.5"
|
version: "0.2.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
path:
|
path:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.2"
|
version: "1.8.2"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.11"
|
version: "2.0.11"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.22"
|
version: "2.0.22"
|
||||||
path_provider_ios:
|
path_provider_ios:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_ios
|
name: path_provider_ios
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.11"
|
version: "2.0.11"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.7"
|
version: "2.1.7"
|
||||||
path_provider_macos:
|
path_provider_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_macos
|
name: path_provider_macos
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.0.6"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
url: "https://pub.dartlang.org"
|
sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
platform_info:
|
platform_info:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform_info
|
name: platform_info
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "012e73712166cf0b56d3eb95c0d33491f56b428c169eca385f036448474147e4"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.4"
|
version: "4.2.4"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: quiver
|
name: quiver
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "93982981971e812c94d4a6fa3a57b89f9ec12b38b6380cd3c1370c3b01e4580e"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
@ -277,65 +321,74 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
version: "1.9.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.2.0"
|
||||||
system_info2:
|
system_info2:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: system_info2
|
name: system_info2
|
||||||
url: "https://pub.dartlang.org"
|
sha256: af2f948e3f31a3367a049932a8ad59faf0063ecf836a020d975b9f41566d8bc9
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.1"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.12"
|
version: "0.4.16"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
veilid:
|
veilid:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -347,21 +400,24 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ca121dbbadb3e43b449053feab0cdf3f2bff93b107cacf0290e3d29f717374b6
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0+2"
|
version: "0.2.0+2"
|
||||||
xterm:
|
xterm:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: xterm
|
name: xterm
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "990286eead883ff5ad9b8ea7674183dced2fe5421771e95ce32cbaa9117d24d8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "3.4.0"
|
||||||
sdks:
|
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 'veilid.dart';
|
||||||
import 'base64url_no_pad.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
|
// Load the veilid_flutter library once
|
||||||
@ -603,7 +716,7 @@ class VeilidTableDBFFI extends VeilidTableDB {
|
|||||||
|
|
||||||
final recvPort = ReceivePort("veilid_table_db_delete");
|
final recvPort = ReceivePort("veilid_table_db_delete");
|
||||||
final sendPort = recvPort.sendPort;
|
final sendPort = recvPort.sendPort;
|
||||||
_tdb.ffi._tableDbLoad(
|
_tdb.ffi._tableDbDelete(
|
||||||
sendPort.nativePort,
|
sendPort.nativePort,
|
||||||
_tdb.id,
|
_tdb.id,
|
||||||
col,
|
col,
|
||||||
@ -635,6 +748,14 @@ class VeilidFFI implements Veilid {
|
|||||||
final _RoutingContextWithSequencingDart _routingContextWithSequencing;
|
final _RoutingContextWithSequencingDart _routingContextWithSequencing;
|
||||||
final _RoutingContextAppCallDart _routingContextAppCall;
|
final _RoutingContextAppCallDart _routingContextAppCall;
|
||||||
final _RoutingContextAppMessageDart _routingContextAppMessage;
|
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 _NewPrivateRouteDart _newPrivateRoute;
|
||||||
final _NewCustomPrivateRouteDart _newCustomPrivateRoute;
|
final _NewCustomPrivateRouteDart _newCustomPrivateRoute;
|
||||||
@ -658,6 +779,32 @@ class VeilidFFI implements Veilid {
|
|||||||
final _TableDbTransactionStoreDart _tableDbTransactionStore;
|
final _TableDbTransactionStoreDart _tableDbTransactionStore;
|
||||||
final _TableDbTransactionDeleteDart _tableDbTransactionDelete;
|
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 _DebugDart _debug;
|
||||||
final _VeilidVersionStringDart _veilidVersionString;
|
final _VeilidVersionStringDart _veilidVersionString;
|
||||||
final _VeilidVersionDart _veilidVersion;
|
final _VeilidVersionDart _veilidVersion;
|
||||||
|
@ -9,6 +9,95 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
import 'base64url_no_pad.dart';
|
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();
|
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_provider: ^2.0.9
|
||||||
path: ^1.8.0
|
path: ^1.8.0
|
||||||
system_info2: ^3.0.2
|
system_info2: ^3.0.2
|
||||||
|
charcode: ^1.3.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -481,7 +481,7 @@ pub extern "C" fn routing_context_app_message(port: i64, id: u32, target: FfiStr
|
|||||||
let routing_context = {
|
let routing_context = {
|
||||||
let rc = ROUTING_CONTEXTS.lock();
|
let rc = ROUTING_CONTEXTS.lock();
|
||||||
let Some(routing_context) = rc.get(&id) else {
|
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()
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn new_private_route(port: i64) {
|
pub extern "C" fn new_private_route(port: i64) {
|
||||||
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn debug(port: i64, command: FfiStr) {
|
pub extern "C" fn debug(port: i64, command: FfiStr) {
|
||||||
let command = command.into_opt_string().unwrap_or_default();
|
let command = command.into_opt_string().unwrap_or_default();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user