@izi-noir/sdk 0.1.5 → 0.1.7

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.cjs CHANGED
@@ -191,8 +191,15 @@ async function initWasm() {
191
191
  } else {
192
192
  const moduleUrl = new URL(import_meta.url);
193
193
  const isSourceFile = moduleUrl.pathname.includes("/src/");
194
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
195
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
194
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
195
+ let wasmJsUrl;
196
+ if (isSourceFile) {
197
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
198
+ } else if (isViteProduction) {
199
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
200
+ } else {
201
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
202
+ }
196
203
  const module2 = await import(
197
204
  /* @vite-ignore */
198
205
  wasmJsUrl.href
@@ -297,18 +304,12 @@ authors = [""]
297
304
  parameters.forEach((p, noirIndex) => {
298
305
  const r1csIndex = noirIndex + 1;
299
306
  witnessIndexMapping.set(noirIndex, r1csIndex);
300
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
301
307
  if (p.visibility === "public") {
302
308
  publicR1csIndices.push(r1csIndex);
303
309
  } else if (p.visibility === "private") {
304
310
  privateR1csIndices.push(r1csIndex);
305
311
  }
306
312
  });
307
- console.log("=== COMPILE: R1CS Witness Assignment ===");
308
- console.log("Public R1CS indices:", publicR1csIndices);
309
- console.log("Private R1CS indices:", privateR1csIndices);
310
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
311
- console.log("=========================================");
312
313
  const r1cs = {
313
314
  num_witnesses: parameters.length + 1,
314
315
  // +1 for w_0
@@ -327,25 +328,18 @@ authors = [""]
327
328
  c: [["0x1", publicIdx]]
328
329
  // expected
329
330
  });
330
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
331
- } else {
332
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
333
331
  }
334
332
  const r1csJson = JSON.stringify(r1cs);
335
- console.log("R1CS JSON:", r1csJson);
336
333
  let provingKey;
337
334
  let verifyingKey;
338
335
  let verifyingKeyGnark;
339
336
  if (this.config.cacheKeys) {
340
337
  try {
341
- console.log("Running trusted setup from R1CS...");
342
338
  const setupResult = wasm.setup_from_r1cs(r1csJson);
343
339
  provingKey = setupResult.proving_key;
344
340
  verifyingKey = setupResult.verifying_key;
345
341
  verifyingKeyGnark = setupResult.verifying_key_gnark;
346
- console.log("Setup complete!");
347
342
  } catch (error) {
348
- console.error("Setup failed:", error);
349
343
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
350
344
  }
351
345
  }
@@ -382,60 +376,23 @@ authors = [""]
382
376
  const noir = new import_noir_js2.Noir(circuit);
383
377
  const { witness: compressedWitness } = await noir.execute(inputs);
384
378
  const witnessMapNoir = (0, import_acvm_js.decompressWitness)(compressedWitness);
385
- console.log("=== ARKWORKS WASM DEBUG ===");
386
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
387
- console.log("Inputs provided:", JSON.stringify(inputs));
388
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
389
- console.log("Decompressed witness entries:", witnessMapNoir.size);
390
- console.log("Witness map entries (first 10):");
391
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
392
- for (const [index, value] of sortedWitness.slice(0, 10)) {
393
- const strVal = String(value);
394
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
395
- if (strVal.startsWith("0x")) {
396
- try {
397
- const decVal = BigInt(strVal).toString(10);
398
- console.log(` \u2192 decimal: ${decVal}`);
399
- } catch {
400
- console.log(` \u2192 failed to parse as BigInt`);
401
- }
402
- }
403
- }
404
379
  const witnessMap = {};
405
380
  const witnessMapping = circuit.witnessIndexMapping;
406
- console.log("Converting noir witness to R1CS witness:");
407
381
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
408
382
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
409
383
  const strVal = String(value);
410
384
  witnessMap[r1csIndex.toString()] = strVal;
411
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
412
385
  }
413
386
  const witnessJson = JSON.stringify(witnessMap);
414
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
415
- const r1csParsed = JSON.parse(circuit.r1csJson);
416
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
417
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
418
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
419
- console.log("R1CS constraints:", r1csParsed.constraints.length);
420
387
  let provingKey = circuit.provingKey;
421
388
  if (!provingKey) {
422
- console.log("Running setup_from_r1cs...");
423
389
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
424
390
  provingKey = setupResult.proving_key;
425
391
  circuit.provingKey = provingKey;
426
392
  circuit.verifyingKey = setupResult.verifying_key;
427
393
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
428
394
  }
429
- console.log("Generating proof from R1CS...");
430
395
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
431
- console.log("=== PROOF RESULT DEBUG ===");
432
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
433
- proofResult.public_inputs.forEach((input, i) => {
434
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
435
- const decValue = BigInt(hexValue).toString(10);
436
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
437
- });
438
- console.log("===========================");
439
396
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
440
397
  return {
441
398
  proof: proofBytes,
@@ -1529,6 +1486,18 @@ var IziNoir = class _IziNoir {
1529
1486
  const networkConfig = NETWORK_CONFIG[this._network];
1530
1487
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1531
1488
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1489
+ const vkPubkey = new PublicKey(vk);
1490
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1491
+ if (!accountInfo) {
1492
+ throw new Error(
1493
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1494
+ );
1495
+ }
1496
+ if (accountInfo.data.length < 8) {
1497
+ throw new Error(
1498
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1499
+ );
1500
+ }
1532
1501
  const builder = new SolanaTransactionBuilder({
1533
1502
  programId: networkConfig.programId,
1534
1503
  computeUnits: 4e5
@@ -1556,12 +1525,59 @@ var IziNoir = class _IziNoir {
1556
1525
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1557
1526
  tx.recentBlockhash = blockhash;
1558
1527
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1559
- const signature = await wallet.sendTransaction(tx, connection);
1560
- await connection.confirmTransaction({
1561
- signature,
1562
- blockhash,
1563
- lastValidBlockHeight
1564
- });
1528
+ try {
1529
+ const simulation = await connection.simulateTransaction(tx);
1530
+ if (simulation.value.err) {
1531
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1532
+ throw new Error(
1533
+ `Transaction simulation failed:
1534
+ Error: ${JSON.stringify(simulation.value.err)}
1535
+ Logs:
1536
+ ${logs}`
1537
+ );
1538
+ }
1539
+ } catch (simError) {
1540
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1541
+ throw simError;
1542
+ }
1543
+ const err = simError;
1544
+ throw new Error(
1545
+ `Failed to simulate transaction: ${err.message}
1546
+ VK Account: ${vk}
1547
+ Network: ${this._network}
1548
+ Proof size: ${proofData.proof.bytes.length} bytes
1549
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1550
+ );
1551
+ }
1552
+ let signature;
1553
+ try {
1554
+ signature = await wallet.sendTransaction(tx, connection);
1555
+ } catch (sendError) {
1556
+ const originalError = sendError;
1557
+ const enhancedError = new Error(
1558
+ `Failed to send verify transaction: ${originalError.message}
1559
+ VK Account: ${vk}
1560
+ Network: ${this._network}
1561
+ Proof size: ${proofData.proof.bytes.length} bytes
1562
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1563
+ );
1564
+ enhancedError.cause = originalError;
1565
+ throw enhancedError;
1566
+ }
1567
+ try {
1568
+ await connection.confirmTransaction({
1569
+ signature,
1570
+ blockhash,
1571
+ lastValidBlockHeight
1572
+ });
1573
+ } catch (confirmError) {
1574
+ const err = confirmError;
1575
+ throw new Error(
1576
+ `Transaction sent but confirmation failed: ${err.message}
1577
+ Signature: ${signature}
1578
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1579
+ );
1580
+ }
1565
1581
  return {
1566
1582
  verified: true,
1567
1583
  signature,
package/dist/index.js CHANGED
@@ -172,8 +172,15 @@ async function initWasm() {
172
172
  } else {
173
173
  const moduleUrl = new URL(import.meta.url);
174
174
  const isSourceFile = moduleUrl.pathname.includes("/src/");
175
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
176
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
175
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
176
+ let wasmJsUrl;
177
+ if (isSourceFile) {
178
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
179
+ } else if (isViteProduction) {
180
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
181
+ } else {
182
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
183
+ }
177
184
  const module = await import(
178
185
  /* @vite-ignore */
179
186
  wasmJsUrl.href
@@ -274,18 +281,12 @@ authors = [""]
274
281
  parameters.forEach((p, noirIndex) => {
275
282
  const r1csIndex = noirIndex + 1;
276
283
  witnessIndexMapping.set(noirIndex, r1csIndex);
277
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
278
284
  if (p.visibility === "public") {
279
285
  publicR1csIndices.push(r1csIndex);
280
286
  } else if (p.visibility === "private") {
281
287
  privateR1csIndices.push(r1csIndex);
282
288
  }
283
289
  });
284
- console.log("=== COMPILE: R1CS Witness Assignment ===");
285
- console.log("Public R1CS indices:", publicR1csIndices);
286
- console.log("Private R1CS indices:", privateR1csIndices);
287
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
288
- console.log("=========================================");
289
290
  const r1cs = {
290
291
  num_witnesses: parameters.length + 1,
291
292
  // +1 for w_0
@@ -304,25 +305,18 @@ authors = [""]
304
305
  c: [["0x1", publicIdx]]
305
306
  // expected
306
307
  });
307
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
308
- } else {
309
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
310
308
  }
311
309
  const r1csJson = JSON.stringify(r1cs);
312
- console.log("R1CS JSON:", r1csJson);
313
310
  let provingKey;
314
311
  let verifyingKey;
315
312
  let verifyingKeyGnark;
316
313
  if (this.config.cacheKeys) {
317
314
  try {
318
- console.log("Running trusted setup from R1CS...");
319
315
  const setupResult = wasm.setup_from_r1cs(r1csJson);
320
316
  provingKey = setupResult.proving_key;
321
317
  verifyingKey = setupResult.verifying_key;
322
318
  verifyingKeyGnark = setupResult.verifying_key_gnark;
323
- console.log("Setup complete!");
324
319
  } catch (error) {
325
- console.error("Setup failed:", error);
326
320
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
327
321
  }
328
322
  }
@@ -359,60 +353,23 @@ authors = [""]
359
353
  const noir = new Noir2(circuit);
360
354
  const { witness: compressedWitness } = await noir.execute(inputs);
361
355
  const witnessMapNoir = decompressWitness(compressedWitness);
362
- console.log("=== ARKWORKS WASM DEBUG ===");
363
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
364
- console.log("Inputs provided:", JSON.stringify(inputs));
365
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
366
- console.log("Decompressed witness entries:", witnessMapNoir.size);
367
- console.log("Witness map entries (first 10):");
368
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
369
- for (const [index, value] of sortedWitness.slice(0, 10)) {
370
- const strVal = String(value);
371
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
372
- if (strVal.startsWith("0x")) {
373
- try {
374
- const decVal = BigInt(strVal).toString(10);
375
- console.log(` \u2192 decimal: ${decVal}`);
376
- } catch {
377
- console.log(` \u2192 failed to parse as BigInt`);
378
- }
379
- }
380
- }
381
356
  const witnessMap = {};
382
357
  const witnessMapping = circuit.witnessIndexMapping;
383
- console.log("Converting noir witness to R1CS witness:");
384
358
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
385
359
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
386
360
  const strVal = String(value);
387
361
  witnessMap[r1csIndex.toString()] = strVal;
388
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
389
362
  }
390
363
  const witnessJson = JSON.stringify(witnessMap);
391
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
392
- const r1csParsed = JSON.parse(circuit.r1csJson);
393
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
394
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
395
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
396
- console.log("R1CS constraints:", r1csParsed.constraints.length);
397
364
  let provingKey = circuit.provingKey;
398
365
  if (!provingKey) {
399
- console.log("Running setup_from_r1cs...");
400
366
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
401
367
  provingKey = setupResult.proving_key;
402
368
  circuit.provingKey = provingKey;
403
369
  circuit.verifyingKey = setupResult.verifying_key;
404
370
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
405
371
  }
406
- console.log("Generating proof from R1CS...");
407
372
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
408
- console.log("=== PROOF RESULT DEBUG ===");
409
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
410
- proofResult.public_inputs.forEach((input, i) => {
411
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
412
- const decValue = BigInt(hexValue).toString(10);
413
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
414
- });
415
- console.log("===========================");
416
373
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
417
374
  return {
418
375
  proof: proofBytes,
@@ -1461,6 +1418,18 @@ var IziNoir = class _IziNoir {
1461
1418
  const networkConfig = NETWORK_CONFIG[this._network];
1462
1419
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1463
1420
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1421
+ const vkPubkey = new PublicKey(vk);
1422
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1423
+ if (!accountInfo) {
1424
+ throw new Error(
1425
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1426
+ );
1427
+ }
1428
+ if (accountInfo.data.length < 8) {
1429
+ throw new Error(
1430
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1431
+ );
1432
+ }
1464
1433
  const builder = new SolanaTransactionBuilder({
1465
1434
  programId: networkConfig.programId,
1466
1435
  computeUnits: 4e5
@@ -1488,12 +1457,59 @@ var IziNoir = class _IziNoir {
1488
1457
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1489
1458
  tx.recentBlockhash = blockhash;
1490
1459
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1491
- const signature = await wallet.sendTransaction(tx, connection);
1492
- await connection.confirmTransaction({
1493
- signature,
1494
- blockhash,
1495
- lastValidBlockHeight
1496
- });
1460
+ try {
1461
+ const simulation = await connection.simulateTransaction(tx);
1462
+ if (simulation.value.err) {
1463
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1464
+ throw new Error(
1465
+ `Transaction simulation failed:
1466
+ Error: ${JSON.stringify(simulation.value.err)}
1467
+ Logs:
1468
+ ${logs}`
1469
+ );
1470
+ }
1471
+ } catch (simError) {
1472
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1473
+ throw simError;
1474
+ }
1475
+ const err = simError;
1476
+ throw new Error(
1477
+ `Failed to simulate transaction: ${err.message}
1478
+ VK Account: ${vk}
1479
+ Network: ${this._network}
1480
+ Proof size: ${proofData.proof.bytes.length} bytes
1481
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1482
+ );
1483
+ }
1484
+ let signature;
1485
+ try {
1486
+ signature = await wallet.sendTransaction(tx, connection);
1487
+ } catch (sendError) {
1488
+ const originalError = sendError;
1489
+ const enhancedError = new Error(
1490
+ `Failed to send verify transaction: ${originalError.message}
1491
+ VK Account: ${vk}
1492
+ Network: ${this._network}
1493
+ Proof size: ${proofData.proof.bytes.length} bytes
1494
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1495
+ );
1496
+ enhancedError.cause = originalError;
1497
+ throw enhancedError;
1498
+ }
1499
+ try {
1500
+ await connection.confirmTransaction({
1501
+ signature,
1502
+ blockhash,
1503
+ lastValidBlockHeight
1504
+ });
1505
+ } catch (confirmError) {
1506
+ const err = confirmError;
1507
+ throw new Error(
1508
+ `Transaction sent but confirmation failed: ${err.message}
1509
+ Signature: ${signature}
1510
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1511
+ );
1512
+ }
1497
1513
  return {
1498
1514
  verified: true,
1499
1515
  signature,
@@ -96,8 +96,15 @@ async function initWasm() {
96
96
  } else {
97
97
  const moduleUrl = new URL(import_meta.url);
98
98
  const isSourceFile = moduleUrl.pathname.includes("/src/");
99
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
100
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
99
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
100
+ let wasmJsUrl;
101
+ if (isSourceFile) {
102
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
103
+ } else if (isViteProduction) {
104
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
105
+ } else {
106
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
107
+ }
101
108
  const module2 = await import(
102
109
  /* @vite-ignore */
103
110
  wasmJsUrl.href
@@ -202,18 +209,12 @@ authors = [""]
202
209
  parameters.forEach((p, noirIndex) => {
203
210
  const r1csIndex = noirIndex + 1;
204
211
  witnessIndexMapping.set(noirIndex, r1csIndex);
205
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
206
212
  if (p.visibility === "public") {
207
213
  publicR1csIndices.push(r1csIndex);
208
214
  } else if (p.visibility === "private") {
209
215
  privateR1csIndices.push(r1csIndex);
210
216
  }
211
217
  });
212
- console.log("=== COMPILE: R1CS Witness Assignment ===");
213
- console.log("Public R1CS indices:", publicR1csIndices);
214
- console.log("Private R1CS indices:", privateR1csIndices);
215
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
216
- console.log("=========================================");
217
218
  const r1cs = {
218
219
  num_witnesses: parameters.length + 1,
219
220
  // +1 for w_0
@@ -232,25 +233,18 @@ authors = [""]
232
233
  c: [["0x1", publicIdx]]
233
234
  // expected
234
235
  });
235
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
236
- } else {
237
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
238
236
  }
239
237
  const r1csJson = JSON.stringify(r1cs);
240
- console.log("R1CS JSON:", r1csJson);
241
238
  let provingKey;
242
239
  let verifyingKey;
243
240
  let verifyingKeyGnark;
244
241
  if (this.config.cacheKeys) {
245
242
  try {
246
- console.log("Running trusted setup from R1CS...");
247
243
  const setupResult = wasm.setup_from_r1cs(r1csJson);
248
244
  provingKey = setupResult.proving_key;
249
245
  verifyingKey = setupResult.verifying_key;
250
246
  verifyingKeyGnark = setupResult.verifying_key_gnark;
251
- console.log("Setup complete!");
252
247
  } catch (error) {
253
- console.error("Setup failed:", error);
254
248
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
255
249
  }
256
250
  }
@@ -287,60 +281,23 @@ authors = [""]
287
281
  const noir = new import_noir_js.Noir(circuit);
288
282
  const { witness: compressedWitness } = await noir.execute(inputs);
289
283
  const witnessMapNoir = (0, import_acvm_js.decompressWitness)(compressedWitness);
290
- console.log("=== ARKWORKS WASM DEBUG ===");
291
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
292
- console.log("Inputs provided:", JSON.stringify(inputs));
293
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
294
- console.log("Decompressed witness entries:", witnessMapNoir.size);
295
- console.log("Witness map entries (first 10):");
296
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
297
- for (const [index, value] of sortedWitness.slice(0, 10)) {
298
- const strVal = String(value);
299
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
300
- if (strVal.startsWith("0x")) {
301
- try {
302
- const decVal = BigInt(strVal).toString(10);
303
- console.log(` \u2192 decimal: ${decVal}`);
304
- } catch {
305
- console.log(` \u2192 failed to parse as BigInt`);
306
- }
307
- }
308
- }
309
284
  const witnessMap = {};
310
285
  const witnessMapping = circuit.witnessIndexMapping;
311
- console.log("Converting noir witness to R1CS witness:");
312
286
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
313
287
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
314
288
  const strVal = String(value);
315
289
  witnessMap[r1csIndex.toString()] = strVal;
316
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
317
290
  }
318
291
  const witnessJson = JSON.stringify(witnessMap);
319
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
320
- const r1csParsed = JSON.parse(circuit.r1csJson);
321
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
322
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
323
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
324
- console.log("R1CS constraints:", r1csParsed.constraints.length);
325
292
  let provingKey = circuit.provingKey;
326
293
  if (!provingKey) {
327
- console.log("Running setup_from_r1cs...");
328
294
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
329
295
  provingKey = setupResult.proving_key;
330
296
  circuit.provingKey = provingKey;
331
297
  circuit.verifyingKey = setupResult.verifying_key;
332
298
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
333
299
  }
334
- console.log("Generating proof from R1CS...");
335
300
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
336
- console.log("=== PROOF RESULT DEBUG ===");
337
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
338
- proofResult.public_inputs.forEach((input, i) => {
339
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
340
- const decValue = BigInt(hexValue).toString(10);
341
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
342
- });
343
- console.log("===========================");
344
301
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
345
302
  return {
346
303
  proof: proofBytes,
@@ -643,6 +600,11 @@ function getExplorerTxUrl(network, signature) {
643
600
  const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
644
601
  return `${config.explorerUrl.replace(/\?.*$/, "")}/tx/${signature}${clusterParam}`;
645
602
  }
603
+ function getExplorerAccountUrl(network, address) {
604
+ const config = NETWORK_CONFIG[network];
605
+ const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
606
+ return `${config.explorerUrl.replace(/\?.*$/, "")}/address/${address}${clusterParam}`;
607
+ }
646
608
 
647
609
  // src/domain/types/provider.ts
648
610
  var Provider = /* @__PURE__ */ ((Provider2) => {
@@ -1402,6 +1364,18 @@ var IziNoir = class _IziNoir {
1402
1364
  const networkConfig = NETWORK_CONFIG[this._network];
1403
1365
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1404
1366
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1367
+ const vkPubkey = new PublicKey(vk);
1368
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1369
+ if (!accountInfo) {
1370
+ throw new Error(
1371
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1372
+ );
1373
+ }
1374
+ if (accountInfo.data.length < 8) {
1375
+ throw new Error(
1376
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1377
+ );
1378
+ }
1405
1379
  const builder = new SolanaTransactionBuilder({
1406
1380
  programId: networkConfig.programId,
1407
1381
  computeUnits: 4e5
@@ -1429,12 +1403,59 @@ var IziNoir = class _IziNoir {
1429
1403
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1430
1404
  tx.recentBlockhash = blockhash;
1431
1405
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1432
- const signature = await wallet.sendTransaction(tx, connection);
1433
- await connection.confirmTransaction({
1434
- signature,
1435
- blockhash,
1436
- lastValidBlockHeight
1437
- });
1406
+ try {
1407
+ const simulation = await connection.simulateTransaction(tx);
1408
+ if (simulation.value.err) {
1409
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1410
+ throw new Error(
1411
+ `Transaction simulation failed:
1412
+ Error: ${JSON.stringify(simulation.value.err)}
1413
+ Logs:
1414
+ ${logs}`
1415
+ );
1416
+ }
1417
+ } catch (simError) {
1418
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1419
+ throw simError;
1420
+ }
1421
+ const err = simError;
1422
+ throw new Error(
1423
+ `Failed to simulate transaction: ${err.message}
1424
+ VK Account: ${vk}
1425
+ Network: ${this._network}
1426
+ Proof size: ${proofData.proof.bytes.length} bytes
1427
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1428
+ );
1429
+ }
1430
+ let signature;
1431
+ try {
1432
+ signature = await wallet.sendTransaction(tx, connection);
1433
+ } catch (sendError) {
1434
+ const originalError = sendError;
1435
+ const enhancedError = new Error(
1436
+ `Failed to send verify transaction: ${originalError.message}
1437
+ VK Account: ${vk}
1438
+ Network: ${this._network}
1439
+ Proof size: ${proofData.proof.bytes.length} bytes
1440
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1441
+ );
1442
+ enhancedError.cause = originalError;
1443
+ throw enhancedError;
1444
+ }
1445
+ try {
1446
+ await connection.confirmTransaction({
1447
+ signature,
1448
+ blockhash,
1449
+ lastValidBlockHeight
1450
+ });
1451
+ } catch (confirmError) {
1452
+ const err = confirmError;
1453
+ throw new Error(
1454
+ `Transaction sent but confirmation failed: ${err.message}
1455
+ Signature: ${signature}
1456
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1457
+ );
1458
+ }
1438
1459
  return {
1439
1460
  verified: true,
1440
1461
  signature,
@@ -77,8 +77,15 @@ async function initWasm() {
77
77
  } else {
78
78
  const moduleUrl = new URL(import.meta.url);
79
79
  const isSourceFile = moduleUrl.pathname.includes("/src/");
80
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
81
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
80
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
81
+ let wasmJsUrl;
82
+ if (isSourceFile) {
83
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
84
+ } else if (isViteProduction) {
85
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
86
+ } else {
87
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
88
+ }
82
89
  const module = await import(
83
90
  /* @vite-ignore */
84
91
  wasmJsUrl.href
@@ -179,18 +186,12 @@ authors = [""]
179
186
  parameters.forEach((p, noirIndex) => {
180
187
  const r1csIndex = noirIndex + 1;
181
188
  witnessIndexMapping.set(noirIndex, r1csIndex);
182
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
183
189
  if (p.visibility === "public") {
184
190
  publicR1csIndices.push(r1csIndex);
185
191
  } else if (p.visibility === "private") {
186
192
  privateR1csIndices.push(r1csIndex);
187
193
  }
188
194
  });
189
- console.log("=== COMPILE: R1CS Witness Assignment ===");
190
- console.log("Public R1CS indices:", publicR1csIndices);
191
- console.log("Private R1CS indices:", privateR1csIndices);
192
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
193
- console.log("=========================================");
194
195
  const r1cs = {
195
196
  num_witnesses: parameters.length + 1,
196
197
  // +1 for w_0
@@ -209,25 +210,18 @@ authors = [""]
209
210
  c: [["0x1", publicIdx]]
210
211
  // expected
211
212
  });
212
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
213
- } else {
214
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
215
213
  }
216
214
  const r1csJson = JSON.stringify(r1cs);
217
- console.log("R1CS JSON:", r1csJson);
218
215
  let provingKey;
219
216
  let verifyingKey;
220
217
  let verifyingKeyGnark;
221
218
  if (this.config.cacheKeys) {
222
219
  try {
223
- console.log("Running trusted setup from R1CS...");
224
220
  const setupResult = wasm.setup_from_r1cs(r1csJson);
225
221
  provingKey = setupResult.proving_key;
226
222
  verifyingKey = setupResult.verifying_key;
227
223
  verifyingKeyGnark = setupResult.verifying_key_gnark;
228
- console.log("Setup complete!");
229
224
  } catch (error) {
230
- console.error("Setup failed:", error);
231
225
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
232
226
  }
233
227
  }
@@ -264,60 +258,23 @@ authors = [""]
264
258
  const noir = new Noir(circuit);
265
259
  const { witness: compressedWitness } = await noir.execute(inputs);
266
260
  const witnessMapNoir = decompressWitness(compressedWitness);
267
- console.log("=== ARKWORKS WASM DEBUG ===");
268
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
269
- console.log("Inputs provided:", JSON.stringify(inputs));
270
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
271
- console.log("Decompressed witness entries:", witnessMapNoir.size);
272
- console.log("Witness map entries (first 10):");
273
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
274
- for (const [index, value] of sortedWitness.slice(0, 10)) {
275
- const strVal = String(value);
276
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
277
- if (strVal.startsWith("0x")) {
278
- try {
279
- const decVal = BigInt(strVal).toString(10);
280
- console.log(` \u2192 decimal: ${decVal}`);
281
- } catch {
282
- console.log(` \u2192 failed to parse as BigInt`);
283
- }
284
- }
285
- }
286
261
  const witnessMap = {};
287
262
  const witnessMapping = circuit.witnessIndexMapping;
288
- console.log("Converting noir witness to R1CS witness:");
289
263
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
290
264
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
291
265
  const strVal = String(value);
292
266
  witnessMap[r1csIndex.toString()] = strVal;
293
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
294
267
  }
295
268
  const witnessJson = JSON.stringify(witnessMap);
296
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
297
- const r1csParsed = JSON.parse(circuit.r1csJson);
298
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
299
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
300
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
301
- console.log("R1CS constraints:", r1csParsed.constraints.length);
302
269
  let provingKey = circuit.provingKey;
303
270
  if (!provingKey) {
304
- console.log("Running setup_from_r1cs...");
305
271
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
306
272
  provingKey = setupResult.proving_key;
307
273
  circuit.provingKey = provingKey;
308
274
  circuit.verifyingKey = setupResult.verifying_key;
309
275
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
310
276
  }
311
- console.log("Generating proof from R1CS...");
312
277
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
313
- console.log("=== PROOF RESULT DEBUG ===");
314
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
315
- proofResult.public_inputs.forEach((input, i) => {
316
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
317
- const decValue = BigInt(hexValue).toString(10);
318
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
319
- });
320
- console.log("===========================");
321
278
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
322
279
  return {
323
280
  proof: proofBytes,
@@ -610,6 +567,11 @@ function getExplorerTxUrl(network, signature) {
610
567
  const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
611
568
  return `${config.explorerUrl.replace(/\?.*$/, "")}/tx/${signature}${clusterParam}`;
612
569
  }
570
+ function getExplorerAccountUrl(network, address) {
571
+ const config = NETWORK_CONFIG[network];
572
+ const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
573
+ return `${config.explorerUrl.replace(/\?.*$/, "")}/address/${address}${clusterParam}`;
574
+ }
613
575
 
614
576
  // src/domain/types/provider.ts
615
577
  var Provider = /* @__PURE__ */ ((Provider2) => {
@@ -1369,6 +1331,18 @@ var IziNoir = class _IziNoir {
1369
1331
  const networkConfig = NETWORK_CONFIG[this._network];
1370
1332
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1371
1333
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1334
+ const vkPubkey = new PublicKey(vk);
1335
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1336
+ if (!accountInfo) {
1337
+ throw new Error(
1338
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1339
+ );
1340
+ }
1341
+ if (accountInfo.data.length < 8) {
1342
+ throw new Error(
1343
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1344
+ );
1345
+ }
1372
1346
  const builder = new SolanaTransactionBuilder({
1373
1347
  programId: networkConfig.programId,
1374
1348
  computeUnits: 4e5
@@ -1396,12 +1370,59 @@ var IziNoir = class _IziNoir {
1396
1370
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1397
1371
  tx.recentBlockhash = blockhash;
1398
1372
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1399
- const signature = await wallet.sendTransaction(tx, connection);
1400
- await connection.confirmTransaction({
1401
- signature,
1402
- blockhash,
1403
- lastValidBlockHeight
1404
- });
1373
+ try {
1374
+ const simulation = await connection.simulateTransaction(tx);
1375
+ if (simulation.value.err) {
1376
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1377
+ throw new Error(
1378
+ `Transaction simulation failed:
1379
+ Error: ${JSON.stringify(simulation.value.err)}
1380
+ Logs:
1381
+ ${logs}`
1382
+ );
1383
+ }
1384
+ } catch (simError) {
1385
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1386
+ throw simError;
1387
+ }
1388
+ const err = simError;
1389
+ throw new Error(
1390
+ `Failed to simulate transaction: ${err.message}
1391
+ VK Account: ${vk}
1392
+ Network: ${this._network}
1393
+ Proof size: ${proofData.proof.bytes.length} bytes
1394
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1395
+ );
1396
+ }
1397
+ let signature;
1398
+ try {
1399
+ signature = await wallet.sendTransaction(tx, connection);
1400
+ } catch (sendError) {
1401
+ const originalError = sendError;
1402
+ const enhancedError = new Error(
1403
+ `Failed to send verify transaction: ${originalError.message}
1404
+ VK Account: ${vk}
1405
+ Network: ${this._network}
1406
+ Proof size: ${proofData.proof.bytes.length} bytes
1407
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1408
+ );
1409
+ enhancedError.cause = originalError;
1410
+ throw enhancedError;
1411
+ }
1412
+ try {
1413
+ await connection.confirmTransaction({
1414
+ signature,
1415
+ blockhash,
1416
+ lastValidBlockHeight
1417
+ });
1418
+ } catch (confirmError) {
1419
+ const err = confirmError;
1420
+ throw new Error(
1421
+ `Transaction sent but confirmation failed: ${err.message}
1422
+ Signature: ${signature}
1423
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1424
+ );
1425
+ }
1405
1426
  return {
1406
1427
  verified: true,
1407
1428
  signature,
@@ -191,8 +191,15 @@ async function initWasm() {
191
191
  } else {
192
192
  const moduleUrl = new URL(import_meta.url);
193
193
  const isSourceFile = moduleUrl.pathname.includes("/src/");
194
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
195
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
194
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
195
+ let wasmJsUrl;
196
+ if (isSourceFile) {
197
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
198
+ } else if (isViteProduction) {
199
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
200
+ } else {
201
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
202
+ }
196
203
  const module2 = await import(
197
204
  /* @vite-ignore */
198
205
  wasmJsUrl.href
@@ -297,18 +304,12 @@ authors = [""]
297
304
  parameters.forEach((p, noirIndex) => {
298
305
  const r1csIndex = noirIndex + 1;
299
306
  witnessIndexMapping.set(noirIndex, r1csIndex);
300
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
301
307
  if (p.visibility === "public") {
302
308
  publicR1csIndices.push(r1csIndex);
303
309
  } else if (p.visibility === "private") {
304
310
  privateR1csIndices.push(r1csIndex);
305
311
  }
306
312
  });
307
- console.log("=== COMPILE: R1CS Witness Assignment ===");
308
- console.log("Public R1CS indices:", publicR1csIndices);
309
- console.log("Private R1CS indices:", privateR1csIndices);
310
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
311
- console.log("=========================================");
312
313
  const r1cs = {
313
314
  num_witnesses: parameters.length + 1,
314
315
  // +1 for w_0
@@ -327,25 +328,18 @@ authors = [""]
327
328
  c: [["0x1", publicIdx]]
328
329
  // expected
329
330
  });
330
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
331
- } else {
332
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
333
331
  }
334
332
  const r1csJson = JSON.stringify(r1cs);
335
- console.log("R1CS JSON:", r1csJson);
336
333
  let provingKey;
337
334
  let verifyingKey;
338
335
  let verifyingKeyGnark;
339
336
  if (this.config.cacheKeys) {
340
337
  try {
341
- console.log("Running trusted setup from R1CS...");
342
338
  const setupResult = wasm.setup_from_r1cs(r1csJson);
343
339
  provingKey = setupResult.proving_key;
344
340
  verifyingKey = setupResult.verifying_key;
345
341
  verifyingKeyGnark = setupResult.verifying_key_gnark;
346
- console.log("Setup complete!");
347
342
  } catch (error) {
348
- console.error("Setup failed:", error);
349
343
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
350
344
  }
351
345
  }
@@ -382,60 +376,23 @@ authors = [""]
382
376
  const noir = new import_noir_js2.Noir(circuit);
383
377
  const { witness: compressedWitness } = await noir.execute(inputs);
384
378
  const witnessMapNoir = (0, import_acvm_js.decompressWitness)(compressedWitness);
385
- console.log("=== ARKWORKS WASM DEBUG ===");
386
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
387
- console.log("Inputs provided:", JSON.stringify(inputs));
388
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
389
- console.log("Decompressed witness entries:", witnessMapNoir.size);
390
- console.log("Witness map entries (first 10):");
391
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
392
- for (const [index, value] of sortedWitness.slice(0, 10)) {
393
- const strVal = String(value);
394
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
395
- if (strVal.startsWith("0x")) {
396
- try {
397
- const decVal = BigInt(strVal).toString(10);
398
- console.log(` \u2192 decimal: ${decVal}`);
399
- } catch {
400
- console.log(` \u2192 failed to parse as BigInt`);
401
- }
402
- }
403
- }
404
379
  const witnessMap = {};
405
380
  const witnessMapping = circuit.witnessIndexMapping;
406
- console.log("Converting noir witness to R1CS witness:");
407
381
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
408
382
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
409
383
  const strVal = String(value);
410
384
  witnessMap[r1csIndex.toString()] = strVal;
411
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
412
385
  }
413
386
  const witnessJson = JSON.stringify(witnessMap);
414
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
415
- const r1csParsed = JSON.parse(circuit.r1csJson);
416
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
417
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
418
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
419
- console.log("R1CS constraints:", r1csParsed.constraints.length);
420
387
  let provingKey = circuit.provingKey;
421
388
  if (!provingKey) {
422
- console.log("Running setup_from_r1cs...");
423
389
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
424
390
  provingKey = setupResult.proving_key;
425
391
  circuit.provingKey = provingKey;
426
392
  circuit.verifyingKey = setupResult.verifying_key;
427
393
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
428
394
  }
429
- console.log("Generating proof from R1CS...");
430
395
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
431
- console.log("=== PROOF RESULT DEBUG ===");
432
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
433
- proofResult.public_inputs.forEach((input, i) => {
434
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
435
- const decValue = BigInt(hexValue).toString(10);
436
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
437
- });
438
- console.log("===========================");
439
396
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
440
397
  return {
441
398
  proof: proofBytes,
@@ -642,6 +599,11 @@ function getExplorerTxUrl(network, signature) {
642
599
  const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
643
600
  return `${config.explorerUrl.replace(/\?.*$/, "")}/tx/${signature}${clusterParam}`;
644
601
  }
602
+ function getExplorerAccountUrl(network, address) {
603
+ const config = NETWORK_CONFIG[network];
604
+ const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
605
+ return `${config.explorerUrl.replace(/\?.*$/, "")}/address/${address}${clusterParam}`;
606
+ }
645
607
 
646
608
  // src/domain/types/provider.ts
647
609
  var Provider = /* @__PURE__ */ ((Provider2) => {
@@ -1401,6 +1363,18 @@ var IziNoir = class _IziNoir {
1401
1363
  const networkConfig = NETWORK_CONFIG[this._network];
1402
1364
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1403
1365
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1366
+ const vkPubkey = new PublicKey(vk);
1367
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1368
+ if (!accountInfo) {
1369
+ throw new Error(
1370
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1371
+ );
1372
+ }
1373
+ if (accountInfo.data.length < 8) {
1374
+ throw new Error(
1375
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1376
+ );
1377
+ }
1404
1378
  const builder = new SolanaTransactionBuilder({
1405
1379
  programId: networkConfig.programId,
1406
1380
  computeUnits: 4e5
@@ -1428,12 +1402,59 @@ var IziNoir = class _IziNoir {
1428
1402
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1429
1403
  tx.recentBlockhash = blockhash;
1430
1404
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1431
- const signature = await wallet.sendTransaction(tx, connection);
1432
- await connection.confirmTransaction({
1433
- signature,
1434
- blockhash,
1435
- lastValidBlockHeight
1436
- });
1405
+ try {
1406
+ const simulation = await connection.simulateTransaction(tx);
1407
+ if (simulation.value.err) {
1408
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1409
+ throw new Error(
1410
+ `Transaction simulation failed:
1411
+ Error: ${JSON.stringify(simulation.value.err)}
1412
+ Logs:
1413
+ ${logs}`
1414
+ );
1415
+ }
1416
+ } catch (simError) {
1417
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1418
+ throw simError;
1419
+ }
1420
+ const err = simError;
1421
+ throw new Error(
1422
+ `Failed to simulate transaction: ${err.message}
1423
+ VK Account: ${vk}
1424
+ Network: ${this._network}
1425
+ Proof size: ${proofData.proof.bytes.length} bytes
1426
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1427
+ );
1428
+ }
1429
+ let signature;
1430
+ try {
1431
+ signature = await wallet.sendTransaction(tx, connection);
1432
+ } catch (sendError) {
1433
+ const originalError = sendError;
1434
+ const enhancedError = new Error(
1435
+ `Failed to send verify transaction: ${originalError.message}
1436
+ VK Account: ${vk}
1437
+ Network: ${this._network}
1438
+ Proof size: ${proofData.proof.bytes.length} bytes
1439
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1440
+ );
1441
+ enhancedError.cause = originalError;
1442
+ throw enhancedError;
1443
+ }
1444
+ try {
1445
+ await connection.confirmTransaction({
1446
+ signature,
1447
+ blockhash,
1448
+ lastValidBlockHeight
1449
+ });
1450
+ } catch (confirmError) {
1451
+ const err = confirmError;
1452
+ throw new Error(
1453
+ `Transaction sent but confirmation failed: ${err.message}
1454
+ Signature: ${signature}
1455
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1456
+ );
1457
+ }
1437
1458
  return {
1438
1459
  verified: true,
1439
1460
  signature,
@@ -172,8 +172,15 @@ async function initWasm() {
172
172
  } else {
173
173
  const moduleUrl = new URL(import.meta.url);
174
174
  const isSourceFile = moduleUrl.pathname.includes("/src/");
175
- const wasmRelativePath = isSourceFile ? "../../wasm/web/arkworks_groth16_wasm.js" : "./wasm/web/arkworks_groth16_wasm.js";
176
- const wasmJsUrl = new URL(wasmRelativePath, moduleUrl);
175
+ const isViteProduction = moduleUrl.pathname.includes("/assets/");
176
+ let wasmJsUrl;
177
+ if (isSourceFile) {
178
+ wasmJsUrl = new URL("../../wasm/web/arkworks_groth16_wasm.js", moduleUrl);
179
+ } else if (isViteProduction) {
180
+ wasmJsUrl = new URL("/wasm/web/arkworks_groth16_wasm.js", moduleUrl.origin);
181
+ } else {
182
+ wasmJsUrl = new URL("./wasm/web/arkworks_groth16_wasm.js", moduleUrl);
183
+ }
177
184
  const module = await import(
178
185
  /* @vite-ignore */
179
186
  wasmJsUrl.href
@@ -274,18 +281,12 @@ authors = [""]
274
281
  parameters.forEach((p, noirIndex) => {
275
282
  const r1csIndex = noirIndex + 1;
276
283
  witnessIndexMapping.set(noirIndex, r1csIndex);
277
- console.log(` Parameter "${p.name}" (${p.visibility}): noir[${noirIndex}] \u2192 R1CS w_${r1csIndex}`);
278
284
  if (p.visibility === "public") {
279
285
  publicR1csIndices.push(r1csIndex);
280
286
  } else if (p.visibility === "private") {
281
287
  privateR1csIndices.push(r1csIndex);
282
288
  }
283
289
  });
284
- console.log("=== COMPILE: R1CS Witness Assignment ===");
285
- console.log("Public R1CS indices:", publicR1csIndices);
286
- console.log("Private R1CS indices:", privateR1csIndices);
287
- console.log("Witness mapping:", Object.fromEntries(witnessIndexMapping));
288
- console.log("=========================================");
289
290
  const r1cs = {
290
291
  num_witnesses: parameters.length + 1,
291
292
  // +1 for w_0
@@ -304,25 +305,18 @@ authors = [""]
304
305
  c: [["0x1", publicIdx]]
305
306
  // expected
306
307
  });
307
- console.log(` Added constraint: w_${privateIdx} * w_${privateIdx} = w_${publicIdx}`);
308
- } else {
309
- console.warn("Complex circuit detected - R1CS constraint generation may be incomplete");
310
308
  }
311
309
  const r1csJson = JSON.stringify(r1cs);
312
- console.log("R1CS JSON:", r1csJson);
313
310
  let provingKey;
314
311
  let verifyingKey;
315
312
  let verifyingKeyGnark;
316
313
  if (this.config.cacheKeys) {
317
314
  try {
318
- console.log("Running trusted setup from R1CS...");
319
315
  const setupResult = wasm.setup_from_r1cs(r1csJson);
320
316
  provingKey = setupResult.proving_key;
321
317
  verifyingKey = setupResult.verifying_key;
322
318
  verifyingKeyGnark = setupResult.verifying_key_gnark;
323
- console.log("Setup complete!");
324
319
  } catch (error) {
325
- console.error("Setup failed:", error);
326
320
  throw new Error(`R1CS setup failed: ${error instanceof Error ? error.message : String(error)}`);
327
321
  }
328
322
  }
@@ -359,60 +353,23 @@ authors = [""]
359
353
  const noir = new Noir2(circuit);
360
354
  const { witness: compressedWitness } = await noir.execute(inputs);
361
355
  const witnessMapNoir = decompressWitness(compressedWitness);
362
- console.log("=== ARKWORKS WASM DEBUG ===");
363
- console.log("Circuit ABI parameters:", circuit.abi.parameters);
364
- console.log("Inputs provided:", JSON.stringify(inputs));
365
- console.log("Compressed witness size:", compressedWitness.length, "bytes");
366
- console.log("Decompressed witness entries:", witnessMapNoir.size);
367
- console.log("Witness map entries (first 10):");
368
- const sortedWitness = Array.from(witnessMapNoir.entries()).sort(([a], [b]) => a - b);
369
- for (const [index, value] of sortedWitness.slice(0, 10)) {
370
- const strVal = String(value);
371
- console.log(` witness[${index}] = "${strVal.slice(0, 66)}${strVal.length > 66 ? "..." : ""}"`);
372
- if (strVal.startsWith("0x")) {
373
- try {
374
- const decVal = BigInt(strVal).toString(10);
375
- console.log(` \u2192 decimal: ${decVal}`);
376
- } catch {
377
- console.log(` \u2192 failed to parse as BigInt`);
378
- }
379
- }
380
- }
381
356
  const witnessMap = {};
382
357
  const witnessMapping = circuit.witnessIndexMapping;
383
- console.log("Converting noir witness to R1CS witness:");
384
358
  for (const [noirIndex, value] of witnessMapNoir.entries()) {
385
359
  const r1csIndex = witnessMapping.get(noirIndex) ?? noirIndex + 1;
386
360
  const strVal = String(value);
387
361
  witnessMap[r1csIndex.toString()] = strVal;
388
- console.log(` noir[${noirIndex}] \u2192 R1CS w_${r1csIndex} = ${strVal.slice(0, 20)}...`);
389
362
  }
390
363
  const witnessJson = JSON.stringify(witnessMap);
391
- console.log("Witness JSON for prove:", witnessJson.slice(0, 200) + "...");
392
- const r1csParsed = JSON.parse(circuit.r1csJson);
393
- console.log("R1CS public_inputs:", r1csParsed.public_inputs);
394
- console.log("R1CS private_inputs:", r1csParsed.private_inputs);
395
- console.log("R1CS num_witnesses:", r1csParsed.num_witnesses);
396
- console.log("R1CS constraints:", r1csParsed.constraints.length);
397
364
  let provingKey = circuit.provingKey;
398
365
  if (!provingKey) {
399
- console.log("Running setup_from_r1cs...");
400
366
  const setupResult = wasm.setup_from_r1cs(circuit.r1csJson);
401
367
  provingKey = setupResult.proving_key;
402
368
  circuit.provingKey = provingKey;
403
369
  circuit.verifyingKey = setupResult.verifying_key;
404
370
  circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
405
371
  }
406
- console.log("Generating proof from R1CS...");
407
372
  const proofResult = wasm.prove_from_r1cs(provingKey, circuit.r1csJson, witnessJson);
408
- console.log("=== PROOF RESULT DEBUG ===");
409
- console.log("Proof public inputs from arkworks:", proofResult.public_inputs);
410
- proofResult.public_inputs.forEach((input, i) => {
411
- const hexValue = input.startsWith("0x") ? input : `0x${input}`;
412
- const decValue = BigInt(hexValue).toString(10);
413
- console.log(` Public input ${i}: ${input} (dec: ${decValue})`);
414
- });
415
- console.log("===========================");
416
373
  const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
417
374
  return {
418
375
  proof: proofBytes,
@@ -610,6 +567,11 @@ function getExplorerTxUrl(network, signature) {
610
567
  const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
611
568
  return `${config.explorerUrl.replace(/\?.*$/, "")}/tx/${signature}${clusterParam}`;
612
569
  }
570
+ function getExplorerAccountUrl(network, address) {
571
+ const config = NETWORK_CONFIG[network];
572
+ const clusterParam = network === "mainnet-beta" /* Mainnet */ ? "" : `?cluster=${network}`;
573
+ return `${config.explorerUrl.replace(/\?.*$/, "")}/address/${address}${clusterParam}`;
574
+ }
613
575
 
614
576
  // src/domain/types/provider.ts
615
577
  var Provider = /* @__PURE__ */ ((Provider2) => {
@@ -1369,6 +1331,18 @@ var IziNoir = class _IziNoir {
1369
1331
  const networkConfig = NETWORK_CONFIG[this._network];
1370
1332
  const { Connection, Transaction, PublicKey } = await import("@solana/web3.js");
1371
1333
  const connection = new Connection(networkConfig.rpcUrl, "confirmed");
1334
+ const vkPubkey = new PublicKey(vk);
1335
+ const accountInfo = await connection.getAccountInfo(vkPubkey);
1336
+ if (!accountInfo) {
1337
+ throw new Error(
1338
+ `VK account ${vk} does not exist on ${this._network}. Did deploy() succeed? Check the account on explorer: ${getExplorerAccountUrl(this._network, vk)}`
1339
+ );
1340
+ }
1341
+ if (accountInfo.data.length < 8) {
1342
+ throw new Error(
1343
+ `VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
1344
+ );
1345
+ }
1372
1346
  const builder = new SolanaTransactionBuilder({
1373
1347
  programId: networkConfig.programId,
1374
1348
  computeUnits: 4e5
@@ -1396,12 +1370,59 @@ var IziNoir = class _IziNoir {
1396
1370
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
1397
1371
  tx.recentBlockhash = blockhash;
1398
1372
  tx.feePayer = new PublicKey(wallet.publicKey.toBase58());
1399
- const signature = await wallet.sendTransaction(tx, connection);
1400
- await connection.confirmTransaction({
1401
- signature,
1402
- blockhash,
1403
- lastValidBlockHeight
1404
- });
1373
+ try {
1374
+ const simulation = await connection.simulateTransaction(tx);
1375
+ if (simulation.value.err) {
1376
+ const logs = simulation.value.logs?.join("\n") || "No logs available";
1377
+ throw new Error(
1378
+ `Transaction simulation failed:
1379
+ Error: ${JSON.stringify(simulation.value.err)}
1380
+ Logs:
1381
+ ${logs}`
1382
+ );
1383
+ }
1384
+ } catch (simError) {
1385
+ if (simError instanceof Error && simError.message.includes("Transaction simulation failed")) {
1386
+ throw simError;
1387
+ }
1388
+ const err = simError;
1389
+ throw new Error(
1390
+ `Failed to simulate transaction: ${err.message}
1391
+ VK Account: ${vk}
1392
+ Network: ${this._network}
1393
+ Proof size: ${proofData.proof.bytes.length} bytes
1394
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1395
+ );
1396
+ }
1397
+ let signature;
1398
+ try {
1399
+ signature = await wallet.sendTransaction(tx, connection);
1400
+ } catch (sendError) {
1401
+ const originalError = sendError;
1402
+ const enhancedError = new Error(
1403
+ `Failed to send verify transaction: ${originalError.message}
1404
+ VK Account: ${vk}
1405
+ Network: ${this._network}
1406
+ Proof size: ${proofData.proof.bytes.length} bytes
1407
+ Public inputs: ${proofData.publicInputs.hex.length} items`
1408
+ );
1409
+ enhancedError.cause = originalError;
1410
+ throw enhancedError;
1411
+ }
1412
+ try {
1413
+ await connection.confirmTransaction({
1414
+ signature,
1415
+ blockhash,
1416
+ lastValidBlockHeight
1417
+ });
1418
+ } catch (confirmError) {
1419
+ const err = confirmError;
1420
+ throw new Error(
1421
+ `Transaction sent but confirmation failed: ${err.message}
1422
+ Signature: ${signature}
1423
+ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
1424
+ );
1425
+ }
1405
1426
  return {
1406
1427
  verified: true,
1407
1428
  signature,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@izi-noir/sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Write ZK circuits in JavaScript/TypeScript, generate Noir code and proofs automatically",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",