Skip to content

Commit 5748971

Browse files
committed
use wasm compiler && bb.js to generate artifacts
1 parent eea883b commit 5748971

File tree

1 file changed

+62
-32
lines changed

1 file changed

+62
-32
lines changed

src/tasks.ts

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { UltraHonkBackend, UltraPlonkBackend } from "@aztec/bb.js";
12
import {
23
TASK_CLEAN,
34
TASK_COMPILE,
@@ -7,28 +8,62 @@ import { task } from "hardhat/config";
78
import { HardhatPluginError } from "hardhat/plugins";
89
import { HardhatConfig } from "hardhat/types";
910
import { NoirCache } from "./cache";
10-
import { installBb, installNargo } from "./install";
11+
import { installNargo } from "./install";
1112
import { getTarget, ProofFlavor } from "./Noir";
1213
import { makeRunCommand, PLUGIN_NAME } from "./utils";
1314

1415
task(TASK_COMPILE, "Compile and generate circuits and contracts").setAction(
1516
async (args, { config }, runSuper) => {
17+
const fs = await import("fs");
18+
const path = await import("path");
19+
1620
const noirDir = config.paths.noir;
1721
const targetDir = await getTarget(noirDir);
1822

19-
const runCommand = makeRunCommand(config.paths.noir);
20-
21-
const nargoBinary = await installNargo(config.noir.version);
22-
const bbBinary = await installBb(config.noir.bbVersion);
23-
2423
await checkNargoWorkspace(config);
2524
await addGitIgnore(noirDir);
2625

2726
const force = !!args.force;
2827
const cache = await NoirCache.fromConfig(config);
2928
if ((await cache.haveSourceFilesChanged()) || force) {
3029
console.log("Compiling Noir circuits...");
31-
await runCommand(`${nargoBinary} compile`);
30+
const { compile, createFileManager } = await import(
31+
"@noir-lang/noir_wasm"
32+
);
33+
const toml = await import("smol-toml");
34+
35+
// list dirs
36+
const dirs = (
37+
(
38+
toml.parse(
39+
fs.readFileSync(path.join(noirDir, "Nargo.toml"), "utf-8"),
40+
) as any
41+
).workspace.members as string[]
42+
).map((dir: string) => path.join(noirDir, dir));
43+
44+
await Promise.all(
45+
dirs.map(async (dir) => {
46+
const fileManager = createFileManager(dir);
47+
const compiled = await compile(fileManager);
48+
const name: unknown = (
49+
toml.parse(
50+
fs.readFileSync(path.join(dir, "Nargo.toml"), "utf-8"),
51+
) as any
52+
).package?.name;
53+
if (typeof name !== "string") {
54+
throw new HardhatPluginError(
55+
PLUGIN_NAME,
56+
`Nargo.toml must contain a name, but ${dir}/Nargo.toml does not`,
57+
);
58+
}
59+
fs.mkdirSync(targetDir, { recursive: true });
60+
fs.writeFileSync(
61+
path.join(targetDir, `${name}.json`),
62+
JSON.stringify(compiled.program, null, 2),
63+
);
64+
}),
65+
);
66+
3267
await cache.saveSourceFilesHash();
3368
console.log("Compiled Noir circuits");
3469
}
@@ -45,13 +80,7 @@ task(TASK_COMPILE, "Compile and generate circuits and contracts").setAction(
4580
if (!config.noir.flavor.includes(flavor)) {
4681
continue;
4782
}
48-
await generateSolidityVerifier(
49-
config,
50-
file,
51-
bbBinary,
52-
targetDir,
53-
flavor,
54-
);
83+
await generateSolidityVerifier(file, targetDir, flavor);
5584
}
5685
await cache.saveJsonFileHash(file);
5786
}),
@@ -108,43 +137,44 @@ task(
108137
);
109138

110139
async function generateSolidityVerifier(
111-
config: HardhatConfig,
112140
file: string,
113-
bbBinary: string,
114141
targetDir: string,
115142
flavor: ProofFlavor,
116143
) {
117144
const path = await import("path");
145+
const fs = await import("fs");
146+
const { UltraHonkBackend, UltraPlonkBackend } = await import("@aztec/bb.js");
118147

119-
const runCommand = makeRunCommand(config.paths.noir);
120-
121-
const name = path.basename(file, ".json");
122-
console.log(`Generating Solidity ${flavor} verifier for ${name}...`);
123-
let writeVkCmd: string, contractCmd: string;
148+
let backend: UltraHonkBackend | UltraPlonkBackend;
149+
const program = JSON.parse(fs.readFileSync(file, "utf-8"));
124150
switch (flavor) {
125151
case "ultra_plonk": {
126-
writeVkCmd = "write_vk";
127-
contractCmd = "contract";
152+
backend = new UltraPlonkBackend(program.bytecode);
128153
break;
129154
}
130155
case "ultra_keccak_honk": {
131-
writeVkCmd = "write_vk_ultra_keccak_honk";
132-
contractCmd = "contract_ultra_honk";
156+
backend = new UltraHonkBackend(program.bytecode);
133157
break;
134158
}
135159
default: {
136160
flavor satisfies never;
137-
return;
161+
throw new HardhatPluginError(
162+
PLUGIN_NAME,
163+
`Unsupported Noir proof flavor: ${flavor}`,
164+
);
138165
}
139166
}
167+
let verifier = await backend.getSolidityVerifier();
168+
if (typeof verifier !== "string") {
169+
// bug in bb types
170+
verifier = new TextDecoder().decode(verifier);
171+
}
172+
173+
const name = path.basename(file, ".json");
174+
console.log(`Generating Solidity ${flavor} verifier for ${name}...`);
140175
const nameSuffix =
141176
flavor === ProofFlavor.ultra_keccak_honk ? "" : `_${flavor}`;
142-
await runCommand(
143-
`${bbBinary} ${writeVkCmd} -b ${targetDir}/${name}.json -o ${targetDir}/${name}${nameSuffix}_vk`,
144-
);
145-
await runCommand(
146-
`${bbBinary} ${contractCmd} -k ${targetDir}/${name}${nameSuffix}_vk -o ${targetDir}/${name}${nameSuffix}.sol`,
147-
);
177+
fs.writeFileSync(path.join(targetDir, `${name}${nameSuffix}.sol`), verifier);
148178
console.log(`Generated Solidity ${flavor} verifier for ${name}`);
149179
}
150180

0 commit comments

Comments
 (0)