diff --git a/ironfish-rust-wasm/src/lib.rs b/ironfish-rust-wasm/src/lib.rs index 95d627b928..0b0b5433e0 100644 --- a/ironfish-rust-wasm/src/lib.rs +++ b/ironfish-rust-wasm/src/lib.rs @@ -22,6 +22,7 @@ pub mod merkle_note; pub mod note; pub mod primitives; pub mod transaction; +pub mod witness; /// Creates a [`wasm_bindgen`] wrapper for an existing type. /// diff --git a/ironfish-rust-wasm/src/witness.rs b/ironfish-rust-wasm/src/witness.rs new file mode 100644 index 0000000000..a02859ded1 --- /dev/null +++ b/ironfish-rust-wasm/src/witness.rs @@ -0,0 +1,90 @@ +/* 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::{merkle_note::MerkleNoteHash, primitives::Scalar, wasm_bindgen_wrapper}; +use ironfish::witness::WitnessTrait; +use wasm_bindgen::prelude::*; + +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Witness(ironfish::witness::Witness); +} + +#[wasm_bindgen] +impl Witness { + #[wasm_bindgen(constructor)] + pub fn new(tree_size: usize, root_hash: Scalar, auth_path: Vec) -> Self { + Self(ironfish::witness::Witness { + tree_size, + root_hash: root_hash.into(), + auth_path: auth_path.into_iter().map(WitnessNode::into).collect(), + }) + } + + #[wasm_bindgen(getter)] + pub fn tree_size(&self) -> usize { + self.0.tree_size + } + + #[wasm_bindgen(getter)] + pub fn root_hash(&self) -> Scalar { + self.0.root_hash.into() + } + + #[wasm_bindgen(getter)] + pub fn auth_path(&self) -> Vec { + self.0 + .auth_path + .iter() + .cloned() + .map(WitnessNode::from) + .collect() + } + + #[wasm_bindgen] + pub fn verify(&self, hash: &MerkleNoteHash) -> bool { + self.0.verify(hash.as_ref()) + } +} + +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct WitnessNode(ironfish::witness::WitnessNode); +} + +#[wasm_bindgen] +impl WitnessNode { + #[wasm_bindgen] + pub fn left(hash: Scalar) -> Self { + Self(ironfish::witness::WitnessNode::Left(hash.into())) + } + + #[wasm_bindgen] + pub fn right(hash: Scalar) -> Self { + Self(ironfish::witness::WitnessNode::Right(hash.into())) + } + + #[wasm_bindgen(getter)] + pub fn is_left(&self) -> bool { + match self.0 { + ironfish::witness::WitnessNode::Left(_) => true, + ironfish::witness::WitnessNode::Right(_) => false, + } + } + + #[wasm_bindgen(getter)] + pub fn is_right(&self) -> bool { + !self.is_left() + } + + #[wasm_bindgen(getter)] + pub fn hash(&self) -> Scalar { + match self.0 { + ironfish::witness::WitnessNode::Left(ref hash) => hash, + ironfish::witness::WitnessNode::Right(ref hash) => hash, + } + .to_owned() + .into() + } +} diff --git a/ironfish-rust/src/witness.rs b/ironfish-rust/src/witness.rs index 06445337e1..2d6a99245c 100644 --- a/ironfish-rust/src/witness.rs +++ b/ironfish-rust/src/witness.rs @@ -35,21 +35,13 @@ pub trait WitnessTrait { /// A Rust implementation of a WitnessTrait, used for testing Witness-related /// code within Rust. +#[derive(Clone, PartialEq, Eq)] pub struct Witness { pub tree_size: usize, pub root_hash: Scalar, pub auth_path: Vec>, } -/// Implement partial equality, ignoring the Sapling Arc -impl PartialEq for Witness { - fn eq(&self, other: &Witness) -> bool { - self.tree_size == other.tree_size - && self.root_hash == other.root_hash - && self.auth_path == other.auth_path - } -} - impl WitnessTrait for Witness { fn verify(&self, my_hash: &MerkleNoteHash) -> bool { let mut cur_hash = my_hash.0;