Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ authors = ["WalletConnect Team"]
license = "Apache-2.0"

[workspace]
members = ["blockchain_api", "relay_client", "relay_rpc"]
members = ["blockchain_api", "relay_client", "relay_rpc", "sign_api"]

[features]
default = ["full"]
full = ["client", "rpc", "http"]
full = ["client", "rpc", "http", "sign_api"]
client = ["dep:relay_client"]
http = ["relay_client/http"]
rpc = ["dep:relay_rpc"]
sign_api = ["dep:sign_api"]

[dependencies]
relay_client = { path = "./relay_client", optional = true }
relay_rpc = { path = "./relay_rpc", optional = true }
sign_api = { path = "./sign_api", optional = true }

[dev-dependencies]
anyhow = "1"
Expand Down
1 change: 0 additions & 1 deletion relay_client/src/websocket/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ impl Connection {

match stream {
Some(mut stream) => stream.close(None).await,

None => Err(WebsocketClientError::ClosingFailed(TransportError::AlreadyClosed).into()),
}
}
Expand Down
3 changes: 3 additions & 0 deletions relay_rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ cacao = [
]

[dependencies]
anyhow = "1.0.86"
bs58 = "0.4"
data-encoding = "2.3"
derive_more = { version = "0.99", default-features = false, features = [
Expand All @@ -42,6 +43,7 @@ chrono = { version = "0.4", default-features = false, features = [
regex = "1.7"
once_cell = "1.16"
jsonwebtoken = "8.1"
hkdf = "0.12.4"
k256 = { version = "0.13", optional = true }
sha3 = { version = "0.10", optional = true }
sha2 = { version = "0.10.6" }
Expand All @@ -56,6 +58,7 @@ alloy-contract = { git = "https://github.com/alloy-rs/alloy.git", rev = "d68a6b7
alloy-json-abi = { version = "0.7.0", optional = true }
alloy-sol-types = { version = "0.7.0", optional = true }
alloy-primitives = { version = "0.7.0", optional = true }
paste = "1.0.15"
strum = { version = "0.26", features = ["strum_macros", "derive"] }

[dev-dependencies]
Expand Down
80 changes: 60 additions & 20 deletions relay_rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@

use {
crate::domain::{DidKey, MessageId, SubscriptionId, Topic},
params::session::{
delete::SessionDeleteRequest,
event::SessionEventRequest,
extend::SessionExtendRequest,
propose::SessionProposeRequest,
request::SessionRequestRequest,
settle::SessionSettleRequest,
update::SessionUpdateRequest,
RequestParams,
},
serde::{de::DeserializeOwned, Deserialize, Serialize},
std::{fmt::Debug, sync::Arc},
};
pub use {error::*, watch::*};

pub mod error;
pub mod msg_id;
pub mod params;
#[cfg(test)]
mod tests;
pub mod watch;
Expand Down Expand Up @@ -88,6 +99,10 @@ impl Payload {
Self::Response(response) => response.validate(),
}
}

pub fn irn_tag_in_range(tag: u32) -> bool {
(1100..=1115).contains(&tag)
}
}

impl<T> From<T> for Payload
Expand All @@ -99,6 +114,18 @@ where
}
}

impl From<Request> for Payload {
fn from(value: Request) -> Self {
Payload::Request(value)
}
}

impl From<Response> for Payload {
fn from(value: Response) -> Self {
Payload::Response(value)
}
}

/// Enum representing a JSON RPC response.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
Expand Down Expand Up @@ -195,26 +222,6 @@ impl ErrorResponse {
}
}

/// Data structure representing error response params.
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorData {
/// Error code.
pub code: i32,

/// Error message.
pub message: String,

/// Error data, if any.
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
}

#[derive(Debug, thiserror::Error, strum::EnumString, strum::IntoStaticStr, PartialEq, Eq)]
pub enum SubscriptionError {
#[error("Subscriber limit exceeded")]
SubscriberLimitExceeded,
}

/// Subscription request parameters. This request does not require the
/// subscription to be fully processed, and returns as soon as the server
/// receives it.
Expand Down Expand Up @@ -808,6 +815,37 @@ pub enum Params {
/// topic the data is published for.
#[serde(rename = "irn_subscription", alias = "iridium_subscription")]
Subscription(Subscription),
#[serde(rename = "wc_sessionPropose")]
SessionPropose(SessionProposeRequest),
#[serde(rename = "wc_sessionSettle")]
SessionSettle(SessionSettleRequest),
#[serde(rename = "wc_sessionRequest")]
SessionRequest(SessionRequestRequest),
#[serde(rename = "wc_sessionEvent")]
SessionEvent(SessionEventRequest),
#[serde(rename = "wc_sessionUpdate")]
SessionUpdate(SessionUpdateRequest),
#[serde(rename = "wc_sessionDelete")]
SessionDelete(SessionDeleteRequest),
#[serde(rename = "wc_sessionExtend")]
SessionExtend(SessionExtendRequest),
#[serde(rename = "wc_sessionPing")]
SessionPing(()),
}

impl From<RequestParams> for Params {
fn from(value: RequestParams) -> Self {
match value {
RequestParams::SessionEvent(params) => Params::SessionEvent(params),
RequestParams::SessionSettle(params) => Params::SessionSettle(params),
RequestParams::SessionExtend(params) => Params::SessionExtend(params),
RequestParams::SessionUpdate(params) => Params::SessionUpdate(params),
RequestParams::SessionPropose(params) => Params::SessionPropose(params),
RequestParams::SessionRequest(params) => Params::SessionRequest(params),
RequestParams::SessionDelete(params) => Params::SessionDelete(params),
RequestParams::SessionPing(()) => Params::SessionPing(()),
}
}
}

/// Data structure representing a JSON RPC request.
Expand Down Expand Up @@ -844,6 +882,7 @@ impl Request {
return Err(PayloadError::InvalidJsonRpcVersion);
}

// TODO: add validation checks for Session Params
match &self.params {
Params::Subscribe(params) => params.validate(),
Params::SubscribeBlocking(params) => params.validate(),
Expand All @@ -858,6 +897,7 @@ impl Request {
Params::WatchRegister(params) => params.validate(),
Params::WatchUnregister(params) => params.validate(),
Params::Subscription(params) => params.validate(),
_ => Ok(()),
}
}
}
27 changes: 23 additions & 4 deletions relay_rpc/src/rpc/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
use {
super::ErrorData,
std::fmt::{Debug, Display},
};
use std::fmt::{Debug, Display};
use serde::{Deserialize, Serialize};


/// Data structure representing error response params.
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorData {
/// Error code.
pub code: i32,

/// Error message.
pub message: String,

/// Error data, if any.
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
}

#[derive(Debug, thiserror::Error, strum::EnumString, strum::IntoStaticStr, PartialEq, Eq)]
pub enum SubscriptionError {
#[error("Subscriber limit exceeded")]
SubscriberLimitExceeded,
}

/// Provides serialization to and from string tags. This has a blanket
/// implementation for all error types that derive [`strum::EnumString`] and
Expand Down
20 changes: 20 additions & 0 deletions relay_rpc/src/rpc/params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pub mod session;

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, PartialEq, Eq, Hash, Deserialize, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct Metadata {
pub description: String,
pub url: String,
pub icons: Vec<String>,
pub name: String,
}

#[derive(Debug, Serialize, PartialEq, Eq, Hash, Deserialize, Clone, Default)]
pub struct Relay {
pub protocol: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub data: Option<String>,
}
Loading