diff --git a/Cargo.lock b/Cargo.lock index 44c8d18421..6506f5d6da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3575,6 +3575,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-sdk" +version = "0.1.0" +dependencies = [ + "client-core", + "rand 0.7.3", + "tokio", +] + [[package]] name = "nym-socks5-client" version = "1.1.4" diff --git a/Cargo.toml b/Cargo.toml index e756fc7bf8..ebe84c2705 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,7 @@ members = [ "gateway/gateway-requests", "integrations/bity", "mixnode", + "sdk/rust/nym-sdk", "service-providers/network-requester", "service-providers/network-statistics", "nym-api", diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml new file mode 100644 index 0000000000..562b127604 --- /dev/null +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "nym-sdk" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +client-core = { path = "../../../clients/client-core" } +rand = { version = "0.7.3" } + +[dev-dependencies] +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/sdk/rust/nym-sdk/examples/complex_config.rs b/sdk/rust/nym-sdk/examples/complex_config.rs new file mode 100644 index 0000000000..38b0086f54 --- /dev/null +++ b/sdk/rust/nym-sdk/examples/complex_config.rs @@ -0,0 +1,23 @@ +#[tokio::main] +async fn main() { + // specify some config options + let config = mixnet::Config { + option: value, + option2: value2, + keyfiles: "~/.flappapapappa/keys/", + }; + + let client = mixnet::Client::new(&config); // passing a config allows the user to set values + + let show_receive = move || println!("got a message from the mixnet: {}", message); // might need to bury this in a struct as a `FnOnce`, see https://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust + client.on_receive(show_receive); // have some way to pipe any received info to a function for processing + + // connect to the mixnet, now we're listening for incoming + client.connect_to_mixnet(); + + // be able to get our client address + println!("Our client address is {}", client.nym_address); + + // send important info up the pipe to a buddy + client.send("foo.bar@blah", "flappappa"); +} diff --git a/sdk/rust/nym-sdk/examples/simple.rs b/sdk/rust/nym-sdk/examples/simple.rs new file mode 100644 index 0000000000..d6a79889de --- /dev/null +++ b/sdk/rust/nym-sdk/examples/simple.rs @@ -0,0 +1,22 @@ +use nym_sdk::mixnet; + +#[tokio::main] +async fn main() { + // here's what I'd actually like to write + let client = mixnet::Client::new(None); // passing no config makes the client fire up an ephemeral session and figure shit out on its own + + let show_receive = move || println!("got a message from the mixnet: {}", message); // might need to bury this in a struct as a `FnMut`, see https://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust + client.on_receive(show_receive); // have some way to pipe any received info to a function for processing + + // connect to the mixnet, now we're listening for incoming + client.connect_to_mixnet(); + + // be able to get our client address + println!("Our client address is {}", client.nym_address); + + // send important string info up the pipe to a buddy + client.send_str("foo.bar@blah", "flappappa"); + + // send some bytes to a buddy + client.send_bytes("foo.bar@blah", "flappappa".as_bytes().to_vec()); +} diff --git a/sdk/rust/nym-sdk/src/lib.rs b/sdk/rust/nym-sdk/src/lib.rs new file mode 100644 index 0000000000..ae7f01c0eb --- /dev/null +++ b/sdk/rust/nym-sdk/src/lib.rs @@ -0,0 +1 @@ +pub mod mixnet; diff --git a/sdk/rust/nym-sdk/src/mixnet/mod.rs b/sdk/rust/nym-sdk/src/mixnet/mod.rs new file mode 100644 index 0000000000..c37c4f1995 --- /dev/null +++ b/sdk/rust/nym-sdk/src/mixnet/mod.rs @@ -0,0 +1,62 @@ +use std::path::PathBuf; + +pub struct Client { + pub nym_address: String, + config: Config, +} + +impl Client { + /// Create a new mixnet client. If no config options are supplied, creates a new client with ephemeral keys + /// stored in RAM, which will be discarded at application close. + /// + /// Callers have the option of supplying futher parameters to store persistent identities at a location on-disk, + /// if desired. + pub fn new(config_option: Option) -> Client { + if config_option.is_none() { + let config = Self::some_minimal_config(); + let nym_address = Self::new_nym_address(); + Client { + config, + nym_address, + } + } else { + let self_address = Self::new_nym_address(); + let nym_address = Self::new_nym_address(); + + Client { + config: config_option.unwrap(), + nym_address, + } + } + } + + /// Connects to the mixnet via the gateway in the client config + pub fn connect_to_mixnet(&self) {} + + /// Sets the callback function which is run when the client receives a message + /// from the mixnet + pub fn on_receive(&mut self, message: &str) { + println!("Message received: {}", message); + } + + /// Sends stringy data to the supplied Nym address + pub fn send_str(&self, address: &str, message: &str) {} + + /// Sends bytes to the supplied Nym address + pub fn send_bytes(&self, address: &str, message: Vec) {} + + fn new_nym_address() -> String { + "the.nym@address".to_string() + } + + fn some_minimal_config() -> Config { + let mut keys_path = PathBuf::new(); + Config { + keys: Some(keys_path), + } + } +} + +pub struct Config { + keys: Option, +}