Skip to content

Commit

Permalink
WASM: expose the MerkleNote and MerkleNoteHash types
Browse files Browse the repository at this point in the history
  • Loading branch information
andiflabs committed Nov 14, 2024
1 parent c18f4d4 commit f21ef0e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions ironfish-rust-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use getrandom as _;

pub mod errors;
pub mod keys;
pub mod merkle_note;
pub mod primitives;

#[cfg(test)]
Expand Down
118 changes: 118 additions & 0 deletions ironfish-rust-wasm/src/merkle_note.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::{errors::IronfishError, primitives::Scalar};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct MerkleNote(ironfish::MerkleNote);

#[wasm_bindgen]
impl MerkleNote {
#[wasm_bindgen(constructor)]
pub fn deserialize(bytes: &[u8]) -> Result<MerkleNote, IronfishError> {
Ok(Self(ironfish::MerkleNote::read(bytes)?))
}

#[wasm_bindgen]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = Vec::new();
self.0
.write(&mut buf)
.expect("failed to serialize merkle note");
buf
}

#[wasm_bindgen(getter, js_name = merkleHash)]
pub fn merkle_hash(&self) -> MerkleNoteHash {
self.0.merkle_hash().into()
}
}

impl From<ironfish::MerkleNote> for MerkleNote {
fn from(d: ironfish::MerkleNote) -> Self {
Self(d)
}
}

impl AsRef<ironfish::MerkleNote> for MerkleNote {
fn as_ref(&self) -> &ironfish::MerkleNote {
&self.0
}
}

#[wasm_bindgen]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct MerkleNoteHash(ironfish::MerkleNoteHash);

#[wasm_bindgen]
impl MerkleNoteHash {
#[wasm_bindgen(constructor)]
pub fn deserialize(bytes: &[u8]) -> Result<MerkleNoteHash, IronfishError> {
Ok(Self(ironfish::MerkleNoteHash::read(bytes)?))
}

#[wasm_bindgen]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = Vec::new();
self.0
.write(&mut buf)
.expect("failed to serialize merkle note hash");
buf
}

#[wasm_bindgen(js_name = fromValue)]
pub fn from_value(value: Scalar) -> Self {
ironfish::MerkleNoteHash(value.as_ref().to_owned()).into()
}

#[wasm_bindgen(getter)]
pub fn value(&self) -> Scalar {
self.0 .0.into()
}

#[wasm_bindgen(js_name = combineHash)]
pub fn combine_hash(depth: usize, left: &Self, right: &Self) -> Self {
let hash = ironfish::MerkleNoteHash::combine_hash(depth, &left.0 .0, &right.0 .0);
ironfish::MerkleNoteHash(hash).into()
}
}

impl From<ironfish::MerkleNoteHash> for MerkleNoteHash {
fn from(d: ironfish::MerkleNoteHash) -> Self {
Self(d)
}
}

impl AsRef<ironfish::MerkleNoteHash> for MerkleNoteHash {
fn as_ref(&self) -> &ironfish::MerkleNoteHash {
&self.0
}
}

#[cfg(test)]
mod tests {
use crate::merkle_note::MerkleNoteHash;
use hex_literal::hex;
use wasm_bindgen_test::wasm_bindgen_test;

#[test]
#[wasm_bindgen_test]
fn combine_hash() {
let a = MerkleNoteHash::deserialize(
hex!("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00").as_slice(),
)
.unwrap();
let b = MerkleNoteHash::deserialize(
hex!("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb00").as_slice(),
)
.unwrap();
let c = MerkleNoteHash::combine_hash(10, &a, &b);
assert_eq!(
c.serialize(),
hex!("65fa868a24f39bead19143c23b7c37c6966bec5cf5e60269cb7964d407fe3d47")
);
}
}
2 changes: 2 additions & 0 deletions ironfish-rust/src/merkle_note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ impl PartialEq for MerkleNote {
}
}

impl Eq for MerkleNote {}

impl MerkleNote {
pub fn new(
outgoing_view_key: &OutgoingViewKey,
Expand Down

0 comments on commit f21ef0e

Please sign in to comment.