From c591637923ccd0d385a1c7be00eaf52694de1e55 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Mon, 12 Feb 2024 11:03:08 +0200 Subject: [PATCH 01/39] add solar_cli as workspace member and create whoami method with example --- Cargo.lock | 267 ++++++++++++++++++++++++++++++-- Cargo.toml | 2 + solar_client/Cargo.toml | 12 ++ solar_client/examples/whoami.rs | 15 ++ solar_client/src/lib.rs | 21 +++ 5 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 solar_client/Cargo.toml create mode 100644 solar_client/examples/whoami.rs create mode 100644 solar_client/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 932052b..188f2f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.20" @@ -71,9 +86,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "async-attributes" @@ -151,7 +166,7 @@ dependencies = [ "polling", "rustix", "slab", - "socket2", + "socket2 0.4.9", "waker-fn", ] @@ -260,6 +275,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.11.0" @@ -272,6 +302,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "beef" version = "0.5.2" @@ -429,6 +465,22 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "cpufeatures" version = "0.2.7" @@ -529,6 +581,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "env_logger" version = "0.10.0" @@ -771,6 +832,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "globset" version = "0.4.10" @@ -920,6 +987,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -966,6 +1034,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.7" @@ -993,6 +1067,30 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc_client" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c1ec33c537dc1d5a8b597313db6d213fee54320f81ea0d19b0c3869b282e1a" +dependencies = [ + "async-trait", + "jsonrpc_client_macro", + "reqwest", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "jsonrpc_client_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c11e429f0eaa41fe659013680b459d2368d8f0a3e69dccfb7a35800b0dc27b" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "jsonrpsee" version = "0.18.2" @@ -1118,9 +1216,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libsodium-sys" @@ -1174,11 +1272,26 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -1207,6 +1320,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.2" @@ -1281,9 +1403,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1321,9 +1443,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1450,6 +1572,48 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "reqwest" +version = "0.11.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -1542,6 +1706,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -1626,6 +1802,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "soketto" version = "0.7.1" @@ -1685,6 +1871,16 @@ dependencies = [ "url", ] +[[package]] +name = "solar_client" +version = "0.1.0" +dependencies = [ + "anyhow", + "jsonrpc_client", + "reqwest", + "tokio", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1719,6 +1915,33 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -1775,26 +1998,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", @@ -2265,6 +2488,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + [[package]] name = "xdg" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 12ff259..7f2d11d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,4 +2,6 @@ members = [ "solar", "solar_cli", + "solar_client", ] +resolver = "2" diff --git a/solar_client/Cargo.toml b/solar_client/Cargo.toml new file mode 100644 index 0000000..1d468a0 --- /dev/null +++ b/solar_client/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "solar_client" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.79" +jsonrpc_client = { version = "0.7.1", features = ["macros", "reqwest"] } +reqwest = { version = "0.11", default-features = false, features = [ "json" ] } + +[dev-dependencies] +tokio = { version = "1.36.0", features = [ "macros", "rt-multi-thread" ] } diff --git a/solar_client/examples/whoami.rs b/solar_client/examples/whoami.rs new file mode 100644 index 0000000..6e9b9b5 --- /dev/null +++ b/solar_client/examples/whoami.rs @@ -0,0 +1,15 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned()); + + let whoami = client.whoami().await?; + println!("{}", whoami); + // @qK93G/R9R5J2fiqK+kxV72HqqPUcss+rth8rACcYr4s=.ed25519 + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs new file mode 100644 index 0000000..20b5743 --- /dev/null +++ b/solar_client/src/lib.rs @@ -0,0 +1,21 @@ +use anyhow::Result; + +#[jsonrpc_client::api] +pub trait SolarClient { + async fn whoami(&self) -> String; +} + +#[jsonrpc_client::implement(SolarClient)] +pub struct Client { + inner: reqwest::Client, + base_url: reqwest::Url, +} + +impl Client { + pub fn new(base_url: String) -> Result { + Ok(Self { + inner: reqwest::Client::new(), + base_url: base_url.parse()?, + }) + } +} From b46b429bb9388eabd305a0a27e6a13f997ee7dd4 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Mon, 12 Feb 2024 11:16:03 +0200 Subject: [PATCH 02/39] handle result --- solar_client/examples/whoami.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solar_client/examples/whoami.rs b/solar_client/examples/whoami.rs index 6e9b9b5..ef01bea 100644 --- a/solar_client/examples/whoami.rs +++ b/solar_client/examples/whoami.rs @@ -5,7 +5,7 @@ const SERVER_ADDR: &str = "http://127.0.0.1:3030"; #[tokio::main] async fn main() -> Result<()> { - let client = Client::new(SERVER_ADDR.to_owned()); + let client = Client::new(SERVER_ADDR.to_owned())?; let whoami = client.whoami().await?; println!("{}", whoami); From 1ff136177d2d5244ff80ba1f435d6e04c7ea50d8 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Mon, 12 Feb 2024 11:16:23 +0200 Subject: [PATCH 03/39] add ping and example --- solar_client/examples/ping.rs | 15 +++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 solar_client/examples/ping.rs diff --git a/solar_client/examples/ping.rs b/solar_client/examples/ping.rs new file mode 100644 index 0000000..216e4d1 --- /dev/null +++ b/solar_client/examples/ping.rs @@ -0,0 +1,15 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let ping = client.ping().await?; + println!("{}", ping); + // pong! + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 20b5743..880c630 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -2,6 +2,8 @@ use anyhow::Result; #[jsonrpc_client::api] pub trait SolarClient { + async fn ping(&self) -> String; + async fn whoami(&self) -> String; } From 28cd2f83bbb6bba73a1d4b5f1292a2673b15e18c Mon Sep 17 00:00:00 2001 From: mycognosist Date: Mon, 12 Feb 2024 14:00:58 +0200 Subject: [PATCH 04/39] add blocks and example --- solar_client/examples/blocks.rs | 21 +++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 solar_client/examples/blocks.rs diff --git a/solar_client/examples/blocks.rs b/solar_client/examples/blocks.rs new file mode 100644 index 0000000..c645b1e --- /dev/null +++ b/solar_client/examples/blocks.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let blocks = client.blocks(PUB_KEY).await?; + println!("{:#?}", blocks); + // [ + // "@dW5ch5miTnxLJDVDtB4ZCvrVxh+S8kGCQIBbd5paLhw=.ed25519", + // "@QIlKZ8DMw9XpjpRZ96RBLpfkLnOUZSqamC6WMddGh3I=.ed25519", + // ... + // "@+rMXLy1md42gvbBq+6l6rp95/drh6QyACO1ZZMMnWI0=.ed25519", + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 880c630..d4227a5 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -2,6 +2,8 @@ use anyhow::Result; #[jsonrpc_client::api] pub trait SolarClient { + async fn blocks(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From cc76af868f9be4d1a9de592a28d122010176d0e8 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:36:50 +0200 Subject: [PATCH 05/39] add blockers --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index d4227a5..2c56571 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -4,6 +4,8 @@ use anyhow::Result; pub trait SolarClient { async fn blocks(&self, pub_key: &str) -> Vec; + async fn blockers(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 5692920899aa55498fb40fd29c197b5fe52d2451 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:44:28 +0200 Subject: [PATCH 06/39] correct the api docs for description --- solar/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solar/README.md b/solar/README.md index f89d409..96f9288 100644 --- a/solar/README.md +++ b/solar/README.md @@ -69,7 +69,7 @@ While running, a solar node can be queried using JSON-RPC over HTTP. | --- | --- | --- | --- | | `blocks` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | | `blockers` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `descriptions` | `"<@...=.ed25519>"` | `[]` | Returns an array of descriptions | +| `descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples containing a public key and description | | `self_descriptions` | `"<@...=.ed25519>"` | `[]` | Returns an array of descriptions | | `latest_description` | `"<@...=.ed25519>"` | `` | Returns a single description | | `latest_self_description` | `"<@...=.ed25519>"` | `` | Returns a single description | From e90cee029695a90021b6673c905ac69490f2e5b5 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:44:42 +0200 Subject: [PATCH 07/39] add descriptions and example --- solar_client/examples/descriptions.rs | 21 +++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 solar_client/examples/descriptions.rs diff --git a/solar_client/examples/descriptions.rs b/solar_client/examples/descriptions.rs new file mode 100644 index 0000000..3119bed --- /dev/null +++ b/solar_client/examples/descriptions.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let descriptions = client.descriptions(PUB_KEY).await?; + println!("{:#?}", descriptions); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "[ sowing seeds of symbiosis | weaving webs of wu wei ]", + // ) + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 2c56571..fc2a54b 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -6,6 +6,8 @@ pub trait SolarClient { async fn blockers(&self, pub_key: &str) -> Vec; + async fn descriptions(&self, pub_key: &str) -> Vec<(String, String)>; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 206c878984317cb2f9e1740a488dd2bcf67d3d8d Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:47:40 +0200 Subject: [PATCH 08/39] add self_descriptions --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index fc2a54b..43960ee 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -8,6 +8,8 @@ pub trait SolarClient { async fn descriptions(&self, pub_key: &str) -> Vec<(String, String)>; + async fn self_descriptions(&self, pub_key: &str) -> Vec<(String, String)>; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 1a41a32577ba22faf9461bb3e8a73bb531d5cb7b Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:49:09 +0200 Subject: [PATCH 09/39] correct the api docs for self_description --- solar/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solar/README.md b/solar/README.md index 96f9288..da6b069 100644 --- a/solar/README.md +++ b/solar/README.md @@ -69,8 +69,8 @@ While running, a solar node can be queried using JSON-RPC over HTTP. | --- | --- | --- | --- | | `blocks` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | | `blockers` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples containing a public key and description | -| `self_descriptions` | `"<@...=.ed25519>"` | `[]` | Returns an array of descriptions | +| `descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and description | +| `self_descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and description | | `latest_description` | `"<@...=.ed25519>"` | `` | Returns a single description | | `latest_self_description` | `"<@...=.ed25519>"` | `` | Returns a single description | | `feed` | `"<@...=.ed25519>"` | `[{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }]` | Returns an array of message KVTs (key, value, timestamp) from the local database | From 903891c079606b8f06fac1ba8559f0be42f62b23 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 08:56:54 +0200 Subject: [PATCH 10/39] return only the description for latest_description --- solar/src/storage/indexes.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/solar/src/storage/indexes.rs b/solar/src/storage/indexes.rs index 4cd45a9..8f374be 100644 --- a/solar/src/storage/indexes.rs +++ b/solar/src/storage/indexes.rs @@ -307,9 +307,12 @@ impl Indexes { } /// Return the most recently indexed description for the given public key. - pub fn get_latest_description(&self, ssb_id: &str) -> Result> { + pub fn get_latest_description(&self, ssb_id: &str) -> Result> { let descriptions = self.get_descriptions(ssb_id)?; - let description = descriptions.last().cloned(); + let description = descriptions + .last() + .map(|(_ssb_id, description)| description) + .cloned(); Ok(description) } From b05997b8af825e687190f348016c93ec1356e9ec Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:17:54 +0200 Subject: [PATCH 11/39] return only the descriptions for self_descriptions --- solar/src/storage/indexes.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/solar/src/storage/indexes.rs b/solar/src/storage/indexes.rs index 8f374be..92feec0 100644 --- a/solar/src/storage/indexes.rs +++ b/solar/src/storage/indexes.rs @@ -299,17 +299,21 @@ impl Indexes { } /// Return all indexed self-assigned descriptions for the given public key. - pub fn get_self_assigned_descriptions(&self, ssb_id: &str) -> Result> { - let mut descriptions = self.get_descriptions(ssb_id)?; - descriptions.retain(|(author, _description)| author == ssb_id); + pub fn get_self_assigned_descriptions(&self, ssb_id: &str) -> Result> { + let descriptions = self + .get_descriptions(ssb_id)? + .into_iter() + .filter(|(author, _description)| author == ssb_id) + .map(|(_ssb_id, description)| description) + .collect(); Ok(descriptions) } /// Return the most recently indexed description for the given public key. pub fn get_latest_description(&self, ssb_id: &str) -> Result> { - let descriptions = self.get_descriptions(ssb_id)?; - let description = descriptions + let description = self + .get_descriptions(ssb_id)? .last() .map(|(_ssb_id, description)| description) .cloned(); @@ -319,10 +323,7 @@ impl Indexes { /// Return the most recently indexed self-assigned description for the given /// public key. - pub fn get_latest_self_assigned_description( - &self, - ssb_id: &str, - ) -> Result> { + pub fn get_latest_self_assigned_description(&self, ssb_id: &str) -> Result> { let self_descriptions = self.get_self_assigned_descriptions(ssb_id)?; let description = self_descriptions.last().cloned(); From a6fde212f288264cdfa1b34b664cb34a4742054d Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:25:01 +0200 Subject: [PATCH 12/39] add latest_description and example, fix self_descriptions return type --- solar_client/examples/latest_description.rs | 16 ++++++++++++++++ solar_client/examples/self_descriptions.rs | 21 +++++++++++++++++++++ solar_client/src/lib.rs | 4 +++- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 solar_client/examples/latest_description.rs create mode 100644 solar_client/examples/self_descriptions.rs diff --git a/solar_client/examples/latest_description.rs b/solar_client/examples/latest_description.rs new file mode 100644 index 0000000..e5b6c6a --- /dev/null +++ b/solar_client/examples/latest_description.rs @@ -0,0 +1,16 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let latest_description = client.latest_description(PUB_KEY).await?; + println!("{:#?}", latest_description); + // "[ sowing seeds of symbiosis | weaving webs of wu wei ]" + + Ok(()) +} diff --git a/solar_client/examples/self_descriptions.rs b/solar_client/examples/self_descriptions.rs new file mode 100644 index 0000000..a236427 --- /dev/null +++ b/solar_client/examples/self_descriptions.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let self_descriptions = client.self_descriptions(PUB_KEY).await?; + println!("{:#?}", self_descriptions); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "[ sowing seeds of symbiosis | weaving webs of wu wei ]", + // ) + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 43960ee..3044910 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -8,7 +8,9 @@ pub trait SolarClient { async fn descriptions(&self, pub_key: &str) -> Vec<(String, String)>; - async fn self_descriptions(&self, pub_key: &str) -> Vec<(String, String)>; + async fn self_descriptions(&self, pub_key: &str) -> Vec; + + async fn latest_description(&self, pub_key: &str) -> String; async fn ping(&self) -> String; From f90adbf1a4e2a51467d38610b13976c02d44d9e9 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:26:26 +0200 Subject: [PATCH 13/39] add latest_self_description and example --- solar_client/examples/latest_self_description.rs | 16 ++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 solar_client/examples/latest_self_description.rs diff --git a/solar_client/examples/latest_self_description.rs b/solar_client/examples/latest_self_description.rs new file mode 100644 index 0000000..66202d3 --- /dev/null +++ b/solar_client/examples/latest_self_description.rs @@ -0,0 +1,16 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let latest_self_description = client.latest_self_description(PUB_KEY).await?; + println!("{:#?}", latest_self_description); + // "[ sowing seeds of symbiosis | weaving webs of wu wei ]" + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 3044910..780aa72 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -12,6 +12,8 @@ pub trait SolarClient { async fn latest_description(&self, pub_key: &str) -> String; + async fn latest_self_description(&self, pub_key: &str) -> String; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From e984e1ec0739272f7b38a3c532e8dd436d4c5f4a Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:39:28 +0200 Subject: [PATCH 14/39] add feed and example --- solar_client/examples/feed.rs | 21 +++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 solar_client/examples/feed.rs diff --git a/solar_client/examples/feed.rs b/solar_client/examples/feed.rs new file mode 100644 index 0000000..5f524b0 --- /dev/null +++ b/solar_client/examples/feed.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let feed = client.feed(PUB_KEY).await?; + println!("{:#?}", feed); + // [ + // "@dW5ch5miTnxLJDVDtB4ZCvrVxh+S8kGCQIBbd5paLhw=.ed25519", + // "@QIlKZ8DMw9XpjpRZ96RBLpfkLnOUZSqamC6WMddGh3I=.ed25519", + // ... + // "@+rMXLy1md42gvbBq+6l6rp95/drh6QyACO1ZZMMnWI0=.ed25519", + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 780aa72..4e29083 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -14,6 +14,8 @@ pub trait SolarClient { async fn latest_self_description(&self, pub_key: &str) -> String; + async fn feed(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 4b19e30ede8629234b67e838a058096ca2f0a030 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:41:45 +0200 Subject: [PATCH 15/39] add follows and example --- solar_client/examples/follows.rs | 21 +++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 solar_client/examples/follows.rs diff --git a/solar_client/examples/follows.rs b/solar_client/examples/follows.rs new file mode 100644 index 0000000..31a744b --- /dev/null +++ b/solar_client/examples/follows.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let follows = client.follows(PUB_KEY).await?; + println!("{:#?}", follows); + // [ + // "@XeP2o+FcSdb5YdTvt/nuYPU2PHJSSwRt+X2y8B2dK5U=.ed25519", + // "@2il4IGrTUzMyInSjCyv6vx6tftELOCxh/FdUuzvj7tE=.ed25519", + // ... + // "@OKRij/n7Uu42A0Z75ty0JI0cZxcieD2NyjXrRdYKNOQ=.ed25519", + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 4e29083..dc78121 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -16,6 +16,8 @@ pub trait SolarClient { async fn feed(&self, pub_key: &str) -> Vec; + async fn follows(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From c0ad688573361c2a566e385a520c7fab338855d1 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:42:07 +0200 Subject: [PATCH 16/39] add followers --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index dc78121..8aa76b7 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -18,6 +18,8 @@ pub trait SolarClient { async fn follows(&self, pub_key: &str) -> Vec; + async fn followers(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 713fb013fe2cc31c85b438f4fb603cef9266b675 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:44:19 +0200 Subject: [PATCH 17/39] add is_following and an example --- solar_client/examples/is_following.rs | 17 +++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 19 insertions(+) create mode 100644 solar_client/examples/is_following.rs diff --git a/solar_client/examples/is_following.rs b/solar_client/examples/is_following.rs new file mode 100644 index 0000000..062dc0e --- /dev/null +++ b/solar_client/examples/is_following.rs @@ -0,0 +1,17 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PEER_A: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; +const PEER_B: &str = "@2il4IGrTUzMyInSjCyv6vx6tftELOCxh/FdUuzvj7tE=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let is_following = client.is_following(PEER_A, PEER_B).await?; + println!("{}", is_following); + // true + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 8aa76b7..ca752a7 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -20,6 +20,8 @@ pub trait SolarClient { async fn followers(&self, pub_key: &str) -> Vec; + async fn is_following(&self, peer_a: &str, peer_b: &str) -> bool; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 99523df298a1775fd066c8b5f07dbc34d6f39640 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:44:50 +0200 Subject: [PATCH 18/39] add friends --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index ca752a7..45bf642 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -22,6 +22,8 @@ pub trait SolarClient { async fn is_following(&self, peer_a: &str, peer_b: &str) -> bool; + async fn friends(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 582b2fb66695810d2dd6e6d42efb4abc0a6df0c3 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:57:33 +0200 Subject: [PATCH 19/39] update the return types for descriptions and images --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 43725ee..864558e 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ While running, a solar node can be queried using JSON-RPC over HTTP. | --- | --- | --- | --- | | `blocks` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | | `blockers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of descriptions | +| `descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and a description | | `self_descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of descriptions | | `latest_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | | `latest_self_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | @@ -143,7 +143,7 @@ While running, a solar node can be queried using JSON-RPC over HTTP. | `followers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | | `is_following` | `{ "peer_a": "<@...=.ed25519>", "peer_b": "<@...=.ed25519>" }` | `` | Returns a boolean | | `friends` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `images` | `{ "pub_key": "<@...=.ed25519>" }` | `[<&...=.sha256>]` | Returns an array of image references | +| `images` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, <&...=.sha256>)]` | Returns an array of tuples, each containing a public key and an image reference | | `self_images` | `{ "pub_key": "<@...=.ed25519>" }` | `[<&...=.sha256>]` | Returns an array of image references | | `latest_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | | `latest_self_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | From 9186ba4c9c979774f06d16dbab2bfc81b8542ee4 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 09:57:43 +0200 Subject: [PATCH 20/39] add images and example --- solar_client/examples/images.rs | 22 ++++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 solar_client/examples/images.rs diff --git a/solar_client/examples/images.rs b/solar_client/examples/images.rs new file mode 100644 index 0000000..0f8a646 --- /dev/null +++ b/solar_client/examples/images.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let images = client.images(PUB_KEY).await?; + println!("{:#?}", images); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "&dmLPhR0npN7tHiICGfM1WLBMHhhzh5I5VR3rEKvmOXw=.sha256", + // ), + // ... + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 45bf642..96126c6 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -24,6 +24,8 @@ pub trait SolarClient { async fn friends(&self, pub_key: &str) -> Vec; + async fn images(&self, pub_key: &str) -> Vec<(String, String)>; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 5febf70ef89f9b9b0ac739454943f1a5569e85ee Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:19:40 +0200 Subject: [PATCH 21/39] add self_images and example --- solar_client/examples/self_images.rs | 22 ++++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 solar_client/examples/self_images.rs diff --git a/solar_client/examples/self_images.rs b/solar_client/examples/self_images.rs new file mode 100644 index 0000000..851d54b --- /dev/null +++ b/solar_client/examples/self_images.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let self_images = client.self_images(PUB_KEY).await?; + println!("{:#?}", self_images); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "&dmLPhR0npN7tHiICGfM1WLBMHhhzh5I5VR3rEKvmOXw=.sha256", + // ), + // ... + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 96126c6..1338ff5 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -26,6 +26,8 @@ pub trait SolarClient { async fn images(&self, pub_key: &str) -> Vec<(String, String)>; + async fn self_images(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 9074460b638529875fba6e527c9caece3ffeb5ee Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:20:11 +0200 Subject: [PATCH 22/39] update the return types for self_images --- solar/src/storage/indexes.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/solar/src/storage/indexes.rs b/solar/src/storage/indexes.rs index 92feec0..31f2f63 100644 --- a/solar/src/storage/indexes.rs +++ b/solar/src/storage/indexes.rs @@ -464,9 +464,13 @@ impl Indexes { /// Return all indexed self-assigned image references for the given public /// key. - pub fn get_self_assigned_images(&self, ssb_id: &str) -> Result> { - let mut images = self.get_images(ssb_id)?; - images.retain(|(author, _image)| author == ssb_id); + pub fn get_self_assigned_images(&self, ssb_id: &str) -> Result> { + let images = self + .get_images(ssb_id)? + .into_iter() + .filter(|(author, _image)| author == ssb_id) + .map(|(_ssb_id, image)| image) + .collect(); Ok(images) } @@ -482,7 +486,7 @@ impl Indexes { /// Return the most recently indexed self-assigned image reference for the /// given public key. - pub fn get_latest_self_assigned_image(&self, ssb_id: &str) -> Result> { + pub fn get_latest_self_assigned_image(&self, ssb_id: &str) -> Result> { let images = self.get_self_assigned_images(ssb_id)?; let image = images.last().cloned(); From 915d06803dbcc5689eaf10f752eedd5e5861e190 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:27:35 +0200 Subject: [PATCH 23/39] add latest_image and example, update self_images example --- solar_client/examples/latest_image.rs | 19 +++++++++++++++++++ solar_client/examples/self_images.rs | 11 ++++++----- solar_client/src/lib.rs | 2 ++ 3 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 solar_client/examples/latest_image.rs diff --git a/solar_client/examples/latest_image.rs b/solar_client/examples/latest_image.rs new file mode 100644 index 0000000..94ea87d --- /dev/null +++ b/solar_client/examples/latest_image.rs @@ -0,0 +1,19 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let latest_image = client.latest_image(PUB_KEY).await?; + println!("{:#?}", latest_image); + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "&8M2JFEFHlxJ5q8Lmu3P4bDdCHg0SLB27Q321cy9Upx4=.sha256", + // ) + + Ok(()) +} diff --git a/solar_client/examples/self_images.rs b/solar_client/examples/self_images.rs index 851d54b..0e03f75 100644 --- a/solar_client/examples/self_images.rs +++ b/solar_client/examples/self_images.rs @@ -11,11 +11,12 @@ async fn main() -> Result<()> { let self_images = client.self_images(PUB_KEY).await?; println!("{:#?}", self_images); // [ - // ( - // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", - // "&dmLPhR0npN7tHiICGfM1WLBMHhhzh5I5VR3rEKvmOXw=.sha256", - // ), - // ... + // "&dmLPhR0npN7tHiICGfM1WLBMHhhzh5I5VR3rEKvmOXw=.sha256", + // "&f4YiGjvj3ClOc3VA0XYQnPZAflQm/GROfTkHBjAb3a0=.sha256", + // "&dmLPhR0npN7tHiICGfM1WLBMHhhzh5I5VR3rEKvmOXw=.sha256", + // "&Z8X3/bszQTRZ3cmyEM6sUoa8hlDbS+qfecziI5gRXpY=.sha256", + // "&LesplCjgV8Q355b93QOFCoL5G1KdyXTqIsm4EL9R2Fw=.sha256", + // "&8M2JFEFHlxJ5q8Lmu3P4bDdCHg0SLB27Q321cy9Upx4=.sha256", // ] Ok(()) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 1338ff5..461d005 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -28,6 +28,8 @@ pub trait SolarClient { async fn self_images(&self, pub_key: &str) -> Vec; + async fn latest_image(&self, pub_key: &str) -> (String, String); + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 37d516070f4fdda1df9f68c4ab94a407fc052ce7 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:28:56 +0200 Subject: [PATCH 24/39] add latest_self_assigned_image --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 461d005..045355e 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -30,6 +30,8 @@ pub trait SolarClient { async fn latest_image(&self, pub_key: &str) -> (String, String); + async fn latest_self_image(&self, pub_key: &str) -> String; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 200fb2fa578d23c984d4228733f54d9a1db52565 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:54:16 +0200 Subject: [PATCH 25/39] add message and example, return json value from feed and message --- solar_client/Cargo.toml | 1 + solar_client/examples/feed.rs | 9 ++------- solar_client/examples/message.rs | 34 ++++++++++++++++++++++++++++++++ solar_client/src/lib.rs | 6 +++++- 4 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 solar_client/examples/message.rs diff --git a/solar_client/Cargo.toml b/solar_client/Cargo.toml index 1d468a0..c0902cd 100644 --- a/solar_client/Cargo.toml +++ b/solar_client/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" anyhow = "1.0.79" jsonrpc_client = { version = "0.7.1", features = ["macros", "reqwest"] } reqwest = { version = "0.11", default-features = false, features = [ "json" ] } +serde_json = { version = "1", features = ["preserve_order", "arbitrary_precision"] } [dev-dependencies] tokio = { version = "1.36.0", features = [ "macros", "rt-multi-thread" ] } diff --git a/solar_client/examples/feed.rs b/solar_client/examples/feed.rs index 5f524b0..e392ae0 100644 --- a/solar_client/examples/feed.rs +++ b/solar_client/examples/feed.rs @@ -2,7 +2,7 @@ use anyhow::Result; use solar_client::{Client, SolarClient}; const SERVER_ADDR: &str = "http://127.0.0.1:3030"; -const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; +const PUB_KEY: &str = "@qK93G/R9R5J2fiqK+kxV72HqqPUcss+rth8rACcYr4s=.ed25519"; #[tokio::main] async fn main() -> Result<()> { @@ -10,12 +10,7 @@ async fn main() -> Result<()> { let feed = client.feed(PUB_KEY).await?; println!("{:#?}", feed); - // [ - // "@dW5ch5miTnxLJDVDtB4ZCvrVxh+S8kGCQIBbd5paLhw=.ed25519", - // "@QIlKZ8DMw9XpjpRZ96RBLpfkLnOUZSqamC6WMddGh3I=.ed25519", - // ... - // "@+rMXLy1md42gvbBq+6l6rp95/drh6QyACO1ZZMMnWI0=.ed25519", - // ] + // TODO Ok(()) } diff --git a/solar_client/examples/message.rs b/solar_client/examples/message.rs new file mode 100644 index 0000000..2ebdae2 --- /dev/null +++ b/solar_client/examples/message.rs @@ -0,0 +1,34 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const MSG_REF: &str = "%RCb++/ZhqV1lJNIcoNrk4yM3AfBobT7u8seObZgcEbA=.sha256"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let message = client.message(MSG_REF).await?; + println!("{:#?}", message); + /* + Object { + "key": String("%RCb++/ZhqV1lJNIcoNrk4yM3AfBobT7u8seObZgcEbA=.sha256"), + "value": Object { + "previous": String("%uhtIvUJeHicd+i/biMI/IlLiLkN4pAYgrVq4CA2rSYA=.sha256"), + "sequence": Number(227), + "author": String("@qK93G/R9R5J2fiqK+kxV72HqqPUcss+rth8rACcYr4s=.ed25519"), + "timestamp": Number(1707730214482), + "hash": String("sha256"), + "content": Object { + "type": String("post"), + "text": String("Testing out the solar JSON-RPC client"), + }, + "signature": String("fsDScOQ3Zbm9sRpcUfKV+Rtf/I70vKpRW3BTIuK3IoZGhYj9Z/pdHDGAWUh+9ixToAevdKltgJZWa7DUWdAuCw==.sig.ed25519"), + }, + "timestamp": Number(1707730214.4837818), + "rts": Null, + } + */ + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 045355e..698b8ff 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -1,4 +1,6 @@ use anyhow::Result; +// TODO: Should we rather be using a custom kuska type? +use serde_json::Value; #[jsonrpc_client::api] pub trait SolarClient { @@ -14,7 +16,7 @@ pub trait SolarClient { async fn latest_self_description(&self, pub_key: &str) -> String; - async fn feed(&self, pub_key: &str) -> Vec; + async fn feed(&self, pub_key: &str) -> Vec; async fn follows(&self, pub_key: &str) -> Vec; @@ -32,6 +34,8 @@ pub trait SolarClient { async fn latest_self_image(&self, pub_key: &str) -> String; + async fn message(&self, msg_ref: &str) -> Value; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 7a1c21ba81072498c0d126a4ed3edbc19e97462d Mon Sep 17 00:00:00 2001 From: mycognosist Date: Tue, 13 Feb 2024 13:54:29 +0200 Subject: [PATCH 26/39] update lockfile --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 188f2f5..7fdd35c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1878,6 +1878,7 @@ dependencies = [ "anyhow", "jsonrpc_client", "reqwest", + "serde_json", "tokio", ] From 5b60e1d1e88def7f8a29766514a026b74a79ccca Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:18:57 +0200 Subject: [PATCH 27/39] add names and example --- solar_client/examples/names.rs | 25 +++++++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 solar_client/examples/names.rs diff --git a/solar_client/examples/names.rs b/solar_client/examples/names.rs new file mode 100644 index 0000000..4d23ad3 --- /dev/null +++ b/solar_client/examples/names.rs @@ -0,0 +1,25 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let names = client.names(PUB_KEY).await?; + println!("{:#?}", names); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "mycognosist", + // ), + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // "glyph", + // ), + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 698b8ff..d23d642 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -36,6 +36,8 @@ pub trait SolarClient { async fn message(&self, msg_ref: &str) -> Value; + async fn names(&self, pub_key: &str) -> Vec<(String, String)>; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 9b549578d92f7dd2100caa1012102abe9cf3882b Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:20:08 +0200 Subject: [PATCH 28/39] add self_names --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index d23d642..191913c 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -38,6 +38,8 @@ pub trait SolarClient { async fn names(&self, pub_key: &str) -> Vec<(String, String)>; + async fn self_names(&self, pub_key: &str) -> Vec; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 130aa5005709530e54cbb10b4c09110364fd35c7 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:20:44 +0200 Subject: [PATCH 29/39] add latest_name --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 191913c..501c6f1 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -40,6 +40,8 @@ pub trait SolarClient { async fn self_names(&self, pub_key: &str) -> Vec; + async fn latest_name(&self, pub_key: &str) -> String; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From f689e1caa945ca42e6ac7cec237318aa93a06a5d Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:20:59 +0200 Subject: [PATCH 30/39] add latest_self_name --- solar_client/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 501c6f1..ce81505 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -42,6 +42,8 @@ pub trait SolarClient { async fn latest_name(&self, pub_key: &str) -> String; + async fn latest_self_name(&self, pub_key: &str) -> String; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From b8ddb1ae9f4cc1e69843f362902052348ce43032 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:40:08 +0200 Subject: [PATCH 31/39] fix description api usage in index tests --- solar/src/storage/indexes.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/solar/src/storage/indexes.rs b/solar/src/storage/indexes.rs index 31f2f63..42857f2 100644 --- a/solar/src/storage/indexes.rs +++ b/solar/src/storage/indexes.rs @@ -603,7 +603,7 @@ mod test { indexes.index_msg(&keypair.id, first_msg)?; - if let Some((_author, description)) = indexes.get_latest_description(&keypair.id)? { + if let Some(description) = indexes.get_latest_description(&keypair.id)? { assert_eq!(description, first_description); } @@ -640,9 +640,7 @@ mod test { assert_eq!(lastest_name, second_name); } - if let Some((_author, latest_description)) = - indexes.get_latest_description(&keypair.id)? - { + if let Some(latest_description) = indexes.get_latest_description(&keypair.id)? { assert_eq!(latest_description, second_description); } } From 64b03cbd37be1ec1081e47ce6d8657daeb26fae6 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:40:41 +0200 Subject: [PATCH 32/39] return vec of tuple from get_peers and update tests --- solar/src/storage/kv.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/solar/src/storage/kv.rs b/solar/src/storage/kv.rs index d18c6e0..538c9cc 100644 --- a/solar/src/storage/kv.rs +++ b/solar/src/storage/kv.rs @@ -221,7 +221,7 @@ impl KvStorage { /// Return the public key and latest sequence number for all peers in the /// database. - pub async fn get_peers(&self) -> Result> { + pub async fn get_peers(&self) -> Result> { let db = self.db.as_ref().ok_or(Error::OptionIsNone)?; let mut peers = Vec::new(); @@ -235,8 +235,7 @@ impl KvStorage { // Get the latest sequence number for the peer. // Fallback to a value of 0 if a `None` value is returned. let seq_num = self.get_latest_seq(&pub_key)?.unwrap_or(0); - let peer_latest_sequence = PubKeyAndSeqNum { pub_key, seq_num }; - peers.push(peer_latest_sequence) + peers.push((pub_key, seq_num)) } Ok(peers) @@ -479,8 +478,8 @@ mod test { assert_eq!(peers.len(), 1); // Ensure the public key of the peer matches expectations and that // the sequence number is correct. - assert_eq!(peers[0].pub_key, keypair.id); - assert_eq!(peers[0].seq_num, 1); + assert_eq!(peers[0].0, keypair.id); + assert_eq!(peers[0].1, 1); // Create, sign and append a second post-type message. let msg_content_2 = TypedMessage::Post { From 689b6ed3555e74626d22d2b5f4d78fe512fa419b Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:40:58 +0200 Subject: [PATCH 33/39] add peers and example --- solar_client/examples/peers.rs | 34 ++++++++++++++++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 36 insertions(+) create mode 100644 solar_client/examples/peers.rs diff --git a/solar_client/examples/peers.rs b/solar_client/examples/peers.rs new file mode 100644 index 0000000..e7d5ebd --- /dev/null +++ b/solar_client/examples/peers.rs @@ -0,0 +1,34 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + // Get the public key and latest sequence number for all peers in the + // local database. + let peers = client.peers().await?; + println!("{:#?}", peers); + // [ + // ( + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // 26681, + // ), + // ( + // "@L/g6qZQE/2FdO2UhSJ0uyDiZb5LjJLatM/d8MN+INSM=.ed25519", + // 46, + // ), + // ( + // "@bMUudXOb9+FrVXKIxyn6ro+jo4drbrKXdSoZ9yXp8rc=.ed25519", + // 3, + // ), + // ( + // "@qK93G/R9R5J2fiqK+kxV72HqqPUcss+rth8rACcYr4s=.ed25519", + // 227, + // ), + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index ce81505..18ded46 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -44,6 +44,8 @@ pub trait SolarClient { async fn latest_self_name(&self, pub_key: &str) -> String; + async fn peers(&self) -> Vec<(String, u64)>; + async fn ping(&self) -> String; async fn whoami(&self) -> String; From 4d4cb7048bcd34c46ab8724c03d58a847217590d Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:45:39 +0200 Subject: [PATCH 34/39] add subscribers and example --- solar_client/examples/subscribers.rs | 18 ++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 20 insertions(+) create mode 100644 solar_client/examples/subscribers.rs diff --git a/solar_client/examples/subscribers.rs b/solar_client/examples/subscribers.rs new file mode 100644 index 0000000..0f16d14 --- /dev/null +++ b/solar_client/examples/subscribers.rs @@ -0,0 +1,18 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const CHANNEL: &str = "myco"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let subscribers = client.subscribers(CHANNEL).await?; + println!("{:#?}", subscribers); + // [ + // "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519", + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index 18ded46..d462bfa 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -48,6 +48,8 @@ pub trait SolarClient { async fn ping(&self) -> String; + async fn subscribers(&self, channel: &str) -> Vec; + async fn whoami(&self) -> String; } From cd42725ca5bffa1c5d4a0f4ee5107bd960c45e66 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Wed, 21 Feb 2024 08:49:24 +0200 Subject: [PATCH 35/39] add subscriptions and example --- solar_client/examples/subscriptions.rs | 27 ++++++++++++++++++++++++++ solar_client/src/lib.rs | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 solar_client/examples/subscriptions.rs diff --git a/solar_client/examples/subscriptions.rs b/solar_client/examples/subscriptions.rs new file mode 100644 index 0000000..f2ad836 --- /dev/null +++ b/solar_client/examples/subscriptions.rs @@ -0,0 +1,27 @@ +use anyhow::Result; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const PUB_KEY: &str = "@HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + let subscriptions = client.subscriptions(PUB_KEY).await?; + println!("{:#?}", subscriptions); + // [ + // "falconry", + // "solarfest", + // "compendiumofmadscience", + // "inktober2018", + // "butt-summaries", + // "squatchcam", + // ... + // "arduino", + // "savingspools", + // "meditation", + // ] + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index d462bfa..bfa139a 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -50,6 +50,8 @@ pub trait SolarClient { async fn subscribers(&self, channel: &str) -> Vec; + async fn subscriptions(&self, pub_key: &str) -> Vec; + async fn whoami(&self) -> String; } From 5abd30182bf70602258cf31ea885ae7290469aa0 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Thu, 22 Feb 2024 08:50:09 +0200 Subject: [PATCH 36/39] make publish endpoint take a message as a named object --- solar/src/actors/jsonrpc/server.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/solar/src/actors/jsonrpc/server.rs b/solar/src/actors/jsonrpc/server.rs index 698c7e9..3232733 100644 --- a/solar/src/actors/jsonrpc/server.rs +++ b/solar/src/actors/jsonrpc/server.rs @@ -26,6 +26,12 @@ struct IsFollowing { peer_b: String, } +/// The contents of a raw message (of any supported type). +#[derive(Debug, Deserialize)] +struct Msg { + msg: TypedMessage, +} + /// Message reference containing the key (sha256 hash) of a message. /// Used to parse the key from the parameters supplied to the `message` /// endpoint. @@ -474,8 +480,9 @@ pub async fn actor(server_id: OwnedIdentity, server_addr: SocketAddr) -> Result< // Returns the key (hash) and sequence number of the published message. rpc_module.register_method("publish", move |params: Params, _| { task::block_on(async { - // Parse the parameter containing the post content. - let post_content: TypedMessage = params.parse()?; + // Parse the parameter containing the message content. + let msg_object: Msg = params.parse()?; + let msg_content: TypedMessage = msg_object.msg; // Open the primary KV database for writing. let db = KV_STORE.write().await; @@ -484,8 +491,8 @@ pub async fn actor(server_id: OwnedIdentity, server_addr: SocketAddr) -> Result< // Return `None` if no messages have yet been published on the feed. let last_msg = db.get_latest_msg_val(&server_id.id)?; - // Instantiate and cryptographically-sign a new message using `post`. - let msg = Message::sign(last_msg.as_ref(), &server_id, json!(post_content)) + // Instantiate and cryptographically-sign a new message. + let msg = Message::sign(last_msg.as_ref(), &server_id, json!(msg_content)) .map_err(Error::Validation)?; // Append the signed message to the feed. @@ -497,7 +504,8 @@ pub async fn actor(server_id: OwnedIdentity, server_addr: SocketAddr) -> Result< seq ); - let response = json![{ "msg_ref": msg.id().to_string(), "seq_num": seq }]; + // Return a tuple of message reference and sequence number. + let response = json!((msg.id().to_string(), seq)); Ok::(response) }) From 0c5cee6b848cbccf07c1204b12bff26e57b73da3 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Thu, 22 Feb 2024 08:50:30 +0200 Subject: [PATCH 37/39] add publish and example --- solar_client/examples/publish.rs | 32 ++++++++++++++++++++++++++++++++ solar_client/src/lib.rs | 3 ++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 solar_client/examples/publish.rs diff --git a/solar_client/examples/publish.rs b/solar_client/examples/publish.rs new file mode 100644 index 0000000..f938bd9 --- /dev/null +++ b/solar_client/examples/publish.rs @@ -0,0 +1,32 @@ +use anyhow::Result; +use serde_json::json; +use solar_client::{Client, SolarClient}; + +const SERVER_ADDR: &str = "http://127.0.0.1:3030"; +const TEXT: &str = "Testing message publishing via the solar JSON-RPC client"; + +#[tokio::main] +async fn main() -> Result<()> { + let client = Client::new(SERVER_ADDR.to_owned())?; + + // Construct a JSON post. + // + // This can take any shape conforming to + // `kuska_ssb::api::dto::content::TypedMessage`. + // + // Consult the `kuska_ssb` repo for more details: + // https://github.com/Kuska-ssb/ssb + let post = json!({ + "type": "post", + "text": TEXT, + }); + + let msg_ref_and_seq_num = client.publish(post).await?; + println!("{:?}", msg_ref_and_seq_num); + // ("%J0k3hbXE6CjoA2yFpUsy+A1K+GRcTc5Eh6LH7OuzzUE=.sha256", 231) + + // Or destructure the tuple into individual components: + // let (msg_ref, seq_num) = client.publish(post).await?; + + Ok(()) +} diff --git a/solar_client/src/lib.rs b/solar_client/src/lib.rs index bfa139a..29f903d 100644 --- a/solar_client/src/lib.rs +++ b/solar_client/src/lib.rs @@ -1,5 +1,4 @@ use anyhow::Result; -// TODO: Should we rather be using a custom kuska type? use serde_json::Value; #[jsonrpc_client::api] @@ -48,6 +47,8 @@ pub trait SolarClient { async fn ping(&self) -> String; + async fn publish(&self, msg: Value) -> (String, u64); + async fn subscribers(&self, channel: &str) -> Vec; async fn subscriptions(&self, pub_key: &str) -> Vec; From ec17451c3d8c5e314c956cf5acddd9aecef32745 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Thu, 22 Feb 2024 09:01:04 +0200 Subject: [PATCH 38/39] remove JSON-RPC API docs from main repo README and update solar README --- README.md | 61 +------------------------------------------------ solar/README.md | 49 ++++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 864558e..518f506 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ or embedded into another Rust application as a [library](https://github.com/myco :warning: **Solar is alpha software; expect breaking changes** :construction: -[Background](#background) | [Features](#features) | [Installation](#installation) | [Usage](#usage) | [Examples](#examples) | [CLI Options](#options) | [Configuration](#configuration) | [JSON-RPC API](#json-rpc) | [License](#license) +[Background](#background) | [Features](#features) | [Installation](#installation) | [Usage](#usage) | [Examples](#examples) | [CLI Options](#options) | [Configuration](#configuration) | [License](#license) ## Background @@ -126,65 +126,6 @@ Alternatively, peers can be added to the replication configuration via CLI optio Log-level can be defined by setting the `RUST_LOG` environment variable. -## JSON-RPC API - -While running, a solar node can be queried using JSON-RPC over HTTP. - -| Method | Parameters | Response | Description | -| --- | --- | --- | --- | -| `blocks` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `blockers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and a description | -| `self_descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of descriptions | -| `latest_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | -| `latest_self_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | -| `feed` | `{ "pub_key": "<@...=.ed25519>" }` | `[{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }]` | Returns an array of message KVTs (key, value, timestamp) from the local database | -| `follows` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `followers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `is_following` | `{ "peer_a": "<@...=.ed25519>", "peer_b": "<@...=.ed25519>" }` | `` | Returns a boolean | -| `friends` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `images` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, <&...=.sha256>)]` | Returns an array of tuples, each containing a public key and an image reference | -| `self_images` | `{ "pub_key": "<@...=.ed25519>" }` | `[<&...=.sha256>]` | Returns an array of image references | -| `latest_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | -| `latest_self_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | -| `message` | `{ "msg_ref": "<%...=.sha256>" }` | `{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }` | Returns a single message KVT (key, value, timestamp) from the local database | -| `names` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of names | -| `self_names` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of names | -| `latest_name` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single name | -| `latest_self_name` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single name | -| `peers` | | `[{ "pub_key": "<@...=.ed25519>", "seq_num": }` | Returns an array of public key and latest sequence number for each peer in the local database | -| `ping` | | `pong!` | Responds if the JSON-RPC server is running | -| `publish` | `` | `{ "msg_ref": "<%...=.sha256>", "seq_num": }` | Publishes a message and returns the reference (message hash) and sequence number | -| `subscribers` | `{ "channel": "" }` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `subscriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of channel names | -| `whoami` | | `<@...=.ed25519>` | Returns the public key of the local node | - -### Examples - -`curl` can be used to invoke the available methods from the commandline. - -Request: - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ping", "id":1 }' 127.0.0.1:3030` - -Response: - -`{"jsonrpc":"2.0","result":"pong!","id":1}` - -Request: - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "publish", "params": {"type": "about", "about": "@o8lWpyLeSqV/BJV9pbxFhKpwm6Lw5k+sqexYK+zT9Tc=.ed25519", "name": "solar_glyph", "description": "glyph's experimental solar (rust) node"}, "id":1 }' 127.0.0.1:3030` - -Response: - -`{"jsonrpc":"2.0","result":{"msg_ref":"%ZwYwLxMHgU8eC43HOziJvYURjZzAzwFk3v5RYS/NbQY=.sha256","seq": 3,"id":1}` - -_Note: You might find it easier to save your JSON to file and pass that to `curl` instead._ - -``` -curl -X POST -H "Content-Type: application/json" --data @publish.json 127.0.0.1:3030 -``` - ## License AGPL-3.0 diff --git a/solar/README.md b/solar/README.md index da6b069..872d05f 100644 --- a/solar/README.md +++ b/solar/README.md @@ -67,33 +67,34 @@ While running, a solar node can be queried using JSON-RPC over HTTP. | Method | Parameters | Response | Description | | --- | --- | --- | --- | -| `blocks` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `blockers` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and description | -| `self_descriptions` | `"<@...=.ed25519>"` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and description | -| `latest_description` | `"<@...=.ed25519>"` | `` | Returns a single description | -| `latest_self_description` | `"<@...=.ed25519>"` | `` | Returns a single description | -| `feed` | `"<@...=.ed25519>"` | `[{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }]` | Returns an array of message KVTs (key, value, timestamp) from the local database | -| `follows` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `followers` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `is_following` | `{ "peer_a": "<@...=.ed25519>", "peer_b": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns a boolean | -| `friends` | `"<@...=.ed25519>"` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `images` | `"<@...=.ed25519>"` | `[<&...=.sha256>]` | Returns an array of image references | -| `self_images` | `"<@...=.ed25519>"` | `[<&...=.sha256>]` | Returns an array of image references | -| `latest_image` | `"<@...=.ed25519>"` | `<&...=.sha256>` | Returns a single image reference | -| `latest_self_image` | `"<@...=.ed25519>"` | `<&...=.sha256>` | Returns a single image reference | -| `message` | `"<%...=.sha256>"` | `{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }` | Returns a single message KVT (key, value, timestamp) from the local database | -| `names` | `"<@...=.ed25519>"` | `[]` | Returns an array of names | -| `self_names` | `"<@...=.ed25519>"` | `[]` | Returns an array of names | -| `latest_name` | `"<@...=.ed25519>"` | `` | Returns a single name | -| `latest_self_name` | `"<@...=.ed25519>"` | `` | Returns a single name | +| `blocks` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `blockers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, )]` | Returns an array of tuples, each containing a public key and a description | +| `self_descriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of descriptions | +| `latest_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | +| `latest_self_description` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single description | +| `feed` | `{ "pub_key": "<@...=.ed25519>" }` | `[{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }]` | Returns an array of message KVTs (key, value, timestamp) from the local database | +| `follows` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `followers` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `is_following` | `{ "peer_a": "<@...=.ed25519>", "peer_b": "<@...=.ed25519>" }` | `` | Returns a boolean | +| `friends` | `{ "pub_key": "<@...=.ed25519>" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `images` | `{ "pub_key": "<@...=.ed25519>" }` | `[(<@...=.ed25519>, <&...=.sha256>)]` | Returns an array of tuples, each containing a public key and an image reference | +| `self_images` | `{ "pub_key": "<@...=.ed25519>" }` | `[<&...=.sha256>]` | Returns an array of image references | +| `latest_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | +| `latest_self_image` | `{ "pub_key": "<@...=.ed25519>" }` | `<&...=.sha256>` | Returns a single image reference | +| `message` | `{ "msg_ref": "<%...=.sha256>" }` | `{ "key": "<%...=.sha256>", "value": , "timestamp": , "rts": null }` | Returns a single message KVT (key, value, timestamp) from the local database | +| `names` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of names | +| `self_names` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of names | +| `latest_name` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single name | +| `latest_self_name` | `{ "pub_key": "<@...=.ed25519>" }` | `` | Returns a single name | | `peers` | | `[{ "pub_key": "<@...=.ed25519>", "seq_num": }` | Returns an array of public key and latest sequence number for each peer in the local database | | `ping` | | `pong!` | Responds if the JSON-RPC server is running | -| `publish` | `` | `{ "msg_ref": "<%...=.sha256>", "seq_num": }` | Publishes a message and returns the reference (message hash) and sequence number | -| `subscribers` | `""` | `[<@...=.ed25519>]` | Returns an array of public keys | -| `subscriptions` | `"<@...=.ed25519>"` | `[]` | Returns an array of channel names | +| `publish` | `{ "msg": {} }` | `("<%...=.sha256>", )` | Returns a tuple of the reference (message hash) and sequence number | +| `subscribers` | `{ "channel": "" }` | `[<@...=.ed25519>]` | Returns an array of public keys | +| `subscriptions` | `{ "pub_key": "<@...=.ed25519>" }` | `[]` | Returns an array of channel names | | `whoami` | | `<@...=.ed25519>` | Returns the public key of the local node | + ### Examples `curl` can be used to invoke the available methods from the commandline. @@ -108,7 +109,7 @@ Response: Request: -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "publish", "params": {"type": "about", "about": "@o8lWpyLeSqV/BJV9pbxFhKpwm6Lw5k+sqexYK+zT9Tc=.ed25519", "name": "solar_glyph", "description": "glyph's experimental solar (rust) node"}, "id":1 }' 127.0.0.1:3030` +`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "publish", "params": {"msg": {"type": "about", "about": "@o8lWpyLeSqV/BJV9pbxFhKpwm6Lw5k+sqexYK+zT9Tc=.ed25519", "name": "solar_glyph", "description": "glyph's experimental solar (rust) node"} }, "id":1 }' 127.0.0.1:3030` Response: From 84c5ebe264d82554d3b83e16a2eddee4c90402d8 Mon Sep 17 00:00:00 2001 From: mycognosist Date: Thu, 22 Feb 2024 09:05:07 +0200 Subject: [PATCH 39/39] add minimal README --- solar_client/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 solar_client/README.md diff --git a/solar_client/README.md b/solar_client/README.md new file mode 100644 index 0000000..b23ed95 --- /dev/null +++ b/solar_client/README.md @@ -0,0 +1,9 @@ +# 🌞 Solar JSON-RPC Client + +An HTTP JSON-RPC client for the Solar node. + +See `src/lib.rs` and `examples/` for API details and usage examples. + +## License + +AGPL-3.0