@solarity/zkit 0.1.1 → 0.2.0

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.
@@ -28,16 +28,12 @@ export type InputLike = NumberLike | ArrayLike;
28
28
 
29
29
  export type Inputs = Record<string, InputLike>;
30
30
 
31
- export type CircuitInfo = {
32
- path: string;
33
- id: string | null;
34
- };
35
-
36
- export type FileType = "r1cs" | "zkey" | "vkey" | "sym" | "json" | "wasm" | "sol";
37
- export type DirType = "circuit" | "artifact" | "verifier";
38
- export type TemplateType = "groth16";
39
-
40
- export type PtauInfo = {
41
- file: string;
42
- url: string | null;
31
+ export type ArtifactsFileType = "r1cs" | "zkey" | "vkey" | "sym" | "json" | "wasm";
32
+ export type VerifierTemplateType = "groth16";
33
+
34
+ export type CircuitZKitConfig = {
35
+ circuitName: string;
36
+ circuitArtifactsPath: string;
37
+ verifierDirPath: string;
38
+ templateType?: VerifierTemplateType;
43
39
  };
@@ -1,43 +0,0 @@
1
- import { TemplateType } from "../types/types";
2
-
3
- const { Context } = require("@distributedlab/circom2");
4
-
5
- export type ManagerZKitConfig = {
6
- circuitsDir: string;
7
- artifactsDir: string;
8
- verifiersDir: string;
9
- ptauDir: string;
10
- allowDownload: boolean;
11
- };
12
-
13
- export const defaultManagerOptions: Partial<ManagerZKitConfig> = {
14
- circuitsDir: "circuits",
15
- artifactsDir: "zkit-artifacts",
16
- verifiersDir: "contracts/verifiers",
17
- allowDownload: true,
18
- };
19
-
20
- export type CompileOptions = {
21
- sym: boolean;
22
- json: boolean;
23
- c: boolean;
24
- quiet: boolean;
25
- setup: TemplateType;
26
- contributions: number;
27
- };
28
-
29
- export const defaultCompileOptions: CompileOptions = {
30
- sym: false,
31
- json: false,
32
- c: false,
33
- quiet: false,
34
- setup: "groth16",
35
- contributions: 5,
36
- };
37
-
38
- export type ManagerZKitPrivateConfig = ManagerZKitConfig & {
39
- compiler: typeof Context;
40
- templates: {
41
- groth16: string;
42
- };
43
- };
@@ -1,110 +0,0 @@
1
- import os from "os";
2
- import path from "path";
3
-
4
- import { CircuitZKit } from "./CircuitZKit";
5
- import { ManagerZKit } from "./ManagerZKit";
6
- import { CircuitInfo } from "../types/types";
7
- import { readDirRecursively } from "../utils/utils";
8
- import { defaultManagerOptions, ManagerZKitConfig } from "../config/config";
9
-
10
- /**
11
- * `CircomZKit` acts as a factory for `CircuitZKit` instances.
12
- */
13
- export class CircomZKit {
14
- private readonly _manager: ManagerZKit;
15
-
16
- /**
17
- * Creates a new `CircomZKit` instance.
18
- *
19
- * @param {Partial<ManagerZKitConfig>} [options=defaultManagerOptions] - The configuration options to use.
20
- */
21
- constructor(options: Partial<ManagerZKitConfig> = defaultManagerOptions) {
22
- this._manager = new ManagerZKit({ ...defaultManagerOptions, ...options });
23
- }
24
-
25
- /**
26
- * Returns a `CircuitZKit` instance for the specified circuit.
27
- *
28
- * @dev If the circuit id is not unique, the path to the circuit file must be provided.
29
- *
30
- * @param {string} circuit - The path to the circuit file or the circuit id (filename without extension).
31
- * @returns {CircomZKit} The `CircuitZKit` instance.
32
- */
33
- public getCircuit(circuit: string): CircuitZKit {
34
- const circuits = this._getAllCircuits();
35
-
36
- const candidates = circuits.filter((file) => {
37
- if (circuit.endsWith(".circom")) {
38
- return file == path.normalize(circuit);
39
- }
40
-
41
- return path.basename(file) == `${circuit}.circom`;
42
- });
43
-
44
- if (candidates.length == 0) {
45
- throw Error(`No circuits with name \"${circuit}\" found`);
46
- }
47
-
48
- if (candidates.length > 1) {
49
- throw Error(
50
- `Found multiple entries for the circuit "${circuit}".
51
-
52
- \rConsider replacing \"${circuit}\" with one of the valid paths:
53
- \r${candidates.map((candidate) => `"${candidate}"`).join(os.EOL)}`,
54
- );
55
- }
56
-
57
- return new CircuitZKit(path.join(this._manager.getCircuitsDir(), candidates[0]), this._manager);
58
- }
59
-
60
- /**
61
- * Returns an array of all circuits available in the circuits directory.
62
- *
63
- * @dev If a circuit id is not unique, the id will be set to `null`.
64
- *
65
- * @returns {CircuitInfo[]} An array of circuit information objects.
66
- */
67
- public getCircuits(): CircuitInfo[] {
68
- const circuits = this._getAllCircuits();
69
-
70
- let circuitsCount = {} as Record<string, number>;
71
-
72
- for (const circuit of circuits) {
73
- const circuitId = path.parse(circuit).name;
74
-
75
- circuitsCount[circuitId] = (circuitsCount[circuitId] || 0) + 1;
76
- }
77
-
78
- let result = [] as CircuitInfo[];
79
-
80
- for (const circuit of circuits) {
81
- const circuitId = path.parse(circuit).name;
82
-
83
- result.push({
84
- path: circuit,
85
- id: circuitsCount[circuitId] > 1 ? null : circuitId,
86
- });
87
- }
88
-
89
- return result;
90
- }
91
-
92
- /**
93
- * Returns an array of all circuits paths available in the circuits directory.
94
- *
95
- * @returns {string[]} An array of circuit paths.
96
- */
97
- private _getAllCircuits(): string[] {
98
- const circuitsDir = this._manager.getCircuitsDir();
99
-
100
- let circuits = [] as string[];
101
-
102
- readDirRecursively(circuitsDir, (_dir: string, file: string) => {
103
- if (path.extname(file) == ".circom") {
104
- circuits.push(path.relative(circuitsDir, file));
105
- }
106
- });
107
-
108
- return circuits;
109
- }
110
- }
@@ -1,231 +0,0 @@
1
- import fs from "fs";
2
- import os from "os";
3
- import path from "path";
4
- import process from "process";
5
- import * as readline from "readline";
6
- import { v4 as uuid } from "uuid";
7
-
8
- import { ManagerZKitConfig, ManagerZKitPrivateConfig, defaultManagerOptions } from "../config/config";
9
- import { PtauInfo, TemplateType } from "../types/types";
10
- import { downloadFile } from "../utils/utils";
11
-
12
- /**
13
- * `ManagerZKit` provides configuration options and utility methods used by the `CircomZKit` and `CircuitZKit` classes.
14
- */
15
- export class ManagerZKit {
16
- private _config: ManagerZKitPrivateConfig;
17
-
18
- /**
19
- * Creates a new `ManagerZKit` instance.
20
- *
21
- * @param {Partial<ManagerZKitConfig>} [config=defaultManagerOptions] - The configuration options to use.
22
- */
23
- constructor(config: Partial<ManagerZKitConfig> = defaultManagerOptions) {
24
- const overriddenConfig = { ...defaultManagerOptions, ...config } as ManagerZKitConfig;
25
-
26
- overriddenConfig.circuitsDir = path.join(process.cwd(), overriddenConfig.circuitsDir);
27
- overriddenConfig.artifactsDir = path.join(process.cwd(), overriddenConfig.artifactsDir);
28
- overriddenConfig.verifiersDir = path.join(process.cwd(), overriddenConfig.verifiersDir);
29
-
30
- if (overriddenConfig.ptauDir) {
31
- overriddenConfig.ptauDir = path.join(process.cwd(), overriddenConfig.ptauDir);
32
- } else {
33
- overriddenConfig.ptauDir = path.join(os.homedir(), ".zkit", ".ptau");
34
- }
35
-
36
- this._config = {
37
- ...overriddenConfig,
38
- compiler: fs.readFileSync(require.resolve("@distributedlab/circom2/circom.wasm")),
39
- templates: {
40
- groth16: fs.readFileSync(path.join(__dirname, "templates", "verifier_groth16.sol.ejs"), "utf8"),
41
- },
42
- };
43
- }
44
-
45
- /**
46
- * Fetches the `ptau` file.
47
- *
48
- * @dev If `ptau` file is not found, this method will try to download it. Use `allowDownload=false` to disable this behavior.
49
- *
50
- * @param {number} minConstraints - The minimum number of constraints the `ptau` file must support.
51
- * @returns {Promise<string>} The path to the `ptau` file.
52
- */
53
- public async fetchPtauFile(minConstraints: number): Promise<string> {
54
- const ptauId = Math.max(Math.ceil(Math.log2(minConstraints)), 8);
55
-
56
- if (ptauId > 20) {
57
- throw new Error(
58
- 'Circuit has too many constraints. The maximum number of constraints is 2^20. Consider passing "ptauDir=PATH_TO_LOCAL_DIR".',
59
- );
60
- }
61
-
62
- const ptauInfo = this._searchPtau(ptauId);
63
-
64
- if (ptauInfo.url) {
65
- await this._downloadPtau(ptauInfo);
66
- }
67
-
68
- return ptauInfo.file;
69
- }
70
-
71
- /**
72
- * Returns the path to the artifacts' directory.
73
- *
74
- * @returns {string} The path to the artifacts' directory.
75
- */
76
- public getArtifactsDir(): string {
77
- return this._config.artifactsDir;
78
- }
79
-
80
- /**
81
- * Returns the path to the circuits' directory.
82
- *
83
- * @returns {string} The path to the circuits' directory.
84
- */
85
- public getCircuitsDir(): string {
86
- return this._config.circuitsDir;
87
- }
88
-
89
- /**
90
- * Returns the path to the verifiers' directory.
91
- *
92
- * @returns {string} The path to the verifiers' directory.
93
- */
94
- public getVerifiersDir(): string {
95
- return this._config.verifiersDir;
96
- }
97
-
98
- /**
99
- * Returns the path to the `ptau` directory.
100
- *
101
- * @dev The default `ptau` directory is located at `${HOME}/.zkit/.ptau`.
102
- *
103
- * @returns {string} The path to the `ptau` directory.
104
- */
105
- public getPtauDir(): string {
106
- return this._config.ptauDir;
107
- }
108
-
109
- /**
110
- * Returns a temporary directory path.
111
- *
112
- * @dev Temporary files are stored in the OS's temporary directory.
113
- *
114
- * @returns {string} A temporary directory path.
115
- */
116
- public getTempDir(): string {
117
- return path.join(os.tmpdir(), ".zkit", uuid());
118
- }
119
-
120
- /**
121
- * Returns the circom compiler's wasm binary.
122
- *
123
- * @returns {string} The circom compiler's wasm binary.
124
- */
125
- public getCompiler(): string {
126
- return this._config.compiler;
127
- }
128
-
129
- /**
130
- * Returns the Solidity verifier template for the specified proving system.
131
- *
132
- * @param {TemplateType} templateType - The template type.
133
- * @returns {string} The Solidity verifier template.
134
- */
135
- public getTemplate(templateType: TemplateType): string {
136
- switch (templateType) {
137
- case "groth16":
138
- return this._config.templates.groth16;
139
- default:
140
- throw new Error(`Ambiguous template type: ${templateType}.`);
141
- }
142
- }
143
-
144
- /**
145
- * Returns whether the download of the `ptau` file is allowed.
146
- *
147
- * @returns {boolean} Whether the download of the `ptau` file is allowed.
148
- */
149
- public getAllowDownload(): boolean {
150
- return this._config.allowDownload;
151
- }
152
-
153
- /**
154
- * Downloads the `ptau` file. The download is allowed only if the user confirms it.
155
- *
156
- * @param {PtauInfo} ptauInfo - The `ptau` file and download url.
157
- */
158
- private async _downloadPtau(ptauInfo: PtauInfo): Promise<void> {
159
- if (!this.getAllowDownload() && !(await this._askForDownloadAllowance(ptauInfo))) {
160
- throw new Error(
161
- 'Download is cancelled. Allow download or consider passing "ptauDir=PATH_TO_LOCAL_DIR" to the existing ptau files',
162
- );
163
- }
164
-
165
- fs.mkdirSync(this.getPtauDir(), { recursive: true });
166
-
167
- if (!(await downloadFile(ptauInfo.file, ptauInfo.url!))) {
168
- throw new Error("Something went wrong while downloading the ptau file.");
169
- }
170
- }
171
-
172
- /**
173
- * Searches for the `ptau` file that supports the specified number of constraints.
174
- *
175
- * @param {number} ptauId - The `ptau` file id.
176
- * @returns {PtauInfo} The `ptau` file path and download url if the file doesn't exist.
177
- */
178
- private _searchPtau(ptauId: number): PtauInfo {
179
- let entries = [] as fs.Dirent[];
180
-
181
- if (fs.existsSync(this.getPtauDir())) {
182
- entries = fs.readdirSync(this.getPtauDir(), { withFileTypes: true });
183
- }
184
-
185
- const entry = entries.find((entry) => {
186
- if (!entry.isFile()) {
187
- return false;
188
- }
189
-
190
- const match = entry.name.match(/^powers-of-tau-(\d+)\.ptau$/);
191
-
192
- if (!match) {
193
- return false;
194
- }
195
-
196
- const entryPtauId = parseInt(match[1]);
197
-
198
- return ptauId <= entryPtauId;
199
- });
200
-
201
- const file = path.join(this.getPtauDir(), entry ? entry.name : `powers-of-tau-${ptauId}.ptau`);
202
- const url = entry
203
- ? null
204
- : `https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_${ptauId.toString().padStart(2, "0")}.ptau`;
205
-
206
- return { file, url };
207
- }
208
-
209
- /**
210
- * Prompts the user to allow the download of the `ptau` file.
211
- *
212
- * @param {PtauInfo} ptauInfo - The `ptau` file and download url.
213
- * @returns {Promise<boolean>} Whether the download is allowed.
214
- */
215
- private _askForDownloadAllowance(ptauInfo: PtauInfo): Promise<boolean> {
216
- return new Promise((resolve) => {
217
- const readLine = readline.createInterface({
218
- input: process.stdin,
219
- output: process.stdout,
220
- });
221
-
222
- readLine.question(
223
- `No ptau found. Press [Y] to download it from "${ptauInfo.url!}" to ${ptauInfo.file}: `,
224
- (response) => {
225
- readLine.close();
226
- resolve(response.toUpperCase() == "Y");
227
- },
228
- );
229
- });
230
- }
231
- }
@@ -1,60 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import https from "https";
4
-
5
- /**
6
- * Reads a directory recursively and calls the callback for each file.
7
- *
8
- * @dev After Node.js 20.0.0 the `recursive` option is available.
9
- *
10
- * @param {string} dir - The directory to read.
11
- * @param {(dir: string, file: string) => void} callback - The callback function.
12
- */
13
- export function readDirRecursively(dir: string, callback: (dir: string, file: string) => void): void {
14
- if (!fs.existsSync(dir)) {
15
- return;
16
- }
17
-
18
- const entries = fs.readdirSync(dir, { withFileTypes: true });
19
-
20
- for (const entry of entries) {
21
- const entryPath = path.join(dir, entry.name);
22
-
23
- if (entry.isDirectory()) {
24
- readDirRecursively(entryPath, callback);
25
- }
26
-
27
- if (entry.isFile()) {
28
- callback(dir, entryPath);
29
- }
30
- }
31
- }
32
-
33
- /**
34
- * Downloads a file from the specified URL.
35
- *
36
- * @param {string} file - The path to save the file to.
37
- * @param {string} url - The URL to download the file from.
38
- * @returns {Promise<boolean>} Whether the file was downloaded successfully.
39
- */
40
- export async function downloadFile(file: string, url: string): Promise<boolean> {
41
- const fileStream = fs.createWriteStream(file);
42
-
43
- return new Promise((resolve, reject) => {
44
- const request = https.get(url, (response) => {
45
- response.pipe(fileStream);
46
- });
47
-
48
- fileStream.on("finish", () => resolve(true));
49
-
50
- request.on("error", (err) => {
51
- fs.unlink(file, () => reject(err));
52
- });
53
-
54
- fileStream.on("error", (err) => {
55
- fs.unlink(file, () => reject(err));
56
- });
57
-
58
- request.end();
59
- });
60
- }