From 53abc1464b2eb5af1e760728199ba152a017d460 Mon Sep 17 00:00:00 2001 From: andrea Date: Tue, 12 Nov 2024 17:31:45 -0800 Subject: [PATCH] WASM: add bindings for `PublicAddress` --- ironfish-rust-wasm/Cargo.toml | 3 + ironfish-rust-wasm/src/keys/mod.rs | 1 + ironfish-rust-wasm/src/keys/public_address.rs | 67 +++++++++++++++++++ ironfish-rust-wasm/src/lib.rs | 1 + ironfish-rust/src/keys/public_address.rs | 6 +- 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 ironfish-rust-wasm/src/keys/mod.rs create mode 100644 ironfish-rust-wasm/src/keys/public_address.rs diff --git a/ironfish-rust-wasm/Cargo.toml b/ironfish-rust-wasm/Cargo.toml index edbf84a64a..f1ed075051 100644 --- a/ironfish-rust-wasm/Cargo.toml +++ b/ironfish-rust-wasm/Cargo.toml @@ -22,3 +22,6 @@ ironfish-jubjub = "0.1.0" ironfish_zkp = { version = "0.2.0", path = "../ironfish-zkp" } rand = "0.8.5" wasm-bindgen = "0.2.95" + +[dev-dependencies] +hex-literal = "0.4.1" diff --git a/ironfish-rust-wasm/src/keys/mod.rs b/ironfish-rust-wasm/src/keys/mod.rs new file mode 100644 index 0000000000..0a5e039be6 --- /dev/null +++ b/ironfish-rust-wasm/src/keys/mod.rs @@ -0,0 +1 @@ +pub mod public_address; diff --git a/ironfish-rust-wasm/src/keys/public_address.rs b/ironfish-rust-wasm/src/keys/public_address.rs new file mode 100644 index 0000000000..7cf6f7377a --- /dev/null +++ b/ironfish-rust-wasm/src/keys/public_address.rs @@ -0,0 +1,67 @@ +use crate::errors::IronfishError; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct PublicAddress(ironfish::PublicAddress); + +#[wasm_bindgen] +impl PublicAddress { + #[wasm_bindgen(constructor)] + pub fn deserialize(bytes: &[u8]) -> Result { + Ok(Self(ironfish::PublicAddress::read(bytes)?)) + } + + #[wasm_bindgen] + pub fn serialize(&self) -> Vec { + self.0.public_address().to_vec() + } + + #[wasm_bindgen(getter)] + pub fn bytes(&self) -> Vec { + self.0.public_address().to_vec() + } + + #[wasm_bindgen(getter)] + pub fn hex(&self) -> String { + self.0.hex_public_address() + } +} + +impl From for PublicAddress { + fn from(d: ironfish::PublicAddress) -> Self { + Self(d) + } +} + +impl AsRef for PublicAddress { + fn as_ref(&self) -> &ironfish::PublicAddress { + &self.0 + } +} + +#[cfg(test)] +mod tests { + use crate::keys::public_address::PublicAddress; + use hex_literal::hex; + + #[test] + fn valid_address() { + let bytes = hex!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0"); + let addr = PublicAddress::deserialize(&bytes[..]) + .expect("valid address deserialization should have succeeded"); + assert_eq!(addr.serialize(), bytes); + assert_eq!(addr.bytes(), bytes); + assert_eq!( + addr.hex(), + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0" + ); + } + + #[test] + fn invalid_address() { + let bytes = hex!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1"); + PublicAddress::deserialize(&bytes[..]) + .expect_err("invalid address deserialization should have failed"); + } +} diff --git a/ironfish-rust-wasm/src/lib.rs b/ironfish-rust-wasm/src/lib.rs index 3815e3640c..a82cbdb4c3 100644 --- a/ironfish-rust-wasm/src/lib.rs +++ b/ironfish-rust-wasm/src/lib.rs @@ -10,4 +10,5 @@ use getrandom as _; pub mod errors; +pub mod keys; pub mod primitives; diff --git a/ironfish-rust/src/keys/public_address.rs b/ironfish-rust/src/keys/public_address.rs index b2b9285af2..e38f574365 100644 --- a/ironfish-rust/src/keys/public_address.rs +++ b/ironfish-rust/src/keys/public_address.rs @@ -38,13 +38,13 @@ impl PublicAddress { } /// Load a public address from a Read implementation (e.g: socket, file) - pub fn read(reader: &mut R) -> Result { + pub fn read(mut reader: R) -> Result { let mut address_bytes = [0; PUBLIC_ADDRESS_SIZE]; reader.read_exact(&mut address_bytes)?; Self::new(&address_bytes) } - pub fn read_unchecked(reader: &mut R) -> Result { + pub fn read_unchecked(mut reader: R) -> Result { let mut address_bytes = [0; PUBLIC_ADDRESS_SIZE]; reader.read_exact(&mut address_bytes)?; Self::new_unchecked(&address_bytes) @@ -100,6 +100,8 @@ impl PartialEq for PublicAddress { } } +impl Eq for PublicAddress {} + #[cfg(test)] mod test { use crate::{