├── .husky ├── .gitignore ├── pre-commit └── commit-msg ├── .czrc ├── .commitlintrc.yml ├── .solhintignore ├── .lintstagedrc.yml ├── .vscode ├── extensions.json └── settings.json ├── .solcover.js ├── .yarnrc.yml ├── .gitpod.yml ├── .editorconfig ├── .eslintignore ├── .prettierignore ├── .gitignore ├── .prettierrc.yml ├── .solhint.json ├── .env.example ├── scripts └── deploy.js ├── .eslintrc.yml ├── tsconfig.json ├── contracts └── Greeter.sol ├── test └── greeter.spec.ts ├── .github ├── scripts │ └── rename.sh └── workflows │ ├── ci.yml │ └── create.yml ├── LICENSE.md ├── hardhat.config.ts ├── package.json └── README.md /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.czrc: -------------------------------------------------------------------------------- 1 | { 2 | "path": "cz-conventional-changelog" 3 | } 4 | -------------------------------------------------------------------------------- /.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - "@commitlint/config-conventional" 3 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | # directories 2 | **/artifacts 3 | **/node_modules 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn dlx lint-staged 5 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn dlx commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.lintstagedrc.yml: -------------------------------------------------------------------------------- 1 | "*.{js,json,md,sol,ts,yml}": 2 | - prettier --config ""./.prettierrc.yml" --write 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "NomicFoundation.hardhat-solidity"] 3 | } 4 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | istanbulReporter: ["html", "lcov"], 3 | providerOptions: { 4 | mnemonic: process.env.MNEMONIC, 5 | }, 6 | skipFiles: ["test"], 7 | }; 8 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: ".yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs" 5 | spec: "@yarnpkg/plugin-interactive-tools" 6 | 7 | yarnPath: .yarn/releases/yarn-3.2.1.cjs 8 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: "gitpod/workspace-node:latest" 2 | 3 | tasks: 4 | - init: "yarn install" 5 | 6 | vscode: 7 | extensions: 8 | - "esbenp.prettier-vscode" 9 | - "NomicFoundation.hardhat-solidity" 10 | - "ritwickdey.LiveServer" 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # All files 7 | [*] 8 | charset = utf-8 9 | end_of_line = lf 10 | indent_size = 2 11 | indent_style = space 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | [*.sol] 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .yarn/ 3 | **/.coverage_artifacts 4 | **/.coverage_cache 5 | **/.coverage_contracts 6 | **/artifacts 7 | **/build 8 | **/cache 9 | **/coverage 10 | **/dist 11 | **/node_modules 12 | **/types 13 | 14 | # files 15 | *.env 16 | *.log 17 | .pnp.* 18 | coverage.json 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .yarn/ 3 | **/.coverage_artifacts 4 | **/.coverage_cache 5 | **/.coverage_contracts 6 | **/artifacts 7 | **/build 8 | **/cache 9 | **/coverage 10 | **/dist 11 | **/node_modules 12 | **/types 13 | 14 | # files 15 | *.env 16 | *.log 17 | .pnp.* 18 | coverage.json 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # directories 2 | .yarn/* 3 | !.yarn/patches 4 | !.yarn/releases 5 | !.yarn/plugins 6 | !.yarn/sdks 7 | !.yarn/versions 8 | **/artifacts 9 | **/build 10 | **/cache 11 | **/coverage 12 | **/.coverage_artifacts 13 | **/.coverage_cache 14 | **/.coverage_contracts 15 | **/dist 16 | **/node_modules 17 | **/types 18 | 19 | # files 20 | *.env 21 | *.log 22 | .pnp.* 23 | coverage.json 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[json]": { 3 | "editor.defaultFormatter": "esbenp.prettier-vscode" 4 | }, 5 | "[markdown]": { 6 | "editor.defaultFormatter": "esbenp.prettier-vscode" 7 | }, 8 | "[solidity]": { 9 | "editor.defaultFormatter": "esbenp.prettier-vscode" 10 | }, 11 | "[typescript]": { 12 | "editor.defaultFormatter": "esbenp.prettier-vscode" 13 | }, 14 | "editor.formatOnSave": true, 15 | "liveServer.settings.root": "/coverage" 16 | } 17 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | bracketSpacing: true 2 | endOfLine: "auto" 3 | printWidth: 120 4 | proseWrap: "always" 5 | singleQuote: false 6 | tabWidth: 2 7 | trailingComma: "all" 8 | 9 | overrides: 10 | - files: "*.sol" 11 | options: 12 | compiler: "0.8.10" 13 | tabWidth: 4 14 | - files: "*.ts" 15 | options: 16 | importOrder: ["", "^[./]"] 17 | importOrderParserPlugins: ["typescript"] 18 | importOrderSeparation: true 19 | importOrderSortSpecifiers: true 20 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "code-complexity": ["error", 8], 6 | "compiler-version": ["error", ">=0.8.4"], 7 | "func-visibility": ["error", { "ignoreConstructors": true }], 8 | "max-line-length": ["error", 120], 9 | "not-rely-on-time": "off", 10 | "prettier/prettier": [ 11 | "error", 12 | { 13 | "endOfLine": "auto" 14 | } 15 | ], 16 | "reason-string": ["warn", { "maxLength": 64 }] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 2 | MNEMONIC="the twelve words that you need to memorize to run this app" 3 | 4 | # Block explorer API keys 5 | ARBISCAN_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 6 | BSCSCAN_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 7 | ETHERSCAN_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 8 | OPTIMISM_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 9 | POLYGONSCAN_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 10 | SNOWTRACE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 11 | -------------------------------------------------------------------------------- /scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | 3 | async function main() { 4 | const [deployer] = await ethers.getSigners(); 5 | console.log("Deploying contracts with the account: " + deployer.address); 6 | 7 | // Deploy First 8 | const First = await ethers.getContractFactory("Greeter"); 9 | const first = await First.deploy("Hello friends"); 10 | await first.deployed(); 11 | console.log("First: " + first.address); 12 | } 13 | 14 | main() 15 | .then(() => process.exit()) 16 | .catch((error) => { 17 | console.error(error); 18 | process.exit(1); 19 | }); 20 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - "eslint:recommended" 3 | - "plugin:@typescript-eslint/eslint-recommended" 4 | - "plugin:@typescript-eslint/recommended" 5 | - "prettier" 6 | parser: "@typescript-eslint/parser" 7 | parserOptions: 8 | project: "tsconfig.json" 9 | plugins: 10 | - "@typescript-eslint" 11 | root: true 12 | rules: 13 | "@typescript-eslint/no-floating-promises": 14 | - error 15 | - ignoreIIFE: true 16 | ignoreVoid: true 17 | "@typescript-eslint/no-inferrable-types": "off" 18 | "@typescript-eslint/no-unused-vars": 19 | - error 20 | - argsIgnorePattern: "_" 21 | varsIgnorePattern: "_" 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationMap": true, 5 | "emitDecoratorMetadata": true, 6 | "esModuleInterop": true, 7 | "experimentalDecorators": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "lib": ["es6"], 10 | "module": "commonjs", 11 | "moduleResolution": "node", 12 | "noImplicitAny": true, 13 | "removeComments": true, 14 | "resolveJsonModule": true, 15 | "sourceMap": true, 16 | "strict": true, 17 | "target": "es6" 18 | }, 19 | "exclude": ["node_modules"], 20 | "files": ["./hardhat.config.ts"], 21 | "include": ["src/**/*", "test/**/*"] 22 | } 23 | -------------------------------------------------------------------------------- /contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | error GreeterError(); 7 | 8 | contract Greeter { 9 | string public greeting; 10 | 11 | constructor(string memory _greeting) { 12 | console.log("Deploying a Greeter with greeting:", _greeting); 13 | greeting = _greeting; 14 | } 15 | 16 | function greet() public view returns (string memory) { 17 | return greeting; 18 | } 19 | 20 | function setGreeting(string memory _greeting) public { 21 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 22 | greeting = _greeting; 23 | } 24 | 25 | function throwError() external pure { 26 | revert GreeterError(); 27 | } 28 | } -------------------------------------------------------------------------------- /test/greeter.spec.ts: -------------------------------------------------------------------------------- 1 | import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; 2 | import { expect } from "chai"; 3 | import { ethers } from "hardhat"; 4 | import { Greeter} from "../types"; 5 | 6 | let account1: SignerWithAddress; 7 | let rest: SignerWithAddress[]; 8 | 9 | let greeter: Greeter; 10 | 11 | 12 | 13 | 14 | describe("Greeter", function () { 15 | before(async () => { 16 | [account1, ...rest] = await ethers.getSigners(); 17 | greeter = await (await ethers.getContractFactory("Greeter")).deploy("Hello there"); 18 | }); 19 | 20 | beforeEach(async () => { 21 | 22 | }); 23 | 24 | describe("greeting change", () => { 25 | it("should change text", async () => { 26 | await greeter.connect(account1).setGreeting("oh hey"); 27 | expect(await greeter.connect(account1).greet()).to.equal("oh hey"); 28 | }); 29 | 30 | }); 31 | 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /.github/scripts/rename.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca 4 | set -euo pipefail 5 | 6 | # Define the input vars 7 | GITHUB_REPOSITORY=${1?Error: Please pass username/repo, e.g. prb/hardhat-template} 8 | GITHUB_REPOSITORY_OWNER=${2?Error: Please pass username, e.g. prb} 9 | 10 | echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY" 11 | echo "GITHUB_REPOSITORY_OWNER: $GITHUB_REPOSITORY_OWNER" 12 | 13 | # jq is like sed for JSON data 14 | JQ_OUTPUT=`jq \ 15 | --arg NAME "@$GITHUB_REPOSITORY" \ 16 | --arg AUTHOR_NAME "$GITHUB_REPOSITORY_OWNER" \ 17 | --arg URL "https://github.com/$GITHUB_REPOSITORY_OWNER" \ 18 | '.name = $NAME | .description = "" | .author |= ( .name = $AUTHOR_NAME | .url = $URL )' \ 19 | package.json 20 | ` 21 | 22 | # Overwrite package.json 23 | echo "$JQ_OUTPUT" > package.json 24 | 25 | # Rename instances of "paulrberg/hardhat-template" to the new repo name in README.md for badges only 26 | sed -i -e "/Use this template/! s|paulrberg/hardhat-template|"${GITHUB_REPOSITORY}"|;" "README.md" 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: "CI" 2 | 3 | env: 4 | DOTENV_CONFIG_PATH: "./.env" 5 | 6 | on: 7 | pull_request: 8 | branches: 9 | - "main" 10 | push: 11 | branches: 12 | - "main" 13 | 14 | jobs: 15 | ci: 16 | runs-on: "ubuntu-latest" 17 | steps: 18 | - name: "Check out the repo" 19 | uses: "actions/checkout@v3" 20 | 21 | - name: "Install Node.js" 22 | uses: "actions/setup-node@v3" 23 | with: 24 | cache: "yarn" 25 | node-version: "lts/*" 26 | 27 | - name: "Install the dependencies" 28 | run: "yarn install --immutable" 29 | 30 | - name: "Lint the code" 31 | run: "yarn lint" 32 | 33 | - name: "Add lint summary" 34 | run: | 35 | echo "## Lint results" >> $GITHUB_STEP_SUMMARY 36 | echo "✅ Passed" >> $GITHUB_STEP_SUMMARY 37 | 38 | - name: "Compile the contracts and generate the TypeChain bindings" 39 | run: "yarn typechain" 40 | 41 | - name: "Test the contracts and generate the coverage report" 42 | run: "yarn coverage" 43 | 44 | - name: "Add test summary" 45 | run: | 46 | echo "## Test results" >> $GITHUB_STEP_SUMMARY 47 | echo "✅ Passed" >> $GITHUB_STEP_SUMMARY 48 | -------------------------------------------------------------------------------- /.github/workflows/create.yml: -------------------------------------------------------------------------------- 1 | name: Create 2 | 3 | # The workflow will run only when `use this template` is used 4 | on: 5 | create: 6 | 7 | jobs: 8 | create: 9 | # We will only run this action when the repository isn't the template repository 10 | # Reference https://docs.github.com/en/actions/learn-github-actions/contexts 11 | # Reference https://docs.github.com/en/actions/learn-github-actions/expressions 12 | if: ${{ !github.event.repository.is_template }} 13 | 14 | runs-on: ubuntu-latest 15 | permissions: write-all 16 | 17 | steps: 18 | - name: "Check out the repo" 19 | uses: "actions/checkout@v3" 20 | 21 | - name: "Update package.json" 22 | run: ./.github/scripts/rename.sh "$GITHUB_REPOSITORY" "$GITHUB_REPOSITORY_OWNER" 23 | 24 | - name: "Add rename summary" 25 | run: | 26 | echo "## Commit results" >> $GITHUB_STEP_SUMMARY 27 | echo "✅ Passed" >> $GITHUB_STEP_SUMMARY 28 | 29 | - name: "Update commit" 30 | uses: stefanzweifel/git-auto-commit-action@v4 31 | with: 32 | commit_message: "feat: initial commit" 33 | commit_options: "--amend" 34 | push_options: "--force" 35 | skip_fetch: true 36 | 37 | - name: "Add commit summary" 38 | run: | 39 | echo "## Commit results" >> $GITHUB_STEP_SUMMARY 40 | echo "✅ Passed" >> $GITHUB_STEP_SUMMARY 41 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import "@nomicfoundation/hardhat-toolbox"; 2 | import chai from "chai"; 3 | import { config as dotenvConfig } from "dotenv"; 4 | import { solidity } from "ethereum-waffle"; 5 | import { BigNumber } from "ethers"; 6 | import "hardhat-deploy"; 7 | import type { HardhatUserConfig } from "hardhat/config"; 8 | import type { NetworkUserConfig } from "hardhat/types"; 9 | import { resolve } from "path"; 10 | 11 | const dotenvConfigPath: string = process.env.DOTENV_CONFIG_PATH || "./.env"; 12 | dotenvConfig({ path: resolve(__dirname, dotenvConfigPath) }); 13 | 14 | // Make sure you have all the environment variables we need. 15 | const mnemonic: string | undefined = process.env.MNEMONIC; 16 | if (!mnemonic) { 17 | throw new Error("Please set your MNEMONIC in a .env file"); 18 | } 19 | 20 | const alchemyApiKey: string | undefined = process.env.ALCHEMY_API_KEY; 21 | if (!alchemyApiKey) { 22 | throw new Error("Please set your ALCHEMY_API_KEY in a .env file"); 23 | } 24 | 25 | const chainIds = { 26 | // "arbitrum-mainnet": 42161, 27 | // avalanche: 43114, 28 | // bsc: 56, 29 | // goerli: 5, 30 | hardhat: 31337, 31 | // mainnet: 1, 32 | // "optimism-mainnet": 10, 33 | // "polygon-mainnet": 137, 34 | "polygon-mumbai": 80001, 35 | }; 36 | 37 | function getChainConfig(chain: keyof typeof chainIds): NetworkUserConfig { 38 | let jsonRpcUrl: string; 39 | switch (chain) { 40 | // case "avalanche": 41 | // jsonRpcUrl = "https://api.avax.network/ext/bc/C/rpc"; 42 | // break; 43 | // case "bsc": 44 | // jsonRpcUrl = "https://bsc-dataseed1.binance.org"; 45 | // break; 46 | default: 47 | jsonRpcUrl = "https://" + chain + ".g.alchemy.com/v2/" + alchemyApiKey; 48 | } 49 | return { 50 | accounts: { 51 | count: 10, 52 | mnemonic, 53 | path: "m/44'/60'/0'/0", 54 | }, 55 | chainId: chainIds[chain], 56 | url: jsonRpcUrl, 57 | }; 58 | } 59 | 60 | const config: HardhatUserConfig = { 61 | defaultNetwork: "hardhat", 62 | etherscan: { 63 | apiKey: { 64 | polygonMumbai: process.env.POLYGONSCAN_API_KEY || "", 65 | }, 66 | }, 67 | gasReporter: { 68 | currency: "USD", 69 | enabled: process.env.REPORT_GAS ? true : false, 70 | excludeContracts: [], 71 | src: "./contracts", 72 | }, 73 | networks: { 74 | hardhat: { 75 | accounts: { 76 | mnemonic, 77 | }, 78 | chainId: chainIds.hardhat, 79 | }, 80 | // arbitrum: getChainConfig("arbitrum-mainnet"), 81 | // avalanche: getChainConfig("avalanche"), 82 | // bsc: getChainConfig("bsc"), 83 | // goerli: getChainConfig("goerli"), 84 | // mainnet: getChainConfig("mainnet"), 85 | // optimism: getChainConfig("optimism-mainnet"), 86 | // "polygon-mainnet": getChainConfig("polygon-mainnet"), 87 | "polygon-mumbai": getChainConfig("polygon-mumbai"), 88 | }, 89 | paths: { 90 | artifacts: "./artifacts", 91 | cache: "./cache", 92 | sources: "./contracts", 93 | tests: "./test", 94 | }, 95 | solidity: { 96 | version: "0.8.10", 97 | settings: { 98 | metadata: { 99 | // Not including the metadata hash 100 | bytecodeHash: "none", 101 | }, 102 | // Disable the optimizer when debugging 103 | // https://hardhat.org/hardhat-network/#solidity-optimizer-support 104 | optimizer: { 105 | enabled: true, 106 | runs: 800, 107 | }, 108 | }, 109 | }, 110 | typechain: { 111 | outDir: "types", 112 | target: "ethers-v5", 113 | }, 114 | }; 115 | 116 | export default config; 117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-template-alchemy", 3 | "description": "Hardhat template with alchemy", 4 | "version": "1.0.0", 5 | "author": { 6 | "name": "Ahmad Kadri", 7 | "url": "https://github.com/elkadro" 8 | }, 9 | "devDependencies": { 10 | "@commitlint/cli": "^17.1.2", 11 | "@commitlint/config-conventional": "^17.1.0", 12 | "@ethersproject/abi": "^5.7.0", 13 | "@ethersproject/abstract-signer": "^5.7.0", 14 | "@ethersproject/bignumber": "^5.7.0", 15 | "@ethersproject/bytes": "^5.7.0", 16 | "@ethersproject/providers": "^5.7.1", 17 | "@nomicfoundation/hardhat-chai-matchers": "^1.0.4", 18 | "@nomicfoundation/hardhat-network-helpers": "^1.0.6", 19 | "@nomicfoundation/hardhat-toolbox": "^2.0.0", 20 | "@nomiclabs/hardhat-ethers": "^2.2.0", 21 | "@nomiclabs/hardhat-etherscan": "^3.1.1", 22 | "@nomiclabs/hardhat-waffle": "^2.0.3", 23 | "@trivago/prettier-plugin-sort-imports": "^3.3.0", 24 | "@typechain/ethers-v5": "^10.1.0", 25 | "@typechain/hardhat": "^6.1.3", 26 | "@types/chai": "^4.3.3", 27 | "@types/fs-extra": "^9.0.13", 28 | "@types/mocha": "^10.0.0", 29 | "@types/node": "^18.8.5", 30 | "@typescript-eslint/eslint-plugin": "^5.40.0", 31 | "@typescript-eslint/parser": "^5.40.0", 32 | "chai": "^4.3.6", 33 | "commitizen": "^4.2.5", 34 | "cross-env": "^7.0.3", 35 | "cz-conventional-changelog": "^3.3.0", 36 | "dotenv": "^16.0.3", 37 | "eslint": "^8.25.0", 38 | "eslint-config-prettier": "^8.5.0", 39 | "ethers": "^5.7.2", 40 | "fs-extra": "^10.1.0", 41 | "hardhat": "^2.12.0", 42 | "hardhat-gas-reporter": "^1.0.9", 43 | "husky": "8.0.1", 44 | "lint-staged": "^13.0.3", 45 | "lodash": "^4.17.21", 46 | "mocha": "^10.0.0", 47 | "pinst": "^3.0.0", 48 | "prettier": "^2.7.1", 49 | "prettier-plugin-solidity": "^1.0.0-beta.24", 50 | "shx": "^0.3.4", 51 | "solhint": "^3.3.7", 52 | "solhint-plugin-prettier": "^0.0.5", 53 | "solidity-coverage": "^0.8.2", 54 | "ts-generator": "^0.1.1", 55 | "ts-node": "^10.9.1", 56 | "typechain": "^8.1.0", 57 | "typescript": "^4.8.4" 58 | }, 59 | "files": [ 60 | "/contracts" 61 | ], 62 | "keywords": [ 63 | "blockchain", 64 | "ethers", 65 | "ethereum", 66 | "hardhat", 67 | "smart-contracts", 68 | "solidity", 69 | "template", 70 | "typescript", 71 | "typechain" 72 | ], 73 | "packageManager": "yarn@3.2.1", 74 | "publishConfig": { 75 | "access": "public" 76 | }, 77 | "scripts": { 78 | "clean": "shx rm -rf ./artifacts ./cache ./coverage ./types ./coverage.json && yarn typechain", 79 | "commit": "git-cz", 80 | "compile": "cross-env TS_NODE_TRANSPILE_ONLY=true hardhat compile", 81 | "coverage": "hardhat coverage --solcoverjs ./.solcover.js --temp artifacts --testfiles \"test/**/*.ts\" && yarn typechain", 82 | "deploy": "hardhat run scripts/deploy.js", 83 | "lint": "yarn lint:sol && yarn lint:ts && yarn prettier:check", 84 | "lint:sol": "solhint --config ./.solhint.json --max-warnings 0 \"contracts/**/*.sol\"", 85 | "lint:ts": "eslint --config ./.eslintrc.yml --ignore-path ./.eslintignore --ext .js,.ts .", 86 | "postinstall": "husky install && DOTENV_CONFIG_PATH=./.env.example yarn typechain", 87 | "postpublish": "pinst --enable", 88 | "prepublishOnly": "pinst --disable", 89 | "prettier": "prettier --config ./.prettierrc.yml --write \"**/*.{js,json,md,sol,ts,yml}\"", 90 | "prettier:check": "prettier --check --config ./.prettierrc.yml \"**/*.{js,json,md,sol,ts,yml}\"", 91 | "test": "hardhat test", 92 | "typechain": "cross-env TS_NODE_TRANSPILE_ONLY=true hardhat typechain" 93 | }, 94 | "dependencies": { 95 | "@metamask/eth-sig-util": "^5.0.0", 96 | "@openzeppelin/contracts": "^4.7.3", 97 | "chai-bignumber": "^3.1.0", 98 | "crypto": "^1.0.1", 99 | "hardhat-deploy": "^0.11.18", 100 | "keccak256": "^1.0.6" 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hardhat Alchemy Template 2 | 3 | A Hardhat-based template for developing Solidity smart contracts, with sensible defaults. 4 | 5 | - [Hardhat](https://github.com/nomiclabs/hardhat): compile, run and test smart contracts 6 | - [TypeChain](https://github.com/ethereum-ts/TypeChain): generate TypeScript bindings for smart contracts 7 | - [Ethers](https://github.com/ethers-io/ethers.js/): renowned Ethereum library and wallet implementation 8 | - [Solhint](https://github.com/protofire/solhint): code linter 9 | - [Solcover](https://github.com/sc-forks/solidity-coverage): code coverage 10 | - [Prettier Plugin Solidity](https://github.com/prettier-solidity/prettier-plugin-solidity): code formatter 11 | 12 | ## Features 13 | 14 | This template builds upon the frameworks and libraries mentioned above, so for details about their specific features, 15 | please consult their respective documentations. 16 | 17 | For example, for Hardhat, you can refer to the [Hardhat Tutorial](https://hardhat.org/tutorial) and the 18 | [Hardhat Docs](https://hardhat.org/docs). You might be in particular interested in reading the 19 | [Testing Contracts](https://hardhat.org/tutorial/testing-contracts) section. 20 | 21 | ### Sensible Defaults 22 | 23 | This template comes with sensible default configurations in the following files: 24 | 25 | ```text 26 | ├── .commitlintrc.yml 27 | ├── .editorconfig 28 | ├── .eslintignore 29 | ├── .eslintrc.yml 30 | ├── .gitignore 31 | ├── .prettierignore 32 | ├── .prettierrc.yml 33 | ├── .solcover.js 34 | ├── .solhintignore 35 | ├── .solhint.json 36 | ├── .yarnrc.yml 37 | └── hardhat.config.ts 38 | ``` 39 | 40 | ### GitHub Actions 41 | 42 | This template comes with GitHub Actions pre-configured. Your contracts will be linted and tested on every push and pull 43 | request made to the `main` branch. 44 | 45 | Note though that to make this work, you must use your `ALCHEMY_API_KEY` and your `MNEMONIC` as GitHub secrets. 46 | 47 | You can edit the CI script in [.github/workflows/ci.yml](./.github/workflows/ci.yml). 48 | 49 | ### Conventional Commits 50 | 51 | This template enforces the [Conventional Commits](https://www.conventionalcommits.org/) standard for git commit 52 | messages. This is a lightweight convention that creates an explicit commit history, which makes it easier to write 53 | automated tools on top of. 54 | 55 | ### Git Hooks 56 | 57 | This template uses [Husky](https://github.com/typicode/husky) to run automated checks on commit messages, and 58 | [Lint Staged](https://github.com/okonet/lint-staged) to automatically format the code with Prettier when making a git 59 | commit. 60 | 61 | ## Usage 62 | 63 | ### Pre Requisites 64 | 65 | Before being able to run any command, you need to create a `.env` file and set a BIP-39 compatible mnemonic as an 66 | environment variable. You can follow the example in `.env.example`. If you don't already have a mnemonic, you can use 67 | this [website](https://iancoleman.io/bip39/) to generate one. 68 | 69 | Then, proceed with installing dependencies: 70 | 71 | ```sh 72 | $ yarn install 73 | ``` 74 | 75 | ### Compile 76 | 77 | Compile the smart contracts with Hardhat: 78 | 79 | ```sh 80 | $ yarn compile 81 | ``` 82 | 83 | ### TypeChain 84 | 85 | Compile the smart contracts and generate TypeChain bindings: 86 | 87 | ```sh 88 | $ yarn typechain 89 | ``` 90 | 91 | ### Test 92 | 93 | Run the tests with Hardhat: 94 | 95 | ```sh 96 | $ yarn test 97 | ``` 98 | 99 | ### Lint Solidity 100 | 101 | Lint the Solidity code: 102 | 103 | ```sh 104 | $ yarn lint:sol 105 | ``` 106 | 107 | ### Lint TypeScript 108 | 109 | Lint the TypeScript code: 110 | 111 | ```sh 112 | $ yarn lint:ts 113 | ``` 114 | 115 | ### Coverage 116 | 117 | Generate the code coverage report: 118 | 119 | ```sh 120 | $ yarn coverage 121 | ``` 122 | 123 | ### Report Gas 124 | 125 | See the gas usage per unit test and average gas per method call: 126 | 127 | ```sh 128 | $ REPORT_GAS=true yarn test 129 | ``` 130 | 131 | ### Clean 132 | 133 | Delete the smart contract artifacts, the coverage reports and the Hardhat cache: 134 | 135 | ```sh 136 | $ yarn clean 137 | ``` 138 | 139 | ### Deploy 140 | 141 | Deploy the contracts to Hardhat Network: 142 | 143 | ```sh 144 | $ yarn deploy --welcome "Hello, welcome" 145 | ``` 146 | 147 | ## Tips 148 | 149 | ### Syntax Highlighting 150 | 151 | If you use VSCode, you can get Solidity syntax highlighting with the 152 | [hardhat-solidity](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) extension. 153 | --------------------------------------------------------------------------------