@noir-lang/noir_js 0.28.0 → 0.29.0-c8b70ac.nightly

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export { ecdsa_secp256r1_verify, ecdsa_secp256k1_verify, keccak256, blake2s256,
5
5
  export { InputMap } from '@noir-lang/noirc_abi';
6
6
  export { WitnessMap, ForeignCallHandler, ForeignCallInput, ForeignCallOutput } from '@noir-lang/acvm_js';
7
7
  export { Noir } from './program.js';
8
+ export { ErrorWithPayload } from './witness_generation.js';
8
9
  /** @ignore */
9
10
  export { acvm, abi };
10
11
  export { CompiledCircuit, ProofData };
package/lib/program.cjs CHANGED
@@ -74,9 +74,10 @@ class Noir {
74
74
  */
75
75
  async execute(inputs, foreignCallHandler) {
76
76
  await this.init();
77
- const witness = await (0, witness_generation_js_1.generateWitness)(this.circuit, inputs, foreignCallHandler);
78
- const { return_value: returnValue } = (0, noirc_abi_1.abiDecode)(this.circuit.abi, witness);
79
- return { witness: (0, acvm_js_1.compressWitness)(witness), returnValue };
77
+ const witness_stack = await (0, witness_generation_js_1.generateWitness)(this.circuit, inputs, foreignCallHandler);
78
+ const main_witness = witness_stack[0].witness;
79
+ const { return_value: returnValue } = (0, noirc_abi_1.abiDecode)(this.circuit.abi, main_witness);
80
+ return { witness: (0, acvm_js_1.compressWitnessStack)(witness_stack), returnValue };
80
81
  }
81
82
  /**
82
83
  *
package/lib/program.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { generateWitness } from "./witness_generation.mjs";
2
2
  import initAbi, { abiDecode } from '@noir-lang/noirc_abi';
3
- import initACVM, { compressWitness } from '@noir-lang/acvm_js';
3
+ import initACVM, { compressWitnessStack } from '@noir-lang/acvm_js';
4
4
  export class Noir {
5
5
  circuit;
6
6
  backend;
@@ -48,9 +48,10 @@ export class Noir {
48
48
  */
49
49
  async execute(inputs, foreignCallHandler) {
50
50
  await this.init();
51
- const witness = await generateWitness(this.circuit, inputs, foreignCallHandler);
52
- const { return_value: returnValue } = abiDecode(this.circuit.abi, witness);
53
- return { witness: compressWitness(witness), returnValue };
51
+ const witness_stack = await generateWitness(this.circuit, inputs, foreignCallHandler);
52
+ const main_witness = witness_stack[0].witness;
53
+ const { return_value: returnValue } = abiDecode(this.circuit.abi, main_witness);
54
+ return { witness: compressWitnessStack(witness_stack), returnValue };
54
55
  }
55
56
  /**
56
57
  *
@@ -19,15 +19,30 @@ const defaultForeignCallHandler = async (name, args) => {
19
19
  // If a user needs to print values then they should provide a custom foreign call handler.
20
20
  return [];
21
21
  }
22
- else if (name == 'assert_message') {
23
- // By default we do not do anything for `assert_message` foreign calls due to a need for formatting,
24
- // however we provide an empty response in order to not halt execution.
25
- //
26
- // If a user needs to use dynamic assertion messages then they should provide a custom foreign call handler.
27
- return [];
28
- }
29
22
  throw Error(`Unexpected oracle during execution: ${name}(${args.join(', ')})`);
30
23
  };
24
+ function parseErrorPayload(abi, originalError) {
25
+ const payload = originalError.rawAssertionPayload;
26
+ if (!payload)
27
+ return originalError;
28
+ const enrichedError = originalError;
29
+ try {
30
+ // Decode the payload
31
+ const decodedPayload = (0, noirc_abi_1.abiDecodeError)(abi, payload);
32
+ if (typeof decodedPayload === 'string') {
33
+ // If it's a string, just add it to the error message
34
+ enrichedError.message = `Circuit execution failed: ${decodedPayload}`;
35
+ }
36
+ else {
37
+ // If not, attach the payload to the original error
38
+ enrichedError.decodedAssertionPayload = decodedPayload;
39
+ }
40
+ }
41
+ catch (_errorDecoding) {
42
+ // Ignore errors decoding the payload
43
+ }
44
+ return enrichedError;
45
+ }
31
46
  // Generates the witnesses needed to feed into the chosen proving system
32
47
  async function generateWitness(compiledProgram, inputs, foreignCallHandler = defaultForeignCallHandler) {
33
48
  // Throws on ABI encoding error
@@ -35,10 +50,14 @@ async function generateWitness(compiledProgram, inputs, foreignCallHandler = def
35
50
  // Execute the circuit to generate the rest of the witnesses and serialize
36
51
  // them into a Uint8Array.
37
52
  try {
38
- const solvedWitness = await (0, acvm_js_1.executeCircuitWithBlackBoxSolver)(await getSolver(), (0, base64_decode_js_1.base64Decode)(compiledProgram.bytecode), witnessMap, foreignCallHandler);
53
+ const solvedWitness = await (0, acvm_js_1.executeProgramWithBlackBoxSolver)(await getSolver(), (0, base64_decode_js_1.base64Decode)(compiledProgram.bytecode), witnessMap, foreignCallHandler);
39
54
  return solvedWitness;
40
55
  }
41
56
  catch (err) {
57
+ // Typescript types catched errors as unknown or any, so we need to narrow its type to check if it has raw assertion payload.
58
+ if (typeof err === 'object' && err !== null && 'rawAssertionPayload' in err) {
59
+ throw parseErrorPayload(compiledProgram.abi, err);
60
+ }
42
61
  throw new Error(`Circuit execution failed: ${err}`);
43
62
  }
44
63
  }
@@ -1,4 +1,7 @@
1
1
  import { InputMap } from '@noir-lang/noirc_abi';
2
- import { WitnessMap, ForeignCallHandler } from '@noir-lang/acvm_js';
2
+ import { WitnessStack, ForeignCallHandler, ExecutionError } from '@noir-lang/acvm_js';
3
3
  import { CompiledCircuit } from '@noir-lang/types';
4
- export declare function generateWitness(compiledProgram: CompiledCircuit, inputs: InputMap, foreignCallHandler?: ForeignCallHandler): Promise<WitnessMap>;
4
+ export type ErrorWithPayload = ExecutionError & {
5
+ decodedAssertionPayload?: any;
6
+ };
7
+ export declare function generateWitness(compiledProgram: CompiledCircuit, inputs: InputMap, foreignCallHandler?: ForeignCallHandler): Promise<WitnessStack>;
@@ -1,6 +1,6 @@
1
- import { abiEncode } from '@noir-lang/noirc_abi';
1
+ import { abiDecodeError, abiEncode } from '@noir-lang/noirc_abi';
2
2
  import { base64Decode } from "./base64_decode.mjs";
3
- import { createBlackBoxSolver, executeCircuitWithBlackBoxSolver, } from '@noir-lang/acvm_js';
3
+ import { createBlackBoxSolver, executeProgramWithBlackBoxSolver, } from '@noir-lang/acvm_js';
4
4
  let solver;
5
5
  const getSolver = () => {
6
6
  if (!solver) {
@@ -16,15 +16,30 @@ const defaultForeignCallHandler = async (name, args) => {
16
16
  // If a user needs to print values then they should provide a custom foreign call handler.
17
17
  return [];
18
18
  }
19
- else if (name == 'assert_message') {
20
- // By default we do not do anything for `assert_message` foreign calls due to a need for formatting,
21
- // however we provide an empty response in order to not halt execution.
22
- //
23
- // If a user needs to use dynamic assertion messages then they should provide a custom foreign call handler.
24
- return [];
25
- }
26
19
  throw Error(`Unexpected oracle during execution: ${name}(${args.join(', ')})`);
27
20
  };
21
+ function parseErrorPayload(abi, originalError) {
22
+ const payload = originalError.rawAssertionPayload;
23
+ if (!payload)
24
+ return originalError;
25
+ const enrichedError = originalError;
26
+ try {
27
+ // Decode the payload
28
+ const decodedPayload = abiDecodeError(abi, payload);
29
+ if (typeof decodedPayload === 'string') {
30
+ // If it's a string, just add it to the error message
31
+ enrichedError.message = `Circuit execution failed: ${decodedPayload}`;
32
+ }
33
+ else {
34
+ // If not, attach the payload to the original error
35
+ enrichedError.decodedAssertionPayload = decodedPayload;
36
+ }
37
+ }
38
+ catch (_errorDecoding) {
39
+ // Ignore errors decoding the payload
40
+ }
41
+ return enrichedError;
42
+ }
28
43
  // Generates the witnesses needed to feed into the chosen proving system
29
44
  export async function generateWitness(compiledProgram, inputs, foreignCallHandler = defaultForeignCallHandler) {
30
45
  // Throws on ABI encoding error
@@ -32,10 +47,14 @@ export async function generateWitness(compiledProgram, inputs, foreignCallHandle
32
47
  // Execute the circuit to generate the rest of the witnesses and serialize
33
48
  // them into a Uint8Array.
34
49
  try {
35
- const solvedWitness = await executeCircuitWithBlackBoxSolver(await getSolver(), base64Decode(compiledProgram.bytecode), witnessMap, foreignCallHandler);
50
+ const solvedWitness = await executeProgramWithBlackBoxSolver(await getSolver(), base64Decode(compiledProgram.bytecode), witnessMap, foreignCallHandler);
36
51
  return solvedWitness;
37
52
  }
38
53
  catch (err) {
54
+ // Typescript types catched errors as unknown or any, so we need to narrow its type to check if it has raw assertion payload.
55
+ if (typeof err === 'object' && err !== null && 'rawAssertionPayload' in err) {
56
+ throw parseErrorPayload(compiledProgram.abi, err);
57
+ }
39
58
  throw new Error(`Circuit execution failed: ${err}`);
40
59
  }
41
60
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "contributors": [
4
4
  "The Noir Team <team@noir-lang.org>"
5
5
  ],
6
- "version": "0.28.0",
6
+ "version": "0.29.0-c8b70ac.nightly",
7
7
  "packageManager": "yarn@3.5.1",
8
8
  "license": "(MIT OR Apache-2.0)",
9
9
  "type": "module",
@@ -17,9 +17,9 @@
17
17
  "url": "https://github.com/noir-lang/noir/issues"
18
18
  },
19
19
  "dependencies": {
20
- "@noir-lang/acvm_js": "0.44.0",
21
- "@noir-lang/noirc_abi": "0.28.0",
22
- "@noir-lang/types": "0.28.0"
20
+ "@noir-lang/acvm_js": "0.45.0-c8b70ac.nightly",
21
+ "@noir-lang/noirc_abi": "0.29.0-c8b70ac.nightly",
22
+ "@noir-lang/types": "0.29.0-c8b70ac.nightly"
23
23
  },
24
24
  "files": [
25
25
  "lib",