Skip to content

Commit 7952277

Browse files
authored
rust-sdk: restructure API to builder pattern (#3000)
1 parent c5866db commit 7952277

File tree

15 files changed

+337
-239
lines changed

15 files changed

+337
-239
lines changed

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,11 @@ edition = "2021"
107107

108108
[workspace.dependencies]
109109
async-trait = "0.1.63"
110+
lazy_static = "1.4.0"
110111
log = "0.4"
111-
thiserror = "1.0.38"
112112
serde = "1.0.152"
113113
serde_json = "1.0.91"
114+
tap = "1.0.1"
115+
thiserror = "1.0.38"
114116
tokio = "1.24.1"
117+
url = "2.2"

clients/client-core/src/client/base_client/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,22 @@ pub mod non_wasm_helpers;
5151

5252
pub mod helpers;
5353

54+
#[derive(Clone)]
5455
pub struct ClientInput {
5556
pub connection_command_sender: ConnectionCommandSender,
5657
pub input_sender: InputMessageSender,
5758
}
5859

60+
impl ClientInput {
61+
pub async fn send(
62+
&self,
63+
message: InputMessage,
64+
) -> Result<(), tokio::sync::mpsc::error::SendError<InputMessage>> {
65+
self.input_sender.send(message).await
66+
}
67+
}
68+
69+
#[derive(Clone)]
5970
pub struct ClientOutput {
6071
pub received_buffer_request_sender: ReceivedBufferRequestSender,
6172
}
@@ -303,6 +314,7 @@ where
303314
let shared_key = if self.key_manager.is_gateway_key_set() {
304315
Some(self.key_manager.gateway_shared_key())
305316
} else {
317+
log::info!("Gateway key not set! Will proceed anyway.");
306318
None
307319
};
308320

clients/client-core/src/client/replies/reply_storage/backend/browser_backend.rs

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::client::replies::reply_storage::backend::Empty;
55
use crate::client::replies::reply_storage::{CombinedReplyStorage, ReplyStorageBackend};
66
use async_trait::async_trait;
77

8+
use std::path::PathBuf;
9+
810
// well, right now we don't have the browser storage : (
911
// so we keep everything in memory
1012
#[derive(Debug)]
@@ -27,6 +29,15 @@ impl Backend {
2729
impl ReplyStorageBackend for Backend {
2830
type StorageError = <Empty as ReplyStorageBackend>::StorageError;
2931

32+
async fn new(debug_config: &crate::config::DebugConfig, _db_path: Option<PathBuf>) -> Self {
33+
Backend {
34+
empty: Empty {
35+
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
36+
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
37+
},
38+
}
39+
}
40+
3041
async fn flush_surb_storage(
3142
&mut self,
3243
storage: &CombinedReplyStorage,

clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use crate::client::base_client::non_wasm_helpers;
45
use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager;
56
use crate::client::replies::reply_storage::backend::fs_backend::models::{
67
ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender,
@@ -367,6 +368,12 @@ impl Backend {
367368
impl ReplyStorageBackend for Backend {
368369
type StorageError = error::StorageError;
369370

371+
async fn new(debug_config: &crate::config::DebugConfig, db_path: Option<PathBuf>) -> Self {
372+
non_wasm_helpers::setup_fs_reply_surb_backend(db_path, debug_config)
373+
.await
374+
.unwrap()
375+
}
376+
370377
fn is_active(&self) -> bool {
371378
self.manager.is_active()
372379
}

clients/client-core/src/client/replies/reply_storage/backend/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::client::replies::reply_storage::CombinedReplyStorage;
55
use async_trait::async_trait;
6-
use std::error::Error;
6+
use std::{error::Error, path::PathBuf};
77
use thiserror::Error;
88

99
#[cfg(target_arch = "wasm32")]
@@ -30,6 +30,13 @@ pub struct Empty {
3030
impl ReplyStorageBackend for Empty {
3131
type StorageError = UndefinedError;
3232

33+
async fn new(debug_config: &crate::config::DebugConfig, _db_path: Option<PathBuf>) -> Self {
34+
Self {
35+
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
36+
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
37+
}
38+
}
39+
3340
async fn flush_surb_storage(
3441
&mut self,
3542
_storage: &CombinedReplyStorage,
@@ -63,6 +70,8 @@ impl ReplyStorageBackend for Empty {
6370
pub trait ReplyStorageBackend: Sized {
6471
type StorageError: Error + 'static;
6572

73+
async fn new(debug_config: &crate::config::DebugConfig, db_path: Option<PathBuf>) -> Self;
74+
6675
fn is_active(&self) -> bool {
6776
true
6877
}

common/client-libs/gateway-client/src/client.rs

+1
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ where
441441
}
442442

443443
debug_assert!(self.connection.is_available());
444+
log::trace!("Registering gateway");
444445

445446
// it's fine to instantiate it here as it's only used once (during authentication or registration)
446447
// and putting it into the GatewayClient struct would be a hassle

sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs

+39-18
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,62 @@ use nym_sdk::mixnet;
44
async fn main() {
55
logging::setup_logging();
66

7-
// We can set a few options
87
let user_chosen_gateway_id = None;
98
let nym_api_endpoints = vec!["https://validator.nymtech.net/api/".parse().unwrap()];
10-
119
let config = mixnet::Config::new(user_chosen_gateway_id, nym_api_endpoints);
1210

13-
let mut client = mixnet::MixnetClient::builder(Some(config), None)
14-
.await
15-
.unwrap();
16-
1711
// Just some plain data to pretend we have some external storage that the application
1812
// implementer is using.
1913
let mut mock_storage = MockStorage::empty();
2014

21-
// In this we want to provide our own gateway config struct, and handle persisting this info to disk
22-
// ourselves (e.g., as part of our own configuration file).
2315
let first_run = true;
24-
if first_run {
25-
client.register_with_gateway().await.unwrap();
16+
17+
let client = if first_run {
18+
// Create a client without a storage backend
19+
let mut client = mixnet::MixnetClientBuilder::new()
20+
.config(config)
21+
.build::<mixnet::EmptyReplyStorage>()
22+
.await
23+
.unwrap();
24+
25+
// In this we want to provide our own gateway config struct, and handle persisting this info to disk
26+
// ourselves (e.g., as part of our own configuration file).
27+
client.register_and_authenticate_gateway().await.unwrap();
2628
mock_storage.write(client.get_keys(), client.get_gateway_endpoint().unwrap());
29+
client
2730
} else {
2831
let (keys, gateway_config) = mock_storage.read();
29-
client.set_keys(keys);
30-
client.set_gateway_endpoint(gateway_config);
31-
}
32+
33+
// Create a client without a storage backend, but with explicitly set keys and gateway
34+
// configuration. This creates the client in a registered state.
35+
let client = mixnet::MixnetClientBuilder::new()
36+
.config(config)
37+
.keys(keys)
38+
.gateway_config(gateway_config)
39+
.build::<mixnet::EmptyReplyStorage>()
40+
.await
41+
.unwrap();
42+
client
43+
};
3244

3345
// Connect to the mixnet, now we're listening for incoming
34-
let client = client.connect_to_mixnet().await.unwrap();
46+
let mut client = client.connect_to_mixnet().await.unwrap();
3547

3648
// Be able to get our client address
37-
println!("Our client address is {}", client.nym_address());
49+
let our_address = client.nym_address();
50+
println!("Our client nym address is: {our_address}");
3851

3952
// Send important info up the pipe to a buddy
40-
let recipient = mixnet::Recipient::try_from_base58_string("foo.bar@blah").unwrap();
41-
client.send_str(recipient, "flappappa").await;
53+
client.send_str(*our_address, "hello there").await;
54+
55+
println!("Waiting for message");
56+
if let Some(received) = client.wait_for_messages().await {
57+
for r in received {
58+
println!("Received: {}", String::from_utf8_lossy(&r.message));
59+
}
60+
}
61+
62+
client.disconnect().await;
4263
}
4364

4465
#[allow(unused)]
@@ -53,7 +74,7 @@ impl MockStorage {
5374
}
5475

5576
fn write(&mut self, _keys: mixnet::KeysArc, _gateway_config: &mixnet::GatewayEndpointConfig) {
56-
todo!();
77+
log::info!("todo");
5778
}
5879

5980
fn empty() -> Self {

sdk/rust/nym-sdk/examples/persist_keys.rs

-39
This file was deleted.

sdk/rust/nym-sdk/examples/simple.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ async fn main() {
55
logging::setup_logging();
66

77
// Passing no config makes the client fire up an ephemeral session and figure shit out on its own
8-
let mut client = mixnet::MixnetClient::connect().await.unwrap();
8+
let mut client = mixnet::MixnetClient::connect_new().await.unwrap();
99

1010
// Be able to get our client address
1111
let our_address = client.nym_address();

sdk/rust/nym-sdk/examples/simple_but_manually_connect.rs

-30
This file was deleted.

sdk/rust/nym-sdk/src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum Error {
3131
supported, and likely and user mistake"
3232
)]
3333
ReregisteringGatewayNotSupported,
34+
#[error("no gateway key set")]
35+
NoGatewayKeySet,
3436
}
3537

3638
pub type Result<T, E = Error> = std::result::Result<T, E>;

sdk/rust/nym-sdk/src/mixnet.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! async fn main() {
1111
//! // Passing no config makes the client fire up an ephemeral session and figure stuff out on
1212
//! // its own
13-
//! let mut client = mixnet::MixnetClient::connect().await.unwrap();
13+
//! let mut client = mixnet::MixnetClient::connect_new().await.unwrap();
1414
//!
1515
//! // Be able to get our client address
1616
//! let our_address = client.nym_address();
@@ -36,8 +36,14 @@ mod connection_state;
3636
mod keys;
3737
mod paths;
3838

39-
pub use client::{MixnetClient, MixnetClientBuilder};
40-
pub use client_core::config::GatewayEndpointConfig;
39+
pub use client::{DisconnectedMixnetClient, MixnetClient, MixnetClientBuilder, MixnetClientSender};
40+
pub use client_core::{
41+
client::{
42+
inbound_messages::InputMessage,
43+
replies::reply_storage::{fs_backend::Backend as ReplyStorage, Empty as EmptyReplyStorage},
44+
},
45+
config::GatewayEndpointConfig,
46+
};
4147
pub use config::Config;
4248
pub use keys::{Keys, KeysArc};
4349
pub use nymsphinx::{

0 commit comments

Comments
 (0)