#![allow(clippy::unused_unit)]
use core::convert::{TryFrom, TryInto};
use core::fmt;
use core::ops::Deref;
use core::str::FromStr;
use arkworks_setups::Curve as ArkCurve;
use js_sys::{JsString, Uint8Array};
use wasm_bindgen::__rt::core::fmt::Formatter;
use wasm_bindgen::prelude::*;
#[cfg(not(test))]
#[wasm_bindgen]
#[derive(PartialEq, Eq, Debug)]
pub struct OperationError {
#[wasm_bindgen(skip)]
pub code: OpStatusCode,
#[wasm_bindgen(skip)]
pub error_message: String,
#[wasm_bindgen(skip)]
pub data: Option<String>,
}
#[allow(clippy::unused_unit)]
#[cfg(not(test))]
#[wasm_bindgen]
impl OperationError {
#[wasm_bindgen(js_name = code)]
#[wasm_bindgen(getter)]
pub fn code(&self) -> JsValue {
JsValue::from(self.code.clone() as u32)
}
#[wasm_bindgen(js_name = error_message)]
#[wasm_bindgen(getter)]
pub fn error_message(&self) -> JsString {
JsString::from(self.error_message.clone())
}
#[wasm_bindgen(js_name = message)]
#[wasm_bindgen(getter)]
pub fn message(&self) -> JsString {
JsString::from(self.error_message.clone())
}
#[wasm_bindgen(js_name = data)]
#[wasm_bindgen(getter)]
pub fn data(&self) -> JsString {
match self.data.clone() {
None => JsString::from("{}"),
Some(e) => JsString::from(e),
}
}
}
#[cfg(test)]
#[derive(PartialEq, Eq, Debug)]
pub struct OperationError {
pub code: OpStatusCode,
pub error_message: String,
pub data: Option<String>,
}
#[cfg(test)]
impl OperationError {
pub fn code(&self) -> JsValue {
JsValue::from(self.code.clone() as u32)
}
pub fn error_message(&self) -> JsString {
JsString::from(self.error_message.clone())
}
pub fn data(&self) -> JsString {
match self.data.clone() {
None => JsString::from("{}"),
Some(e) => JsString::from(e),
}
}
}
#[cfg(test)]
impl From<OperationError> for JsValue {
fn from(e: OperationError) -> Self {
JsValue::from(e.to_string())
}
}
impl fmt::Display for OperationError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"Code {}, message {}, data {}",
self.code.clone() as u32,
self.error_message.clone(),
self.data()
)
}
}
impl OperationError {
pub fn new_with_message(code: OpStatusCode, message: String) -> Self {
let mut oe: Self = code.into();
oe.error_message = message;
oe
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum NoteVersion {
V1,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Chain {
Edgeware,
Ganache,
Beresheet,
HarmonyTestShard1,
Rinkeby,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Backend {
Arkworks,
Circom,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Curve {
Bls381,
Bn254,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum HashFunction {
Poseidon,
MiMCTornado,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum NoteProtocol {
Mixer,
VAnchor,
}
impl fmt::Display for NoteVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NoteVersion::V1 => write!(f, "v1"),
}
}
}
impl FromStr for NoteVersion {
type Err = OpStatusCode;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"v1" => Ok(NoteVersion::V1),
_ => Err(OpStatusCode::InvalidNoteVersion),
}
}
}
impl fmt::Display for Backend {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Backend::Arkworks => write!(f, "Arkworks"),
Backend::Circom => write!(f, "Circom"),
}
}
}
impl FromStr for Backend {
type Err = OpStatusCode;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Arkworks" => Ok(Backend::Arkworks),
"Circom" => Ok(Backend::Circom),
_ => Err(OpStatusCode::InvalidBackend),
}
}
}
impl fmt::Display for Curve {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Curve::Bls381 => write!(f, "Bls381"),
Curve::Bn254 => write!(f, "Bn254"),
}
}
}
impl FromStr for Curve {
type Err = OpStatusCode;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Bls381" => Ok(Curve::Bls381),
"Bn254" => Ok(Curve::Bn254),
_ => Err(OpStatusCode::InvalidCurve),
}
}
}
impl fmt::Display for HashFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
HashFunction::Poseidon => write!(f, "Poseidon"),
HashFunction::MiMCTornado => write!(f, "MiMCTornado"),
}
}
}
impl FromStr for NoteProtocol {
type Err = OpStatusCode;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"mixer" => Ok(NoteProtocol::Mixer),
"vanchor" => Ok(NoteProtocol::VAnchor),
_ => Err(OpStatusCode::InvalidNoteProtocol),
}
}
}
impl fmt::Display for NoteProtocol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NoteProtocol::Mixer => write!(f, "mixer"),
NoteProtocol::VAnchor => write!(f, "vanchor"),
}
}
}
impl FromStr for HashFunction {
type Err = OpStatusCode;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Poseidon" => Ok(HashFunction::Poseidon),
"MiMCTornado" => Ok(HashFunction::MiMCTornado),
_ => Err(OpStatusCode::InvalidHasFunction),
}
}
}
impl From<Curve> for ArkCurve {
fn from(curve: Curve) -> Self {
match curve {
Curve::Bls381 => ArkCurve::Bls381,
Curve::Bn254 => ArkCurve::Bn254,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
#[repr(u32)]
pub enum OpStatusCode {
Unknown = 0,
InvalidHexLength = 1,
HexParsingFailed = 2,
InvalidNoteLength = 3,
InvalidNoteProtocol = 4,
InvalidNoteVersion = 5,
InvalidNoteId = 6,
InvalidNoteBlockNumber = 7,
InvalidNoteSecrets = 8,
MerkleTreeNotFound = 9,
SerializationFailed = 10,
DeserializationFailed = 11,
InvalidArrayLength = 12,
InvalidCurve = 13,
InvalidHasFunction = 14,
InvalidBackend = 15,
InvalidDenomination = 16,
SecretGenFailed = 17,
InvalidSourceChain = 18,
InvalidTargetChain = 19,
InvalidTokenSymbol = 20,
InvalidExponentiation = 21,
InvalidWidth = 22,
InvalidAmount = 23,
InvalidProofParameters = 24,
InvalidProvingKey = 25,
InvalidRecipient = 26,
InvalidRelayer = 27,
InvalidLeafIndex = 28,
InvalidFee = 29,
InvalidRefund = 30,
InvalidLeaves = 31,
FailedToGenerateTheLeaf = 32,
ProofBuilderNoteNotSet = 33,
CommitmentNotSet = 34,
RootsNotSet = 35,
InvalidNoteMiscData = 36,
InvalidSourceIdentifyingData = 37,
InvalidTargetIdentifyingData = 38,
UnsupportedParameterCombination = 39,
InvalidProof = 40,
InvalidUTXOIndex = 41,
UnsupportedBackend = 42,
PublicAmountNotSet = 43,
VAnchorProofChainId = 44,
VAnchorNotesNotSet = 45,
VAnchorProofIndices = 46,
VAnchorProofLeavesMap = 47,
ProofInputFieldInstantiationError = 48,
ProofInputFieldInstantiationProtocolInvalid = 49,
InvalidNullifer = 50,
InvalidRoots = 51,
InvalidChainId = 52,
InvalidIndices = 53,
InvalidPublicAmount = 54,
InvalidOutputUtxoConfig = 55,
InvalidExtDataHash = 56,
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
pub fn log(s: &str);
#[wasm_bindgen(typescript_type = "NoteProtocol")]
pub type Protocol;
#[wasm_bindgen(typescript_type = "Curve")]
#[derive(Clone)]
pub type WasmCurve;
#[wasm_bindgen(typescript_type = "HashFunction")]
pub type HF;
#[wasm_bindgen(typescript_type = "Version")]
pub type Version;
#[wasm_bindgen(typescript_type = "Backend")]
#[derive(Clone)]
pub type BE;
#[wasm_bindgen(typescript_type = "Leaves")]
pub type Leaves;
#[wasm_bindgen(typescript_type = "Indices")]
pub type Indices;
}
#[wasm_bindgen(typescript_custom_section)]
const NOTE_PROTOCOL: &str = "type NoteProtocol = 'mixer' | 'vanchor' ";
#[wasm_bindgen(typescript_custom_section)]
const LEAVES: &str = "type Leaves = Array<Uint8Array>;";
#[wasm_bindgen(typescript_custom_section)]
const INDICES: &str = "type Indices = Array<number>;";
#[wasm_bindgen(typescript_custom_section)]
const HF: &str = "type HashFunction = 'Poseidon' | 'MiMCTornado'";
#[wasm_bindgen(typescript_custom_section)]
const CURVE: &str = "type Curve = 'Bls381' | 'Bn254'";
#[wasm_bindgen(typescript_custom_section)]
const VERSION: &str = "type Version = 'v1'";
#[wasm_bindgen(typescript_custom_section)]
const BE: &str = "type Backend = 'Arkworks' | 'Circom'";
pub struct Uint8Arrayx32(pub [u8; 32]);
impl Deref for Uint8Arrayx32 {
type Target = [u8; 32];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl TryFrom<Uint8Array> for Uint8Arrayx32 {
type Error = OpStatusCode;
fn try_from(value: Uint8Array) -> Result<Self, Self::Error> {
let bytes: [u8; 32] = value
.to_vec()
.try_into()
.map_err(|_| OpStatusCode::InvalidArrayLength)?;
Ok(Self(bytes))
}
}
impl From<OpStatusCode> for String {
fn from(e: OpStatusCode) -> Self {
match e {
OpStatusCode::Unknown => "Unknown error",
OpStatusCode::InvalidHexLength => "Invalid hex length",
OpStatusCode::HexParsingFailed => "Failed to parse hex",
OpStatusCode::InvalidNoteLength => "Invalid note length",
OpStatusCode::InvalidNoteProtocol => "Invalid note protocol",
OpStatusCode::InvalidNoteVersion => "Invalid note version",
OpStatusCode::InvalidNoteId => "Invalid note id",
OpStatusCode::InvalidNoteBlockNumber => "Invalid block number",
OpStatusCode::InvalidNoteSecrets => "Invalid note secrets",
OpStatusCode::MerkleTreeNotFound => "Merkle tree not found",
OpStatusCode::SerializationFailed => "Failed to serialize",
OpStatusCode::DeserializationFailed => "Failed to deserialize",
OpStatusCode::InvalidArrayLength => "Invalid array length",
OpStatusCode::InvalidCurve => "Invalid curve",
OpStatusCode::InvalidHasFunction => "Invalid hash function",
OpStatusCode::InvalidBackend => "Invalid backend",
OpStatusCode::InvalidDenomination => "Invalid denomination",
OpStatusCode::SecretGenFailed => "Failed to generate secrets",
OpStatusCode::InvalidSourceChain => "Invalid source chain id",
OpStatusCode::InvalidTargetChain => "Invalid target chain id",
OpStatusCode::InvalidTokenSymbol => "Invalid token symbol",
OpStatusCode::InvalidExponentiation => "Invalid exponentiation",
OpStatusCode::InvalidWidth => "Invalid width",
OpStatusCode::InvalidAmount => "Invalid amount",
OpStatusCode::InvalidProofParameters => "Invalid proof parameters",
OpStatusCode::InvalidProvingKey => "Invalid proving key",
OpStatusCode::InvalidRecipient => "Invalid recipient address",
OpStatusCode::InvalidRelayer => "Invalid relayer address",
OpStatusCode::InvalidLeafIndex => "Invalid leaf index",
OpStatusCode::InvalidFee => "Invalid fee",
OpStatusCode::InvalidRefund => "Invalid refund",
OpStatusCode::InvalidLeaves => "Invalid leaves",
OpStatusCode::FailedToGenerateTheLeaf => "Failed to generate the leaf",
OpStatusCode::ProofBuilderNoteNotSet => "Proof building failed note isn't set",
OpStatusCode::CommitmentNotSet => "Proof building failed refresh commitment isn't set",
OpStatusCode::RootsNotSet => "Proof building failed roots array isn't set",
OpStatusCode::InvalidNoteMiscData => "Invalid note misc data",
OpStatusCode::InvalidSourceIdentifyingData => "Invalid source identifying data",
OpStatusCode::InvalidTargetIdentifyingData => "Invalid target identifying data",
OpStatusCode::UnsupportedParameterCombination => "Unsupported Paramater combination to generate proof",
OpStatusCode::InvalidProof => "Proof verification failed",
OpStatusCode::InvalidUTXOIndex => "Invalid UTXO Index value",
OpStatusCode::UnsupportedBackend => "Unsupported backend",
OpStatusCode::PublicAmountNotSet => "VAnchor proof input requires public amount field",
OpStatusCode::VAnchorProofChainId => "VAnchor proof input requires chain id",
OpStatusCode::VAnchorNotesNotSet => "VAnchor proof input requires list of notes",
OpStatusCode::VAnchorProofIndices => "VAnchor proof input require list of indices",
OpStatusCode::VAnchorProofLeavesMap => "VAnchor proof input require leaves map",
OpStatusCode::ProofInputFieldInstantiationError => "The proof input field installation failed",
OpStatusCode::ProofInputFieldInstantiationProtocolInvalid => {
"The proof input field installation failed wrong protocol or field"
}
OpStatusCode::InvalidNullifer => "Invalid nullifer value",
OpStatusCode::InvalidRoots => "Invalid roots value",
OpStatusCode::InvalidChainId => "Invalid chain id",
OpStatusCode::InvalidIndices => "Invalid indices value",
OpStatusCode::InvalidPublicAmount => "Invalid public amount",
OpStatusCode::InvalidOutputUtxoConfig => "Invalid output UTXO config",
OpStatusCode::InvalidExtDataHash => "Invalid external data hash",
}
.to_string()
}
}
impl From<OpStatusCode> for OperationError {
fn from(e: OpStatusCode) -> Self {
OperationError {
code: e.clone(),
data: None,
error_message: e.into(),
}
}
}
impl From<OpStatusCode> for JsValue {
fn from(e: OpStatusCode) -> Self {
let op: OperationError = e.into();
op.into()
}
}
impl From<Backend> for JsString {
fn from(e: Backend) -> Self {
JsString::from(e.to_string())
}
}
impl From<Curve> for JsString {
fn from(e: Curve) -> Self {
JsString::from(e.to_string())
}
}
impl From<HashFunction> for JsString {
fn from(e: HashFunction) -> Self {
JsString::from(e.to_string())
}
}
impl From<NoteVersion> for JsString {
fn from(e: NoteVersion) -> Self {
JsString::from(e.to_string())
}
}
impl From<NoteProtocol> for JsString {
fn from(e: NoteProtocol) -> Self {
JsString::from(e.to_string())
}
}
impl From<Curve> for WasmCurve {
fn from(curve: Curve) -> Self {
let js_str = curve.to_string();
JsValue::from(&js_str).try_into().unwrap()
}
}
impl From<HashFunction> for HF {
fn from(hash_function: HashFunction) -> Self {
let js_str = hash_function.to_string();
JsValue::from(&js_str).try_into().unwrap()
}
}
impl From<NoteVersion> for Version {
fn from(version: NoteVersion) -> Self {
let js_str = version.to_string();
JsValue::from(&js_str).try_into().unwrap()
}
}
impl From<Backend> for BE {
fn from(backend: Backend) -> Self {
let js_str = backend.to_string();
JsValue::from(&js_str).try_into().unwrap()
}
}
impl From<NoteProtocol> for Protocol {
fn from(proto: NoteProtocol) -> Self {
let js_str = proto.to_string();
JsValue::from(&js_str).try_into().unwrap()
}
}
#[cfg(not(test))]
#[allow(clippy::unused_unit)]
#[wasm_bindgen(start)]
pub fn main() {
console_error_panic_hook::set_once();
}