create-izi-noir 0.1.1

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/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # create-izi-noir
2
+
3
+ CLI to scaffold IZI-NOIR ZK projects.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ # Create a new project interactively
9
+ npx create-izi-noir my-project
10
+
11
+ # Create with options
12
+ npx create-izi-noir my-project --template balance-proof --provider arkworks
13
+
14
+ # Skip prompts
15
+ npx create-izi-noir my-project --skip-install --skip-git
16
+ ```
17
+
18
+ ## Options
19
+
20
+ | Option | Description | Default |
21
+ |--------|-------------|---------|
22
+ | `-t, --template <template>` | Template to use (default, minimal, balance-proof) | default |
23
+ | `-p, --provider <provider>` | Proving provider (arkworks, barretenberg) | arkworks |
24
+ | `-y, --yes` | Skip prompts and use defaults | false |
25
+ | `--skip-install` | Skip npm install | false |
26
+ | `--skip-git` | Skip git initialization | false |
27
+
28
+ ## Templates
29
+
30
+ ### Default
31
+ Includes balance proof and age proof circuit examples.
32
+
33
+ ### Minimal
34
+ Empty circuit for starting from scratch.
35
+
36
+ ### Balance Proof
37
+ Single balance proof circuit example.
38
+
39
+ ## Generated Project Structure
40
+
41
+ ```
42
+ my-project/
43
+ ├── circuits/
44
+ │ ├── balance-proof.ts # ZK circuit as JS function
45
+ │ ├── age-proof.ts
46
+ │ └── index.ts
47
+ ├── generated/ # Compiled circuits (npm run build)
48
+ ├── scripts/
49
+ │ └── test-proof.ts # Test script
50
+ ├── package.json
51
+ ├── tsconfig.json
52
+ ├── izi-noir.config.ts
53
+ └── README.md
54
+ ```
55
+
56
+ ## Development
57
+
58
+ ```bash
59
+ # Install dependencies
60
+ npm install
61
+
62
+ # Build the CLI
63
+ npm run build
64
+
65
+ # Test locally
66
+ node dist/index.js test-project
67
+ ```
68
+
69
+ ## License
70
+
71
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,648 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import path2 from "path";
8
+ import { execSync } from "child_process";
9
+ import pc3 from "picocolors";
10
+
11
+ // src/prompts/project.ts
12
+ import prompts from "prompts";
13
+ import pc from "picocolors";
14
+ var TEMPLATES = [
15
+ { title: "Default (balance + age proofs)", value: "default" },
16
+ { title: "Minimal (empty circuit)", value: "minimal" },
17
+ { title: "Balance Proof only", value: "balance-proof" }
18
+ ];
19
+ var PROVIDERS = [
20
+ { title: "Arkworks (recommended)", value: "arkworks" },
21
+ { title: "Barretenberg", value: "barretenberg" }
22
+ ];
23
+ async function promptProjectOptions(defaults) {
24
+ console.log();
25
+ console.log(pc.bold(pc.cyan(" IZI-NOIR")) + " - Privacy-preserving toolkit for Solana");
26
+ console.log();
27
+ const questions = [];
28
+ if (!defaults.projectName) {
29
+ questions.push({
30
+ type: "text",
31
+ name: "projectName",
32
+ message: "Project name:",
33
+ initial: "my-zk-project",
34
+ validate: (value) => {
35
+ if (!value) return "Project name is required";
36
+ if (!/^[a-z0-9-_]+$/i.test(value)) {
37
+ return "Project name can only contain letters, numbers, hyphens, and underscores";
38
+ }
39
+ return true;
40
+ }
41
+ });
42
+ }
43
+ questions.push(
44
+ {
45
+ type: "select",
46
+ name: "template",
47
+ message: "Select a template:",
48
+ choices: TEMPLATES,
49
+ initial: TEMPLATES.findIndex((t) => t.value === defaults.template) || 0
50
+ },
51
+ {
52
+ type: "select",
53
+ name: "provider",
54
+ message: "Select proving provider:",
55
+ choices: PROVIDERS,
56
+ initial: PROVIDERS.findIndex((p) => p.value === defaults.provider) || 0
57
+ },
58
+ {
59
+ type: "confirm",
60
+ name: "installDeps",
61
+ message: "Install dependencies?",
62
+ initial: !defaults.skipInstall
63
+ },
64
+ {
65
+ type: "confirm",
66
+ name: "initGit",
67
+ message: "Initialize git repository?",
68
+ initial: !defaults.skipGit
69
+ }
70
+ );
71
+ try {
72
+ const response = await prompts(questions, {
73
+ onCancel: () => {
74
+ throw new Error("Operation cancelled");
75
+ }
76
+ });
77
+ return {
78
+ projectName: defaults.projectName || response.projectName,
79
+ template: response.template || defaults.template || "default",
80
+ provider: response.provider || defaults.provider || "arkworks",
81
+ skipInstall: response.installDeps === false,
82
+ skipGit: response.initGit === false
83
+ };
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
88
+
89
+ // src/utils/fs.ts
90
+ import fs from "fs-extra";
91
+ import path from "path";
92
+ async function ensureDir(dir) {
93
+ await fs.ensureDir(dir);
94
+ }
95
+ async function writeFile(filePath, content) {
96
+ await fs.ensureDir(path.dirname(filePath));
97
+ await fs.writeFile(filePath, content, "utf-8");
98
+ }
99
+ async function directoryExists(dir) {
100
+ try {
101
+ const stat = await fs.stat(dir);
102
+ return stat.isDirectory();
103
+ } catch {
104
+ return false;
105
+ }
106
+ }
107
+ async function isDirectoryEmpty(dir) {
108
+ try {
109
+ const files = await fs.readdir(dir);
110
+ return files.length === 0;
111
+ } catch {
112
+ return true;
113
+ }
114
+ }
115
+
116
+ // src/utils/spinner.ts
117
+ import pc2 from "picocolors";
118
+ var frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
119
+ var Spinner = class {
120
+ message;
121
+ interval = null;
122
+ frameIndex = 0;
123
+ constructor(message) {
124
+ this.message = message;
125
+ }
126
+ start() {
127
+ process.stdout.write("\x1B[?25l");
128
+ this.interval = setInterval(() => {
129
+ const frame = pc2.cyan(frames[this.frameIndex]);
130
+ process.stdout.write(`\r${frame} ${this.message}`);
131
+ this.frameIndex = (this.frameIndex + 1) % frames.length;
132
+ }, 80);
133
+ }
134
+ stop(success = true) {
135
+ if (this.interval) {
136
+ clearInterval(this.interval);
137
+ this.interval = null;
138
+ }
139
+ process.stdout.write("\x1B[?25h");
140
+ const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
141
+ process.stdout.write(`\r${icon} ${this.message}
142
+ `);
143
+ }
144
+ update(message) {
145
+ this.message = message;
146
+ }
147
+ };
148
+ function createSpinner(message) {
149
+ return new Spinner(message);
150
+ }
151
+
152
+ // src/generators/package-json.ts
153
+ function generatePackageJson(options) {
154
+ const pkg = {
155
+ name: options.projectName,
156
+ version: "0.1.0",
157
+ description: "ZK circuits built with IZI-NOIR",
158
+ type: "module",
159
+ main: "./dist/index.js",
160
+ types: "./dist/index.d.ts",
161
+ exports: {
162
+ ".": {
163
+ types: "./dist/index.d.ts",
164
+ import: "./dist/index.js"
165
+ },
166
+ "./circuits": {
167
+ types: "./circuits/index.d.ts",
168
+ import: "./circuits/index.js"
169
+ }
170
+ },
171
+ files: ["dist", "circuits", "generated"],
172
+ scripts: {
173
+ build: "izi-noir build && tsc",
174
+ "build:circuits": "izi-noir build",
175
+ dev: "izi-noir build --watch",
176
+ test: "tsx scripts/test-proof.ts",
177
+ prepublishOnly: "npm run build"
178
+ },
179
+ dependencies: {
180
+ "@izi-noir/sdk": "^0.1.0"
181
+ },
182
+ devDependencies: {
183
+ "@types/node": "^22.0.0",
184
+ tsx: "^4.0.0",
185
+ typescript: "^5.4.0"
186
+ },
187
+ keywords: ["zk", "noir", "zero-knowledge", "privacy", "solana"],
188
+ license: "MIT"
189
+ };
190
+ return JSON.stringify(pkg, null, 2);
191
+ }
192
+
193
+ // src/generators/tsconfig.ts
194
+ function generateTsconfig() {
195
+ const config = {
196
+ compilerOptions: {
197
+ target: "ES2022",
198
+ module: "ESNext",
199
+ moduleResolution: "bundler",
200
+ lib: ["ES2022"],
201
+ outDir: "./dist",
202
+ rootDir: ".",
203
+ strict: true,
204
+ esModuleInterop: true,
205
+ skipLibCheck: true,
206
+ forceConsistentCasingInFileNames: true,
207
+ declaration: true,
208
+ declarationMap: true,
209
+ sourceMap: true,
210
+ resolveJsonModule: true
211
+ },
212
+ include: ["circuits/**/*", "generated/**/*", "scripts/**/*"],
213
+ exclude: ["node_modules", "dist"]
214
+ };
215
+ return JSON.stringify(config, null, 2);
216
+ }
217
+
218
+ // src/generators/config.ts
219
+ function generateConfig(options) {
220
+ return `import { defineConfig } from '@izi-noir/sdk';
221
+
222
+ export default defineConfig({
223
+ // Directory containing your circuit files
224
+ circuitsDir: './circuits',
225
+
226
+ // Output directory for compiled circuits
227
+ outDir: './generated',
228
+
229
+ // Proving provider to use
230
+ provider: '${options.provider}',
231
+
232
+ // Enable watch mode optimizations
233
+ watch: {
234
+ // Debounce file changes (ms)
235
+ debounce: 100,
236
+ },
237
+ });
238
+ `;
239
+ }
240
+
241
+ // src/generators/circuits.ts
242
+ function generateBalanceProof() {
243
+ return `/**
244
+ * Balance Proof Circuit
245
+ *
246
+ * Proves that a private balance is greater than or equal to a public threshold
247
+ * without revealing the actual balance.
248
+ *
249
+ * @param threshold - The minimum required balance (public)
250
+ * @param balance - The actual balance to prove (private, not revealed)
251
+ */
252
+ export function balanceProof(
253
+ [threshold]: [number],
254
+ [balance]: [number]
255
+ ): void {
256
+ assert(balance >= threshold);
257
+ }
258
+ `;
259
+ }
260
+ function generateAgeProof() {
261
+ return `/**
262
+ * Age Proof Circuit
263
+ *
264
+ * Proves that a private birth year results in an age >= minimum age
265
+ * without revealing the actual birth year.
266
+ *
267
+ * @param currentYear - The current year (public)
268
+ * @param minAge - The minimum required age (public)
269
+ * @param birthYear - The actual birth year (private, not revealed)
270
+ */
271
+ export function ageProof(
272
+ [currentYear, minAge]: [number, number],
273
+ [birthYear]: [number]
274
+ ): void {
275
+ const age = currentYear - birthYear;
276
+ assert(age >= minAge);
277
+ }
278
+ `;
279
+ }
280
+ function generateMinimalCircuit() {
281
+ return `/**
282
+ * My Custom Circuit
283
+ *
284
+ * Replace this with your own circuit logic.
285
+ * Use assert() statements to define constraints.
286
+ *
287
+ * @param publicInput - A public input value
288
+ * @param privateInput - A private input value (not revealed)
289
+ */
290
+ export function myCircuit(
291
+ [publicInput]: [number],
292
+ [privateInput]: [number]
293
+ ): void {
294
+ // Example: prove that private input equals public input
295
+ assert(privateInput === publicInput);
296
+ }
297
+ `;
298
+ }
299
+ function generateCircuitsIndex(template) {
300
+ switch (template) {
301
+ case "minimal":
302
+ return `export { myCircuit } from './my-circuit.js';
303
+ `;
304
+ case "balance-proof":
305
+ return `export { balanceProof } from './balance-proof.js';
306
+ `;
307
+ default:
308
+ return `export { balanceProof } from './balance-proof.js';
309
+ export { ageProof } from './age-proof.js';
310
+ `;
311
+ }
312
+ }
313
+
314
+ // src/generators/scripts.ts
315
+ function generateTestScript(options) {
316
+ const imports = getImports(options.template);
317
+ const tests = getTests(options.template);
318
+ return `/**
319
+ * Test script for ZK proofs
320
+ *
321
+ * Run with: npm test
322
+ */
323
+ import { IziNoir, Provider } from '@izi-noir/sdk';
324
+ ${imports}
325
+
326
+ async function main() {
327
+ console.log('Initializing IZI-NOIR...');
328
+ const izi = await IziNoir.init({
329
+ provider: Provider.${capitalizeFirst(options.provider)},
330
+ });
331
+
332
+ ${tests}
333
+
334
+ console.log('\\n\u2713 All proofs verified successfully!');
335
+ }
336
+
337
+ main().catch((error) => {
338
+ console.error('Error:', error);
339
+ process.exit(1);
340
+ });
341
+ `;
342
+ }
343
+ function getImports(template) {
344
+ switch (template) {
345
+ case "minimal":
346
+ return `import { myCircuit } from '../circuits/index.js';`;
347
+ case "balance-proof":
348
+ return `import { balanceProof } from '../circuits/index.js';`;
349
+ default:
350
+ return `import { balanceProof, ageProof } from '../circuits/index.js';`;
351
+ }
352
+ }
353
+ function getTests(template) {
354
+ switch (template) {
355
+ case "minimal":
356
+ return ` // Test: myCircuit
357
+ console.log('\\nTesting myCircuit...');
358
+ const result1 = await izi.createProof(
359
+ myCircuit,
360
+ [42], // public: expected value
361
+ [42] // private: actual value
362
+ );
363
+ console.log(' Proof verified:', result1.verified);`;
364
+ case "balance-proof":
365
+ return ` // Test: Balance Proof
366
+ console.log('\\nTesting balanceProof...');
367
+ const result1 = await izi.createProof(
368
+ balanceProof,
369
+ [100], // public: threshold
370
+ [1500] // private: actual balance
371
+ );
372
+ console.log(' Proof verified:', result1.verified);
373
+ console.log(' The prover has >= 100 balance (actual: hidden)');`;
374
+ default:
375
+ return ` // Test 1: Balance Proof
376
+ console.log('\\nTesting balanceProof...');
377
+ const result1 = await izi.createProof(
378
+ balanceProof,
379
+ [100], // public: threshold
380
+ [1500] // private: actual balance
381
+ );
382
+ console.log(' Proof verified:', result1.verified);
383
+ console.log(' The prover has >= 100 balance (actual: hidden)');
384
+
385
+ // Test 2: Age Proof
386
+ console.log('\\nTesting ageProof...');
387
+ const result2 = await izi.createProof(
388
+ ageProof,
389
+ [2024, 18], // public: current year, minimum age
390
+ [1990] // private: birth year
391
+ );
392
+ console.log(' Proof verified:', result2.verified);
393
+ console.log(' The prover is >= 18 years old (birth year: hidden)');`;
394
+ }
395
+ }
396
+ function capitalizeFirst(str) {
397
+ return str.charAt(0).toUpperCase() + str.slice(1);
398
+ }
399
+
400
+ // src/generators/readme.ts
401
+ function generateReadme(options) {
402
+ return `# ${options.projectName}
403
+
404
+ ZK circuits built with [IZI-NOIR](https://github.com/izi-noir/izi-noir).
405
+
406
+ ## Getting Started
407
+
408
+ \`\`\`bash
409
+ # Build circuits
410
+ npm run build
411
+
412
+ # Run tests
413
+ npm test
414
+
415
+ # Watch mode (rebuild on changes)
416
+ npm run dev
417
+ \`\`\`
418
+
419
+ ## Project Structure
420
+
421
+ \`\`\`
422
+ ${options.projectName}/
423
+ \u251C\u2500\u2500 circuits/ # Your ZK circuit definitions
424
+ \u2502 \u251C\u2500\u2500 *.ts # Circuits as JS functions with assert()
425
+ \u2502 \u2514\u2500\u2500 index.ts # Re-exports
426
+ \u251C\u2500\u2500 generated/ # Compiled circuits (auto-generated)
427
+ \u2502 \u251C\u2500\u2500 *.json # Compiled circuit artifacts
428
+ \u2502 \u2514\u2500\u2500 index.ts # Typed re-exports
429
+ \u251C\u2500\u2500 scripts/
430
+ \u2502 \u2514\u2500\u2500 test-proof.ts # Local test script
431
+ \u251C\u2500\u2500 izi-noir.config.ts # Build configuration
432
+ \u2514\u2500\u2500 package.json
433
+ \`\`\`
434
+
435
+ ## Writing Circuits
436
+
437
+ Circuits are JavaScript functions with \`assert()\` statements:
438
+
439
+ \`\`\`typescript
440
+ // circuits/my-circuit.ts
441
+ export function myCircuit(
442
+ [publicInput]: [number],
443
+ [privateInput]: [number]
444
+ ): void {
445
+ assert(privateInput >= publicInput);
446
+ }
447
+ \`\`\`
448
+
449
+ ## Usage in Frontend
450
+
451
+ \`\`\`typescript
452
+ import { IziNoir, Provider } from '@izi-noir/sdk';
453
+ import { myCircuit } from '${options.projectName}/circuits';
454
+
455
+ const izi = await IziNoir.init({ provider: Provider.Arkworks });
456
+
457
+ const proof = await izi.createProof(
458
+ myCircuit,
459
+ [100], // public inputs
460
+ [1500] // private inputs (hidden)
461
+ );
462
+
463
+ console.log(proof.verified); // true
464
+ \`\`\`
465
+
466
+ ## Publishing
467
+
468
+ \`\`\`bash
469
+ npm publish
470
+ \`\`\`
471
+
472
+ Your circuits can then be installed as a dependency in other projects.
473
+
474
+ ## Learn More
475
+
476
+ - [IZI-NOIR Documentation](https://github.com/izi-noir/izi-noir)
477
+ - [Noir Language](https://noir-lang.org)
478
+ `;
479
+ }
480
+
481
+ // src/generators/gitignore.ts
482
+ function generateGitignore() {
483
+ return `# Dependencies
484
+ node_modules/
485
+
486
+ # Build output
487
+ dist/
488
+ generated/
489
+
490
+ # IDE
491
+ .idea/
492
+ .vscode/
493
+ *.swp
494
+ *.swo
495
+
496
+ # OS
497
+ .DS_Store
498
+ Thumbs.db
499
+
500
+ # Logs
501
+ *.log
502
+ npm-debug.log*
503
+
504
+ # Environment
505
+ .env
506
+ .env.local
507
+ .env.*.local
508
+
509
+ # Test coverage
510
+ coverage/
511
+ `;
512
+ }
513
+
514
+ // src/commands/init.ts
515
+ async function initCommand(projectName, options) {
516
+ let projectOptions;
517
+ if (options.yes && projectName) {
518
+ projectOptions = {
519
+ projectName,
520
+ template: options.template,
521
+ provider: options.provider,
522
+ skipInstall: options.skipInstall,
523
+ skipGit: options.skipGit
524
+ };
525
+ } else {
526
+ projectOptions = await promptProjectOptions({
527
+ projectName,
528
+ template: options.template,
529
+ provider: options.provider,
530
+ skipInstall: options.skipInstall,
531
+ skipGit: options.skipGit
532
+ });
533
+ }
534
+ if (!projectOptions) {
535
+ console.log(pc3.yellow("\nOperation cancelled."));
536
+ process.exit(0);
537
+ }
538
+ const projectDir = path2.resolve(process.cwd(), projectOptions.projectName);
539
+ if (await directoryExists(projectDir)) {
540
+ if (!await isDirectoryEmpty(projectDir)) {
541
+ console.log(
542
+ pc3.red(`
543
+ Error: Directory "${projectOptions.projectName}" already exists and is not empty.`)
544
+ );
545
+ process.exit(1);
546
+ }
547
+ }
548
+ console.log();
549
+ const spinner = createSpinner("Creating project structure...");
550
+ spinner.start();
551
+ try {
552
+ await createProjectStructure(projectDir, projectOptions);
553
+ spinner.stop(true);
554
+ } catch (error) {
555
+ spinner.stop(false);
556
+ console.error(pc3.red("\nFailed to create project structure:"), error);
557
+ process.exit(1);
558
+ }
559
+ if (!projectOptions.skipGit) {
560
+ const gitSpinner = createSpinner("Initializing git repository...");
561
+ gitSpinner.start();
562
+ try {
563
+ execSync("git init", { cwd: projectDir, stdio: "ignore" });
564
+ gitSpinner.stop(true);
565
+ } catch {
566
+ gitSpinner.stop(false);
567
+ console.log(pc3.yellow(" Warning: Failed to initialize git repository"));
568
+ }
569
+ }
570
+ if (!projectOptions.skipInstall) {
571
+ const installSpinner = createSpinner("Installing dependencies...");
572
+ installSpinner.start();
573
+ try {
574
+ execSync("npm install", { cwd: projectDir, stdio: "ignore" });
575
+ installSpinner.stop(true);
576
+ } catch {
577
+ installSpinner.stop(false);
578
+ console.log(pc3.yellow(' Warning: Failed to install dependencies. Run "npm install" manually.'));
579
+ }
580
+ }
581
+ printSuccessMessage(projectOptions);
582
+ }
583
+ async function createProjectStructure(projectDir, options) {
584
+ await ensureDir(path2.join(projectDir, "circuits"));
585
+ await ensureDir(path2.join(projectDir, "generated"));
586
+ await ensureDir(path2.join(projectDir, "scripts"));
587
+ const files = [
588
+ ["package.json", generatePackageJson(options)],
589
+ ["tsconfig.json", generateTsconfig()],
590
+ ["izi-noir.config.ts", generateConfig(options)],
591
+ ["README.md", generateReadme(options)],
592
+ [".gitignore", generateGitignore()],
593
+ ["scripts/test-proof.ts", generateTestScript(options)]
594
+ ];
595
+ switch (options.template) {
596
+ case "minimal":
597
+ files.push(["circuits/my-circuit.ts", generateMinimalCircuit()]);
598
+ break;
599
+ case "balance-proof":
600
+ files.push(["circuits/balance-proof.ts", generateBalanceProof()]);
601
+ break;
602
+ default:
603
+ files.push(["circuits/balance-proof.ts", generateBalanceProof()]);
604
+ files.push(["circuits/age-proof.ts", generateAgeProof()]);
605
+ break;
606
+ }
607
+ files.push(["circuits/index.ts", generateCircuitsIndex(options.template)]);
608
+ files.push([
609
+ "generated/.gitkeep",
610
+ "# This directory contains compiled circuit artifacts\n# Generated by: npm run build\n"
611
+ ]);
612
+ await Promise.all(
613
+ files.map(
614
+ ([relativePath, content]) => writeFile(path2.join(projectDir, relativePath), content)
615
+ )
616
+ );
617
+ }
618
+ function printSuccessMessage(options) {
619
+ console.log();
620
+ console.log(pc3.green("\u2713") + " Project created successfully!");
621
+ console.log();
622
+ console.log("Next steps:");
623
+ console.log();
624
+ console.log(pc3.cyan(` cd ${options.projectName}`));
625
+ if (options.skipInstall) {
626
+ console.log(pc3.cyan(" npm install"));
627
+ }
628
+ console.log(pc3.cyan(" npm run build"));
629
+ console.log(pc3.cyan(" npm test"));
630
+ console.log();
631
+ console.log("To start developing:");
632
+ console.log();
633
+ console.log(pc3.dim(" 1. Edit circuits in circuits/*.ts"));
634
+ console.log(pc3.dim(' 2. Run "npm run dev" for watch mode'));
635
+ console.log(pc3.dim(' 3. Test with "npm test"'));
636
+ console.log();
637
+ console.log(
638
+ pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
639
+ );
640
+ console.log();
641
+ }
642
+
643
+ // src/cli.ts
644
+ var VERSION = "0.1.0";
645
+ var cli = new Command().name("create-izi-noir").description("Create a new IZI-NOIR ZK project").version(VERSION).argument("[project-name]", "Name of the project to create").option("-t, --template <template>", "Template to use", "default").option("-p, --provider <provider>", "Proving provider", "arkworks").option("-y, --yes", "Skip prompts and use defaults", false).option("--skip-install", "Skip npm install", false).option("--skip-git", "Skip git initialization", false).action(initCommand);
646
+
647
+ // src/index.ts
648
+ cli.parse(process.argv);
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "create-izi-noir",
3
+ "version": "0.1.1",
4
+ "description": "CLI to scaffold IZI-NOIR ZK projects",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-izi-noir": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "templates"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format esm --dts --clean",
16
+ "dev": "tsup src/index.ts --format esm --watch",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "dependencies": {
20
+ "commander": "^12.0.0",
21
+ "prompts": "^2.4.2",
22
+ "picocolors": "^1.0.0",
23
+ "fs-extra": "^11.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/fs-extra": "^11.0.4",
27
+ "@types/node": "^22.0.0",
28
+ "@types/prompts": "^2.4.9",
29
+ "tsup": "^8.0.0",
30
+ "typescript": "^5.4.0"
31
+ },
32
+ "keywords": [
33
+ "zk",
34
+ "noir",
35
+ "solana",
36
+ "privacy",
37
+ "zero-knowledge",
38
+ "scaffold",
39
+ "cli"
40
+ ],
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/izi-noir/izi-noir.git",
45
+ "directory": "packages/create-izi-noir"
46
+ }
47
+ }