create-izi-noir 0.2.10 → 0.2.12

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 (2) hide show
  1. package/dist/index.js +236 -35
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -172,7 +172,7 @@ var ProgressReporter = class {
172
172
  const frame = pc2.cyan(frames[frameIndex]);
173
173
  const phrase = THINKING_PHRASES[this.thinkingIndex % THINKING_PHRASES.length];
174
174
  const dots = ".".repeat(dotCount % 4);
175
- process.stdout.write(`\r${frame} ${pc2.dim(phrase)}${dots} `);
175
+ process.stdout.write(`\x1B[2K\r${frame} ${pc2.dim(phrase)}${dots}`);
176
176
  frameIndex = (frameIndex + 1) % frames.length;
177
177
  dotCount++;
178
178
  if (dotCount % 12 === 0) {
@@ -243,7 +243,7 @@ var InstallProgress = class {
243
243
  const bar = pc2.green("\u2588".repeat(filled)) + pc2.dim("\u2591".repeat(empty));
244
244
  const pkg = this.packages[this.currentPackage % this.packages.length];
245
245
  process.stdout.write(
246
- `\r${frame} Installing dependencies ${bar} ${pc2.dim(pkg)} `
246
+ `\x1B[2K\r${frame} Installing dependencies ${bar} ${pc2.dim(pkg)}`
247
247
  );
248
248
  frameIndex = (frameIndex + 1) % frames.length;
249
249
  if (this.progress < 95) {
@@ -288,7 +288,7 @@ var GitProgress = class {
288
288
  const frame = pc2.cyan(frames[frameIndex]);
289
289
  const phase = this.phases[this.phaseIndex % this.phases.length];
290
290
  const dots = ".".repeat(this.dotCount % 4);
291
- process.stdout.write(`\r${frame} ${pc2.dim(phase)}${dots} `);
291
+ process.stdout.write(`\x1B[2K\r${frame} ${pc2.dim(phase)}${dots}`);
292
292
  frameIndex = (frameIndex + 1) % frames.length;
293
293
  this.dotCount++;
294
294
  if (this.dotCount % 8 === 0) {
@@ -316,7 +316,7 @@ function createGitProgress() {
316
316
  function generatePackageJson(options) {
317
317
  const isSolana = options.provider === "arkworks";
318
318
  const dependencies = {
319
- "@izi-noir/sdk": "^0.1.6",
319
+ "@izi-noir/sdk": "^0.1.8",
320
320
  "@noir-lang/acvm_js": "1.0.0-beta.13-1d260df.nightly",
321
321
  "@noir-lang/noirc_abi": "1.0.0-beta.13-1d260df.nightly",
322
322
  "react": "^18.3.1",
@@ -483,7 +483,7 @@ function generateReadme(options) {
483
483
  const networkInfo = isSolana ? "- Deploy VK to Solana devnet\n- Verify proofs on-chain" : "- Local proof verification";
484
484
  return `# ${options.projectName}
485
485
 
486
- ZK proof demo built with [IZI-NOIR](https://github.com/izi-noir/izi-noir) and React.
486
+ ZK proof demo built with [IZI-NOIR](https://github.com/izi-noir) and React.
487
487
 
488
488
  ## Getting Started
489
489
 
@@ -543,7 +543,7 @@ After adding a new circuit:
543
543
 
544
544
  ## Learn More
545
545
 
546
- - [IZI-NOIR Documentation](https://github.com/izi-noir/izi-noir)
546
+ - [IZI-NOIR Documentation](https://github.com/izi-noir)
547
547
  - [Noir Language](https://noir-lang.org)
548
548
  - [Vite](https://vitejs.dev)
549
549
  - [React](https://react.dev)
@@ -717,7 +717,7 @@ function generateAppTsx(options) {
717
717
  const solanaImports = isSolana ? `
718
718
  import { useWallet } from '@solana/wallet-adapter-react';
719
719
  import { useWalletModal } from '@solana/wallet-adapter-react-ui';
720
- import { Chain, Network } from '@izi-noir/sdk';` : "";
720
+ import { Chain, Network, getExplorerTxUrl, getExplorerAccountUrl } from '@izi-noir/sdk';` : "";
721
721
  const solanaHooks = isSolana ? `
722
722
  const { publicKey, connected, sendTransaction } = useWallet();
723
723
  const { setVisible } = useWalletModal();` : "";
@@ -728,12 +728,23 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
728
728
  // Deploy state
729
729
  const [isDeploying, setIsDeploying] = useState(false);
730
730
  const [vkAccount, setVkAccount] = useState<string | null>(null);
731
+ const [deployTx, setDeployTx] = useState<string | null>(null);
731
732
  const [deployError, setDeployError] = useState<string | null>(null);
732
733
 
733
734
  // Verify state
734
735
  const [isVerifying, setIsVerifying] = useState(false);
735
736
  const [verified, setVerified] = useState<boolean | null>(null);
736
737
  const [verifyError, setVerifyError] = useState<string | null>(null);` : "";
738
+ const solanaCircuitResetCode = isSolana ? `
739
+ // Reset deploy state when circuit changes (VK will be different)
740
+ setVkAccount(null);
741
+ setDeployTx(null);
742
+ setVerified(null);` : "";
743
+ const solanaRecompileResetCode = isSolana ? `
744
+ // Reset deploy state since VK will change with recompilation
745
+ setVkAccount(null);
746
+ setDeployTx(null);
747
+ setVerified(null);` : "";
737
748
  const solanaHandlers = isSolana ? `
738
749
  // Deploy VK to Solana
739
750
  const handleDeploy = async () => {
@@ -745,6 +756,7 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
745
756
  try {
746
757
  const result = await iziInstance.deploy({ publicKey, sendTransaction });
747
758
  setVkAccount(result.vkAccount);
759
+ setDeployTx(result.signature);
748
760
  } catch (error) {
749
761
  console.error('Deploy error:', error);
750
762
  setDeployError((error as Error).message);
@@ -764,12 +776,23 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
764
776
  const result = await iziInstance.verifyOnChain({ publicKey, sendTransaction }, vkAccount);
765
777
  setVerified(result.verified);
766
778
  } catch (error) {
767
- console.error('Verify error:', error);
768
- setVerifyError((error as Error).message);
779
+ const err = error as Error;
780
+ console.error('Verify error details:', {
781
+ message: err.message,
782
+ cause: (err as unknown as { cause?: unknown }).cause,
783
+ stack: err.stack,
784
+ });
785
+ setVerifyError(err.message);
769
786
  } finally {
770
787
  setIsVerifying(false);
771
788
  }
772
789
  };` : "";
790
+ const solanaVkWarning = isSolana ? `
791
+ {vkAccount && compiledNoirCode !== noirCode && (
792
+ <div className="warning">
793
+ Circuit code changed. Generating a new proof will require re-deploying the VK.
794
+ </div>
795
+ )}` : "";
773
796
  const solanaDeploySection = isSolana ? `
774
797
  {/* Deploy & Verify Section */}
775
798
  {proof && (
@@ -791,21 +814,62 @@ import { Chain, Network } from '@izi-noir/sdk';` : "";
791
814
  {isDeploying ? 'Deploying...' : vkAccount ? 'Deployed' : 'Deploy VK'}
792
815
  </button>
793
816
  {deployError && <p className="error">{deployError}</p>}
794
- {vkAccount && <p className="success">VK: {vkAccount.slice(0, 8)}...</p>}
817
+ {vkAccount && (
818
+ <div className="deploy-result">
819
+ <div className="deploy-result-item">
820
+ <span className="deploy-label">VK Account:</span>
821
+ <a
822
+ href={getExplorerAccountUrl(Network.Devnet, vkAccount)}
823
+ target="_blank"
824
+ rel="noopener noreferrer"
825
+ className="explorer-link"
826
+ >
827
+ {vkAccount}
828
+ </a>
829
+ </div>
830
+ {deployTx && (
831
+ <div className="deploy-result-item">
832
+ <span className="deploy-label">Transaction:</span>
833
+ <a
834
+ href={getExplorerTxUrl(Network.Devnet, deployTx)}
835
+ target="_blank"
836
+ rel="noopener noreferrer"
837
+ className="explorer-link"
838
+ >
839
+ {deployTx}
840
+ </a>
841
+ </div>
842
+ )}
843
+ </div>
844
+ )}
795
845
  </div>
796
846
 
797
847
  <div className="verify-box">
798
- {publicInputs && (
799
- <div className="public-inputs-display">
800
- <span>Public inputs:</span>
801
- <code>{JSON.stringify(publicInputs)}</code>
848
+ {publicInputs && publicInputs.length > 0 && (
849
+ <div className="claim-card">
850
+ <p className="claim-label">Verifying claim:</p>
851
+ <div className="claim-content">
852
+ <p className="claim-text">
853
+ "I know private values that satisfy the circuit constraints with these public inputs:"
854
+ </p>
855
+ <div className="public-inputs-grid">
856
+ {publicInputs.map((hex, idx) => {
857
+ const decimal = BigInt(hex).toString();
858
+ return (
859
+ <div key={idx} className="public-input-card">
860
+ <span className="input-badge public">public</span>
861
+ <span className="public-input-value">{decimal}</span>
862
+ </div>
863
+ );
864
+ })}
865
+ </div>
866
+ </div>
802
867
  </div>
803
868
  )}
804
869
  <button
805
870
  onClick={handleVerify}
806
871
  disabled={!vkAccount || isVerifying}
807
872
  className="btn btn-primary"
808
- style={{ marginTop: publicInputs ? '0.5rem' : 0 }}
809
873
  >
810
874
  {isVerifying ? 'Verifying...' : verified ? 'Verified!' : 'Verify On-Chain'}
811
875
  </button>
@@ -875,8 +939,9 @@ function App() {
875
939
  const [localVerified, setLocalVerified] = useState<boolean | null>(null);
876
940
  const [publicInputs, setPublicInputs] = useState<string[] | null>(null);
877
941
 
878
- // IziNoir instance
942
+ // IziNoir instance and compiled code tracking
879
943
  const [iziInstance, setIziInstance] = useState<IziNoir | null>(null);
944
+ const [compiledNoirCode, setCompiledNoirCode] = useState<string | null>(null);
880
945
  ${solanaHooks}
881
946
  ${solanaState}
882
947
 
@@ -892,6 +957,9 @@ ${solanaState}
892
957
  setLocalVerified(null);
893
958
  setPublicInputs(null);
894
959
  setNoirCode(null);
960
+ // Reset compiled instance (forces recompilation)
961
+ setIziInstance(null);
962
+ setCompiledNoirCode(null);${solanaCircuitResetCode}
895
963
  }
896
964
  }, [selectedCircuit]);
897
965
 
@@ -939,14 +1007,21 @@ ${solanaState}
939
1007
 
940
1008
  const startTime = performance.now();
941
1009
 
942
- const izi = await IziNoir.init({
943
- provider: Provider.${capitalizeFirst(options.provider)},${solanaProviderConfig}
944
- });
1010
+ // Reuse existing instance if circuit hasn't changed
1011
+ let izi = iziInstance;
1012
+ const needsRecompile = !izi || compiledNoirCode !== noirCode;
945
1013
 
946
- await izi.compile(noirCode);
1014
+ if (needsRecompile) {
1015
+ izi = await IziNoir.init({
1016
+ provider: Provider.${capitalizeFirst(options.provider)},${solanaProviderConfig}
1017
+ });
947
1018
 
948
- const proofResult = await izi.prove(inputs);
949
- setIziInstance(izi);
1019
+ await izi.compile(noirCode);
1020
+ setIziInstance(izi);
1021
+ setCompiledNoirCode(noirCode);${solanaRecompileResetCode}
1022
+ }
1023
+
1024
+ const proofResult = await izi!.prove(inputs);
950
1025
 
951
1026
  // Get proof bytes
952
1027
  const proofBytes = 'bytes' in proofResult.proof
@@ -957,7 +1032,7 @@ ${solanaState}
957
1032
  : proofResult.publicInputs;
958
1033
 
959
1034
  // Local verification
960
- const verified = await izi.verify(proofBytes, publicInputsHex);
1035
+ const verified = await izi!.verify(proofBytes, publicInputsHex);
961
1036
  setLocalVerified(verified);
962
1037
 
963
1038
  const endTime = performance.now();
@@ -970,7 +1045,7 @@ ${solanaState}
970
1045
  } finally {
971
1046
  setIsGenerating(false);
972
1047
  }
973
- }, [noirCode, inputs]);
1048
+ }, [noirCode, inputs, iziInstance, compiledNoirCode]);
974
1049
  ${solanaHandlers}
975
1050
 
976
1051
  return (
@@ -1042,7 +1117,7 @@ ${solanaHandlers}
1042
1117
 
1043
1118
  {/* Generate Proof */}
1044
1119
  <div className="section">
1045
- <h2>4. Generate Proof</h2>
1120
+ <h2>4. Generate Proof</h2>${solanaVkWarning}
1046
1121
  <button
1047
1122
  onClick={handleGenerateProof}
1048
1123
  disabled={isGenerating || !noirCode || !!transpileError}
@@ -1076,7 +1151,7 @@ ${solanaDeploySection}
1076
1151
  </main>
1077
1152
 
1078
1153
  <footer>
1079
- <p>Built with <a href="https://github.com/izi-noir/izi-noir" target="_blank">IZI-NOIR</a></p>
1154
+ <p>Built with <a href="https://github.com/izi-noir" target="_blank">IZI-NOIR</a></p>
1080
1155
  </footer>
1081
1156
  </div>
1082
1157
  );
@@ -1469,6 +1544,16 @@ main {
1469
1544
  border-radius: 8px;
1470
1545
  }
1471
1546
 
1547
+ .warning {
1548
+ padding: 0.75rem 1rem;
1549
+ background: rgba(255, 193, 7, 0.1);
1550
+ border: 1px solid rgba(255, 193, 7, 0.3);
1551
+ border-radius: 8px;
1552
+ color: #ffc107;
1553
+ font-size: 0.875rem;
1554
+ margin-bottom: 1rem;
1555
+ }
1556
+
1472
1557
  /* ================================
1473
1558
  Noir Code Details
1474
1559
  ================================ */
@@ -1526,22 +1611,138 @@ main {
1526
1611
  }
1527
1612
 
1528
1613
  .public-inputs-display {
1529
- margin-top: 0.75rem;
1614
+ margin-bottom: 1rem;
1615
+ }
1616
+
1617
+ .public-inputs-label {
1618
+ display: block;
1530
1619
  font-size: 0.75rem;
1531
1620
  color: var(--text-muted);
1621
+ text-transform: uppercase;
1622
+ letter-spacing: 0.05em;
1623
+ margin-bottom: 0.75rem;
1532
1624
  }
1533
1625
 
1534
- .public-inputs-display code {
1535
- display: block;
1536
- margin-top: 0.5rem;
1537
- padding: 0.75rem;
1626
+ .public-inputs-list {
1627
+ display: flex;
1628
+ flex-direction: column;
1629
+ gap: 0.5rem;
1630
+ }
1631
+
1632
+ .public-input-item {
1633
+ display: flex;
1634
+ align-items: center;
1635
+ gap: 0.75rem;
1636
+ padding: 0.75rem 1rem;
1538
1637
  background: rgba(0, 0, 0, 0.4);
1539
1638
  border: 1px solid var(--border);
1639
+ border-radius: 12px;
1640
+ transition: border-color 0.3s ease;
1641
+ }
1642
+
1643
+ .public-input-item:hover {
1644
+ border-color: rgba(20, 241, 149, 0.3);
1645
+ }
1646
+
1647
+ .public-input-value {
1648
+ font-family: 'JetBrains Mono', monospace;
1649
+ font-size: 1rem;
1650
+ font-weight: 500;
1651
+ color: var(--text);
1652
+ }
1653
+
1654
+ /* ================================
1655
+ Claim Card - Public Inputs Display
1656
+ ================================ */
1657
+ .claim-card {
1658
+ margin-bottom: 1rem;
1659
+ padding: 1rem;
1660
+ background: rgba(20, 241, 149, 0.05);
1661
+ border: 1px solid rgba(20, 241, 149, 0.2);
1662
+ border-radius: 12px;
1663
+ }
1664
+
1665
+ .claim-label {
1666
+ font-size: 0.75rem;
1667
+ color: var(--solana-green);
1668
+ text-transform: uppercase;
1669
+ letter-spacing: 0.1em;
1670
+ font-weight: 600;
1671
+ margin-bottom: 0.75rem;
1672
+ }
1673
+
1674
+ .claim-content {
1675
+ padding: 0.5rem 0;
1676
+ }
1677
+
1678
+ .claim-text {
1679
+ font-size: 0.875rem;
1680
+ color: var(--text-muted);
1681
+ font-style: italic;
1682
+ margin-bottom: 1rem;
1683
+ line-height: 1.5;
1684
+ }
1685
+
1686
+ .public-inputs-grid {
1687
+ display: flex;
1688
+ flex-wrap: wrap;
1689
+ gap: 0.75rem;
1690
+ }
1691
+
1692
+ .public-input-card {
1693
+ display: flex;
1694
+ align-items: center;
1695
+ gap: 0.75rem;
1696
+ padding: 0.75rem 1rem;
1697
+ background: rgba(0, 0, 0, 0.4);
1698
+ border: 1px solid rgba(20, 241, 149, 0.3);
1699
+ border-radius: 12px;
1700
+ transition: border-color 0.3s ease, transform 0.3s ease;
1701
+ }
1702
+
1703
+ .public-input-card:hover {
1704
+ border-color: var(--solana-green);
1705
+ transform: translateY(-2px);
1706
+ }
1707
+
1708
+ .deploy-result {
1709
+ margin-top: 1rem;
1710
+ padding: 1rem;
1711
+ background: rgba(20, 241, 149, 0.05);
1712
+ border: 1px solid rgba(20, 241, 149, 0.2);
1540
1713
  border-radius: 8px;
1714
+ }
1715
+
1716
+ .deploy-result-item {
1717
+ margin-bottom: 0.75rem;
1718
+ }
1719
+
1720
+ .deploy-result-item:last-child {
1721
+ margin-bottom: 0;
1722
+ }
1723
+
1724
+ .deploy-label {
1725
+ display: block;
1726
+ font-size: 0.75rem;
1727
+ color: var(--text-muted);
1728
+ text-transform: uppercase;
1729
+ letter-spacing: 0.05em;
1730
+ margin-bottom: 0.25rem;
1731
+ }
1732
+
1733
+ .explorer-link {
1734
+ display: block;
1541
1735
  font-family: 'JetBrains Mono', monospace;
1542
- font-size: 0.7rem;
1543
- overflow-x: auto;
1544
- max-width: 100%;
1736
+ font-size: 0.75rem;
1737
+ color: var(--solana-green);
1738
+ text-decoration: none;
1739
+ word-break: break-all;
1740
+ transition: color 0.3s ease;
1741
+ }
1742
+
1743
+ .explorer-link:hover {
1744
+ color: var(--solana-purple);
1745
+ text-decoration: underline;
1545
1746
  }
1546
1747
 
1547
1748
  /* ================================
@@ -2741,7 +2942,7 @@ function printSuccessMessage(options) {
2741
2942
  console.log(pc3.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
2742
2943
  console.log();
2743
2944
  console.log(
2744
- pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
2945
+ pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir")
2745
2946
  );
2746
2947
  console.log();
2747
2948
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-izi-noir",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "CLI to scaffold IZI-NOIR ZK projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,7 +41,7 @@
41
41
  "license": "MIT",
42
42
  "repository": {
43
43
  "type": "git",
44
- "url": "https://github.com/izi-noir/izi-noir.git",
44
+ "url": "https://github.com/izi-noir.git",
45
45
  "directory": "packages/create-izi-noir"
46
46
  }
47
47
  }