diff --git a/ironfish-rust-wasm/src/lib.rs b/ironfish-rust-wasm/src/lib.rs index d92f15465a..3048349c14 100644 --- a/ironfish-rust-wasm/src/lib.rs +++ b/ironfish-rust-wasm/src/lib.rs @@ -18,6 +18,7 @@ pub mod errors; pub mod keys; pub mod merkle_note; pub mod primitives; +pub mod transaction; #[cfg(test)] mod tests { diff --git a/ironfish-rust-wasm/src/transaction/burns.rs b/ironfish-rust-wasm/src/transaction/burns.rs new file mode 100644 index 0000000000..7224e4b9db --- /dev/null +++ b/ironfish-rust-wasm/src/transaction/burns.rs @@ -0,0 +1,51 @@ +/* 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::{assets::AssetIdentifier, errors::IronfishError}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct BurnDescription(ironfish::transaction::burns::BurnDescription); + +#[wasm_bindgen] +impl BurnDescription { + #[wasm_bindgen(constructor)] + pub fn deserialize(bytes: &[u8]) -> Result { + Ok(Self(ironfish::transaction::burns::BurnDescription::read( + bytes, + )?)) + } + + #[wasm_bindgen] + pub fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + self.0 + .write(&mut buf) + .expect("failed to serialize mint description"); + buf + } + + #[wasm_bindgen(getter, js_name = assetId)] + pub fn asset_id(&self) -> AssetIdentifier { + self.0.asset_id.into() + } + + #[wasm_bindgen(getter)] + pub fn value(&self) -> u64 { + self.0.value + } +} + +impl From for BurnDescription { + fn from(d: ironfish::transaction::burns::BurnDescription) -> Self { + Self(d) + } +} + +impl AsRef for BurnDescription { + fn as_ref(&self) -> &ironfish::transaction::burns::BurnDescription { + &self.0 + } +} diff --git a/ironfish-rust-wasm/src/transaction/mints.rs b/ironfish-rust-wasm/src/transaction/mints.rs new file mode 100644 index 0000000000..d9975c3555 --- /dev/null +++ b/ironfish-rust-wasm/src/transaction/mints.rs @@ -0,0 +1,91 @@ +/* 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::{ + assets::Asset, + errors::IronfishError, + keys::PublicAddress, + primitives::{PublicKey, Scalar}, +}; +use ironfish::{errors::IronfishErrorKind, transaction::TransactionVersion}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct MintDescription(ironfish::transaction::mints::MintDescription); + +#[wasm_bindgen] +impl MintDescription { + #[wasm_bindgen(constructor)] + pub fn deserialize(bytes: &[u8]) -> Result { + Ok(Self(ironfish::transaction::mints::MintDescription::read( + bytes, + TransactionVersion::V1, + )?)) + } + + #[wasm_bindgen] + pub fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + self.0 + .write(&mut buf, TransactionVersion::V1) + .expect("failed to serialize mint description"); + buf + } + + #[wasm_bindgen(getter)] + pub fn assets(&self) -> Asset { + self.0.asset.into() + } + + #[wasm_bindgen(getter)] + pub fn value(&self) -> u64 { + self.0.value + } + + #[wasm_bindgen(getter)] + pub fn owner(&self) -> PublicAddress { + self.0.owner.into() + } + + #[wasm_bindgen(js_name = verifySignature)] + pub fn verify_signature( + &self, + signature: &[u8], + randomized_public_key: &PublicKey, + ) -> Result<(), IronfishError> { + let signature = signature + .try_into() + .map_err(|_| IronfishErrorKind::InvalidSignature)?; + self.0 + .verify_signature(signature, randomized_public_key.as_ref()) + .map_err(|e| e.into()) + } + + #[wasm_bindgen(js_name = partialVerify)] + pub fn partial_verify(&self) -> Result<(), IronfishError> { + self.0.partial_verify().map_err(|e| e.into()) + } + + #[wasm_bindgen(js_name = publicInputs)] + pub fn public_inputs(&self, randomized_public_key: &PublicKey) -> Vec { + self.0 + .public_inputs(randomized_public_key.as_ref()) + .into_iter() + .map(Scalar::from) + .collect() + } +} + +impl From for MintDescription { + fn from(d: ironfish::transaction::mints::MintDescription) -> Self { + Self(d) + } +} + +impl AsRef for MintDescription { + fn as_ref(&self) -> &ironfish::transaction::mints::MintDescription { + &self.0 + } +} diff --git a/ironfish-rust-wasm/src/transaction/mod.rs b/ironfish-rust-wasm/src/transaction/mod.rs new file mode 100644 index 0000000000..3d0fd2a72d --- /dev/null +++ b/ironfish-rust-wasm/src/transaction/mod.rs @@ -0,0 +1,13 @@ +/* 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/. */ + +mod burns; +mod mints; +mod outputs; +mod spends; + +pub use burns::BurnDescription; +pub use mints::MintDescription; +pub use outputs::OutputDescription; +pub use spends::SpendDescription; diff --git a/ironfish-rust-wasm/src/transaction/outputs.rs b/ironfish-rust-wasm/src/transaction/outputs.rs new file mode 100644 index 0000000000..5f63b72ad1 --- /dev/null +++ b/ironfish-rust-wasm/src/transaction/outputs.rs @@ -0,0 +1,62 @@ +/* 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, + merkle_note::MerkleNote, + primitives::{PublicKey, Scalar}, +}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Clone, PartialEq, Debug)] +pub struct OutputDescription(ironfish::OutputDescription); + +#[wasm_bindgen] +impl OutputDescription { + #[wasm_bindgen(constructor)] + pub fn deserialize(bytes: &[u8]) -> Result { + Ok(Self(ironfish::OutputDescription::read(bytes)?)) + } + + #[wasm_bindgen] + pub fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + self.0 + .write(&mut buf) + .expect("failed to serialize output description"); + buf + } + + #[wasm_bindgen(js_name = partialVerify)] + pub fn partial_verify(&self) -> Result<(), IronfishError> { + self.0.partial_verify().map_err(|e| e.into()) + } + + #[wasm_bindgen(js_name = publicInputs)] + pub fn public_inputs(&self, randomized_public_key: &PublicKey) -> Vec { + self.0 + .public_inputs(randomized_public_key.as_ref()) + .into_iter() + .map(Scalar::from) + .collect() + } + + #[wasm_bindgen(getter, js_name = merkleNote)] + pub fn merkle_note(&self) -> MerkleNote { + self.0.merkle_note().into() + } +} + +impl From for OutputDescription { + fn from(d: ironfish::OutputDescription) -> Self { + Self(d) + } +} + +impl AsRef for OutputDescription { + fn as_ref(&self) -> &ironfish::OutputDescription { + &self.0 + } +} diff --git a/ironfish-rust-wasm/src/transaction/spends.rs b/ironfish-rust-wasm/src/transaction/spends.rs new file mode 100644 index 0000000000..6ce969b2fc --- /dev/null +++ b/ironfish-rust-wasm/src/transaction/spends.rs @@ -0,0 +1,86 @@ +/* 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::{Nullifier, PublicKey, Scalar}, +}; +use ironfish::errors::IronfishErrorKind; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Clone, Debug)] +pub struct SpendDescription(ironfish::SpendDescription); + +#[wasm_bindgen] +impl SpendDescription { + #[wasm_bindgen(constructor)] + pub fn deserialize(bytes: &[u8]) -> Result { + Ok(Self(ironfish::SpendDescription::read(bytes)?)) + } + + #[wasm_bindgen] + pub fn serialize(&self) -> Vec { + let mut buf = Vec::new(); + self.0 + .write(&mut buf) + .expect("failed to serialize spend description"); + buf + } + + #[wasm_bindgen(getter)] + pub fn nullifier(&self) -> Nullifier { + self.0.nullifier().into() + } + + #[wasm_bindgen(getter, js_name = rootHash)] + pub fn root_hash(&self) -> Scalar { + self.0.root_hash().into() + } + + #[wasm_bindgen(getter, js_name = treeSize)] + pub fn tree_size(&self) -> u32 { + self.0.tree_size() + } + + #[wasm_bindgen(js_name = verifySignature)] + pub fn verify_signature( + &self, + signature: &[u8], + randomized_public_key: &PublicKey, + ) -> Result<(), IronfishError> { + let signature = signature + .try_into() + .map_err(|_| IronfishErrorKind::InvalidSignature)?; + self.0 + .verify_signature(signature, randomized_public_key.as_ref()) + .map_err(|e| e.into()) + } + + #[wasm_bindgen(js_name = partialVerify)] + pub fn partial_verify(&self) -> Result<(), IronfishError> { + self.0.partial_verify().map_err(|e| e.into()) + } + + #[wasm_bindgen(js_name = publicInputs)] + pub fn public_inputs(&self, randomized_public_key: &PublicKey) -> Vec { + self.0 + .public_inputs(randomized_public_key.as_ref()) + .into_iter() + .map(Scalar::from) + .collect() + } +} + +impl From for SpendDescription { + fn from(d: ironfish::SpendDescription) -> Self { + Self(d) + } +} + +impl AsRef for SpendDescription { + fn as_ref(&self) -> &ironfish::SpendDescription { + &self.0 + } +} diff --git a/ironfish-rust/src/transaction/burns.rs b/ironfish-rust/src/transaction/burns.rs index 5595347761..74757b4f19 100644 --- a/ironfish-rust/src/transaction/burns.rs +++ b/ironfish-rust/src/transaction/burns.rs @@ -32,7 +32,7 @@ impl BurnBuilder { /// This description represents an action to decrease the supply of an existing /// asset on Iron Fish -#[derive(Clone, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct BurnDescription { /// Identifier for the Asset which is being burned pub asset_id: AssetIdentifier, diff --git a/ironfish-rust/src/transaction/outputs.rs b/ironfish-rust/src/transaction/outputs.rs index 008c8a9cb3..26402f6789 100644 --- a/ironfish-rust/src/transaction/outputs.rs +++ b/ironfish-rust/src/transaction/outputs.rs @@ -131,7 +131,7 @@ impl OutputBuilder { /// /// This is the variation of an Output that gets serialized to bytes and can /// be loaded from bytes. -#[derive(Clone, Debug)] +#[derive(Clone, PartialEq, Debug)] pub struct OutputDescription { /// Proof that the output circuit was valid and successful pub(crate) proof: groth16::Proof,