Skip to content

Commit

Permalink
save dev state - walletconnect client impl
Browse files Browse the repository at this point in the history
  • Loading branch information
borngraced committed Sep 9, 2024
1 parent 9100780 commit ca3f558
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 10 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions mm2src/kdf_walletconnect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
# chacha20poly1305 = "0.10"
common = { path = "../common" }
derive_more = "0.99"
futures = { version = "0.3", package = "futures", features = [
"compat",
"async-await",
Expand All @@ -21,4 +22,7 @@ relay_client = { path = "../../../kdf-wc/relay_client" }
relay_rpc = { path = "../../../kdf-wc/relay_rpc" }
sha2 = "0.10.8"
thiserror = "1.0.40"
wc_common = { path = "../../../kdf-wc/wc_common" }
x25519-dalek = { version = "2.0", features = ["static_secrets"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order", "raw_value"] }
25 changes: 25 additions & 0 deletions mm2src/kdf_walletconnect/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use derive_more::Display;
use pairing_api::PairingClientError;
use relay_client::error::{ClientError, Error};
use relay_rpc::rpc::PublishError;

#[derive(Debug, Display)]
pub enum WalletConnectClientError {
PairingError(PairingClientError),
EncodeError(String),
PublishError(Error<PublishError>),
ClientError(ClientError),
PairingNotFound(String)
}

impl From<PairingClientError> for WalletConnectClientError {
fn from(value: PairingClientError) -> Self {
WalletConnectClientError::PairingError(value)
}
}

impl From<ClientError> for WalletConnectClientError {
fn from(value: ClientError) -> Self {
WalletConnectClientError::ClientError(value)
}
}
123 changes: 113 additions & 10 deletions mm2src/kdf_walletconnect/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
use std::{collections::HashMap, sync::Arc};
use std::{collections::HashMap, sync::Arc, time::Duration};

use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex};
use error::WalletConnectClientError;
use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, StreamExt};
use handler::Handler;
use mm2_err_handle::prelude::MmResult;
use pairing_api::PairingClient;
use relay_client::{error::ClientError, websocket::{Client, PublishedMessage}, ConnectionOptions};
use relay_rpc::domain::{SubscriptionId, Topic};
use pairing_api::{Methods, PairingClient};
use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator};
use relay_rpc::{domain::{MessageId, SubscriptionId, Topic}, rpc::{params::{IrnMetadata, Metadata}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}};
use session_key::SessionKey;
use mm2_err_handle::prelude::*;
use wc_common::{encrypt_and_encode, EnvelopeType};
use common::log::info;


mod session_key;
mod handler;
mod error;

pub const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com";
pub const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b";
Expand Down Expand Up @@ -39,22 +44,120 @@ impl Default for WalletConnectClient {

impl WalletConnectClient {
pub fn new() -> Self {
let (sender, receiver) = unbounded();
let (msg_sender, msg_receiver) = unbounded();

let pairing = PairingClient::new();
let client = Arc::new(Client::new(Handler::new("Komodefi", sender)));
let client = Arc::new(Client::new(Handler::new("Komodefi", msg_sender)));

Self {
client,
pairing,
sessions: HashMap::new(),
handler: Arc::new(Mutex::new(receiver))
handler: Arc::new(Mutex::new(msg_receiver))
}
}

pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), ClientError>{
self.client.connect(opts).await.map_to_mm(|err|err)
pub async fn create_pairing(&self, metadata: Metadata, methods: Option<Methods>) -> MmResult<(Topic, String), WalletConnectClientError> {
Ok(self.pairing.create(metadata, methods, &self.client).await?)
}

pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult<Topic, WalletConnectClientError> {
Ok(self.pairing.pair(url, activate, &self.client).await?)
}

pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), WalletConnectClientError> {
Ok(self.client.connect(opts).await?)
}


/// Private function to publish a request.
async fn publish_request(
&self,
topic: &str,
params: Params,
irn_metadata: IrnMetadata
) -> MmResult<(), WalletConnectClientError> {
let message_id = MessageIdGenerator::new().next();
let request = Request::new(message_id, params);
// Publish the encrypted message
self.publish_payload(topic, irn_metadata, Payload::Request(request))
.await?;

info!("Otbound request sent!\n");

Ok(())
}

/// Private function to publish a request response.
async fn publish_response(
&self,
topic: &str,
params: Params,
irn_metadata: IrnMetadata,
message_id: MessageId,
) -> MmResult<(), WalletConnectClientError> {
let response = Response::Success(SuccessfulResponse {
id: message_id,
jsonrpc: JSON_RPC_VERSION_STR.into(),
result: serde_json::to_value(params)
.map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?,
});

// Publish the encrypted message
self.publish_payload(topic, irn_metadata, Payload::Response(response))
.await?;

println!("\nOutbound request sent!");

Ok(())
}


/// Private function to publish a payload.
async fn publish_payload(
&self,
topic: &str,
irn_metadata: IrnMetadata,
payload: Payload,
) -> MmResult<(), WalletConnectClientError> {
// try to extend session before updating local store.
let sym_key = {
let pairings = self.pairing.pairings.lock().await;
let pairing = pairings
.get(topic)
.ok_or_else(|| WalletConnectClientError::PairingNotFound(format!("Pariring not found for topic:{topic}")))?;
hex::decode(pairing.sym_key.clone()).map_to_mm(|err| {
WalletConnectClientError::EncodeError(format!("Failed to decode sym_key: {:?}", err))
})?
};

let payload = serde_json::to_string(&payload)
.map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?;
let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)
.map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?;

// Publish the encrypted message
{
self.client
.publish(
topic.into(),
message,
None,
irn_metadata.tag,
Duration::from_secs(irn_metadata.ttl),
irn_metadata.prompt,
)
.await
.map_to_mm(WalletConnectClientError::PublishError)?;
};

Ok(())
}
}

pub async fn published_message_event_loop(client: Arc<WalletConnectClient>) {
let mut recv = client.handler.lock().await;
while let Some(data) = recv.next().await {
todo!()
}
}

0 comments on commit ca3f558

Please sign in to comment.