diff --git a/Cargo.lock b/Cargo.lock index d039f8df0..70888ef8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,7 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" dependencies = [ "memchr", - "regex-automata", + "regex-automata 0.3.8", "serde", ] @@ -1361,19 +1361,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -2765,6 +2752,15 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -3879,10 +3875,19 @@ checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata", + "regex-automata 0.3.8", "regex-syntax 0.7.5", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + [[package]] name = "regex-automata" version = "0.3.8" @@ -3894,6 +3899,12 @@ dependencies = [ "regex-syntax 0.7.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -4432,6 +4443,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shinkai_message_primitives" version = "0.2.0" @@ -4454,6 +4474,8 @@ dependencies = [ "serde_json", "shinkai_vector_resources", "thiserror", + "tracing", + "tracing-subscriber", "x25519-dalek", ] @@ -4480,7 +4502,6 @@ dependencies = [ "csv", "dashmap", "ed25519-dalek", - "env_logger 0.10.0", "ethers", "futures", "hex", @@ -4527,7 +4548,7 @@ dependencies = [ "chrono", "chrono-tz", "csv", - "env_logger 0.9.3", + "env_logger", "hex", "keyphrases", "lazy_static", @@ -4908,6 +4929,16 @@ dependencies = [ "syn 2.0.31", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tiff" version = "0.6.1" @@ -5162,11 +5193,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -5186,11 +5216,12 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", ] [[package]] @@ -5203,6 +5234,49 @@ dependencies = [ "tracing", ] +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec 1.11.0", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + [[package]] name = "try-lock" version = "0.2.4" @@ -5385,6 +5459,12 @@ dependencies = [ "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index 30d4129cf..95d01311f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ chashmap = "2.2.2" async-channel = "1.6.1" lazy_static = "1.4.0" clap = "3.0.0-beta.5" -env_logger = "0.10" anyhow = "1.0" regex = "1" csv = "1.1.6" diff --git a/scripts/run_identity_9552.sh b/scripts/run_identity_9552.sh new file mode 100755 index 000000000..c3b163947 --- /dev/null +++ b/scripts/run_identity_9552.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +export NODE_IP="0.0.0.0" +export NODE_PORT="9552" +export NODE_WS_PORT="9551" +export NODE_API_IP="0.0.0.0" +export NODE_API_PORT="9550" +export IDENTITY_SECRET_KEY="fd1ca428ec1be6ae8b0b3d23ea507eba8cf7da0869578753b9781efda2b6a8ab" +export ENCRYPTION_SECRET_KEY="e06a1c02d638d4552d733dca8ff8f023841d1126965050b2048f1140bfd82a5c" +export PING_INTERVAL_SECS="0" +export GLOBAL_IDENTITY_NAME="@@_my_9552.shinkai" +export RUST_LOG=debug,error,info +export STARTING_NUM_QR_PROFILES="1" +export STARTING_NUM_QR_DEVICES="1" +export FIRST_DEVICE_NEEDS_REGISTRATION_CODE="false" +export LOG_SIMPLE="true" +export NO_SECRET_FILE="true" +export EMBEDDINGS_SERVER_URL="https://internal.shinkai.com/x-embed-api/" +export UNSTRUCTURED_SERVER_URL="https://internal.shinkai.com" + +export INITIAL_AGENT_NAMES="my_gpt,my_gpt_vision" +export INITIAL_AGENT_URLS="https://api.openai.com,https://api.openai.com" +export INITIAL_AGENT_MODELS="openai:gpt-4-1106-preview,openai:gpt-4-vision-preview" + +# Add these lines to enable all log options +export LOG_ALL=1 + +cargo run diff --git a/scripts/run_identity_9652.sh b/scripts/run_identity_9652.sh new file mode 100755 index 000000000..ad7663af6 --- /dev/null +++ b/scripts/run_identity_9652.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +export NODE_IP="0.0.0.0" +export NODE_PORT="9652" +export NODE_WS_PORT="9651" +export NODE_API_IP="0.0.0.0" +export NODE_API_PORT="9650" +export IDENTITY_SECRET_KEY="bf0be9c2da2d5f9371bb61f5b2b9f4a6bb294f064e187056005a8bda8dc2ef00" +export ENCRYPTION_SECRET_KEY="806bbcca2ab460aaa57ed00aa2fdf88b1d039b5ca2d89306d4ebd77b14e52c77" +export PING_INTERVAL_SECS="0" +export GLOBAL_IDENTITY_NAME="@@_my_9652.shinkai" +export RUST_LOG=debug,error,info +export STARTING_NUM_QR_PROFILES="1" +export STARTING_NUM_QR_DEVICES="1" +export FIRST_DEVICE_NEEDS_REGISTRATION_CODE="false" +export LOG_SIMPLE="true" +export NO_SECRET_FILE="true" +export EMBEDDINGS_SERVER_URL="https://internal.shinkai.com/x-embed-api/" +export UNSTRUCTURED_SERVER_URL="https://internal.shinkai.com/" + +export INITIAL_AGENT_NAMES="my_gpt,my_gpt_vision" +export INITIAL_AGENT_URLS="https://api.openai.com,https://api.openai.com" +export INITIAL_AGENT_MODELS="openai:gpt-4-1106-preview,openai:gpt-4-vision-preview" + +# Add these lines to enable all log options +export LOG_ALL=1 + +cargo run diff --git a/shinkai-libs/shinkai-message-primitives/Cargo.lock b/shinkai-libs/shinkai-message-primitives/Cargo.lock index b434edd60..864c25dad 100644 --- a/shinkai-libs/shinkai-message-primitives/Cargo.lock +++ b/shinkai-libs/shinkai-message-primitives/Cargo.lock @@ -98,6 +98,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.75" @@ -1041,6 +1050,15 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.6.3" @@ -1479,8 +1497,17 @@ checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1491,9 +1518,15 @@ checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -1715,6 +1748,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shinkai_message_primitives" version = "0.2.0" @@ -1737,6 +1779,8 @@ dependencies = [ "serde_json", "shinkai_vector_resources", "thiserror", + "tracing", + "tracing-subscriber", "x25519-dalek", ] @@ -1938,6 +1982,16 @@ dependencies = [ "syn 2.0.31", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2001,22 +2055,77 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ + "log", "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -2104,6 +2213,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/shinkai-libs/shinkai-message-primitives/Cargo.toml b/shinkai-libs/shinkai-message-primitives/Cargo.toml index ba95f10db..af78b72f0 100644 --- a/shinkai-libs/shinkai-message-primitives/Cargo.toml +++ b/shinkai-libs/shinkai-message-primitives/Cargo.toml @@ -25,6 +25,8 @@ hex = "=0.4.3" shinkai_vector_resources = { path = "../shinkai-vector-resources", default-features = false } aes-gcm = "0.10.3" blake3 = "1.2.0" +tracing = "0.1.40" +tracing-subscriber = "0.2.0" [dependencies.serde] version = "1.0.188" diff --git a/shinkai-libs/shinkai-message-primitives/src/shinkai_utils/shinkai_logging.rs b/shinkai-libs/shinkai-message-primitives/src/shinkai_utils/shinkai_logging.rs index 0feb6fb23..e46b637fc 100644 --- a/shinkai-libs/shinkai-message-primitives/src/shinkai_utils/shinkai_logging.rs +++ b/shinkai-libs/shinkai-message-primitives/src/shinkai_utils/shinkai_logging.rs @@ -1,5 +1,11 @@ use chrono::Local; use colored::*; +use tracing::{span, Level, error, info, debug, instrument}; +use tracing_subscriber::FmtSubscriber; + +// Note(Nico): Added this to avoid issues when running tests +use std::sync::Once; +static INIT: Once = Once::new(); #[derive(PartialEq, Debug)] pub enum ShinkaiLogOption { @@ -26,11 +32,11 @@ pub enum ShinkaiLogLevel { } impl ShinkaiLogLevel { - fn to_log_level(&self) -> log::Level { + fn to_log_level(&self) -> Level { match self { - ShinkaiLogLevel::Error => log::Level::Error, - ShinkaiLogLevel::Info => log::Level::Info, - ShinkaiLogLevel::Debug => log::Level::Debug, + ShinkaiLogLevel::Error => Level::ERROR, + ShinkaiLogLevel::Info => Level::INFO, + ShinkaiLogLevel::Debug => Level::DEBUG, } } } @@ -100,31 +106,49 @@ fn active_log_options() -> Vec { pub fn shinkai_log(option: ShinkaiLogOption, level: ShinkaiLogLevel, message: &str) { let active_options = active_log_options(); if active_options.contains(&option) { - let time = Local::now().format("%Y-%m-%dT%H:%M:%S%.fZ"); // RFC 3339 timestamp - let option_str = format!("{:?}", option); + let is_simple_log = std::env::var("LOG_SIMPLE").is_ok(); + let time = Local::now().format("%Y-%m-%d %H:%M:%S"); // Simplified timestamp - let (level_str, color_fn): (&str, Box ColoredString>) = match level { - ShinkaiLogLevel::Error => ("(ERROR)", Box::new(|s: &str| s.red())), - ShinkaiLogLevel::Info => ("(INFO)", Box::new(|s: &str| s.yellow())), - ShinkaiLogLevel::Debug => ("(DEBUG)", Box::new(|s: &str| s.normal())), + let option_str = format!("{:?}", option); + let level_str = match level { + ShinkaiLogLevel::Error => "ERROR", + ShinkaiLogLevel::Info => "INFO", + ShinkaiLogLevel::Debug => "DEBUG", }; - let message_with_header = if std::env::var("LOG_SIMPLE").is_ok() { - format!("{} {} - {} - {}", time, level_str, option_str, message) + let message_with_header = if is_simple_log { + format!("{}", message) } else { let hostname = "localhost"; let app_name = "shinkai"; let proc_id = std::process::id().to_string(); - let msg_id = "-"; // No specific message ID + let msg_id = "-"; let header = format!("{} {} {} {} {}", time, hostname, app_name, proc_id, msg_id); format!("{} - {} - {} - {}", header, level_str, option_str, message) }; - match level.to_log_level() { - log::Level::Error => eprintln!("{}", color_fn(&message_with_header)), - log::Level::Info => println!("{}", color_fn(&message_with_header)), - log::Level::Debug => println!("{}", color_fn(&message_with_header)), - _ => {} + let span = match level { + ShinkaiLogLevel::Error => span!(Level::ERROR, "{}", option_str), + ShinkaiLogLevel::Info => span!(Level::INFO, "{}", option_str), + ShinkaiLogLevel::Debug => span!(Level::DEBUG, "{}", option_str), + }; + let _enter = span.enter(); + + match level { + ShinkaiLogLevel::Error => error!("{}", message_with_header), + ShinkaiLogLevel::Info => info!("{}", message_with_header), + ShinkaiLogLevel::Debug => debug!("{}", message_with_header), } } } + +pub fn init_tracing() { + INIT.call_once(|| { + let subscriber = FmtSubscriber::builder() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .finish(); + + tracing::subscriber::set_global_default(subscriber) + .expect("setting default subscriber failed"); + }); +} \ No newline at end of file diff --git a/shinkai-libs/shinkai-message-pyo3/Cargo.lock b/shinkai-libs/shinkai-message-pyo3/Cargo.lock index 3f3262974..b40e54a9d 100644 --- a/shinkai-libs/shinkai-message-pyo3/Cargo.lock +++ b/shinkai-libs/shinkai-message-pyo3/Cargo.lock @@ -109,6 +109,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.4" @@ -402,7 +411,7 @@ dependencies = [ "indicatif", "paste", "path-slash", - "tracing-subscriber", + "tracing-subscriber 0.3.18", "which", "xwin", ] @@ -1699,6 +1708,15 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "matchers" version = "0.1.0" @@ -1766,7 +1784,7 @@ dependencies = [ "toml 0.7.8", "toml_edit 0.19.15", "tracing", - "tracing-subscriber", + "tracing-subscriber 0.3.18", "ureq", "url", "wild", @@ -2904,6 +2922,8 @@ dependencies = [ "serde_json", "shinkai_vector_resources", "thiserror", + "tracing", + "tracing-subscriber 0.2.25", "x25519-dalek", ] @@ -3392,11 +3412,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -3405,9 +3424,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", @@ -3416,9 +3435,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -3426,12 +3445,23 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -3447,11 +3477,33 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers 0.0.1", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-serde", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "matchers", + "matchers 0.1.0", "nu-ansi-term", "once_cell", "regex", @@ -3462,7 +3514,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", "tracing-serde", ] @@ -4009,7 +4061,7 @@ dependencies = [ "sha2", "tempfile", "tracing", - "tracing-subscriber", + "tracing-subscriber 0.3.18", "twox-hash", "ureq", "versions", diff --git a/shinkai-libs/shinkai-message-wasm/Cargo.lock b/shinkai-libs/shinkai-message-wasm/Cargo.lock index 9a8e0a45e..c75eeb219 100644 --- a/shinkai-libs/shinkai-message-wasm/Cargo.lock +++ b/shinkai-libs/shinkai-message-wasm/Cargo.lock @@ -98,6 +98,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.75" @@ -1084,6 +1093,15 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.6.3" @@ -1522,8 +1540,17 @@ checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1534,9 +1561,15 @@ checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -1788,6 +1821,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shinkai_message_primitives" version = "0.2.0" @@ -1810,6 +1852,8 @@ dependencies = [ "serde_json", "shinkai_vector_resources", "thiserror", + "tracing", + "tracing-subscriber", "x25519-dalek", ] @@ -2042,6 +2086,16 @@ dependencies = [ "syn 2.0.31", ] +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2105,22 +2159,77 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.31", +] + [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ + "log", "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -2208,6 +2317,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json b/src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json index 7bb5982d8..714b67e52 100644 --- a/src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json +++ b/src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json @@ -1,1515 +1,1109 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "delegatedTokens", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stakedTokens", - "type": "uint256" - } - ], - "name": "DelegatedTokensExceedingStakedTokens", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "IdentityNotAvailable", - "type": "error" - }, - { - "inputs": [], - "name": "InputArityMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientStakeAmountForDelegation", - "type": "error" - }, - { - "inputs": [], - "name": "InsufficientStakeAmountForIdentity", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "rate", - "type": "uint256" - } - ], - "name": "InvalidBaseRewardsRate", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "InvalidDelegationAmount", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - } - ], - "name": "InvalidName", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - } - ], - "name": "InvalidNamespace", - "type": "error" - }, - { - "inputs": [], - "name": "Unauthorized", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "bool", - "name": "routing", - "type": "bool" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "addressOrProxyNodes", - "type": "string[]" - } - ], - "name": "AddressOrProxyNodesUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "newRate", - "type": "uint256" - } - ], - "name": "BaseRewardsRateUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newDelegatedTokens", - "type": "uint256" - } - ], - "name": "DelegatedTokensUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewards", - "type": "uint256" - } - ], - "name": "DelegationRewardsAccrual", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewards", - "type": "uint256" - } - ], - "name": "DelegationRewardsClaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "components": [ - { - "internalType": "string", - "name": "delegatee", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "indexed": false, - "internalType": "struct ShinkaiRegistryInterface.Delegation[]", - "name": "delegations", - "type": "tuple[]" - } - ], - "name": "DelegationsUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "nftTokenId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "identityRaw", - "type": "string" - } - ], - "name": "IdentityClaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "nftTokenId", - "type": "uint256" - } - ], - "name": "IdentityUnclaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "signatureKey", - "type": "string" - } - ], - "name": "KeysUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "keys", - "type": "string[]" - } - ], - "name": "MetadataRemoval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "keys", - "type": "string[]" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "values", - "type": "string[]" - } - ], - "name": "MetadataUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newStake", - "type": "uint256" - } - ], - "name": "StakeUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "rewards", - "type": "uint256" - } - ], - "name": "StakingRewardsClaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "accrueDelegationRewards", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "baseRewardsRate", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseRewardsRateMaxMantissa", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "claimDelegationRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "identities", - "type": "string[]" - } - ], - "name": "claimDelegationRewardsBatched", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stakeAmount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "claimIdentity", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stakeAmount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "components": [ - { - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "internalType": "string", - "name": "signatureKey", - "type": "string" - }, - { - "internalType": "bool", - "name": "routing", - "type": "bool" - }, - { - "internalType": "string[]", - "name": "addressOrProxyNodes", - "type": "string[]" - } - ], - "internalType": "struct ShinkaiRegistryInterface.SetRecordParams", - "name": "setRecordParams", - "type": "tuple" - } - ], - "name": "claimIdentityAndSetRecord", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "names", - "type": "string[]" - }, - { - "internalType": "uint256[]", - "name": "namespaces", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "stakeAmounts", - "type": "uint256[]" - }, - { - "internalType": "address[]", - "name": "owners", - "type": "address[]" - } - ], - "name": "claimIdentityBatched", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "claimRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "identities", - "type": "string[]" - } - ], - "name": "claimRewardsBatched", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "claimStakingRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "identities", - "type": "string[]" - } - ], - "name": "claimStakingRewardsBatched", - "outputs": [ - { - "internalType": "uint256", - "name": "tokensAccrued", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "decreaseStake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "getAvailableTokensForDelegation", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "fromIdentity", - "type": "string" - }, - { - "internalType": "string", - "name": "toIdentity", - "type": "string" - } - ], - "name": "getDelegatedTokensTowards", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "getDelegatees", - "outputs": [ - { - "internalType": "string[]", - "name": "", - "type": "string[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - } - ], - "name": "getIdentity", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "getIdentityRecord", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "boundNft", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stakedTokens", - "type": "uint256" - }, - { - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "internalType": "string", - "name": "signatureKey", - "type": "string" - }, - { - "internalType": "bool", - "name": "routing", - "type": "bool" - }, - { - "internalType": "string[]", - "name": "addressOrProxyNodes", - "type": "string[]" - }, - { - "internalType": "uint256", - "name": "delegatedTokens", - "type": "uint256" - } - ], - "internalType": "struct ShinkaiRegistryInterface.IdentityRecord", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "identityDelegatees", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "identityDelegationAccrued", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "identityDelegationIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - }, - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "identityDelegations", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "uint256", - "name": "namespace", - "type": "uint256" - } - ], - "name": "identityStakeRequirement", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "name": "identityStakingIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "increaseStake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "shinToken_", - "type": "address" - }, - { - "internalType": "address", - "name": "shinkaiNft_", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "proxiableUUID", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string[]", - "name": "keys", - "type": "string[]" - }, - { - "internalType": "string[]", - "name": "values", - "type": "string[]" - } - ], - "name": "readMetadata", - "outputs": [ - { - "internalType": "string[]", - "name": "", - "type": "string[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string[]", - "name": "keys", - "type": "string[]" - } - ], - "name": "removeMetadata", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "resetIdentityData", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "rewardsState", - "outputs": [ - { - "internalType": "uint224", - "name": "index", - "type": "uint224" - }, - { - "internalType": "uint32", - "name": "block", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "rate", - "type": "uint256" - } - ], - "name": "setBaseRewardsRate", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "components": [ - { - "internalType": "string", - "name": "delegatee", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct ShinkaiRegistryInterface.Delegation[]", - "name": "delegations", - "type": "tuple[]" - } - ], - "name": "setDelegations", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "internalType": "string", - "name": "signatureKey", - "type": "string" - } - ], - "name": "setKeys", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string", - "name": "nodeAddress", - "type": "string" - } - ], - "name": "setNodeAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string[]", - "name": "proxyNodes", - "type": "string[]" - } - ], - "name": "setProxyNodes", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "components": [ - { - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "internalType": "string", - "name": "signatureKey", - "type": "string" - }, - { - "internalType": "bool", - "name": "routing", - "type": "bool" - }, - { - "internalType": "string[]", - "name": "addressOrProxyNodes", - "type": "string[]" - } - ], - "internalType": "struct ShinkaiRegistryInterface.SetRecordParams", - "name": "params", - "type": "tuple" - } - ], - "name": "setRecord", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "identities", - "type": "string[]" - }, - { - "components": [ - { - "internalType": "string", - "name": "encryptionKey", - "type": "string" - }, - { - "internalType": "string", - "name": "signatureKey", - "type": "string" - }, - { - "internalType": "bool", - "name": "routing", - "type": "bool" - }, - { - "internalType": "string[]", - "name": "addressOrProxyNodes", - "type": "string[]" - } - ], - "internalType": "struct ShinkaiRegistryInterface.SetRecordParams[]", - "name": "setRecordsParams", - "type": "tuple[]" - } - ], - "name": "setRecordBatched", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "shinToken", - "outputs": [ - { - "internalType": "contract ShinkaiTokenInterface", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "shinkaiNft", - "outputs": [ - { - "internalType": "contract ShinkaiNFTInterface", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "tokenIdToIdentity", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - } - ], - "name": "unclaimIdentity", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string[]", - "name": "identities", - "type": "string[]" - } - ], - "name": "unclaimIdentityBatched", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string[]", - "name": "keys", - "type": "string[]" - }, - { - "internalType": "string[]", - "name": "values", - "type": "string[]" - } - ], - "name": "updateMetadata", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - } - ], - "name": "validName", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - } -] +[ + { "type": "constructor", "inputs": [], "stateMutability": "nonpayable" }, + { + "type": "function", + "name": "accrueDelegationRewards", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "baseRewardsRate", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "baseRewardsRateMaxMantissa", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimDelegationRewards", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimDelegationRewardsBatched", + "inputs": [ + { "name": "identities", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimIdentity", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct ShinkaiRegistryInterface.ClaimIdentityParams", + "components": [ + { "name": "name", "type": "string", "internalType": "string" }, + { + "name": "namespace", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stakeAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "owner", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimIdentityAndSetData", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct ShinkaiRegistryInterface.ClaimIdentityParams", + "components": [ + { "name": "name", "type": "string", "internalType": "string" }, + { + "name": "namespace", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stakeAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "owner", "type": "address", "internalType": "address" } + ] + }, + { + "name": "setDataParams", + "type": "tuple", + "internalType": "struct ShinkaiRegistryInterface.SetDataParams", + "components": [ + { + "name": "encryptionKey", + "type": "string", + "internalType": "string" + }, + { + "name": "signatureKey", + "type": "string", + "internalType": "string" + }, + { "name": "routing", "type": "bool", "internalType": "bool" }, + { + "name": "addressOrProxyNodes", + "type": "string[]", + "internalType": "string[]" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimIdentityBatched", + "inputs": [ + { + "name": "params", + "type": "tuple[]", + "internalType": "struct ShinkaiRegistryInterface.ClaimIdentityParams[]", + "components": [ + { "name": "name", "type": "string", "internalType": "string" }, + { + "name": "namespace", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stakeAmount", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "owner", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewards", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimRewardsBatched", + "inputs": [ + { "name": "identities", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimStakingRewards", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimStakingRewardsBatched", + "inputs": [ + { "name": "identities", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [ + { + "name": "tokensAccrued", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "decreaseStake", + "inputs": [ + { "name": "name", "type": "string", "internalType": "string" }, + { "name": "namespace", "type": "uint256", "internalType": "uint256" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getAvailableTokensForDelegation", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getDelegatedTokensTowards", + "inputs": [ + { "name": "fromIdentity", "type": "string", "internalType": "string" }, + { "name": "toIdentity", "type": "string", "internalType": "string" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getDelegatees", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [ + { "name": "", "type": "string[]", "internalType": "string[]" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getIdentity", + "inputs": [ + { "name": "name", "type": "string", "internalType": "string" }, + { "name": "namespace", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "string", "internalType": "string" }], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getIdentityData", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct ShinkaiRegistryInterface.IdentityData", + "components": [ + { + "name": "boundNft", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "stakedTokens", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "encryptionKey", + "type": "string", + "internalType": "string" + }, + { + "name": "signatureKey", + "type": "string", + "internalType": "string" + }, + { "name": "routing", "type": "bool", "internalType": "bool" }, + { + "name": "addressOrProxyNodes", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "delegatedTokens", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "lastUpdated", + "type": "uint256", + "internalType": "uint256" + } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "identityDelegatees", + "inputs": [ + { "name": "", "type": "string", "internalType": "string" }, + { "name": "", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "string", "internalType": "string" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "identityDelegationAccrued", + "inputs": [{ "name": "", "type": "string", "internalType": "string" }], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "identityDelegationIndex", + "inputs": [{ "name": "", "type": "string", "internalType": "string" }], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "identityDelegations", + "inputs": [ + { "name": "", "type": "string", "internalType": "string" }, + { "name": "", "type": "string", "internalType": "string" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "identityStakeRequirement", + "inputs": [ + { "name": "name", "type": "string", "internalType": "string" }, + { "name": "namespace", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "identityStakingIndex", + "inputs": [{ "name": "", "type": "string", "internalType": "string" }], + "outputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "increaseStake", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { "name": "shinToken_", "type": "address", "internalType": "address" }, + { "name": "shinkaiNft_", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ownerOf", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "readRecords", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "keys", "type": "string[]", "internalType": "string[]" }, + { "name": "values", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [ + { "name": "", "type": "string[]", "internalType": "string[]" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeRecords", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "keys", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "resetIdentityData", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "rewardsState", + "inputs": [], + "outputs": [ + { "name": "index", "type": "uint224", "internalType": "uint224" }, + { "name": "block", "type": "uint32", "internalType": "uint32" } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setBaseRewardsRate", + "inputs": [ + { "name": "rate", "type": "uint256", "internalType": "uint256" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setData", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { + "name": "params", + "type": "tuple", + "internalType": "struct ShinkaiRegistryInterface.SetDataParams", + "components": [ + { + "name": "encryptionKey", + "type": "string", + "internalType": "string" + }, + { + "name": "signatureKey", + "type": "string", + "internalType": "string" + }, + { "name": "routing", "type": "bool", "internalType": "bool" }, + { + "name": "addressOrProxyNodes", + "type": "string[]", + "internalType": "string[]" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setDataBatched", + "inputs": [ + { + "name": "identities", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "setDataParams", + "type": "tuple[]", + "internalType": "struct ShinkaiRegistryInterface.SetDataParams[]", + "components": [ + { + "name": "encryptionKey", + "type": "string", + "internalType": "string" + }, + { + "name": "signatureKey", + "type": "string", + "internalType": "string" + }, + { "name": "routing", "type": "bool", "internalType": "bool" }, + { + "name": "addressOrProxyNodes", + "type": "string[]", + "internalType": "string[]" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setDelegations", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { + "name": "delegations", + "type": "tuple[]", + "internalType": "struct ShinkaiRegistryInterface.Delegation[]", + "components": [ + { "name": "delegatee", "type": "string", "internalType": "string" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setKeys", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "encryptionKey", "type": "string", "internalType": "string" }, + { "name": "signatureKey", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setNodeAddress", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "nodeAddress", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "setProxyNodes", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "proxyNodes", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "shinToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ShinkaiTokenInterface" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "shinkaiNft", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract ShinkaiNFTInterface" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "tokenIdToIdentity", + "inputs": [{ "name": "", "type": "uint256", "internalType": "uint256" }], + "outputs": [{ "name": "", "type": "string", "internalType": "string" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { "name": "newOwner", "type": "address", "internalType": "address" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "unclaimIdentity", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "unclaimIdentityBatched", + "inputs": [ + { "name": "identities", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "updateRecords", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" }, + { "name": "keys", "type": "string[]", "internalType": "string[]" }, + { "name": "values", "type": "string[]", "internalType": "string[]" } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeTo", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { "name": "data", "type": "bytes", "internalType": "bytes" } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "validName", + "inputs": [ + { "name": "name", "type": "string", "internalType": "string" } + ], + "outputs": [{ "name": "", "type": "bool", "internalType": "bool" }], + "stateMutability": "pure" + }, + { + "type": "event", + "name": "AddressOrProxyNodesUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "routing", + "type": "bool", + "indexed": false, + "internalType": "bool" + }, + { + "name": "addressOrProxyNodes", + "type": "string[]", + "indexed": false, + "internalType": "string[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AdminChanged", + "inputs": [ + { + "name": "previousAdmin", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "newAdmin", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BaseRewardsRateUpdate", + "inputs": [ + { + "name": "newRate", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "BeaconUpgraded", + "inputs": [ + { + "name": "beacon", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DelegatedTokensUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "newDelegatedTokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DelegationRewardsAccrual", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "rewards", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DelegationRewardsClaim", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "rewards", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DelegationsUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "delegations", + "type": "tuple[]", + "indexed": false, + "internalType": "struct ShinkaiRegistryInterface.Delegation[]", + "components": [ + { "name": "delegatee", "type": "string", "internalType": "string" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "IdentityClaim", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "nftTokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "identityRaw", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "IdentityUnclaim", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "nftTokenId", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "KeysUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "encryptionKey", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "signatureKey", + "type": "string", + "indexed": false, + "internalType": "string" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "previousOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RecordsRemoval", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "keys", + "type": "string[]", + "indexed": false, + "internalType": "string[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RecordsUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "keys", + "type": "string[]", + "indexed": false, + "internalType": "string[]" + }, + { + "name": "values", + "type": "string[]", + "indexed": false, + "internalType": "string[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StakeUpdate", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "newStake", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StakingRewardsClaim", + "inputs": [ + { + "name": "identity", + "type": "string", + "indexed": true, + "internalType": "string" + }, + { + "name": "rewards", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "DelegatedTokensExceedingStakedTokens", + "inputs": [ + { + "name": "delegatedTokens", + "type": "uint256", + "internalType": "uint256" + }, + { "name": "stakedTokens", "type": "uint256", "internalType": "uint256" } + ] + }, + { + "type": "error", + "name": "IdentityNotAvailable", + "inputs": [ + { "name": "identity", "type": "string", "internalType": "string" } + ] + }, + { "type": "error", "name": "InputArityMismatch", "inputs": [] }, + { + "type": "error", + "name": "InsufficientStakeAmountForDelegation", + "inputs": [] + }, + { + "type": "error", + "name": "InsufficientStakeAmountForIdentity", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidBaseRewardsRate", + "inputs": [ + { "name": "rate", "type": "uint256", "internalType": "uint256" } + ] + }, + { + "type": "error", + "name": "InvalidDelegationAmount", + "inputs": [ + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + }, + { + "type": "error", + "name": "InvalidName", + "inputs": [{ "name": "name", "type": "string", "internalType": "string" }] + }, + { + "type": "error", + "name": "InvalidNamespace", + "inputs": [ + { "name": "namespace", "type": "uint256", "internalType": "uint256" } + ] + }, + { "type": "error", "name": "Unauthorized", "inputs": [] } + ] \ No newline at end of file diff --git a/src/crypto_identities/shinkai_registry.rs b/src/crypto_identities/shinkai_registry.rs index a8f2d2ee1..73c866052 100644 --- a/src/crypto_identities/shinkai_registry.rs +++ b/src/crypto_identities/shinkai_registry.rs @@ -1,17 +1,25 @@ +use chrono::DateTime; +use chrono::Utc; use dashmap::DashMap; +use ed25519_dalek::VerifyingKey; use ethers::abi::Abi; use ethers::prelude::*; +use hex; use lazy_static::lazy_static; +use shinkai_message_primitives::shinkai_utils::encryption::string_to_encryption_public_key; use shinkai_message_primitives::shinkai_utils::shinkai_logging::shinkai_log; use shinkai_message_primitives::shinkai_utils::shinkai_logging::ShinkaiLogLevel; use shinkai_message_primitives::shinkai_utils::shinkai_logging::ShinkaiLogOption; +use shinkai_message_primitives::shinkai_utils::signatures::string_to_signature_public_key; use std::convert::TryFrom; use std::fmt; use std::fs; +use std::net::{AddrParseError, SocketAddr}; use std::sync::Arc; -use std::time::Duration; use std::time::SystemTime; +use std::time::{Duration, UNIX_EPOCH}; use tokio::task; +use x25519_dalek::PublicKey; lazy_static! { static ref CACHE_TIME: Duration = Duration::from_secs(60 * 10); @@ -25,6 +33,7 @@ pub enum ShinkaiRegistryError { JsonError(serde_json::Error), CustomError(String), SystemTimeError(std::time::SystemTimeError), + AddressParseError(AddrParseError), } impl fmt::Display for ShinkaiRegistryError { @@ -36,10 +45,17 @@ impl fmt::Display for ShinkaiRegistryError { ShinkaiRegistryError::JsonError(err) => write!(f, "JSON Error: {}", err), ShinkaiRegistryError::CustomError(err) => write!(f, "Custom Error: {}", err), ShinkaiRegistryError::SystemTimeError(err) => write!(f, "System Time Error: {}", err), + ShinkaiRegistryError::AddressParseError(err) => write!(f, "Address Parse Error: {}", err), } } } +impl From for ShinkaiRegistryError { + fn from(err: AddrParseError) -> ShinkaiRegistryError { + ShinkaiRegistryError::AddressParseError(err) + } +} + impl From for ShinkaiRegistryError { fn from(err: std::time::SystemTimeError) -> ShinkaiRegistryError { ShinkaiRegistryError::SystemTimeError(err) @@ -74,6 +90,7 @@ impl std::error::Error for ShinkaiRegistryError {} #[derive(Debug, PartialEq, Clone)] pub struct OnchainIdentity { + pub shinkai_identity: String, pub bound_nft: U256, // id of the nft pub staked_tokens: U256, pub encryption_key: String, @@ -81,6 +98,27 @@ pub struct OnchainIdentity { pub routing: bool, pub address_or_proxy_nodes: Vec, pub delegated_tokens: U256, + pub last_updated: DateTime, +} + +impl OnchainIdentity { + pub fn first_address(&self) -> Result { + if let Some(first_address) = self.address_or_proxy_nodes.first() { + first_address.parse().map_err(ShinkaiRegistryError::from) + } else { + Err(ShinkaiRegistryError::CustomError("No address available".to_string())) + } + } + + pub fn encryption_public_key(&self) -> Result { + string_to_encryption_public_key(&self.encryption_key) + .map_err(|err| ShinkaiRegistryError::CustomError(err.to_string())) + } + + pub fn signature_verifying_key(&self) -> Result { + string_to_signature_public_key(&self.signature_key) + .map_err(|err| ShinkaiRegistryError::CustomError(err.to_string())) + } } pub trait ShinkaiRegistryTrait { @@ -99,7 +137,8 @@ pub struct ShinkaiRegistry { impl ShinkaiRegistry { pub async fn new(url: &str, contract_address: &str, abi_path: &str) -> Result { - let provider = Provider::::try_from(url).map_err(|err| ShinkaiRegistryError::CustomError(err.to_string()))?; + let provider = + Provider::::try_from(url).map_err(|err| ShinkaiRegistryError::CustomError(err.to_string()))?; let contract_address: Address = contract_address.parse().map_err(|e| { shinkai_log( ShinkaiLogOption::CryptoIdentity, @@ -121,7 +160,7 @@ impl ShinkaiRegistry { pub async fn get_identity_record(&mut self, identity: String) -> Result { let now = SystemTime::now(); - + // If the cache is up-to-date, return the cached value if let Some(value) = self.cache.get(&identity) { let (last_updated, record) = value.value().clone(); @@ -140,23 +179,27 @@ impl ShinkaiRegistry { ); } }); - + return Ok(record); } } - + // Otherwise, update the cache let record = Self::update_cache(&self.contract, &self.cache, identity.clone()).await?; Ok(record.clone()) } - async fn update_cache(contract: &ContractInstance>, Provider>, cache: &DashMap, identity: String) -> Result { + async fn update_cache( + contract: &ContractInstance>, Provider>, + cache: &DashMap, + identity: String, + ) -> Result { // Fetch the identity record from the contract let record = Self::fetch_identity_record(contract, identity.clone()).await?; - + // Update the cache and the timestamp cache.insert(identity.clone(), (SystemTime::now(), record.clone())); - + Ok(record) } @@ -164,10 +207,14 @@ impl ShinkaiRegistry { self.cache.get(identity).map(|value| value.value().0) } - pub async fn fetch_identity_record(contract: &ContractInstance>, Provider>, identity: String) -> Result { - let function_call = match contract - .method::<_, (U256, U256, String, String, bool, Vec, U256)>("getIdentityRecord", (identity,)) - { + pub async fn fetch_identity_record( + contract: &ContractInstance>, Provider>, + identity: String, + ) -> Result { + let function_call = match contract.method::<_, (U256, U256, String, String, bool, Vec, U256, U256)>( + "getIdentityData", + (identity.clone(),), + ) { Ok(call) => call, Err(err) => { shinkai_log( @@ -179,7 +226,7 @@ impl ShinkaiRegistry { } }; - let result: (U256, U256, String, String, bool, Vec, U256) = match function_call.call().await { + let result: (U256, U256, String, String, bool, Vec, U256, U256) = match function_call.call().await { Ok(res) => res, Err(e) => { shinkai_log( @@ -191,7 +238,11 @@ impl ShinkaiRegistry { } }; + let last_updated = UNIX_EPOCH + Duration::from_secs(result.7.low_u64()); + let last_updated = DateTime::::from(last_updated); + Ok(OnchainIdentity { + shinkai_identity: identity, bound_nft: result.0, staked_tokens: result.1, encryption_key: result.2, @@ -199,6 +250,7 @@ impl ShinkaiRegistry { routing: result.4, address_or_proxy_nodes: result.5, delegated_tokens: result.6, + last_updated, }) } } diff --git a/src/db/db_inbox.rs b/src/db/db_inbox.rs index 7d526c9d2..8d690be2e 100644 --- a/src/db/db_inbox.rs +++ b/src/db/db_inbox.rs @@ -58,16 +58,6 @@ impl ShinkaiDB { // Commit the write batch self.db.write(batch)?; - { - // Note: this is the code for enabling WS - if let Some(manager) = &self.ws_manager { - let m = manager.lock().await; - let _ = m - .queue_message(WSTopic::SmartInboxes, "".to_string(), inbox_name.clone()) - .await; - } - } - Ok(()) } diff --git a/src/db/db_jobs.rs b/src/db/db_jobs.rs index 903ffdb0a..c3f5c07c6 100644 --- a/src/db/db_jobs.rs +++ b/src/db/db_jobs.rs @@ -7,7 +7,6 @@ use rocksdb::{IteratorMode, Options, WriteBatch}; use shinkai_message_primitives::schemas::{inbox_name::InboxName, shinkai_time::ShinkaiTime}; use shinkai_message_primitives::shinkai_message::shinkai_message::ShinkaiMessage; use shinkai_message_primitives::shinkai_utils::job_scope::JobScope; -use shinkai_message_primitives::shinkai_utils::utils::hash_string; enum JobInfo { IsFinished, diff --git a/src/main.rs b/src/main.rs index d55716ffc..f781c6f74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; use shinkai_message_primitives::shinkai_utils::encryption::{ encryption_public_key_to_string, encryption_secret_key_to_string, }; -use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption}; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption, init_tracing}; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, hash_signature_public_key, signature_public_key_to_string, signature_secret_key_to_string, @@ -48,7 +48,7 @@ mod utils; mod vector_fs; fn main() { - env_logger::init(); + init_tracing(); let main_db: &str = "main_db"; let vector_fs_db: &str = "vector_fs_db"; @@ -65,7 +65,9 @@ fn main() { // Storage db filesystem let main_db_path = get_main_db_path(main_db, &node_keys.identity_public_key, node_storage_path.clone()); + eprintln!("main_db_path: {}", main_db_path); let vector_fs_db_path = get_vector_fs_db_path(vector_fs_db, &node_keys.identity_public_key, node_storage_path); + eprintln!("vector_fs_db_path: {}", vector_fs_db_path); // Acquire the Node's keys. TODO: Should check with on // and then it's with onchain data for matching with the keys provided @@ -84,6 +86,9 @@ fn main() { let encryption_secret_key_string = encryption_secret_key_to_string(node_keys.encryption_secret_key.clone()); let encryption_public_key_string = encryption_public_key_to_string(node_keys.encryption_public_key.clone()); + eprintln!("Encryption Public Key: {}", encryption_public_key_string); + eprintln!("Signature Public Key: {}", identity_public_key_string); + // Initialize Embedding Generator & Unstructured API let embedding_generator = init_embedding_generator(&node_env); let unstructured_api = init_unstructured_api(&node_env); @@ -202,13 +207,15 @@ fn main() { }); } -/// Initialzied Tokio runtime +/// Initialized Tokio runtime fn initialize_runtime() -> Runtime { Runtime::new().unwrap() } /// Machine filesystem path to the main ShinkaiDB database, pub key based. fn get_main_db_path(main_db: &str, identity_public_key: &VerifyingKey, node_storage_path: Option) -> String { + eprintln!("node_storage_path: {:?}", node_storage_path); + eprintln!("main_db: {:?}", main_db); if let Some(path) = node_storage_path { Path::new(&path) .join(main_db) diff --git a/src/managers/identity_manager.rs b/src/managers/identity_manager.rs index cb9336565..3595958b2 100644 --- a/src/managers/identity_manager.rs +++ b/src/managers/identity_manager.rs @@ -1,17 +1,18 @@ use super::identity_network_manager::IdentityNetworkManager; +use crate::crypto_identities::shinkai_registry::ShinkaiRegistryError; use crate::db::db_errors::ShinkaiDBError; use crate::db::ShinkaiDB; use crate::network::node_error::NodeError; use crate::network::node_message_handlers::verify_message_signature; use crate::schemas::identity::{DeviceIdentity, Identity, StandardIdentity, StandardIdentityType}; +use async_trait::async_trait; use shinkai_message_primitives::schemas::agents::serialized_agent::SerializedAgent; use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; use shinkai_message_primitives::shinkai_message::shinkai_message::ShinkaiMessage; use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::IdentityPermissions; -use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogOption, ShinkaiLogLevel}; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption}; use std::sync::Arc; use tokio::sync::Mutex; -use async_trait::async_trait; #[derive(Clone)] pub struct IdentityManager { @@ -60,10 +61,10 @@ impl IdentityManager { let db = db.lock().await; db.debug_print_all_keys_for_profiles_identity_key(); } - + identities.extend(agents); - let external_identity_manager = Arc::new(Mutex::new(IdentityNetworkManager::new())); + let external_identity_manager = Arc::new(Mutex::new(IdentityNetworkManager::new().await)); // Logic to check if the node is ready let current_ready_status = identities.iter().any(|identity| { @@ -83,10 +84,7 @@ impl IdentityManager { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Info, - format!( - "add_profile_subidentity > identity: {}", - identity - ).as_str() + format!("add_profile_subidentity > identity: {}", identity).as_str(), ); let previously_had_profile_identity = self.has_profile_identity(); self.local_identities.push(Identity::Standard(identity.clone())); @@ -95,10 +93,7 @@ impl IdentityManager { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Debug, - format!( - "YAY! first profile added! identity: {}", - identity - ).as_str() + format!("YAY! first profile added! identity: {}", identity).as_str(), ); self.is_ready = true; } @@ -109,10 +104,7 @@ impl IdentityManager { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Info, - format!( - "add_agent_subidentity > agent: {:?}", - agent - ).as_str() + format!("add_agent_subidentity > agent: {:?}", agent).as_str(), ); self.local_identities.push(Identity::Agent(agent.clone())); Ok(()) @@ -122,10 +114,7 @@ impl IdentityManager { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Info, - format!( - "add_device_subidentity > device: {}", - device - ).as_str() + format!("add_device_subidentity > device: {}", device).as_str(), ); self.local_identities.push(Identity::Device(device.clone())); Ok(()) @@ -192,14 +181,15 @@ impl IdentityManager { db.get_all_agents() } - pub async fn external_profile_to_global_identity(&self, full_profile_name: &str) -> Option { + pub async fn external_profile_to_global_identity(&self, full_profile_name: &str) -> Result { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Debug, format!( "external_profile_to_global_identity > full_profile_name: {}", full_profile_name - ).as_str() + ) + .as_str(), ); let full_identity_name = match ShinkaiName::new(full_profile_name.to_string().clone()) { @@ -210,29 +200,49 @@ impl IdentityManager { ShinkaiLogLevel::Error, format!( "external_profile_to_global_identity > is_valid_node_identity_name_and_no_subidentities: false" - ).as_str() + ) + .as_str(), ); - return None; + return Err(format!( + "Failed to convert profile name to ShinkaiName: {}", + full_profile_name + )); } }; let node_name = full_identity_name.get_node_name().to_string(); let external_im = self.external_identity_manager.lock().await; + match external_im .external_identity_to_profile_data(node_name.to_string()) .await { - Ok(identity_network_manager) => Some(StandardIdentity::new( - full_identity_name.extract_node(), - Some(identity_network_manager.addr), - identity_network_manager.encryption_public_key, - identity_network_manager.signature_public_key, - None, - None, - StandardIdentityType::Global, - IdentityPermissions::None, - )), - Err(_) => None, // return None if the identity is not found in the network manager + Ok(identity_network_manager) => match identity_network_manager.first_address() { + Ok(first_address) => { + eprintln!("first_address: {:?}", first_address); + eprintln!("identity_network_manager: {:?}", identity_network_manager); + let encryption_key = match identity_network_manager.encryption_public_key() { + Ok(key) => key, + Err(e) => return Err(format!("Failed to get encryption public key: {}", e.to_string())), + }; + let signature_key = match identity_network_manager.signature_verifying_key() { + Ok(key) => key, + Err(e) => return Err(format!("Failed to get signature verifying key: {}", e.to_string())), + }; + Ok(StandardIdentity::new( + full_identity_name.extract_node(), + Some(first_address), + encryption_key, + signature_key, + None, + None, + StandardIdentityType::Global, + IdentityPermissions::None, + )) + } + Err(_) => Err("Failed to get first address".to_string()), + }, + Err(_) => Err(format!("Failed to get identity network manager for profile name: {}", full_profile_name)), } } } @@ -250,11 +260,10 @@ impl IdentityManagerTrait for IdentityManager { }) } - async fn search_identity(&self, full_identity_name: &str) -> Option { let identity_name = ShinkaiName::new(full_identity_name.to_string()).ok()?; let node_name = identity_name.extract_node(); - + // If the node name matches local node, search in self.identities if self.local_node_name == node_name { self.search_local_identity(full_identity_name).await @@ -265,16 +274,29 @@ impl IdentityManagerTrait for IdentityManager { .external_identity_to_profile_data(full_identity_name.to_string()) .await { - Ok(identity_network_manager) => Some(Identity::Standard(StandardIdentity::new( - node_name, - Some(identity_network_manager.addr), - identity_network_manager.encryption_public_key, - identity_network_manager.signature_public_key, - None, - None, - StandardIdentityType::Global, - IdentityPermissions::None, - ))), + Ok(identity_network_manager) => match identity_network_manager.first_address() { + Ok(first_address) => { + let encryption_key = match identity_network_manager.encryption_public_key() { + Ok(key) => key, + Err(_) => return None, + }; + let signature_key = match identity_network_manager.signature_verifying_key() { + Ok(key) => key, + Err(_) => return None, + }; + Some(Identity::Standard(StandardIdentity::new( + node_name, + Some(first_address), + encryption_key, + signature_key, + None, + None, + StandardIdentityType::Global, + IdentityPermissions::None, + ))) + } + Err(_) => None, + }, Err(_) => None, // return None if the identity is not found in the network manager } } @@ -307,7 +329,8 @@ impl IdentityManager { format!( "signature check > Subidentity not found for profile name: {}", decrypted_message.external_metadata.clone().sender - ).as_str() + ) + .as_str(), ); return Err(NodeError { message: format!( @@ -328,9 +351,7 @@ impl IdentityManager { shinkai_log( ShinkaiLogOption::Identity, ShinkaiLogLevel::Error, - format!( - "signature check > Agent identities cannot send onionized messages" - ).as_str() + format!("signature check > Agent identities cannot send onionized messages").as_str(), ); return Ok(()); } @@ -343,7 +364,8 @@ impl IdentityManager { format!( "signature check > Signature public key doesn't exist for identity: {}", subidentity.get_full_identity_name() - ).as_str() + ) + .as_str(), ); return Err(NodeError { message: format!("Failed to verify message signature. Signature public key doesn't exist for identity"), @@ -359,7 +381,8 @@ impl IdentityManager { format!( "signature check > Failed to verify message signature: {}", e.to_string() - ).as_str() + ) + .as_str(), ); return Err(NodeError { message: format!("Failed to verify message signature: {}", e.to_string()), diff --git a/src/managers/identity_network_manager.rs b/src/managers/identity_network_manager.rs index 28791cb2f..0ce431964 100644 --- a/src/managers/identity_network_manager.rs +++ b/src/managers/identity_network_manager.rs @@ -1,131 +1,48 @@ -use ed25519_dalek::VerifyingKey; -use shinkai_message_primitives::shinkai_utils::{signatures::{signature_public_key_to_string, string_to_signature_public_key}, encryption::string_to_encryption_public_key}; +use shinkai_message_primitives::shinkai_utils::{ + signatures::{signature_public_key_to_string, string_to_signature_public_key}, +}; use std::{collections::HashMap, net::SocketAddr, sync::Arc}; use tokio::sync::Mutex; -use x25519_dalek::{PublicKey as EncryptionPublicKey}; +use x25519_dalek::PublicKey as EncryptionPublicKey; -#[derive(Debug)] -pub struct NetworkIdentity { - pub node_identity_name: String, - pub addr: SocketAddr, - pub signature_public_key: VerifyingKey, - pub encryption_public_key: EncryptionPublicKey, -} +use crate::crypto_identities::shinkai_registry::{OnchainIdentity, ShinkaiRegistry}; pub struct IdentityNetworkManager { - identities: Arc>>, + registry: Arc>, + identities: Arc>>, } impl IdentityNetworkManager { - pub fn get_mock_identities() -> HashMap { - let mut m = HashMap::new(); - // RPC call simulation for node data fetch - // Here, I am reusing the hardcoded data, but you should replace this section with actual RPC calls - m.insert( - "@@node1.shinkai".to_string(), // nico - NetworkIdentity { - node_identity_name: "@@node1.shinkai".to_string(), - addr: SocketAddr::from(([192, 168, 1, 109], 8080)), - signature_public_key: string_to_signature_public_key("69fa099bdce516bfeb46d5fc6e908f6cf8ffac0aba76ca0346a7b1a751a2712e") - .expect("Failed to parse public key"), - encryption_public_key: string_to_encryption_public_key("60045bdb15c24b161625cf05558078208698272bfe113f792ea740dbd79f4708") - .expect("Failed to parse public key"), - }, - ); - m.insert( - "@@node2.shinkai".to_string(), // nico-linux - NetworkIdentity { - node_identity_name: "@@node2.shinkai".to_string(), - addr: SocketAddr::from(([192, 168, 1, 233], 8081)), - signature_public_key: string_to_signature_public_key("389fb4bbb3d382a2f2f23cdfa5614ed288975bc4f4a0448876efba108dc2c583") - .expect("Failed to parse public key"), - encryption_public_key: string_to_encryption_public_key("912fed05e286af45f44580d6a87da61e1f9a0946237dd29f7bc2d3cbeba0857f") - .expect("Failed to parse public key"), - }, - ); - m.insert( - "@@node3.shinkai".to_string(), - NetworkIdentity { - node_identity_name: "@@node3.shinkai".to_string(), - addr: SocketAddr::from(([127, 0, 0, 1], 8082)), - signature_public_key: string_to_signature_public_key("63dd3953fe0b9e3212503fc1de9be9b46008615a4522facf271f0c2b3585c3e6") - .expect("Failed to parse public key"), - encryption_public_key: string_to_encryption_public_key("3273d113e401a215e429e3272352186a7370cf7edf1e2d68aa7ef87a20237371") - .expect("Failed to parse public key"), - }, - ); - m.insert( - "@@node1_test.shinkai".to_string(), // nico - NetworkIdentity { - node_identity_name: "@@node1_test.shinkai".to_string(), - addr: SocketAddr::from(([127, 0, 0, 1], 8080)), - signature_public_key: string_to_signature_public_key("69fa099bdce516bfeb46d5fc6e908f6cf8ffac0aba76ca0346a7b1a751a2712e") - .expect("Failed to parse public key"), - encryption_public_key: string_to_encryption_public_key("60045bdb15c24b161625cf05558078208698272bfe113f792ea740dbd79f4708") - .expect("Failed to parse public key"), - }, - ); - m.insert( - "@@node2_test.shinkai".to_string(), // nico-linux - NetworkIdentity { - node_identity_name: "@@node2_test.shinkai".to_string(), - addr: SocketAddr::from(([127, 0, 0, 1], 8081)), - signature_public_key: string_to_signature_public_key("389fb4bbb3d382a2f2f23cdfa5614ed288975bc4f4a0448876efba108dc2c583") - .expect("Failed to parse public key"), - encryption_public_key: string_to_encryption_public_key("912fed05e286af45f44580d6a87da61e1f9a0946237dd29f7bc2d3cbeba0857f") - .expect("Failed to parse public key"), - }, - ); - m - } - - pub fn new() -> Self { - let identities = Arc::new(Mutex::new(Self::get_mock_identities())); - IdentityNetworkManager { identities } + pub async fn new() -> Self { + // TODO: read from config + let registry = ShinkaiRegistry::new( + "https://rpc.sepolia.org", + "0x6964241D2458f0Fd300BB37535CF0145380810E0", + "./src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json", + ) + .await + .unwrap(); + + let registry = Arc::new(Mutex::new(registry)); + let identities = Arc::new(Mutex::new(HashMap::new())); + + IdentityNetworkManager { registry, identities } } pub async fn external_identity_to_profile_data( &self, global_identity: String, - ) -> Result { - let identities = self.identities.lock().await; - match identities.get(&global_identity) { - Some(data) => Ok(NetworkIdentity { - node_identity_name: data.node_identity_name.clone(), - addr: data.addr, - signature_public_key: data.signature_public_key.clone(), - encryption_public_key: data.encryption_public_key.clone(), - }), - None => Err("Unrecognized global identity"), - } - } - - pub async fn identity_pk_to_external_identity(&self, pk: VerifyingKey) -> Result { - let pk_string = signature_public_key_to_string(pk); - let identities = self.identities.lock().await; - for (global_identity, data) in identities.iter() { - if signature_public_key_to_string(data.signature_public_key) == pk_string { - return Ok(global_identity.clone()); + ) -> Result { + eprintln!("(external_identity) Getting identity record for {}", global_identity); + let record = { + let identity = global_identity.trim_start_matches("@@"); + let mut registry = self.registry.lock().await; + match registry.get_identity_record(identity.to_string()).await { + Ok(record) => record, + Err(_) => return Err("Unrecognized global identity"), } - } - Err("Unrecognized public key") - } - - pub async fn addr_to_external_profile_data(&self, addr: SocketAddr) -> Vec { - let mut result = Vec::new(); - let identities = self.identities.lock().await; - - for (_, data) in identities.iter() { - if data.addr == addr { - result.push(NetworkIdentity { - node_identity_name: data.node_identity_name.clone(), - addr: data.addr, - signature_public_key: data.signature_public_key.clone(), - encryption_public_key: data.encryption_public_key.clone(), - }); - } - } - - result + }; + + Ok(record) } } diff --git a/src/network/node.rs b/src/network/node.rs index 8a6206d55..6d90d4abd 100644 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -826,7 +826,7 @@ impl Node { // TODO: add identity to this fn so we can check for permissions shinkai_log( ShinkaiLogOption::Node, - ShinkaiLogLevel::Debug, + ShinkaiLogLevel::Info, &format!("save_to_db> message_to_save: {:?}", message_to_save.clone()), ); let mut db = db.lock().await; diff --git a/src/network/node_api.rs b/src/network/node_api.rs index b223076cc..b61df2612 100644 --- a/src/network/node_api.rs +++ b/src/network/node_api.rs @@ -65,6 +65,26 @@ impl From<&str> for APIError { } } +impl From> for APIError { + fn from(error: async_channel::SendError) -> Self { + APIError { + code: StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + error: "Internal Server Error".to_string(), + message: format!("Failed with error: {}", error), + } + } +} + +impl From for APIError { + fn from(error: String) -> Self { + APIError { + code: StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + error: "Internal Server Error".to_string(), + message: error, + } + } +} + impl warp::reject::Reject for APIError {} pub async fn run_api(node_commands_sender: Sender, address: SocketAddr, node_name: String) { @@ -505,14 +525,15 @@ async fn send_msg_handler( res: res_send_msg_sender, }) .await - .map_err(|_| warp::reject::reject())?; - let send_result = res_send_msg_receiver.recv().await.map_err(|_| warp::reject::reject())?; - if send_result.is_err() { - return Err(warp::reject::reject()); + .map_err(|e| warp::reject::custom(APIError::from(e)))?; + let send_result = res_send_msg_receiver.recv().await.map_err(|e| warp::reject::custom(APIError::from(format!("{}", e))))?; + match send_result { + Ok(_) => { + let resp = warp::reply::json(&"Message sent successfully"); + Ok(resp) + } + Err(api_error) => Err(warp::reject::custom(api_error)), } - - let resp = warp::reply::json(&"Message sent successfully"); - Ok(resp) } async fn get_peers_handler(node_commands_sender: Sender) -> Result { @@ -923,7 +944,11 @@ async fn get_all_subidentities_handler( } async fn handle_rejection(err: warp::Rejection) -> Result { - if err.is_not_found() { + eprintln!("rejection: {:?}", err); + if let Some(api_error) = err.find::() { + let json = warp::reply::json(api_error); + return Ok(warp::reply::with_status(json, StatusCode::from_u16(api_error.code).unwrap())); + } else if err.is_not_found() { let json = warp::reply::json(&APIError::new( StatusCode::NOT_FOUND, "Not Found", diff --git a/src/network/node_api_commands.rs b/src/network/node_api_commands.rs index fbd60ceb8..151c28aba 100644 --- a/src/network/node_api_commands.rs +++ b/src/network/node_api_commands.rs @@ -2113,7 +2113,6 @@ impl Node { // // Part 2: Check if the message needs to be sent to another node or not // - let recipient_node_name = ShinkaiName::from_shinkai_message_only_using_recipient_node_name(&msg.clone()) .unwrap() .get_node_name(); @@ -2184,18 +2183,26 @@ impl Node { .unwrap() .to_string(); - let external_global_identity = self + let external_global_identity_result = self .identity_manager .lock() .await .external_profile_to_global_identity(&recipient_node_name_string.clone()) - .await - .unwrap(); + .await; - println!( - "handle_onionized_message > recipient_profile_name_string: {}", - recipient_node_name_string - ); + let external_global_identity = match external_global_identity_result { + Ok(identity) => identity, + Err(err) => { + let _ = res + .send(Err(APIError { + code: StatusCode::INTERNAL_SERVER_ERROR.as_u16(), + error: "Error".to_string(), + message: err, + })) + .await; + return Ok(()); + } + }; msg.external_metadata.intra_sender = "".to_string(); msg.encryption = EncryptionMethod::DiffieHellmanChaChaPoly1305; diff --git a/src/network/node_message_handlers.rs b/src/network/node_message_handlers.rs index be3b35495..f27f3ccb5 100644 --- a/src/network/node_message_handlers.rs +++ b/src/network/node_message_handlers.rs @@ -1,5 +1,5 @@ use crate::{db::ShinkaiDB, managers::IdentityManager, network::Node}; -use ed25519_dalek::{VerifyingKey, SigningKey}; +use ed25519_dalek::{SigningKey, VerifyingKey}; use shinkai_message_primitives::{ shinkai_message::{ shinkai_message::{MessageBody, MessageData, ShinkaiMessage}, @@ -131,10 +131,7 @@ pub fn extract_message(bytes: &[u8], receiver_address: SocketAddr) -> io::Result }) } -pub fn verify_message_signature( - sender_signature_pk: VerifyingKey, - message: &ShinkaiMessage, -) -> io::Result<()> { +pub fn verify_message_signature(sender_signature_pk: VerifyingKey, message: &ShinkaiMessage) -> io::Result<()> { match message.verify_outer_layer_signature(&sender_signature_pk) { Ok(is_valid) if is_valid => Ok(()), Ok(_) => { @@ -143,10 +140,14 @@ pub fn verify_message_signature( ShinkaiLogLevel::Error, "Failed to validate message's signature", ); - shinkai_log(ShinkaiLogOption::Network, ShinkaiLogLevel::Error, &format!( - "Sender signature pk: {:?}", - signature_public_key_to_string(sender_signature_pk) - )); + shinkai_log( + ShinkaiLogOption::Network, + ShinkaiLogLevel::Error, + &format!( + "Sender signature pk: {:?}", + signature_public_key_to_string(sender_signature_pk) + ), + ); Err(io::Error::new( io::ErrorKind::Other, "Failed to validate message's signature", @@ -198,37 +199,52 @@ pub async fn handle_default_encryption( my_encryption_secret_key: &EncryptionStaticKey, my_signature_secret_key: &SigningKey, my_node_profile_name: &str, - receiver_address: SocketAddr, - unsafe_sender_address: SocketAddr, + _receiver_address: SocketAddr, + _unsafe_sender_address: SocketAddr, maybe_db: Arc>, maybe_identity_manager: Arc>, ) -> Result<(), NodeError> { - println!( - "{} > handle_default_encryption message: {:?}", - receiver_address, message - ); - println!( - "Sender encryption pk: {:?}", - encryption_public_key_to_string(sender_encryption_pk) - ); let decrypted_message_result = message.decrypt_outer_layer(&my_encryption_secret_key, &sender_encryption_pk); match decrypted_message_result { - Ok(_) => { - println!( - "{} > Got message from {:?}. Sending ACK", - receiver_address, unsafe_sender_address - ); - send_ack( - (sender_address.clone(), sender_profile_name.clone()), - clone_static_secret_key(my_encryption_secret_key), - clone_signature_secret_key(my_signature_secret_key), - sender_encryption_pk, - my_node_profile_name.to_string(), - sender_profile_name, - maybe_db, - maybe_identity_manager, - ) - .await + Ok(content) => { + // println!( + // "{} > Got message from {:?}. Sending ACK", + // receiver_address, unsafe_sender_address + // ); + + let message = content.get_message_content(); + match message { + Ok(message_content) => { + if message_content != "ACK" { + let _ = send_ack( + (sender_address.clone(), sender_profile_name.clone()), + clone_static_secret_key(my_encryption_secret_key), + clone_signature_secret_key(my_signature_secret_key), + sender_encryption_pk, + my_node_profile_name.to_string(), + sender_profile_name, + maybe_db, + maybe_identity_manager, + ) + .await; + } + } + Err(_) => { + // Note(Nico): if we can't decrypt the inner content (it's okay). We still send an ACK + let _ = send_ack( + (sender_address.clone(), sender_profile_name.clone()), + clone_static_secret_key(my_encryption_secret_key), + clone_signature_secret_key(my_signature_secret_key), + sender_encryption_pk, + my_node_profile_name.to_string(), + sender_profile_name, + maybe_db, + maybe_identity_manager, + ) + .await; + } + } + Ok(()) } Err(_) => { println!("handle_default_encryption > Failed to decrypt message."); diff --git a/src/network/node_shareable_logic.rs b/src/network/node_shareable_logic.rs index 9e87fe9f8..d22c276b1 100644 --- a/src/network/node_shareable_logic.rs +++ b/src/network/node_shareable_logic.rs @@ -58,7 +58,7 @@ pub async fn validate_message_main_logic( &potentially_encrypted_msg.clone(), )?; - eprintln!("sender_name: {:?}", sender_name); + // eprintln!("sender_name: {:?}", sender_name); let sender_encryption_pk = match identity_manager .lock() .await diff --git a/src/network/ws_manager.rs b/src/network/ws_manager.rs index 555243406..444e09584 100644 --- a/src/network/ws_manager.rs +++ b/src/network/ws_manager.rs @@ -118,7 +118,7 @@ impl WebSocketManager { ) { loop { // Sleep for a while - sleep(Duration::from_millis(500)).await; + sleep(Duration::from_millis(200)).await; // Check if there are any messages in the queue let message = { @@ -141,7 +141,6 @@ impl WebSocketManager { // Message can't be encrypted at this point let is_body_encrypted = message.clone().is_body_currently_encrypted(); if is_body_encrypted { - eprintln!("Message body is encrypted, can't validate user: {}", shinkai_name); shinkai_log( ShinkaiLogOption::DetailedAPI, ShinkaiLogLevel::Debug, @@ -180,17 +179,29 @@ impl WebSocketManager { }; match Node::has_inbox_access(self.shinkai_db.clone(), &inbox_name, &sender_identity).await { - Ok(_) => { - shinkai_log( - ShinkaiLogOption::WsAPI, - ShinkaiLogLevel::Error, - format!( - "Access granted for inbox: {} and sender_subidentity: {}", - inbox_name, shinkai_name.full_name - ) - .as_str(), - ); - return true; + Ok(value) => { + if value { + shinkai_log( + ShinkaiLogOption::WsAPI, + ShinkaiLogLevel::Debug, + format!( + "Access granted for inbox: {} and sender_subidentity: {}", + inbox_name, shinkai_name.full_name + ) + .as_str(), + ); + } else { + shinkai_log( + ShinkaiLogOption::WsAPI, + ShinkaiLogLevel::Debug, + format!( + "Access denied for inbox: {} and sender_subidentity: {}", + inbox_name, shinkai_name.full_name + ) + .as_str(), + ); + } + return value; } Err(_) => { shinkai_log( @@ -339,9 +350,9 @@ impl WebSocketManager { ); } - pub fn get_all_connections(&self) -> Vec>>> { - self.connections.values().cloned().collect() - } + // pub fn get_all_connections(&self) -> Vec>>> { + // self.connections.values().cloned().collect() + // } pub async fn handle_update(&self, topic: WSTopic, subtopic: String, update: String) { let topic_subtopic = format!("{}:::{}", topic, subtopic); @@ -351,19 +362,41 @@ impl WebSocketManager { format!("Sending update to topic: {}", topic_subtopic).as_str(), ); - // Check if topic is WS::SmartInboxes and ignore it if it is - if topic == WSTopic::SmartInboxes { - shinkai_log( - ShinkaiLogOption::WsAPI, - ShinkaiLogLevel::Debug, - format!("Ignoring update to topic: {}", topic_subtopic).as_str(), - ); - return; - } - // Send the update to all active connections that are subscribed to the topic for (id, connection) in self.connections.iter() { - if self.subscriptions.get(id).unwrap().get(&topic_subtopic).is_some() { + let is_subscribed_to_smart_inboxes = self + .subscriptions + .get(id) + .unwrap() + .get(&format!("{}:::{}", WSTopic::SmartInboxes, "")) + .is_some(); + let is_subscribed_to_topic = self.subscriptions.get(id).unwrap().get(&topic_subtopic).is_some(); + + if is_subscribed_to_smart_inboxes || is_subscribed_to_topic { + // If the user is subscribed to SmartInboxes, check if they have access to the specific inbox + if is_subscribed_to_smart_inboxes { + match ShinkaiName::new(id.clone()) { + Ok(shinkai_name) => { + let shinkai_name_clone = shinkai_name.clone(); + if !self.has_access(shinkai_name_clone, topic.clone(), Some(subtopic.clone())).await { + continue; + } + eprintln!( + "Access granted for shinkai_name: {} on topic: {:?} and subtopic: {:?}", + shinkai_name, topic, subtopic + ); + }, + Err(e) => { + shinkai_log( + ShinkaiLogOption::WsAPI, + ShinkaiLogLevel::Error, + format!("Failed to create ShinkaiName for id {}: {}", id, e).as_str(), + ); + continue; + } + } + } + let mut connection = connection.lock().await; // Encrypt the update using the shared key @@ -375,8 +408,16 @@ impl WebSocketManager { let encrypted_update_hex = hex::encode(&encrypted_update); match connection.send(Message::text(encrypted_update_hex.clone())).await { - Ok(_) => eprintln!("Successfully sent update to connection {}", id), - Err(e) => eprintln!("Failed to send update to connection {}: {}", id, e), + Ok(_) => shinkai_log( + ShinkaiLogOption::WsAPI, + ShinkaiLogLevel::Info, + format!("Successfully sent update to connection {}", id).as_str(), + ), + Err(e) => shinkai_log( + ShinkaiLogOption::WsAPI, + ShinkaiLogLevel::Error, + format!("Failed to send update to connection {}: {}", id, e).as_str(), + ), } } else { shinkai_log( diff --git a/src/utils/environment.rs b/src/utils/environment.rs index 3522ba157..6f383f04d 100644 --- a/src/utils/environment.rs +++ b/src/utils/environment.rs @@ -124,10 +124,10 @@ pub fn fetch_node_environment() -> NodeEnvironment { let js_toolkit_executor_remote: Option = env::var("JS_TOOLKIT_ADDRESS").ok().filter(|s| !s.is_empty()); - let no_secrets_file: bool = env::var("NO_secretsS_FILE") + let no_secrets_file: bool = env::var("NO_SECRET_FILE") .unwrap_or_else(|_| "false".to_string()) .parse() - .expect("Failed to parse NO_secretsS_FILE"); + .expect("Failed to parse NO_SECRET_FILE"); // Define the address and port where your node will listen let listen_address = SocketAddr::new(ip, port); diff --git a/tests/it/agent_integration_tests.rs b/tests/it/agent_integration_tests.rs index f60fc68ab..3e59ef578 100644 --- a/tests/it/agent_integration_tests.rs +++ b/tests/it/agent_integration_tests.rs @@ -9,7 +9,7 @@ use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{JobMe use shinkai_message_primitives::shinkai_utils::encryption::{ clone_static_secret_key, unsafe_deterministic_encryption_keypair, EncryptionMethod, }; -use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption}; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption, init_tracing}; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -40,6 +40,7 @@ fn setup() { #[test] fn node_agent_registration() { + init_tracing(); // WIP: need to find a way to test the agent registration setup(); let rt = Runtime::new().unwrap(); diff --git a/tests/it/cron_job_tests.rs b/tests/it/cron_job_tests.rs index 3555de7db..1e0b37e05 100644 --- a/tests/it/cron_job_tests.rs +++ b/tests/it/cron_job_tests.rs @@ -10,7 +10,7 @@ mod tests { }, shinkai_utils::{ encryption::unsafe_deterministic_encryption_keypair, - signatures::{clone_signature_secret_key, unsafe_deterministic_signature_keypair}, + signatures::{clone_signature_secret_key, unsafe_deterministic_signature_keypair}, shinkai_logging::init_tracing, }, }; use shinkai_node::{ @@ -38,6 +38,7 @@ mod tests { #[tokio::test] async fn test_process_cron_job() { + init_tracing(); setup(); let db = Arc::new(Mutex::new(ShinkaiDB::new("db_tests/").unwrap())); let (identity_secret_key, identity_public_key) = unsafe_deterministic_signature_keypair(0); @@ -174,6 +175,8 @@ mod tests { #[test] fn test_should_execute_cron_task() { + init_tracing(); + use chrono::Timelike; use chrono::Utc; diff --git a/tests/it/crypto_payment_tests.rs b/tests/it/crypto_payment_tests.rs index 65ac6f51b..62c53081f 100644 --- a/tests/it/crypto_payment_tests.rs +++ b/tests/it/crypto_payment_tests.rs @@ -5,6 +5,7 @@ mod tests { use ethers::core::k256::SecretKey; use ethers::signers::LocalWallet; use ethers::signers::Signer; + use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_node::payments::execute_transaction::execute_transaction; use shinkai_node::payments::payment_manager::{PaymentManager, PaymentManagerError}; use shinkai_node::payments::payment_methods::CryptoNetwork; @@ -98,6 +99,7 @@ mod tests { #[ignore] #[tokio::test] async fn test_payment_manager() { + init_tracing(); let sepolia_rpc = "https://ethereum-sepolia.publicnode.com"; let execute_transaction_evm: fn( CryptoWallet, @@ -187,7 +189,6 @@ mod tests { _ => Err(PaymentManagerError::UnsupportedNetwork), }; - eprintln!("Result: {:?}", result); assert!(result.is_ok()); // Create SHIN token diff --git a/tests/it/db_agents_tests.rs b/tests/it/db_agents_tests.rs index 6bc7e3ca1..81c9343ea 100644 --- a/tests/it/db_agents_tests.rs +++ b/tests/it/db_agents_tests.rs @@ -18,7 +18,7 @@ mod tests { agents::serialized_agent::{AgentLLMInterface, OpenAI, SerializedAgent}, shinkai_name::ShinkaiName, }, - shinkai_utils::utils::hash_string, + shinkai_utils::{utils::hash_string, shinkai_logging::init_tracing}, }; use shinkai_node::agent::{agent::Agent, error::AgentError, execution::job_prompts::JobPromptGenerator}; @@ -26,6 +26,7 @@ mod tests { #[test] fn test_add_and_remove_agent() { + init_tracing(); setup(); // Initialize ShinkaiDB let db_path = format!("db_tests/{}", hash_string("agent_test")); @@ -79,6 +80,7 @@ mod tests { #[test] fn test_update_agent_access() { + init_tracing(); setup(); // Initialize ShinkaiDB let db_path = format!("db_tests/{}", hash_string("agent_test")); @@ -130,6 +132,7 @@ mod tests { #[test] fn test_get_agent_profiles_and_toolkits() { + init_tracing(); setup(); let db_path = format!("db_tests/{}", hash_string("agent_test")); let mut db = ShinkaiDB::new(&db_path).unwrap(); @@ -168,6 +171,7 @@ mod tests { #[test] fn test_remove_profile_and_toolkit_from_agent_access() { + init_tracing(); setup(); let db_path = format!("db_tests/{}", hash_string("agent_test".clone())); let mut db = ShinkaiDB::new(&db_path).unwrap(); @@ -209,6 +213,7 @@ mod tests { #[tokio::test] async fn test_agent_call_external_api_openai() { + init_tracing(); let mut server = Server::new(); let _m = server .mock("POST", "/v1/chat/completions") diff --git a/tests/it/db_identity_tests.rs b/tests/it/db_identity_tests.rs index 8c77e790e..293d87977 100644 --- a/tests/it/db_identity_tests.rs +++ b/tests/it/db_identity_tests.rs @@ -4,6 +4,7 @@ use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{Ident use shinkai_message_primitives::shinkai_utils::encryption::{ encryption_public_key_to_string, unsafe_deterministic_encryption_keypair, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::signatures::{ signature_public_key_to_string, unsafe_deterministic_signature_keypair, }; @@ -18,7 +19,6 @@ use std::path::Path; use ed25519_dalek::{VerifyingKey, SigningKey}; use x25519_dalek::{PublicKey as EncryptionPublicKey, StaticSecret as EncryptionStaticKey}; -#[test] fn setup() { let path = Path::new("db_tests/"); let _ = fs::remove_dir_all(&path); @@ -39,6 +39,7 @@ async fn create_local_node_profile( #[test] fn test_generate_and_use_registration_code_for_specific_profile() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (_, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -85,6 +86,7 @@ fn test_generate_and_use_registration_code_for_specific_profile() { #[test] fn test_generate_and_use_registration_code_for_device() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -165,6 +167,7 @@ fn test_generate_and_use_registration_code_for_device() { #[test] fn test_generate_and_use_registration_code_for_device_with_main_profile() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -241,6 +244,7 @@ fn test_generate_and_use_registration_code_for_device_with_main_profile() { #[test] fn test_generate_and_use_registration_code_no_associated_profile() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -292,6 +296,7 @@ fn test_generate_and_use_registration_code_no_associated_profile() { #[test] fn test_new_load_all_sub_identities() { + init_tracing(); setup(); let node_profile_name = ShinkaiName::new("@@node1.shinkai".to_string()).unwrap(); let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -361,6 +366,7 @@ fn test_new_load_all_sub_identities() { #[test] fn test_update_local_node_keys() { + init_tracing(); setup(); let node_profile_name = ShinkaiName::new("@@node1.shinkai".to_string()).unwrap(); let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -405,6 +411,7 @@ fn test_update_local_node_keys() { #[test] fn test_new_insert_profile() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); @@ -465,6 +472,7 @@ fn test_new_insert_profile() { #[test] fn test_remove_profile() { + init_tracing(); setup(); let node_profile_name = "@@node1.shinkai"; let (identity_sk, identity_pk) = unsafe_deterministic_signature_keypair(0); diff --git a/tests/it/db_inbox_tests.rs b/tests/it/db_inbox_tests.rs index d4f3a2aed..07502f16a 100644 --- a/tests/it/db_inbox_tests.rs +++ b/tests/it/db_inbox_tests.rs @@ -8,6 +8,7 @@ use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{Ident use shinkai_message_primitives::shinkai_utils::encryption::{ unsafe_deterministic_encryption_keypair, EncryptionMethod, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -23,7 +24,6 @@ use std::path::Path; use ed25519_dalek::SigningKey; use x25519_dalek::{PublicKey as EncryptionPublicKey, StaticSecret as EncryptionStaticKey}; -#[test] fn setup() { let path = Path::new("db_tests/"); let _ = fs::remove_dir_all(&path); @@ -73,6 +73,7 @@ fn generate_message_with_text( #[tokio::test] async fn test_insert_messages_with_simple_tree_structure() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; @@ -192,6 +193,7 @@ async fn test_insert_messages_with_simple_tree_structure() { #[tokio::test] async fn test_insert_messages_with_simple_tree_structure_and_root() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; @@ -357,6 +359,7 @@ async fn test_insert_messages_with_simple_tree_structure_and_root() { #[tokio::test] async fn test_insert_messages_with_tree_structure() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; @@ -588,6 +591,7 @@ async fn test_insert_messages_with_tree_structure() { #[tokio::test] async fn db_inbox() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; @@ -936,6 +940,7 @@ async fn db_inbox() { #[test] fn test_permission_errors() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; diff --git a/tests/it/db_job_tests.rs b/tests/it/db_job_tests.rs index abdf25eef..c45056086 100644 --- a/tests/it/db_job_tests.rs +++ b/tests/it/db_job_tests.rs @@ -67,7 +67,7 @@ mod tests { shinkai_message::shinkai_message_schemas::JobMessage, shinkai_utils::{ encryption::unsafe_deterministic_encryption_keypair, job_scope::JobScope, - shinkai_message_builder::ShinkaiMessageBuilder, signatures::unsafe_deterministic_signature_keypair, + shinkai_message_builder::ShinkaiMessageBuilder, signatures::unsafe_deterministic_signature_keypair, shinkai_logging::init_tracing, }, shinkai_utils::{signatures::clone_signature_secret_key, utils::hash_string}, }; @@ -77,6 +77,7 @@ mod tests { #[test] fn test_create_new_job() { + init_tracing(); setup(); let job_id = "job1".to_string(); let agent_id = "agent1".to_string(); @@ -103,6 +104,7 @@ mod tests { #[test] fn test_get_agent_jobs() { + init_tracing(); setup(); let agent_id = "agent2".to_string(); let db_path = format!("db_tests/{}", hash_string(&agent_id.clone())); @@ -135,6 +137,7 @@ mod tests { #[test] fn test_update_job_to_finished() { + init_tracing(); setup(); let job_id = "job3".to_string(); let agent_id = "agent3".to_string(); @@ -158,6 +161,7 @@ mod tests { #[tokio::test] async fn test_update_step_history() { + init_tracing(); setup(); let job_id = "test_job".to_string(); let agent_id = "agent4".to_string(); @@ -210,6 +214,7 @@ mod tests { #[test] fn test_get_non_existent_job() { + init_tracing(); setup(); let job_id = "non_existent_job".to_string(); let agent_id = "agent".to_string(); @@ -227,6 +232,7 @@ mod tests { #[test] fn test_get_agent_jobs_none_exist() { + init_tracing(); setup(); let agent_id = "agent_without_jobs".to_string(); let db_path = format!("db_tests/{}", hash_string(&agent_id.clone())); @@ -249,6 +255,7 @@ mod tests { #[test] fn test_update_non_existent_job() { + init_tracing(); setup(); let job_id = "non_existent_job".to_string(); let agent_id = "agent".to_string(); @@ -266,6 +273,7 @@ mod tests { #[test] fn test_get_agent_jobs_multiple_jobs() { + init_tracing(); setup(); let agent_id = "agent5".to_string(); let db_path = format!("db_tests/{}", hash_string(&agent_id.clone())); @@ -297,6 +305,7 @@ mod tests { #[tokio::test] async fn test_job_inbox_empty() { + init_tracing(); setup(); let job_id = "job_test".to_string(); let agent_id = "agent_test".to_string(); @@ -330,6 +339,7 @@ mod tests { #[tokio::test] async fn test_job_inbox_tree_structure() { + init_tracing(); setup(); let job_id = "job_test".to_string(); let agent_id = "agent_test".to_string(); @@ -422,6 +432,7 @@ mod tests { #[tokio::test] async fn test_job_inbox_tree_structure_with_step_history_and_execution_context() { + init_tracing(); setup(); let job_id = "job_test".to_string(); let agent_id = "agent_test".to_string(); @@ -584,6 +595,7 @@ mod tests { #[tokio::test] async fn test_insert_steps_with_simple_tree_structure() { + init_tracing(); setup(); let node1_identity_name = "@@node1.shinkai"; diff --git a/tests/it/db_tests.rs b/tests/it/db_tests.rs index d602c20cc..106fece2a 100644 --- a/tests/it/db_tests.rs +++ b/tests/it/db_tests.rs @@ -2,6 +2,7 @@ use async_channel::{bounded, Receiver, Sender}; use shinkai_message_primitives::shinkai_message::shinkai_message::ShinkaiMessage; use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::MessageSchemaType; use shinkai_message_primitives::shinkai_utils::encryption::{unsafe_deterministic_encryption_keypair, EncryptionMethod}; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -20,7 +21,6 @@ use tokio::runtime::Runtime; use ed25519_dalek::{VerifyingKey, SigningKey}; use x25519_dalek::{PublicKey as EncryptionPublicKey, StaticSecret as EncryptionStaticKey}; -#[test] fn setup() { let path = Path::new("db_tests/"); let _ = fs::remove_dir_all(&path); @@ -56,6 +56,7 @@ fn generate_message_with_text( #[test] fn test_insert_message_to_all() { + init_tracing(); setup(); // Initialization same as in db_inbox test @@ -142,6 +143,7 @@ fn test_insert_message_to_all() { #[test] fn test_schedule_and_get_due_scheduled_messages() { + init_tracing(); setup(); // Initialization same as in db_inbox test diff --git a/tests/it/encrypted_files_tests.rs b/tests/it/encrypted_files_tests.rs index b877e256d..d5c49df5f 100644 --- a/tests/it/encrypted_files_tests.rs +++ b/tests/it/encrypted_files_tests.rs @@ -17,6 +17,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -45,6 +46,7 @@ use mockito::Server; #[test] fn sandwich_messages_with_files_test() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/get_onchain_identity_tests.rs b/tests/it/get_onchain_identity_tests.rs index 83e499d4a..3180c73de 100644 --- a/tests/it/get_onchain_identity_tests.rs +++ b/tests/it/get_onchain_identity_tests.rs @@ -2,37 +2,42 @@ mod tests { use std::time::Duration; - use ethers::{types::U256}; + use chrono::{DateTime, Utc}; + use ethers::types::U256; + use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_node::crypto_identities::shinkai_registry::{OnchainIdentity, ShinkaiRegistry}; use tokio::{runtime::Runtime, time::sleep}; #[test] fn test_get_identity_record() { + init_tracing(); let rt = Runtime::new().unwrap(); rt.block_on(async { let mut registry = ShinkaiRegistry::new( "https://rpc.sepolia.org", - "0xb2945D0CDa4C119DE184380955aA4FbfAFb6B8cC", + "0x6964241D2458f0Fd300BB37535CF0145380810E0", "./src/crypto_identities/abi/ShinkaiRegistry.sol/ShinkaiRegistry.json", ) .await .unwrap(); - let identity = "nico.shinkai".to_string(); + let identity = "node1_test.shinkai".to_string(); let record = registry.get_identity_record(identity.clone()).await.unwrap(); let expected_record = OnchainIdentity { - bound_nft: U256::from_dec_str("11").unwrap(), - staked_tokens: U256::from_dec_str("62000000000000000000").unwrap(), - encryption_key: "858bef3bb7839329e28e569288f441f8fa86af00d9f41a9845ef50dd3b6cd15f".to_string(), - signature_key: "7aa221ec6761fdfdb478616babad8fad5330587392ad7e7dc9002af269909882".to_string(), + shinkai_identity: "node1_test.shinkai".to_string(), + bound_nft: U256::from_dec_str("29").unwrap(), + staked_tokens: U256::from_dec_str("50000000000000000000").unwrap(), + encryption_key: "60045bdb15c24b161625cf05558078208698272bfe113f792ea740dbd79f4708".to_string(), + signature_key: "69fa099bdce516bfeb46d5fc6e908f6cf8ffac0aba76ca0346a7b1a751a2712e".to_string(), routing: false, - address_or_proxy_nodes: vec![], + address_or_proxy_nodes: vec!["127.0.0.1:8080".to_string()], delegated_tokens: U256::from_dec_str("0").unwrap(), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1705342752)), }; - assert_eq!(record, expected_record); - + assert_eq!(record, expected_record); + let initial_cache_time = registry.get_cache_time(&identity).unwrap(); // Request the identity record again to trigger a cache update diff --git a/tests/it/job_image_analysis_tests.rs b/tests/it/job_image_analysis_tests.rs index 50dba71c1..f4255caa2 100644 --- a/tests/it/job_image_analysis_tests.rs +++ b/tests/it/job_image_analysis_tests.rs @@ -11,6 +11,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::clone_signature_secret_key; use shinkai_node::db::db_cron_task::CronTask; @@ -30,6 +31,7 @@ use mockito::Server; #[test] #[ignore] fn job_image_analysis() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/job_manager_concurrency_tests.rs b/tests/it/job_manager_concurrency_tests.rs index 11c5f2602..cecc7c486 100644 --- a/tests/it/job_manager_concurrency_tests.rs +++ b/tests/it/job_manager_concurrency_tests.rs @@ -4,7 +4,7 @@ use shinkai_message_primitives::schemas::inbox_name::InboxName; use shinkai_message_primitives::shinkai_utils::encryption::{ unsafe_deterministic_encryption_keypair, EncryptionMethod, }; -use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption}; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::{shinkai_log, ShinkaiLogLevel, ShinkaiLogOption, init_tracing}; use shinkai_message_primitives::shinkai_utils::signatures::unsafe_deterministic_signature_keypair; use shinkai_message_primitives::{ schemas::shinkai_name::ShinkaiName, @@ -72,6 +72,7 @@ fn generate_message_with_text( #[tokio::test] async fn test_process_job_queue_concurrency() { + init_tracing(); utils::db_handlers::setup(); let NUM_THREADS = 8; @@ -175,6 +176,7 @@ async fn test_process_job_queue_concurrency() { #[tokio::test] async fn test_sequnetial_process_for_same_job_id() { + init_tracing(); super::utils::db_handlers::setup(); let NUM_THREADS = 8; diff --git a/tests/it/job_multi_page_cron_tests.rs b/tests/it/job_multi_page_cron_tests.rs index eb0070ecd..ce2603401 100644 --- a/tests/it/job_multi_page_cron_tests.rs +++ b/tests/it/job_multi_page_cron_tests.rs @@ -17,6 +17,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -48,6 +49,7 @@ use mockito::Server; #[test] #[ignore] fn job_from_cron_multi_page() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/job_one_page_cron_tests.rs b/tests/it/job_one_page_cron_tests.rs index 63696163b..00b4728a9 100644 --- a/tests/it/job_one_page_cron_tests.rs +++ b/tests/it/job_one_page_cron_tests.rs @@ -14,6 +14,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -36,6 +37,7 @@ use mockito::Server; #[test] #[ignore] fn job_from_cron_one_page() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/job_tree_usage_tests.rs b/tests/it/job_tree_usage_tests.rs index 266a21ea3..353d15f81 100644 --- a/tests/it/job_tree_usage_tests.rs +++ b/tests/it/job_tree_usage_tests.rs @@ -11,6 +11,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::clone_signature_secret_key; use shinkai_node::db::db_cron_task::CronTask; @@ -30,6 +31,7 @@ use mockito::Server; #[test] #[ignore] fn job_tree_usage_tests() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/model_capabilities_manager_tests.rs b/tests/it/model_capabilities_manager_tests.rs index 588c7e229..5413d07c9 100644 --- a/tests/it/model_capabilities_manager_tests.rs +++ b/tests/it/model_capabilities_manager_tests.rs @@ -2,6 +2,7 @@ mod tests { use shinkai_message_primitives::schemas::agents::serialized_agent::{AgentLLMInterface, OpenAI, SerializedAgent}; use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; + use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_node::db::ShinkaiDB; use shinkai_node::managers::model_capabilities_manager::{ ModelCapability, ModelCost, ModelPrivacy, ModelCapabilitiesManager, @@ -20,6 +21,7 @@ mod tests { #[tokio::test] async fn test_has_capability() { + init_tracing(); setup(); let db = Arc::new(Mutex::new(ShinkaiDB::new("db_tests/").unwrap())); @@ -60,6 +62,7 @@ mod tests { #[tokio::test] async fn test_gpt_4_vision_preview_capabilities() { + init_tracing(); setup(); let db = Arc::new(Mutex::new(ShinkaiDB::new("db_tests/").unwrap())); @@ -96,6 +99,7 @@ mod tests { #[tokio::test] async fn test_fake_gpt_model_capabilities() { + init_tracing(); setup(); let db = Arc::new(Mutex::new(ShinkaiDB::new("db_tests/").unwrap())); diff --git a/tests/it/node_integration_tests.rs b/tests/it/node_integration_tests.rs index eb90f03bf..5f2624d4f 100644 --- a/tests/it/node_integration_tests.rs +++ b/tests/it/node_integration_tests.rs @@ -1,5 +1,6 @@ use async_channel::{bounded, Receiver, Sender}; use async_std::println; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use core::panic; use ed25519_dalek::{SigningKey, VerifyingKey}; use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; @@ -41,6 +42,7 @@ fn setup() { #[test] fn subidentity_registration() { + init_tracing(); setup(); let rt = Runtime::new().unwrap(); diff --git a/tests/it/node_retrying_tests.rs b/tests/it/node_retrying_tests.rs index a93e11bc6..55ea69c69 100644 --- a/tests/it/node_retrying_tests.rs +++ b/tests/it/node_retrying_tests.rs @@ -6,6 +6,7 @@ use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{JobMe use shinkai_message_primitives::shinkai_utils::encryption::{ clone_static_secret_key, encryption_public_key_to_string, unsafe_deterministic_encryption_keypair, EncryptionMethod, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -29,6 +30,7 @@ use super::utils::node_test_local::local_registration_profile_node; #[test] fn node_retrying_test() { + init_tracing(); utils::db_handlers::setup(); let rt = Runtime::new().unwrap(); diff --git a/tests/it/node_simple_ux_tests.rs b/tests/it/node_simple_ux_tests.rs index b56d91049..ef81c2eca 100644 --- a/tests/it/node_simple_ux_tests.rs +++ b/tests/it/node_simple_ux_tests.rs @@ -7,6 +7,7 @@ use shinkai_message_primitives::shinkai_message::shinkai_message_schemas::{JobMe use shinkai_message_primitives::shinkai_utils::encryption::{ clone_static_secret_key, unsafe_deterministic_encryption_keypair, EncryptionMethod, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -30,6 +31,7 @@ use super::utils; #[test] fn simple_node_registration_test() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/node_toolkit_api_tests.rs b/tests/it/node_toolkit_api_tests.rs index 80ea314ed..963a534e4 100644 --- a/tests/it/node_toolkit_api_tests.rs +++ b/tests/it/node_toolkit_api_tests.rs @@ -10,6 +10,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -27,6 +28,7 @@ use mockito::Server; #[test] fn node_toolkit_api() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/planner_integration_tests.rs b/tests/it/planner_integration_tests.rs index 5a5aacb8c..4084e53b4 100644 --- a/tests/it/planner_integration_tests.rs +++ b/tests/it/planner_integration_tests.rs @@ -19,6 +19,7 @@ use shinkai_message_primitives::shinkai_utils::file_encryption::{ aes_encryption_key_to_string, aes_nonce_to_hex_string, hash_of_aes_encryption_key_hex, unsafe_deterministic_aes_encryption_key, }; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::{ clone_signature_secret_key, unsafe_deterministic_signature_keypair, @@ -82,6 +83,7 @@ fn create_mock_openai(server: &mut mockito::Server, request_body: &str, response #[test] #[ignore] fn planner_integration_test() { + init_tracing(); run_test_one_node_network(|env| { Box::pin(async move { let node1_commands_sender = env.node1_commands_sender.clone(); diff --git a/tests/it/planner_tests.rs b/tests/it/planner_tests.rs index 6dbcee3d2..7a6e63a5a 100644 --- a/tests/it/planner_tests.rs +++ b/tests/it/planner_tests.rs @@ -6,6 +6,7 @@ mod tests { use pddl_ish_parser::parser::action::Action; use pddl_ish_parser::parser::parameter::Parameter; use pddl_ish_parser::parser::{domain_parser::parse_domain, problem_parser::parse_problem}; + use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use std::{io::Cursor, path::PathBuf}; use std::{pin::Pin, sync::Arc}; use tokio::sync::Mutex; @@ -70,6 +71,7 @@ mod tests { #[test] fn test_ai_news_summary_pddl() { + init_tracing(); let res = parse_domain(DOMAIN_PDDL); match res { Ok((_, domain)) => { @@ -92,6 +94,7 @@ mod tests { #[test] fn test_execute_actions() { + init_tracing(); let res = parse_domain(DOMAIN_PDDL); let mut state = SharedState::default(); match res { diff --git a/tests/it/prompt_tests.rs b/tests/it/prompt_tests.rs index 1ee83b5e0..0a56af4bc 100644 --- a/tests/it/prompt_tests.rs +++ b/tests/it/prompt_tests.rs @@ -5,6 +5,7 @@ mod tests { use super::*; use reqwest::Client; use shinkai_message_primitives::schemas::agents::serialized_agent::{AgentLLMInterface, GenericAPI, OpenAI}; + use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_node::agent::execution::job_prompts::Prompt; use shinkai_node::agent::providers::LLMProvider; use shinkai_node::agent::{ @@ -44,6 +45,7 @@ mod tests { #[tokio::test] async fn test_call_llm_with_prompts_case_a() { + init_tracing(); match setup_vars() { Ok((provider, client, url, api_key)) => { let elements_list: Vec> = @@ -62,6 +64,7 @@ mod tests { #[tokio::test] async fn test_call_llm_with_prompts_case_b() { + init_tracing(); match setup_vars() { Ok((provider, client, url, api_key)) => { let elements_list: Vec = vec![get_zeko_description() /* add more elements here */]; @@ -85,6 +88,7 @@ mod tests { #[tokio::test] async fn test_call_llm_with_simple_prompt() { + init_tracing(); match setup_vars() { Ok((provider, client, url, api_key)) => { let elements_list: Vec = vec![ diff --git a/tests/it/resources_tests.rs b/tests/it/resources_tests.rs index b0b055abb..f30499fbc 100644 --- a/tests/it/resources_tests.rs +++ b/tests/it/resources_tests.rs @@ -1,4 +1,5 @@ use shinkai_message_primitives::schemas::shinkai_name::ShinkaiName; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_node::agent::file_parsing::ParsingHelper; use shinkai_node::db::ShinkaiDB; use shinkai_vector_resources::base_vector_resources::BaseVectorResource; @@ -53,6 +54,7 @@ fn get_shinkai_intro_doc(generator: &RemoteEmbeddingGenerator, data_tags: &Vec Result { #[test] fn test_default_js_toolkit_json_parsing() { + init_tracing(); let toolkit = JSToolkit::from_toolkit_json(&default_toolkit_json(), "").unwrap(); assert_eq!(toolkit.name, "Google Calendar Toolkit"); @@ -56,6 +58,7 @@ fn test_default_js_toolkit_json_parsing() { #[tokio::test] async fn test_js_toolkit_execution() { + init_tracing(); setup(); // Load the toolkit let toolkit_js_code = load_test_js_toolkit_from_file().unwrap(); @@ -88,6 +91,7 @@ async fn test_js_toolkit_execution() { #[tokio::test] async fn test_toolkit_installation_and_retrieval() { + init_tracing(); setup(); // Load the toolkit let toolkit_js_code = load_test_js_toolkit_from_file().unwrap(); @@ -119,6 +123,7 @@ async fn test_toolkit_installation_and_retrieval() { #[tokio::test] async fn test_tool_router_and_toolkit_flow() { + init_tracing(); setup(); let generator = RemoteEmbeddingGenerator::new_default(); diff --git a/tests/it/utils/mocked_shinkai_registry.rs b/tests/it/utils/mocked_shinkai_registry.rs index 18022e995..b6c62c922 100644 --- a/tests/it/utils/mocked_shinkai_registry.rs +++ b/tests/it/utils/mocked_shinkai_registry.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, Utc}; use shinkai_node::crypto_identities::shinkai_registry::ShinkaiRegistryError; use shinkai_node::crypto_identities::shinkai_registry::{OnchainIdentity, ShinkaiRegistryTrait}; use dashmap::DashMap; @@ -15,6 +16,7 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { let identities = vec![ OnchainIdentity { + shinkai_identity: "nico.shinkai".to_string(), bound_nft: U256::from(1), staked_tokens: U256::from(1000), encryption_key: "60045bdb15c24b161625cf05558078208698272bfe113f792ea740dbd79f4708".to_string(), @@ -22,8 +24,10 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { routing: true, address_or_proxy_nodes: vec!["192.168.1.109:8080".to_string()], delegated_tokens: U256::from(500), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1704927408)), }, OnchainIdentity { + shinkai_identity: "nico.shinkai".to_string(), bound_nft: U256::from(2), staked_tokens: U256::from(1000), encryption_key: "912fed05e286af45f44580d6a87da61e1f9a0946237dd29f7bc2d3cbeba0857f".to_string(), @@ -31,8 +35,10 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { routing: true, address_or_proxy_nodes: vec!["192.168.1.233:8081".to_string()], delegated_tokens: U256::from(500), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1704927408)), }, OnchainIdentity { + shinkai_identity: "nico.shinkai".to_string(), bound_nft: U256::from(3), staked_tokens: U256::from(1000), encryption_key: "3273d113e401a215e429e3272352186a7370cf7edf1e2d68aa7ef87a20237371".to_string(), @@ -40,8 +46,10 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { routing: true, address_or_proxy_nodes: vec!["127.0.0.1:8082".to_string()], delegated_tokens: U256::from(500), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1704927408)), }, OnchainIdentity { + shinkai_identity: "nico.shinkai".to_string(), bound_nft: U256::from(4), staked_tokens: U256::from(1000), encryption_key: "60045bdb15c24b161625cf05558078208698272bfe113f792ea740dbd79f4708".to_string(), @@ -49,8 +57,10 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { routing: true, address_or_proxy_nodes: vec!["127.0.0.1:8080".to_string()], delegated_tokens: U256::from(500), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1704927408)), }, OnchainIdentity { + shinkai_identity: "nico.shinkai".to_string(), bound_nft: U256::from(5), staked_tokens: U256::from(1000), encryption_key: "912fed05e286af45f44580d6a87da61e1f9a0946237dd29f7bc2d3cbeba0857f".to_string(), @@ -58,6 +68,7 @@ impl ShinkaiRegistryTrait for MockedShinkaiRegistry { routing: true, address_or_proxy_nodes: vec!["127.0.0.1:8081".to_string()], delegated_tokens: U256::from(500), + last_updated: DateTime::::from(std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1704927408)), }, ]; diff --git a/tests/it/web_scraper_tests.rs b/tests/it/web_scraper_tests.rs index e0e8bc1a6..1ee133efe 100644 --- a/tests/it/web_scraper_tests.rs +++ b/tests/it/web_scraper_tests.rs @@ -7,7 +7,7 @@ mod tests { use mockito::Server; use shinkai_message_primitives::{ schemas::shinkai_name::ShinkaiName, - shinkai_utils::signatures::{clone_signature_secret_key, unsafe_deterministic_signature_keypair}, + shinkai_utils::{signatures::{clone_signature_secret_key, unsafe_deterministic_signature_keypair}, shinkai_logging::init_tracing}, }; use shinkai_node::{ agent::job_manager::JobManager, @@ -22,7 +22,6 @@ mod tests { use tokio::sync::Mutex; use x25519_dalek::{PublicKey as EncryptionPublicKey, StaticSecret as EncryptionStaticKey}; - #[test] fn setup() { let path = Path::new("db_tests/"); let _ = fs::remove_dir_all(&path); @@ -30,6 +29,7 @@ mod tests { #[test] fn test_extract_links() { + init_tracing(); let links = WebScraper::extract_links(&get_unstructured_response()); assert_eq!(links.len(), 30); } @@ -37,6 +37,7 @@ mod tests { #[tokio::test] #[ignore] async fn test_web_scraper() { + init_tracing(); setup(); let db = Arc::new(Mutex::new(ShinkaiDB::new("db_tests/").unwrap())); let (identity_secret_key, _) = unsafe_deterministic_signature_keypair(0); @@ -109,7 +110,6 @@ mod tests { .await; // let result = scraper.download_and_parse().await; - eprintln!("result: {:?}", result); assert!(result.is_ok()); } diff --git a/tests/it/websocket_tests.rs b/tests/it/websocket_tests.rs index 667ae5b22..5595152a8 100644 --- a/tests/it/websocket_tests.rs +++ b/tests/it/websocket_tests.rs @@ -19,6 +19,7 @@ use shinkai_message_primitives::shinkai_utils::encryption::EncryptionMethod; use shinkai_message_primitives::shinkai_utils::file_encryption::aes_encryption_key_to_string; use shinkai_message_primitives::shinkai_utils::file_encryption::unsafe_deterministic_aes_encryption_key; use shinkai_message_primitives::shinkai_utils::job_scope::JobScope; +use shinkai_message_primitives::shinkai_utils::shinkai_logging::init_tracing; use shinkai_message_primitives::shinkai_utils::shinkai_message_builder::ShinkaiMessageBuilder; use shinkai_message_primitives::shinkai_utils::signatures::unsafe_deterministic_signature_keypair; use shinkai_message_primitives::shinkai_utils::utils::hash_string; @@ -70,7 +71,6 @@ impl MockIdentityManager { #[async_trait] impl IdentityManagerTrait for MockIdentityManager { fn find_by_identity_name(&self, _full_profile_name: ShinkaiName) -> Option<&Identity> { - eprintln!("find_by_identity_name: {}", _full_profile_name); if _full_profile_name.to_string() == "@@node1.shinkai/main_profile_node1" { Some(&self.dummy_standard_identity) } else { @@ -79,7 +79,6 @@ impl IdentityManagerTrait for MockIdentityManager { } async fn search_identity(&self, _full_identity_name: &str) -> Option { - eprintln!("search_identity: {}", _full_identity_name); if _full_identity_name == "@@node1.shinkai/main_profile_node1" { Some(self.dummy_standard_identity.clone()) } else { @@ -151,6 +150,7 @@ fn setup() { #[tokio::test] async fn test_websocket() { + init_tracing(); // Setup setup(); let job_id1 = "test_job".to_string(); @@ -449,112 +449,192 @@ async fn test_websocket() { .expect("Failed to send close message"); } -// Note(Nico): I'm rethinking if we actually need this or we if we can do everything that we need -// by just using message updates - -// #[tokio::test] -// async fn test_websocket_smart_inbox() { -// // Setup -// setup(); - -// let agent_id = "agent4".to_string(); -// let db_path = format!("db_tests/{}", hash_string(&agent_id.clone())); -// let shinkai_db = ShinkaiDB::new(&db_path).unwrap(); -// let shinkai_db = Arc::new(Mutex::new(shinkai_db)); - -// let node1_identity_name = "@@node1.shinkai"; -// let node1_subidentity_name = "main_profile_node1"; -// let (node1_identity_sk, _) = unsafe_deterministic_signature_keypair(0); -// let (node1_encryption_sk, node1_encryption_pk) = unsafe_deterministic_encryption_keypair(0); - -// let node_name = ShinkaiName::new(node1_identity_name.to_string()).unwrap(); -// let identity_manager_trait = Arc::new(Mutex::new( -// Box::new(MockIdentityManager::new()) as Box -// )); - -// // Start the WebSocket server -// let manager = WebSocketManager::new(shinkai_db.clone(), node_name, identity_manager_trait.clone()).await; -// let ws_address = "127.0.0.1:8080".parse().expect("Failed to parse WebSocket address"); -// tokio::spawn(run_ws_api(ws_address, Arc::clone(&manager))); - -// // Update ShinkaiDB with manager so it can trigger updates -// { -// let mut shinkai_db = shinkai_db.lock().await; -// shinkai_db.set_ws_manager(Arc::clone(&manager) as Arc>); -// } - -// // Give the server a little time to start -// tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - -// // Connect to the server -// let connection_result = tokio_tungstenite::connect_async("ws://127.0.0.1:8080/ws").await; - -// // Check if the connection was successful -// assert!(connection_result.is_ok(), "Failed to connect"); - -// let (mut ws_stream, _) = connection_result.expect("Failed to connect"); - -// // Create a shared encryption key Aes256Gcm -// let symmetrical_sk = unsafe_deterministic_aes_encryption_key(0); -// let shared_enc_string = aes_encryption_key_to_string(symmetrical_sk); - -// // Send a message to the server to establish the connection and subscribe to a topic -// let ws_message = WSMessage { -// subscriptions: vec![TopicSubscription { -// topic: WSTopic::SmartInboxes, -// subtopic: None, -// }], -// unsubscriptions: vec![], -// shared_key: Some(shared_enc_string.to_string()), -// }; - -// // Serialize WSMessage to a JSON string -// let ws_message_json = serde_json::to_string(&ws_message).unwrap(); - -// // Generate a ShinkaiMessage -// let shinkai_message = generate_message_with_text( -// ws_message_json, -// "".to_string(), -// node1_encryption_sk.clone(), -// node1_identity_sk.clone(), -// node1_encryption_pk, -// node1_subidentity_name.to_string(), -// node1_identity_name.to_string(), -// "2023-07-02T20:53:34.810Z".to_string(), -// ); - -// // Convert ShinkaiMessage to String -// let message_string = shinkai_message.to_string().unwrap(); - -// ws_stream -// .send(tungstenite::Message::Text(message_string)) -// .await -// .expect("Failed to send message"); - -// // Wait for the server to process the subscription message -// tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; - -// // Send a new message to inbox_name1_string -// { -// let mut shinkai_db = shinkai_db.lock().await; -// let _ = shinkai_db.create_empty_inbox("test_inbox".to_string()).await; -// } - -// // Check the response -// let msg = ws_stream -// .next() -// .await -// .expect("Failed to read message") -// .expect("Failed to read message"); - -// let encrypted_message = msg.to_text().unwrap(); -// let decrypted_message = decrypt_message(encrypted_message, &shared_enc_string).expect("Failed to decrypt message"); - -// assert_eq!(decrypted_message, "test_inbox"); - -// // Send a close message -// ws_stream -// .send(tungstenite::Message::Close(None)) -// .await -// .expect("Failed to send close message"); -// } +// TODO(Nico): if you subscribe to smart_inbox you will receive messages of all the inboxes that you have access to +#[tokio::test] +async fn test_websocket_smart_inbox() { + init_tracing(); + // Setup + setup(); + + let job_id1 = "test_job".to_string(); + let no_access_job_id = "no_access_job_id".to_string(); + let agent_id = "agent4".to_string(); + let db_path = format!("db_tests/{}", hash_string(&agent_id.clone())); + let shinkai_db = ShinkaiDB::new(&db_path).unwrap(); + let shinkai_db = Arc::new(Mutex::new(shinkai_db)); + + let node1_identity_name = "@@node1.shinkai"; + let node1_subidentity_name = "main_profile_node1"; + let (node1_identity_sk, _) = unsafe_deterministic_signature_keypair(0); + let (node1_encryption_sk, node1_encryption_pk) = unsafe_deterministic_encryption_keypair(0); + + let node_name = ShinkaiName::new(node1_identity_name.to_string()).unwrap(); + let identity_manager_trait = Arc::new(Mutex::new( + Box::new(MockIdentityManager::new()) as Box + )); + + let inbox_name1 = InboxName::get_job_inbox_name_from_params(job_id1.to_string()).unwrap(); + let inbox_name1_string = match inbox_name1 { + InboxName::RegularInbox { value, .. } | InboxName::JobInbox { value, .. } => value.clone(), + }; + + let no_access_job_id_name = InboxName::get_job_inbox_name_from_params(no_access_job_id.to_string()).unwrap(); + let no_access_job_id_name_string = match no_access_job_id_name { + InboxName::RegularInbox { value, .. } | InboxName::JobInbox { value, .. } => value.clone(), + }; + + // Start the WebSocket server + let manager = WebSocketManager::new(shinkai_db.clone(), node_name, identity_manager_trait.clone()).await; + let ws_address = "127.0.0.1:8080".parse().expect("Failed to parse WebSocket address"); + tokio::spawn(run_ws_api(ws_address, Arc::clone(&manager))); + + // Update ShinkaiDB with manager so it can trigger updates + { + let mut shinkai_db = shinkai_db.lock().await; + shinkai_db.set_ws_manager(Arc::clone(&manager) as Arc>); + } + + // Give the server a little time to start + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + + // Connect to the server + let connection_result = tokio_tungstenite::connect_async("ws://127.0.0.1:8080/ws").await; + + // Check if the connection was successful + assert!(connection_result.is_ok(), "Failed to connect"); + + let (mut ws_stream, _) = connection_result.expect("Failed to connect"); + + // Create a shared encryption key Aes256Gcm + let symmetrical_sk = unsafe_deterministic_aes_encryption_key(0); + let shared_enc_string = aes_encryption_key_to_string(symmetrical_sk); + + // Send a message to the server to establish the connection and subscribe to a topic + let ws_message = WSMessage { + subscriptions: vec![TopicSubscription { + topic: WSTopic::SmartInboxes, + subtopic: None, + }], + unsubscriptions: vec![], + shared_key: Some(shared_enc_string.to_string()), + }; + + // Serialize WSMessage to a JSON string + let ws_message_json = serde_json::to_string(&ws_message).unwrap(); + + // Generate a ShinkaiMessage + let shinkai_message = generate_message_with_text( + ws_message_json, + "".to_string(), + node1_encryption_sk.clone(), + node1_identity_sk.clone(), + node1_encryption_pk, + node1_subidentity_name.to_string(), + node1_identity_name.to_string(), + "2023-07-02T20:53:34.810Z".to_string(), + ); + + { + // Add identity to the database + let sender_subidentity = { + let shinkai_name = + ShinkaiName::from_node_and_profile(node1_identity_name.to_string(), node1_subidentity_name.to_string()) + .unwrap(); + let identity_manager_lock = identity_manager_trait.lock().await; + match identity_manager_lock.find_by_identity_name(shinkai_name).unwrap() { + Identity::Standard(std_identity) => std_identity.clone(), + _ => panic!("Identity is not of type StandardIdentity"), + } + }; + + let mut shinkai_db = shinkai_db.lock().await; + let _ = shinkai_db.insert_profile(sender_subidentity.clone()); + let scope = JobScope::new_default(); + match shinkai_db.create_new_job(job_id1, agent_id.clone(), scope.clone()) { + Ok(_) => (), + Err(e) => panic!("Failed to create a new job: {}", e), + } + shinkai_db + .add_permission(&inbox_name1_string, &sender_subidentity, InboxPermission::Admin) + .unwrap(); + + match shinkai_db.create_new_job(no_access_job_id, agent_id, scope) { + Ok(_) => (), + Err(e) => panic!("Failed to create a new job: {}", e), + } + } + + // Convert ShinkaiMessage to String + let message_string = shinkai_message.to_string().unwrap(); + + ws_stream + .send(tungstenite::Message::Text(message_string)) + .await + .expect("Failed to send message"); + + // Wait for the server to process the subscription message + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + + // Send a new message to inbox_name1_string + { + // Generate a ShinkaiMessage + let shinkai_message = generate_message_with_text( + "Hello, world!".to_string(), + inbox_name1_string.to_string(), + node1_encryption_sk.clone(), + node1_identity_sk.clone(), + node1_encryption_pk, + node1_subidentity_name.to_string(), + node1_identity_name.to_string(), + "2023-07-02T20:53:34.810Z".to_string(), + ); + + let mut shinkai_db = shinkai_db.lock().await; + let _ = shinkai_db + .unsafe_insert_inbox_message(&&shinkai_message.clone(), None) + .await; + } + + // Check the response + let msg = ws_stream + .next() + .await + .expect("Failed to read message") + .expect("Failed to read message"); + + let encrypted_message = msg.to_text().unwrap(); + let decrypted_message = decrypt_message(encrypted_message, &shared_enc_string).expect("Failed to decrypt message"); + let recovered_shinkai = ShinkaiMessage::from_string(decrypted_message).unwrap(); + let recovered_content = recovered_shinkai.get_message_content().unwrap(); + assert_eq!(recovered_content, "Hello, world!"); + + // Send a message to an inbox that the user DOES NOT have access. the user shouldn't receive a notification + { + let shinkai_message = generate_message_with_text( + "Hello, no one!".to_string(), + no_access_job_id_name_string.to_string(), + node1_encryption_sk.clone(), + node1_identity_sk.clone(), + node1_encryption_pk, + node1_subidentity_name.to_string(), + node1_identity_name.to_string(), + "2023-07-02T20:53:34.810Z".to_string(), + ); + + let mut shinkai_db = shinkai_db.lock().await; + let _ = shinkai_db + .unsafe_insert_inbox_message(&&shinkai_message.clone(), None) + .await; + } + + // Check that no message is received + let result = tokio::time::timeout(tokio::time::Duration::from_secs(1), ws_stream.next()).await; + eprintln!("result: {:?}", result); + assert!(result.is_err()); + + // Send a close message + ws_stream + .send(tungstenite::Message::Close(None)) + .await + .expect("Failed to send close message"); +}