Skip to content

Commit

Permalink
implement sqlite session storage table and insert session method
Browse files Browse the repository at this point in the history
  • Loading branch information
borngraced committed Sep 24, 2024
1 parent 3a85a17 commit be98c40
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 25 deletions.
4 changes: 4 additions & 0 deletions mm2src/db_common/src/async_sql_conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ impl std::error::Error for AsyncConnError {
}
}

impl From<String> for AsyncConnError {
fn from(err: String) -> Self { Self::Internal(InternalError(err)) }
}

#[derive(Debug)]
pub struct InternalError(pub String);

Expand Down
8 changes: 2 additions & 6 deletions mm2src/kdf_walletconnect/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,11 @@ pub enum WalletConnectCtxError {
}

impl From<Error<PublishError>> for WalletConnectCtxError {
fn from(error: Error<PublishError>) -> Self {
WalletConnectCtxError::PublishError(format!("{error:?}"))
}
fn from(error: Error<PublishError>) -> Self { WalletConnectCtxError::PublishError(format!("{error:?}")) }
}

impl From<Error<SubscriptionError>> for WalletConnectCtxError {
fn from(error: Error<SubscriptionError>) -> Self {
WalletConnectCtxError::SubscriptionError(format!("{error:?}"))
}
fn from(error: Error<SubscriptionError>) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) }
}

/// Session key and topic derivation errors.
Expand Down
9 changes: 9 additions & 0 deletions mm2src/kdf_walletconnect/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ pub enum SessionType {
Proposer,
}

impl ToString for SessionType {
fn to_string(&self) -> String {
match self {
Self::Controller => "Controller".to_string(),
Self::Proposer => "Proposer".to_string(),
}
}
}

/// This struct is typically used in the core session management logic of a WalletConnect
/// implementation. It's used to store, retrieve, and update session information throughout
/// the lifecycle of a WalletConnect connection.
Expand Down
22 changes: 10 additions & 12 deletions mm2src/kdf_walletconnect/src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use async_trait::async_trait;
use mm2_err_handle::prelude::MmResult;
use mm2_err_handle::prelude::*;
use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces};

use crate::session::Session;
Expand All @@ -9,18 +10,15 @@ pub(crate) mod wasm;

pub(crate) const SESSION_STORAGE_TABLE_NAME: &str = "kdf_wc_session_storage";

#[derive(Debug, thiserror::Error)]
pub(crate) enum WalletConnectStorageError {
#[error("Table Error: {0}")]
TableError(String),
}

#[async_trait]
pub(crate) trait WalletConnectStorageOps {
fn init(&self) -> MmResult<(), WalletConnectStorageError>;
fn save_session(&self, session: &Session) -> MmResult<(), WalletConnectStorageError>;
fn get_all_sessions(&self) -> MmResult<Vec<Session>, WalletConnectStorageError>;
fn delete_session(&self, topic: &Topic) -> MmResult<(), WalletConnectStorageError>;
fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), WalletConnectStorageError>;
fn update_expiry(&self, expiry: u64) -> MmResult<(), WalletConnectStorageError>;
type Error: std::fmt::Debug + NotMmError + NotEqual + Send;

async fn init(&self) -> MmResult<(), Self::Error>;
async fn is_initialized(&self) -> MmResult<bool, Self::Error>;
async fn save_session(&self, session: Session) -> MmResult<(), Self::Error>;
async fn get_sessions(&self) -> MmResult<Vec<Session>, Self::Error>;
async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error>;
async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error>;
async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error>;
}
125 changes: 118 additions & 7 deletions mm2src/kdf_walletconnect/src/storage/sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,121 @@
use db_common::sqlite::validate_table_name;
use mm2_err_handle::prelude::MmResult;
use async_trait::async_trait;
use db_common::sqlite::rusqlite::{Connection, Result as SqlResult};
use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL};
use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection},
sqlite::validate_table_name};
use futures::lock::{Mutex, MutexGuard};
use mm2_err_handle::prelude::*;
use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces};
use std::sync::Arc;

use super::{WalletConnectStorageError, SESSION_STORAGE_TABLE_NAME};
use super::WalletConnectStorageOps;
use crate::session::Session;

fn validate_sql_table_name() -> MmResult<String, WalletConnectStorageError> {
validate_table_name(SESSION_STORAGE_TABLE_NAME)
.map_err(|err| WalletConnectStorageError::TableError(err.to_string()))?;
Ok(SESSION_STORAGE_TABLE_NAME.to_owned())
const SESSION_TBALE_NAME: &str = "session";

/// Sessions table
fn create_sessions_table() -> SqlResult<String> {
validate_table_name(SESSION_TBALE_NAME)?;
Ok(format!(
"CREATE TABLE IF NOT EXISTS {SESSION_TBALE_NAME} (
topic VARCHAR(255) PRIMARY KEY,
subscription_id VARCHAR(255) NOT NULL,
session_key TEXT NOT NULL,
expiry BIGINT NOT NULL,
pairing_topic VARCHAR(255) NOT NULL,
session_type VARCHAR(50) NOT NULL,
proposer TEXT NOT NULL,
controller TEXT NOT NULL,
relay TEXT NOT NULL,
namespaces TEXT,
proposed_namespace TEXT
);"
))
}

#[derive(Clone, Debug)]
pub struct SqliteSessionStorage {
pub conn: Arc<Mutex<Connection>>,
}

#[async_trait]
impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> {
type Error = AsyncConnError;

async fn init(&self) -> MmResult<(), Self::Error> {
self.call(move |conn| {
conn.execute(&create_sessions_table()?, []).map(|_| ())?;
Ok(())
})
.await
.map_to_mm(AsyncConnError::from)
}

async fn is_initialized(&self) -> MmResult<bool, Self::Error> {
validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?;
self.call(move |conn| {
let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TBALE_NAME], string_from_row)?;
Ok(initialized.is_some())
})
.await
.map_to_mm(AsyncConnError::from)
}

async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> {
validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?;
let sql = format!(
"INSERT INTO {} (
topic, subscription_id, session_key, expiry, pairing_topic, session_type, proposer, controller, relay, namespace, propose_namespaces
) VALUES (
?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11
);",
SESSION_TBALE_NAME
);

self.call(move |conn| {
let transaction = conn.transaction()?;

let session_key =
serde_json::to_string(&session.session_key).map_err(|err| AsyncConnError::from(err.to_string()))?;
let relay = serde_json::to_string(&session.relay).map_err(|err| AsyncConnError::from(err.to_string()))?;
let proposer =
serde_json::to_string(&session.proposer).map_err(|err| AsyncConnError::from(err.to_string()))?;
let controller =
serde_json::to_string(&session.controller).map_err(|err| AsyncConnError::from(err.to_string()))?;
let namespaces =
serde_json::to_string(&session.namespaces).map_err(|err| AsyncConnError::from(err.to_string()))?;
let propose_namespaces = serde_json::to_string(&session.propose_namespaces)
.map_err(|err| AsyncConnError::from(err.to_string()))?;

let params = [
session.topic.to_string(),
session.subscription_id.to_string(),
session_key,
session.expiry.to_string(),
session.pairing_topic.to_string(),
session.session_type.to_string(),
proposer,
controller,
relay,
namespaces,
propose_namespaces,
];
transaction.execute(&sql, params)?;
transaction.commit()?;

Ok(())
})
.await
.map_to_mm(AsyncConnError::from)
}

async fn get_sessions(&self) -> MmResult<Vec<Session>, Self::Error> { todo!() }

async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error> { todo!() }

async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() }

async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error> {
todo!()
}
}
1 change: 1 addition & 0 deletions mm2src/kdf_walletconnect/src/storage/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit be98c40

Please sign in to comment.