create-izi-noir 0.2.1 → 0.2.5
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/dist/index.js +358 -130
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import path2 from "path";
|
|
8
8
|
import { execSync } from "child_process";
|
|
9
|
-
import
|
|
9
|
+
import pc3 from "picocolors";
|
|
10
10
|
|
|
11
11
|
// src/prompts/project.ts
|
|
12
12
|
import prompts from "prompts";
|
|
@@ -17,8 +17,7 @@ var TEMPLATES = [
|
|
|
17
17
|
{ title: "Balance Proof only", value: "balance-proof" }
|
|
18
18
|
];
|
|
19
19
|
var NETWORKS = [
|
|
20
|
-
{ title: "Solana
|
|
21
|
-
{ title: "EVM (Ethereum, Base, etc.)", value: "evm", description: "Uses UltraHonk proofs" }
|
|
20
|
+
{ title: "Solana", value: "solana", description: "Uses Groth16 for on-chain verification" }
|
|
22
21
|
];
|
|
23
22
|
function networkToProvider(network) {
|
|
24
23
|
return network === "solana" ? "arkworks" : "barretenberg";
|
|
@@ -117,44 +116,8 @@ async function isDirectoryEmpty(dir) {
|
|
|
117
116
|
}
|
|
118
117
|
}
|
|
119
118
|
|
|
120
|
-
// src/utils/spinner.ts
|
|
121
|
-
import pc2 from "picocolors";
|
|
122
|
-
var frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
123
|
-
var Spinner = class {
|
|
124
|
-
message;
|
|
125
|
-
interval = null;
|
|
126
|
-
frameIndex = 0;
|
|
127
|
-
constructor(message) {
|
|
128
|
-
this.message = message;
|
|
129
|
-
}
|
|
130
|
-
start() {
|
|
131
|
-
process.stdout.write("\x1B[?25l");
|
|
132
|
-
this.interval = setInterval(() => {
|
|
133
|
-
const frame = pc2.cyan(frames[this.frameIndex]);
|
|
134
|
-
process.stdout.write(`\r${frame} ${this.message}`);
|
|
135
|
-
this.frameIndex = (this.frameIndex + 1) % frames.length;
|
|
136
|
-
}, 80);
|
|
137
|
-
}
|
|
138
|
-
stop(success = true) {
|
|
139
|
-
if (this.interval) {
|
|
140
|
-
clearInterval(this.interval);
|
|
141
|
-
this.interval = null;
|
|
142
|
-
}
|
|
143
|
-
process.stdout.write("\x1B[?25h");
|
|
144
|
-
const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
|
|
145
|
-
process.stdout.write(`\r${icon} ${this.message}
|
|
146
|
-
`);
|
|
147
|
-
}
|
|
148
|
-
update(message) {
|
|
149
|
-
this.message = message;
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
function createSpinner(message) {
|
|
153
|
-
return new Spinner(message);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
119
|
// src/utils/progress.ts
|
|
157
|
-
import
|
|
120
|
+
import pc2 from "picocolors";
|
|
158
121
|
var THINKING_PHRASES = [
|
|
159
122
|
"Initializing ZK environment",
|
|
160
123
|
"Configuring proof system",
|
|
@@ -191,15 +154,15 @@ var ProgressReporter = class {
|
|
|
191
154
|
this.showThinking();
|
|
192
155
|
}
|
|
193
156
|
showThinking() {
|
|
194
|
-
const
|
|
157
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
195
158
|
let frameIndex = 0;
|
|
196
159
|
let dotCount = 0;
|
|
197
160
|
this.thinkingInterval = setInterval(() => {
|
|
198
|
-
const frame =
|
|
161
|
+
const frame = pc2.cyan(frames[frameIndex]);
|
|
199
162
|
const phrase = THINKING_PHRASES[this.thinkingIndex % THINKING_PHRASES.length];
|
|
200
163
|
const dots = ".".repeat(dotCount % 4);
|
|
201
|
-
process.stdout.write(`\r${frame} ${
|
|
202
|
-
frameIndex = (frameIndex + 1) %
|
|
164
|
+
process.stdout.write(`\r${frame} ${pc2.dim(phrase)}${dots} `);
|
|
165
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
203
166
|
dotCount++;
|
|
204
167
|
if (dotCount % 12 === 0) {
|
|
205
168
|
this.thinkingIndex++;
|
|
@@ -215,29 +178,29 @@ var ProgressReporter = class {
|
|
|
215
178
|
}
|
|
216
179
|
async reportFile(filename, isLast = false) {
|
|
217
180
|
const icon = getFileIcon(filename);
|
|
218
|
-
const line = ` ${icon} ${
|
|
219
|
-
process.stdout.write(" " + icon + " " +
|
|
181
|
+
const line = ` ${icon} ${pc2.dim("created")} ${pc2.white(filename)}`;
|
|
182
|
+
process.stdout.write(" " + icon + " " + pc2.dim("created") + " ");
|
|
220
183
|
for (const char of filename) {
|
|
221
|
-
process.stdout.write(
|
|
184
|
+
process.stdout.write(pc2.white(char));
|
|
222
185
|
await sleep(8 + Math.random() * 12);
|
|
223
186
|
}
|
|
224
187
|
process.stdout.write("\n");
|
|
225
188
|
this.currentLine = line;
|
|
226
189
|
}
|
|
227
190
|
async reportDirectory(dirname) {
|
|
228
|
-
process.stdout.write(` \u{1F4C1} ${
|
|
191
|
+
process.stdout.write(` \u{1F4C1} ${pc2.dim("mkdir")} ${pc2.blue(dirname)}/
|
|
229
192
|
`);
|
|
230
193
|
await sleep(30);
|
|
231
194
|
}
|
|
232
195
|
showSuccess(message) {
|
|
233
196
|
process.stdout.write("\x1B[?25h");
|
|
234
197
|
console.log();
|
|
235
|
-
console.log(
|
|
198
|
+
console.log(pc2.green("\u2713") + " " + message);
|
|
236
199
|
}
|
|
237
200
|
showError(message) {
|
|
238
201
|
process.stdout.write("\x1B[?25h");
|
|
239
202
|
console.log();
|
|
240
|
-
console.log(
|
|
203
|
+
console.log(pc2.red("\u2717") + " " + message);
|
|
241
204
|
}
|
|
242
205
|
};
|
|
243
206
|
function createProgressReporter() {
|
|
@@ -260,18 +223,18 @@ var InstallProgress = class {
|
|
|
260
223
|
start() {
|
|
261
224
|
process.stdout.write("\x1B[?25l");
|
|
262
225
|
const barWidth = 30;
|
|
263
|
-
const
|
|
226
|
+
const frames = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
264
227
|
let frameIndex = 0;
|
|
265
228
|
this.interval = setInterval(() => {
|
|
266
|
-
const frame =
|
|
229
|
+
const frame = pc2.cyan(frames[frameIndex]);
|
|
267
230
|
const filled = Math.floor(this.progress / 100 * barWidth);
|
|
268
231
|
const empty = barWidth - filled;
|
|
269
|
-
const bar =
|
|
232
|
+
const bar = pc2.green("\u2588".repeat(filled)) + pc2.dim("\u2591".repeat(empty));
|
|
270
233
|
const pkg = this.packages[this.currentPackage % this.packages.length];
|
|
271
234
|
process.stdout.write(
|
|
272
|
-
`\r${frame} Installing dependencies ${bar} ${
|
|
235
|
+
`\r${frame} Installing dependencies ${bar} ${pc2.dim(pkg)} `
|
|
273
236
|
);
|
|
274
|
-
frameIndex = (frameIndex + 1) %
|
|
237
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
275
238
|
if (this.progress < 95) {
|
|
276
239
|
this.progress += Math.random() * 3;
|
|
277
240
|
if (this.progress > (this.currentPackage + 1) * 12) {
|
|
@@ -287,7 +250,7 @@ var InstallProgress = class {
|
|
|
287
250
|
}
|
|
288
251
|
process.stdout.write("\x1B[?25h");
|
|
289
252
|
process.stdout.write("\r\x1B[K");
|
|
290
|
-
const icon = success ?
|
|
253
|
+
const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
|
|
291
254
|
const message = success ? "Dependencies installed" : "Failed to install dependencies";
|
|
292
255
|
console.log(`${icon} ${message}`);
|
|
293
256
|
}
|
|
@@ -295,17 +258,61 @@ var InstallProgress = class {
|
|
|
295
258
|
function createInstallProgress() {
|
|
296
259
|
return new InstallProgress();
|
|
297
260
|
}
|
|
261
|
+
var GitProgress = class {
|
|
262
|
+
interval = null;
|
|
263
|
+
phases = [
|
|
264
|
+
"Initializing repository",
|
|
265
|
+
"Setting up version control",
|
|
266
|
+
"Creating .git directory",
|
|
267
|
+
"Configuring git objects",
|
|
268
|
+
"Preparing initial branch"
|
|
269
|
+
];
|
|
270
|
+
phaseIndex = 0;
|
|
271
|
+
dotCount = 0;
|
|
272
|
+
start() {
|
|
273
|
+
process.stdout.write("\x1B[?25l");
|
|
274
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
275
|
+
let frameIndex = 0;
|
|
276
|
+
this.interval = setInterval(() => {
|
|
277
|
+
const frame = pc2.cyan(frames[frameIndex]);
|
|
278
|
+
const phase = this.phases[this.phaseIndex % this.phases.length];
|
|
279
|
+
const dots = ".".repeat(this.dotCount % 4);
|
|
280
|
+
process.stdout.write(`\r${frame} ${pc2.dim(phase)}${dots} `);
|
|
281
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
282
|
+
this.dotCount++;
|
|
283
|
+
if (this.dotCount % 8 === 0) {
|
|
284
|
+
this.phaseIndex++;
|
|
285
|
+
}
|
|
286
|
+
}, 80);
|
|
287
|
+
}
|
|
288
|
+
stop(success = true) {
|
|
289
|
+
if (this.interval) {
|
|
290
|
+
clearInterval(this.interval);
|
|
291
|
+
this.interval = null;
|
|
292
|
+
}
|
|
293
|
+
process.stdout.write("\x1B[?25h");
|
|
294
|
+
process.stdout.write("\r\x1B[K");
|
|
295
|
+
const icon = success ? pc2.green("\u2713") : pc2.red("\u2717");
|
|
296
|
+
const message = success ? "Git repository initialized" : "Failed to initialize git";
|
|
297
|
+
console.log(`${icon} ${message}`);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
function createGitProgress() {
|
|
301
|
+
return new GitProgress();
|
|
302
|
+
}
|
|
298
303
|
|
|
299
304
|
// src/generators/package-json.ts
|
|
300
305
|
function generatePackageJson(options) {
|
|
301
306
|
const isSolana = options.provider === "arkworks";
|
|
302
307
|
const dependencies = {
|
|
303
|
-
"@izi-noir/sdk": "^0.1.
|
|
308
|
+
"@izi-noir/sdk": "^0.1.5",
|
|
304
309
|
"@noir-lang/acvm_js": "1.0.0-beta.13-1d260df.nightly",
|
|
305
310
|
"@noir-lang/noirc_abi": "1.0.0-beta.13-1d260df.nightly",
|
|
306
311
|
"react": "^18.3.1",
|
|
307
312
|
"react-dom": "^18.3.1",
|
|
308
|
-
"prism-react-renderer": "^2.4.1"
|
|
313
|
+
"prism-react-renderer": "^2.4.1",
|
|
314
|
+
"buffer": "^6.0.3",
|
|
315
|
+
"util": "^0.12.5"
|
|
309
316
|
};
|
|
310
317
|
if (isSolana) {
|
|
311
318
|
dependencies["@solana/wallet-adapter-react"] = "^0.15.0";
|
|
@@ -592,14 +599,23 @@ export default defineConfig({
|
|
|
592
599
|
alias: {
|
|
593
600
|
"@": path.resolve(__dirname, "./src"),
|
|
594
601
|
buffer: "buffer/",
|
|
602
|
+
util: "util/",
|
|
595
603
|
},
|
|
596
604
|
},
|
|
597
605
|
define: {
|
|
598
606
|
"global": "globalThis",
|
|
607
|
+
"process.env": {},
|
|
599
608
|
},
|
|
600
609
|
optimizeDeps: {
|
|
601
|
-
exclude: [
|
|
602
|
-
|
|
610
|
+
exclude: [
|
|
611
|
+
"@noir-lang/noir_wasm",
|
|
612
|
+
"@noir-lang/noir_js",
|
|
613
|
+
"@noir-lang/acvm_js",
|
|
614
|
+
"@noir-lang/noirc_abi",
|
|
615
|
+
"@aztec/bb.js",
|
|
616
|
+
"@izi-noir/sdk",
|
|
617
|
+
],
|
|
618
|
+
include: ["buffer", "util"],
|
|
603
619
|
},
|
|
604
620
|
build: {
|
|
605
621
|
rollupOptions: {
|
|
@@ -633,6 +649,9 @@ function generateIndexHtml(options) {
|
|
|
633
649
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
634
650
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
635
651
|
<title>${options.projectName} - ZK Proof Demo</title>
|
|
652
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
653
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
654
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
636
655
|
</head>
|
|
637
656
|
<body>
|
|
638
657
|
<div id="root"></div>
|
|
@@ -765,10 +784,17 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
|
|
|
765
784
|
</div>
|
|
766
785
|
|
|
767
786
|
<div className="verify-box">
|
|
787
|
+
{publicInputs && (
|
|
788
|
+
<div className="public-inputs-display">
|
|
789
|
+
<span>Public inputs:</span>
|
|
790
|
+
<code>{JSON.stringify(publicInputs)}</code>
|
|
791
|
+
</div>
|
|
792
|
+
)}
|
|
768
793
|
<button
|
|
769
794
|
onClick={handleVerify}
|
|
770
795
|
disabled={!vkAccount || isVerifying}
|
|
771
796
|
className="btn btn-primary"
|
|
797
|
+
style={{ marginTop: publicInputs ? '0.5rem' : 0 }}
|
|
772
798
|
>
|
|
773
799
|
{isVerifying ? 'Verifying...' : verified ? 'Verified!' : 'Verify On-Chain'}
|
|
774
800
|
</button>
|
|
@@ -836,6 +862,7 @@ function App() {
|
|
|
836
862
|
const [proofTime, setProofTime] = useState<number | null>(null);
|
|
837
863
|
const [proofError, setProofError] = useState<string | null>(null);
|
|
838
864
|
const [localVerified, setLocalVerified] = useState<boolean | null>(null);
|
|
865
|
+
const [publicInputs, setPublicInputs] = useState<string[] | null>(null);
|
|
839
866
|
|
|
840
867
|
// IziNoir instance
|
|
841
868
|
const [iziInstance, setIziInstance] = useState<IziNoir | null>(null);
|
|
@@ -852,6 +879,7 @@ ${solanaState}
|
|
|
852
879
|
setProof(null);
|
|
853
880
|
setProofTime(null);
|
|
854
881
|
setLocalVerified(null);
|
|
882
|
+
setPublicInputs(null);
|
|
855
883
|
setNoirCode(null);
|
|
856
884
|
}
|
|
857
885
|
}, [selectedCircuit]);
|
|
@@ -924,6 +952,7 @@ ${solanaState}
|
|
|
924
952
|
const endTime = performance.now();
|
|
925
953
|
setProof(proofBytes);
|
|
926
954
|
setProofTime(Math.round(endTime - startTime));
|
|
955
|
+
setPublicInputs(publicInputsHex);
|
|
927
956
|
} catch (error) {
|
|
928
957
|
console.error('Proof generation error:', error);
|
|
929
958
|
setProofError((error as Error).message);
|
|
@@ -937,7 +966,7 @@ ${solanaHandlers}
|
|
|
937
966
|
<div className="app">
|
|
938
967
|
<header>
|
|
939
968
|
<h1>${options.projectName}</h1>
|
|
940
|
-
<p>
|
|
969
|
+
<p>Built with IZI-NOIR</p>
|
|
941
970
|
</header>
|
|
942
971
|
|
|
943
972
|
<main>
|
|
@@ -1100,29 +1129,65 @@ function capitalizeFirst(str) {
|
|
|
1100
1129
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1101
1130
|
}
|
|
1102
1131
|
function generateAppCss() {
|
|
1103
|
-
return
|
|
1132
|
+
return `/* ================================
|
|
1133
|
+
CSS Variables - IZI-NOIR Theme
|
|
1134
|
+
================================ */
|
|
1135
|
+
:root {
|
|
1136
|
+
--solana-purple: #9945FF;
|
|
1137
|
+
--solana-green: #14F195;
|
|
1138
|
+
--noir-primary: #050505;
|
|
1139
|
+
--noir-elevated: #0A0A0A;
|
|
1140
|
+
--noir-orange: #FF6B35;
|
|
1141
|
+
--izi-cyan: #00D4FF;
|
|
1142
|
+
--text: #ffffff;
|
|
1143
|
+
--text-muted: #888888;
|
|
1144
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/* ================================
|
|
1148
|
+
Reset & Base Styles
|
|
1149
|
+
================================ */
|
|
1150
|
+
* {
|
|
1104
1151
|
box-sizing: border-box;
|
|
1105
1152
|
margin: 0;
|
|
1106
1153
|
padding: 0;
|
|
1107
1154
|
}
|
|
1108
1155
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
--green: #14F195;
|
|
1112
|
-
--bg: #0a0a0a;
|
|
1113
|
-
--bg-elevated: #111111;
|
|
1114
|
-
--border: #222222;
|
|
1115
|
-
--text: #ffffff;
|
|
1116
|
-
--text-muted: #888888;
|
|
1156
|
+
html {
|
|
1157
|
+
scroll-behavior: smooth;
|
|
1117
1158
|
}
|
|
1118
1159
|
|
|
1119
1160
|
body {
|
|
1120
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
|
1121
|
-
background: var(--
|
|
1161
|
+
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
1162
|
+
background-color: var(--noir-primary);
|
|
1163
|
+
/* Noise texture + radial gradients like the main frontend */
|
|
1164
|
+
background-image:
|
|
1165
|
+
url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.015'/%3E%3C/svg%3E"),
|
|
1166
|
+
radial-gradient(
|
|
1167
|
+
ellipse 60% 40% at 50% 30%,
|
|
1168
|
+
rgba(153, 69, 255, 0.06) 0%,
|
|
1169
|
+
transparent 50%
|
|
1170
|
+
),
|
|
1171
|
+
radial-gradient(
|
|
1172
|
+
ellipse 80% 50% at 50% 110%,
|
|
1173
|
+
rgba(20, 241, 149, 0.04) 0%,
|
|
1174
|
+
transparent 40%
|
|
1175
|
+
);
|
|
1176
|
+
background-attachment: fixed;
|
|
1122
1177
|
color: var(--text);
|
|
1123
1178
|
line-height: 1.6;
|
|
1179
|
+
-webkit-font-smoothing: antialiased;
|
|
1180
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
::selection {
|
|
1184
|
+
background: rgba(153, 69, 255, 0.3);
|
|
1185
|
+
color: white;
|
|
1124
1186
|
}
|
|
1125
1187
|
|
|
1188
|
+
/* ================================
|
|
1189
|
+
Layout
|
|
1190
|
+
================================ */
|
|
1126
1191
|
.app {
|
|
1127
1192
|
min-height: 100vh;
|
|
1128
1193
|
display: flex;
|
|
@@ -1133,11 +1198,14 @@ header {
|
|
|
1133
1198
|
padding: 2rem;
|
|
1134
1199
|
text-align: center;
|
|
1135
1200
|
border-bottom: 1px solid var(--border);
|
|
1201
|
+
backdrop-filter: blur(8px);
|
|
1202
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1136
1203
|
}
|
|
1137
1204
|
|
|
1138
1205
|
header h1 {
|
|
1139
1206
|
font-size: 2rem;
|
|
1140
|
-
|
|
1207
|
+
font-weight: 700;
|
|
1208
|
+
background: linear-gradient(135deg, var(--solana-purple) 0%, var(--noir-orange) 100%);
|
|
1141
1209
|
-webkit-background-clip: text;
|
|
1142
1210
|
-webkit-text-fill-color: transparent;
|
|
1143
1211
|
background-clip: text;
|
|
@@ -1156,34 +1224,51 @@ main {
|
|
|
1156
1224
|
width: 100%;
|
|
1157
1225
|
}
|
|
1158
1226
|
|
|
1227
|
+
/* ================================
|
|
1228
|
+
Section Cards - Glassmorphism
|
|
1229
|
+
================================ */
|
|
1159
1230
|
.section {
|
|
1160
1231
|
margin-bottom: 2rem;
|
|
1161
1232
|
padding: 1.5rem;
|
|
1162
|
-
background:
|
|
1233
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1234
|
+
backdrop-filter: blur(8px);
|
|
1163
1235
|
border: 1px solid var(--border);
|
|
1164
|
-
border-radius:
|
|
1236
|
+
border-radius: 16px;
|
|
1237
|
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
.section:hover {
|
|
1241
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
1242
|
+
box-shadow: 0 0 30px rgba(153, 69, 255, 0.1);
|
|
1165
1243
|
}
|
|
1166
1244
|
|
|
1167
1245
|
.section h2 {
|
|
1168
1246
|
font-size: 1.25rem;
|
|
1247
|
+
font-weight: 600;
|
|
1169
1248
|
margin-bottom: 1rem;
|
|
1170
1249
|
color: var(--text);
|
|
1171
1250
|
}
|
|
1172
1251
|
|
|
1252
|
+
/* ================================
|
|
1253
|
+
Form Controls
|
|
1254
|
+
================================ */
|
|
1173
1255
|
.select {
|
|
1174
1256
|
width: 100%;
|
|
1175
|
-
padding: 0.75rem;
|
|
1176
|
-
background:
|
|
1257
|
+
padding: 0.75rem 1rem;
|
|
1258
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1177
1259
|
border: 1px solid var(--border);
|
|
1178
|
-
border-radius:
|
|
1260
|
+
border-radius: 12px;
|
|
1179
1261
|
color: var(--text);
|
|
1262
|
+
font-family: inherit;
|
|
1180
1263
|
font-size: 1rem;
|
|
1181
1264
|
cursor: pointer;
|
|
1265
|
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
1182
1266
|
}
|
|
1183
1267
|
|
|
1184
1268
|
.select:focus {
|
|
1185
1269
|
outline: none;
|
|
1186
|
-
border-color: var(--purple);
|
|
1270
|
+
border-color: var(--solana-purple);
|
|
1271
|
+
box-shadow: 0 0 20px rgba(153, 69, 255, 0.2);
|
|
1187
1272
|
}
|
|
1188
1273
|
|
|
1189
1274
|
.inputs-grid {
|
|
@@ -1208,71 +1293,93 @@ main {
|
|
|
1208
1293
|
|
|
1209
1294
|
.input-badge {
|
|
1210
1295
|
font-size: 0.625rem;
|
|
1211
|
-
padding: 0.125rem 0.
|
|
1212
|
-
border-radius:
|
|
1296
|
+
padding: 0.125rem 0.5rem;
|
|
1297
|
+
border-radius: 6px;
|
|
1213
1298
|
text-transform: uppercase;
|
|
1214
1299
|
font-weight: 600;
|
|
1300
|
+
letter-spacing: 0.05em;
|
|
1215
1301
|
}
|
|
1216
1302
|
|
|
1217
1303
|
.input-badge.public {
|
|
1218
|
-
background:
|
|
1219
|
-
color:
|
|
1304
|
+
background: rgba(20, 241, 149, 0.2);
|
|
1305
|
+
color: var(--solana-green);
|
|
1306
|
+
border: 1px solid rgba(20, 241, 149, 0.3);
|
|
1220
1307
|
}
|
|
1221
1308
|
|
|
1222
1309
|
.input-badge.private {
|
|
1223
|
-
background:
|
|
1224
|
-
color:
|
|
1310
|
+
background: rgba(153, 69, 255, 0.2);
|
|
1311
|
+
color: var(--solana-purple);
|
|
1312
|
+
border: 1px solid rgba(153, 69, 255, 0.3);
|
|
1225
1313
|
}
|
|
1226
1314
|
|
|
1227
1315
|
.input-group input {
|
|
1228
|
-
padding: 0.75rem;
|
|
1229
|
-
background:
|
|
1316
|
+
padding: 0.75rem 1rem;
|
|
1317
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1230
1318
|
border: 1px solid var(--border);
|
|
1231
|
-
border-radius:
|
|
1319
|
+
border-radius: 12px;
|
|
1232
1320
|
color: var(--text);
|
|
1321
|
+
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
|
1233
1322
|
font-size: 1rem;
|
|
1323
|
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
1234
1324
|
}
|
|
1235
1325
|
|
|
1236
1326
|
.input-group input:focus {
|
|
1237
1327
|
outline: none;
|
|
1238
|
-
border-color: var(--purple);
|
|
1328
|
+
border-color: var(--solana-purple);
|
|
1329
|
+
box-shadow: 0 0 20px rgba(153, 69, 255, 0.2);
|
|
1239
1330
|
}
|
|
1240
1331
|
|
|
1332
|
+
/* ================================
|
|
1333
|
+
Buttons - Animated Gradient
|
|
1334
|
+
================================ */
|
|
1241
1335
|
.btn {
|
|
1242
1336
|
padding: 0.75rem 1.5rem;
|
|
1243
1337
|
font-size: 1rem;
|
|
1244
1338
|
font-weight: 600;
|
|
1245
1339
|
border: none;
|
|
1246
|
-
border-radius:
|
|
1340
|
+
border-radius: 12px;
|
|
1247
1341
|
cursor: pointer;
|
|
1248
|
-
transition: all 0.
|
|
1342
|
+
transition: all 0.3s ease;
|
|
1249
1343
|
}
|
|
1250
1344
|
|
|
1251
1345
|
.btn:disabled {
|
|
1252
|
-
opacity: 0.
|
|
1346
|
+
opacity: 0.4;
|
|
1253
1347
|
cursor: not-allowed;
|
|
1254
1348
|
}
|
|
1255
1349
|
|
|
1256
1350
|
.btn-primary {
|
|
1257
|
-
background: linear-gradient(
|
|
1351
|
+
background: linear-gradient(
|
|
1352
|
+
90deg,
|
|
1353
|
+
var(--solana-purple) 0%,
|
|
1354
|
+
var(--solana-purple) 50%,
|
|
1355
|
+
var(--solana-green) 100%
|
|
1356
|
+
);
|
|
1357
|
+
background-size: 200% 100%;
|
|
1358
|
+
background-position: 0% 0%;
|
|
1258
1359
|
color: white;
|
|
1360
|
+
box-shadow: 0 0 20px rgba(153, 69, 255, 0.3);
|
|
1259
1361
|
}
|
|
1260
1362
|
|
|
1261
1363
|
.btn-primary:hover:not(:disabled) {
|
|
1364
|
+
background-position: 100% 0%;
|
|
1262
1365
|
transform: translateY(-2px);
|
|
1263
|
-
box-shadow: 0
|
|
1366
|
+
box-shadow: 0 0 30px rgba(20, 241, 149, 0.3);
|
|
1264
1367
|
}
|
|
1265
1368
|
|
|
1266
1369
|
.btn-secondary {
|
|
1267
|
-
background:
|
|
1370
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1268
1371
|
border: 1px solid var(--border);
|
|
1269
1372
|
color: var(--text);
|
|
1270
1373
|
}
|
|
1271
1374
|
|
|
1272
1375
|
.btn-secondary:hover:not(:disabled) {
|
|
1273
|
-
border-color: var(--purple);
|
|
1376
|
+
border-color: var(--solana-purple);
|
|
1377
|
+
box-shadow: 0 0 20px rgba(153, 69, 255, 0.15);
|
|
1274
1378
|
}
|
|
1275
1379
|
|
|
1380
|
+
/* ================================
|
|
1381
|
+
Results Grid
|
|
1382
|
+
================================ */
|
|
1276
1383
|
.results {
|
|
1277
1384
|
display: grid;
|
|
1278
1385
|
grid-template-columns: repeat(3, 1fr);
|
|
@@ -1280,22 +1387,36 @@ main {
|
|
|
1280
1387
|
margin-top: 1rem;
|
|
1281
1388
|
}
|
|
1282
1389
|
|
|
1390
|
+
@media (max-width: 640px) {
|
|
1391
|
+
.results {
|
|
1392
|
+
grid-template-columns: 1fr;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1283
1396
|
.result-card {
|
|
1284
|
-
padding:
|
|
1285
|
-
background:
|
|
1397
|
+
padding: 1.25rem;
|
|
1398
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1286
1399
|
border: 1px solid var(--border);
|
|
1287
|
-
border-radius:
|
|
1400
|
+
border-radius: 12px;
|
|
1288
1401
|
text-align: center;
|
|
1402
|
+
transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
.result-card:hover {
|
|
1406
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
1407
|
+
transform: translateY(-4px);
|
|
1408
|
+
box-shadow: 0 0 25px rgba(153, 69, 255, 0.15);
|
|
1289
1409
|
}
|
|
1290
1410
|
|
|
1291
1411
|
.result-value {
|
|
1292
|
-
font-size: 1.
|
|
1293
|
-
font-weight:
|
|
1412
|
+
font-size: 1.5rem;
|
|
1413
|
+
font-weight: 700;
|
|
1414
|
+
font-family: 'JetBrains Mono', monospace;
|
|
1294
1415
|
display: block;
|
|
1295
1416
|
}
|
|
1296
1417
|
|
|
1297
1418
|
.result-value.success {
|
|
1298
|
-
color: var(--green);
|
|
1419
|
+
color: var(--solana-green);
|
|
1299
1420
|
}
|
|
1300
1421
|
|
|
1301
1422
|
.result-value.error {
|
|
@@ -1306,22 +1427,40 @@ main {
|
|
|
1306
1427
|
font-size: 0.75rem;
|
|
1307
1428
|
color: var(--text-muted);
|
|
1308
1429
|
text-transform: uppercase;
|
|
1309
|
-
|
|
1430
|
+
letter-spacing: 0.1em;
|
|
1431
|
+
margin-top: 0.5rem;
|
|
1310
1432
|
display: block;
|
|
1311
1433
|
}
|
|
1312
1434
|
|
|
1435
|
+
/* ================================
|
|
1436
|
+
Messages
|
|
1437
|
+
================================ */
|
|
1313
1438
|
.error {
|
|
1314
|
-
color: #
|
|
1439
|
+
color: #ff6b6b;
|
|
1315
1440
|
font-size: 0.875rem;
|
|
1316
1441
|
margin-top: 0.5rem;
|
|
1442
|
+
padding: 0.75rem 1rem;
|
|
1443
|
+
background: rgba(255, 107, 107, 0.1);
|
|
1444
|
+
border: 1px solid rgba(255, 107, 107, 0.2);
|
|
1445
|
+
border-radius: 8px;
|
|
1446
|
+
word-break: break-word;
|
|
1447
|
+
overflow-wrap: break-word;
|
|
1448
|
+
max-width: 100%;
|
|
1317
1449
|
}
|
|
1318
1450
|
|
|
1319
1451
|
.success {
|
|
1320
|
-
color: var(--green);
|
|
1452
|
+
color: var(--solana-green);
|
|
1321
1453
|
font-size: 0.875rem;
|
|
1322
1454
|
margin-top: 0.5rem;
|
|
1455
|
+
padding: 0.75rem 1rem;
|
|
1456
|
+
background: rgba(20, 241, 149, 0.1);
|
|
1457
|
+
border: 1px solid rgba(20, 241, 149, 0.2);
|
|
1458
|
+
border-radius: 8px;
|
|
1323
1459
|
}
|
|
1324
1460
|
|
|
1461
|
+
/* ================================
|
|
1462
|
+
Noir Code Details
|
|
1463
|
+
================================ */
|
|
1325
1464
|
.noir-details {
|
|
1326
1465
|
margin-top: 1rem;
|
|
1327
1466
|
}
|
|
@@ -1330,12 +1469,21 @@ main {
|
|
|
1330
1469
|
cursor: pointer;
|
|
1331
1470
|
color: var(--text-muted);
|
|
1332
1471
|
font-size: 0.875rem;
|
|
1472
|
+
padding: 0.5rem 0;
|
|
1473
|
+
transition: color 0.3s ease;
|
|
1333
1474
|
}
|
|
1334
1475
|
|
|
1335
1476
|
.noir-details summary:hover {
|
|
1336
|
-
color: var(--
|
|
1477
|
+
color: var(--solana-purple);
|
|
1337
1478
|
}
|
|
1338
1479
|
|
|
1480
|
+
.noir-details[open] summary {
|
|
1481
|
+
color: var(--solana-purple);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
/* ================================
|
|
1485
|
+
Deploy & Verify Section
|
|
1486
|
+
================================ */
|
|
1339
1487
|
.deploy-verify-row {
|
|
1340
1488
|
display: grid;
|
|
1341
1489
|
grid-template-columns: 1fr 1fr;
|
|
@@ -1343,38 +1491,118 @@ main {
|
|
|
1343
1491
|
margin-top: 1rem;
|
|
1344
1492
|
}
|
|
1345
1493
|
|
|
1494
|
+
@media (max-width: 640px) {
|
|
1495
|
+
.deploy-verify-row {
|
|
1496
|
+
grid-template-columns: 1fr;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1346
1500
|
.deploy-box,
|
|
1347
1501
|
.verify-box {
|
|
1348
|
-
padding:
|
|
1349
|
-
background:
|
|
1502
|
+
padding: 1.25rem;
|
|
1503
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1504
|
+
border: 1px solid var(--border);
|
|
1505
|
+
border-radius: 12px;
|
|
1506
|
+
overflow: hidden;
|
|
1507
|
+
word-break: break-word;
|
|
1508
|
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
.deploy-box:hover,
|
|
1512
|
+
.verify-box:hover {
|
|
1513
|
+
border-color: rgba(255, 255, 255, 0.15);
|
|
1514
|
+
box-shadow: 0 0 20px rgba(153, 69, 255, 0.1);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
.public-inputs-display {
|
|
1518
|
+
margin-top: 0.75rem;
|
|
1519
|
+
font-size: 0.75rem;
|
|
1520
|
+
color: var(--text-muted);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
.public-inputs-display code {
|
|
1524
|
+
display: block;
|
|
1525
|
+
margin-top: 0.5rem;
|
|
1526
|
+
padding: 0.75rem;
|
|
1527
|
+
background: rgba(0, 0, 0, 0.4);
|
|
1350
1528
|
border: 1px solid var(--border);
|
|
1351
1529
|
border-radius: 8px;
|
|
1530
|
+
font-family: 'JetBrains Mono', monospace;
|
|
1531
|
+
font-size: 0.7rem;
|
|
1532
|
+
overflow-x: auto;
|
|
1533
|
+
max-width: 100%;
|
|
1352
1534
|
}
|
|
1353
1535
|
|
|
1536
|
+
/* ================================
|
|
1537
|
+
Footer
|
|
1538
|
+
================================ */
|
|
1354
1539
|
footer {
|
|
1355
1540
|
padding: 1.5rem;
|
|
1356
1541
|
text-align: center;
|
|
1357
1542
|
border-top: 1px solid var(--border);
|
|
1543
|
+
backdrop-filter: blur(8px);
|
|
1544
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1358
1545
|
color: var(--text-muted);
|
|
1359
1546
|
font-size: 0.875rem;
|
|
1360
1547
|
}
|
|
1361
1548
|
|
|
1362
1549
|
footer a {
|
|
1363
|
-
color: var(--purple);
|
|
1550
|
+
color: var(--solana-purple);
|
|
1364
1551
|
text-decoration: none;
|
|
1552
|
+
transition: color 0.3s ease;
|
|
1365
1553
|
}
|
|
1366
1554
|
|
|
1367
1555
|
footer a:hover {
|
|
1368
|
-
|
|
1556
|
+
color: var(--solana-green);
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
/* ================================
|
|
1560
|
+
Custom Scrollbar
|
|
1561
|
+
================================ */
|
|
1562
|
+
::-webkit-scrollbar {
|
|
1563
|
+
width: 6px;
|
|
1564
|
+
height: 6px;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
::-webkit-scrollbar-track {
|
|
1568
|
+
background: var(--noir-primary);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
::-webkit-scrollbar-thumb {
|
|
1572
|
+
background: rgba(255, 255, 255, 0.1);
|
|
1573
|
+
border-radius: 9999px;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
::-webkit-scrollbar-thumb:hover {
|
|
1577
|
+
background: rgba(255, 255, 255, 0.2);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
/* ================================
|
|
1581
|
+
Accessibility - Reduced Motion
|
|
1582
|
+
================================ */
|
|
1583
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1584
|
+
*,
|
|
1585
|
+
*::before,
|
|
1586
|
+
*::after {
|
|
1587
|
+
animation-duration: 0.01ms !important;
|
|
1588
|
+
animation-iteration-count: 1 !important;
|
|
1589
|
+
transition-duration: 0.01ms !important;
|
|
1590
|
+
}
|
|
1369
1591
|
}
|
|
1370
1592
|
`;
|
|
1371
1593
|
}
|
|
1372
1594
|
function generateIndexCss() {
|
|
1373
|
-
return
|
|
1595
|
+
return `/* Base styles - fonts are loaded in index.html */
|
|
1596
|
+
body {
|
|
1374
1597
|
margin: 0;
|
|
1375
1598
|
-webkit-font-smoothing: antialiased;
|
|
1376
1599
|
-moz-osx-font-smoothing: grayscale;
|
|
1377
1600
|
}
|
|
1601
|
+
|
|
1602
|
+
/* Ensure mono font is applied to code elements */
|
|
1603
|
+
code, pre, .mono {
|
|
1604
|
+
font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
|
|
1605
|
+
}
|
|
1378
1606
|
`;
|
|
1379
1607
|
}
|
|
1380
1608
|
function generateViteEnvDts() {
|
|
@@ -1553,14 +1781,14 @@ async function initCommand(projectName, options) {
|
|
|
1553
1781
|
});
|
|
1554
1782
|
}
|
|
1555
1783
|
if (!projectOptions) {
|
|
1556
|
-
console.log(
|
|
1784
|
+
console.log(pc3.yellow("\nOperation cancelled."));
|
|
1557
1785
|
process.exit(0);
|
|
1558
1786
|
}
|
|
1559
1787
|
const projectDir = path2.resolve(process.cwd(), projectOptions.projectName);
|
|
1560
1788
|
if (await directoryExists(projectDir)) {
|
|
1561
1789
|
if (!await isDirectoryEmpty(projectDir)) {
|
|
1562
1790
|
console.log(
|
|
1563
|
-
|
|
1791
|
+
pc3.red(`
|
|
1564
1792
|
Error: Directory "${projectOptions.projectName}" already exists and is not empty.`)
|
|
1565
1793
|
);
|
|
1566
1794
|
process.exit(1);
|
|
@@ -1572,23 +1800,23 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
|
|
|
1572
1800
|
await progress.startThinking();
|
|
1573
1801
|
await new Promise((r) => setTimeout(r, 800));
|
|
1574
1802
|
progress.stopThinking();
|
|
1575
|
-
console.log(
|
|
1803
|
+
console.log(pc3.bold("\n Scaffolding your ZK project...\n"));
|
|
1576
1804
|
await createProjectStructure(projectDir, projectOptions, progress);
|
|
1577
1805
|
progress.showSuccess("Project structure created");
|
|
1578
1806
|
} catch (error) {
|
|
1579
1807
|
progress.showError("Failed to create project structure");
|
|
1580
|
-
console.error(
|
|
1808
|
+
console.error(pc3.red("\n"), error);
|
|
1581
1809
|
process.exit(1);
|
|
1582
1810
|
}
|
|
1583
1811
|
if (!projectOptions.skipGit) {
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1812
|
+
const gitProgress = createGitProgress();
|
|
1813
|
+
gitProgress.start();
|
|
1586
1814
|
try {
|
|
1587
1815
|
execSync("git init", { cwd: projectDir, stdio: "ignore" });
|
|
1588
|
-
|
|
1816
|
+
gitProgress.stop(true);
|
|
1589
1817
|
} catch {
|
|
1590
|
-
|
|
1591
|
-
console.log(
|
|
1818
|
+
gitProgress.stop(false);
|
|
1819
|
+
console.log(pc3.yellow(" Warning: Failed to initialize git repository"));
|
|
1592
1820
|
}
|
|
1593
1821
|
}
|
|
1594
1822
|
if (!projectOptions.skipInstall) {
|
|
@@ -1599,7 +1827,7 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
|
|
|
1599
1827
|
installProgress.stop(true);
|
|
1600
1828
|
} catch {
|
|
1601
1829
|
installProgress.stop(false);
|
|
1602
|
-
console.log(
|
|
1830
|
+
console.log(pc3.yellow(' Run "npm install" manually.'));
|
|
1603
1831
|
}
|
|
1604
1832
|
}
|
|
1605
1833
|
printSuccessMessage(projectOptions);
|
|
@@ -1653,26 +1881,26 @@ async function createProjectStructure(projectDir, options, progress) {
|
|
|
1653
1881
|
}
|
|
1654
1882
|
function printSuccessMessage(options) {
|
|
1655
1883
|
console.log();
|
|
1656
|
-
console.log(
|
|
1884
|
+
console.log(pc3.green("\u2713") + " Project created successfully!");
|
|
1657
1885
|
console.log();
|
|
1658
1886
|
console.log("Next steps:");
|
|
1659
1887
|
console.log();
|
|
1660
|
-
console.log(
|
|
1888
|
+
console.log(pc3.cyan(` cd ${options.projectName}`));
|
|
1661
1889
|
if (options.skipInstall) {
|
|
1662
|
-
console.log(
|
|
1890
|
+
console.log(pc3.cyan(" npm install"));
|
|
1663
1891
|
}
|
|
1664
|
-
console.log(
|
|
1892
|
+
console.log(pc3.cyan(" npm run dev"));
|
|
1665
1893
|
console.log();
|
|
1666
|
-
console.log("Then open " +
|
|
1894
|
+
console.log("Then open " + pc3.blue("http://localhost:5173") + " in your browser.");
|
|
1667
1895
|
console.log();
|
|
1668
1896
|
console.log("To add circuits:");
|
|
1669
1897
|
console.log();
|
|
1670
|
-
console.log(
|
|
1671
|
-
console.log(
|
|
1672
|
-
console.log(
|
|
1898
|
+
console.log(pc3.dim(" 1. Create a new circuit in circuits/*.ts"));
|
|
1899
|
+
console.log(pc3.dim(" 2. Export it from circuits/index.ts"));
|
|
1900
|
+
console.log(pc3.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
|
|
1673
1901
|
console.log();
|
|
1674
1902
|
console.log(
|
|
1675
|
-
|
|
1903
|
+
pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
|
|
1676
1904
|
);
|
|
1677
1905
|
console.log();
|
|
1678
1906
|
}
|