├── .github └── ISSUE_TEMPLATE │ ├── bug.yml │ └── feature.yml ├── .gitignore ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── components │ ├── Button.jsx │ ├── Code.jsx │ ├── OpenUrl.jsx │ └── index.js ├── icons │ └── CopyIcon.jsx ├── next.config.js ├── package.json ├── pages │ ├── _app.js │ ├── foundry │ │ ├── file-structure.mdx │ │ ├── meta.json │ │ └── resources.mdx │ ├── get-started │ │ ├── deploy-contracts.mdx │ │ ├── environment.mdx │ │ ├── installing-packages.mdx │ │ ├── meta.json │ │ └── quick-start.mdx │ ├── hardhat │ │ ├── deploy-script.mdx │ │ ├── errors.mdx │ │ ├── file-structure.mdx │ │ ├── greeter.mdx │ │ ├── hardhat-config.mdx │ │ ├── local-network.mdx │ │ └── meta.json │ ├── index.mdx │ ├── meta.json │ ├── next-js │ │ ├── file-structure.mdx │ │ └── meta.json │ ├── thank-you.mdx │ └── vite │ │ ├── file-structure.mdx │ │ └── meta.json ├── postcss.config.js ├── public │ ├── deploy │ │ └── config-file.png │ └── errors │ │ ├── MM-nounce-1.png │ │ ├── MM-nounce-2.png │ │ └── MM-nounce-3.png ├── styles │ └── globals.css ├── tailwind.config.js └── theme.config.js ├── lerna.json ├── package.json └── packages └── create-web3 ├── .npmignore ├── .prettierrc ├── README.md ├── create-app.js ├── helpers ├── get-pkg-manager.js ├── git.js ├── install-hardhat.js ├── install-next.js ├── install.js ├── is-folder-empty.js ├── is-online.js ├── is-writeable.js ├── make-dir.js ├── should-use-yarn.js └── validate-pkg.js ├── index.js ├── package.json └── templates ├── common ├── README-template.md ├── env.example └── gitignore ├── css ├── chakra │ ├── next │ │ ├── default │ │ │ ├── package.json │ │ │ └── pages │ │ │ │ └── _app.js │ │ └── typescript │ │ │ ├── package.json │ │ │ └── pages │ │ │ └── _app.tsx │ └── vite │ │ ├── default │ │ ├── package.json │ │ └── src │ │ │ └── main.jsx │ │ └── typescript │ │ ├── package.json │ │ └── src │ │ └── main.tsx └── tailwind │ ├── next │ ├── default │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── styles │ │ │ └── globals.css │ │ └── tailwind.config.js │ └── typescript │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── styles │ │ └── globals.css │ │ └── tailwind.config.js │ └── vite │ ├── default │ ├── package.json │ ├── postcss.config.js │ ├── src │ │ └── index.css │ └── tailwind.config.js │ └── typescript │ ├── package.json │ ├── postcss.config.js │ ├── src │ └── index.css │ └── tailwind.config.js ├── foundry ├── .github │ └── workflows │ │ └── test.yml ├── foundry.toml ├── gitmodules ├── lib │ └── forge-std │ │ ├── .github │ │ └── workflows │ │ │ └── tests.yml │ │ ├── .gitignore │ │ ├── .gitmodules │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── README.md │ │ ├── lib │ │ └── ds-test │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── Makefile │ │ │ ├── default.nix │ │ │ ├── demo │ │ │ └── demo.sol │ │ │ └── src │ │ │ └── test.sol │ │ └── src │ │ ├── Script.sol │ │ ├── Test.sol │ │ ├── Vm.sol │ │ ├── console.sol │ │ ├── console2.sol │ │ └── test │ │ ├── StdAssertions.t.sol │ │ ├── StdCheats.t.sol │ │ ├── StdError.t.sol │ │ ├── StdMath.t.sol │ │ └── StdStorage.t.sol ├── package-template.json ├── package.json ├── script │ └── Greeter.s.sol ├── src │ └── Greeter.sol └── test │ └── Greeter.t.sol ├── hardhat ├── default │ ├── contracts │ │ └── Greeter.sol │ ├── deploy │ │ └── 00_deploy_contract.js │ ├── hardhat.config.js │ ├── package-template.json │ ├── package.json │ └── test │ │ └── sample-test.js └── typescript │ ├── contracts │ └── Greeter.sol │ ├── deploy │ └── 00_deploy_contract.ts │ ├── hardhat.config.ts │ ├── package-template.json │ ├── package.json │ ├── test │ └── index.ts │ └── tsconfig.json ├── next ├── default │ ├── .eslintrc.json │ ├── components │ │ └── contract │ │ │ ├── GetGreeter.js │ │ │ ├── SetGreeter.js │ │ │ └── index.js │ ├── config.js │ ├── contracts │ │ └── hardhat_contracts.json │ ├── hooks │ │ ├── index.js │ │ └── useIsMounted.js │ ├── next.config.js │ ├── package-template.json │ ├── package.json │ ├── pages │ │ ├── _app.js │ │ ├── api │ │ │ └── hello.js │ │ └── index.js │ ├── public │ │ └── favicon.ico │ └── styles │ │ └── globals.css └── typescript │ ├── .eslintrc.json │ ├── components │ └── contract │ │ ├── GetGreeter.tsx │ │ ├── SetGreeter.tsx │ │ └── index.ts │ ├── config.ts │ ├── contracts │ └── hardhat_contracts.json │ ├── hooks │ ├── index.ts │ └── useIsMounted.ts │ ├── next-env.d.ts │ ├── next.config.js │ ├── package-template.json │ ├── package.json │ ├── pages │ ├── _app.tsx │ ├── api │ │ └── hello.ts │ └── index.tsx │ ├── public │ └── favicon.ico │ ├── styles │ └── globals.css │ └── tsconfig.json └── vite ├── default ├── contracts │ └── hardhat_contracts.json ├── index.html ├── package-template.json ├── package.json ├── src │ ├── App.jsx │ ├── components │ │ ├── GetGreeter.jsx │ │ ├── SetGreeter.jsx │ │ └── index.js │ ├── config.js │ ├── favicon.svg │ ├── index.css │ └── main.jsx └── vite.config.js └── typescript ├── contracts └── hardhat_contracts.json ├── index.html ├── package-template.json ├── package.json ├── src ├── App.tsx ├── components │ ├── GetGreeter.tsx │ ├── SetGreeter.tsx │ └── index.ts ├── config.ts ├── favicon.svg ├── index.css ├── main.tsx └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: "Bug Report" 2 | description: "Found a bug, and want to report it" 3 | labels: ["bug"] 4 | body: 5 | - type: "markdown" 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this bug report! 9 | 10 | Make sure to search open/closed issues before submitting. 11 | - type: "textarea" 12 | id: "what-happened" 13 | attributes: 14 | label: "What happened?" 15 | description: "What happeaned and can you explain how to re-create it?" 16 | placeholder: "Tell us what you see!" 17 | validations: 18 | required: true 19 | - type: "textarea" 20 | id: "what-expected" 21 | attributes: 22 | label: "What was Expected?" 23 | description: "What did you expect to happen?" 24 | placeholder: "Tell us what you see!" 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: logs 29 | attributes: 30 | label: Relevant log output 31 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 32 | render: shell 33 | - type: "textarea" 34 | id: "proposed-solution" 35 | attributes: 36 | label: "Proposed Solution" 37 | description: | 38 | Please share if you know of a possible solution. 39 | - type: "textarea" 40 | id: "additional-information" 41 | attributes: 42 | label: "Additional Information" 43 | description: | 44 | What resources (links, screenshots, etc.) do you have to assist this 45 | effort? 46 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: "Feature Request" 2 | description: "Add suggestion for a feature" 3 | labels: ["enhancement"] 4 | body: 5 | - type: "markdown" 6 | attributes: 7 | value: | 8 | Thanks for creating an issue! 9 | 10 | Make sure to search open/closed issues before submitting. 11 | - type: "textarea" 12 | id: "description" 13 | attributes: 14 | label: "Description" 15 | description: "Please describe your idea in one or two sentences." 16 | validations: 17 | required: true 18 | - type: "textarea" 19 | id: "justification" 20 | attributes: 21 | label: "Why is this needed?" 22 | description: | 23 | Please explain why you believe this is needed. 24 | validations: 25 | required: true 26 | - type: "textarea" 27 | id: "proposed-solution" 28 | attributes: 29 | label: "Proposed Solution or API" 30 | description: | 31 | Please share what you believe the ideal design/API should be like. 32 | You can use code snippets, gists, or links to communicate it. 33 | validations: 34 | required: true 35 | - type: "textarea" 36 | id: "additional-information" 37 | attributes: 38 | label: "Additional Information" 39 | description: | 40 | What resources (links, screenshots, etc.) do you have to assist this 41 | effort? 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | package-lock.json 4 | .bin 5 | 6 | /node_modules 7 | /.idea 8 | *.tsbuildinfo 9 | 10 | .DS_Store 11 | 12 | 13 | # hardhat files 14 | cache/ 15 | artifacts/ 16 | deployments/ 17 | 18 | # Below is Github's node gitignore template, 19 | # ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing 20 | 21 | # Logs 22 | logs 23 | *.log 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | lerna-debug.log* 28 | 29 | # Diagnostic reports (https://nodejs.org/api/report.html) 30 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 31 | 32 | # Runtime data 33 | pids 34 | *.pid 35 | *.seed 36 | *.pid.lock 37 | 38 | # Directory for instrumented libs generated by jscoverage/JSCover 39 | lib-cov 40 | 41 | # Coverage directory used by tools like istanbul 42 | coverage 43 | 44 | # nyc test coverage 45 | .nyc_output 46 | 47 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 48 | .grunt 49 | 50 | # Bower dependency directory (https://bower.io/) 51 | bower_components 52 | 53 | # node-waf configuration 54 | .lock-wscript 55 | 56 | # Compiled binary addons (https://nodejs.org/api/addons.html) 57 | build/Release 58 | 59 | # Dependency directories 60 | #node_modules/ 61 | jspm_packages/ 62 | 63 | # TypeScript v1 declaration files 64 | typings/ 65 | 66 | # Optional npm cache directory 67 | .npm 68 | 69 | # Optional eslint cache 70 | .eslintcache 71 | 72 | # Optional REPL history 73 | .node_repl_history 74 | 75 | # Output of 'npm pack' 76 | *.tgz 77 | 78 | # Yarn Integrity file 79 | .yarn-integrity 80 | yarn.lock 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | 85 | # next.js build output 86 | .next 87 | 88 | # nuxt.js build output 89 | .nuxt 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | out/ 104 | 105 | .env -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "githubPullRequests.ignoredPullRequestBranches": ["main"] 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome! 4 | 5 | 1. Check the [ISSUES](). Read every issue to understand what's needed and whether it's something you can help with. 6 | 7 | 2. Ask other contributors to see if no one has taken the issue yet. If you're interested in tackling such a feature and it's still available, we will assign you to the task. 8 | 9 | 3. Clone the repo and create your own branch using `git checkout -b your_branch_name`. Remember to use a branch name that describes WHAT you're doing/fixing. 10 | 11 | 4. Setup your local development environment. Instructions 12 | 13 | 5. Once your work is done with the local copy of the repo, don't hesitate to open a pull request. We'll gladly revise and push as deemed fit. 14 | 15 | 6. Feel free to add new issues as you read the code and find inconsistencies and/or possible features that may add up to the website. Follow the labeling standards to make it easier to understand what you're proposing. 16 | 17 | 7. Document changes and/or issues clearly. Make it easy for everyone involved to understand your ideas/changes. 18 | 19 | ## Local development 20 | 21 | To setup your local dev environment: 22 | 23 | ```sh 24 | # Clone the repo 25 | 26 | cd create-web3 27 | 28 | # yarn install also runs `preconstruct dev`, which dynamically links all 29 | # packages in the monorepo together. 30 | yarn install 31 | 32 | # all development can be done from the root folder 33 | # to start a local hardhat chain, in one terminal 34 | yarn chain 35 | 36 | # in another terminal, deploy the contract locally with 37 | yarn deploy 38 | # then you can start developing with 39 | yarn dev 40 | 41 | ``` 42 | 43 | ## Creating a pull request 44 | 45 | In order to create a pull request for create-dao, follow the GitHub instructions for [Creating a pull request from a fork](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork). Please link your pull request to an existing issue. 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # create-web3 2 | 3 | A boilerplate for creating a web3 projects 4 | 5 |

6 | 7 | Version 8 | 9 | 10 | Downloads per month 11 | 12 | 13 | License 14 | 15 |

16 | 17 | This boilerplate quickly creates a mono repo with 2 environments, a react frontend environment and a Ethereum development environment for writing, testing and deploying contracts. 18 | 19 | ## Quick Start Notes 20 | 21 | 1. To start install 22 | 23 | ```bash 24 | npx create-web3 25 | ``` 26 | 27 | 2. Run `yarn` or `npm install` to install all the dependencies 28 | 3. Once installation is complete, `cd` into your app's directory and run `yarn chain` or `npm run chain` to start a local hardhat environment 29 | 4. Open another terminal and `cd` into your app's directory 30 | 5. Run `yarn deploy` or `npm run deploy` to deploy the example contract locally 31 | 6. Run `yarn dev` or `npm run dev` to start your Next dev environment 32 | 33 | ## Technologies 34 | 35 | This project is built with the following open source libraries, frameworks and languages. User choice of framework used, available in plain js or typescript. 36 | | Tech | Description | 37 | | --------------------------------------------- | ------------------------------------------------------------------ | 38 | | ------ | ------ React Frontend Environment ------ | 39 | | [Next JS](https://nextjs.org/) | React Framework | 40 | | [Vite JS](https://vitejs.dev/) | Next Generation Frontend Tooling | 41 | | ------ | ------ CSS Framework ------ | 42 | | none | | 43 | | [Tailwind](https://tailwindcss.com/) | A utility-first CSS framework | 44 | | [Chakra](https://chakra-ui.com/) | A simple, modular and accessible component library that gives you the building blocks you need to build your React applications. | 45 | | ------ | ------ Ethereum Development Environment ------ | 46 | | [Hardhat](https://hardhat.org/) | Ethereum development environment for professionals | 47 | | [Foundry](https://getfoundry.sh/) | a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. | 48 | | ------ | ------ Included Libraries ------ | 49 | | [WAGMI](https://wagmi.sh/) | A set of React Hooks for Web3 | 50 | | [RainbowKit](https://www.rainbowkit.com/docs/introduction) | RainbowKit is a React library that makes it easy to add wallet connection to your dapp. | 51 | 52 | ## Documentation 53 | 54 | Please visit [create-web3.xyz](https://create-web3.xyz) to view the full documentation. 55 | 56 | ## Discussions 57 | 58 | If you have questions how to use, want to suggest a feature, or show off a project you created with create-web3, join [discussions on GitHub](https://github.com/e-roy/create-web3/discussions). I would love to hear from you. 🙂 59 | 60 | ## Issues 61 | 62 | If you find a bug or would like to request a feature, please visit [ISSUES](https://github.com/e-roy/create-web3/issues) 63 | -------------------------------------------------------------------------------- /docs/components/Button.jsx: -------------------------------------------------------------------------------- 1 | export const Button = () => { 2 | return ; 3 | }; 4 | -------------------------------------------------------------------------------- /docs/components/Code.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import copy from "copy-to-clipboard"; 3 | import { CopyIcon } from "../icons/CopyIcon"; 4 | 5 | function classNames(...classes) { 6 | return classes.filter(Boolean).join(" "); 7 | } 8 | 9 | export const Code = ({ children, terminal = false }) => { 10 | const [terminalCommand, setTerminalCommand] = useState("npm run"); 11 | 12 | const handleCopy = () => { 13 | // console.log(children); 14 | if (terminal) { 15 | copy(terminalCommand + " " + children); 16 | } else { 17 | copy(children); 18 | } 19 | }; 20 | 21 | return ( 22 |
23 | {terminal && ( 24 |
25 | 36 | 47 |
48 | )} 49 |
50 |
51 | {terminal ? ( 52 | <> 53 | {terminalCommand} {children} 54 | 55 | ) : ( 56 | <>{children} 57 | )} 58 |
59 | 65 |
66 |
67 | ); 68 | }; 69 | -------------------------------------------------------------------------------- /docs/components/OpenUrl.jsx: -------------------------------------------------------------------------------- 1 | export const OpenUrl = ({ children, url = "" }) => { 2 | return ( 3 | 4 | {children} 5 | 6 | ); 7 | }; 8 | -------------------------------------------------------------------------------- /docs/components/index.js: -------------------------------------------------------------------------------- 1 | export { Button } from "./Button"; 2 | export { Code } from "./Code"; 3 | export { OpenUrl } from "./OpenUrl"; 4 | -------------------------------------------------------------------------------- /docs/icons/CopyIcon.jsx: -------------------------------------------------------------------------------- 1 | export const CopyIcon = () => { 2 | return ( 3 | 18 | 19 | 20 | 21 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /docs/next.config.js: -------------------------------------------------------------------------------- 1 | const withNextra = require("nextra")({ 2 | theme: "nextra-theme-docs", 3 | themeConfig: "./theme.config.js", 4 | unstable_staticImage: true, 5 | unstable_contentDump: true, 6 | unstable_flexsearch: true, 7 | unstable_staticImage: true, 8 | }); 9 | module.exports = withNextra(); 10 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3-docs/docs", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next", 8 | "start": "next start", 9 | "build": "next build" 10 | }, 11 | "keywords": [], 12 | "author": "Eric Roupe", 13 | "license": "MIT", 14 | "dependencies": { 15 | "copy-to-clipboard": "^3.3.1", 16 | "next": "^12.1.5", 17 | "next-themes": "0.2.0-beta.0", 18 | "nextra": "2.0.0-alpha.44", 19 | "nextra-theme-docs": "2.0.0-alpha.44", 20 | "react": "^18.1.0", 21 | "react-dom": "^18.1.0" 22 | }, 23 | "gitHead": "da4ed9ad6fa2d4386d4e35e60c221fda2bc5ccaa", 24 | "devDependencies": { 25 | "@heroicons/react": "^1.0.6", 26 | "autoprefixer": "^10.4.5", 27 | "postcss": "^8.4.12", 28 | "tailwindcss": "^3.0.24" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/pages/_app.js: -------------------------------------------------------------------------------- 1 | import "../styles/globals.css"; 2 | import "nextra-theme-docs/style.css"; 3 | 4 | function App({ Component, pageProps }) { 5 | const getLayout = Component.getLayout || ((page) => page); 6 | 7 | return <>{getLayout()}; 8 | } 9 | 10 | export default App; 11 | -------------------------------------------------------------------------------- /docs/pages/foundry/file-structure.mdx: -------------------------------------------------------------------------------- 1 | # File Structure - Foundry 2 | 3 | ```jsx 4 | ├── backend 5 | │ ├── .github 6 | │ │ └── workflows 7 | │ │ └── test.yml 8 | │ ├── lib 9 | │ │ └── forge-std 10 | │ │ └── ... 11 | │ ├── script 12 | │ │ └── Greeter.s.sol 13 | │ ├── src 14 | │ │ └── Greeter.sol 15 | │ ├── test 16 | │ │ └── Greeter.t.sol 17 | │ ├── foundry.toml 18 | │ ├── gitmodules 19 | │ └── package.json 20 | │ 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/pages/foundry/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-structure": "File Structure", 3 | "resources": "Resources" 4 | } 5 | -------------------------------------------------------------------------------- /docs/pages/foundry/resources.mdx: -------------------------------------------------------------------------------- 1 | import { OpenUrl } from "../../components/OpenUrl"; 2 | 3 | # Foundry Resources 4 | 5 | Foundry 6 | 7 | 8 | Foundry Cheatsheet 9 | 10 | 11 | 12 | Awesome Foundry 13 | 14 | -------------------------------------------------------------------------------- /docs/pages/get-started/deploy-contracts.mdx: -------------------------------------------------------------------------------- 1 | import { Code } from "../../components"; 2 | import Bleed from "nextra-theme-docs/bleed"; 3 | import Callout from "nextra-theme-docs/callout"; 4 | 5 | # Deploying Contracts 6 | 7 | To deploy to your local hardhat environment, first start your local environment by running 8 | 9 | chain 10 | 11 | and then in another terminal run 12 | 13 | deploy 14 | 15 | After every deployment, a copy of the deployment (contract address and abi) is copied to the hardhat_contracts.json file in the next-app/contracts folder 16 | 17 | When you deploy to the hardhat network, Account #0 is the owner of the contract. 18 | 19 | 20 | All 20 of the hardhat accounts created in your local hardhat environment are 21 | the same private and public keys for everyone. DO NOT send anything valueable 22 | to these accounts. 23 | 24 | 25 | To deploy to another network, go to your hardhat.config.js file in the hardhat folder. Uncomment the network you'd like to deploy to. 26 | 27 | Be sure to add your environment varables and only uncomment the node provider you'd like to use (ie. Alchemy or Infrua) 28 | 29 | and run: 30 | 31 | deploy --network (network name) 32 | 33 | For example to deploy to the Mumbai testnet run: 34 | 35 | deploy --network mumbai 36 | 37 | Once you deploy to a network other than hardhat, go into your config.js file inside the next-app folder and change the NETWORK_ID and NETWORK_NAME to the network your Next App will interact with. 38 | 39 | 40 |
41 | ![Config File](../../public/deploy/config-file.png){" "} 42 |
43 |
44 | 45 | Now you will be able to test your deployed contract locally or when you deploy your Next App 46 | -------------------------------------------------------------------------------- /docs/pages/get-started/environment.mdx: -------------------------------------------------------------------------------- 1 | import { OpenUrl, Code } from "../../components"; 2 | 3 | # Environment Varables 4 | 5 | In the root of the next-app folder there is a .env.example file 6 | 7 | Copy this file and create a .env 8 | 9 | ### If using Next JS for frontend, you will need 10 | 11 | ```jsx 12 | NEXT_PUBLIC_ALCHEMY_ID= 13 | NEXT_PUBLIC_INFURA_ID= 14 | ``` 15 | 16 | ### If using Vite JS for frontend, you will need 17 | 18 | ```jsx 19 | VITE_ALCHEMY_ID= 20 | VITE_INFURA_ID= 21 | ``` 22 | 23 | ### For hardhat you will need 24 | 25 | ```jsx 26 | PRIVATE_KEY= 27 | ETHERSCAN_API_KEY= 28 | ``` 29 | 30 | Your Private Key can be gotten from your Metamask Wallet 31 | 32 | import Callout from "nextra-theme-docs/callout"; 33 | 34 | 35 | Do not share your Private Key with anyone, and be sure not to commit to GitHub 36 | or any other git repo. Your Private Key is the permission to use your Public 37 | Key Address and everything connected to it. 38 | 39 | 40 | - To get a Alchemy API Key 41 | 42 | - To get a Infura API Key 43 | -------------------------------------------------------------------------------- /docs/pages/get-started/installing-packages.mdx: -------------------------------------------------------------------------------- 1 | import { Code } from "../../components"; 2 | 3 | # Installing Packages 4 | 5 | When adding packages, you will need to point to the correct workspace 6 | 7 | ### YARN 8 | 9 | to add packages to the Frontend Environment dependencies 10 | 11 | yarn workspace @create-web3/frontend add (package-name) 12 | 13 | to add packages to the hardhat Environment dependencies 14 | 15 | yarn workspace @create-web3/backend add (package-name) 16 | -------------------------------------------------------------------------------- /docs/pages/get-started/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "quick-start": "Quick Start", 3 | "environment": "Environment Variables", 4 | "installing-packages": "Installing Packages", 5 | "deploy-contracts": "Deploying Contracts" 6 | } 7 | -------------------------------------------------------------------------------- /docs/pages/get-started/quick-start.mdx: -------------------------------------------------------------------------------- 1 | import { Code } from "../../components"; 2 | 3 | # Quick Start 4 | 5 | First start by opening your terminal and typing : 6 | 7 | npx create-web3 8 | 9 | 1. Name your project. 10 | 11 | 2. Choose install by using NPM or YARN 12 | 13 | 3. Choose project create with Javascript or Typescript 14 | 15 | When finished now install packages 16 | 17 | install 18 | 19 | Once packages are installed `cd` into the directory of your project 20 | 21 | To start your local hardhat environment: 22 | 23 | chain 24 | 25 | Now open another terminal, `cd` into the directory of your project, and deploy the Greetor.sol contract 26 | 27 | deploy 28 | 29 | Now in the same terminal start your Front End: 30 | 31 | dev 32 | 33 | import Callout from "nextra-theme-docs/callout"; 34 | 35 | 36 | Now open your browser and go to [localhost:3000](http://localhost:3000). 37 | 38 | 39 | ### Congratulations!!! 40 | 41 | ### You've just setup your local development environment and deployed a contract locally 42 | 43 | You can now connect a wallet and interact with the Greeter contract by typing in a new message. 44 | -------------------------------------------------------------------------------- /docs/pages/hardhat/deploy-script.mdx: -------------------------------------------------------------------------------- 1 | # Deploy Script 2 | 3 | Inside the hardhat/deploy folder are where deploy scripts are run from. As you see, there is a script called `00_deploy_contract.js` 4 | 5 | ```jsx 6 | module.exports = async ({ getNamedAccounts, deployments }) => { 7 | const { deploy } = deployments; 8 | const { deployer } = await getNamedAccounts(); 9 | 10 | const args = ["Hello!!!!!!!!"]; 11 | 12 | await deploy("Greeter", { 13 | // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy 14 | args: args, 15 | from: deployer, 16 | log: true, 17 | }); 18 | }; 19 | module.exports.tags = ["all", "greeter"]; 20 | ``` 21 | 22 | The const deployer is targeting the `hardhat.config.js` and looking at the deployer in the namedAccounts 23 | 24 | ```jsx 25 | namedAccounts: { 26 | deployer: { 27 | default: 0, // here this will by default take the first account as deployer 28 | }, 29 | tokenOwner: 1, 30 | }, 31 | ``` 32 | 33 | deployer.default is set to 0 meaning the Account #0 in your local hardhat network when you run `chain` 34 | 35 | The args array passes arguments into the the Greeter.sol contract's constructor. 36 | 37 | ```jsx 38 | constructor(string memory _greeting) { 39 | greeting = _greeting; 40 | } 41 | ``` 42 | 43 | This constructor takes a single string arugment. Passing ["Hello!!!!!!!!"], sets the 44 | 45 | ```jsx 46 | string private greeting; 47 | ``` 48 | 49 | to "Hello!!!!!!!!" 50 | 51 | To deploy another contract, create another file incrementing the filename ie `01_deploy_another_contract` 52 | 53 | For deploying contracts, tags help target contracts you'd like to deploy. So in the `00_deploy_contract.js` file: 54 | 55 | ```jsx 56 | module.exports.tags = ["all", "greeter"]; 57 | ``` 58 | 59 | The 'all' tag will call this script for when using `yarn deploy`. 60 | 61 | To target just this contract to deploy, use the flag greeter `yarn deploy --tags greeter` 62 | 63 | When you run the deploy script, each deploy script will run async from lowest number to highest. This gives the advantage to deploy multiple contracts and using a previous deployed contact's address in a script to pass into another contract. 64 | 65 | So in this example if you wanted to get the contract address from the Greeter contract you could use 66 | 67 | ```jsx 68 | const greeterAddress = await deployments.get("Greeter"); 69 | ``` 70 | 71 | To get the contract data. 72 | 73 | And then pass greeterAddress.address into the args like so 74 | 75 | ```jsx 76 | module.exports = async ({ getNamedAccounts, deployments }) => { 77 | const { deploy } = deployments; 78 | const { deployer } = await getNamedAccounts(); 79 | 80 | const greeterAddress = await deployments.get("Greeter"); 81 | 82 | const args = [greeterAddress.address]; 83 | 84 | await deploy("Another", { 85 | // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy 86 | args: args, 87 | from: deployer, 88 | log: true, 89 | }); 90 | }; 91 | module.exports.tags = ["all", "another"]; 92 | ``` 93 | 94 | You can also create an instance of the previous contract to get the address with ethers. 95 | 96 | ```jsx 97 | module.exports = async ({ getNamedAccounts, deployments }) => { 98 | const { deploy } = deployments; 99 | const { deployer } = await getNamedAccounts(); 100 | 101 | const greeter = await ethers.getContract("Greeter"); 102 | 103 | const args = [greeter.address]; 104 | 105 | await deploy("Another", { 106 | // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy 107 | args: args, 108 | from: deployer, 109 | log: true, 110 | }); 111 | }; 112 | module.exports.tags = ["all", "another"]; 113 | ``` 114 | -------------------------------------------------------------------------------- /docs/pages/hardhat/errors.mdx: -------------------------------------------------------------------------------- 1 | import Bleed from "nextra-theme-docs/bleed"; 2 | 3 | # Common Errors 4 | 5 | Every once in a while when working on the your local hardhat chain, a 'Nonce too high' error will occur 6 | 7 | 8 |
9 | ![Nonce Error 1](../../public/errors/MM-nounce-1.png) 10 |
11 |
12 | 13 | 14 |
15 | ![Nonce Error 2](../../public/errors/MM-nounce-2.png) 16 |
17 |
18 | 19 | The only way I've found so far to get around this error is to go into settings -> Advanced, and Reset Account. 20 | 21 | 22 |
23 | ![Nonce Error 3](../../public/errors/MM-nounce-3.png) 24 |
25 |
26 | -------------------------------------------------------------------------------- /docs/pages/hardhat/file-structure.mdx: -------------------------------------------------------------------------------- 1 | # File Structure - Hardhat 2 | 3 | ```jsx 4 | ├── backend 5 | │ ├── artifacts 6 | │ │ └── ... 7 | │ ├── cache 8 | │ │ └── ... 9 | │ ├── contracts 10 | │ │ └── Greeter.sol 11 | │ ├── deploy 12 | │ │ └── 00_deploy_contract.js 13 | │ ├── deployments 14 | │ │ └── ... 15 | │ ├── node_modules 16 | │ │ └── ... 17 | │ ├── test 18 | │ │ └── sample-test.js 19 | │ ├── hardhat.config.js 20 | │ └── package.json 21 | │ 22 | │ 23 | ``` 24 | 25 | ### Contracts folder 26 | 27 | Store solidity contracts here. 28 | 29 | ### Deploy folder 30 | 31 | The deploy folder is expected to contains the deploy script that are executed upon invocation of hardhat deploy or hardhat node. 32 | 33 | Each file is run async depending on it's name. So using a naming convention like: 34 | 35 | ```jsx 36 | 00_deploy_greeter.js; 37 | 01_deploy_basic_nft.js; 38 | 02_deploy_dynamic_svg_nft.js; 39 | 03_deploy_random_ipfs_nft.js; 40 | 04_mint.js; 41 | ``` 42 | 43 | will run each file in this order. 44 | 45 | ### Deployments folder 46 | 47 | The deployments folder will contain the resulting deployments (contract addresses along their abi, bytecode, metadata...). One folder per network and one file per contract. 48 | -------------------------------------------------------------------------------- /docs/pages/hardhat/greeter.mdx: -------------------------------------------------------------------------------- 1 | # Greeter Contract 2 | 3 | This is the starter contract that hardhat creates on initaiting a new project 4 | 5 | ```jsx 6 | //SPDX-License-Identifier: Unlicense 7 | pragma solidity ^0.8.7; 8 | 9 | import "hardhat/console.sol"; 10 | 11 | contract Greeter { 12 | string private greeting; 13 | 14 | constructor(string memory _greeting) { 15 | console.log("Greeter with greeting:", _greeting); 16 | greeting = _greeting; 17 | } 18 | 19 | function greet() public view returns (string memory) { 20 | return greeting; 21 | } 22 | 23 | function setGreeting(string memory _greeting) public { 24 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 25 | greeting = _greeting; 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/pages/hardhat/hardhat-config.mdx: -------------------------------------------------------------------------------- 1 | # hardhat-config 2 | 3 | ## Setting Solidity Versions 4 | 5 | create-web3 ships with configuration for `solidity version 0.8.10` 6 | 7 | ```jsx 8 | module.exports = { 9 | solidity: '0.8.10', 10 | 11 | ... 12 | } 13 | ``` 14 | 15 | If your contract requires another version of solidity, you will need to make a change to your hardhat.config file. 16 | You can simply change versions here. 17 | 18 | If you have contracts that require multiple versions of solidity to compile, change solidity to an object to add and array of compiler versions 19 | 20 | ```jsx 21 | module.exports = { 22 | // solidity: "0.8.10", 23 | solidity: { 24 | compilers: [ 25 | { 26 | version: "0.8.10", 27 | }, 28 | { 29 | version: "0.6.0", 30 | }, 31 | ], 32 | }, 33 | 34 | ... 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/pages/hardhat/local-network.mdx: -------------------------------------------------------------------------------- 1 | # Setting up Local Network for Hardhat 2 | 3 | Open your metamask extension and go to settings 4 | 5 | Select Networks 6 | 7 | Click on the 'Add a network' button 8 | 9 | Network Name : `Hardhat` 10 | 11 | New RPC URL : `http://127.0.0.1:8545` 12 | 13 | Chain ID : `31337` 14 | 15 | Then click the 'Save' button 16 | -------------------------------------------------------------------------------- /docs/pages/hardhat/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-structure": "File Structure", 3 | "local-network": "Local Network", 4 | "hardhat-config": "hardhat-config file", 5 | "greeter": "Greeter Contract", 6 | "deploy-script": "Deploy Scripts", 7 | "errors": "Common Errors" 8 | } 9 | -------------------------------------------------------------------------------- /docs/pages/index.mdx: -------------------------------------------------------------------------------- 1 | import { OpenUrl, Code } from "../components"; 2 | 3 | # Create Web3 4 | 5 | ### Welcome 😃 6 | 7 | 🧱 & 🚀 more 8 | 9 | Setting up a project takes a lot of time, so I created `create-web3` to help others quickly get a starting point to either test an idea or build their dapp. 10 | 11 | I hope this helps you get up and going quickly and so you can focus on creating something great! 😃 12 | 13 | Get started by running in your terminal 14 | 15 | npx create-web3 16 | 17 | This guide is a work in progress 18 | 19 | ### Version 20 | 21 | Current Version [![Version](https://img.shields.io/npm/v/create-web3)](https://www.npmjs.com/package/create-web3) 22 | 23 | When using `npx create-web3` you are saving this package locally on your machine. To check the current version on your machine 24 | 25 | npx create-web3 --version 26 | 27 | To install the latest version 28 | 29 | npm install --global create-web3 30 | 31 | ### Overview 32 | 33 | This project was created as a quick start boilerplate for developing web3 apps and deploying smart contracts. 34 | 35 | The bolierplate sets up a monorepo that keeps the front-end environment and the contract environment seperate from each other. 36 | The advantage to setting up in this way, is that packages and libraries are kept seperate, and reduces clutter when developing. 37 | 38 | The goal of this boilerplate is to give you the options of frameworks and quickly set up a lean starting point to test or build an idea. 39 | 40 | ### Technologies 41 | 42 | This project is built with the following open source libraries, frameworks and languages. User choice of framework used, available in plain js or typescript. 43 | | Tech | Description | 44 | | --------------------------------------------- | ------------------------------------------------------------------ | 45 | | ------ | ------ React Frontend Environment ------ | 46 | | Next JS | React Framework | 47 | | Vite JS | Next Generation Frontend Tooling | 48 | | ------ | ------ CSS Framework ------ | 49 | | none | | 50 | | Tailwind | A utility-first CSS framework | 51 | | Chakra | A simple, modular and accessible component library that gives you the building blocks you need to build your React applications. | 52 | | ------ | ------ Ethereum Development Environment ------ | 53 | | Hardhat | Ethereum development environment for professionals | 54 | | Foundry | a blazing fast, portable and modular toolkit for Ethereum application development written in Rust | 55 | | ------ | ------ Included Libraries ------ | 56 | | WAGMI | A set of React Hooks for Web3 | 57 | | RainbowKit | RainbowKit is a React library that makes it easy to add wallet connection to your dapp. | 58 | 59 | ### Issues 60 | 61 | If you find a bug, an error in the docs, or have a suggestion, please go to [ISSUES](https://github.com/e-roy/create-web3/issues) and open a new issue. 62 | 63 | ### Discussions 64 | 65 | If you have questions how to use, want to suggest a feature, or show off a project you created with create-web3, join [discussions on GitHub](https://github.com/e-roy/create-web3/discussions). I would love to hear from you. 🙂 66 | -------------------------------------------------------------------------------- /docs/pages/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": "Introduction", 3 | "get-started": "Get Started", 4 | "hardhat": "Hardhat", 5 | "foundry": "Foundry", 6 | "next-js": "Next.js", 7 | "vite": "Vite", 8 | "thank-you": "Thank You" 9 | } 10 | -------------------------------------------------------------------------------- /docs/pages/next-js/file-structure.mdx: -------------------------------------------------------------------------------- 1 | # File Structure - Next JS 2 | 3 | ```jsx 4 | ├── frontend 5 | │ ├── .next 6 | │ │ └── ... 7 | │ ├── components 8 | │ │ └── contract 9 | │ │ ├── GetGreeter.js 10 | │ │ └── SetGreeter.js 11 | │ ├── contracts 12 | │ │ └── hardhat_contracts.json 13 | │ ├── hooks 14 | │ │ ├── index.js 15 | │ │ └── useIsMounted.js 16 | │ ├── node_modules 17 | │ │ └── ... 18 | │ ├── pages 19 | │ │ ├── api 20 | │ │ │ └── hello.js 21 | │ │ ├── _app.js 22 | │ │ └── index.js 23 | │ ├── public 24 | │ │ └── favicon.ico 25 | │ ├── styles 26 | │ │ ├── globals.css 27 | │ │ └── Home.module.css 28 | │ ├── .eslintrc.json 29 | │ ├── config.json 30 | │ ├── next.config.js 31 | │ └── package.json 32 | │ 33 | │ 34 | ``` 35 | 36 | ### Components folder 37 | 38 | ### Contracts folder 39 | 40 | After deploying your contract(s), a file called hardhat_contracts.json is created with a copy of each contract's address and abi to use in your dapp. 41 | 42 | An example how to import this file to use in a component: 43 | 44 | ```jsx 45 | // import the json file 46 | import contracts from "../../contracts/hardhat_contracts.json"; 47 | // get the network id the next app is currently using 48 | import { NETWORK_ID } from "../../config"; 49 | 50 | // get the contract's address 51 | const contractAddress = contracts[NETWORK_ID][0].contracts..address; 52 | // get the contract's abi 53 | const contractrABI = contracts[NETWORK_ID][0].contracts..abi; 54 | ``` 55 | 56 | ### Hooks folder 57 | -------------------------------------------------------------------------------- /docs/pages/next-js/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-structure": "File Structure" 3 | } 4 | -------------------------------------------------------------------------------- /docs/pages/thank-you.mdx: -------------------------------------------------------------------------------- 1 | import { OpenUrl } from "../components/OpenUrl"; 2 | 3 | # Thank You 4 | 5 | The goal of this project together to get a better understanding for creating, deploying and working with contracts in connection to a Front End. 6 | 7 | The focus was to create a quick, lightweight starting point to test an idea or create an dapp without spending a lot of time on setup. 8 | 9 | I wanted to give thanks to those that helped inspire me to understand and create this project, and also to those that put content out there to help others in their journey. 10 | 11 | | | | 12 | | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- | 13 | | scaffold-eth | This project was inspired mostly from | 14 | | Speed Run Ethereum | Same people, another great resource for learning | 15 | | Developer DAO | Awesome group of people creating cool things | 16 | | LearnWeb3DAO | A Community of Developers learning web3 and a great web3 education course | 17 | | Buildspace.so | Build Web3 projects with other Developers | 18 | | WAGMI | A set of React Hooks for Web3 | 19 | | RainbowKit | The best way to connect a wallet | 20 | | Dhaiwat Pandya | An awesome dude that builds stuff | 21 | -------------------------------------------------------------------------------- /docs/pages/vite/file-structure.mdx: -------------------------------------------------------------------------------- 1 | # File Structure - Vite JS 2 | 3 | ```jsx 4 | ├── frontend 5 | │ ├── contracts 6 | │ │ └── hardhat_contracts.json 7 | │ ├── node_modules 8 | │ │ └── ... 9 | │ ├── src 10 | │ │ ├── components 11 | │ │ | ├── GetGreeter.jsx 12 | │ │ | ├── index.js 13 | │ │ │ └── SetGreeter.jsx 14 | │ │ ├── App.css 15 | │ │ ├── App.jsx 16 | │ │ ├── config.js 17 | │ │ ├── favicon.svg 18 | │ │ ├── index.css 19 | │ │ └── main.jsx 20 | │ ├── index.html 21 | │ ├── package.json 22 | │ └── vite.config.js 23 | │ 24 | │ 25 | ``` 26 | 27 | ### Components folder 28 | 29 | ### Contracts folder 30 | 31 | After deploying your contract(s), a file called hardhat_contracts.json is created with a copy of each contract's address and abi to use in your dapp. 32 | 33 | An example how to import this file to use in a component: 34 | 35 | ```jsx 36 | // import the json file 37 | import contracts from "../../contracts/hardhat_contracts.json"; 38 | // get the network id the next app is currently using 39 | import { NETWORK_ID } from "../../config"; 40 | 41 | // get the contract's address 42 | const contractAddress = contracts[NETWORK_ID][0].contracts..address; 43 | // get the contract's abi 44 | const contractrABI = contracts[NETWORK_ID][0].contracts..abi; 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/pages/vite/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-structure": "File Structure" 3 | } 4 | -------------------------------------------------------------------------------- /docs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /docs/public/deploy/config-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/docs/public/deploy/config-file.png -------------------------------------------------------------------------------- /docs/public/errors/MM-nounce-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/docs/public/errors/MM-nounce-1.png -------------------------------------------------------------------------------- /docs/public/errors/MM-nounce-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/docs/public/errors/MM-nounce-2.png -------------------------------------------------------------------------------- /docs/public/errors/MM-nounce-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/docs/public/errors/MM-nounce-3.png -------------------------------------------------------------------------------- /docs/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind utilities; 2 | 3 | html { 4 | font-feature-settings: "rlig" 1, "calt" 1, "ss01" 1, "ss06" 1 !important; 5 | } 6 | 7 | [data-reach-skip-link] { 8 | @apply sr-only; 9 | } 10 | 11 | [data-reach-skip-link]:focus { 12 | @apply not-sr-only fixed ml-6 top-0 bg-white text-lg px-6 py-2 mt-2 outline-none focus:ring z-50; 13 | } 14 | 15 | .dark .invert-on-dark { 16 | filter: invert(1) brightness(1.8); 17 | } 18 | 19 | .dark body { 20 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #111 300px), 21 | fixed 0 0 / 20px 20px radial-gradient(#313131 1px, transparent 0), 22 | fixed 10px 10px / 20px 20px radial-gradient(#313131 1px, transparent 0); 23 | } 24 | 25 | .callout a { 26 | color: inherit; 27 | } 28 | 29 | sup a { 30 | @apply text-current; 31 | text-decoration: none; 32 | } 33 | 34 | .footnotes { 35 | @apply text-sm; 36 | } 37 | -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | darkMode: "class", 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx,md,mdx}", 5 | "./components/**/*.{js,ts,jsx,tsx,md,mdx}", 6 | "./theme.config.js", 7 | ], 8 | }; 9 | -------------------------------------------------------------------------------- /docs/theme.config.js: -------------------------------------------------------------------------------- 1 | // import { useTheme } from "next-themes"; 2 | 3 | const github = "https://github.com/e-roy/create-web3"; 4 | 5 | export default { 6 | github, 7 | projectLink: github, 8 | titleSuffix: " – Create Web3", 9 | logo: ( 10 | <> 11 | Create-Web3 12 | 13 | A boilerplate for web3 projects 14 | 15 | 16 | ), 17 | head: ({ meta, title }) => { 18 | const description = 19 | meta.description || 20 | "create-web3 is a boilplate for creating and deploying dapps and smart contracts. non opinionated, user choice of frameworks, and quick to setup."; 21 | const title_ = 22 | title && !title.startsWith("create-web3") 23 | ? title + " – create-web3" 24 | : "create-web3: A boilerplate to quickly create a new web3 project."; 25 | 26 | return ( 27 | <> 28 | {/* General */} 29 | 30 | 31 | {title_} 32 | 33 | {/* SEO */} 34 | 35 | 36 | 37 | {/* */} 38 | 39 | 40 | 41 | 42 | 43 | 44 | ); 45 | }, 46 | search: true, 47 | prevLinks: true, 48 | nextLinks: true, 49 | nextThemes: { 50 | defaultTheme: "dark", 51 | }, 52 | footer: true, 53 | footerEditLink: "", 54 | footerText: <>MIT {new Date().getFullYear()} © Eric Roupe, 55 | unstable_faviconGlyph: "🧱", 56 | unstable_flexsearch: true, 57 | }; 58 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "packages": [ 5 | "packages/*" 6 | ], 7 | "command": { 8 | "version": { 9 | "exact": true 10 | }, 11 | "publish": { 12 | "npmClient": "npm", 13 | "allowBranch": [ 14 | "main" 15 | ], 16 | "registry": "https://registry.npmjs.org/" 17 | } 18 | }, 19 | "version": "0.4.10" 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-web3", 3 | "version": "0.0.0", 4 | "private": true, 5 | "keywords": [ 6 | "create-web3", 7 | "web3", 8 | "boilerplate", 9 | "nextjs", 10 | "vite", 11 | "react", 12 | "wagmi", 13 | "hardhat", 14 | "foundry" 15 | ], 16 | "scripts": { 17 | "dev": "yarn workspace @create-web3/next dev", 18 | "build": "yarn workspace @create-web3/next build", 19 | "start": "yarn workspace @create-web3/next start", 20 | "lint": "yarn workspace @create-web3/next lint", 21 | "dev:ts": "yarn workspace @create-web3/next-ts dev", 22 | "build:ts": "yarn workspace @create-web3/next-ts build", 23 | "start:ts": "yarn workspace @create-web3/next-ts start", 24 | "lint:ts": "yarn workspace @create-web3/next-ts lint", 25 | "dev:vite": "yarn workspace @create-web3/vite dev", 26 | "build:vite": "yarn workspace @create-web3/vite build", 27 | "preview:vite": "yarn workspace @create-web3/vite preview", 28 | "dev:vite:ts": "yarn workspace @create-web3/vite-ts dev", 29 | "build:vite:ts": "yarn workspace @create-web3/vite-ts build", 30 | "preview:vite:ts": "yarn workspace @create-web3/vite-ts preview", 31 | "chain": "yarn workspace @create-web3/hardhat chain", 32 | "clean": "yarn workspace @create-web3/hardhat clean", 33 | "deploy": "yarn workspace @create-web3/hardhat deploy", 34 | "test": "yarn workspace @create-web3/hardhat test", 35 | "deploy:rinkeby": "yarn workspace @create-web3/hardhat deploy:rinkeby", 36 | "deploy:mainnet": "yarn workspace @create-web3/hardhat deploy:mainnet", 37 | "chain:ts": "yarn workspace @create-web3/hardhat-ts chain", 38 | "clean:ts": "yarn workspace @create-web3/hardhat-ts clean", 39 | "deploy:ts": "yarn workspace @create-web3/hardhat-ts deploy", 40 | "test:ts": "yarn workspace @create-web3/hardhat-ts test", 41 | "chain:foundry": "yarn workspace @create-web3/foundry chain", 42 | "compile:foundry": "yarn workspace @create-web3/foundry compile", 43 | "test:foundry": "yarn workspace @create-web3/foundry test", 44 | "clean:foundry": "yarn workspace @create-web3/foundry clean", 45 | "update-version": "lerna version --force-publish --no-private", 46 | "publish-latest": "lerna publish from-package", 47 | "create-web3": "node ./packages/create-web3/index.js", 48 | "dev:docs": "yarn workspace @create-web3-docs/docs dev" 49 | }, 50 | "devDependencies": { 51 | "lerna": "^4.0.0" 52 | }, 53 | "workspaces": [ 54 | "packages/*", 55 | "packages/create-web3/*", 56 | "packages/create-web3/templates/foundry/*", 57 | "packages/create-web3/templates/hardhat/*", 58 | "packages/create-web3/templates/next/*", 59 | "packages/create-web3/templates/vite/*", 60 | "docs/" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /packages/create-web3/.npmignore: -------------------------------------------------------------------------------- 1 | template/src/artifacts/* 2 | template/.next 3 | template/cache 4 | *.tgz 5 | 6 | node_modules 7 | .next 8 | 9 | .prettierrc 10 | 11 | artifacts 12 | deployments 13 | cache 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/create-web3/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "tab": 2 5 | } 6 | -------------------------------------------------------------------------------- /packages/create-web3/README.md: -------------------------------------------------------------------------------- 1 | # create-web3 2 | 3 | A boilerplate for creating a web3 projects 4 | 5 | This boilerplate quickly creates a mono repo with 2 environments, a react frontend environment and a Ethereum development environment for writing, testing and deploying contracts. 6 | 7 |

8 | 9 | Version 10 | 11 | 12 | Downloads per month 13 | 14 | 15 | License 16 | 17 |

18 | 19 | ## Quick Start Notes 20 | 21 | 1. To start install 22 | 23 | ```bash 24 | npx create-web3 25 | ``` 26 | 27 | 2. Run `yarn` or `npm install` to install all the dependencies 28 | 3. Once installation is complete, `cd` into your app's directory and run `yarn chain` or `npm run chain` to start a local hardhat environment 29 | 4. Open another terminal and `cd` into your app's directory 30 | 5. Run `yarn deploy` or `npm run deploy` to deploy the example contract locally 31 | 6. Run `yarn dev` or `npm run dev` to start your Next dev environment 32 | 33 | ## Technologies 34 | 35 | This project is built with the following open source libraries, frameworks and languages. User choice of framework used, available in plain js or typescript. 36 | | Tech | Description | 37 | | --------------------------------------------- | ------------------------------------------------------------------ | 38 | | ------ | ------ React Frontend Environment ------ | 39 | | [Next JS](https://nextjs.org/) | React Framework | 40 | | [Vite JS](https://vitejs.dev/) | Next Generation Frontend Tooling | 41 | | ------ | ------ CSS Framework ------ | 42 | | none | | 43 | | [Tailwind](https://tailwindcss.com/) | A utility-first CSS framework | 44 | | [Chakra](https://chakra-ui.com/) | A simple, modular and accessible component library that gives you the building blocks you need to build your React applications. | 45 | | ------ | ------ Ethereum Development Environment ------ | 46 | | [Hardhat](https://hardhat.org/) | Ethereum development environment for professionals | 47 | | [Foundry](https://getfoundry.sh/) | a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. | 48 | | ------ | ------ Included Libraries ------ | 49 | | [WAGMI](https://wagmi.sh/) | A set of React Hooks for Web3 | 50 | | [RainbowKit](https://www.rainbowkit.com/docs/introduction) | RainbowKit is a React library that makes it easy to add wallet connection to your dapp. | 51 | 52 | ## Documentation 53 | 54 | Please visit [create-web3.xyz](https://create-web3.xyz) to view the full documentation. 55 | 56 | ## Discussions 57 | 58 | If you have questions how to use, want to suggest a feature, or show off a project you created with create-web3, join [discussions on GitHub](https://github.com/e-roy/create-web3/discussions). I would love to hear from you. 🙂 59 | 60 | ## Issues 61 | 62 | If you find a bug or would like to request a feature, please visit [ISSUES](https://github.com/e-roy/create-web3/issues) 63 | -------------------------------------------------------------------------------- /packages/create-web3/create-app.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const chalk = require('chalk'); 3 | const fs = require('fs'); 4 | const os = require('os'); 5 | const cpy = require('cpy'); 6 | const checkWriteable = require('./helpers/is-writeable'); 7 | const makeDir = require('./helpers/make-dir'); 8 | const checkFolder = require('./helpers/is-folder-empty'); 9 | // const checkYarn = require('./helpers/should-use-yarn'); 10 | // const checkOnline = require('./helpers/is-online'); 11 | const gitInit = require('./helpers/git'); 12 | 13 | // const installNext = require('./helpers/install-next'); 14 | // const installHardhat = require('./helpers/install-hardhat'); 15 | 16 | const init = async ({ 17 | appPath, 18 | useNpm, 19 | typescript, 20 | frontend, 21 | backend, 22 | css, 23 | }) => { 24 | console.log('running create-web3'); 25 | // console.log(`appPath: ${appPath}`); 26 | // console.log(`useNpm: ${useNpm}`); 27 | // console.log(typescript); 28 | const template = typescript ? 'typescript' : 'default'; 29 | const root = path.resolve(appPath); 30 | // console.log('template: ', template); 31 | 32 | if (!(await checkWriteable.isWriteable(path.dirname(root)))) { 33 | console.error( 34 | 'The application path is not writable, please check folder permissions and try again.' 35 | ); 36 | console.error( 37 | 'It is likely you do not have write permissions for this folder.' 38 | ); 39 | process.exit(1); 40 | } 41 | 42 | const appName = path.basename(root); 43 | 44 | await makeDir.makeDir(root); 45 | if (!checkFolder.isFolderEmpty(root, appName)) { 46 | process.exit(1); 47 | } 48 | 49 | await makeDir.makeDir(path.join(root, 'packages')); 50 | await makeDir.makeDir(path.join(root, 'packages', 'frontend')); 51 | await makeDir.makeDir(path.join(root, 'packages', 'backend')); 52 | 53 | // const useYarn = useNpm ? false : checkYarn.shouldUseYarn(); 54 | const useYarn = useNpm ? false : true; 55 | // const isOnline = !useYarn || (await checkOnline.getOnline()); 56 | const originalDirectory = process.cwd(); 57 | 58 | const displayedCommand = useYarn ? 'yarn' : 'npm'; 59 | console.log(`Creating a new Web3 app in ${chalk.green(root)}.`); 60 | console.log(); 61 | 62 | process.chdir(root); 63 | 64 | console.log(chalk.bold(`Using ${displayedCommand}.`)); 65 | 66 | /** 67 | * Create a package.json for the new project. 68 | */ 69 | 70 | const nextScripts = { 71 | dev: 'yarn workspace @create-web3/frontend dev', 72 | build: 'yarn workspace @create-web3/frontend build', 73 | start: 'yarn workspace @create-web3/frontend start', 74 | lint: 'yarn workspace @create-web3/frontend lint', 75 | }; 76 | 77 | const viteScripts = { 78 | dev: 'yarn workspace @create-web3/frontend dev', 79 | build: 'yarn workspace @create-web3/frontend build', 80 | serve: 'yarn workspace @create-web3/frontend serve', 81 | }; 82 | 83 | const hardhatScripts = { 84 | chain: 'yarn workspace @create-web3/backend chain', 85 | compile: 'yarn workspace @create-web3/backend compile', 86 | test: 'yarn workspace @create-web3/backend test', 87 | clean: 'yarn workspace @create-web3/backend clean', 88 | deploy: 'yarn workspace @create-web3/backend deploy', 89 | }; 90 | 91 | const foundryScripts = { 92 | chain: 'yarn workspace @create-web3/backend chain', 93 | compile: 'yarn workspace @create-web3/backend compile', 94 | test: 'yarn workspace @create-web3/backend test', 95 | clean: 'yarn workspace @create-web3/backend clean', 96 | gas: 'yarn workspace @create-web3/backend gas', 97 | }; 98 | 99 | const frontendScripts = frontend === 'vite' ? viteScripts : nextScripts; 100 | const backendScripts = 101 | backend === 'hardhat' ? hardhatScripts : foundryScripts; 102 | 103 | const packageJson = { 104 | name: appName, 105 | version: '0.0.1', 106 | description: `create-web3 monorepo quickstart with ${frontend} and ${backend}`, 107 | main: 'index.js', 108 | private: true, 109 | scripts: { 110 | ...frontendScripts, 111 | ...backendScripts, 112 | }, 113 | workspaces: { 114 | packages: ['packages/*'], 115 | nohoist: [ 116 | '**/@graphprotocol/graph-ts', 117 | '**/@graphprotocol/graph-ts/**', 118 | '**/backend', 119 | '**/backend/**', 120 | ], 121 | }, 122 | }; 123 | /** 124 | * Write it to disk. 125 | */ 126 | fs.writeFileSync( 127 | path.join(root, 'package.json'), 128 | JSON.stringify(packageJson, null, 2) + os.EOL 129 | ); 130 | 131 | /** 132 | * These flags will be passed to `install()`. 133 | */ 134 | // const installFlags = { useYarn, isOnline }; 135 | /** 136 | * Create Next package.json and install dependencies. 137 | */ 138 | // await installNext.installNext(appPath, installFlags, typescript); 139 | /** 140 | * Create hardhat package.json and install dependencies. 141 | */ 142 | // await installHardhat.installHardhat(appPath, installFlags, typescript); 143 | 144 | console.log(); 145 | /** 146 | * Copy the template files to the target directory. 147 | */ 148 | 149 | /** 150 | * Copy common files. 151 | */ 152 | await cpy('**', root, { 153 | cwd: path.join(__dirname, 'templates', 'common'), 154 | rename: (name) => { 155 | switch (name) { 156 | case 'gitignore': 157 | case 'env.example': 158 | case 'eslintrc.json': { 159 | return '.'.concat(name); 160 | } 161 | case 'README-template.md': { 162 | return 'README.md'; 163 | } 164 | default: { 165 | return name; 166 | } 167 | } 168 | }, 169 | }); 170 | 171 | /** 172 | * Copy backend files. 173 | */ 174 | const backendpath = backend === 'hardhat' ? `hardhat/${template}` : 'foundry'; 175 | 176 | await cpy('**', root + '/packages/backend/', { 177 | parents: true, 178 | // cwd: path.join(__dirname, "templates", "hardhat", template), 179 | cwd: path.join(__dirname, 'templates', backendpath), 180 | 181 | filter: (name) => { 182 | if (name.relativePath === 'package.json') { 183 | return false; 184 | } 185 | return true; 186 | }, 187 | rename: (name) => { 188 | switch (name) { 189 | case 'package-template.json': { 190 | return 'package.json'; 191 | } 192 | case 'gitmodules': { 193 | return '.'.concat(name); 194 | } 195 | default: { 196 | return name; 197 | } 198 | } 199 | }, 200 | }); 201 | 202 | /** 203 | * Copy frontend files. 204 | */ 205 | 206 | await cpy('**', root + '/packages/frontend/', { 207 | parents: true, 208 | cwd: path.join(__dirname, 'templates', frontend, template), 209 | filter: (name) => { 210 | if (name.relativePath === 'package.json') { 211 | return false; 212 | } 213 | return true; 214 | }, 215 | rename: (name) => { 216 | switch (name) { 217 | case 'package-template.json': { 218 | return 'package.json'; 219 | } 220 | default: { 221 | return name; 222 | } 223 | } 224 | }, 225 | }); 226 | 227 | /** 228 | * Copy css framework files. 229 | */ 230 | 231 | if (css) { 232 | await cpy('**', root + '/packages/frontend/', { 233 | parents: true, 234 | cwd: path.join(__dirname, 'templates/css', css, frontend, template), 235 | }); 236 | } 237 | 238 | /** 239 | * Init git. 240 | */ 241 | 242 | if (gitInit.tryGitInit(root)) { 243 | console.log('Initialized a git repository.'); 244 | console.log(); 245 | } 246 | 247 | let cdpath = ''; 248 | if (path.join(originalDirectory, appName) === appPath) { 249 | cdpath = appName; 250 | } else { 251 | cdpath = appPath; 252 | } 253 | 254 | console.log(`${chalk.green('Success!')} Created ${appName} at ${appPath}`); 255 | console.log(); 256 | console.log( 257 | 'Get started by going into the directory and install dependencies.' 258 | ); 259 | console.log(chalk.cyan(' cd'), cdpath); 260 | console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'install '}`)); 261 | console.log(); 262 | console.log( 263 | `For a walk through guild, visit https://www.create-web3.xyz/get-started/quick-start` 264 | ); 265 | // console.log('Inside that directory, you can run several commands:'); 266 | // console.log(); 267 | // console.log(); 268 | // console.log('Suggest that you begin by, creating 3 terminals.'); 269 | // console.log(); 270 | // console.log('In one terminal type:'); 271 | // console.log(chalk.cyan(' cd'), cdpath); 272 | // console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'install '}`)); 273 | // console.log( 274 | // ` ${chalk.cyan(`${displayedCommand} ${useYarn ? '' : 'run '}chain`)}` 275 | // ); 276 | // console.log(); 277 | // console.log('In a second terminal type:'); 278 | // console.log(chalk.cyan(' cd'), cdpath); 279 | // console.log( 280 | // ` ${chalk.cyan(`${displayedCommand} ${useYarn ? '' : 'run '}deploy`)}` 281 | // ); 282 | // console.log(); 283 | // console.log('In a third terminal type:'); 284 | // console.log(chalk.cyan(' cd'), cdpath); 285 | // console.log( 286 | // ` ${chalk.cyan(`${displayedCommand} ${useYarn ? '' : 'run '}dev`)}` 287 | // ); 288 | console.log(); 289 | }; 290 | 291 | module.exports = { 292 | init, 293 | }; 294 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/get-pkg-manager.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | const { execSync } = require('child_process'); 3 | 4 | function getPkgManager() { 5 | try { 6 | const userAgent = process.env.npm_config_user_agent; 7 | if (userAgent) { 8 | if (userAgent.startsWith('yarn')) { 9 | return 'yarn'; 10 | } else if (userAgent.startsWith('pnpm')) { 11 | return 'pnpm'; 12 | } 13 | } 14 | try { 15 | execSync('yarn --version', { stdio: 'ignore' }); 16 | return 'yarn'; 17 | } catch { 18 | execSync('pnpm --version', { stdio: 'ignore' }); 19 | return 'pnpm'; 20 | } 21 | } catch { 22 | return 'npm'; 23 | } 24 | } 25 | 26 | exports.getPkgManager = getPkgManager; 27 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/git.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | const { execSync } = require('child_process'); 3 | const path = require('path'); 4 | const rimraf = require('rimraf'); 5 | 6 | function isInGitRepository() { 7 | try { 8 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); 9 | return true; 10 | } catch (_) {} 11 | return false; 12 | } 13 | 14 | function isInMercurialRepository() { 15 | try { 16 | execSync('hg --cwd . root', { stdio: 'ignore' }); 17 | return true; 18 | } catch (_) {} 19 | return false; 20 | } 21 | 22 | const tryGitInit = (root) => { 23 | let didInit = false; 24 | try { 25 | execSync('git --version', { stdio: 'ignore' }); 26 | if (isInGitRepository() || isInMercurialRepository()) { 27 | return false; 28 | } 29 | 30 | execSync('git init', { stdio: 'ignore' }); 31 | didInit = true; 32 | 33 | execSync('git checkout -b main', { stdio: 'ignore' }); 34 | 35 | execSync('git add -A', { stdio: 'ignore' }); 36 | execSync('git commit -m "Initial commit from create-web3"', { 37 | stdio: 'ignore', 38 | }); 39 | return true; 40 | } catch (e) { 41 | if (didInit) { 42 | try { 43 | rimraf.sync(path.join(root, '.git')); 44 | } catch (_) {} 45 | } 46 | return false; 47 | } 48 | }; 49 | 50 | exports.tryGitInit = tryGitInit; 51 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/install-hardhat.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const os = require('os'); 3 | const path = require('path'); 4 | const chalk = require('chalk'); 5 | const installDep = require('./install'); 6 | 7 | const installHardhat = async (appPath, installFlags, typescript) => { 8 | console.log('running install hardhat'); 9 | const root = path.resolve(appPath); 10 | /** 11 | * Create a package.json for the hardhat. 12 | */ 13 | const packageHardhatJson = { 14 | name: '@project/hardhat', 15 | version: '0.1.0', 16 | private: true, 17 | scripts: { 18 | chain: 'hardhat node --network hardhat --no-deploy', 19 | clean: 'npx hardhat clean', 20 | deploy: 21 | 'hardhat deploy --export-all ../next-app/contracts/hardhat_contracts.json', 22 | }, 23 | }; 24 | /** 25 | * Create hardhat folders and write it to disk. 26 | */ 27 | fs.writeFileSync( 28 | path.join(root, 'packages', 'hardhat', 'package.json'), 29 | JSON.stringify(packageHardhatJson, null, 2) + os.EOL 30 | ); 31 | 32 | /** 33 | * Default dependencies. 34 | */ 35 | const dependencies = ['dotenv']; 36 | /** 37 | * Default devDependencies. 38 | */ 39 | const devDependencies = [ 40 | '@nomiclabs/hardhat-ethers', 41 | '@nomiclabs/hardhat-etherscan', 42 | '@nomiclabs/hardhat-waffle', 43 | '@openzeppelin/contracts', 44 | 'chai', 45 | 'ethereum-waffle', 46 | 'ethers', 47 | 'hardhat', 48 | 'hardhat-deploy', 49 | ]; 50 | /** 51 | * TypeScript projects will have type definitions and other devDependencies. 52 | */ 53 | if (typescript) { 54 | devDependencies.push('typescript'); 55 | } 56 | /** 57 | * Install package.json dependencies if they exist. 58 | */ 59 | 60 | let installDir = path.join(root, '/packages/hardhat'); 61 | 62 | if (dependencies.length) { 63 | console.log(); 64 | console.log('Installing dependencies:'); 65 | for (const dependency of dependencies) { 66 | console.log(`- ${chalk.cyan(dependency)}`); 67 | } 68 | console.log(); 69 | 70 | await installDep.install(installDir, dependencies, installFlags); 71 | } 72 | /** 73 | * Install package.json devDependencies if they exist. 74 | */ 75 | if (devDependencies.length) { 76 | console.log(); 77 | console.log('Installing devDependencies:'); 78 | for (const devDependency of devDependencies) { 79 | console.log(`- ${chalk.cyan(devDependency)}`); 80 | } 81 | console.log(); 82 | 83 | const devInstallFlags = { devDependencies: true, ...installFlags }; 84 | await installDep.install(installDir, devDependencies, devInstallFlags); 85 | } 86 | console.log(); 87 | }; 88 | 89 | exports.installHardhat = installHardhat; 90 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/install-next.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const os = require('os'); 3 | const path = require('path'); 4 | const chalk = require('chalk'); 5 | const installDep = require('./install'); 6 | 7 | const installNext = async (appPath, installFlags, typescript) => { 8 | console.log('running install next'); 9 | const root = path.resolve(appPath); 10 | 11 | /** 12 | * Create a package.json for the next-app. 13 | */ 14 | const packageNextJson = { 15 | name: '@project/next-app', 16 | version: '0.1.0', 17 | private: true, 18 | scripts: { 19 | dev: 'next dev', 20 | build: 'next build', 21 | start: 'next start', 22 | lint: 'next lint', 23 | }, 24 | }; 25 | /** 26 | * Create next-app folders and write it to disk. 27 | */ 28 | fs.writeFileSync( 29 | path.join(root, 'packages', 'next-app', 'package.json'), 30 | JSON.stringify(packageNextJson, null, 2) + os.EOL 31 | ); 32 | 33 | /** 34 | * Default dependencies. 35 | */ 36 | const dependencies = [ 37 | 'ethers', 38 | 'next@12.1.4', 39 | 'react@18.0.0', 40 | 'react-dom@18.0.0', 41 | 'wagmi@0.2.28', 42 | ]; 43 | /** 44 | * Default devDependencies. 45 | */ 46 | const devDependencies = ['eslint@8.12.0', 'eslint-config-next@12.1.4']; 47 | /** 48 | * TypeScript projects will have type definitions and other devDependencies. 49 | */ 50 | if (typescript) { 51 | devDependencies.push( 52 | 'typescript', 53 | '@types/react', 54 | '@types/node', 55 | '@types/react-dom' 56 | ); 57 | } 58 | /** 59 | * Install package.json dependencies if they exist. 60 | */ 61 | 62 | let installDir = path.join(root, '/packages/next-app'); 63 | 64 | if (dependencies.length) { 65 | console.log(); 66 | console.log('Installing dependencies:'); 67 | for (const dependency of dependencies) { 68 | console.log(`- ${chalk.cyan(dependency)}`); 69 | } 70 | console.log(); 71 | console.log('installDir : ', installDir); 72 | await installDep.install(installDir, dependencies, installFlags); 73 | } 74 | /** 75 | * Install package.json devDependencies if they exist. 76 | */ 77 | if (devDependencies.length) { 78 | console.log(); 79 | console.log('Installing devDependencies:'); 80 | for (const devDependency of devDependencies) { 81 | console.log(`- ${chalk.cyan(devDependency)}`); 82 | } 83 | console.log(); 84 | 85 | const devInstallFlags = { devDependencies: true, ...installFlags }; 86 | await installDep.install(installDir, devDependencies, devInstallFlags); 87 | } 88 | console.log(); 89 | }; 90 | 91 | exports.installNext = installNext; 92 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/install.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | const chalk = require('chalk'); 3 | const spawn = require('cross-spawn'); 4 | 5 | /** 6 | * Spawn a package manager installation with either Yarn or NPM. 7 | * 8 | * @returns A Promise that resolves once the installation is finished. 9 | */ 10 | const install = ( 11 | root, 12 | dependencies, 13 | { useYarn, isOnline, devDependencies } 14 | ) => { 15 | /** 16 | * NPM-specific command-line flags. 17 | */ 18 | const npmFlags = []; 19 | /** 20 | * Yarn-specific command-line flags. 21 | */ 22 | const yarnFlags = []; 23 | /** 24 | * Return a Promise that resolves once the installation is finished. 25 | */ 26 | return new Promise((resolve, reject) => { 27 | let args = []; 28 | let command = useYarn ? 'yarnpkg' : 'npm'; 29 | 30 | if (dependencies && dependencies.length) { 31 | /** 32 | * If there are dependencies, run a variation of `{displayCommand} add`. 33 | */ 34 | if (useYarn) { 35 | /** 36 | * Call `yarn add --exact (--offline)? (-D)? ...`. 37 | */ 38 | args = ['add', '--exact', '--legacy-peer-deps']; 39 | if (!isOnline) args.push('--offline'); 40 | args.push('--cwd', root); 41 | if (devDependencies) args.push('--dev'); 42 | args.push(...dependencies); 43 | } else { 44 | /** 45 | * Call `npm install [--save|--save-dev] ...`. 46 | */ 47 | args = ['install', '--save-exact', '--legacy-peer-deps']; 48 | args.push(devDependencies ? '--save-dev' : '--save'); 49 | args.push(...dependencies); 50 | } 51 | } else { 52 | /** 53 | * If there are no dependencies, run a variation of `{displayCommand} 54 | * install`. 55 | */ 56 | args = ['install']; 57 | if (useYarn) { 58 | if (!isOnline) { 59 | console.log(chalk.yellow('You appear to be offline.')); 60 | console.log(chalk.yellow('Falling back to the local Yarn cache.')); 61 | console.log(); 62 | args.push('--offline'); 63 | } 64 | } else { 65 | if (!isOnline) { 66 | console.log(chalk.yellow('You appear to be offline.')); 67 | console.log(); 68 | } 69 | } 70 | } 71 | /** 72 | * Add any package manager-specific flags. 73 | */ 74 | if (useYarn) { 75 | args.push(...yarnFlags); 76 | } else { 77 | args.push(...npmFlags); 78 | } 79 | /** 80 | * Spawn the installation process. 81 | */ 82 | const child = spawn(command, args, { 83 | stdio: 'inherit', 84 | env: { ...process.env, ADBLOCK: '1', DISABLE_OPENCOLLECTIVE: '1' }, 85 | }); 86 | child.on('close', (code) => { 87 | if (code !== 0) { 88 | reject({ command: `${command} ${args.join(' ')}` }); 89 | return; 90 | } 91 | resolve(); 92 | }); 93 | }); 94 | }; 95 | 96 | exports.install = install; 97 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/is-folder-empty.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | const chalk = require('chalk'); 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | const isFolderEmpty = (root, name) => { 7 | const validFiles = [ 8 | '.DS_Store', 9 | '.git', 10 | '.gitattributes', 11 | '.gitignore', 12 | '.gitlab-ci.yml', 13 | '.hg', 14 | '.hgcheck', 15 | '.hgignore', 16 | '.idea', 17 | '.npmignore', 18 | '.travis.yml', 19 | 'LICENSE', 20 | 'Thumbs.db', 21 | 'docs', 22 | 'mkdocs.yml', 23 | 'npm-debug.log', 24 | 'yarn-debug.log', 25 | 'yarn-error.log', 26 | ]; 27 | 28 | const conflicts = fs 29 | .readdirSync(root) 30 | .filter((file) => !validFiles.includes(file)) 31 | // Support IntelliJ IDEA-based editors 32 | .filter((file) => !/\.iml$/.test(file)); 33 | 34 | if (conflicts.length > 0) { 35 | console.log( 36 | `The directory ${chalk.green(name)} contains files that could conflict:` 37 | ); 38 | console.log(); 39 | for (const file of conflicts) { 40 | try { 41 | const stats = fs.lstatSync(path.join(root, file)); 42 | if (stats.isDirectory()) { 43 | console.log(` ${chalk.blue(file)}/`); 44 | } else { 45 | console.log(` ${file}`); 46 | } 47 | } catch { 48 | console.log(` ${file}`); 49 | } 50 | } 51 | console.log(); 52 | console.log( 53 | 'Either try using a new directory name, or remove the files listed above.' 54 | ); 55 | console.log(); 56 | return false; 57 | } 58 | 59 | return true; 60 | }; 61 | 62 | exports.isFolderEmpty = isFolderEmpty; 63 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/is-online.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require('child_process'); 2 | const dns = require('dns'); 3 | const url = require('url'); 4 | 5 | function getProxy() { 6 | if (process.env.https_proxy) { 7 | return process.env.https_proxy; 8 | } 9 | 10 | try { 11 | const httpsProxy = execSync('npm config get https-proxy').toString().trim(); 12 | return httpsProxy !== 'null' ? httpsProxy : undefined; 13 | } catch (e) { 14 | return; 15 | } 16 | } 17 | 18 | const getOnline = () => { 19 | return new Promise((resolve) => { 20 | dns.lookup('registry.yarnpkg.com', (registryErr) => { 21 | if (!registryErr) { 22 | return resolve(true); 23 | } 24 | 25 | const proxy = getProxy(); 26 | if (!proxy) { 27 | return resolve(false); 28 | } 29 | 30 | const { hostname } = url.parse(proxy); 31 | if (!hostname) { 32 | return resolve(false); 33 | } 34 | 35 | dns.lookup(hostname, (proxyErr) => { 36 | resolve(proxyErr == null); 37 | }); 38 | }); 39 | }); 40 | }; 41 | 42 | exports.getOnline = getOnline; 43 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/is-writeable.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const isWriteable = async (directory) => { 4 | try { 5 | await fs.promises.access(directory, (fs.constants || fs).W_OK); 6 | return true; 7 | } catch (err) { 8 | return false; 9 | } 10 | }; 11 | 12 | exports.isWriteable = isWriteable; 13 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/make-dir.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const makeDir = async (root, options = { recursive: true }) => { 4 | return fs.promises.mkdir(root, options); 5 | }; 6 | 7 | exports.makeDir = makeDir; 8 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/should-use-yarn.js: -------------------------------------------------------------------------------- 1 | const { execSync } = require('child_process'); 2 | 3 | const shouldUseYarn = () => { 4 | try { 5 | const userAgent = process.env.npm_config_user_agent; 6 | if (userAgent) { 7 | return Boolean(userAgent && userAgent.startsWith('yarn')); 8 | } 9 | execSync('yarnpkg --version', { stdio: 'ignore' }); 10 | return true; 11 | } catch (e) { 12 | return false; 13 | } 14 | }; 15 | 16 | exports.shouldUseYarn = shouldUseYarn; 17 | -------------------------------------------------------------------------------- /packages/create-web3/helpers/validate-pkg.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/no-extraneous-dependencies 2 | const validateProjectName = require('validate-npm-package-name'); 3 | 4 | const validateNpmName = (name) => { 5 | const nameValidation = validateProjectName(name); 6 | if (nameValidation.validForNewPackages) { 7 | return { valid: true }; 8 | } 9 | 10 | return { 11 | valid: false, 12 | problems: [ 13 | ...(nameValidation.errors || []), 14 | ...(nameValidation.warnings || []), 15 | ], 16 | }; 17 | }; 18 | 19 | exports.validateNpmName = validateNpmName; 20 | -------------------------------------------------------------------------------- /packages/create-web3/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | const chalk = require('chalk'); 4 | const { Command } = require('commander'); 5 | const path = require('path'); 6 | const prompts = require('prompts'); 7 | const { init } = require('./create-app'); 8 | const checkForUpdate = require('update-check'); 9 | const validated = require('./helpers/validate-pkg'); 10 | const packageJson = require('./package.json'); 11 | const { getPkgManager } = require('./helpers/get-pkg-manager'); 12 | 13 | let projectPath = ''; 14 | 15 | const program = new Command(packageJson.name) 16 | .version(packageJson.version) 17 | .arguments('[project-directory]') 18 | .action((name) => { 19 | projectPath = name; 20 | console.log(`projectPath: ${projectPath}`); 21 | }) 22 | .option( 23 | '--ts, --typescript', 24 | ` 25 | Initialize as a TypeScript project. 26 | ` 27 | ) 28 | .option( 29 | '--use-npm', 30 | ` 31 | Explicitly tell the CLI to bootstrap the app using npm 32 | ` 33 | ) 34 | .allowUnknownOption() 35 | .parse(process.argv); 36 | 37 | async function run() { 38 | if (typeof projectPath === 'string') { 39 | projectPath = projectPath.trim(); 40 | } 41 | if (!projectPath) { 42 | const resName = await prompts({ 43 | type: 'text', 44 | name: 'path', 45 | message: 'What is your web3 app named?', 46 | initial: 'my-app', 47 | validate: (name) => { 48 | const validation = validated.validateNpmName( 49 | path.basename(path.resolve(name)) 50 | ); 51 | if (validation.valid) { 52 | return true; 53 | } 54 | console.log(validation); 55 | return 'Invalid Name: ' + validation.problems[0]; 56 | }, 57 | }); 58 | 59 | if (typeof resName.path === 'string') { 60 | projectPath = resName.path.trim(); 61 | } 62 | } 63 | 64 | const resFrontend = await prompts({ 65 | type: 'select', 66 | name: 'frontend', 67 | message: 'Frontend : React w/ Next or Vite?', 68 | choices: [ 69 | { title: 'Next', value: 'next' }, 70 | { title: 'Vite', value: 'vite' }, 71 | ], 72 | }); 73 | 74 | const resCSS = await prompts({ 75 | type: 'select', 76 | name: 'css', 77 | message: 'CSS Framework?', 78 | choices: [ 79 | { title: 'None', value: null }, 80 | { title: 'Tailwind', value: 'tailwind' }, 81 | { title: 'Chakra', value: 'chakra' }, 82 | ], 83 | }); 84 | 85 | const resBackend = await prompts({ 86 | type: 'select', 87 | name: 'backend', 88 | message: 'Backend : Hardhat or Foundry?', 89 | choices: [ 90 | { title: 'Hardhat', value: 'hardhat' }, 91 | { title: 'Foundry - currently testing', value: 'foundry' }, 92 | ], 93 | }); 94 | 95 | const resTypescript = await prompts({ 96 | type: 'select', 97 | name: 'typescript', 98 | message: 'Javascript or Typescript?', 99 | choices: [ 100 | { title: 'Javascript', value: false }, 101 | { title: 'Typescript', value: true }, 102 | ], 103 | }); 104 | 105 | const resUseNpm = await prompts({ 106 | type: 'select', 107 | name: 'useNpm', 108 | message: 'Use NPM or YARN?', 109 | choices: [ 110 | { title: 'NPM', value: true }, 111 | { title: 'YARN', value: false }, 112 | ], 113 | }); 114 | 115 | const resolvedProjectPath = path.resolve(projectPath); 116 | const projectName = path.basename(resolvedProjectPath); 117 | 118 | const { valid, problems } = validated.validateNpmName(projectName); 119 | if (!valid) { 120 | console.error( 121 | `Could not create a project called ${chalk.red( 122 | `"${projectName}"` 123 | )} because of npm naming restrictions:` 124 | ); 125 | 126 | problems.forEach((p) => console.error(` ${chalk.red.bold('*')} ${p}`)); 127 | process.exit(1); 128 | } 129 | 130 | try { 131 | await init({ 132 | appPath: resolvedProjectPath, 133 | useNpm: resUseNpm.useNpm, 134 | typescript: resTypescript.typescript, 135 | frontend: resFrontend.frontend, 136 | backend: resBackend.backend, 137 | css: resCSS.css, 138 | }); 139 | } catch (error) { 140 | console.log(error); 141 | } 142 | } 143 | 144 | const update = checkForUpdate(packageJson).catch(() => null); 145 | 146 | async function notifyUpdate() { 147 | try { 148 | console.log('Checking for updates...'); 149 | const res = await update; 150 | if (res?.latest) { 151 | const pkgManager = getPkgManager(); 152 | console.log('pkgManager', pkgManager); 153 | 154 | console.log(); 155 | console.log( 156 | chalk.yellow.bold('A new version of `create-web3` is available!') 157 | ); 158 | console.log( 159 | 'You can update by running: ' + 160 | chalk.cyan(`npm install --global create-web3`) 161 | // chalk.cyan( 162 | // pkgManager === 'yarn' 163 | // ? 'yarn global add create-web3' 164 | // : `${pkgManager} install --global create-web3` 165 | // ) 166 | ); 167 | console.log(); 168 | } else { 169 | console.log(chalk.green('You are running the latest version.')); 170 | } 171 | process.exit(); 172 | } catch { 173 | // ignore error 174 | } 175 | } 176 | 177 | run() 178 | .then(notifyUpdate) 179 | .catch(async (reason) => { 180 | console.log(); 181 | console.log('Aborting installation.'); 182 | if (reason.command) { 183 | console.log(` ${chalk.cyan(reason.command)} has failed.`); 184 | } else { 185 | console.log( 186 | chalk.red( 187 | 'Unexpected error. Please report it as a bug: https://github.com/e-roy/create-web3/issues' 188 | ) 189 | ); 190 | console.log(reason); 191 | } 192 | console.log(); 193 | 194 | await notifyUpdate(); 195 | 196 | process.exit(1); 197 | }); 198 | -------------------------------------------------------------------------------- /packages/create-web3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-web3", 3 | "version": "0.4.10", 4 | "description": "", 5 | "scripts": {}, 6 | "keywords": [ 7 | "create-web3", 8 | "web3", 9 | "boilerplate", 10 | "nextjs", 11 | "react", 12 | "vite", 13 | "wagmi", 14 | "hardhat", 15 | "foundry", 16 | "rainbowkit", 17 | "dapp" 18 | ], 19 | "author": "Eric Roupe", 20 | "license": "MIT", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/e-roy/create-web3", 24 | "directory": "packages/create-web3" 25 | }, 26 | "homepage": "create-web3.xyz", 27 | "bin": { 28 | "create-web3": "./index.js" 29 | }, 30 | "dependencies": { 31 | "chalk": "2.4.2", 32 | "commander": "^8.3.0", 33 | "cpy": "^8.1.2", 34 | "cross-spawn": "^7.0.3", 35 | "prompts": "^2.4.2", 36 | "rimraf": "^3.0.2", 37 | "update-check": "1.5.4", 38 | "validate-npm-package-name": "^3.0.0" 39 | }, 40 | "engines": { 41 | "node": ">=14" 42 | }, 43 | "gitHead": "da4ed9ad6fa2d4386d4e35e60c221fda2bc5ccaa" 44 | } 45 | -------------------------------------------------------------------------------- /packages/create-web3/templates/common/README-template.md: -------------------------------------------------------------------------------- 1 | # create-web3 boilerplate 2 | 3 | A boilerplate for starting a web3 project. 4 | 5 | This boilerplate quickly creates a mono repo with 2 environments, a react frontend environment and a Ethereum development environment for writing, testing and deploying contracts. 6 | 7 | ## Quick Start Notes 8 | 9 | 1. To start install 10 | 11 | ```bash 12 | npx create-web3 13 | ``` 14 | 15 | 2. Run `yarn` or `npm install` to install all the dependencies 16 | 3. Once installation is complete, `cd` into your app's directory and run `yarn chain` or `npm run chain` to start a local hardhat environment 17 | 4. Open another terminal and `cd` into your app's directory 18 | 5. Run `yarn deploy` or `npm run deploy` to deploy the example contract locally 19 | 6. Run `yarn dev` or `npm run dev` to start your FrontEnd dev environment 20 | 21 | ## Technologies 22 | 23 | This project is built with the following open source libraries, frameworks and languages. User choice of framework used, available in plain js or typescript. 24 | | Tech | Description | 25 | | --------------------------------------------- | ------------------------------------------------------------------ | 26 | | ------ | ------ React Frontend Environment ------ | 27 | | [Next JS](https://nextjs.org/) | React Framework | 28 | | [Vite JS](https://vitejs.dev/) | Next Generation Frontend Tooling | 29 | | ------ | ------ CSS Framework ------ | 30 | | none | | 31 | | [Tailwind](https://tailwindcss.com/) | A utility-first CSS framework | 32 | | [Chakra](https://chakra-ui.com/) | A simple, modular and accessible component library that gives you the building blocks you need to build your React applications. | 33 | | ------ | ------ Ethereum Development Environment ------ | 34 | | [Hardhat](https://hardhat.org/) | Ethereum development environment for professionals | 35 | | [Foundry](https://getfoundry.sh/) | a blazing fast, portable and modular toolkit for Ethereum application development written in Rust. | 36 | | ------ | ------ Included Libraries ------ | 37 | | [WAGMI](https://wagmi.sh/) | A set of React Hooks for Web3 | 38 | | [RainbowKit](https://www.rainbowkit.com/docs/introduction) | RainbowKit is a React library that makes it easy to add wallet connection to your dapp. | 39 | 40 | ## Documentation 41 | 42 | Please visit [create-web3.xyz](https://create-web3.xyz) to view the full documentation. 43 | 44 | ## Discussions 45 | 46 | If you have questions how to use, want to suggest a feature, or show off a project you created with create-web3, join [discussions on GitHub](https://github.com/e-roy/create-web3/discussions). I would love to hear from you. 🙂 47 | 48 | ## Issues 49 | 50 | If you find a bug or would like to request a feature, please visit [ISSUES](https://github.com/e-roy/create-web3/issues) 51 | -------------------------------------------------------------------------------- /packages/create-web3/templates/common/env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_ALCHEMY_ID= 2 | NEXT_PUBLIC_INFURA_ID= 3 | VITE_ALCHEMY_ID= 4 | VITE_INFURA_ID= 5 | ETHERSCAN_API_KEY= 6 | PRIVATE_KEY= 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/common/gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | 5 | /node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | 11 | coverage 12 | coverage.json 13 | typechain 14 | 15 | # Hardhat files 16 | 17 | cache 18 | artifacts 19 | /packages/backend/node_modules 20 | /packages/backend/deployments/\* 21 | 22 | # Foundry files 23 | 24 | /packages/backend/cache 25 | /packages/backend/out 26 | 27 | # next.js 28 | 29 | /packages/frontend/node_modules 30 | packages/frontend/.next/ 31 | /out/ 32 | 33 | # vite 34 | 35 | /packages/frontend/node_modules 36 | /packages/frontend/dist 37 | 38 | # production 39 | 40 | /build 41 | 42 | # misc 43 | 44 | .DS_Store 45 | \*.pem 46 | 47 | # debug 48 | 49 | npm-debug.log* 50 | yarn-debug.log* 51 | yarn-error.log\* 52 | 53 | # local env files 54 | 55 | .env 56 | .env.local 57 | .env.development.local 58 | .env.test.local 59 | .env.production.local 60 | 61 | # vercel 62 | 63 | .vercel 64 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/next/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@chakra-ui/react": "^2.4.9", 14 | "@emotion/react": "^11.10.5", 15 | "@emotion/styled": "^11.10.5", 16 | "@rainbow-me/rainbowkit": "^0.8.1", 17 | "ethers": "^5.7.2", 18 | "framer-motion": "^9.0.1", 19 | "next": "^13.1.6", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "wagmi": "^0.11.3" 23 | }, 24 | "devDependencies": { 25 | "eslint": "^8.27.0", 26 | "eslint-config-next": "^13.0.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/next/default/pages/_app.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import NextHead from 'next/head'; 3 | import '../styles/globals.css'; 4 | 5 | import { ChakraProvider } from '@chakra-ui/react'; 6 | 7 | // Imports 8 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 9 | import { 10 | mainnet, 11 | polygon, 12 | polygonMumbai, 13 | optimism, 14 | arbitrum, 15 | hardhat, 16 | } from 'wagmi/chains'; 17 | import { publicProvider } from 'wagmi/providers/public'; 18 | 19 | import '@rainbow-me/rainbowkit/styles.css'; 20 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 21 | 22 | import { useIsMounted } from '../hooks'; 23 | 24 | const { chains, provider, webSocketProvider } = configureChains( 25 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 26 | [publicProvider()] 27 | ); 28 | 29 | const { connectors } = getDefaultWallets({ 30 | appName: 'create-web3', 31 | chains, 32 | }); 33 | 34 | const wagmiClient = createClient({ 35 | autoConnect: true, 36 | connectors, 37 | provider, 38 | webSocketProvider, 39 | }); 40 | 41 | const App = ({ Component, pageProps }) => { 42 | const isMounted = useIsMounted(); 43 | 44 | if (!isMounted) return null; 45 | return ( 46 | 47 | 48 | 49 | create-web3 50 | 51 | 52 | 53 | 54 | 55 | 56 | ); 57 | }; 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/next/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@chakra-ui/react": "^2.4.9", 14 | "@emotion/react": "^11.10.5", 15 | "@emotion/styled": "^11.10.5", 16 | "@rainbow-me/rainbowkit": "^0.8.1", 17 | "ethers": "^5.7.2", 18 | "framer-motion": "^9.0.1", 19 | "next": "^13.1.6", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0", 22 | "wagmi": "^0.11.3" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "^18.11.18", 26 | "@types/react": "^18.0.27", 27 | "@types/react-dom": "^18.0.10", 28 | "eslint": "^8.27.0", 29 | "eslint-config-next": "^13.0.2", 30 | "typescript": "^4.9.5" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/next/typescript/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import type { AppProps } from 'next/app'; 3 | import NextHead from 'next/head'; 4 | import '../styles/globals.css'; 5 | 6 | import { ChakraProvider } from '@chakra-ui/react'; 7 | 8 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 9 | import { 10 | mainnet, 11 | polygon, 12 | polygonMumbai, 13 | optimism, 14 | arbitrum, 15 | hardhat, 16 | } from 'wagmi/chains'; 17 | import { publicProvider } from 'wagmi/providers/public'; 18 | 19 | import '@rainbow-me/rainbowkit/styles.css'; 20 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 21 | 22 | import { useIsMounted } from '../hooks'; 23 | 24 | const { chains, provider, webSocketProvider } = configureChains( 25 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 26 | [publicProvider()] 27 | ); 28 | 29 | const { connectors } = getDefaultWallets({ 30 | appName: 'create-web3', 31 | chains, 32 | }); 33 | 34 | const wagmiClient = createClient({ 35 | autoConnect: true, 36 | connectors, 37 | provider, 38 | webSocketProvider, 39 | }); 40 | 41 | const App = ({ Component, pageProps }: AppProps) => { 42 | const isMounted = useIsMounted(); 43 | 44 | if (!isMounted) return null; 45 | return ( 46 | 47 | 48 | 49 | create-web3 50 | 51 | 52 | 53 | 54 | 55 | 56 | ); 57 | }; 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/vite/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@chakra-ui/react": "^2.4.9", 12 | "@emotion/react": "^11.10.5", 13 | "@emotion/styled": "^11.10.5", 14 | "@rainbow-me/rainbowkit": "^0.8.1", 15 | "buffer": "^6.0.3", 16 | "ethers": "^5.7.2", 17 | "framer-motion": "^9.0.1", 18 | "process": "^0.11.10", 19 | "react": "^18.2.0", 20 | "react-dom": "^18.2.0", 21 | "util": "^0.12.4", 22 | "wagmi": "^0.11.3" 23 | }, 24 | "devDependencies": { 25 | "@types/react": "^18.0.27", 26 | "@types/react-dom": "^18.0.5", 27 | "@vitejs/plugin-react": "^3.1.0", 28 | "vite": "^4.1.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/vite/default/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | import './index.css'; 5 | 6 | import { ChakraProvider } from '@chakra-ui/react'; 7 | 8 | // Imports 9 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 10 | import { 11 | mainnet, 12 | polygon, 13 | polygonMumbai, 14 | optimism, 15 | arbitrum, 16 | hardhat, 17 | } from 'wagmi/chains'; 18 | import { publicProvider } from 'wagmi/providers/public'; 19 | 20 | import '@rainbow-me/rainbowkit/styles.css'; 21 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 22 | 23 | const { chains, provider, webSocketProvider } = configureChains( 24 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 25 | [publicProvider()] 26 | ); 27 | 28 | const { connectors } = getDefaultWallets({ 29 | appName: 'create-web3', 30 | chains, 31 | }); 32 | 33 | const wagmiClient = createClient({ 34 | autoConnect: true, 35 | connectors, 36 | provider, 37 | }); 38 | 39 | createRoot(document.getElementById('root')).render( 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ); 50 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/vite/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@chakra-ui/react": "^2.4.9", 12 | "@emotion/react": "^11.10.5", 13 | "@emotion/styled": "^11.10.5", 14 | "@rainbow-me/rainbowkit": "^0.8.1", 15 | "buffer": "^6.0.3", 16 | "ethers": "^5.7.2", 17 | "framer-motion": "^9.0.1", 18 | "process": "^0.11.10", 19 | "react": "^18.2.0", 20 | "react-dom": "^18.2.0", 21 | "util": "^0.12.4", 22 | "wagmi": "^0.11.3" 23 | }, 24 | "devDependencies": { 25 | "@types/react": "^18.0.27", 26 | "@types/react-dom": "^18.0.10", 27 | "@vitejs/plugin-react": "^3.1.0", 28 | "typescript": "^4.9.5", 29 | "vite": "^4.1.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/chakra/vite/typescript/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import App from './App'; 5 | import './index.css'; 6 | 7 | import { ChakraProvider } from '@chakra-ui/react'; 8 | 9 | // Imports 10 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 11 | import { 12 | mainnet, 13 | polygon, 14 | polygonMumbai, 15 | optimism, 16 | arbitrum, 17 | hardhat, 18 | } from 'wagmi/chains'; 19 | import { publicProvider } from 'wagmi/providers/public'; 20 | 21 | import '@rainbow-me/rainbowkit/styles.css'; 22 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 23 | 24 | const { chains, provider, webSocketProvider } = configureChains( 25 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 26 | [publicProvider()] 27 | ); 28 | 29 | const { connectors } = getDefaultWallets({ 30 | appName: 'create-web3', 31 | chains, 32 | }); 33 | 34 | const wagmiClient = createClient({ 35 | autoConnect: true, 36 | connectors, 37 | provider, 38 | webSocketProvider, 39 | }); 40 | 41 | createRoot(document.getElementById('root')!).render( 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ); 52 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@rainbow-me/rainbowkit": "^0.8.1", 14 | "ethers": "^5.7.2", 15 | "next": "^13.1.6", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "autoprefixer": "^10.4.13", 22 | "eslint": "^8.27.0", 23 | "eslint-config-next": "^13.0.2", 24 | "postcss": "^8.4.18", 25 | "tailwindcss": "^3.2.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/default/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/default/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | padding: 0; 8 | margin: 0; 9 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 10 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 11 | } 12 | 13 | a { 14 | color: inherit; 15 | text-decoration: none; 16 | } 17 | 18 | * { 19 | box-sizing: border-box; 20 | } 21 | 22 | button { 23 | cursor: pointer; 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/default/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | "./pages/**/*.{js,ts,jsx,tsx}", 4 | "./components/**/*.{js,ts,jsx,tsx}", 5 | ], 6 | theme: { 7 | extend: {}, 8 | }, 9 | plugins: [], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@rainbow-me/rainbowkit": "^0.8.1", 14 | "ethers": "^5.7.2", 15 | "next": "^13.1.6", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^18.11.18", 22 | "@types/react": "^18.0.27", 23 | "@types/react-dom": "^18.0.10", 24 | "autoprefixer": "^10.4.13", 25 | "eslint": "^8.27.0", 26 | "eslint-config-next": "^13.0.2", 27 | "postcss": "^8.4.18", 28 | "tailwindcss": "^3.2.2", 29 | "typescript": "^4.9.5" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/typescript/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/typescript/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | padding: 0; 8 | margin: 0; 9 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 10 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 11 | } 12 | 13 | a { 14 | color: inherit; 15 | text-decoration: none; 16 | } 17 | 18 | * { 19 | box-sizing: border-box; 20 | } 21 | 22 | button { 23 | cursor: pointer; 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/next/typescript/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | "./pages/**/*.{js,ts,jsx,tsx}", 4 | "./components/**/*.{js,ts,jsx,tsx}", 5 | ], 6 | theme: { 7 | extend: {}, 8 | }, 9 | plugins: [], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "buffer": "^6.0.3", 13 | "ethers": "^5.7.2", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.5", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "autoprefixer": "^10.4.13", 25 | "postcss": "^8.4.18", 26 | "tailwindcss": "^3.2.2", 27 | "vite": "^4.1.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/default/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/default/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | margin: 0; 7 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 8 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 9 | sans-serif; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | code { 15 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 16 | monospace; 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/default/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["./src/**/*.{js,ts,jsx,tsx}"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | }; 8 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "buffer": "^6.0.3", 13 | "ethers": "^5.7.2", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "autoprefixer": "^10.4.13", 25 | "postcss": "^8.4.18", 26 | "tailwindcss": "^3.2.2", 27 | "typescript": "^4.9.5", 28 | "vite": "^4.1.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/typescript/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/typescript/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | margin: 0; 7 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 8 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 9 | sans-serif; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | code { 15 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 16 | monospace; 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-web3/templates/css/tailwind/vite/typescript/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["./src/**/*.{js,ts,jsx,tsx}"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | }; 8 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | check: 6 | name: Foundry project 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | with: 11 | submodules: recursive 12 | 13 | - name: Install Foundry 14 | uses: onbjerg/foundry-toolchain@v1 15 | with: 16 | version: nightly 17 | 18 | - name: Install dependencies 19 | run: forge install 20 | - name: Run tests 21 | run: forge test -vvv 22 | - name: Build Test with older solc versions 23 | run: | 24 | forge build --contracts src/Test.sol --use solc:0.8.0 25 | forge build --contracts src/Test.sol --use solc:0.7.0 26 | forge build --contracts src/Test.sol --use solc:0.6.0 27 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | .vscode 4 | .idea -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/ds-test"] 2 | path = lib/ds-test 3 | url = https://github.com/dapphub/ds-test 4 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Brock Elmore 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE.R 26 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/lib/ds-test/.gitignore: -------------------------------------------------------------------------------- 1 | /.dapple 2 | /build 3 | /out 4 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/lib/ds-test/Makefile: -------------------------------------------------------------------------------- 1 | all:; dapp build 2 | 3 | test: 4 | -dapp --use solc:0.4.23 build 5 | -dapp --use solc:0.4.26 build 6 | -dapp --use solc:0.5.17 build 7 | -dapp --use solc:0.6.12 build 8 | -dapp --use solc:0.7.5 build 9 | 10 | demo: 11 | DAPP_SRC=demo dapp --use solc:0.7.5 build 12 | -hevm dapp-test --verbose 3 13 | 14 | .PHONY: test demo 15 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/lib/ds-test/default.nix: -------------------------------------------------------------------------------- 1 | { solidityPackage, dappsys }: solidityPackage { 2 | name = "ds-test"; 3 | src = ./src; 4 | } 5 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/lib/ds-test/demo/demo.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | import "../src/test.sol"; 5 | 6 | contract DemoTest is DSTest { 7 | function test_this() public pure { 8 | require(true); 9 | } 10 | function test_logs() public { 11 | emit log("-- log(string)"); 12 | emit log("a string"); 13 | 14 | emit log("-- log_named_uint(string, uint)"); 15 | emit log_named_uint("uint", 512); 16 | 17 | emit log("-- log_named_int(string, int)"); 18 | emit log_named_int("int", -512); 19 | 20 | emit log("-- log_named_address(string, address)"); 21 | emit log_named_address("address", address(this)); 22 | 23 | emit log("-- log_named_bytes32(string, bytes32)"); 24 | emit log_named_bytes32("bytes32", "a string"); 25 | 26 | emit log("-- log_named_bytes(string, bytes)"); 27 | emit log_named_bytes("bytes", hex"cafefe"); 28 | 29 | emit log("-- log_named_string(string, string)"); 30 | emit log_named_string("string", "a string"); 31 | 32 | emit log("-- log_named_decimal_uint(string, uint, uint)"); 33 | emit log_named_decimal_uint("decimal uint", 1.0e18, 18); 34 | 35 | emit log("-- log_named_decimal_int(string, int, uint)"); 36 | emit log_named_decimal_int("decimal int", -1.0e18, 18); 37 | } 38 | event log_old_named_uint(bytes32,uint); 39 | function test_old_logs() public { 40 | emit log_old_named_uint("key", 500); 41 | emit log_named_bytes32("bkey", "val"); 42 | } 43 | function test_trace() public view { 44 | this.echo("string 1", "string 2"); 45 | } 46 | function test_multiline() public { 47 | emit log("a multiline\\nstring"); 48 | emit log("a multiline string"); 49 | emit log_bytes("a string"); 50 | emit log_bytes("a multiline\nstring"); 51 | emit log_bytes("a multiline\\nstring"); 52 | emit logs(hex"0000"); 53 | emit log_named_bytes("0x0000", hex"0000"); 54 | emit logs(hex"ff"); 55 | } 56 | function echo(string memory s1, string memory s2) public pure 57 | returns (string memory, string memory) 58 | { 59 | return (s1, s2); 60 | } 61 | 62 | function prove_this(uint x) public { 63 | emit log_named_uint("sym x", x); 64 | assertGt(x + 1, 0); 65 | } 66 | 67 | function test_logn() public { 68 | assembly { 69 | log0(0x01, 0x02) 70 | log1(0x01, 0x02, 0x03) 71 | log2(0x01, 0x02, 0x03, 0x04) 72 | log3(0x01, 0x02, 0x03, 0x04, 0x05) 73 | } 74 | } 75 | 76 | event MyEvent(uint, uint indexed, uint, uint indexed); 77 | function test_events() public { 78 | emit MyEvent(1, 2, 3, 4); 79 | } 80 | 81 | function test_asserts() public { 82 | string memory err = "this test has failed!"; 83 | emit log("## assertTrue(bool)\n"); 84 | assertTrue(false); 85 | emit log("\n"); 86 | assertTrue(false, err); 87 | 88 | emit log("\n## assertEq(address,address)\n"); 89 | assertEq(address(this), msg.sender); 90 | emit log("\n"); 91 | assertEq(address(this), msg.sender, err); 92 | 93 | emit log("\n## assertEq32(bytes32,bytes32)\n"); 94 | assertEq32("bytes 1", "bytes 2"); 95 | emit log("\n"); 96 | assertEq32("bytes 1", "bytes 2", err); 97 | 98 | emit log("\n## assertEq(bytes32,bytes32)\n"); 99 | assertEq32("bytes 1", "bytes 2"); 100 | emit log("\n"); 101 | assertEq32("bytes 1", "bytes 2", err); 102 | 103 | emit log("\n## assertEq(uint,uint)\n"); 104 | assertEq(uint(0), 1); 105 | emit log("\n"); 106 | assertEq(uint(0), 1, err); 107 | 108 | emit log("\n## assertEq(int,int)\n"); 109 | assertEq(-1, -2); 110 | emit log("\n"); 111 | assertEq(-1, -2, err); 112 | 113 | emit log("\n## assertEqDecimal(int,int,uint)\n"); 114 | assertEqDecimal(-1.0e18, -1.1e18, 18); 115 | emit log("\n"); 116 | assertEqDecimal(-1.0e18, -1.1e18, 18, err); 117 | 118 | emit log("\n## assertEqDecimal(uint,uint,uint)\n"); 119 | assertEqDecimal(uint(1.0e18), 1.1e18, 18); 120 | emit log("\n"); 121 | assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); 122 | 123 | emit log("\n## assertGt(uint,uint)\n"); 124 | assertGt(uint(0), 0); 125 | emit log("\n"); 126 | assertGt(uint(0), 0, err); 127 | 128 | emit log("\n## assertGt(int,int)\n"); 129 | assertGt(-1, -1); 130 | emit log("\n"); 131 | assertGt(-1, -1, err); 132 | 133 | emit log("\n## assertGtDecimal(int,int,uint)\n"); 134 | assertGtDecimal(-2.0e18, -1.1e18, 18); 135 | emit log("\n"); 136 | assertGtDecimal(-2.0e18, -1.1e18, 18, err); 137 | 138 | emit log("\n## assertGtDecimal(uint,uint,uint)\n"); 139 | assertGtDecimal(uint(1.0e18), 1.1e18, 18); 140 | emit log("\n"); 141 | assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); 142 | 143 | emit log("\n## assertGe(uint,uint)\n"); 144 | assertGe(uint(0), 1); 145 | emit log("\n"); 146 | assertGe(uint(0), 1, err); 147 | 148 | emit log("\n## assertGe(int,int)\n"); 149 | assertGe(-1, 0); 150 | emit log("\n"); 151 | assertGe(-1, 0, err); 152 | 153 | emit log("\n## assertGeDecimal(int,int,uint)\n"); 154 | assertGeDecimal(-2.0e18, -1.1e18, 18); 155 | emit log("\n"); 156 | assertGeDecimal(-2.0e18, -1.1e18, 18, err); 157 | 158 | emit log("\n## assertGeDecimal(uint,uint,uint)\n"); 159 | assertGeDecimal(uint(1.0e18), 1.1e18, 18); 160 | emit log("\n"); 161 | assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); 162 | 163 | emit log("\n## assertLt(uint,uint)\n"); 164 | assertLt(uint(0), 0); 165 | emit log("\n"); 166 | assertLt(uint(0), 0, err); 167 | 168 | emit log("\n## assertLt(int,int)\n"); 169 | assertLt(-1, -1); 170 | emit log("\n"); 171 | assertLt(-1, -1, err); 172 | 173 | emit log("\n## assertLtDecimal(int,int,uint)\n"); 174 | assertLtDecimal(-1.0e18, -1.1e18, 18); 175 | emit log("\n"); 176 | assertLtDecimal(-1.0e18, -1.1e18, 18, err); 177 | 178 | emit log("\n## assertLtDecimal(uint,uint,uint)\n"); 179 | assertLtDecimal(uint(2.0e18), 1.1e18, 18); 180 | emit log("\n"); 181 | assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); 182 | 183 | emit log("\n## assertLe(uint,uint)\n"); 184 | assertLe(uint(1), 0); 185 | emit log("\n"); 186 | assertLe(uint(1), 0, err); 187 | 188 | emit log("\n## assertLe(int,int)\n"); 189 | assertLe(0, -1); 190 | emit log("\n"); 191 | assertLe(0, -1, err); 192 | 193 | emit log("\n## assertLeDecimal(int,int,uint)\n"); 194 | assertLeDecimal(-1.0e18, -1.1e18, 18); 195 | emit log("\n"); 196 | assertLeDecimal(-1.0e18, -1.1e18, 18, err); 197 | 198 | emit log("\n## assertLeDecimal(uint,uint,uint)\n"); 199 | assertLeDecimal(uint(2.0e18), 1.1e18, 18); 200 | emit log("\n"); 201 | assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); 202 | 203 | emit log("\n## assertEq(string,string)\n"); 204 | string memory s1 = "string 1"; 205 | string memory s2 = "string 2"; 206 | assertEq(s1, s2); 207 | emit log("\n"); 208 | assertEq(s1, s2, err); 209 | 210 | emit log("\n## assertEq0(bytes,bytes)\n"); 211 | assertEq0(hex"abcdef01", hex"abcdef02"); 212 | emit log("\n"); 213 | assertEq0(hex"abcdef01", hex"abcdef02", err); 214 | } 215 | } 216 | 217 | contract DemoTestWithSetUp { 218 | function setUp() public { 219 | } 220 | function test_pass() public pure { 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/src/Script.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity >=0.6.0 <0.9.0; 3 | 4 | import "./Vm.sol"; 5 | import "./console.sol"; 6 | import "./console2.sol"; 7 | 8 | abstract contract Script { 9 | bool public IS_SCRIPT = true; 10 | address constant private VM_ADDRESS = 11 | address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); 12 | 13 | Vm public constant vm = Vm(VM_ADDRESS); 14 | } 15 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/src/Vm.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity >=0.6.0; 3 | pragma experimental ABIEncoderV2; 4 | 5 | interface Vm { 6 | // Sets block.timestamp (newTimestamp) 7 | function warp(uint256) external; 8 | // Sets block.height (newHeight) 9 | function roll(uint256) external; 10 | // Sets block.basefee (newBasefee) 11 | function fee(uint256) external; 12 | // Sets block.chainid 13 | function chainId(uint256) external; 14 | // Loads a storage slot from an address (who, slot) 15 | function load(address,bytes32) external returns (bytes32); 16 | // Stores a value to an address' storage slot, (who, slot, value) 17 | function store(address,bytes32,bytes32) external; 18 | // Signs data, (privateKey, digest) => (v, r, s) 19 | function sign(uint256,bytes32) external returns (uint8,bytes32,bytes32); 20 | // Gets the address for a given private key, (privateKey) => (address) 21 | function addr(uint256) external returns (address); 22 | // Gets the nonce of an account 23 | function getNonce(address) external returns (uint64); 24 | // Sets the nonce of an account; must be higher than the current nonce of the account 25 | function setNonce(address, uint64) external; 26 | // Performs a foreign function call via the terminal, (stringInputs) => (result) 27 | function ffi(string[] calldata) external returns (bytes memory); 28 | // Sets environment variables, (name, value) 29 | function setEnv(string calldata, string calldata) external; 30 | // Reads environment variables, (name) => (value) 31 | function envBool(string calldata) external returns (bool); 32 | function envUint(string calldata) external returns (uint256); 33 | function envInt(string calldata) external returns (int256); 34 | function envAddress(string calldata) external returns (address); 35 | function envBytes32(string calldata) external returns (bytes32); 36 | function envString(string calldata) external returns (string memory); 37 | function envBytes(string calldata) external returns (bytes memory); 38 | // Reads environment variables as arrays, (name, delim) => (value[]) 39 | function envBool(string calldata, string calldata) external returns (bool[] memory); 40 | function envUint(string calldata, string calldata) external returns (uint256[] memory); 41 | function envInt(string calldata, string calldata) external returns (int256[] memory); 42 | function envAddress(string calldata, string calldata) external returns (address[] memory); 43 | function envBytes32(string calldata, string calldata) external returns (bytes32[] memory); 44 | function envString(string calldata, string calldata) external returns (string[] memory); 45 | function envBytes(string calldata, string calldata) external returns (bytes[] memory); 46 | // Sets the *next* call's msg.sender to be the input address 47 | function prank(address) external; 48 | // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called 49 | function startPrank(address) external; 50 | // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input 51 | function prank(address,address) external; 52 | // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input 53 | function startPrank(address,address) external; 54 | // Resets subsequent calls' msg.sender to be `address(this)` 55 | function stopPrank() external; 56 | // Sets an address' balance, (who, newBalance) 57 | function deal(address, uint256) external; 58 | // Sets an address' code, (who, newCode) 59 | function etch(address, bytes calldata) external; 60 | // Expects an error on next call 61 | function expectRevert(bytes calldata) external; 62 | function expectRevert(bytes4) external; 63 | function expectRevert() external; 64 | // Records all storage reads and writes 65 | function record() external; 66 | // Gets all accessed reads and write slot from a recording session, for a given address 67 | function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes); 68 | // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). 69 | // Call this function, then emit an event, then call a function. Internally after the call, we check if 70 | // logs were emitted in the expected order with the expected topics and data (as specified by the booleans) 71 | function expectEmit(bool,bool,bool,bool) external; 72 | function expectEmit(bool,bool,bool,bool,address) external; 73 | // Mocks a call to an address, returning specified data. 74 | // Calldata can either be strict or a partial match, e.g. if you only 75 | // pass a Solidity selector to the expected calldata, then the entire Solidity 76 | // function will be mocked. 77 | function mockCall(address,bytes calldata,bytes calldata) external; 78 | // Mocks a call to an address with a specific msg.value, returning specified data. 79 | // Calldata match takes precedence over msg.value in case of ambiguity. 80 | function mockCall(address,uint256,bytes calldata,bytes calldata) external; 81 | // Clears all mocked calls 82 | function clearMockedCalls() external; 83 | // Expects a call to an address with the specified calldata. 84 | // Calldata can either be a strict or a partial match 85 | function expectCall(address,bytes calldata) external; 86 | // Expects a call to an address with the specified msg.value and calldata 87 | function expectCall(address,uint256,bytes calldata) external; 88 | // Gets the code from an artifact file. Takes in the relative path to the json file 89 | function getCode(string calldata) external returns (bytes memory); 90 | // Labels an address in call traces 91 | function label(address, string calldata) external; 92 | // If the condition is false, discard this run's fuzz inputs and generate new ones 93 | function assume(bool) external; 94 | // Sets block.coinbase (who) 95 | function coinbase(address) external; 96 | // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain 97 | function broadcast() external; 98 | // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain 99 | function broadcast(address) external; 100 | // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain 101 | function startBroadcast() external; 102 | // Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain 103 | function startBroadcast(address) external; 104 | // Stops collecting onchain transactions 105 | function stopBroadcast() external; 106 | } 107 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/src/test/StdCheats.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity >=0.7.0 <0.9.0; 3 | 4 | import "../Test.sol"; 5 | 6 | contract StdCheatsTest is Test { 7 | Bar test; 8 | 9 | function setUp() public { 10 | test = new Bar(); 11 | } 12 | 13 | function testSkip() public { 14 | vm.warp(100); 15 | skip(25); 16 | assertEq(block.timestamp, 125); 17 | } 18 | 19 | function testRewind() public { 20 | vm.warp(100); 21 | rewind(25); 22 | assertEq(block.timestamp, 75); 23 | } 24 | 25 | function testHoax() public { 26 | hoax(address(1337)); 27 | test.bar{value: 100}(address(1337)); 28 | } 29 | 30 | function testHoaxOrigin() public { 31 | hoax(address(1337), address(1337)); 32 | test.origin{value: 100}(address(1337)); 33 | } 34 | 35 | function testHoaxDifferentAddresses() public { 36 | hoax(address(1337), address(7331)); 37 | test.origin{value: 100}(address(1337), address(7331)); 38 | } 39 | 40 | function testStartHoax() public { 41 | startHoax(address(1337)); 42 | test.bar{value: 100}(address(1337)); 43 | test.bar{value: 100}(address(1337)); 44 | vm.stopPrank(); 45 | test.bar(address(this)); 46 | } 47 | 48 | function testStartHoaxOrigin() public { 49 | startHoax(address(1337), address(1337)); 50 | test.origin{value: 100}(address(1337)); 51 | test.origin{value: 100}(address(1337)); 52 | vm.stopPrank(); 53 | test.bar(address(this)); 54 | } 55 | 56 | function testChangePrank() public { 57 | vm.startPrank(address(1337)); 58 | test.bar(address(1337)); 59 | changePrank(address(0xdead)); 60 | test.bar(address(0xdead)); 61 | changePrank(address(1337)); 62 | test.bar(address(1337)); 63 | vm.stopPrank(); 64 | } 65 | 66 | function testDeal() public { 67 | deal(address(this), 1 ether); 68 | assertEq(address(this).balance, 1 ether); 69 | } 70 | 71 | function testDealToken() public { 72 | Bar barToken = new Bar(); 73 | address bar = address(barToken); 74 | deal(bar, address(this), 10000e18); 75 | assertEq(barToken.balanceOf(address(this)), 10000e18); 76 | } 77 | 78 | function testDealTokenAdjustTS() public { 79 | Bar barToken = new Bar(); 80 | address bar = address(barToken); 81 | deal(bar, address(this), 10000e18, true); 82 | assertEq(barToken.balanceOf(address(this)), 10000e18); 83 | assertEq(barToken.totalSupply(), 20000e18); 84 | deal(bar, address(this), 0, true); 85 | assertEq(barToken.balanceOf(address(this)), 0); 86 | assertEq(barToken.totalSupply(), 10000e18); 87 | } 88 | 89 | function testBound() public { 90 | assertEq(bound(5, 0, 4), 0); 91 | assertEq(bound(0, 69, 69), 69); 92 | assertEq(bound(0, 68, 69), 68); 93 | assertEq(bound(10, 150, 190), 160); 94 | assertEq(bound(300, 2800, 3200), 3100); 95 | assertEq(bound(9999, 1337, 6666), 6006); 96 | } 97 | 98 | function testCannotBoundMaxLessThanMin() public { 99 | vm.expectRevert(bytes("Test bound(uint256,uint256,uint256): Max is less than min.")); 100 | bound(5, 100, 10); 101 | } 102 | 103 | function testBound( 104 | uint256 num, 105 | uint256 min, 106 | uint256 max 107 | ) public { 108 | if (min > max) (min, max) = (max, min); 109 | 110 | uint256 bounded = bound(num, min, max); 111 | 112 | assertGe(bounded, min); 113 | assertLe(bounded, max); 114 | } 115 | 116 | function testBoundUint256Max() public { 117 | assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); 118 | assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); 119 | } 120 | 121 | function testCannotBoundMaxLessThanMin( 122 | uint256 num, 123 | uint256 min, 124 | uint256 max 125 | ) public { 126 | vm.assume(min > max); 127 | vm.expectRevert(bytes("Test bound(uint256,uint256,uint256): Max is less than min.")); 128 | bound(num, min, max); 129 | } 130 | 131 | function testDeployCode() public { 132 | address deployed = deployCode("StdCheats.t.sol:StdCheatsTest", bytes("")); 133 | assertEq(string(getCode(deployed)), string(getCode(address(this)))); 134 | } 135 | 136 | function testDeployCodeNoArgs() public { 137 | address deployed = deployCode("StdCheats.t.sol:StdCheatsTest"); 138 | assertEq(string(getCode(deployed)), string(getCode(address(this)))); 139 | } 140 | 141 | function testDeployCodeFail() public { 142 | vm.expectRevert(bytes("Test deployCode(string): Deployment failed.")); 143 | this.deployCode("StdCheats.t.sol:RevertingContract"); 144 | } 145 | 146 | function getCode(address who) internal view returns (bytes memory o_code) { 147 | /// @solidity memory-safe-assembly 148 | assembly { 149 | // retrieve the size of the code, this needs assembly 150 | let size := extcodesize(who) 151 | // allocate output byte array - this could also be done without assembly 152 | // by using o_code = new bytes(size) 153 | o_code := mload(0x40) 154 | // new "memory end" including padding 155 | mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) 156 | // store length in memory 157 | mstore(o_code, size) 158 | // actually retrieve the code, this needs assembly 159 | extcodecopy(who, add(o_code, 0x20), 0, size) 160 | } 161 | } 162 | } 163 | 164 | contract Bar { 165 | constructor() { 166 | /// `DEAL` STDCHEAT 167 | totalSupply = 10000e18; 168 | balanceOf[address(this)] = totalSupply; 169 | } 170 | 171 | /// `HOAX` STDCHEATS 172 | function bar(address expectedSender) public payable { 173 | require(msg.sender == expectedSender, "!prank"); 174 | } 175 | function origin(address expectedSender) public payable { 176 | require(msg.sender == expectedSender, "!prank"); 177 | require(tx.origin == expectedSender, "!prank"); 178 | } 179 | function origin(address expectedSender, address expectedOrigin) public payable { 180 | require(msg.sender == expectedSender, "!prank"); 181 | require(tx.origin == expectedOrigin, "!prank"); 182 | } 183 | 184 | /// `DEAL` STDCHEAT 185 | mapping (address => uint256) public balanceOf; 186 | uint256 public totalSupply; 187 | } 188 | 189 | contract RevertingContract { 190 | constructor() { 191 | revert(); 192 | } 193 | } -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/lib/forge-std/src/test/StdError.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Unlicense 2 | pragma solidity >=0.8.10 <0.9.0; 3 | 4 | import "../Test.sol"; 5 | 6 | contract StdErrorsTest is Test { 7 | ErrorsTest test; 8 | 9 | function setUp() public { 10 | test = new ErrorsTest(); 11 | } 12 | 13 | function testExpectAssertion() public { 14 | vm.expectRevert(stdError.assertionError); 15 | test.assertionError(); 16 | } 17 | 18 | function testExpectArithmetic() public { 19 | vm.expectRevert(stdError.arithmeticError); 20 | test.arithmeticError(10); 21 | } 22 | 23 | function testExpectDiv() public { 24 | vm.expectRevert(stdError.divisionError); 25 | test.divError(0); 26 | } 27 | 28 | function testExpectMod() public { 29 | vm.expectRevert(stdError.divisionError); 30 | test.modError(0); 31 | } 32 | 33 | function testExpectEnum() public { 34 | vm.expectRevert(stdError.enumConversionError); 35 | test.enumConversion(1); 36 | } 37 | 38 | function testExpectEncodeStg() public { 39 | vm.expectRevert(stdError.encodeStorageError); 40 | test.encodeStgError(); 41 | } 42 | 43 | function testExpectPop() public { 44 | vm.expectRevert(stdError.popError); 45 | test.pop(); 46 | } 47 | 48 | function testExpectOOB() public { 49 | vm.expectRevert(stdError.indexOOBError); 50 | test.indexOOBError(1); 51 | } 52 | 53 | function testExpectMem() public { 54 | vm.expectRevert(stdError.memOverflowError); 55 | test.mem(); 56 | } 57 | 58 | function testExpectIntern() public { 59 | vm.expectRevert(stdError.zeroVarError); 60 | test.intern(); 61 | } 62 | 63 | function testExpectLowLvl() public { 64 | vm.expectRevert(stdError.lowLevelError); 65 | test.someArr(0); 66 | } 67 | } 68 | 69 | contract ErrorsTest { 70 | enum T { 71 | T1 72 | } 73 | 74 | uint256[] public someArr; 75 | bytes someBytes; 76 | 77 | function assertionError() public pure { 78 | assert(false); 79 | } 80 | 81 | function arithmeticError(uint256 a) public pure { 82 | a -= 100; 83 | } 84 | 85 | function divError(uint256 a) public pure { 86 | 100 / a; 87 | } 88 | 89 | function modError(uint256 a) public pure { 90 | 100 % a; 91 | } 92 | 93 | function enumConversion(uint256 a) public pure { 94 | T(a); 95 | } 96 | 97 | function encodeStgError() public { 98 | /// @solidity memory-safe-assembly 99 | assembly { 100 | sstore(someBytes.slot, 1) 101 | } 102 | keccak256(someBytes); 103 | } 104 | 105 | function pop() public { 106 | someArr.pop(); 107 | } 108 | 109 | function indexOOBError(uint256 a) public pure { 110 | uint256[] memory t = new uint256[](0); 111 | t[a]; 112 | } 113 | 114 | function mem() public pure { 115 | uint256 l = 2**256 / 32; 116 | new uint256[](l); 117 | } 118 | 119 | function intern() public returns (uint256) { 120 | function(uint256) internal returns (uint256) x; 121 | x(2); 122 | return 7; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "chain": "anvil", 8 | "compile": "forge build", 9 | "test": "forge test", 10 | "clean": "forge clean", 11 | "gas": "forge test --gas-report" 12 | }, 13 | "devDependencies": {}, 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/foundry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "chain": "anvil", 8 | "compile": "forge build", 9 | "test": "forge test", 10 | "clean": "forge clean", 11 | "gas": "forge test --gas-report" 12 | }, 13 | "devDependencies": {}, 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/script/Greeter.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import '../lib/forge-std/src/Script.sol'; 5 | import {Greeter} from '../src/Greeter.sol'; 6 | 7 | contract GreeterScript is Script { 8 | function setUp() public {} 9 | 10 | function run() public { 11 | vm.broadcast(); 12 | new Greeter('Hello from Foundry!'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/src/Greeter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | contract Greeter { 5 | string private greeting; 6 | 7 | constructor(string memory _greeting) { 8 | greeting = _greeting; 9 | } 10 | 11 | function greet() public view returns (string memory) { 12 | return greeting; 13 | } 14 | 15 | function setGreeting(string memory _greeting) public { 16 | greeting = _greeting; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/create-web3/templates/foundry/test/Greeter.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import '../lib/forge-std/src/Test.sol'; 5 | import {Greeter} from '../src/Greeter.sol'; 6 | 7 | contract GreeterTest is Test { 8 | Greeter greeter; 9 | 10 | function setUp() public { 11 | greeter = new Greeter('Hello, world!'); 12 | } 13 | 14 | function testGreet() public { 15 | assertEq(greeter.greet(), 'Hello, world!'); 16 | } 17 | 18 | function testSetGreeting() public { 19 | greeter.setGreeting('Hello, universe!'); 20 | assertEq(greeter.greet(), 'Hello, universe!'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | contract Greeter { 7 | string private greeting; 8 | 9 | constructor(string memory _greeting) { 10 | console.log("Greeter with greeting:", _greeting); 11 | greeting = _greeting; 12 | } 13 | 14 | function greet() public view returns (string memory) { 15 | return greeting; 16 | } 17 | 18 | function setGreeting(string memory _greeting) public { 19 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 20 | greeting = _greeting; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/deploy/00_deploy_contract.js: -------------------------------------------------------------------------------- 1 | // deploy/00_deploy_contract 2 | 3 | module.exports = async ({ getNamedAccounts, deployments }) => { 4 | const { deploy } = deployments; 5 | const { deployer } = await getNamedAccounts(); 6 | 7 | const args = ['Hello!!!!!!!!']; 8 | await deploy('Greeter', { 9 | // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy 10 | args: args, 11 | from: deployer, 12 | log: true, 13 | }); 14 | }; 15 | module.exports.tags = ['all', 'greeter']; 16 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require('@nomiclabs/hardhat-waffle'); 2 | require('dotenv').config({ path: '../../.env' }); 3 | 4 | require('hardhat-deploy'); 5 | require('@nomiclabs/hardhat-ethers'); 6 | require('@nomiclabs/hardhat-etherscan'); 7 | 8 | const defaultNetwork = 'localhost'; 9 | 10 | /** 11 | * @type import('hardhat/config').HardhatUserConfig 12 | */ 13 | module.exports = { 14 | solidity: '0.8.10', 15 | 16 | defaultNetwork, 17 | 18 | networks: { 19 | localhost: { 20 | chainId: 31337, 21 | }, 22 | 23 | ///////// 24 | // L1 NETWORKS 25 | ///////// 26 | 27 | // mainnet: { 28 | // chainId: 1, 29 | // url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 30 | // url: `https://mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 31 | // accounts: [`${process.env.PRIVATE_KEY}`], 32 | // }, 33 | 34 | // L1 TEST NETWORKS 35 | 36 | // ropsten: { 37 | // chainId: 3, 38 | // url: `https://eth-ropsten.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 39 | // url: `https://ropsten.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 40 | // accounts: [`${process.env.PRIVATE_KEY}`], 41 | // }, 42 | // rinkeby: { 43 | // chainId: 4, 44 | // url: `https://eth-rinkeby.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 45 | // url: `https://rinkeby.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 46 | // accounts: [`${process.env.PRIVATE_KEY}`], 47 | // }, 48 | // goerli: { 49 | // chainId: 5, 50 | // url: `https://eth-goerli.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 51 | // url: `https://goerli.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 52 | // accounts: [`${process.env.PRIVATE_KEY}`], 53 | // }, 54 | // kovan: { 55 | // chainId: 42, 56 | // url: `https://eth-kovan.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 57 | // url: `https://kovan.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 58 | // accounts: [`${process.env.PRIVATE_KEY}`], 59 | // }, 60 | 61 | ///////// 62 | // L2 NETWORKS 63 | ///////// 64 | 65 | // polygon: { 66 | // chainId: 137, 67 | // url: `https://polygon-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 68 | // url: `https://polygon-mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 69 | // accounts: [`${process.env.PRIVATE_KEY}`], 70 | // }, 71 | 72 | // L2 TEST NETWORKS 73 | 74 | // mumbai: { 75 | // chainId: 80001, 76 | // url: `https://polygon-mumbai.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 77 | // url: `https://polygon-mumbai.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 78 | // accounts: [`${process.env.PRIVATE_KEY}`], 79 | // }, 80 | }, 81 | namedAccounts: { 82 | deployer: { 83 | default: 0, // here this will by default take the first account as deployer 84 | }, 85 | tokenOwner: 1, 86 | etherscan: { 87 | apiKey: process.env.ETHERSCAN_API_KEY, 88 | }, 89 | }, 90 | }; 91 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "chain": "hardhat node --network hardhat --no-deploy", 8 | "clean": "npx hardhat clean", 9 | "deploy": "hardhat deploy --export-all ../frontend/contracts/hardhat_contracts.json", 10 | "compile": "hardhat compile", 11 | "test": "hardhat test" 12 | }, 13 | "devDependencies": { 14 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.10", 15 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 16 | "@nomiclabs/hardhat-waffle": "^2.0.3", 17 | "@openzeppelin/contracts": "^4.6.0", 18 | "chai": "^4.3.6", 19 | "ethereum-waffle": "^4.0.9", 20 | "ethers": "^5.7.2", 21 | "hardhat": "^2.12.6", 22 | "hardhat-deploy": "^0.11.23" 23 | }, 24 | "dependencies": { 25 | "dotenv": "^16.0.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/hardhat", 3 | "version": "1.0.0", 4 | "description": "mono repo with hardhat and next", 5 | "private": true, 6 | "scripts": { 7 | "chain": "hardhat node --network hardhat --no-deploy", 8 | "clean": "npx hardhat clean", 9 | "deploy": "hardhat deploy --export-all ../../vite/typescript/contracts/hardhat_contracts.json", 10 | "compile": "hardhat compile", 11 | "test": "hardhat test" 12 | }, 13 | "devDependencies": { 14 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.10", 15 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 16 | "@nomiclabs/hardhat-waffle": "^2.0.3", 17 | "@openzeppelin/contracts": "^4.6.0", 18 | "chai": "^4.3.6", 19 | "ethereum-waffle": "^4.0.9", 20 | "ethers": "^5.7.2", 21 | "hardhat": "^2.12.6", 22 | "hardhat-deploy": "^0.11.23" 23 | }, 24 | "dependencies": { 25 | "dotenv": "^16.0.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/default/test/sample-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | const { ethers } = require('hardhat'); 3 | 4 | describe('Greeter', function () { 5 | it("Should return the new greeting once it's changed", async function () { 6 | const Greeter = await ethers.getContractFactory('Greeter'); 7 | const greeter = await Greeter.deploy('Hello, world!'); 8 | await greeter.deployed(); 9 | 10 | expect(await greeter.greet()).to.equal('Hello, world!'); 11 | 12 | const setGreetingTx = await greeter.setGreeting('Hola, mundo!'); 13 | 14 | // wait until the transaction is mined 15 | await setGreetingTx.wait(); 16 | 17 | expect(await greeter.greet()).to.equal('Hola, mundo!'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | contract Greeter { 7 | string private greeting; 8 | 9 | constructor(string memory _greeting) { 10 | console.log("Deploying a Greeter with greeting:", _greeting); 11 | greeting = _greeting; 12 | } 13 | 14 | function greet() public view returns (string memory) { 15 | return greeting; 16 | } 17 | 18 | function setGreeting(string memory _greeting) public { 19 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 20 | greeting = _greeting; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/deploy/00_deploy_contract.ts: -------------------------------------------------------------------------------- 1 | import {HardhatRuntimeEnvironment} from 'hardhat/types'; 2 | import {DeployFunction} from 'hardhat-deploy/types'; 3 | 4 | const main: DeployFunction = async function ({getNamedAccounts, deployments}: HardhatRuntimeEnvironment) { 5 | const { deploy } = deployments; 6 | const { deployer } = await getNamedAccounts(); 7 | 8 | const args = ['Hello!!!!!!!!']; 9 | await deploy('Greeter', { 10 | // Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy 11 | args: args, 12 | from: deployer, 13 | log: true, 14 | }); 15 | }; 16 | 17 | export default main; 18 | 19 | export const tags = ['all', 'greeter']; 20 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import '@nomiclabs/hardhat-waffle'; 2 | import * as dotenv from 'dotenv'; 3 | import { HardhatUserConfig } from 'hardhat/config'; 4 | import 'hardhat-deploy'; 5 | import '@nomiclabs/hardhat-ethers'; 6 | import '@nomiclabs/hardhat-etherscan'; 7 | 8 | dotenv.config({ path: '../../.env' }); 9 | const defaultNetwork = 'localhost'; 10 | 11 | /** 12 | * @type import('hardhat/config').HardhatUserConfig 13 | */ 14 | const config: HardhatUserConfig = { 15 | solidity: '0.8.10', 16 | defaultNetwork, 17 | 18 | networks: { 19 | localhost: { 20 | chainId: 31337, 21 | }, 22 | 23 | ///////// 24 | // L1 NETWORKS 25 | ///////// 26 | 27 | // mainnet: { 28 | // chainId: 1, 29 | // url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 30 | // url: `https://mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 31 | // accounts: [`${process.env.PRIVATE_KEY}`], 32 | // }, 33 | 34 | // L1 TEST NETWORKS 35 | 36 | // ropsten: { 37 | // chainId: 3, 38 | // url: `https://eth-ropsten.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 39 | // url: `https://ropsten.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 40 | // accounts: [`${process.env.PRIVATE_KEY}`], 41 | // }, 42 | // rinkeby: { 43 | // chainId: 4, 44 | // url: `https://eth-rinkeby.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 45 | // url: `https://rinkeby.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 46 | // accounts: [`${process.env.PRIVATE_KEY}`], 47 | // }, 48 | // goerli: { 49 | // chainId: 5, 50 | // url: `https://eth-goerli.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 51 | // url: `https://goerli.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 52 | // accounts: [`${process.env.PRIVATE_KEY}`], 53 | // }, 54 | // kovan: { 55 | // chainId: 42, 56 | // url: `https://eth-kovan.alchemyapi.io/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 57 | // url: `https://kovan.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 58 | // accounts: [`${process.env.PRIVATE_KEY}`], 59 | // }, 60 | 61 | ///////// 62 | // L2 NETWORKS 63 | ///////// 64 | 65 | // polygon: { 66 | // chainId: 137, 67 | // url: `https://polygon-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 68 | // url: `https://polygon-mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 69 | // accounts: [`${process.env.PRIVATE_KEY}`], 70 | // }, 71 | 72 | // L2 TEST NETWORKS 73 | 74 | // mumbai: { 75 | // chainId: 80001, 76 | // url: `https://polygon-mumbai.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_ID}`, 77 | // url: `https://polygon-mumbai.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_ID}`, 78 | // accounts: [`${process.env.PRIVATE_KEY}`], 79 | // }, 80 | }, 81 | namedAccounts: { 82 | deployer: { 83 | default: 0, // here this will by default take the first account as deployer 84 | }, 85 | tokenOwner: 1, 86 | etherscan: { 87 | apiKey: process.env.ETHERSCAN_API_KEY as string, 88 | }, 89 | }, 90 | }; 91 | 92 | export default config; 93 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "chain": "hardhat node --network hardhat --no-deploy", 8 | "clean": "npx hardhat clean", 9 | "deploy": "hardhat deploy --export-all ../frontend/contracts/hardhat_contracts.json", 10 | "compile": "hardhat compile", 11 | "test": "hardhat test" 12 | }, 13 | "devDependencies": { 14 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.10", 15 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 16 | "@nomiclabs/hardhat-waffle": "^2.0.3", 17 | "@openzeppelin/contracts": "^4.6.0", 18 | "@types/chai": "^4.3.1", 19 | "@types/mocha": "^9.1.1", 20 | "@types/node": "^18.11.18", 21 | "chai": "^4.3.6", 22 | "ethereum-waffle": "^4.0.9", 23 | "ethers": "^5.7.2", 24 | "hardhat": "^2.12.6", 25 | "hardhat-deploy": "^0.11.23", 26 | "ts-node": "^10.8.1", 27 | "typescript": "^4.9.5" 28 | }, 29 | "dependencies": { 30 | "dotenv": "^16.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/hardhat-ts", 3 | "version": "1.0.0", 4 | "description": "mono repo with hardhat and next", 5 | "private": true, 6 | "scripts": { 7 | "chain": "hardhat node --network hardhat --no-deploy", 8 | "clean": "npx hardhat clean", 9 | "deploy": "hardhat deploy --export-all ../next-app/contracts/hardhat_contracts.json", 10 | "compile": "hardhat compile", 11 | "test": "hardhat test" 12 | }, 13 | "devDependencies": { 14 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.10", 15 | "@nomiclabs/hardhat-etherscan": "^3.0.3", 16 | "@nomiclabs/hardhat-waffle": "^2.0.3", 17 | "@openzeppelin/contracts": "^4.6.0", 18 | "@types/chai": "^4.3.1", 19 | "@types/mocha": "^9.1.1", 20 | "@types/node": "^18.11.18", 21 | "chai": "^4.3.6", 22 | "ethereum-waffle": "^4.0.9", 23 | "ethers": "^5.7.2", 24 | "hardhat": "^2.12.6", 25 | "hardhat-deploy": "^0.11.23", 26 | "ts-node": "^10.8.1", 27 | "typescript": "^4.9.5" 28 | }, 29 | "dependencies": { 30 | "dotenv": "^16.0.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/test/index.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { ethers } from "hardhat"; 3 | 4 | describe("Greeter", function () { 5 | it("Should return the new greeting once it's changed", async function () { 6 | const Greeter = await ethers.getContractFactory("Greeter"); 7 | const greeter = await Greeter.deploy("Hello, world!"); 8 | await greeter.deployed(); 9 | 10 | expect(await greeter.greet()).to.equal("Hello, world!"); 11 | 12 | const setGreetingTx = await greeter.setGreeting("Hola, mundo!"); 13 | 14 | // wait until the transaction is mined 15 | await setGreetingTx.wait(); 16 | 17 | expect(await greeter.greet()).to.equal("Hola, mundo!"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/create-web3/templates/hardhat/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "declaration": true 9 | }, 10 | "include": ["./scripts", "./deploy", "./test"], 11 | "files": ["./hardhat.config.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/components/contract/GetGreeter.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useCallback } from 'react'; 2 | import { useContract, useProvider } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../../config'; 6 | 7 | export const GetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [currentGreeter, setCurrentGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const provider = useProvider(); 14 | 15 | const allContracts = contracts; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: provider, 23 | }); 24 | 25 | const fetchData = useCallback(async () => { 26 | try { 27 | const greeter = await greeterContract.greet(); 28 | setCurrentGreeter(greeter); 29 | setError(''); 30 | } catch (error) { 31 | setError("Contract couldn't be fetched. Please check your network."); 32 | } 33 | setLoading(false); 34 | }, [greeterContract]); 35 | 36 | useEffect(() => { 37 | if (provider) { 38 | fetchData(); 39 | } 40 | }, [provider, greeterContract, fetchData]); 41 | 42 | if (loading) { 43 | return
Loading...
; 44 | } 45 | 46 | if (error) { 47 | return
{error}
; 48 | } 49 | 50 | return ( 51 |
52 | current greeting : {currentGreeter} 53 | 56 |
57 | ); 58 | }; 59 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/components/contract/SetGreeter.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useContract, useSigner } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../../config'; 6 | 7 | export const SetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [newGreeter, setNewGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const { data: signerData } = useSigner(); 14 | 15 | const allContracts = contracts; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: signerData, 23 | }); 24 | 25 | useEffect(() => { 26 | if (signerData) { 27 | setError(''); 28 | setLoading(false); 29 | } else { 30 | setLoading(false); 31 | setError('please connect your wallet'); 32 | } 33 | }, [signerData]); 34 | 35 | const handleSubmit = async (e) => { 36 | e.preventDefault(); 37 | try { 38 | setLoading(true); 39 | const tx = await greeterContract.setGreeting(newGreeter); 40 | await tx.wait(); 41 | setNewGreeter(''); 42 | setLoading(false); 43 | } catch (error) { 44 | setError('txn failed, check contract'); 45 | setLoading(false); 46 | } 47 | }; 48 | 49 | if (loading) { 50 | return
Loading...
; 51 | } 52 | 53 | if (error) { 54 | return
{error}
; 55 | } 56 | 57 | return ( 58 |
59 |
handleSubmit(e)}> 60 | setNewGreeter(e.target.value)} 65 | /> 66 | 69 |
70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/components/contract/index.js: -------------------------------------------------------------------------------- 1 | export { GetGreeter } from './GetGreeter'; 2 | export { SetGreeter } from './SetGreeter'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/config.js: -------------------------------------------------------------------------------- 1 | export const NETWORK_ID = 31337; 2 | export const NETWORK_NAME = 'localhost'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/contracts/hardhat_contracts.json: -------------------------------------------------------------------------------- 1 | { 2 | "31337": [ 3 | { 4 | "name": "localhost", 5 | "chainId": "31337", 6 | "contracts": { 7 | "Greeter": { 8 | "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", 9 | "abi": [ 10 | { 11 | "inputs": [ 12 | { 13 | "internalType": "string", 14 | "name": "_greeting", 15 | "type": "string" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "constructor" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "greet", 24 | "outputs": [ 25 | { 26 | "internalType": "string", 27 | "name": "", 28 | "type": "string" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "string", 38 | "name": "_greeting", 39 | "type": "string" 40 | } 41 | ], 42 | "name": "setGreeting", 43 | "outputs": [], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/hooks/index.js: -------------------------------------------------------------------------------- 1 | export { useIsMounted } from "./useIsMounted"; 2 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/hooks/useIsMounted.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export const useIsMounted = () => { 4 | const [mounted, setMounted] = React.useState(false); 5 | 6 | React.useEffect(() => setMounted(true), []); 7 | 8 | return mounted; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@rainbow-me/rainbowkit": "^0.8.1", 14 | "ethers": "^5.7.2", 15 | "next": "^13.1.6", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^8.27.0", 22 | "eslint-config-next": "^13.0.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/next", 3 | "version": "0.1.0", 4 | "description": "mono repo with hardhat and next", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@rainbow-me/rainbowkit": "^0.8.1", 14 | "ethers": "^5.7.2", 15 | "next": "^13.1.6", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "eslint": "^8.27.0", 22 | "eslint-config-next": "^13.0.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/pages/_app.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import NextHead from 'next/head'; 3 | import '../styles/globals.css'; 4 | 5 | // Imports 6 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 7 | import { 8 | mainnet, 9 | polygon, 10 | polygonMumbai, 11 | optimism, 12 | arbitrum, 13 | hardhat, 14 | } from 'wagmi/chains'; 15 | import { publicProvider } from 'wagmi/providers/public'; 16 | 17 | import '@rainbow-me/rainbowkit/styles.css'; 18 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 19 | 20 | import { useIsMounted } from '../hooks'; 21 | 22 | const { chains, provider, webSocketProvider } = configureChains( 23 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 24 | [publicProvider()] 25 | ); 26 | 27 | const { connectors } = getDefaultWallets({ 28 | appName: 'create-web3', 29 | chains, 30 | }); 31 | 32 | const wagmiClient = createClient({ 33 | autoConnect: true, 34 | connectors, 35 | provider, 36 | webSocketProvider, 37 | }); 38 | 39 | const App = ({ Component, pageProps }) => { 40 | const isMounted = useIsMounted(); 41 | 42 | if (!isMounted) return null; 43 | return ( 44 | 45 | 46 | 47 | create-web3 48 | 49 | 50 | 51 | 52 | ); 53 | }; 54 | 55 | export default App; 56 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default function handler(req, res) { 4 | res.status(200).json({ name: 'John Doe' }) 5 | } 6 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/pages/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | 3 | import { ConnectButton } from '@rainbow-me/rainbowkit'; 4 | import { GetGreeter, SetGreeter } from '../components/contract'; 5 | 6 | export default function Home() { 7 | return ( 8 |
9 | 10 | Create-Web3 App 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 |
29 | 30 | 31 |
32 |
33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/packages/create-web3/templates/next/default/public/favicon.ico -------------------------------------------------------------------------------- /packages/create-web3/templates/next/default/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | 18 | button { 19 | cursor: pointer; 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/components/contract/GetGreeter.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useCallback } from 'react'; 2 | import { useContract, useProvider } from 'wagmi'; 3 | 4 | import contracts from '@/contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '@/config'; 6 | 7 | export const GetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [currentGreeter, setCurrentGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const provider = useProvider(); 14 | 15 | const allContracts = contracts as any; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: provider, 23 | }); 24 | 25 | const fetchData = useCallback(async () => { 26 | try { 27 | const greeter = await greeterContract?.greet(); 28 | setCurrentGreeter(greeter); 29 | setError(''); 30 | } catch (error) { 31 | setError("Contract couldn't be fetched. Please check your network."); 32 | } 33 | setLoading(false); 34 | }, [greeterContract]); 35 | 36 | useEffect(() => { 37 | if (provider) { 38 | fetchData(); 39 | } 40 | }, [provider, greeterContract, fetchData]); 41 | 42 | if (loading) { 43 | return
Loading...
; 44 | } 45 | 46 | if (error) { 47 | return
{error}
; 48 | } 49 | 50 | return ( 51 |
52 | current greeting : {currentGreeter} 53 | 56 |
57 | ); 58 | }; 59 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/components/contract/SetGreeter.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, FormEvent } from 'react'; 2 | import { useContract, useSigner } from 'wagmi'; 3 | 4 | import contracts from '@/contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '@/config'; 6 | 7 | export const SetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [newGreeter, setNewGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const { data: signerData } = useSigner(); 14 | 15 | const allContracts = contracts as any; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: signerData, 23 | }); 24 | 25 | useEffect(() => { 26 | if (signerData) { 27 | setError(''); 28 | setLoading(false); 29 | } else { 30 | setLoading(false); 31 | setError('please connect your wallet'); 32 | } 33 | }, [signerData]); 34 | 35 | const handleSubmit = async (e: FormEvent) => { 36 | e.preventDefault(); 37 | try { 38 | setLoading(true); 39 | const tx = await greeterContract?.setGreeting(newGreeter); 40 | await tx.wait(); 41 | setNewGreeter(''); 42 | setLoading(false); 43 | } catch (error) { 44 | setError('txn failed, check contract'); 45 | setLoading(false); 46 | } 47 | }; 48 | 49 | if (loading) { 50 | return
Loading...
; 51 | } 52 | 53 | if (error) { 54 | return
{error}
; 55 | } 56 | 57 | return ( 58 |
59 |
handleSubmit(e)}> 60 | setNewGreeter(e.target.value)} 65 | /> 66 | 69 |
70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/components/contract/index.ts: -------------------------------------------------------------------------------- 1 | export { GetGreeter } from './GetGreeter'; 2 | export { SetGreeter } from './SetGreeter'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/config.ts: -------------------------------------------------------------------------------- 1 | export const NETWORK_ID = 31337 as number; 2 | export const NETWORK_NAME = 'localhost' as string; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/contracts/hardhat_contracts.json: -------------------------------------------------------------------------------- 1 | { 2 | "31337": [ 3 | { 4 | "name": "localhost", 5 | "chainId": "31337", 6 | "contracts": { 7 | "Greeter": { 8 | "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", 9 | "abi": [ 10 | { 11 | "inputs": [ 12 | { 13 | "internalType": "string", 14 | "name": "_greeting", 15 | "type": "string" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "constructor" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "greet", 24 | "outputs": [ 25 | { 26 | "internalType": "string", 27 | "name": "", 28 | "type": "string" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "string", 38 | "name": "_greeting", 39 | "type": "string" 40 | } 41 | ], 42 | "name": "setGreeting", 43 | "outputs": [], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { useIsMounted } from './useIsMounted'; 2 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/hooks/useIsMounted.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const useIsMounted = () => { 4 | const [mounted, setMounted] = React.useState(false); 5 | 6 | React.useEffect(() => setMounted(true), []); 7 | 8 | return mounted; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "version": "0.1.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "next build", 9 | "start": "next start", 10 | "lint": "next lint" 11 | }, 12 | "dependencies": { 13 | "@rainbow-me/rainbowkit": "^0.8.1", 14 | "ethers": "^5.7.2", 15 | "next": "^13.1.6", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^18.11.18", 22 | "@types/react": "^18.0.27", 23 | "@types/react-dom": "^18.0.10", 24 | "eslint": "^8.27.0", 25 | "eslint-config-next": "^13.0.2", 26 | "typescript": "^4.9.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/next-ts", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@rainbow-me/rainbowkit": "^0.8.1", 13 | "ethers": "^5.7.2", 14 | "next": "^13.1.6", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "wagmi": "^0.11.3" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^18.11.18", 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "eslint": "^8.27.0", 24 | "eslint-config-next": "^13.0.2", 25 | "typescript": "^4.9.5" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import type { AppProps } from 'next/app'; 3 | import NextHead from 'next/head'; 4 | import '../styles/globals.css'; 5 | 6 | // Imports 7 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 8 | import { 9 | mainnet, 10 | polygon, 11 | polygonMumbai, 12 | optimism, 13 | arbitrum, 14 | hardhat, 15 | } from 'wagmi/chains'; 16 | import { publicProvider } from 'wagmi/providers/public'; 17 | 18 | import '@rainbow-me/rainbowkit/styles.css'; 19 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 20 | 21 | import { useIsMounted } from '../hooks'; 22 | 23 | const { chains, provider, webSocketProvider } = configureChains( 24 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 25 | [publicProvider()] 26 | ); 27 | 28 | const { connectors } = getDefaultWallets({ 29 | appName: 'create-web3', 30 | chains, 31 | }); 32 | 33 | const wagmiClient = createClient({ 34 | autoConnect: true, 35 | connectors, 36 | provider, 37 | webSocketProvider, 38 | }); 39 | 40 | const App = ({ Component, pageProps }: AppProps) => { 41 | const isMounted = useIsMounted(); 42 | 43 | if (!isMounted) return null; 44 | return ( 45 | 46 | 47 | 48 | create-web3 49 | 50 | 51 | 52 | 53 | ); 54 | }; 55 | 56 | export default App; 57 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | 3 | import { ConnectButton } from '@rainbow-me/rainbowkit'; 4 | import { GetGreeter, SetGreeter } from '../components/contract'; 5 | 6 | export default function Home() { 7 | return ( 8 |
9 | 10 | Create-Web3 App 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 |
28 | 29 | 30 |
31 |
32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/e-roy/create-web3/dd5049e02cf1643e3a47a277ad031298c69f58ba/packages/create-web3/templates/next/typescript/public/favicon.ico -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | 18 | button { 19 | cursor: pointer; 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-web3/templates/next/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@/*": ["*"] 20 | } 21 | }, 22 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/contracts/hardhat_contracts.json: -------------------------------------------------------------------------------- 1 | { 2 | "31337": [ 3 | { 4 | "name": "localhost", 5 | "chainId": "31337", 6 | "contracts": { 7 | "Greeter": { 8 | "address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", 9 | "abi": [ 10 | { 11 | "inputs": [ 12 | { 13 | "internalType": "string", 14 | "name": "_greeting", 15 | "type": "string" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "constructor" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "greet", 24 | "outputs": [ 25 | { 26 | "internalType": "string", 27 | "name": "", 28 | "type": "string" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "string", 38 | "name": "_greeting", 39 | "type": "string" 40 | } 41 | ], 42 | "name": "setGreeting", 43 | "outputs": [], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 11 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "ethers": "^5.7.2", 13 | "buffer": "^6.0.3", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "vite": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "ethers": "^5.7.2", 13 | "buffer": "^6.0.3", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "vite": "^4.1.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { ConnectButton } from '@rainbow-me/rainbowkit'; 2 | import { GetGreeter, SetGreeter } from './components'; 3 | 4 | function App() { 5 | return ( 6 |
7 |
8 | 9 |
10 |
20 | 21 | 22 |
23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/components/GetGreeter.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useCallback } from 'react'; 2 | import { useContract, useProvider } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../config'; 6 | 7 | export const GetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [currentGreeter, setCurrentGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const provider = useProvider(); 14 | 15 | const allContracts = contracts; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: provider, 23 | }); 24 | 25 | const fetchData = useCallback(async () => { 26 | try { 27 | const greeter = await greeterContract.greet(); 28 | setCurrentGreeter(greeter); 29 | setError(''); 30 | } catch (error) { 31 | setError("Contract couldn't be fetched. Please check your network."); 32 | } 33 | setLoading(false); 34 | }, [greeterContract]); 35 | 36 | useEffect(() => { 37 | if (provider) { 38 | fetchData(); 39 | } 40 | }, [provider, greeterContract, fetchData]); 41 | 42 | if (loading) { 43 | return
Loading...
; 44 | } 45 | 46 | if (error) { 47 | return
{error}
; 48 | } 49 | 50 | return ( 51 |
52 | current greeting : {currentGreeter} 53 | 56 |
57 | ); 58 | }; 59 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/components/SetGreeter.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useContract, useSigner } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../config'; 6 | 7 | export const SetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [newGreeter, setNewGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const { data: signerData } = useSigner(); 14 | 15 | const allContracts = contracts; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: signerData, 23 | }); 24 | 25 | useEffect(() => { 26 | if (signerData) { 27 | setError(''); 28 | setLoading(false); 29 | } else { 30 | setLoading(false); 31 | setError('please connect your wallet'); 32 | } 33 | }, [signerData]); 34 | 35 | const handleSubmit = async (e) => { 36 | e.preventDefault(); 37 | try { 38 | setLoading(true); 39 | const tx = await greeterContract.setGreeting(newGreeter); 40 | await tx.wait(); 41 | setNewGreeter(''); 42 | setLoading(false); 43 | } catch (error) { 44 | setError('txn failed, check contract'); 45 | setLoading(false); 46 | } 47 | }; 48 | 49 | if (loading) { 50 | return
Loading...
; 51 | } 52 | 53 | if (error) { 54 | return
{error}
; 55 | } 56 | 57 | return ( 58 |
59 |
handleSubmit(e)}> 60 | setNewGreeter(e.target.value)} 65 | /> 66 | 69 |
70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/components/index.js: -------------------------------------------------------------------------------- 1 | export { GetGreeter } from './GetGreeter'; 2 | export { SetGreeter } from './SetGreeter'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/config.js: -------------------------------------------------------------------------------- 1 | export const NETWORK_ID = 31337; 2 | export const NETWORK_NAME = 'localhost'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | import './index.css'; 5 | 6 | // Imports 7 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 8 | import { 9 | mainnet, 10 | polygon, 11 | polygonMumbai, 12 | optimism, 13 | arbitrum, 14 | hardhat, 15 | } from 'wagmi/chains'; 16 | import { publicProvider } from 'wagmi/providers/public'; 17 | 18 | import '@rainbow-me/rainbowkit/styles.css'; 19 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 20 | 21 | const { chains, provider, webSocketProvider } = configureChains( 22 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 23 | [publicProvider()] 24 | ); 25 | 26 | const { connectors } = getDefaultWallets({ 27 | appName: 'create-web3', 28 | chains, 29 | }); 30 | 31 | const wagmiClient = createClient({ 32 | autoConnect: true, 33 | connectors, 34 | provider, 35 | }); 36 | 37 | createRoot(document.getElementById('root')).render( 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ); 46 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/default/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | resolve: { 7 | alias: { 8 | process: 'process/browser', 9 | util: 'util', 10 | }, 11 | }, 12 | plugins: [react()], 13 | }); 14 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/contracts/hardhat_contracts.json: -------------------------------------------------------------------------------- 1 | { 2 | "31337": [ 3 | { 4 | "name": "localhost", 5 | "chainId": "31337", 6 | "contracts": { 7 | "Greeter": { 8 | "address": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", 9 | "abi": [ 10 | { 11 | "inputs": [ 12 | { 13 | "internalType": "string", 14 | "name": "_greeting", 15 | "type": "string" 16 | } 17 | ], 18 | "stateMutability": "nonpayable", 19 | "type": "constructor" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "greet", 24 | "outputs": [ 25 | { 26 | "internalType": "string", 27 | "name": "", 28 | "type": "string" 29 | } 30 | ], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { 37 | "internalType": "string", 38 | "name": "_greeting", 39 | "type": "string" 40 | } 41 | ], 42 | "name": "setGreeting", 43 | "outputs": [], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | } 47 | ] 48 | } 49 | } 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 11 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/package-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "buffer": "^6.0.3", 13 | "ethers": "^5.7.2", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "typescript": "^4.9.5", 25 | "vite": "^4.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@create-web3/vite-ts", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@rainbow-me/rainbowkit": "^0.8.1", 12 | "buffer": "^6.0.3", 13 | "ethers": "^5.7.2", 14 | "process": "^0.11.10", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "util": "^0.12.4", 18 | "wagmi": "^0.11.3" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.0.27", 22 | "@types/react-dom": "^18.0.10", 23 | "@vitejs/plugin-react": "^3.1.0", 24 | "typescript": "^4.9.5", 25 | "vite": "^4.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { ConnectButton } from '@rainbow-me/rainbowkit'; 2 | import { GetGreeter, SetGreeter } from './components'; 3 | 4 | function App() { 5 | return ( 6 |
7 |
8 | 9 |
10 |
20 | 21 | 22 |
23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/components/GetGreeter.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useCallback } from 'react'; 2 | import { useContract, useProvider } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../config'; 6 | 7 | export const GetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [currentGreeter, setCurrentGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const provider = useProvider(); 14 | 15 | const allContracts = contracts as any; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: provider, 23 | }); 24 | 25 | const fetchData = useCallback(async () => { 26 | try { 27 | const greeter = await greeterContract?.greet(); 28 | setCurrentGreeter(greeter); 29 | setError(''); 30 | } catch (error) { 31 | setError("Contract couldn't be fetched. Please check your network."); 32 | } 33 | setLoading(false); 34 | }, [greeterContract]); 35 | 36 | useEffect(() => { 37 | if (provider) { 38 | fetchData(); 39 | } 40 | }, [provider, greeterContract, fetchData]); 41 | 42 | if (loading) { 43 | return
Loading...
; 44 | } 45 | 46 | if (error) { 47 | return
{error}
; 48 | } 49 | 50 | return ( 51 |
52 | current greeting : {currentGreeter} 53 | 56 |
57 | ); 58 | }; 59 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/components/SetGreeter.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, FormEvent } from 'react'; 2 | import { useContract, useSigner } from 'wagmi'; 3 | 4 | import contracts from '../../contracts/hardhat_contracts.json'; 5 | import { NETWORK_ID } from '../config'; 6 | 7 | export const SetGreeter = () => { 8 | const chainId = Number(NETWORK_ID); 9 | const [newGreeter, setNewGreeter] = useState(''); 10 | const [loading, setLoading] = useState(true); 11 | const [error, setError] = useState(''); 12 | 13 | const { data: signerData } = useSigner(); 14 | 15 | const allContracts = contracts as any; 16 | const greeterAddress = allContracts[chainId][0].contracts.Greeter.address; 17 | const greeterABI = allContracts[chainId][0].contracts.Greeter.abi; 18 | 19 | const greeterContract = useContract({ 20 | address: greeterAddress, 21 | abi: greeterABI, 22 | signerOrProvider: signerData, 23 | }); 24 | 25 | useEffect(() => { 26 | if (signerData) { 27 | setError(''); 28 | setLoading(false); 29 | } else { 30 | setLoading(false); 31 | setError('please connect your wallet'); 32 | } 33 | }, [signerData]); 34 | 35 | const handleSubmit = async (e: FormEvent) => { 36 | e.preventDefault(); 37 | try { 38 | setLoading(true); 39 | const tx = await greeterContract?.setGreeting(newGreeter); 40 | await tx.wait(); 41 | setNewGreeter(''); 42 | setLoading(false); 43 | } catch (error) { 44 | setError('txn failed, check contract'); 45 | setLoading(false); 46 | } 47 | }; 48 | 49 | if (loading) { 50 | return
Loading...
; 51 | } 52 | 53 | if (error) { 54 | return
{error}
; 55 | } 56 | 57 | return ( 58 |
59 |
handleSubmit(e)}> 60 | setNewGreeter(e.target.value)} 65 | /> 66 | 69 |
70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { GetGreeter } from './GetGreeter'; 2 | export { SetGreeter } from './SetGreeter'; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/config.ts: -------------------------------------------------------------------------------- 1 | export const NETWORK_ID = 31337 as number; 2 | export const NETWORK_NAME = 'localhost' as string; 3 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import App from './App'; 5 | import './index.css'; 6 | 7 | // Imports 8 | import { createClient, WagmiConfig, configureChains } from 'wagmi'; 9 | import { 10 | mainnet, 11 | polygon, 12 | polygonMumbai, 13 | optimism, 14 | arbitrum, 15 | hardhat, 16 | } from 'wagmi/chains'; 17 | import { publicProvider } from 'wagmi/providers/public'; 18 | 19 | import '@rainbow-me/rainbowkit/styles.css'; 20 | import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'; 21 | 22 | const { chains, provider, webSocketProvider } = configureChains( 23 | [mainnet, polygon, polygonMumbai, optimism, arbitrum, hardhat], 24 | [publicProvider()] 25 | ); 26 | 27 | const { connectors } = getDefaultWallets({ 28 | appName: 'create-web3', 29 | chains, 30 | }); 31 | 32 | const wagmiClient = createClient({ 33 | autoConnect: true, 34 | connectors, 35 | provider, 36 | webSocketProvider, 37 | }); 38 | 39 | createRoot(document.getElementById('root')!).render( 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ); 48 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/create-web3/templates/vite/typescript/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | // @ts-ignore 3 | import react from '@vitejs/plugin-react'; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | resolve: { 8 | alias: { 9 | process: 'process/browser', 10 | util: 'util', 11 | }, 12 | }, 13 | plugins: [react()], 14 | }); 15 | --------------------------------------------------------------------------------