@izi-noir/sdk 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +458 -0
  3. package/dist/IProvingSystem-D9TnEig0.d.ts +140 -0
  4. package/dist/IProvingSystem-TKNofoo8.d.cts +140 -0
  5. package/dist/index.cjs +2793 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +1196 -0
  8. package/dist/index.d.ts +1196 -0
  9. package/dist/index.js +2730 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/providers/arkworks.cjs +824 -0
  12. package/dist/providers/arkworks.cjs.map +1 -0
  13. package/dist/providers/arkworks.d.cts +121 -0
  14. package/dist/providers/arkworks.d.ts +121 -0
  15. package/dist/providers/arkworks.js +791 -0
  16. package/dist/providers/arkworks.js.map +1 -0
  17. package/dist/providers/barretenberg.cjs +822 -0
  18. package/dist/providers/barretenberg.cjs.map +1 -0
  19. package/dist/providers/barretenberg.d.cts +18 -0
  20. package/dist/providers/barretenberg.d.ts +18 -0
  21. package/dist/providers/barretenberg.js +790 -0
  22. package/dist/providers/barretenberg.js.map +1 -0
  23. package/dist/providers/solana.cjs +262 -0
  24. package/dist/providers/solana.cjs.map +1 -0
  25. package/dist/providers/solana.d.cts +223 -0
  26. package/dist/providers/solana.d.ts +223 -0
  27. package/dist/providers/solana.js +222 -0
  28. package/dist/providers/solana.js.map +1 -0
  29. package/dist/providers/sunspot.cjs +475 -0
  30. package/dist/providers/sunspot.cjs.map +1 -0
  31. package/dist/providers/sunspot.d.cts +210 -0
  32. package/dist/providers/sunspot.d.ts +210 -0
  33. package/dist/providers/sunspot.js +443 -0
  34. package/dist/providers/sunspot.js.map +1 -0
  35. package/dist/types-CaaigonG.d.cts +93 -0
  36. package/dist/types-CaaigonG.d.ts +93 -0
  37. package/dist/wasm/nodejs/arkworks_groth16_wasm.js +448 -0
  38. package/dist/wasm/nodejs/arkworks_groth16_wasm_bg.wasm +0 -0
  39. package/dist/wasm/web/arkworks_groth16_wasm.js +536 -0
  40. package/dist/wasm/web/arkworks_groth16_wasm_bg.wasm +0 -0
  41. package/dist/wasmInit-KV6DTj4J.d.ts +282 -0
  42. package/dist/wasmInit-iEYiiB8M.d.cts +282 -0
  43. package/package.json +87 -0
@@ -0,0 +1,822 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/infra/provingSystems/Barretenberg.ts
34
+ var Barretenberg_exports = {};
35
+ __export(Barretenberg_exports, {
36
+ Barretenberg: () => Barretenberg
37
+ });
38
+ function stringToStream(content) {
39
+ return new ReadableStream({
40
+ start(controller) {
41
+ controller.enqueue(new TextEncoder().encode(content));
42
+ controller.close();
43
+ }
44
+ });
45
+ }
46
+ function isNodeJs() {
47
+ return typeof globalThis.process !== "undefined" && globalThis.process.versions != null && globalThis.process.versions.node != null;
48
+ }
49
+ async function createTempDir() {
50
+ if (!isNodeJs()) {
51
+ return { basePath: "/", cleanup: null };
52
+ }
53
+ const fs = await import("fs/promises");
54
+ const os = await import("os");
55
+ const path = await import("path");
56
+ const basePath = await fs.mkdtemp(path.join(os.tmpdir(), "noir-circuit-"));
57
+ const cleanup = async () => {
58
+ await fs.rm(basePath, { recursive: true, force: true });
59
+ };
60
+ return { basePath, cleanup };
61
+ }
62
+ var import_noir_wasm, import_noir_js, import_bb, Barretenberg;
63
+ var init_Barretenberg = __esm({
64
+ "src/infra/provingSystems/Barretenberg.ts"() {
65
+ "use strict";
66
+ import_noir_wasm = require("@noir-lang/noir_wasm");
67
+ import_noir_js = require("@noir-lang/noir_js");
68
+ import_bb = require("@aztec/bb.js");
69
+ Barretenberg = class {
70
+ async compile(noirCode) {
71
+ const { basePath, cleanup } = await createTempDir();
72
+ const fm = (0, import_noir_wasm.createFileManager)(basePath);
73
+ const nargoToml = `[package]
74
+ name = "circuit"
75
+ type = "bin"
76
+ authors = [""]
77
+
78
+ [dependencies]
79
+ `;
80
+ try {
81
+ if (isNodeJs()) {
82
+ await fm.writeFile("./src/main.nr", stringToStream(noirCode));
83
+ await fm.writeFile("./Nargo.toml", stringToStream(nargoToml));
84
+ } else {
85
+ fm.writeFile("./src/main.nr", stringToStream(noirCode));
86
+ fm.writeFile("./Nargo.toml", stringToStream(nargoToml));
87
+ }
88
+ const result = await (0, import_noir_wasm.compile)(fm);
89
+ const compiled = result.program;
90
+ if (!compiled || !compiled.bytecode) {
91
+ throw new Error("Compilation failed: no bytecode generated");
92
+ }
93
+ return compiled;
94
+ } finally {
95
+ if (cleanup) {
96
+ await cleanup();
97
+ }
98
+ }
99
+ }
100
+ async generateProof(circuit, inputs) {
101
+ const noir = new import_noir_js.Noir(circuit);
102
+ const { witness } = await noir.execute(inputs);
103
+ const barretenberg = await import_bb.Barretenberg.new({ threads: 1 });
104
+ const backend = new import_bb.UltraHonkBackend(circuit.bytecode, barretenberg);
105
+ try {
106
+ const proofData = await backend.generateProof(witness);
107
+ return {
108
+ proof: proofData.proof,
109
+ publicInputs: proofData.publicInputs || []
110
+ };
111
+ } finally {
112
+ await barretenberg.destroy();
113
+ }
114
+ }
115
+ async verifyProof(circuit, proof, publicInputs) {
116
+ const barretenberg = await import_bb.Barretenberg.new({ threads: 1 });
117
+ const backend = new import_bb.UltraHonkBackend(circuit.bytecode, barretenberg);
118
+ try {
119
+ return await backend.verifyProof({ proof, publicInputs });
120
+ } finally {
121
+ await barretenberg.destroy();
122
+ }
123
+ }
124
+ };
125
+ }
126
+ });
127
+
128
+ // src/infra/provingSystems/ArkworksWasm.ts
129
+ var ArkworksWasm_exports = {};
130
+ __export(ArkworksWasm_exports, {
131
+ ArkworksWasm: () => ArkworksWasm,
132
+ isArkworksCircuit: () => isArkworksCircuit
133
+ });
134
+ function stringToStream2(content) {
135
+ return new ReadableStream({
136
+ start(controller) {
137
+ controller.enqueue(new TextEncoder().encode(content));
138
+ controller.close();
139
+ }
140
+ });
141
+ }
142
+ function isNodeJs3() {
143
+ return typeof globalThis.process !== "undefined" && globalThis.process.versions != null && globalThis.process.versions.node != null;
144
+ }
145
+ async function createTempDir2() {
146
+ if (!isNodeJs3()) {
147
+ return { basePath: "/", cleanup: null };
148
+ }
149
+ const fs = await import("fs/promises");
150
+ const os = await import("os");
151
+ const path = await import("path");
152
+ const basePath = await fs.mkdtemp(path.join(os.tmpdir(), "arkworks-circuit-"));
153
+ const cleanup = async () => {
154
+ await fs.rm(basePath, { recursive: true, force: true });
155
+ };
156
+ return { basePath, cleanup };
157
+ }
158
+ function isArkworksCircuit(circuit) {
159
+ return "__arkworks" in circuit && circuit.__arkworks === true;
160
+ }
161
+ async function initWasm() {
162
+ if (wasmModule) {
163
+ return wasmModule;
164
+ }
165
+ if (wasmInitPromise2) {
166
+ return wasmInitPromise2;
167
+ }
168
+ wasmInitPromise2 = (async () => {
169
+ try {
170
+ if (isNodeJs3()) {
171
+ const module2 = await import("../wasm/nodejs/arkworks_groth16_wasm.js");
172
+ wasmModule = module2;
173
+ } else {
174
+ const module2 = await import("../wasm/web/arkworks_groth16_wasm.js");
175
+ if (typeof module2.default === "function") {
176
+ await module2.default();
177
+ }
178
+ wasmModule = module2;
179
+ }
180
+ return wasmModule;
181
+ } catch (error) {
182
+ wasmInitPromise2 = null;
183
+ throw new Error(
184
+ `Failed to initialize arkworks-groth16-wasm: ${error instanceof Error ? error.message : String(error)}
185
+ Make sure the WASM module is built: cd packages/arkworks-groth16-wasm && npm run build`
186
+ );
187
+ }
188
+ })();
189
+ return wasmInitPromise2;
190
+ }
191
+ function base64ToUint8Array(b64) {
192
+ const binaryString = atob(b64);
193
+ const bytes = new Uint8Array(binaryString.length);
194
+ for (let i = 0; i < binaryString.length; i++) {
195
+ bytes[i] = binaryString.charCodeAt(i);
196
+ }
197
+ return bytes;
198
+ }
199
+ function uint8ArrayToBase64(bytes) {
200
+ let binary = "";
201
+ for (let i = 0; i < bytes.length; i++) {
202
+ binary += String.fromCharCode(bytes[i]);
203
+ }
204
+ return btoa(binary);
205
+ }
206
+ function publicInputsToGnarkBase64(publicInputs) {
207
+ const FIELD_SIZE = 32;
208
+ const bytes = new Uint8Array(publicInputs.length * FIELD_SIZE);
209
+ for (let i = 0; i < publicInputs.length; i++) {
210
+ const input = publicInputs[i];
211
+ const hex = input.startsWith("0x") ? input.slice(2) : input;
212
+ const inputBytes = hexToBytes(hex.padStart(64, "0"));
213
+ bytes.set(inputBytes, i * FIELD_SIZE);
214
+ }
215
+ return uint8ArrayToBase64(bytes);
216
+ }
217
+ function hexToBytes(hex) {
218
+ const bytes = new Uint8Array(hex.length / 2);
219
+ for (let i = 0; i < hex.length; i += 2) {
220
+ bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
221
+ }
222
+ return bytes;
223
+ }
224
+ var import_noir_wasm2, import_noir_js2, wasmModule, wasmInitPromise2, ArkworksWasm;
225
+ var init_ArkworksWasm = __esm({
226
+ "src/infra/provingSystems/ArkworksWasm.ts"() {
227
+ "use strict";
228
+ import_noir_wasm2 = require("@noir-lang/noir_wasm");
229
+ import_noir_js2 = require("@noir-lang/noir_js");
230
+ wasmModule = null;
231
+ wasmInitPromise2 = null;
232
+ ArkworksWasm = class {
233
+ config;
234
+ constructor(config = {}) {
235
+ this.config = {
236
+ keepArtifacts: false,
237
+ cacheKeys: true,
238
+ ...config
239
+ };
240
+ }
241
+ /**
242
+ * Compile Noir code to a circuit with ACIR for Groth16 proving
243
+ */
244
+ async compile(noirCode) {
245
+ const wasm = await initWasm();
246
+ const { basePath, cleanup } = await createTempDir2();
247
+ const fm = (0, import_noir_wasm2.createFileManager)(basePath);
248
+ const nargoToml = `[package]
249
+ name = "circuit"
250
+ type = "bin"
251
+ authors = [""]
252
+
253
+ [dependencies]
254
+ `;
255
+ try {
256
+ if (isNodeJs3()) {
257
+ await fm.writeFile("./src/main.nr", stringToStream2(noirCode));
258
+ await fm.writeFile("./Nargo.toml", stringToStream2(nargoToml));
259
+ } else {
260
+ fm.writeFile("./src/main.nr", stringToStream2(noirCode));
261
+ fm.writeFile("./Nargo.toml", stringToStream2(nargoToml));
262
+ }
263
+ const result = await (0, import_noir_wasm2.compile)(fm);
264
+ const compiled = result.program;
265
+ if (!compiled || !compiled.bytecode) {
266
+ throw new Error("Compilation failed: no bytecode generated");
267
+ }
268
+ const acirJson = JSON.stringify({
269
+ functions: [
270
+ {
271
+ current_witness_index: compiled.abi.parameters.length + 1,
272
+ opcodes: [],
273
+ // Will be extracted from bytecode during prove
274
+ private_parameters: compiled.abi.parameters.filter((p) => p.visibility === "private").map((_, i) => i + 1),
275
+ public_parameters: {
276
+ witnesses: compiled.abi.parameters.filter((p) => p.visibility === "public").map((_, i) => i + 1)
277
+ },
278
+ return_values: { witnesses: [] }
279
+ }
280
+ ]
281
+ });
282
+ let provingKey;
283
+ let verifyingKey;
284
+ let verifyingKeyGnark;
285
+ if (this.config.cacheKeys) {
286
+ try {
287
+ const setupResult = wasm.setup(acirJson);
288
+ provingKey = setupResult.proving_key;
289
+ verifyingKey = setupResult.verifying_key;
290
+ verifyingKeyGnark = setupResult.verifying_key_gnark;
291
+ } catch (error) {
292
+ console.warn("Deferred setup: will run during proof generation");
293
+ }
294
+ }
295
+ const arkworksCircuit = {
296
+ ...compiled,
297
+ __arkworks: true,
298
+ acirJson,
299
+ provingKey,
300
+ verifyingKey,
301
+ verifyingKeyGnark
302
+ };
303
+ return arkworksCircuit;
304
+ } finally {
305
+ if (cleanup) {
306
+ await cleanup();
307
+ }
308
+ }
309
+ }
310
+ /**
311
+ * Generate a Groth16 proof
312
+ */
313
+ async generateProof(circuit, inputs) {
314
+ const wasm = await initWasm();
315
+ if (!isArkworksCircuit(circuit)) {
316
+ throw new Error(
317
+ "ArkworksWasm.generateProof requires an ArkworksCompiledCircuit. Use ArkworksWasm.compile() first."
318
+ );
319
+ }
320
+ const noir = new import_noir_js2.Noir(circuit);
321
+ const { witness } = await noir.execute(inputs);
322
+ const witnessMap = {};
323
+ for (const [index, value] of witness.entries()) {
324
+ witnessMap[index.toString()] = String(value);
325
+ }
326
+ const witnessJson = JSON.stringify(witnessMap);
327
+ let provingKey = circuit.provingKey;
328
+ if (!provingKey) {
329
+ const setupResult = wasm.setup(circuit.acirJson);
330
+ provingKey = setupResult.proving_key;
331
+ circuit.provingKey = provingKey;
332
+ circuit.verifyingKey = setupResult.verifying_key;
333
+ circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
334
+ }
335
+ const proofResult = wasm.prove(provingKey, circuit.acirJson, witnessJson);
336
+ const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
337
+ return {
338
+ proof: proofBytes,
339
+ publicInputs: proofResult.public_inputs
340
+ };
341
+ }
342
+ /**
343
+ * Verify a Groth16 proof
344
+ */
345
+ async verifyProof(circuit, proof, publicInputs) {
346
+ const wasm = await initWasm();
347
+ if (!isArkworksCircuit(circuit)) {
348
+ throw new Error(
349
+ "ArkworksWasm.verifyProof requires an ArkworksCompiledCircuit. Use ArkworksWasm.compile() first."
350
+ );
351
+ }
352
+ let verifyingKeyGnark = circuit.verifyingKeyGnark;
353
+ if (!verifyingKeyGnark) {
354
+ const setupResult = wasm.setup(circuit.acirJson);
355
+ circuit.provingKey = setupResult.proving_key;
356
+ circuit.verifyingKey = setupResult.verifying_key;
357
+ verifyingKeyGnark = setupResult.verifying_key_gnark;
358
+ circuit.verifyingKeyGnark = verifyingKeyGnark;
359
+ }
360
+ const proofB64 = uint8ArrayToBase64(proof);
361
+ const publicInputsGnarkB64 = publicInputsToGnarkBase64(publicInputs);
362
+ return wasm.verify_gnark(
363
+ verifyingKeyGnark,
364
+ proofB64,
365
+ publicInputsGnarkB64,
366
+ publicInputs.length
367
+ );
368
+ }
369
+ /**
370
+ * Get the verifying key in gnark format for on-chain deployment
371
+ */
372
+ async getVerifyingKeyGnark(circuit) {
373
+ const wasm = await initWasm();
374
+ if (!isArkworksCircuit(circuit)) {
375
+ throw new Error("getVerifyingKeyGnark requires an ArkworksCompiledCircuit");
376
+ }
377
+ if (!circuit.verifyingKeyGnark) {
378
+ const setupResult = wasm.setup(circuit.acirJson);
379
+ circuit.provingKey = setupResult.proving_key;
380
+ circuit.verifyingKey = setupResult.verifying_key;
381
+ circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
382
+ }
383
+ return base64ToUint8Array(circuit.verifyingKeyGnark);
384
+ }
385
+ };
386
+ }
387
+ });
388
+
389
+ // src/infra/chainFormatters/SolanaFormatter.ts
390
+ var SolanaFormatter_exports = {};
391
+ __export(SolanaFormatter_exports, {
392
+ SolanaFormatter: () => SolanaFormatter
393
+ });
394
+ var G1_SIZE, G2_SIZE, SolanaFormatter;
395
+ var init_SolanaFormatter = __esm({
396
+ "src/infra/chainFormatters/SolanaFormatter.ts"() {
397
+ "use strict";
398
+ G1_SIZE = 64;
399
+ G2_SIZE = 128;
400
+ SolanaFormatter = class {
401
+ constructor(arkworksProvider) {
402
+ this.arkworksProvider = arkworksProvider;
403
+ }
404
+ chainId = "solana";
405
+ /**
406
+ * Format a generic proof for Solana on-chain verification.
407
+ *
408
+ * @param proofData - Generic proof data from Arkworks
409
+ * @param circuit - The compiled circuit (must be Arkworks circuit)
410
+ * @param metadata - Circuit metadata with public input count
411
+ * @returns SolanaProofData ready for on-chain verification
412
+ */
413
+ async formatProof(proofData, circuit, metadata) {
414
+ const vkBytes = await this.arkworksProvider.getVerifyingKeyGnark(circuit);
415
+ const vkBase64 = this.uint8ArrayToBase64(vkBytes);
416
+ const nrPublicInputs = metadata.numPublicInputs;
417
+ const publicInputsBytes = proofData.publicInputs.map((input) => {
418
+ const hex = input.startsWith("0x") ? input.slice(2) : input;
419
+ return this.hexToBytes(hex.padStart(64, "0"));
420
+ });
421
+ const { accountSize, estimatedRent } = this.getChainMetadata(nrPublicInputs);
422
+ return {
423
+ verifyingKey: {
424
+ base64: vkBase64,
425
+ bytes: vkBytes,
426
+ nrPublicInputs
427
+ },
428
+ proof: {
429
+ base64: this.uint8ArrayToBase64(proofData.proof),
430
+ bytes: proofData.proof
431
+ },
432
+ publicInputs: {
433
+ hex: proofData.publicInputs,
434
+ bytes: publicInputsBytes
435
+ },
436
+ accountSize,
437
+ estimatedRent
438
+ };
439
+ }
440
+ /**
441
+ * Get Solana-specific metadata for a circuit.
442
+ *
443
+ * @param publicInputCount - Number of public inputs in the circuit
444
+ * @returns Solana metadata with account size and rent estimates
445
+ */
446
+ getChainMetadata(publicInputCount) {
447
+ const accountSize = this.calculateVkAccountSize(publicInputCount);
448
+ const estimatedRent = this.calculateVkAccountRent(publicInputCount);
449
+ return {
450
+ chainId: "solana",
451
+ accountSize,
452
+ estimatedRent
453
+ };
454
+ }
455
+ /**
456
+ * Calculate the size of a VK account for a given number of public inputs.
457
+ * Matches the Rust `vk_account_size` function in the Solana program.
458
+ */
459
+ calculateVkAccountSize(nrPublicInputs) {
460
+ const fixedSize = 8 + 32 + 1 + G1_SIZE + G2_SIZE * 3 + 4;
461
+ return fixedSize + (nrPublicInputs + 1) * G1_SIZE;
462
+ }
463
+ /**
464
+ * Calculate the minimum rent for a VK account.
465
+ */
466
+ calculateVkAccountRent(nrPublicInputs, rentExemptionPerByte = 6960) {
467
+ const size = this.calculateVkAccountSize(nrPublicInputs);
468
+ return size * rentExemptionPerByte;
469
+ }
470
+ /**
471
+ * Convert Uint8Array to base64 string.
472
+ */
473
+ uint8ArrayToBase64(bytes) {
474
+ if (typeof btoa === "function") {
475
+ let binary = "";
476
+ for (let i = 0; i < bytes.length; i++) {
477
+ binary += String.fromCharCode(bytes[i]);
478
+ }
479
+ return btoa(binary);
480
+ }
481
+ return Buffer.from(bytes).toString("base64");
482
+ }
483
+ /**
484
+ * Convert hex string to Uint8Array.
485
+ */
486
+ hexToBytes(hex) {
487
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
488
+ const bytes = new Uint8Array(cleanHex.length / 2);
489
+ for (let i = 0; i < bytes.length; i++) {
490
+ bytes[i] = parseInt(cleanHex.substring(i * 2, i * 2 + 2), 16);
491
+ }
492
+ return bytes;
493
+ }
494
+ };
495
+ }
496
+ });
497
+
498
+ // src/providers/barretenberg.ts
499
+ var barretenberg_exports = {};
500
+ __export(barretenberg_exports, {
501
+ Barretenberg: () => Barretenberg,
502
+ IziNoir: () => IziNoir,
503
+ Provider: () => Provider,
504
+ initNoirWasm: () => initNoirWasm,
505
+ isWasmInitialized: () => isWasmInitialized
506
+ });
507
+ module.exports = __toCommonJS(barretenberg_exports);
508
+ init_Barretenberg();
509
+
510
+ // src/domain/types/provider.ts
511
+ var Provider = /* @__PURE__ */ ((Provider2) => {
512
+ Provider2["Barretenberg"] = "barretenberg";
513
+ Provider2["Arkworks"] = "arkworks";
514
+ Provider2["Sunspot"] = "sunspot";
515
+ return Provider2;
516
+ })(Provider || {});
517
+
518
+ // src/infra/wasm/wasmInit.ts
519
+ var wasmInitPromise = null;
520
+ var wasmInitialized = false;
521
+ function isNodeJs2() {
522
+ return typeof globalThis.process !== "undefined" && globalThis.process.versions != null && globalThis.process.versions.node != null;
523
+ }
524
+ async function initNoirWasm() {
525
+ if (wasmInitialized) return;
526
+ if (!wasmInitPromise) {
527
+ wasmInitPromise = initWasmInternal();
528
+ }
529
+ await wasmInitPromise;
530
+ wasmInitialized = true;
531
+ }
532
+ async function initWasmInternal() {
533
+ if (isNodeJs2()) {
534
+ await import("@noir-lang/acvm_js/nodejs/acvm_js.js");
535
+ await import("@noir-lang/noirc_abi/nodejs/noirc_abi_wasm.js");
536
+ } else {
537
+ const [{ default: initACVM }, { default: initNoirC }] = await Promise.all([
538
+ import("@noir-lang/acvm_js"),
539
+ import("@noir-lang/noirc_abi")
540
+ ]);
541
+ await Promise.all([initACVM(), initNoirC()]);
542
+ }
543
+ }
544
+ function isWasmInitialized() {
545
+ return wasmInitialized;
546
+ }
547
+
548
+ // src/IziNoir.ts
549
+ var IziNoir = class _IziNoir {
550
+ provingSystem;
551
+ compiledCircuit = null;
552
+ chainFormatters = /* @__PURE__ */ new Map();
553
+ chain;
554
+ _verifyingKey;
555
+ _lastProof;
556
+ constructor(provingSystem, chain) {
557
+ this.provingSystem = provingSystem;
558
+ this.chain = chain;
559
+ }
560
+ /**
561
+ * Get the verifying key from the last proof generation.
562
+ * Only available after calling prove() with a chain configured.
563
+ */
564
+ get vk() {
565
+ return this._verifyingKey;
566
+ }
567
+ /**
568
+ * Get the configured chain, if any.
569
+ */
570
+ get targetChain() {
571
+ return this.chain;
572
+ }
573
+ /**
574
+ * Check if operating in offchain mode (no chain configured).
575
+ */
576
+ get isOffchain() {
577
+ return this.chain === void 0;
578
+ }
579
+ /**
580
+ * Register a chain formatter for chain-specific proof formatting.
581
+ *
582
+ * @param formatter - The chain formatter to register
583
+ */
584
+ registerChainFormatter(formatter) {
585
+ this.chainFormatters.set(formatter.chainId, formatter);
586
+ }
587
+ /**
588
+ * Get a registered chain formatter.
589
+ *
590
+ * @param chainId - The chain ID to get the formatter for
591
+ * @returns The formatter or undefined if not registered
592
+ */
593
+ getChainFormatter(chainId) {
594
+ return this.chainFormatters.get(chainId);
595
+ }
596
+ /**
597
+ * Initialize IziNoir with the specified provider and optional chain.
598
+ *
599
+ * @param config - Configuration specifying the provider, chain, and optional circuit paths
600
+ * @returns Initialized IziNoir instance
601
+ *
602
+ * @example
603
+ * ```typescript
604
+ * // On-chain mode (Solana)
605
+ * const izi = await IziNoir.init({
606
+ * provider: Provider.Arkworks,
607
+ * chain: Chain.Solana
608
+ * });
609
+ *
610
+ * // Offchain mode (no chain formatting)
611
+ * const iziOffchain = await IziNoir.init({
612
+ * provider: Provider.Arkworks
613
+ * });
614
+ *
615
+ * // Barretenberg (browser-compatible, ~16KB proofs, offchain only)
616
+ * const bb = await IziNoir.init({ provider: Provider.Barretenberg });
617
+ * ```
618
+ */
619
+ static async init(config) {
620
+ await initNoirWasm();
621
+ let provingSystem;
622
+ switch (config.provider) {
623
+ case "barretenberg" /* Barretenberg */: {
624
+ if (config.chain) {
625
+ throw new Error(
626
+ "Barretenberg provider does not support chain formatting. Use Provider.Arkworks for on-chain proofs."
627
+ );
628
+ }
629
+ const { Barretenberg: Barretenberg2 } = await Promise.resolve().then(() => (init_Barretenberg(), Barretenberg_exports));
630
+ provingSystem = new Barretenberg2();
631
+ return new _IziNoir(provingSystem);
632
+ }
633
+ case "arkworks" /* Arkworks */: {
634
+ const { ArkworksWasm: ArkworksWasm2 } = await Promise.resolve().then(() => (init_ArkworksWasm(), ArkworksWasm_exports));
635
+ const arkworksInstance = new ArkworksWasm2();
636
+ provingSystem = arkworksInstance;
637
+ const instance = new _IziNoir(provingSystem, config.chain);
638
+ if (config.chain === "solana" /* Solana */ || !config.chain) {
639
+ const { SolanaFormatter: SolanaFormatter2 } = await Promise.resolve().then(() => (init_SolanaFormatter(), SolanaFormatter_exports));
640
+ instance.registerChainFormatter(new SolanaFormatter2(arkworksInstance));
641
+ }
642
+ return instance;
643
+ }
644
+ case "sunspot" /* Sunspot */: {
645
+ throw new Error(
646
+ 'Sunspot is not available in the main entry point. Import from "@izi-noir/sdk/sunspot" for Sunspot support.'
647
+ );
648
+ }
649
+ default:
650
+ throw new Error(`Unknown provider: ${config.provider}`);
651
+ }
652
+ }
653
+ /**
654
+ * Get the underlying proving system instance.
655
+ * Useful for advanced use cases.
656
+ */
657
+ getProvingSystem() {
658
+ return this.provingSystem;
659
+ }
660
+ /**
661
+ * Get the currently compiled circuit, if any.
662
+ */
663
+ getCompiledCircuit() {
664
+ return this.compiledCircuit;
665
+ }
666
+ /**
667
+ * Compile Noir code into a circuit.
668
+ *
669
+ * @param noirCode - The Noir source code to compile
670
+ * @returns The compiled circuit
671
+ */
672
+ async compile(noirCode) {
673
+ this.compiledCircuit = await this.provingSystem.compile(noirCode);
674
+ return this.compiledCircuit;
675
+ }
676
+ /**
677
+ * Generate a proof for the given inputs.
678
+ *
679
+ * If a chain is configured, returns chain-formatted proof data and stores
680
+ * the verifying key in `this.vk`. Otherwise, returns raw proof data.
681
+ *
682
+ * @param inputs - The inputs (both public and private) for the circuit
683
+ * @param circuit - Optional circuit to use (defaults to last compiled circuit)
684
+ * @returns The proof data - type depends on configured chain
685
+ * @throws Error if no circuit is available
686
+ *
687
+ * @example
688
+ * ```typescript
689
+ * // With chain configured - returns SolanaProofData
690
+ * const izi = await IziNoir.init({ provider: Provider.Arkworks, chain: Chain.Solana });
691
+ * await izi.compile(noirCode);
692
+ * const proof = await izi.prove({ expected: '100', secret: '10' });
693
+ * // proof is SolanaProofData, izi.vk is available
694
+ *
695
+ * // Offchain mode - returns ProofData
696
+ * const iziOffchain = await IziNoir.init({ provider: Provider.Arkworks });
697
+ * await iziOffchain.compile(noirCode);
698
+ * const rawProof = await iziOffchain.prove({ expected: '100', secret: '10' });
699
+ * // rawProof is ProofData, iziOffchain.vk is undefined
700
+ * ```
701
+ */
702
+ async prove(inputs, circuit) {
703
+ const circuitToUse = circuit || this.compiledCircuit;
704
+ if (!circuitToUse) {
705
+ throw new Error("No circuit available. Call compile() first or provide a circuit.");
706
+ }
707
+ const rawProof = await this.provingSystem.generateProof(circuitToUse, inputs);
708
+ if (!this.chain) {
709
+ this._lastProof = rawProof;
710
+ return rawProof;
711
+ }
712
+ const formatter = this.chainFormatters.get(this.chain);
713
+ if (!formatter) {
714
+ throw new Error(
715
+ `No formatter registered for chain: ${this.chain}. This is an internal error - please report it.`
716
+ );
717
+ }
718
+ const metadata = {
719
+ numPublicInputs: rawProof.publicInputs.length
720
+ };
721
+ const formattedProof = await formatter.formatProof(rawProof, circuitToUse, metadata);
722
+ const chainProof = formattedProof;
723
+ this._verifyingKey = chainProof.verifyingKey;
724
+ this._lastProof = chainProof;
725
+ return chainProof;
726
+ }
727
+ /**
728
+ * Verify a proof.
729
+ * Available in both on-chain and offchain modes.
730
+ *
731
+ * @param proof - The proof bytes to verify
732
+ * @param publicInputs - The public inputs that were used
733
+ * @param circuit - Optional circuit to use (defaults to last compiled circuit)
734
+ * @returns true if the proof is valid, false otherwise
735
+ * @throws Error if no circuit is available
736
+ */
737
+ async verify(proof, publicInputs, circuit) {
738
+ const circuitToUse = circuit || this.compiledCircuit;
739
+ if (!circuitToUse) {
740
+ throw new Error("No circuit available. Call compile() first or provide a circuit.");
741
+ }
742
+ return this.provingSystem.verifyProof(circuitToUse, proof, publicInputs);
743
+ }
744
+ /**
745
+ * Convenience method: compile, prove, and verify in one call.
746
+ *
747
+ * @param noirCode - The Noir source code to compile
748
+ * @param inputs - The inputs (both public and private) for the circuit
749
+ * @returns Object containing proof data and verification result
750
+ *
751
+ * @example
752
+ * ```typescript
753
+ * const { proof, verified } = await izi.createProof(noirCode, {
754
+ * x: '100',
755
+ * y: '10',
756
+ * });
757
+ * console.log(`Verified: ${verified}`);
758
+ * ```
759
+ */
760
+ async createProof(noirCode, inputs) {
761
+ const circuit = await this.compile(noirCode);
762
+ const proof = await this.prove(inputs, circuit);
763
+ const proofBytes = "proof" in proof && proof.proof instanceof Uint8Array ? proof.proof : proof.proof.bytes;
764
+ const pubInputs = Array.isArray(proof.publicInputs) ? proof.publicInputs : proof.publicInputs.hex;
765
+ const verified = await this.verify(proofBytes, pubInputs, circuit);
766
+ return { proof, verified };
767
+ }
768
+ /**
769
+ * Get deployment data for the verifying key.
770
+ * Returns the data needed to deploy to the configured blockchain.
771
+ * Use with SolanaTransactionBuilder to build and send the transaction.
772
+ *
773
+ * @param options - Optional configuration
774
+ * @returns Deployment data that can be used with SolanaTransactionBuilder
775
+ * @throws Error if no chain is configured (offchain mode)
776
+ * @throws Error if prove() hasn't been called yet
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const izi = await IziNoir.init({ provider: Provider.Arkworks, chain: Chain.Solana });
781
+ * await izi.compile(noirCode);
782
+ * await izi.prove(inputs);
783
+ *
784
+ * // Get deployment data
785
+ * const deployData = izi.getDeployData();
786
+ *
787
+ * // Use with SolanaTransactionBuilder in your frontend
788
+ * const builder = new SolanaTransactionBuilder({ programId: deployData.programId });
789
+ * const { initVk, rentLamports, accountSize } = builder.buildInitAndVerifyInstructions(
790
+ * deployData.proofData,
791
+ * vkAccountPubkey,
792
+ * authority,
793
+ * payer
794
+ * );
795
+ * ```
796
+ */
797
+ getDeployData(options) {
798
+ if (!this.chain) {
799
+ throw new Error("Cannot deploy in offchain mode. Initialize with a chain parameter.");
800
+ }
801
+ if (!this._verifyingKey || !this._lastProof) {
802
+ throw new Error("Must call prove() before getDeployData().");
803
+ }
804
+ if (this.chain !== "solana" /* Solana */) {
805
+ throw new Error(`Deployment for ${this.chain} is not yet supported.`);
806
+ }
807
+ return {
808
+ proofData: this._lastProof,
809
+ programId: options?.programId ?? "EYhRED7EuMyyVjx57aDXUD9h6ArnEKng64qtz8999KrS",
810
+ computeUnits: options?.computeUnits ?? 4e5
811
+ };
812
+ }
813
+ };
814
+ // Annotate the CommonJS export names for ESM import in node:
815
+ 0 && (module.exports = {
816
+ Barretenberg,
817
+ IziNoir,
818
+ Provider,
819
+ initNoirWasm,
820
+ isWasmInitialized
821
+ });
822
+ //# sourceMappingURL=barretenberg.cjs.map