Add utilities to handle text and binary payloads for mixnet messages

This commit is contained in:
Mark Sinclair
2022-11-07 16:11:13 +00:00
parent bf1d2a12bc
commit 43ef098aad
3 changed files with 101 additions and 7 deletions
@@ -0,0 +1,83 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use serde::{Serialize, Deserialize};
#[wasm_bindgen(typescript_custom_section)]
const TS_DEFS: &'static str = r#"
export interface BinaryMessage {
kind: number,
payload: Uint8Array;
}
export interface StringMessage {
kind: number,
payload: string;
}
"#;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "BinaryMessage")]
pub type IBinaryMessage;
#[wasm_bindgen(typescript_type = "StringMessage")]
pub type IStringMessage;
}
#[derive(Serialize, Deserialize)]
pub struct BinaryMessage {
pub kind: u8,
pub payload: Vec<u8>,
}
#[derive(Serialize, Deserialize)]
pub struct StringMessage {
pub kind: u8,
pub payload: String,
}
/// Create a new binary message with a user-specified `kind`.
#[wasm_bindgen]
pub fn create_binary_message(kind: u8, payload: Vec<u8>) -> Vec<u8> {
vec![vec![kind], payload].concat()
}
/// Create a new message with a UTF-8 encoded string `payload` and a user-specified `kind`.
#[wasm_bindgen]
pub fn create_binary_message_from_string(kind: u8, payload: String) -> Vec<u8> {
vec!(vec![kind], payload.into_bytes()).concat()
}
/// Parse the `kind` and byte array `payload` from a byte array
#[wasm_bindgen]
pub async fn parse_binary_message(message: Vec<u8>) -> Result<IBinaryMessage, JsError> {
if message.len() < 2 {
return Err(JsError::new("Could not parse message, as less than 2 bytes long"));
}
let kind = message[0];
let payload = &message[1..];
Ok(serde_wasm_bindgen::to_value(&BinaryMessage {
kind,
payload: payload.to_vec(),
}).unwrap().unchecked_into::<IBinaryMessage>())
}
/// Parse the `kind` and UTF-8 string `payload` from a byte array
#[wasm_bindgen]
pub async fn parse_string_message(message: Vec<u8>) -> Result<IStringMessage, JsError> {
if message.len() < 2 {
return Err(JsError::new("Could not parse message, as less than 2 bytes long"));
}
let kind = message[0];
let payload = String::from_utf8_lossy(&message[1..]).into_owned();
Ok(serde_wasm_bindgen::to_value(&StringMessage {
kind,
payload,
}).unwrap().unchecked_into::<IStringMessage>())
}
+16 -7
View File
@@ -26,7 +26,7 @@ use nymsphinx::params::PacketSize;
use rand::rngs::OsRng;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::spawn_local;
use wasm_utils::{console_log, console_warn};
use wasm_utils::console_log;
pub mod config;
@@ -45,6 +45,7 @@ pub struct NymClient {
// callbacks
on_message: Option<js_sys::Function>,
on_binary_message: Option<js_sys::Function>,
on_gateway_connect: Option<js_sys::Function>,
}
@@ -56,6 +57,7 @@ impl NymClient {
config,
key_manager: Self::setup_key_manager(),
on_message: None,
on_binary_message: None,
on_gateway_connect: None,
input_tx: None,
}
@@ -73,8 +75,11 @@ impl NymClient {
self.on_message = Some(on_message);
}
pub fn set_on_binary_message(&mut self, on_binary_message: js_sys::Function) {
self.on_binary_message = Some(on_binary_message);
}
pub fn set_on_gateway_connect(&mut self, on_connect: js_sys::Function) {
console_log!("setting on connect...");
self.on_gateway_connect = Some(on_connect)
}
@@ -267,6 +272,7 @@ impl NymClient {
received_buffer_request_sender: ReceivedBufferRequestSender,
) {
let on_message = self.on_message.take();
let on_binary_message = self.on_binary_message.take();
spawn_local(async move {
let (reconstructed_sender, mut reconstructed_receiver) = mpsc::unbounded();
@@ -281,8 +287,14 @@ impl NymClient {
let this = JsValue::null();
while let Some(reconstructed) = reconstructed_receiver.next().await {
if let Some(ref callback) = on_message {
for msg in reconstructed {
for msg in reconstructed {
if let Some(ref callback_binary) = on_binary_message {
let arg1 = serde_wasm_bindgen::to_value(&msg.message).unwrap();
callback_binary
.call1(&this, &arg1)
.expect("on binary message failed!");
}
if let Some(ref callback) = on_message {
if msg.reply_surb.is_some() {
console_log!("the received message contained a reply-surb that we do not know how to handle (yet)")
}
@@ -290,9 +302,6 @@ impl NymClient {
let arg1 = serde_wasm_bindgen::to_value(&stringified).unwrap();
callback.call1(&this, &arg1).expect("on message failed!");
}
} else {
console_warn!("no on_message callback was specified. the received message content is getting dropped");
console_log!("the raw messages: {:?}", reconstructed)
}
}
});
+2
View File
@@ -3,6 +3,8 @@
use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
pub mod binary_message_helper;
#[cfg(target_arch = "wasm32")]
mod client;
#[cfg(target_arch = "wasm32")]