Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions crates/rust-sample-wallet/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,9 @@ pub fn App() -> impl IntoView {
"session delete on topic: {id}: {topic}",
);
}
IncomingSessionMessage::SessionEvent(id, topic, params) => {
IncomingSessionMessage::SessionEvent(topic, name, data, chain_id) => {
tracing::info!(
"session event on topic: {id}: {topic}: {params:?}",
"session event on topic: {topic}: name={name}, chainId={chain_id}, data={data}",
);
}
IncomingSessionMessage::SessionUpdate(id, topic, params) => {
Expand Down
60 changes: 54 additions & 6 deletions crates/yttrium/src/sign/client.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use {
crate::sign::{
client_errors::{
ApproveError, ConnectError, DisconnectError, ExtendError,
PairError, RejectError, RequestError, RespondError, UpdateError,
ApproveError, ConnectError, DisconnectError, EmitError,
ExtendError, PairError, RejectError, RequestError, RespondError,
UpdateError,
},
client_types::{
ConnectParams, ConnectResult, PairingInfo, RejectionReason,
Expand Down Expand Up @@ -804,10 +805,57 @@ impl Client {
unimplemented!()
}

pub async fn _emit(&self) {
// TODO implement
// https://github.com/WalletConnect/walletconnect-monorepo/blob/5bef698dcf0ae910548481959a6a5d87eaf7aaa5/packages/sign-client/src/controllers/engine.ts#L764
unimplemented!()
pub async fn emit(
&mut self,
topic: Topic,
name: String,
data: serde_json::Value,
chain_id: String,
) -> Result<(), EmitError> {
let shared_secret = self
.session_store
.get_session(topic.clone())
.map_err(EmitError::Storage)?
.map(|s| s.session_sym_key)
.ok_or(EmitError::SessionNotFound)?;

let id = generate_rpc_id();
let message = serialize_and_encrypt_message_type0_envelope(
shared_secret,
&crate::sign::protocol_types::SessionEventJsonRpc {
id,
jsonrpc: "2.0".to_string(),
method: "wc_sessionEvent".to_string(),
params: crate::sign::protocol_types::EventParams {
event: crate::sign::protocol_types::SessionEventVO {
name,
data,
},
chain_id,
},
},
)
.map_err(EmitError::ShouldNeverHappen)?;

self.do_request::<bool>(relay_rpc::rpc::Params::Publish(Publish {
topic,
message,
attestation: None,
ttl_secs: 86400,
tag: 1110,
prompt: false,
analytics: Some(AnalyticsData {
correlation_id: Some(id.try_into().unwrap()),
chain_id: None,
rpc_methods: None,
tx_hashes: None,
contract_addresses: None,
}),
}))
.await
.map_err(EmitError::Request)?;

Ok(())
}

pub async fn disconnect(
Expand Down
17 changes: 17 additions & 0 deletions crates/yttrium/src/sign/client_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,23 @@ pub enum DisconnectError {
Request(RequestError),
}

#[derive(Debug, thiserror::Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi_macros::Error))]
#[error("Sign emit error: {0}")]
pub enum EmitError {
#[error("Storage: {0}")]
Storage(StorageError),

#[error("Session not found")]
SessionNotFound,

#[error("Request: {0}")]
Request(RequestError),

#[error("Should never happen: {0}")]
ShouldNeverHappen(String),
}

#[derive(Debug, thiserror::Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi_macros::Error))]
#[error("Sign connect error: {0}")]
Expand Down
26 changes: 22 additions & 4 deletions crates/yttrium/src/sign/incoming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,16 +258,34 @@ pub fn handle(
);
}
Ok(())
} else if method.as_str() == Some("wc_sessionEmit") {
} else if method.as_str() == Some("wc_sessionEvent") {
// TODO dedup events based on JSON RPC history
// TODO emit event callback (blocking?)
// Parse wc_sessionEvent params
let params =
serde_json::from_value::<
crate::sign::protocol_types::EventParams,
>(value.get("params").cloned().ok_or_else(
|| HandleError::Client("params not found".to_string()),
)?)
.map_err(|e| {
HandleError::Client(format!("parse event params: {e}"))
})?;

let name = params.event.name;
let data_str =
serde_json::to_string(&params.event.data).map_err(|e| {
HandleError::Client(format!("serialize event data: {e}"))
})?;
let chain_id = params.chain_id;

session_request_tx
.send((
sub_msg.data.topic.clone(),
IncomingSessionMessage::SessionEvent(
0, // TODO
sub_msg.data.topic,
false, // TODO
name,
data_str,
chain_id,
),
))
.map_err(|e| {
Expand Down
23 changes: 23 additions & 0 deletions crates/yttrium/src/sign/protocol_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,26 @@ pub struct SessionExtendJsonRpc {
pub method: String,
pub params: SessionExtend,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SessionEventVO {
pub name: String,
pub data: serde_json::Value,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct EventParams {
pub event: SessionEventVO,
pub chain_id: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SessionEventJsonRpc {
pub id: u64,
pub jsonrpc: String,
pub method: String,
pub params: EventParams,
}
2 changes: 1 addition & 1 deletion crates/yttrium/src/sign/relay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ enum ConnectionState {
pub enum IncomingSessionMessage {
SessionRequest(SessionRequestJsonRpc),
Disconnect(u64, Topic),
SessionEvent(u64, Topic, bool),
SessionEvent(Topic, String, String, String),
SessionUpdate(u64, Topic, crate::sign::protocol_types::SettleNamespaces),
SessionExtend(u64, Topic),
SessionConnect(u64, Topic),
Expand Down
40 changes: 32 additions & 8 deletions crates/yttrium/src/uniffi_compat/sign/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use {
sign::{
client::{generate_client_id_key, Client},
client_errors::{
ApproveError, ConnectError, DisconnectError, ExtendError,
PairError, RejectError, RequestError, RespondError,
UpdateError,
ApproveError, ConnectError, DisconnectError, EmitError,
ExtendError, PairError, RejectError, RequestError,
RespondError, UpdateError,
},
client_types::{ConnectParams, SessionProposal},
protocol_types::{Metadata, SessionRequest, SettleNamespace},
Expand Down Expand Up @@ -33,7 +33,13 @@ pub trait SignListener: Send + Sync {
);

fn on_session_disconnect(&self, id: u64, topic: String);
fn on_session_event(&self, id: u64, topic: String, params: bool);
fn on_session_event(
&self,
topic: String,
name: String,
data: String,
chain_id: String,
);
fn on_session_extend(&self, id: u64, topic: String);
fn on_session_update(
&self,
Expand Down Expand Up @@ -121,14 +127,16 @@ impl SignClient {
.on_session_disconnect(id, topic.to_string());
}
IncomingSessionMessage::SessionEvent(
id,
topic,
params,
name,
data,
chain_id,
) => {
listener.on_session_event(
id,
topic.to_string(),
params,
name,
data,
chain_id,
);
}
IncomingSessionMessage::SessionUpdate(
Expand Down Expand Up @@ -249,6 +257,22 @@ impl SignClient {
Ok(topic)
}

pub async fn emit(
&self,
topic: String,
name: String,
data: String,
chain_id: String,
) -> Result<(), EmitError> {
let mut client = self.client.lock().await;
let data_value = match serde_json::from_str::<serde_json::Value>(&data)
{
Ok(v) => v,
Err(_) => serde_json::Value::String(data.clone()),
};
client.emit(topic.into(), name, data_value, chain_id).await
}

pub async fn disconnect(
&self,
topic: String,
Expand Down
Loading