├── .env.template ├── .eslintrc.json ├── .github └── DISCUSSION_TEMPLATE │ ├── challenge-ideas.yml │ ├── content-ideas.yml │ └── solidity-module-ideas.yml ├── .gitignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── data │ └── vyper │ │ ├── arrays.mdx │ │ ├── assertions-and-exceptions.mdx │ │ ├── conditional-statements.mdx │ │ ├── constants.mdx │ │ ├── data-types.mdx │ │ ├── events.mdx │ │ ├── functions.mdx │ │ ├── immutable.mdx │ │ ├── imports.mdx │ │ ├── interface.mdx │ │ ├── loops.mdx │ │ ├── mapping.mdx │ │ ├── mutability.mdx │ │ ├── operator.mdx │ │ ├── re-entrancy-locks.mdx │ │ ├── reentrancy-locks.mdx │ │ ├── structs.mdx │ │ ├── transacting-ether.mdx │ │ ├── variables.mdx │ │ └── visibility.mdx ├── favicon.ico ├── heros │ └── test.jpg ├── images │ ├── LevelUp.png │ ├── banner.jpg │ ├── banner.png │ ├── challenges │ │ └── order-route.png │ ├── coming-soon.png │ ├── comming_soon.png │ ├── comming_soon.svg │ ├── complete-lesson.png │ ├── content-banner.png │ ├── content-banner.svg │ ├── content.json │ ├── contents │ │ ├── how-to-fetch-scroll-canvas-badges │ │ │ ├── diagram.png │ │ │ └── final-result.png │ │ ├── matcha.png │ │ ├── order-route.png │ │ ├── stablecoins-module0 │ │ │ ├── openzeppelin_wizard.png │ │ │ ├── scroll_testnet_metamask.png │ │ │ └── token_hashmap.png │ │ ├── stablecoins-module1 │ │ │ ├── price_stability.png │ │ │ └── stablecoin_marketcap.png │ │ ├── stablecoins-module2 │ │ │ ├── gho_buckets.png │ │ │ ├── stablecoin_scenario.png │ │ │ └── stablecoin_users.png │ │ └── staticcall.png │ ├── contributing-banner.jpg │ ├── events.svg │ ├── events │ │ ├── alchemy-mini-hack.svg │ │ ├── eth-argentina.svg │ │ ├── eth-bkk.svg │ │ ├── eth-kl.svg │ │ ├── eth-tokyo.svg │ │ ├── ethcon.svg │ │ ├── icon │ │ │ ├── calendar.svg │ │ │ └── location.svg │ │ ├── scroll-open.svg │ │ └── writers-competition-2024q4.svg │ ├── funding-banner.png │ ├── how-it-works │ │ └── cozy.png │ ├── landing.png │ ├── landing.svg │ ├── landing │ │ ├── banner.svg │ │ ├── bg-mobile.png │ │ ├── bg.png │ │ ├── hero-mobile.svg │ │ ├── hero.svg │ │ ├── landing.png │ │ └── landing.svg │ ├── level-up-metadata.png │ ├── level-up-preview.png │ ├── podcast-banner.png │ ├── podcast-banner.svg │ ├── readme-banner.jpg │ ├── socials │ │ ├── telegram.svg │ │ ├── x.svg │ │ └── youtube.svg │ ├── solidity-banner.png │ ├── solidity-banner.svg │ ├── solidity │ │ ├── constants.png │ │ ├── data-types.png │ │ ├── operator.png │ │ └── transacting_ether.png │ └── warpcast.svg ├── opengraph-image.png └── twitter-image.png ├── scripts ├── processChallengeMarkdown.js ├── processContentMarkdown.js ├── processEventsMarkdown.js ├── processSolidityMarkdown.js ├── processVyperMarkdown.js └── turbo-ignore.sh ├── src ├── app │ ├── _grants │ │ └── page.tsx │ ├── _podcast │ │ ├── List │ │ │ ├── Category.tsx │ │ │ └── index.tsx │ │ └── page.tsx │ ├── api │ │ ├── challenge │ │ │ └── status │ │ │ │ └── route.ts │ │ ├── lesson │ │ │ └── progress │ │ │ │ └── route.ts │ │ ├── user │ │ │ └── profile │ │ │ │ └── route.ts │ │ └── utils │ │ │ └── auth.ts │ ├── challenges │ │ ├── List │ │ │ └── index.tsx │ │ ├── [slug] │ │ │ ├── ChallengeHeader.tsx │ │ │ ├── ChallengeNavigation.tsx │ │ │ ├── ChallengeStatus.tsx │ │ │ ├── ChallengeSubmit │ │ │ │ ├── CodeChallengeSubmit.tsx │ │ │ │ ├── CodeEditor.tsx │ │ │ │ ├── PureChallengeSubmit.tsx │ │ │ │ ├── SuccessAlert.tsx │ │ │ │ └── index.tsx │ │ │ ├── ChallengeViewer.tsx │ │ │ ├── MoreContent.tsx │ │ │ ├── SubmitAction.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── submission │ │ │ └── page.tsx │ ├── content │ │ ├── List │ │ │ ├── CategorySelect.tsx │ │ │ ├── LevelSelect.tsx │ │ │ └── index.tsx │ │ ├── [slug] │ │ │ ├── Attribution.tsx │ │ │ ├── ContentViewer │ │ │ │ └── index.tsx │ │ │ ├── MoreContent │ │ │ │ └── index.tsx │ │ │ └── page.tsx │ │ ├── content.json │ │ ├── layout.tsx │ │ └── page.tsx │ ├── events │ │ ├── List │ │ │ ├── HackathonItem.tsx │ │ │ └── index.tsx │ │ ├── [slug] │ │ │ ├── EventHeader.tsx │ │ │ ├── EventNavigation.tsx │ │ │ ├── EventOverview.tsx │ │ │ ├── EventSection.tsx │ │ │ ├── EventSubmit.tsx │ │ │ ├── EventViewer │ │ │ │ └── index.tsx │ │ │ ├── page.tsx │ │ │ ├── register │ │ │ │ └── page.tsx │ │ │ └── submit │ │ │ │ └── page.tsx │ │ ├── ethcon-korea │ │ │ ├── [challengeId] │ │ │ │ ├── ethcon-banner-base64.ts │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── actions │ │ │ │ ├── fetchBase.ts │ │ │ │ ├── fetchChallengeData.ts │ │ │ │ ├── fetchFlag.ts │ │ │ │ ├── fetchScoreboardData.ts │ │ │ │ ├── fetchUserData.ts │ │ │ │ ├── fetchUserSolvesData.ts │ │ │ │ └── index.ts │ │ │ ├── components │ │ │ │ ├── AuthWrapper.tsx │ │ │ │ ├── ErrorMsg.tsx │ │ │ │ ├── ErrorToastMsg.tsx │ │ │ │ ├── EthconPageLayout.tsx │ │ │ │ ├── EthconSectionHeader.tsx │ │ │ │ ├── JoinButton.tsx │ │ │ │ ├── LoadingMsg.tsx │ │ │ │ ├── Score.tsx │ │ │ │ └── index.tsx │ │ │ ├── config │ │ │ │ └── index.js │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ └── scoreboard │ │ │ │ └── page.tsx │ │ ├── eventsList.json │ │ ├── layout.tsx │ │ └── page.tsx │ ├── global-error.tsx │ ├── global.ts │ ├── globals.css │ ├── layout.tsx │ ├── loading.tsx │ ├── not-found.tsx │ ├── page.tsx │ ├── profile │ │ ├── InfoCard │ │ │ └── index.tsx │ │ ├── components │ │ │ ├── AvatarWithOverlay.tsx │ │ │ └── ProfileModal.tsx │ │ ├── layout.tsx │ │ ├── linkedList │ │ │ ├── LinkedSocialItem.tsx │ │ │ └── index.tsx │ │ ├── page.tsx │ │ └── poapsList │ │ │ └── index.tsx │ ├── sitemap.ts │ ├── solidity │ │ ├── LessonList │ │ │ ├── LessonCard.tsx │ │ │ └── index.tsx │ │ ├── [slug] │ │ │ ├── EditorPanel │ │ │ │ ├── CodeEditor.tsx │ │ │ │ ├── CongratulationModal.tsx │ │ │ │ ├── DiffEditor.tsx │ │ │ │ ├── Editor.tsx │ │ │ │ ├── ExerciseTabs.tsx │ │ │ │ ├── SubmitButton.tsx │ │ │ │ └── index.tsx │ │ │ ├── LessonNavigation │ │ │ │ └── index.tsx │ │ │ ├── LessonProgress │ │ │ │ └── index.tsx │ │ │ ├── Teaching │ │ │ │ └── index.tsx │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ └── page.tsx │ ├── template.tsx │ └── vyper │ │ ├── LessonList │ │ ├── LessonCard.tsx │ │ └── index.tsx │ │ ├── [slug] │ │ ├── EditorPanel │ │ │ ├── CodeEditor.tsx │ │ │ ├── CongratulationModal.tsx │ │ │ ├── DiffEditor.tsx │ │ │ ├── Editor.tsx │ │ │ ├── ExerciseTabs.tsx │ │ │ ├── SubmitButton.tsx │ │ │ └── index.tsx │ │ ├── LessonNavigation │ │ │ └── index.tsx │ │ ├── LessonProgress │ │ │ └── index.tsx │ │ ├── Teaching │ │ │ └── index.tsx │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── markdownData.json │ │ └── page.tsx ├── assets │ ├── abis │ │ ├── L1ETHGateway.json │ │ ├── L1GasPriceOracle.json │ │ ├── L1ScrollMessenger.json │ │ ├── L1StandardERC20Gateway.json │ │ ├── L1_GATEWAY_ROUTER_PROXY_ADDR.json │ │ ├── L1_MESSAGE_QUEUE_WITH_GAS_PRICE_ORACLE.json │ │ ├── L1_erc20ABI.json │ │ ├── L2ERC20Gateway.json │ │ ├── L2ETHGateway.json │ │ ├── L2ScrollMessenger.json │ │ ├── L2StandardERC20Gateway.json │ │ ├── L2WETHGateway.json │ │ ├── L2_GATEWAY_ROUTER_PROXY_ADDR.json │ │ ├── L2_erc20ABI.json │ │ ├── ScrollChain.json │ │ ├── ScrollOriginsNFT.json │ │ └── ScrollOriginsNFTV2.json │ ├── blog │ │ └── contribute-to-scroll.md │ ├── css │ │ ├── custom.css │ │ ├── markdown-level-up-light.css │ │ └── markdown-level-up.css │ ├── fonts │ │ ├── NeueHelvetica-Bold.woff │ │ ├── NeueHelvetica-Bold.woff2 │ │ ├── NeueHelvetica-Light.woff │ │ ├── NeueHelvetica-Light.woff2 │ │ ├── NeueHelvetica-Medium.woff │ │ ├── NeueHelvetica-Medium.woff2 │ │ ├── NeueHelvetica-Regular.woff │ │ └── NeueHelvetica-Regular.woff2 │ └── svgs │ │ ├── bridge │ │ ├── alert-error.svg │ │ ├── alert-success.svg │ │ ├── approve-token-selected.svg │ │ ├── arrow-down.svg │ │ ├── close.svg │ │ ├── copy-success.svg │ │ ├── copy.svg │ │ ├── disconnect.svg │ │ ├── edit.svg │ │ ├── empty.svg │ │ ├── etherscan.svg │ │ ├── external-link.svg │ │ ├── history-disconnected.svg │ │ ├── history.svg │ │ ├── info.svg │ │ ├── network-mainnet.svg │ │ ├── network-scroll.svg │ │ ├── praise.svg │ │ ├── remove.svg │ │ ├── token-list-close.svg │ │ ├── token-list-search.svg │ │ └── warning.svg │ │ ├── challenge │ │ ├── completed.svg │ │ └── success.svg │ │ ├── common │ │ ├── arrow-right.svg │ │ ├── back.svg │ │ ├── banner.svg │ │ ├── close-modal.svg │ │ ├── comming-soon.svg │ │ ├── external-link.svg │ │ ├── header-triangle-down.svg │ │ ├── landing.svg │ │ ├── no-data.svg │ │ ├── scroll-logo-icon.svg │ │ ├── scroll-logo-light.svg │ │ ├── scroll-logo-m.svg │ │ ├── scroll-logo.svg │ │ ├── three-dots.svg │ │ ├── triangle-down.svg │ │ ├── triangle-left.svg │ │ └── widgets.svg │ │ ├── content │ │ ├── copy.svg │ │ ├── link.svg │ │ ├── mobile-copy.svg │ │ └── slide.svg │ │ ├── ecosystem │ │ ├── arrow.svg │ │ ├── double-eyes.svg │ │ ├── empty.svg │ │ ├── error.svg │ │ ├── heart.svg │ │ ├── search.svg │ │ ├── settings.svg │ │ └── twitter.svg │ │ ├── events │ │ └── star.svg │ │ ├── header │ │ ├── arrow.svg │ │ └── menu.svg │ │ ├── profile │ │ ├── email.svg │ │ ├── github.svg │ │ ├── google.svg │ │ ├── link.svg │ │ ├── telegram.svg │ │ ├── twitter.svg │ │ ├── unlink.svg │ │ ├── upload.svg │ │ └── wallet.svg │ │ ├── socials │ │ ├── telegram.svg │ │ ├── x.svg │ │ └── youtube.svg │ │ ├── solidity │ │ ├── close.svg │ │ ├── error.svg │ │ ├── finish.svg │ │ ├── left-arrow-mobile.svg │ │ ├── left-arrow.svg │ │ ├── right-arrow-mobile.svg │ │ ├── right-arrow.svg │ │ ├── success.svg │ │ ├── twitter.svg │ │ ├── up.svg │ │ └── warpcast.svg │ │ └── wallet-connector │ │ ├── block.svg │ │ ├── copy.svg │ │ ├── disconnect.svg │ │ ├── down-triangle.svg │ │ └── wrong-network.svg ├── challenges │ ├── defi-challenges │ │ ├── 0x-challenge.mdx │ │ ├── ERC20.mdx │ │ ├── simple-lending.mdx │ │ └── simple-token-swap.mdx │ ├── solidity │ │ ├── arrays.mdx │ │ ├── conditional-statements.mdx │ │ ├── constants.mdx │ │ ├── constructor.mdx │ │ ├── data-location.mdx │ │ ├── data-types.mdx │ │ ├── enumerables.mdx │ │ ├── errors.mdx │ │ ├── ether-units.mdx │ │ ├── events.mdx │ │ ├── fallback.mdx │ │ ├── function-modifier.mdx │ │ ├── functions.mdx │ │ ├── getter-functions.mdx │ │ ├── immutable.mdx │ │ ├── loops.mdx │ │ ├── mapping.mdx │ │ ├── operator.mdx │ │ ├── payable.mdx │ │ ├── struct.mdx │ │ ├── transacting-ether.mdx │ │ ├── try-catch.mdx │ │ ├── validations-and-assertions.mdx │ │ ├── variables.mdx │ │ └── visibility.mdx │ └── vyper │ │ ├── arrays.mdx │ │ ├── assertions-and-exceptions.mdx │ │ ├── conditional-statements.mdx │ │ ├── constants.mdx │ │ ├── data-types.mdx │ │ ├── events.mdx │ │ ├── functions.mdx │ │ ├── immutable.mdx │ │ ├── imports.mdx │ │ ├── interface.mdx │ │ ├── loops.mdx │ │ ├── mapping.mdx │ │ ├── mutability.mdx │ │ ├── operator.mdx │ │ ├── reentrancy-locks.mdx │ │ ├── structs.mdx │ │ ├── transacting-ether.mdx │ │ ├── variables.mdx │ │ └── visibility.mdx ├── components │ ├── AnnouncementBar │ │ └── index.tsx │ ├── Back │ │ └── index.tsx │ ├── Button │ │ └── index.tsx │ ├── Card │ │ └── index.tsx │ ├── ChallengeButton │ │ └── index.tsx │ ├── ComingSoon │ │ └── index.js │ ├── CrossDetection │ │ └── index.tsx │ ├── EditorTooltip │ │ └── index.tsx │ ├── EventsHeader │ │ └── index.tsx │ ├── Footer │ │ └── index.tsx │ ├── Header │ │ ├── DesktopHeader.tsx │ │ ├── MenuTrigger │ │ │ └── index.tsx │ │ ├── MobileHeader.tsx │ │ ├── constants.ts │ │ ├── index.tsx │ │ ├── useCheckCustomNavBarBg.tsx │ │ └── useCheckTheme.tsx │ ├── HelpAlert │ │ └── index.tsx │ ├── MDXCodeHighlighter │ │ ├── CopyButton.tsx │ │ └── index.tsx │ ├── MDXHeaders │ │ └── index.tsx │ ├── MDXLayout │ │ └── index.tsx │ ├── MarkdownViewer │ │ ├── MarkdownLoading.tsx │ │ └── index.tsx │ ├── MoreContentSlide │ │ └── index.tsx │ ├── Navigation │ │ ├── NavigationWrapper.tsx │ │ └── index.tsx │ ├── NoData │ │ └── index.tsx │ ├── PageHeaderWrapper │ │ └── index.tsx │ ├── PlainSelect │ │ └── index.tsx │ ├── ScrollLogo │ │ └── index.tsx │ ├── ScrollToTop │ │ └── index.tsx │ ├── SectionHeader │ │ └── index.tsx │ ├── Select │ │ └── index.tsx │ ├── SiteTab │ │ └── index.tsx │ ├── TallyForm │ │ └── index.tsx │ ├── WalletToolkit │ │ ├── WalletDropdown.tsx │ │ └── index.tsx │ ├── Wrapper │ │ └── index.tsx │ └── YoutubeEmbed │ │ └── index.tsx ├── constants │ ├── common.ts │ ├── index.ts │ ├── layout.ts │ ├── networks.ts │ ├── route.ts │ ├── solidity │ │ ├── code-exercises.ts │ │ └── code-solutions.ts │ └── vyper │ │ ├── code-exercises.ts │ │ └── code-solutions.ts ├── contents │ ├── 0x-on-scroll.mdx │ ├── build-chance-based-dapp.mdx │ ├── exploring-solidity-objects-address-part-1.mdx │ ├── exploring-solidity-objects-address-part-2.mdx │ ├── guardrail-ai-agents.mdx │ ├── how-to-fetch-scroll-canvas-badges.mdx │ ├── huracan.mdx │ ├── l1sload-guide-read-arrays-mappings-structs.mdx │ ├── l1sload-guide-read-the-l1-state-from-l2.mdx │ ├── level-up-foundry.mdx │ ├── privacy-interfaces-on-soldity-zk-wasm.mdx │ ├── private-smart-contracts-with-solidity-and-circom.mdx │ ├── stablecoins-module0.mdx │ ├── stablecoins-module1.mdx │ └── stablecoins-module2.mdx ├── contexts │ ├── MessageProvider.tsx │ └── providers.tsx ├── events │ ├── alchemy-mini-hack │ │ ├── overview.mdx │ │ └── prizes.mdx │ └── writers-competition-2024q4 │ │ └── overview.mdx ├── hooks │ ├── index.ts │ ├── useAsyncMemo.tsx │ ├── useCheckViewport.ts │ ├── useMainBgColor.ts │ ├── useScrollToTop.ts │ └── useShowWalletToolkit.tsx ├── middleware.ts ├── stores │ ├── processStore.ts │ └── profileStore.ts ├── styles │ ├── globals.less │ ├── index.less │ ├── overrides.less │ └── variable.less ├── theme │ ├── dark.tsx │ ├── editorTheme.ts │ ├── index.tsx │ ├── light.tsx │ ├── markdownCodeViewer.ts │ └── options.ts ├── types │ ├── index.d.ts │ ├── network.d.ts │ ├── svg.d.ts │ └── token.d.ts └── utils │ ├── common.ts │ ├── dom.ts │ ├── format.ts │ ├── fs.ts │ ├── index.ts │ ├── localStorage.ts │ ├── logger.ts │ └── route.ts ├── tailwind.config.ts ├── tsconfig.json ├── turbo.json └── yarn.lock /.env.template: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_PRIVY_APP_ID="" 2 | NEXT_PUBLIC_PRIVY_APP_SECRET="" 3 | 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/core-web-vitals", "prettier"], 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "prettier/prettier": "error", 6 | "no-template-curly-in-string": "off", 7 | "no-useless-escape": "off", 8 | "no-unused-vars": "warn", 9 | "jsx-a11y/anchor-is-valid": "off", 10 | "no-extend-native": "off", 11 | "no-sequences": "off", 12 | "react-hooks/exhaustive-deps": "off", 13 | "react/jsx-pascal-case": "off" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/content-ideas.yml: -------------------------------------------------------------------------------- 1 | title: "🌟 List title of content idea here" 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: | 6 | Example of title: Introduce new category, Combine content ... 7 | - type: textarea 8 | attributes: 9 | label: 🧠 Description 10 | description: Describe your content idea. Include as much details as needed to convey your point. You may include resources, references or examples. 11 | validations: 12 | required: true 13 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/solidity-module-ideas.yml: -------------------------------------------------------------------------------- 1 | title: "🌟 List title of Solidity module idea here" 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: | 6 | Example of Solidity module title: Data Types 7 | - type: textarea 8 | attributes: 9 | label: 🧠 Module Overview 10 | description: Briefly describe key topics or concepts that the module will cover. How does this module complement or enhance current offerings? Are there any overlaps with existing modules? 11 | validations: 12 | required: true 13 | - type: textarea 14 | attributes: 15 | label: 📖 Learning Objectives 16 | description: List the specific outcomes for this module. What should participants ideally be able to do upon successful completion? 17 | validations: 18 | required: true 19 | - type: textarea 20 | attributes: 21 | label: 💭 Prerequisite 22 | description: High-level description of the 5 levels of exercises which will be created. (Aim of exercises are to help devs level up their concept/coding proficiency via repetition in progressive difficulty.) 23 | - type: textarea 24 | attributes: 25 | label: 🌐 Resources 26 | description: Are there any resources that you would like to add to support the development of this challenge? 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env 30 | .env*.local 31 | .vscode 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | next-env.d.ts 39 | 40 | # data files, generated at `next` dev/build time 41 | /public/data/challenges/ 42 | /public/data/solidity/ 43 | /public/data/contents/ 44 | /public/data/events/ 45 | /src/app/content/markdownData.json 46 | /src/app/challenges/markdownData.json 47 | /src/app/events/markdownData.json 48 | /src/app/solidity/markdownData.json 49 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Scroll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Level Up README](./public/images/readme-banner.jpg) 2 | 3 | [![X Follow](https://img.shields.io/twitter/follow/levelupweb3?style=social)](https://x.com/levelupweb3) 4 | [![Study Group](https://img.shields.io/badge/Telegram-Join%20Study%20Group-blue)](https://t.me/+jbhmyDZ63Vw0ZGYy) 5 | 6 | ## About Level Up 7 | 8 | At the core, Level Up is a one-stop platform to access any online or physical resources (i.e. Level Up Hub) that a developer could want or need in order to succeed in this ecosystem. 9 | 10 | We believe that community-oriented learning aligns with Ethereum ecosystem, and would open more doors for developers to get onboarded into the ecosystem. 11 | 12 | Level Up's North Star is to provide you with the best access to resources and support for beginner to expert Web3 builders around the world to skill up, find jobs, and launch their best ideas. 13 | 14 | ## Getting Started 15 | 16 | The Level Up community believes that the most effective way to learn is through practical experience. So, what are you waiting for? Join us today and begin your journey at [levelup.xyz](https://levelup.xyz) 17 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/data/vyper/conditional-statements.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Conditional Statements 3 | index: 13 4 | lesson: 13 5 | summary: Introduction to Vyper conditional statements 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Conditional Statements 10 | 11 | Vyper uses the `if` , `elif`, and `else` statements to control flow for conditional logic. 12 | 13 | Conditions are evaluated from left-to-right, an expression at a time, until the logic is found to be `true` or `false`. 14 | 15 | ```python 16 | # pragma version 0.4.0 17 | 18 | # Notice that the syntax for defining `bool` output must have the words "True" or "False" start with first letter capitalised 19 | @external 20 | @pure 21 | def check_less_than_ten(x: uint256) -> bool: 22 | if (x < 10): 23 | return True 24 | else: 25 | return False 26 | 27 | @external 28 | @pure 29 | def check_multiple_conditions(y: uint256) -> uint256: 30 | if (y < 5): 31 | return 1 32 | elif (y == 5): 33 | return 2 34 | else: 35 | return 3 36 | 37 | @external 38 | @pure 39 | def ternary_syntax(z: uint256) -> bool: 40 | return True if z < 5 else False 41 | ``` 42 | 43 |
44 | 45 | Vyper Differentiators 46 | 47 | 54 |
55 | 56 | ### Further Reading: 57 | 58 | - [Vyper Lang - Conditional Statements](https://docs.vyperlang.org/en/latest/control-structures.html#if-statements) 59 | -------------------------------------------------------------------------------- /public/data/vyper/constants.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Constants 3 | index: 3 4 | lesson: 3 5 | summary: Introduction to Vyper constants 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Constants 10 | 11 | Constants are variables that is only defined at a global level. Use the keyword `constant` to define a constant variable. 12 | 13 | ```python 14 | # pragma version 0.4.0 15 | 16 | SUPPLY_AMOUNT: constant(uint256) = 21000000 17 | BYTES_VALUE: constant(bytes32) = 0xabcd1123f8ae9a65dcc16f95643f2030aa505c6b465c8206e26ae84b525cdacb 18 | STRING_VALUE: constant(String[13]) = "Hello, world!" 19 | 20 | @external 21 | def retrieveConstants() -> (uint256, bytes32, String[13]): 22 | return (SUPPLY_AMOUNT, BYTES_VALUE, STRING_VALUE) 23 | ``` 24 | 25 |
26 | 27 | Vyper Differentiators 28 | 29 | 36 |
37 | 38 | ### Further Reading: 39 | 40 | - [Vyper Lang - Constants](https://docs.vyperlang.org/en/latest/constants-and-vars.html#custom-constants) 41 | -------------------------------------------------------------------------------- /public/data/vyper/events.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Events 3 | index: 17 4 | lesson: 17 5 | summary: Introduction to Vyper events 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Events 10 | 11 | Vyper emits up to five event logs. Each log contains both topics and data. 12 | 13 | - Topics (indexed arguments) are 32-byte description used to describe an event.They can be queried by listeners,and are identified by the `indexed` keyword. 14 | - Data (value arguments) do not have limitations. They can be complex data structures like arrays or strings. 15 | 16 | Important thing to remember is that events are not stored in the state. They are only available to clients. 17 | 18 | > ℹ️ Note 19 | > 20 | > Like Solidity, the first topic of the log record stores the event signature. 21 | 22 | ```python 23 | # pragma version 0.4.0 24 | 25 | event SendEtherEvent: 26 | sender: indexed(address) 27 | recipient: indexed(address) 28 | value: uint256 29 | 30 | @external 31 | @payable 32 | def sendEther(_recipient: address, _amount: uint256): 33 | assert _amount > 0, "Amount must be greater than 0" 34 | send(_recipient, _amount) 35 | 36 | # Emit event log 37 | log SendEtherEvent(msg.sender, _recipient, _amount) 38 | ``` 39 | 40 |
41 | 42 | Vyper Differentiators 43 | 44 | 47 |
48 | 49 | ### Further Reading: 50 | 51 | - [Vyper Lang - Events](https://docs.vyperlang.org/en/latest/event-logging.html#event-logging) 52 | -------------------------------------------------------------------------------- /public/data/vyper/immutable.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Immutable 3 | index: 4 4 | lesson: 4 5 | summary: Introduction to immutable keyword in Vyper 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Immutable 10 | 11 | Immutable variables are similar to constants, except the value must be defined in the constructor of the contract. Declare `immutable` variables if you want a variable to remain constant throughout the lifetime of a deployed contract. 12 | 13 | Accessing an immutable variable reduces runtime gas costs in comparison with `constant` variables. 14 | 15 | ```python 16 | # pragma version 0.4.0 17 | 18 | IMMUTABLE_INT: immutable(uint256) 19 | IMMUTABLE_ADDR: immutable(address) 20 | 21 | @deploy 22 | def __init__(): 23 | IMMUTABLE_INT = 999 24 | IMMUTABLE_ADDR = 0xE2b4795039517653c5Ae8C2A9BFdd783b48f447A 25 | 26 | @external 27 | @view 28 | def retrieveImmutables() -> (uint256, address): 29 | return (IMMUTABLE_INT, IMMUTABLE_ADDR) 30 | ``` 31 | 32 |
33 | 34 | Vyper Differentiators 35 | 36 | 39 |
40 | 41 | ### Further Reading: 42 | 43 | - [Vyper Lang - Immutable](https://docs.vyperlang.org/en/stable/scoping-and-declarations.html#declaring-immutable-variables) 44 | - [Vyper Lang - Built-In Function `convert()`](https://docs.vyperlang.org/en/stable/built-in-functions.html#convert) 45 | -------------------------------------------------------------------------------- /public/data/vyper/mapping.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mapping 3 | index: 7 4 | lesson: 7 5 | summary: Introduction to Vyper mapping 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Mapping 10 | 11 | Mappings are data structures known has [hash tables](https://en.wikipedia.org/wiki/Hash_table), that associate keys with values. They are declared as `HashMap[KeyType, ValueType]`. 12 | 13 | To look up a mapping value, you will need to use the `keccak256` hash of the key data. 14 | 15 | Note that mappings can only be declared as state variables. 16 | 17 | ```python 18 | # pragma version 0.4.0 19 | 20 | # Notice you will need to define mapping variable using `HashMap` keyword 21 | mapping_example: HashMap[uint256, String[100]] 22 | 23 | # Example below maps key value "1" to "Hello, World!" 24 | @external 25 | def set_mapping_pair(): 26 | self.mapping_example[1] = "Hello, World!" 27 | 28 | # Pass argument of "1" to deployed function below to view response 29 | @external 30 | @view 31 | def get_mapping_value(x: uint256) -> String[100]: 32 | return self.mapping_example[x] 33 | ``` 34 | 35 | ### Further Reading: 36 | 37 | - [Vyper Lang - Mapping](https://docs.vyperlang.org/en/stable/types.html#mappings) 38 | -------------------------------------------------------------------------------- /public/data/vyper/mutability.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mutability 3 | index: 9 4 | lesson: 9 5 | summary: Introduction to Vyper mutability 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Mutability 10 | 11 | In addition to visibility decorators, Vyper have four types of optional decorators which can be used to declare a function's mutability. 12 | 13 | - @pure: purely to execute a function without reading or modifying state. 14 | - @view: to read state but not modify it. Necessary decorator to define getter functions. 15 | 16 | - @nonpayable(default): prevents receival of Ether. 17 | - @payable: can receive and access Ether via `msg.value`. 18 | 19 | ```python 20 | # pragma version 0.4.0 21 | 22 | example_integer: public(uint256) 23 | 24 | # If the decorator "@payable" is absent, the contract will not be able to receive Ether 25 | @deploy 26 | @payable 27 | def __init__(): 28 | self.example_integer = 534532 29 | 30 | # Pure function to test addition function without modifying state 31 | @external 32 | @pure 33 | def purelyAddingFunction(x: uint256, y: uint256) -> uint256: 34 | return x + y 35 | 36 | @external 37 | @view 38 | def getExampleInteger() -> uint256: 39 | return self.example_integer 40 | ``` 41 | 42 |
43 | 44 | Vyper Differentiators 45 | 46 | 51 |
52 | 53 | ### Further Reading: 54 | 55 | - [Vyper Lang - Mutability](https://docs.vyperlang.org/en/latest/control-structures.html#mutability) 56 | -------------------------------------------------------------------------------- /public/data/vyper/structs.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | name: Structs 3 | index: 12 4 | lesson: 12 5 | summary: Introduction to Vyper structs 6 | labels: ["vyper"] 7 | --- 8 | 9 | # Structs 10 | 11 | Structs are custom data types to define a group of variables. They can be used inside mappings and arrays. 12 | 13 | Struct members can be accessed via `struct.argument_name`. 14 | 15 | ```python 16 | # pragma version 0.4.0 17 | 18 | struct ExampleStruct: 19 | sender_address: address 20 | amount_sent: uint256 21 | 22 | exampleStruct: public(ExampleStruct) 23 | 24 | # State modifying function to update struct variable 25 | @external 26 | def modify_struct_variable(amount: uint256): 27 | self.exampleStruct.sender_address = msg.sender 28 | self.exampleStruct.amount_sent = amount 29 | 30 | # Getter function to return struct variable 31 | @external 32 | @view 33 | def get_struct_variable() -> ExampleStruct: 34 | return self.exampleStruct 35 | ``` 36 | 37 | ### Further Reading: 38 | 39 | - [Vyper Lang - Struct](https://docs.vyperlang.org/en/latest/types.html#structs) 40 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/favicon.ico -------------------------------------------------------------------------------- /public/heros/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/heros/test.jpg -------------------------------------------------------------------------------- /public/images/LevelUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/LevelUp.png -------------------------------------------------------------------------------- /public/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/banner.jpg -------------------------------------------------------------------------------- /public/images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/banner.png -------------------------------------------------------------------------------- /public/images/challenges/order-route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/challenges/order-route.png -------------------------------------------------------------------------------- /public/images/coming-soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/coming-soon.png -------------------------------------------------------------------------------- /public/images/comming_soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/comming_soon.png -------------------------------------------------------------------------------- /public/images/complete-lesson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/complete-lesson.png -------------------------------------------------------------------------------- /public/images/content-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/content-banner.png -------------------------------------------------------------------------------- /public/images/contents/how-to-fetch-scroll-canvas-badges/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/how-to-fetch-scroll-canvas-badges/diagram.png -------------------------------------------------------------------------------- /public/images/contents/how-to-fetch-scroll-canvas-badges/final-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/how-to-fetch-scroll-canvas-badges/final-result.png -------------------------------------------------------------------------------- /public/images/contents/matcha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/matcha.png -------------------------------------------------------------------------------- /public/images/contents/order-route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/order-route.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module0/openzeppelin_wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module0/openzeppelin_wizard.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module0/scroll_testnet_metamask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module0/scroll_testnet_metamask.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module0/token_hashmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module0/token_hashmap.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module1/price_stability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module1/price_stability.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module1/stablecoin_marketcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module1/stablecoin_marketcap.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module2/gho_buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module2/gho_buckets.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module2/stablecoin_scenario.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module2/stablecoin_scenario.png -------------------------------------------------------------------------------- /public/images/contents/stablecoins-module2/stablecoin_users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/stablecoins-module2/stablecoin_users.png -------------------------------------------------------------------------------- /public/images/contents/staticcall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contents/staticcall.png -------------------------------------------------------------------------------- /public/images/contributing-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/contributing-banner.jpg -------------------------------------------------------------------------------- /public/images/events/icon/location.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/images/funding-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/funding-banner.png -------------------------------------------------------------------------------- /public/images/how-it-works/cozy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/how-it-works/cozy.png -------------------------------------------------------------------------------- /public/images/landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/landing.png -------------------------------------------------------------------------------- /public/images/landing/bg-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/landing/bg-mobile.png -------------------------------------------------------------------------------- /public/images/landing/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/landing/bg.png -------------------------------------------------------------------------------- /public/images/landing/landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/landing/landing.png -------------------------------------------------------------------------------- /public/images/level-up-metadata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/level-up-metadata.png -------------------------------------------------------------------------------- /public/images/level-up-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/level-up-preview.png -------------------------------------------------------------------------------- /public/images/podcast-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/podcast-banner.png -------------------------------------------------------------------------------- /public/images/readme-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/readme-banner.jpg -------------------------------------------------------------------------------- /public/images/socials/telegram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/images/socials/x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/images/socials/youtube.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/images/solidity-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/solidity-banner.png -------------------------------------------------------------------------------- /public/images/solidity/constants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/solidity/constants.png -------------------------------------------------------------------------------- /public/images/solidity/data-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/solidity/data-types.png -------------------------------------------------------------------------------- /public/images/solidity/operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/solidity/operator.png -------------------------------------------------------------------------------- /public/images/solidity/transacting_ether.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/images/solidity/transacting_ether.png -------------------------------------------------------------------------------- /public/images/warpcast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/opengraph-image.png -------------------------------------------------------------------------------- /public/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LevelUpWeb3/app/c2be2e98a3f4d932c335a895624d9b13475577ee/public/twitter-image.png -------------------------------------------------------------------------------- /scripts/processContentMarkdown.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const matter = require("gray-matter"); 4 | 5 | const markdownDirectory = path.join(process.cwd(), "src/contents"); 6 | const JSONDirectory = path.join(process.cwd(), "src/app/content/"); 7 | const publicDirectory = path.join(process.cwd(), "public/data/contents"); 8 | 9 | const processContentMarkdownFiles = async () => { 10 | const fileNames = fs.readdirSync(markdownDirectory); 11 | 12 | const allContentDataPromises = fileNames.map(async (fileName) => { 13 | const id = fileName.replace(/\.mdx$/, ""); 14 | 15 | const fullPath = path.join(markdownDirectory, fileName); 16 | const fileContents = fs.readFileSync(fullPath, "utf8"); 17 | 18 | const { data } = matter(fileContents); 19 | 20 | if (!data.name) return null; 21 | 22 | const contentData = { 23 | id, 24 | ...data, 25 | }; 26 | const individualOutputPath = path.join(publicDirectory, `${id}.mdx`); 27 | 28 | if (!fs.existsSync(publicDirectory)) 29 | fs.mkdirSync(publicDirectory, { recursive: true }); 30 | fs.writeFileSync(individualOutputPath, fileContents); 31 | 32 | return contentData; 33 | }); 34 | 35 | const allContentData = await Promise.all(allContentDataPromises); 36 | 37 | const markdownData = allContentData 38 | .filter((data) => data) 39 | .sort(({ index: a }, { index: b }) => { 40 | return a - b; 41 | }); 42 | 43 | fs.writeFileSync( 44 | path.join(JSONDirectory, "markdownData.json"), 45 | JSON.stringify(markdownData, null, 2), 46 | ); // Pretty print JSON 47 | }; 48 | 49 | processContentMarkdownFiles().catch(console.error); 50 | -------------------------------------------------------------------------------- /scripts/processSolidityMarkdown.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const matter = require("gray-matter"); 4 | 5 | const markdownDirectory = path.join(process.cwd(), "src/challenges/solidity"); 6 | const JSONDirectory = path.join(process.cwd(), "src/app/solidity/"); 7 | const outputDirectory = path.join(process.cwd(), "public/data/solidity"); 8 | 9 | const processSolidityMarkdownFiles = async () => { 10 | const fileNames = fs.readdirSync(markdownDirectory); 11 | 12 | const allChallengesDataPromises = fileNames.map(async (fileName) => { 13 | const id = fileName.replace(/\.mdx$/, ""); 14 | 15 | const fullPath = path.join(markdownDirectory, fileName); 16 | const fileContents = fs.readFileSync(fullPath, "utf8"); 17 | 18 | const { data } = matter(fileContents); 19 | if (!data.name) return null; 20 | 21 | const challengeData = { 22 | id, 23 | ...data, 24 | }; 25 | const individualOutputPath = path.join(outputDirectory, `${id}.mdx`); 26 | 27 | if (!fs.existsSync(outputDirectory)) 28 | fs.mkdirSync(outputDirectory, { recursive: true }); 29 | fs.writeFileSync(individualOutputPath, fileContents); 30 | 31 | return challengeData; 32 | }); 33 | 34 | const allChallengesData = await Promise.all(allChallengesDataPromises); 35 | 36 | const markdownData = allChallengesData 37 | .filter((data) => data) 38 | .sort(({ index: a }, { index: b }) => { 39 | return a - b; 40 | }); 41 | 42 | fs.writeFileSync( 43 | path.join(JSONDirectory, "markdownData.json"), 44 | JSON.stringify(markdownData, null, 2), 45 | ); // Pretty print JSON 46 | }; 47 | 48 | processSolidityMarkdownFiles().catch(console.error); 49 | -------------------------------------------------------------------------------- /scripts/processVyperMarkdown.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const matter = require("gray-matter"); 4 | 5 | const markdownDirectory = path.join(process.cwd(), "src/challenges/vyper"); 6 | const JSONDirectory = path.join(process.cwd(), "src/app/vyper/"); 7 | const outputDirectory = path.join(process.cwd(), "public/data/vyper"); 8 | 9 | const processVyperMarkdownFiles = async () => { 10 | const fileNames = fs.readdirSync(markdownDirectory); 11 | 12 | const allChallengesDataPromises = fileNames.map(async (fileName) => { 13 | const id = fileName.replace(/\.mdx$/, ""); 14 | 15 | const fullPath = path.join(markdownDirectory, fileName); 16 | const fileContents = fs.readFileSync(fullPath, "utf8"); 17 | 18 | const { data } = matter(fileContents); 19 | if (!data.name) return null; 20 | 21 | const challengeData = { 22 | id, 23 | ...data, 24 | }; 25 | const individualOutputPath = path.join(outputDirectory, `${id}.mdx`); 26 | 27 | if (!fs.existsSync(outputDirectory)) 28 | fs.mkdirSync(outputDirectory, { recursive: true }); 29 | fs.writeFileSync(individualOutputPath, fileContents); 30 | 31 | return challengeData; 32 | }); 33 | 34 | const allChallengesData = await Promise.all(allChallengesDataPromises); 35 | 36 | const markdownData = allChallengesData 37 | .filter((data) => data) 38 | .sort(({ index: a }, { index: b }) => { 39 | return a - b; 40 | }); 41 | 42 | fs.writeFileSync( 43 | path.join(JSONDirectory, "markdownData.json"), 44 | JSON.stringify(markdownData, null, 2), 45 | ); // Pretty print JSON 46 | }; 47 | 48 | processVyperMarkdownFiles().catch(console.error); 49 | -------------------------------------------------------------------------------- /scripts/turbo-ignore.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if [ -f next.config.js ]; then 4 | npx turbo-ignore --fallback=HEAD^1 5 | else 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /src/app/_grants/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import Script from "next/script"; 5 | import { styled } from "@mui/material"; 6 | 7 | const Header = styled("header")({ 8 | background: 'url("/images/banner.png") center center / cover no-repeat', 9 | }); 10 | 11 | function GrantsPage() { 12 | return ( 13 |
14 |
15 |

16 | Grants Program 17 |

18 |
19 | 26 | 27 |