#![deny(missing_docs)]
mod client;
mod error;
mod event_loop;
mod transport;
pub(crate) use client::{client_impl, client_transport_impl};
pub use event_loop::{Event, EventStream, JsonMessage};
pub use transport::{NetworkTransport, Transport};
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
mod native;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
pub use native::{
NativeClient as Client, NativeEventLoop as EventLoop,
};
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
mod web;
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
pub use web::{WebClient as Client, WebEventLoop as EventLoop};
use mpc_protocol::{
hex, Encoding, Keypair, OpaqueMessage, ProtocolState,
RequestMessage, SealedEnvelope, SessionId, TAGLEN,
};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;
pub(crate) type Peers = Arc<RwLock<HashMap<Vec<u8>, ProtocolState>>>;
pub(crate) type Server = Arc<RwLock<Option<ProtocolState>>>;
pub struct ClientOptions {
pub keypair: Keypair,
pub server_public_key: Vec<u8>,
}
impl ClientOptions {
pub fn url(&self, server: &str) -> String {
let server = server.trim_end_matches('/');
format!(
"{}/?public_key={}",
server,
hex::encode(self.keypair.public_key())
)
}
}
pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
async fn encrypt_peer_channel(
public_key: impl AsRef<[u8]>,
peer: &mut ProtocolState,
payload: &[u8],
encoding: Encoding,
broadcast: bool,
session_id: Option<SessionId>,
) -> Result<RequestMessage> {
match peer {
ProtocolState::Transport(transport) => {
let mut contents = vec![0; payload.len() + TAGLEN];
let length =
transport.write_message(payload, &mut contents)?;
let envelope = SealedEnvelope {
length,
encoding,
payload: contents,
broadcast,
};
let request =
RequestMessage::Opaque(OpaqueMessage::PeerMessage {
public_key: public_key.as_ref().to_vec(),
session_id,
envelope,
});
Ok(request)
}
_ => Err(Error::NotTransportState),
}
}
async fn decrypt_peer_channel(
peer: &mut ProtocolState,
envelope: &SealedEnvelope,
) -> Result<Vec<u8>> {
match peer {
ProtocolState::Transport(transport) => {
let mut contents = vec![0; envelope.length];
transport.read_message(
&envelope.payload[..envelope.length],
&mut contents,
)?;
let new_length = contents.len() - TAGLEN;
contents.truncate(new_length);
Ok(contents)
}
_ => Err(Error::NotTransportState),
}
}