From 7e42d72ff65cbad3c92bb90372d5e5b79f039b59 Mon Sep 17 00:00:00 2001 From: MaiCVCR Date: Wed, 11 Sep 2024 12:41:07 -0600 Subject: [PATCH] feat: add noir section --- .../app/engineering/circom/[slug]/page.tsx | 9 +- .../app/engineering/noir/[slug]/page.tsx | 59 +++++++++++++ .../nextjs/app/engineering/noir/layout.tsx | 18 ++++ packages/nextjs/app/engineering/noir/page.tsx | 78 ++++++++++++++++++ packages/nextjs/app/engineering/page.tsx | 2 +- packages/nextjs/components/Statement.tsx | 70 ++++++++++++---- .../{ => circom}/challenge_1/steps.json | 0 .../challenge_2/files/KnightsKnaves.circom | 0 .../challenge_2/files/Knightsknaves.wasm | Bin .../{ => circom}/challenge_2/files/input.json | 0 .../challenge_2/files/knightsknaves_0001.zkey | Bin .../challenge_2/files/verification_key.json | 0 .../{ => circom}/challenge_2/statement.js | 0 .../{ => circom}/challenge_2/steps.json | 0 .../challenge_3/files/CircomCustomLogic.sol | 0 .../{ => circom}/challenge_3/steps.json | 0 .../challenge_4/files/KnightsKnaves.circom | 0 .../challenge_4/files/Knightsknaves.wasm | Bin .../{ => circom}/challenge_4/files/index.html | 0 .../challenge_4/files/knightsknaves_0000.zkey | Bin .../challenge_4/files/verification_key.json | 0 .../{ => circom}/challenge_4/files/verify.js | 0 .../challenge_4/files/verifyProofPlonk.js | 0 .../{ => circom}/challenge_4/statement.js | 0 .../{ => circom}/challenge_4/steps.json | 0 .../challenges/noir/challenge_1/steps.json | 35 ++++++++ packages/nextjs/utils/getStep.ts | 4 +- 27 files changed, 253 insertions(+), 22 deletions(-) create mode 100644 packages/nextjs/app/engineering/noir/[slug]/page.tsx create mode 100644 packages/nextjs/app/engineering/noir/layout.tsx create mode 100644 packages/nextjs/app/engineering/noir/page.tsx rename packages/nextjs/public/challenges/{ => circom}/challenge_1/steps.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/files/KnightsKnaves.circom (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/files/Knightsknaves.wasm (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/files/input.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/files/knightsknaves_0001.zkey (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/files/verification_key.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/statement.js (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_2/steps.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_3/files/CircomCustomLogic.sol (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_3/steps.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/KnightsKnaves.circom (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/Knightsknaves.wasm (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/index.html (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/knightsknaves_0000.zkey (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/verification_key.json (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/verify.js (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/files/verifyProofPlonk.js (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/statement.js (100%) rename packages/nextjs/public/challenges/{ => circom}/challenge_4/steps.json (100%) create mode 100644 packages/nextjs/public/challenges/noir/challenge_1/steps.json diff --git a/packages/nextjs/app/engineering/circom/[slug]/page.tsx b/packages/nextjs/app/engineering/circom/[slug]/page.tsx index a64e1ec..0c0938b 100644 --- a/packages/nextjs/app/engineering/circom/[slug]/page.tsx +++ b/packages/nextjs/app/engineering/circom/[slug]/page.tsx @@ -11,7 +11,7 @@ type PageProps = { }; export default async function Page({ params }: PageProps) { - const { title, steps } = await getSteps(params.slug); + const { title, steps } = await getSteps(params.slug, "circom"); const challengeId = params.slug; return ( @@ -26,7 +26,7 @@ export default async function Page({ params }: PageProps) { {params.slug !== "1" && ( <> - +

@@ -45,7 +45,10 @@ export default async function Page({ params }: PageProps) {

{item.description}

{item.commands.join("\n")}
{item.files && ( - + Download: {item.files} )} diff --git a/packages/nextjs/app/engineering/noir/[slug]/page.tsx b/packages/nextjs/app/engineering/noir/[slug]/page.tsx new file mode 100644 index 0000000..f059711 --- /dev/null +++ b/packages/nextjs/app/engineering/noir/[slug]/page.tsx @@ -0,0 +1,59 @@ +import Image from "next/image"; +import Statement from "~~/components/Statement"; +import Verifier from "~~/components/Verifier"; +import AccordionItem from "~~/components/ui/AccordionItem"; +import { getSteps } from "~~/utils/getStep"; + +type PageProps = { + params: { + slug: string; + }; +}; + +export default async function Page({ params }: PageProps) { + const { title, steps } = await getSteps(params.slug, "noir"); + const challengeId = params.slug; + + return ( +
+
+
+ Mission +

+ Challenge #{params.slug} - {title} +

+
+ + {params.slug !== "1" && ( + <> + +
+ +
+ + )} + + {steps.map((item: any, index: number) => ( + +

{item.description}

+
{item.commands.join("\n")}
+ {item.files && ( + + Download: {item.files} + + )} +
+ } + /> + ))} +
+ + ); +} diff --git a/packages/nextjs/app/engineering/noir/layout.tsx b/packages/nextjs/app/engineering/noir/layout.tsx new file mode 100644 index 0000000..7790d64 --- /dev/null +++ b/packages/nextjs/app/engineering/noir/layout.tsx @@ -0,0 +1,18 @@ +import "@rainbow-me/rainbowkit/styles.css"; +import "~~/styles/globals.css"; +import { getMetadata } from "~~/utils/scaffold-eth/getMetadata"; + +export const metadata = getMetadata({ + title: "Zk Multiverse", + description: "Learn ZK with ZK Multiverse", +}); + +const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => { + return ( +
+ {children} +
+ ); +}; + +export default ScaffoldEthApp; diff --git a/packages/nextjs/app/engineering/noir/page.tsx b/packages/nextjs/app/engineering/noir/page.tsx new file mode 100644 index 0000000..d37cafc --- /dev/null +++ b/packages/nextjs/app/engineering/noir/page.tsx @@ -0,0 +1,78 @@ +"use client"; + +import React, { Fragment } from "react"; +import Image from "next/image"; +import Link from "next/link"; +import type { NextPage } from "next"; +import { chunkArray } from "~~/utils/chunkArray"; + +const challenges = [ + { id: 1, title: "Challenge #1", isLocked: false }, + { id: 2, title: "Challenge #2", isLocked: true }, + { id: 3, title: "Challenge #3", isLocked: true }, + { id: 4, title: "Challenge #4", isLocked: true }, + { id: 5, title: "Challenge #5", isLocked: true }, + { id: 6, title: "Challenge #6", isLocked: true }, +]; + +const Home: NextPage = () => { + const rows = chunkArray(challenges, 3); + + return ( + <> +
+

Noir

+ {rows.map((row, rowIndex) => ( +
+ {row.map((step, index) => { + const content = ( +
+
+
+ {step.title} + {step.isLocked && ( + Locked + )} +
+
+
+
+ ); + + return ( + + {step.isLocked ? ( + content + ) : ( + + {content} + + )} + {index < row.length - 1 &&
} +
+ ); + })} +
+ ))} +
+ + + ); +}; + +export default Home; diff --git a/packages/nextjs/app/engineering/page.tsx b/packages/nextjs/app/engineering/page.tsx index d188738..e35f75c 100644 --- a/packages/nextjs/app/engineering/page.tsx +++ b/packages/nextjs/app/engineering/page.tsx @@ -16,7 +16,7 @@ const languages = [ title: "Noir", image: "/images/languages/noir.png", link: "/engineering/noir", - locked: true, + locked: false, }, { title: "Python", diff --git a/packages/nextjs/components/Statement.tsx b/packages/nextjs/components/Statement.tsx index 50ab454..5c6b2f9 100644 --- a/packages/nextjs/components/Statement.tsx +++ b/packages/nextjs/components/Statement.tsx @@ -1,26 +1,64 @@ -import React from "react"; -// Import the statement for every challenge -import Challenge2Content from "../public/challenges/challenge_2/statement"; -import Challenge4Content from "../public/challenges/challenge_4/statement"; +"use client"; + +import React, { useEffect, useState } from "react"; type StatementProps = { challengeId: string; + lang: string; }; const NotFoundContent = () =>

Challenge not found

; -const Statement = ({ challengeId }: StatementProps) => { - let ChallengeContent; - - switch (challengeId) { - case "2": - ChallengeContent = Challenge2Content; - break; - case "4": - ChallengeContent = Challenge4Content; - break; - default: - ChallengeContent = NotFoundContent; +const Statement = ({ challengeId, lang }: StatementProps) => { + const [ChallengeContent, setChallengeContent] = useState(null); + + useEffect(() => { + const loadChallengeContent = async () => { + try { + switch (lang) { + case "circom": + switch (challengeId) { + case "2": + const { default: Challenge2Content } = await import( + "../public/challenges/circom/challenge_2/statement" + ); + setChallengeContent(() => Challenge2Content); + break; + case "4": + const { default: Challenge4Content } = await import( + "../public/challenges/circom/challenge_4/statement" + ); + setChallengeContent(() => Challenge4Content); + break; + default: + setChallengeContent(() => NotFoundContent); + break; + } + break; + + case "noir": // Otro caso para otro lenguaje + switch (challengeId) { + default: + setChallengeContent(() => NotFoundContent); + break; + } + break; + + default: + setChallengeContent(() => NotFoundContent); + break; + } + } catch (error) { + console.error("Error loading challenge content", error); + setChallengeContent(() => NotFoundContent); + } + }; + + loadChallengeContent(); + }, [challengeId, lang]); + + if (!ChallengeContent) { + return
Loading...
; } return ; diff --git a/packages/nextjs/public/challenges/challenge_1/steps.json b/packages/nextjs/public/challenges/circom/challenge_1/steps.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_1/steps.json rename to packages/nextjs/public/challenges/circom/challenge_1/steps.json diff --git a/packages/nextjs/public/challenges/challenge_2/files/KnightsKnaves.circom b/packages/nextjs/public/challenges/circom/challenge_2/files/KnightsKnaves.circom similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/files/KnightsKnaves.circom rename to packages/nextjs/public/challenges/circom/challenge_2/files/KnightsKnaves.circom diff --git a/packages/nextjs/public/challenges/challenge_2/files/Knightsknaves.wasm b/packages/nextjs/public/challenges/circom/challenge_2/files/Knightsknaves.wasm similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/files/Knightsknaves.wasm rename to packages/nextjs/public/challenges/circom/challenge_2/files/Knightsknaves.wasm diff --git a/packages/nextjs/public/challenges/challenge_2/files/input.json b/packages/nextjs/public/challenges/circom/challenge_2/files/input.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/files/input.json rename to packages/nextjs/public/challenges/circom/challenge_2/files/input.json diff --git a/packages/nextjs/public/challenges/challenge_2/files/knightsknaves_0001.zkey b/packages/nextjs/public/challenges/circom/challenge_2/files/knightsknaves_0001.zkey similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/files/knightsknaves_0001.zkey rename to packages/nextjs/public/challenges/circom/challenge_2/files/knightsknaves_0001.zkey diff --git a/packages/nextjs/public/challenges/challenge_2/files/verification_key.json b/packages/nextjs/public/challenges/circom/challenge_2/files/verification_key.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/files/verification_key.json rename to packages/nextjs/public/challenges/circom/challenge_2/files/verification_key.json diff --git a/packages/nextjs/public/challenges/challenge_2/statement.js b/packages/nextjs/public/challenges/circom/challenge_2/statement.js similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/statement.js rename to packages/nextjs/public/challenges/circom/challenge_2/statement.js diff --git a/packages/nextjs/public/challenges/challenge_2/steps.json b/packages/nextjs/public/challenges/circom/challenge_2/steps.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_2/steps.json rename to packages/nextjs/public/challenges/circom/challenge_2/steps.json diff --git a/packages/nextjs/public/challenges/challenge_3/files/CircomCustomLogic.sol b/packages/nextjs/public/challenges/circom/challenge_3/files/CircomCustomLogic.sol similarity index 100% rename from packages/nextjs/public/challenges/challenge_3/files/CircomCustomLogic.sol rename to packages/nextjs/public/challenges/circom/challenge_3/files/CircomCustomLogic.sol diff --git a/packages/nextjs/public/challenges/challenge_3/steps.json b/packages/nextjs/public/challenges/circom/challenge_3/steps.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_3/steps.json rename to packages/nextjs/public/challenges/circom/challenge_3/steps.json diff --git a/packages/nextjs/public/challenges/challenge_4/files/KnightsKnaves.circom b/packages/nextjs/public/challenges/circom/challenge_4/files/KnightsKnaves.circom similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/KnightsKnaves.circom rename to packages/nextjs/public/challenges/circom/challenge_4/files/KnightsKnaves.circom diff --git a/packages/nextjs/public/challenges/challenge_4/files/Knightsknaves.wasm b/packages/nextjs/public/challenges/circom/challenge_4/files/Knightsknaves.wasm similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/Knightsknaves.wasm rename to packages/nextjs/public/challenges/circom/challenge_4/files/Knightsknaves.wasm diff --git a/packages/nextjs/public/challenges/challenge_4/files/index.html b/packages/nextjs/public/challenges/circom/challenge_4/files/index.html similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/index.html rename to packages/nextjs/public/challenges/circom/challenge_4/files/index.html diff --git a/packages/nextjs/public/challenges/challenge_4/files/knightsknaves_0000.zkey b/packages/nextjs/public/challenges/circom/challenge_4/files/knightsknaves_0000.zkey similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/knightsknaves_0000.zkey rename to packages/nextjs/public/challenges/circom/challenge_4/files/knightsknaves_0000.zkey diff --git a/packages/nextjs/public/challenges/challenge_4/files/verification_key.json b/packages/nextjs/public/challenges/circom/challenge_4/files/verification_key.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/verification_key.json rename to packages/nextjs/public/challenges/circom/challenge_4/files/verification_key.json diff --git a/packages/nextjs/public/challenges/challenge_4/files/verify.js b/packages/nextjs/public/challenges/circom/challenge_4/files/verify.js similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/verify.js rename to packages/nextjs/public/challenges/circom/challenge_4/files/verify.js diff --git a/packages/nextjs/public/challenges/challenge_4/files/verifyProofPlonk.js b/packages/nextjs/public/challenges/circom/challenge_4/files/verifyProofPlonk.js similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/files/verifyProofPlonk.js rename to packages/nextjs/public/challenges/circom/challenge_4/files/verifyProofPlonk.js diff --git a/packages/nextjs/public/challenges/challenge_4/statement.js b/packages/nextjs/public/challenges/circom/challenge_4/statement.js similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/statement.js rename to packages/nextjs/public/challenges/circom/challenge_4/statement.js diff --git a/packages/nextjs/public/challenges/challenge_4/steps.json b/packages/nextjs/public/challenges/circom/challenge_4/steps.json similarity index 100% rename from packages/nextjs/public/challenges/challenge_4/steps.json rename to packages/nextjs/public/challenges/circom/challenge_4/steps.json diff --git a/packages/nextjs/public/challenges/noir/challenge_1/steps.json b/packages/nextjs/public/challenges/noir/challenge_1/steps.json new file mode 100644 index 0000000..a1066cd --- /dev/null +++ b/packages/nextjs/public/challenges/noir/challenge_1/steps.json @@ -0,0 +1,35 @@ +{ + "title": "Noir installation", + "steps": [ + { + "step": "Step 1 - Install Rust", + "description": ["Noir is built using Rust, so you need to install Rust first. Run the following command to install Rust:"], + "commands": ["curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"] + }, + { + "step": "Step 2", + "description": "After installation, you need to add Rust to your PATH by running:", + "commands": ["gsource $HOME/.cargo/env"] + }, + { + "step": "Step 3", + "description": "Verify that Rust is installed correctly by checking its version:", + "commands": ["rustc --version"] + }, + { + "step": "Step 4 - Install Noir", + "description": "With Rust installed, you can now install Noir using Cargo, the Rust package manager. To install the Noir version manager (noirup), run:", + "commands": ["cargo install noirup"] + }, + { + "step": "Step 5", + "description": "This installs the version manager, noirup, which helps you install and manage versions of Noir. To install the latest version of Noir, run:", + "commands": ["noirup install"] + }, + { + "step": "Step 6 - Create a New Noir Project", + "description": "Once Noir is installed, you can create a new project to start writing zk-SNARK circuits. To initialize a new Noir project inside a directory, use this command:", + "commands": ["nargo init"] + } + ] + } \ No newline at end of file diff --git a/packages/nextjs/utils/getStep.ts b/packages/nextjs/utils/getStep.ts index c697f8b..11cb2ba 100644 --- a/packages/nextjs/utils/getStep.ts +++ b/packages/nextjs/utils/getStep.ts @@ -1,8 +1,8 @@ import fs from "fs/promises"; import path from "path"; -export const getSteps = async (slug: string) => { - const filePath = path.join(process.cwd(), "public", "challenges", `challenge_${slug}/steps.json`); +export const getSteps = async (slug: string, lang: string) => { + const filePath = path.join(process.cwd(), "public", "challenges", `${lang}/challenge_${slug}/steps.json`); const jsonData = await fs.readFile(filePath, "utf-8"); const data = JSON.parse(jsonData);