Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions docs/docs/tutorials/noirjs_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ You can find the complete app code for this guide [here](https://github.com/noir

Before we start, we want to make sure we have Node installed. If you don't have it already you can install it [here](https://nodejs.org/en/download), we recommend using [Yarn](https://yarnpkg.com/getting-started/install) as our package manager for this tutorial.

We'll also need version 1.0.0-beta.14 nargo installed, see the Noir [installation guide](../getting_started/noir_installation.md) for details.
We'll also need version 1.0.0-beta.15 nargo installed, see the Noir [installation guide](../getting_started/noir_installation.md) for details.

Let's go barebones. Doing the bare minimum is not only simple, but also allows you to easily adapt it to almost any frontend framework.

Barebones means we can immediately start with the dependencies even on an empty folder 😈:

```bash
yarn add @noir-lang/noir_js@1.0.0-beta.14 @aztec/bb.js@3.0.0-nightly.20251030-2 buffer vite vite-plugin-node-polyfills
yarn add @noir-lang/noir_js@1.0.0-beta.15 @aztec/bb.js@3.0.0-nightly.20251104 buffer vite vite-plugin-node-polyfills@0.17.0
```

Wait, what are these dependencies?
Expand All @@ -33,7 +33,7 @@ Wait, what are these dependencies?

:::info

In this guide, we will install versions pinned to 1.0.0-beta.14. These work with Barretenberg version 3.0.0-nightly.20251030-2, so we are using that one version too. Feel free to try with older or later versions, though!
In this guide, we will install versions pinned to 1.0.0-beta.15. These work with Barretenberg version 3.0.0-nightly.20251104, so we are using that one version too. Feel free to try with older or later versions, though!

:::

Expand All @@ -47,7 +47,7 @@ It's not just you. We also enjoy syntax highlighting. [Check out the Language Se

:::

All you need is a `main.nr` and a `Nargo.toml` file. You can follow the [noirup](../getting_started/noir_installation.md) installation and just run `noirup -v 1.0.0-beta.14`, or just create them by hand:
All you need is a `main.nr` and a `Nargo.toml` file. You can follow the [noirup](../getting_started/noir_installation.md) installation and just run `noirup -v 1.0.0-beta.15`, or just create them by hand:

```bash
mkdir -p circuit/src
Expand Down Expand Up @@ -77,7 +77,7 @@ Finally we're up for something cool. But before we can execute a Noir program, w
This can be done by cd-ing into our circuit directory and running the `nargo compile` command.

```bash
cd circuits
cd circuit

nargo compile
```
Expand All @@ -86,7 +86,7 @@ This will write the compiled circuit into the `target` directory, which we'll th

## Setting up our app

Remember when apps only had one `html` and one `js` file? Well, that's enough for Noir webapps. Let's create them:
Remember when apps only had one `html` and one `js` file? Well, that's enough for Noir webapps. Let's create them in the project root:

```bash
touch index.html index.js
Expand All @@ -100,30 +100,41 @@ It _could_ be a beautiful UI... Depending on which universe you live in. In any

As for the JS, real madmen could just `console.log` everything, but let's say we want to see things happening (the true initial purpose of JS... right?). Here's some boilerplate for that. Just paste it in `index.js`:

#include_code show_function examples/browser/index.js js
```js
#include_code show_function examples/browser/index.js raw

document.getElementById('submit').addEventListener('click', async () => {
try {
// code will go in here
} catch {
show('logs', 'Oh 💔');
}
});
```

:::info

At this point in the tutorial, your folder structure should look like this:

```tree
.
└── circuit
└── node_modules
└── src
└── main.nr
Nargo.toml
index.html
index.js
package.json
...etc
├── circuit
│ ├── Nargo.toml
│ ├── src
│ │ └── main.nr
│ └── target
│ └── circuit.json
├── index.html
├── index.js
├── package.json
├── etc...
```

:::

## Some more JS

We're starting with the good stuff now. We want to execute our circuit to get the witness, and then feed that witness to Barretenberg. Luckily, both packages are quite easy to work with. Let's import them at the top of the file:
We're starting with the good stuff now. We want to execute our circuit to get the witness, and then feed that witness to Barretenberg. Luckily, both packages are quite easy to work with. Let's import them at the top of the file and initialize the WASM modules:

#include_code imports examples/browser/index.js js

Expand Down
105 changes: 65 additions & 40 deletions docs/versioned_docs/version-v1.0.0-beta.14/tutorials/noirjs_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ You can find the complete app code for this guide [here](https://github.com/noir

Before we start, we want to make sure we have Node installed. If you don't have it already you can install it [here](https://nodejs.org/en/download), we recommend using [Yarn](https://yarnpkg.com/getting-started/install) as our package manager for this tutorial.

We'll also need version 1.0.0-beta.2 nargo installed, see the Noir [installation guide](../getting_started/noir_installation.md) for details.
We'll also need version 1.0.0-beta.14 nargo installed, see the Noir [installation guide](../getting_started/noir_installation.md) for details.

Let's go barebones. Doing the bare minimum is not only simple, but also allows you to easily adapt it to almost any frontend framework.

Barebones means we can immediately start with the dependencies even on an empty folder 😈:

```bash
yarn add @noir-lang/noir_js@1.0.0-beta.9 @aztec/bb.js@0.87.0
yarn add @noir-lang/noir_js@1.0.0-beta.14 @aztec/bb.js@3.0.0-nightly.20251030-2 buffer vite vite-plugin-node-polyfills@0.17.0
```

Wait, what are these dependencies?
Expand All @@ -33,7 +33,7 @@ Wait, what are these dependencies?

:::info

In this guide, we will install versions pinned to 1.0.0-beta.9. These work with Barretenberg version 0.87.0, so we are using that one version too. Feel free to try with older or later versions, though!
In this guide, we will install versions pinned to 1.0.0-beta.14. These work with Barretenberg version 3.0.0-nightly.20251030-2, so we are using that one version too. Feel free to try with older or later versions, though!

:::

Expand All @@ -47,7 +47,7 @@ It's not just you. We also enjoy syntax highlighting. [Check out the Language Se

:::

All you need is a `main.nr` and a `Nargo.toml` file. You can follow the [noirup](../getting_started/noir_installation.md) installation and just run `noirup -v 1.0.0-beta.6`, or just create them by hand:
All you need is a `main.nr` and a `Nargo.toml` file. You can follow the [noirup](../getting_started/noir_installation.md) installation and just run `noirup -v 1.0.0-beta.14`, or just create them by hand:

```bash
mkdir -p circuit/src
Expand All @@ -56,7 +56,7 @@ touch circuit/src/main.nr circuit/Nargo.toml

To make our program interesting, let's give it a real use-case scenario: Bob wants to prove he is older than 18, without disclosing his age. Open `main.nr` and write:

```rust title="age_check" showLineNumbers
```rust title="age_check" showLineNumbers
fn main(age: u8) {
assert(age > 18);
}
Expand All @@ -83,7 +83,7 @@ Finally we're up for something cool. But before we can execute a Noir program, w
This can be done by cd-ing into our circuit directory and running the `nargo compile` command.

```bash
cd circuits
cd circuit

nargo compile
```
Expand All @@ -92,15 +92,15 @@ This will write the compiled circuit into the `target` directory, which we'll th

## Setting up our app

Remember when apps only had one `html` and one `js` file? Well, that's enough for Noir webapps. Let's create them:
Remember when apps only had one `html` and one `js` file? Well, that's enough for Noir webapps. Let's create them in the project root:

```bash
touch index.html index.js
```

And add something useful to our HTML file:

```html title="index" showLineNumbers
```html title="index" showLineNumbers
<!DOCTYPE html>
<head>
<style>
Expand Down Expand Up @@ -138,12 +138,20 @@ It _could_ be a beautiful UI... Depending on which universe you live in. In any

As for the JS, real madmen could just `console.log` everything, but let's say we want to see things happening (the true initial purpose of JS... right?). Here's some boilerplate for that. Just paste it in `index.js`:

```js title="show_function" showLineNumbers
```js title="show_function" showLineNumbers
const show = (id, content) => {
const container = document.getElementById(id);
container.appendChild(document.createTextNode(content));
container.appendChild(document.createElement('br'));
};

document.getElementById('submit').addEventListener('click', async () => {
try {
// code will go in here
} catch {
show('logs', 'Oh 💔');
}
});
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L7-L13" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L7-L13</a></sub></sup>

Expand All @@ -154,15 +162,16 @@ At this point in the tutorial, your folder structure should look like this:

```tree
.
└── circuit
└── node_modules
└── src
└── main.nr
Nargo.toml
index.html
index.js
package.json
...etc
├── circuit
│ ├── Nargo.toml
│ ├── src
│ │ └── main.nr
│ └── target
│ └── circuit.json
├── index.html
├── index.js
├── package.json
├── etc...
```

:::
Expand All @@ -171,19 +180,26 @@ At this point in the tutorial, your folder structure should look like this:

We're starting with the good stuff now. We want to execute our circuit to get the witness, and then feed that witness to Barretenberg. Luckily, both packages are quite easy to work with. Let's import them at the top of the file:

```js title="imports" showLineNumbers
import { UltraHonkBackend } from '@aztec/bb.js';
import { Noir } from '@noir-lang/noir_js';
import circuit from './target/circuit.json';
```js title="imports" showLineNumbers
import { UltraHonkBackend } from "@aztec/bb.js";
import { Noir } from "@noir-lang/noir_js";
import initNoirC from "@noir-lang/noirc_abi";
import initACVM from "@noir-lang/acvm_js";
import acvm from "@noir-lang/acvm_js/web/acvm_js_bg.wasm?url";
import noirc from "@noir-lang/noirc_abi/web/noirc_abi_wasm_bg.wasm?url";
import circuit from "./circuit/target/circuit.json";

// Initialize WASM modules
await Promise.all([initACVM(fetch(acvm)), initNoirC(fetch(noirc))]);
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L1-L5" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L1-L5</a></sub></sup>


And instantiate them inside our try-catch block:

```js title="init" showLineNumbers
```js title="init" showLineNumbers
const noir = new Noir(circuit);
const backend = new UltraHonkBackend(circuit.bytecode);
const backend = new UltraHonkBackend(circuit.bytecode);
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L17-L20" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L17-L20</a></sub></sup>

Expand All @@ -192,11 +208,11 @@ const noir = new Noir(circuit);

Now for the app itself. We're capturing whatever is in the input when people press the submit button. Inside our `try` block, let's just grab that input and get its value. Noir will gladly execute it, and give us a witness:

```js title="execute" showLineNumbers
```js title="execute" showLineNumbers
const age = document.getElementById('age').value;
show('logs', 'Generating witness... ⏳');
const { witness } = await noir.execute({ age });
show('logs', 'Generated witness... ✅');
show('logs', 'Generating witness... ⏳');
const { witness } = await noir.execute({ age });
show('logs', 'Generated witness... ✅');
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L21-L26" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L21-L26</a></sub></sup>

Expand All @@ -209,11 +225,11 @@ For the remainder of the tutorial, everything will be happening inside the `try`

Now we're ready to prove stuff! Let's feed some inputs to our circuit and calculate the proof:

```js title="prove" showLineNumbers
```js title="prove" showLineNumbers
show('logs', 'Generating proof... ⏳');
const proof = await backend.generateProof(witness);
show('logs', 'Generated proof... ✅');
show('results', proof.proof);
const proof = await backend.generateProof(witness);
show('logs', 'Generated proof... ✅');
show('results', proof.proof);
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L27-L32" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L27-L32</a></sub></sup>

Expand All @@ -227,20 +243,29 @@ touch vite.config.js
Noir needs to load two WASM modules, but Vite doesn't include them by default in the bundle. We need to add the configuration below to `vite.config.js` to make it work.
We also need to target ESNext since `bb.js` uses top-level await, which isn't supported in some browsers.

```js title="config" showLineNumbers
export default {
```js title="config" showLineNumbers
import { defineConfig } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills';

export default defineConfig({
plugins: [nodePolyfills()],
optimizeDeps: {
esbuildOptions: { target: 'esnext' },
exclude: ['@noir-lang/noirc_abi', '@noir-lang/acvm_js'],
exclude: ['@aztec/bb.js'],
},
resolve: {
alias: {
pino: 'pino/browser.js',
},
},
});
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/vite.config.js#L1-L7" target="_blank" rel="noopener noreferrer">Source code: examples/browser/vite.config.js#L1-L7</a></sub></sup>


This should be enough for vite. We don't even need to install it, just run:

```bash
yarn dlx vite
yarn vite dev
```

If it doesn't open a browser for you, just visit `localhost:5173`. You should now see the worst UI ever, with an ugly input.
Expand All @@ -255,10 +280,10 @@ By the way, if you're human, you shouldn't be able to understand anything on the

Time to celebrate, yes! But we shouldn't trust machines so blindly. Let's add these lines to see our proof being verified:

```js title="verify" showLineNumbers
```js title="verify" showLineNumbers
show('logs', 'Verifying proof... ⌛');
const isValid = await backend.verifyProof(proof);
show('logs', `Proof is ${isValid ? 'valid' : 'invalid'}... ✅`);
const isValid = await backend.verifyProof(proof);
show('logs', `Proof is ${isValid ? 'valid' : 'invalid'}... ✅`);
```
> <sup><sub><a href="https://github.com/noir-lang/noir/blob/master/examples/browser/index.js#L34-L38" target="_blank" rel="noopener noreferrer">Source code: examples/browser/index.js#L34-L38</a></sub></sup>

Expand Down
Loading
Loading