Skip to content

Commit 21bae4e

Browse files
authored
feat: watch rpc types; http client (#22)
1 parent 68bcc3d commit 21bae4e

File tree

24 files changed

+1667
-578
lines changed

24 files changed

+1667
-578
lines changed

Cargo.toml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ members = [
1313
]
1414

1515
[features]
16-
full = [
17-
"client",
18-
"rpc",
19-
]
16+
default = ["full"]
17+
full = ["client", "rpc"]
2018
client = ["dep:relay_client"]
2119
rpc = ["dep:relay_rpc"]
2220

@@ -28,7 +26,12 @@ relay_rpc = { path = "./relay_rpc", optional = true }
2826
anyhow = "1"
2927
structopt = { version = "0.3", default-features = false }
3028
tokio = { version = "1.22", features = ["full"] }
29+
url = "2.3"
30+
31+
[[example]]
32+
name = "websocket_client"
33+
required-features = ["client","rpc"]
3134

3235
[[example]]
33-
name = "basic_client"
34-
required-features = ["full"]
36+
name = "http_client"
37+
required-features = ["client","rpc"]

examples/http_client.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use {
2+
relay_client::{http::Client, ConnectionOptions},
3+
relay_rpc::{
4+
auth::{ed25519_dalek::Keypair, rand, AuthToken},
5+
domain::Topic,
6+
},
7+
std::{sync::Arc, time::Duration},
8+
structopt::StructOpt,
9+
url::Url,
10+
};
11+
12+
#[derive(StructOpt)]
13+
struct Args {
14+
/// Specify HTTP address.
15+
#[structopt(short, long, default_value = "https://relay.walletconnect.com/rpc")]
16+
address: String,
17+
18+
/// Specify WalletConnect project ID.
19+
#[structopt(short, long, default_value = "3cbaa32f8fbf3cdcc87d27ca1fa68069")]
20+
project_id: String,
21+
}
22+
23+
fn create_conn_opts(key: &Keypair, address: &str, project_id: &str) -> ConnectionOptions {
24+
let aud = Url::parse(address)
25+
.unwrap()
26+
.origin()
27+
.unicode_serialization();
28+
29+
let auth = AuthToken::new("http://example.com")
30+
.aud(aud)
31+
.ttl(Duration::from_secs(60 * 60))
32+
.as_jwt(key)
33+
.unwrap();
34+
35+
ConnectionOptions::new(project_id, auth).with_address(address)
36+
}
37+
38+
#[tokio::main]
39+
async fn main() -> anyhow::Result<()> {
40+
let args = Args::from_args();
41+
42+
let key1 = Keypair::generate(&mut rand::thread_rng());
43+
let client1 = Client::new(&create_conn_opts(&key1, &args.address, &args.project_id))?;
44+
45+
let key2 = Keypair::generate(&mut rand::thread_rng());
46+
let client2 = Client::new(&create_conn_opts(&key2, &args.address, &args.project_id))?;
47+
48+
let topic = Topic::generate();
49+
let message: Arc<str> = Arc::from("Hello WalletConnect!");
50+
51+
client1
52+
.publish(
53+
topic.clone(),
54+
message.clone(),
55+
1100,
56+
Duration::from_secs(30),
57+
)
58+
.await?;
59+
60+
println!("[client1] published message with topic: {topic}",);
61+
62+
tokio::time::sleep(Duration::from_secs(1)).await;
63+
64+
let messages = client2.fetch(topic).await?.messages;
65+
let message = messages
66+
.get(0)
67+
.ok_or(anyhow::anyhow!("fetch did not return any messages"))?;
68+
69+
println!("[client2] received message: {}", message.message);
70+
71+
Ok(())
72+
}

examples/basic_client.rs renamed to examples/websocket_client.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use {
22
relay_client::{
3-
Client,
4-
CloseFrame,
5-
ConnectionHandler,
3+
error::Error,
4+
websocket::{Client, CloseFrame, ConnectionHandler, PublishedMessage},
65
ConnectionOptions,
7-
Error,
8-
PublishedMessage,
96
},
107
relay_rpc::{
118
auth::{ed25519_dalek::Keypair, rand, AuthToken},
12-
domain::{AuthSubject, Topic},
9+
domain::Topic,
1310
},
1411
std::{sync::Arc, time::Duration},
1512
structopt::StructOpt,
@@ -64,7 +61,7 @@ impl ConnectionHandler for Handler {
6461
fn create_conn_opts(address: &str, project_id: &str) -> ConnectionOptions {
6562
let key = Keypair::generate(&mut rand::thread_rng());
6663

67-
let auth = AuthToken::new(AuthSubject::generate())
64+
let auth = AuthToken::new("http://example.com")
6865
.aud(address)
6966
.ttl(Duration::from_secs(60 * 60))
7067
.as_jwt(&key)
@@ -79,12 +76,12 @@ async fn main() -> anyhow::Result<()> {
7976

8077
let client1 = Client::new(Handler::new("client1"));
8178
client1
82-
.connect(create_conn_opts(&args.address, &args.project_id))
79+
.connect(&create_conn_opts(&args.address, &args.project_id))
8380
.await?;
8481

8582
let client2 = Client::new(Handler::new("client2"));
8683
client2
87-
.connect(create_conn_opts(&args.address, &args.project_id))
84+
.connect(&create_conn_opts(&args.address, &args.project_id))
8885
.await?;
8986

9087
let topic = Topic::generate();
@@ -101,7 +98,9 @@ async fn main() -> anyhow::Result<()> {
10198
)
10299
.await?;
103100

104-
println!("[client2] published message with topic: {topic}");
101+
println!("[client2] published message with topic: {topic}",);
102+
103+
tokio::time::sleep(Duration::from_millis(500)).await;
105104

106105
drop(client1);
107106
drop(client2);

relay_client/Cargo.toml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,20 @@ rustls = ["tokio-tungstenite/rustls-tls-native-roots"]
1111
relay_rpc = { path = "../relay_rpc" }
1212
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
1313
thiserror = "1.0"
14-
tokio = { version = "1.22", features = ["rt", "time", "sync", "macros", "rt-multi-thread"] }
15-
tokio-tungstenite = "0.18"
1614
serde = { version = "1.0", features = ["derive"] }
1715
serde_json = "1.0"
1816
serde_qs = "0.10"
19-
futures-channel = "0.3"
20-
tokio-stream = "0.1"
21-
tokio-util = "0.7"
2217
pin-project = "1.0"
2318
chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
2419
url = "2.3"
20+
http = "0.2"
21+
22+
# HTTP client dependencies.
23+
reqwest = { version = "0.11", features = ["json"] }
24+
25+
# WebSocket client dependencies.
26+
tokio = { version = "1.22", features = ["rt", "time", "sync", "macros", "rt-multi-thread"] }
27+
tokio-tungstenite = "0.18"
28+
futures-channel = "0.3"
29+
tokio-stream = "0.1"
30+
tokio-util = "0.7"

relay_client/src/errors.rs renamed to relay_client/src/error.rs

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,5 @@
1-
pub use tokio_tungstenite::tungstenite::protocol::CloseFrame;
2-
3-
pub type WsError = tokio_tungstenite::tungstenite::Error;
41
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
52

6-
/// Wrapper around the websocket [`CloseFrame`] providing info about the
7-
/// connection closing reason.
8-
#[derive(Debug, Clone)]
9-
pub struct CloseReason(pub Option<CloseFrame<'static>>);
10-
11-
impl std::fmt::Display for CloseReason {
12-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13-
if let Some(frame) = &self.0 {
14-
frame.fmt(f)
15-
} else {
16-
f.write_str("<close frame unavailable>")
17-
}
18-
}
19-
}
20-
213
/// Errors generated while parsing
224
/// [`ConnectionOptions`][crate::ConnectionOptions] and creating an HTTP request
235
/// for the websocket connection.
@@ -33,7 +15,10 @@ pub enum RequestBuildError {
3315
Url(#[from] url::ParseError),
3416

3517
#[error("Failed to create websocket request: {0}")]
36-
Other(WsError),
18+
WebsocketClient(#[from] crate::websocket::WebsocketClientError),
19+
20+
#[error("Failed to create HTTP request: {0}")]
21+
HttpClient(#[from] crate::http::HttpClientError),
3722
}
3823

3924
/// Possible Relay client errors.
@@ -42,20 +27,11 @@ pub enum Error {
4227
#[error("Failed to build connection request: {0}")]
4328
RequestBuilder(#[from] RequestBuildError),
4429

45-
#[error("Failed to connect: {0}")]
46-
ConnectionFailed(WsError),
47-
48-
#[error("Connection closed: {0}")]
49-
ConnectionClosed(CloseReason),
50-
51-
#[error("Failed to close connection: {0}")]
52-
ClosingFailed(WsError),
53-
54-
#[error("Not connected")]
55-
NotConnected,
30+
#[error("Websocket client error: {0}")]
31+
WebsocketClient(#[from] crate::websocket::WebsocketClientError),
5632

57-
#[error("Websocket error: {0}")]
58-
Socket(WsError),
33+
#[error("HTTP client error: {0}")]
34+
HttpClient(#[from] crate::http::HttpClientError),
5935

6036
#[error("Internal error: Channel closed")]
6137
ChannelClosed,

0 commit comments

Comments
 (0)