1#![allow(clippy::unused_unit)]
2use core::convert::{TryFrom, TryInto};
3use core::fmt;
4use core::ops::Deref;
5use core::str::FromStr;
6
7use arkworks_setups::Curve as ArkCurve;
8use js_sys::{JsString, Uint8Array};
9use wasm_bindgen::__rt::core::fmt::Formatter;
10use wasm_bindgen::prelude::*;
11
12#[cfg(not(test))]
14#[wasm_bindgen]
15#[derive(PartialEq, Eq, Debug)]
16pub struct OperationError {
17 #[wasm_bindgen(skip)]
18 pub code: OpStatusCode,
19 #[wasm_bindgen(skip)]
20 pub error_message: String,
21 #[wasm_bindgen(skip)]
22 pub data: Option<String>,
23}
24
25#[allow(clippy::unused_unit)]
26#[cfg(not(test))]
27#[wasm_bindgen]
28impl OperationError {
29 #[wasm_bindgen(js_name = code)]
30 #[wasm_bindgen(getter)]
31 pub fn code(&self) -> JsValue {
32 JsValue::from(self.code.clone() as u32)
33 }
34
35 #[wasm_bindgen(js_name = error_message)]
37 #[wasm_bindgen(getter)]
38 pub fn error_message(&self) -> JsString {
39 JsString::from(self.error_message.clone())
40 }
41
42 #[wasm_bindgen(js_name = message)]
43 #[wasm_bindgen(getter)]
44 pub fn message(&self) -> JsString {
45 JsString::from(self.error_message.clone())
46 }
47
48 #[wasm_bindgen(js_name = data)]
49 #[wasm_bindgen(getter)]
50 pub fn data(&self) -> JsString {
51 match self.data.clone() {
52 None => JsString::from("{}"),
53 Some(e) => JsString::from(e),
54 }
55 }
56}
57#[cfg(test)]
59#[derive(PartialEq, Eq, Debug)]
60pub struct OperationError {
61 pub code: OpStatusCode,
62 pub error_message: String,
63 pub data: Option<String>,
64}
65#[cfg(test)]
66impl OperationError {
67 pub fn code(&self) -> JsValue {
68 JsValue::from(self.code.clone() as u32)
69 }
70
71 pub fn error_message(&self) -> JsString {
72 JsString::from(self.error_message.clone())
73 }
74
75 pub fn data(&self) -> JsString {
76 match self.data.clone() {
77 None => JsString::from("{}"),
78 Some(e) => JsString::from(e),
79 }
80 }
81}
82
83#[cfg(test)]
84impl From<OperationError> for JsValue {
85 fn from(e: OperationError) -> Self {
86 JsValue::from(e.to_string())
87 }
88}
89
90impl fmt::Display for OperationError {
91 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
92 write!(
93 f,
94 "Code {}, message {}, data {}",
95 self.code.clone() as u32,
96 self.error_message.clone(),
97 self.data()
98 )
99 }
100}
101
102impl OperationError {
103 pub fn new_with_message(code: OpStatusCode, message: String) -> Self {
104 let mut oe: Self = code.into();
105 oe.error_message = message;
106 oe
107 }
108}
109#[derive(Clone, Copy, PartialEq, Eq, Debug)]
110pub enum NoteVersion {
111 V1,
112}
113
114#[derive(Clone, Copy, PartialEq, Eq, Debug)]
115pub enum Chain {
116 Edgeware,
117 Ganache,
118 Beresheet,
119 HarmonyTestShard1,
120 Rinkeby,
121}
122
123#[derive(Clone, Copy, PartialEq, Eq, Debug)]
124pub enum Backend {
125 Arkworks,
126 Circom,
127}
128
129#[derive(Clone, Copy, PartialEq, Eq, Debug)]
130pub enum Curve {
131 Bls381,
132 Bn254,
133}
134
135#[derive(Clone, Copy, PartialEq, Eq, Debug)]
136pub enum HashFunction {
137 Poseidon,
138 MiMCTornado,
139}
140
141#[derive(Clone, Copy, PartialEq, Eq, Debug)]
142pub enum NoteProtocol {
143 Mixer,
144 VAnchor,
145}
146
147impl fmt::Display for NoteVersion {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 match self {
150 NoteVersion::V1 => write!(f, "v1"),
151 }
152 }
153}
154
155impl FromStr for NoteVersion {
156 type Err = OpStatusCode;
157
158 fn from_str(s: &str) -> Result<Self, Self::Err> {
159 match s {
160 "v1" => Ok(NoteVersion::V1),
161 _ => Err(OpStatusCode::InvalidNoteVersion),
162 }
163 }
164}
165
166impl fmt::Display for Backend {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 match self {
169 Backend::Arkworks => write!(f, "Arkworks"),
170 Backend::Circom => write!(f, "Circom"),
171 }
172 }
173}
174
175impl FromStr for Backend {
176 type Err = OpStatusCode;
177
178 fn from_str(s: &str) -> Result<Self, Self::Err> {
179 match s {
180 "Arkworks" => Ok(Backend::Arkworks),
181 "Circom" => Ok(Backend::Circom),
182 _ => Err(OpStatusCode::InvalidBackend),
183 }
184 }
185}
186
187impl fmt::Display for Curve {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 match self {
190 Curve::Bls381 => write!(f, "Bls381"),
191 Curve::Bn254 => write!(f, "Bn254"),
192 }
193 }
194}
195
196impl FromStr for Curve {
197 type Err = OpStatusCode;
198
199 fn from_str(s: &str) -> Result<Self, Self::Err> {
200 match s {
201 "Bls381" => Ok(Curve::Bls381),
202 "Bn254" => Ok(Curve::Bn254),
203 _ => Err(OpStatusCode::InvalidCurve),
204 }
205 }
206}
207
208impl fmt::Display for HashFunction {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 match self {
211 HashFunction::Poseidon => write!(f, "Poseidon"),
212 HashFunction::MiMCTornado => write!(f, "MiMCTornado"),
213 }
214 }
215}
216
217impl FromStr for NoteProtocol {
218 type Err = OpStatusCode;
219
220 fn from_str(s: &str) -> Result<Self, Self::Err> {
221 match s {
222 "mixer" => Ok(NoteProtocol::Mixer),
223 "vanchor" => Ok(NoteProtocol::VAnchor),
224 _ => Err(OpStatusCode::InvalidNoteProtocol),
225 }
226 }
227}
228
229impl fmt::Display for NoteProtocol {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 match self {
232 NoteProtocol::Mixer => write!(f, "mixer"),
233 NoteProtocol::VAnchor => write!(f, "vanchor"),
234 }
235 }
236}
237
238impl FromStr for HashFunction {
239 type Err = OpStatusCode;
240
241 fn from_str(s: &str) -> Result<Self, Self::Err> {
242 match s {
243 "Poseidon" => Ok(HashFunction::Poseidon),
244 "MiMCTornado" => Ok(HashFunction::MiMCTornado),
245 _ => Err(OpStatusCode::InvalidHasFunction),
246 }
247 }
248}
249
250impl From<Curve> for ArkCurve {
251 fn from(curve: Curve) -> Self {
252 match curve {
253 Curve::Bls381 => ArkCurve::Bls381,
254 Curve::Bn254 => ArkCurve::Bn254,
255 }
256 }
257}
258
259#[derive(Debug, Eq, PartialEq, Clone)]
260#[repr(u32)]
261pub enum OpStatusCode {
262 Unknown = 0,
263 InvalidHexLength = 1,
265 HexParsingFailed = 2,
267 InvalidNoteLength = 3,
269 InvalidNoteProtocol = 4,
271 InvalidNoteVersion = 5,
273 InvalidNoteId = 6,
275 InvalidNoteBlockNumber = 7,
277 InvalidNoteSecrets = 8,
279 MerkleTreeNotFound = 9,
281 SerializationFailed = 10,
284 DeserializationFailed = 11,
286 InvalidArrayLength = 12,
288 InvalidCurve = 13,
290 InvalidHasFunction = 14,
292 InvalidBackend = 15,
294 InvalidDenomination = 16,
296 SecretGenFailed = 17,
298 InvalidSourceChain = 18,
300 InvalidTargetChain = 19,
302 InvalidTokenSymbol = 20,
304 InvalidExponentiation = 21,
306 InvalidWidth = 22,
308 InvalidAmount = 23,
310 InvalidProofParameters = 24,
312 InvalidProvingKey = 25,
314 InvalidRecipient = 26,
316 InvalidRelayer = 27,
318 InvalidLeafIndex = 28,
320 InvalidFee = 29,
322 InvalidRefund = 30,
324 InvalidLeaves = 31,
326 FailedToGenerateTheLeaf = 32,
328 ProofBuilderNoteNotSet = 33,
330 CommitmentNotSet = 34,
332 RootsNotSet = 35,
334 InvalidNoteMiscData = 36,
336 InvalidSourceIdentifyingData = 37,
338 InvalidTargetIdentifyingData = 38,
340 UnsupportedParameterCombination = 39,
342 InvalidProof = 40,
344 InvalidUTXOIndex = 41,
346 UnsupportedBackend = 42,
348 PublicAmountNotSet = 43,
350 VAnchorProofChainId = 44,
352 VAnchorNotesNotSet = 45,
354 VAnchorProofIndices = 46,
356 VAnchorProofLeavesMap = 47,
358 ProofInputFieldInstantiationError = 48,
360 ProofInputFieldInstantiationProtocolInvalid = 49,
362 InvalidNullifer = 50,
363 InvalidRoots = 51,
364 InvalidChainId = 52,
365 InvalidIndices = 53,
366 InvalidPublicAmount = 54,
367 InvalidOutputUtxoConfig = 55,
368 InvalidExtDataHash = 56,
369}
370
371#[wasm_bindgen]
372extern "C" {
373 #[wasm_bindgen(js_namespace = console)]
376 pub fn log(s: &str);
377
378 #[wasm_bindgen(typescript_type = "NoteProtocol")]
379 pub type Protocol;
380
381 #[wasm_bindgen(typescript_type = "Curve")]
382 #[derive(Clone)]
383 pub type WasmCurve;
384
385 #[wasm_bindgen(typescript_type = "HashFunction")]
386 pub type HF;
387
388 #[wasm_bindgen(typescript_type = "Version")]
389 pub type Version;
390
391 #[wasm_bindgen(typescript_type = "Backend")]
392 #[derive(Clone)]
393 pub type BE;
394
395 #[wasm_bindgen(typescript_type = "Leaves")]
396 pub type Leaves;
397
398 #[wasm_bindgen(typescript_type = "Indices")]
399 pub type Indices;
400
401}
402
403#[wasm_bindgen(typescript_custom_section)]
404const NOTE_PROTOCOL: &str = "type NoteProtocol = 'mixer' | 'vanchor' ";
405
406#[wasm_bindgen(typescript_custom_section)]
407const LEAVES: &str = "type Leaves = Array<Uint8Array>;";
408
409#[wasm_bindgen(typescript_custom_section)]
410const INDICES: &str = "type Indices = Array<number>;";
411
412#[wasm_bindgen(typescript_custom_section)]
413const HF: &str = "type HashFunction = 'Poseidon' | 'MiMCTornado'";
414
415#[wasm_bindgen(typescript_custom_section)]
416const CURVE: &str = "type Curve = 'Bls381' | 'Bn254'";
417
418#[wasm_bindgen(typescript_custom_section)]
419const VERSION: &str = "type Version = 'v1'";
420
421#[wasm_bindgen(typescript_custom_section)]
422const BE: &str = "type Backend = 'Arkworks' | 'Circom'";
423
424pub struct Uint8Arrayx32(pub [u8; 32]);
425
426impl Deref for Uint8Arrayx32 {
427 type Target = [u8; 32];
428
429 fn deref(&self) -> &Self::Target {
430 &self.0
431 }
432}
433
434impl TryFrom<Uint8Array> for Uint8Arrayx32 {
435 type Error = OpStatusCode;
436
437 fn try_from(value: Uint8Array) -> Result<Self, Self::Error> {
438 let bytes: [u8; 32] = value
439 .to_vec()
440 .try_into()
441 .map_err(|_| OpStatusCode::InvalidArrayLength)?;
442 Ok(Self(bytes))
443 }
444}
445impl From<OpStatusCode> for String {
446 fn from(e: OpStatusCode) -> Self {
447 match e {
448 OpStatusCode::Unknown => "Unknown error",
449 OpStatusCode::InvalidHexLength => "Invalid hex length",
450 OpStatusCode::HexParsingFailed => "Failed to parse hex",
451 OpStatusCode::InvalidNoteLength => "Invalid note length",
452 OpStatusCode::InvalidNoteProtocol => "Invalid note protocol",
453 OpStatusCode::InvalidNoteVersion => "Invalid note version",
454 OpStatusCode::InvalidNoteId => "Invalid note id",
455 OpStatusCode::InvalidNoteBlockNumber => "Invalid block number",
456 OpStatusCode::InvalidNoteSecrets => "Invalid note secrets",
457 OpStatusCode::MerkleTreeNotFound => "Merkle tree not found",
458 OpStatusCode::SerializationFailed => "Failed to serialize",
459 OpStatusCode::DeserializationFailed => "Failed to deserialize",
460 OpStatusCode::InvalidArrayLength => "Invalid array length",
461 OpStatusCode::InvalidCurve => "Invalid curve",
462 OpStatusCode::InvalidHasFunction => "Invalid hash function",
463 OpStatusCode::InvalidBackend => "Invalid backend",
464 OpStatusCode::InvalidDenomination => "Invalid denomination",
465 OpStatusCode::SecretGenFailed => "Failed to generate secrets",
466 OpStatusCode::InvalidSourceChain => "Invalid source chain id",
467 OpStatusCode::InvalidTargetChain => "Invalid target chain id",
468 OpStatusCode::InvalidTokenSymbol => "Invalid token symbol",
469 OpStatusCode::InvalidExponentiation => "Invalid exponentiation",
470 OpStatusCode::InvalidWidth => "Invalid width",
471 OpStatusCode::InvalidAmount => "Invalid amount",
472 OpStatusCode::InvalidProofParameters => "Invalid proof parameters",
473 OpStatusCode::InvalidProvingKey => "Invalid proving key",
474 OpStatusCode::InvalidRecipient => "Invalid recipient address",
475 OpStatusCode::InvalidRelayer => "Invalid relayer address",
476 OpStatusCode::InvalidLeafIndex => "Invalid leaf index",
477 OpStatusCode::InvalidFee => "Invalid fee",
478 OpStatusCode::InvalidRefund => "Invalid refund",
479 OpStatusCode::InvalidLeaves => "Invalid leaves",
480 OpStatusCode::FailedToGenerateTheLeaf => "Failed to generate the leaf",
481 OpStatusCode::ProofBuilderNoteNotSet => "Proof building failed note isn't set",
482 OpStatusCode::CommitmentNotSet => "Proof building failed refresh commitment isn't set",
483 OpStatusCode::RootsNotSet => "Proof building failed roots array isn't set",
484 OpStatusCode::InvalidNoteMiscData => "Invalid note misc data",
485 OpStatusCode::InvalidSourceIdentifyingData => "Invalid source identifying data",
486 OpStatusCode::InvalidTargetIdentifyingData => "Invalid target identifying data",
487 OpStatusCode::UnsupportedParameterCombination => "Unsupported Paramater combination to generate proof",
488 OpStatusCode::InvalidProof => "Proof verification failed",
489 OpStatusCode::InvalidUTXOIndex => "Invalid UTXO Index value",
490 OpStatusCode::UnsupportedBackend => "Unsupported backend",
491 OpStatusCode::PublicAmountNotSet => "VAnchor proof input requires public amount field",
492 OpStatusCode::VAnchorProofChainId => "VAnchor proof input requires chain id",
493 OpStatusCode::VAnchorNotesNotSet => "VAnchor proof input requires list of notes",
494 OpStatusCode::VAnchorProofIndices => "VAnchor proof input require list of indices",
495 OpStatusCode::VAnchorProofLeavesMap => "VAnchor proof input require leaves map",
496 OpStatusCode::ProofInputFieldInstantiationError => "The proof input field installation failed",
497 OpStatusCode::ProofInputFieldInstantiationProtocolInvalid => {
498 "The proof input field installation failed wrong protocol or field"
499 }
500 OpStatusCode::InvalidNullifer => "Invalid nullifer value",
501 OpStatusCode::InvalidRoots => "Invalid roots value",
502 OpStatusCode::InvalidChainId => "Invalid chain id",
503 OpStatusCode::InvalidIndices => "Invalid indices value",
504 OpStatusCode::InvalidPublicAmount => "Invalid public amount",
505 OpStatusCode::InvalidOutputUtxoConfig => "Invalid output UTXO config",
506 OpStatusCode::InvalidExtDataHash => "Invalid external data hash",
507 }
508 .to_string()
509 }
510}
511impl From<OpStatusCode> for OperationError {
512 fn from(e: OpStatusCode) -> Self {
513 OperationError {
514 code: e.clone(),
515 data: None,
516 error_message: e.into(),
517 }
518 }
519}
520
521impl From<OpStatusCode> for JsValue {
522 fn from(e: OpStatusCode) -> Self {
523 let op: OperationError = e.into();
524 op.into()
525 }
526}
527
528impl From<Backend> for JsString {
529 fn from(e: Backend) -> Self {
530 JsString::from(e.to_string())
531 }
532}
533
534impl From<Curve> for JsString {
535 fn from(e: Curve) -> Self {
536 JsString::from(e.to_string())
537 }
538}
539
540impl From<HashFunction> for JsString {
541 fn from(e: HashFunction) -> Self {
542 JsString::from(e.to_string())
543 }
544}
545
546impl From<NoteVersion> for JsString {
547 fn from(e: NoteVersion) -> Self {
548 JsString::from(e.to_string())
549 }
550}
551
552impl From<NoteProtocol> for JsString {
553 fn from(e: NoteProtocol) -> Self {
554 JsString::from(e.to_string())
555 }
556}
557
558impl From<Curve> for WasmCurve {
559 fn from(curve: Curve) -> Self {
560 let js_str = curve.to_string();
561 JsValue::from(&js_str).try_into().unwrap()
562 }
563}
564
565impl From<HashFunction> for HF {
566 fn from(hash_function: HashFunction) -> Self {
567 let js_str = hash_function.to_string();
568 JsValue::from(&js_str).try_into().unwrap()
569 }
570}
571
572impl From<NoteVersion> for Version {
573 fn from(version: NoteVersion) -> Self {
574 let js_str = version.to_string();
575 JsValue::from(&js_str).try_into().unwrap()
576 }
577}
578
579impl From<Backend> for BE {
580 fn from(backend: Backend) -> Self {
581 let js_str = backend.to_string();
582 JsValue::from(&js_str).try_into().unwrap()
583 }
584}
585
586impl From<NoteProtocol> for Protocol {
587 fn from(proto: NoteProtocol) -> Self {
588 let js_str = proto.to_string();
589 JsValue::from(&js_str).try_into().unwrap()
590 }
591}
592
593#[cfg(not(test))]
594#[allow(clippy::unused_unit)]
595#[wasm_bindgen(start)]
596pub fn main() {
597 console_error_panic_hook::set_once();
598}