├── packages ├── hardhat │ ├── .gitattributes │ ├── test │ │ ├── helpers │ │ │ ├── index.ts │ │ │ └── deploy.ts │ │ └── Greeter.ts │ ├── tasks │ │ ├── index.ts │ │ ├── task-names.ts │ │ ├── clean.ts │ │ └── accounts.ts │ ├── config │ │ ├── index.ts │ │ ├── env.ts │ │ └── networks.ts │ ├── .solhintignore │ ├── .commitlintrc.js │ ├── .huskyrc │ ├── .mocharc.json │ ├── .prettierignore │ ├── .prettierrc │ ├── .eslintignore │ ├── .env.example │ ├── .editorconfig │ ├── .gitignore │ ├── .eslintrc.yaml │ ├── deploy │ │ └── 001_deploy_greeter.ts │ ├── .solcover.js │ ├── .solhint.json │ ├── contracts │ │ └── Greeter.sol │ ├── tsconfig.json │ ├── LICENSE.md │ ├── README.md │ ├── hardhat.config.ts │ └── package.json ├── subgraph │ ├── .gitattributes │ ├── schema.graphql │ ├── README.md │ ├── migrations │ │ ├── 1_initial_migration.js │ │ ├── 2_deploy_contract.js │ │ └── 3_create_gravatars.js │ ├── bin │ │ └── Counter.bin │ ├── contracts │ │ ├── Migrations.sol │ │ └── Gravity.sol │ ├── truffle.js │ ├── src │ │ └── mapping.ts │ ├── subgraph.yaml │ ├── package.json │ ├── LICENSE │ ├── .gitignore │ └── abis │ │ └── Gravity.json └── next │ ├── next-env.d.ts │ ├── public │ ├── favicon.ico │ └── vercel.svg │ ├── pages │ ├── api │ │ └── hello.tsx │ ├── _app.tsx │ └── index.tsx │ ├── .eslintrc.json │ ├── styles │ ├── globals.css │ └── Home.module.css │ ├── .gitignore │ ├── package.json │ ├── tsconfig.json │ └── README.md ├── package.json ├── README.md └── .gitignore /packages/hardhat/.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /packages/hardhat/test/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./deploy"; 2 | -------------------------------------------------------------------------------- /packages/subgraph/.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /packages/hardhat/tasks/index.ts: -------------------------------------------------------------------------------- 1 | import "./accounts"; 2 | import "./clean"; 3 | -------------------------------------------------------------------------------- /packages/hardhat/tasks/task-names.ts: -------------------------------------------------------------------------------- 1 | export const TASK_ACCOUNTS = "accounts"; 2 | -------------------------------------------------------------------------------- /packages/hardhat/config/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./networks"; 2 | export * from "./env"; 3 | -------------------------------------------------------------------------------- /packages/hardhat/.solhintignore: -------------------------------------------------------------------------------- 1 | # folders 2 | .yarn/ 3 | build/ 4 | dist/ 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /packages/next/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /packages/hardhat/.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@commitlint/config-conventional"], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/hardhat/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/next/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GalloDaSballo/hardhat-next-subgraph-mono/HEAD/packages/next/public/favicon.ico -------------------------------------------------------------------------------- /packages/subgraph/schema.graphql: -------------------------------------------------------------------------------- 1 | type Gravatar @entity { 2 | id: ID! 3 | owner: Bytes! 4 | displayName: String! 5 | imageUrl: String! 6 | } 7 | -------------------------------------------------------------------------------- /packages/hardhat/.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extension": ["ts"], 3 | "recursive": "test", 4 | "require": ["hardhat/register"], 5 | "timeout": 20000 6 | } 7 | -------------------------------------------------------------------------------- /packages/subgraph/README.md: -------------------------------------------------------------------------------- 1 | # Example Subgraph 2 | 3 | An example to help you get started with The Graph. For more information see the docs on https://thegraph.com/docs/. 4 | -------------------------------------------------------------------------------- /packages/hardhat/.prettierignore: -------------------------------------------------------------------------------- 1 | # folders 2 | artifacts/ 3 | build/ 4 | cache/ 5 | coverage/ 6 | dist/ 7 | lib/ 8 | node_modules/ 9 | typechain/ 10 | 11 | # files 12 | coverage.json 13 | -------------------------------------------------------------------------------- /packages/subgraph/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require('./Migrations.sol') 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations) 5 | } 6 | -------------------------------------------------------------------------------- /packages/next/pages/api/hello.tsx: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next' 2 | 3 | export default (req: NextApiRequest, res: NextApiResponse) => { 4 | res.status(200).json({ name: 'John Doe' }) 5 | } -------------------------------------------------------------------------------- /packages/hardhat/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "endOfLine": "auto", 5 | "printWidth": 120, 6 | "singleQuote": false, 7 | "tabWidth": 4, 8 | "trailingComma": "all" 9 | } -------------------------------------------------------------------------------- /packages/subgraph/migrations/2_deploy_contract.js: -------------------------------------------------------------------------------- 1 | const GravatarRegistry = artifacts.require('./GravatarRegistry.sol') 2 | 3 | module.exports = async function(deployer) { 4 | await deployer.deploy(GravatarRegistry) 5 | } 6 | -------------------------------------------------------------------------------- /packages/hardhat/.eslintignore: -------------------------------------------------------------------------------- 1 | # folders 2 | artifacts/ 3 | build/ 4 | cache/ 5 | contracts/ 6 | coverage/ 7 | dist/ 8 | lib/ 9 | node_modules/ 10 | typechain/ 11 | 12 | # files 13 | .solcover.js 14 | coverage.json 15 | -------------------------------------------------------------------------------- /packages/hardhat/.env.example: -------------------------------------------------------------------------------- 1 | INFURA_API_KEY=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 2 | MATICVIGIL_API_KEY=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 3 | MNEMONIC=here is where your twelve words mnemonic should be put my friend 4 | ETHERSCAN_API_KEY=Your Etherscan API Key for verification -------------------------------------------------------------------------------- /packages/next/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-typescript-prettier", 3 | "rules": { 4 | "react/jsx-props-no-spreading": "warn", 5 | "react/react-in-jsx-scope": "off", 6 | "jsx-a11y/anchor-is-valid": "off", // Next spreads the prop from Link to a 7 | "import/no-extraneous-dependencies": "off" //Mono repo deps 8 | } 9 | } -------------------------------------------------------------------------------- /packages/hardhat/.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 | -------------------------------------------------------------------------------- /packages/hardhat/.gitignore: -------------------------------------------------------------------------------- 1 | # folders 2 | .coverage_artifacts/ 3 | .coverage_cache/ 4 | .coverage_contracts/ 5 | artifacts/ 6 | build/ 7 | cache/ 8 | coverage/ 9 | dist/ 10 | lib/ 11 | node_modules/ 12 | typechain/ 13 | 14 | # files 15 | *.env 16 | *.log 17 | *.tsbuildinfo 18 | coverage.json 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "private": true, 4 | "name": "mono", 5 | "workspaces": ["packages/*"], 6 | "scripts": { 7 | "hardhat": "yarn workspace @mono/hardhat hardhat", 8 | 9 | "subgraph": "yarn workspace @mono/subgraph", 10 | 11 | "next": "yarn workspace @mono/next", 12 | "dev": "yarn next dev", 13 | "lint": "yarn next lint" 14 | } 15 | } -------------------------------------------------------------------------------- /packages/next/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 | -------------------------------------------------------------------------------- /packages/hardhat/.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: 2 | - airbnb-base-typescript-prettier 3 | parserOptions: 4 | project: ./tsconfig.json 5 | root: true 6 | rules: 7 | "import/extensions": 8 | - "error" 9 | - { "ts": "never", "d.ts": "never" } 10 | "import/prefer-default-export": "off" 11 | "import/no-extraneous-dependencies": "off" 12 | # Needed for Mocha context 13 | "prefer-arrow-callback": "off" 14 | -------------------------------------------------------------------------------- /packages/hardhat/tasks/clean.ts: -------------------------------------------------------------------------------- 1 | import fsExtra from "fs-extra"; 2 | import { TASK_CLEAN } from "hardhat/builtin-tasks/task-names"; 3 | import { task } from "hardhat/config"; 4 | 5 | task(TASK_CLEAN, "Overrides the standard clean task", async (_taskArgs, { config }, runSuper) => { 6 | await fsExtra.remove("./coverage"); 7 | await fsExtra.remove("./coverage.json"); 8 | if (config.typechain?.outDir) { 9 | await fsExtra.remove(config.typechain.outDir); 10 | } 11 | await runSuper(); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/hardhat/tasks/accounts.ts: -------------------------------------------------------------------------------- 1 | import { Signer } from "@ethersproject/abstract-signer"; 2 | import { task } from "hardhat/config"; 3 | 4 | import { TASK_ACCOUNTS } from "./task-names"; 5 | 6 | task(TASK_ACCOUNTS, "Prints the list of accounts", async (_taskArgs, hre) => { 7 | const signers: Signer[] = await hre.ethers.getSigners(); 8 | const addresses = await Promise.all(signers.map(signer => signer.getAddress())); 9 | 10 | // eslint-disable-next-line no-console 11 | console.log(addresses); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/hardhat/config/env.ts: -------------------------------------------------------------------------------- 1 | import { config as dotenvConfig } from "dotenv"; 2 | import { resolve } from "path"; 3 | 4 | dotenvConfig({ path: resolve(__dirname, "../.env") }); 5 | 6 | // Ensure that we have all the environment variables we need. 7 | if (!process.env.MNEMONIC) { 8 | throw new Error("Please set your MNEMONIC in a .env file"); 9 | } 10 | 11 | export const mnemonic: string = process.env.MNEMONIC; 12 | export const infuraApiKey = process.env.INFURA_API_KEY; 13 | export const maticVigilApiKey = process.env.MATICVIGIL_API_KEY; 14 | -------------------------------------------------------------------------------- /packages/subgraph/bin/Counter.bin: -------------------------------------------------------------------------------- 1 | 60806040526000808190555060f5806100196000396000f3fe6080604052600436106043576000357c0100000000000000000000000000000000000000000000000000000000900480633fa4f245146048578063d09de08a146070575b600080fd5b348015605357600080fd5b50605a6078565b6040518082815260200191505060405180910390f35b6076607e565b005b60005481565b600160008082825401925050819055507f20d8a6f5a693f9d1d627a598e8820f7a55ee74c183aa8f1a30e8d4e8dd9a8d846000546040518082815260200191505060405180910390a156fea165627a7a72305820fca3d11af59a6ac98027ec3bebdb10711f195860d6d9abd07921c88c8c50228f0029 -------------------------------------------------------------------------------- /packages/next/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /packages/hardhat/deploy/001_deploy_greeter.ts: -------------------------------------------------------------------------------- 1 | import { HardhatRuntimeEnvironment } from "hardhat/types"; 2 | import { DeployFunction } from "hardhat-deploy/types"; 3 | 4 | const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { 5 | const { deployments, getNamedAccounts } = hre; 6 | 7 | const { deployer } = await getNamedAccounts(); 8 | const greeting = "Hello, world!"; 9 | 10 | await deployments.deploy("Greeter", { 11 | from: deployer, 12 | args: [greeting], 13 | log: true, 14 | }); 15 | }; 16 | 17 | export default func; 18 | -------------------------------------------------------------------------------- /packages/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mono/next", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "eslint . --ext ts --ext tsx" 10 | }, 11 | "dependencies": { 12 | "next": "10.1.3", 13 | "react": "17.0.2", 14 | "react-dom": "17.0.2" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^17.0.3", 18 | "eslint": "^7.24.0", 19 | "eslint-config-airbnb-typescript-prettier": "^4.2.0", 20 | "prettier": "^2.2.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/subgraph/migrations/3_create_gravatars.js: -------------------------------------------------------------------------------- 1 | const GravatarRegistry = artifacts.require('./GravatarRegistry.sol') 2 | 3 | module.exports = async function(deployer) { 4 | const registry = await GravatarRegistry.deployed() 5 | 6 | console.log('Account address:', registry.address) 7 | 8 | let accounts = await web3.eth.getAccounts() 9 | await registry.createGravatar('Carl', 'https://thegraph.com/img/team/team_04.png', { 10 | from: accounts[0], 11 | }) 12 | await registry.createGravatar('Lucas', 'https://thegraph.com/img/team/bw_Lucas.jpg', { 13 | from: accounts[1], 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /packages/hardhat/.solcover.js: -------------------------------------------------------------------------------- 1 | const shell = require("shelljs"); 2 | const { mnemonic } = require("./config"); 3 | 4 | module.exports = { 5 | istanbulReporter: ["html"], 6 | onCompileComplete: async function (_config) { 7 | await run("typechain"); 8 | }, 9 | onIstanbulComplete: async function (_config) { 10 | // We need to do this because solcover generates bespoke artifacts. 11 | shell.rm("-rf", "./artifacts"); 12 | shell.rm("-rf", "./typechain"); 13 | }, 14 | providerOptions: { 15 | mnemonic, 16 | }, 17 | skipFiles: ["mocks", "test"], 18 | }; 19 | -------------------------------------------------------------------------------- /packages/hardhat/.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "code-complexity": ["error", 7], 6 | "compiler-version": ["error", "0.8.0"], 7 | "const-name-snakecase": "off", 8 | "constructor-syntax": "error", 9 | "func-visibility": ["error", { "ignoreConstructors": true }], 10 | "max-line-length": ["error", 120], 11 | "not-rely-on-time": "off", 12 | "prettier/prettier": [ 13 | "error", 14 | { 15 | "endOfLine": "auto" 16 | } 17 | ], 18 | "reason-string": ["warn", { "maxLength": 64 }] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/subgraph/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve" 20 | }, 21 | "include": [ 22 | "next-env.d.ts", 23 | "**/*.ts", 24 | "**/*.tsx" 25 | ], 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /packages/hardhat/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity 0.8.0; 4 | 5 | import "hardhat/console.sol"; 6 | 7 | contract Greeter { 8 | string public greeting; 9 | 10 | constructor(string memory _greeting) { 11 | console.log("Deploying a Greeter with greeting:", _greeting); 12 | greeting = _greeting; 13 | } 14 | 15 | function greet() public view returns (string memory) { 16 | return greeting; 17 | } 18 | 19 | function setGreeting(string memory _greeting) public { 20 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 21 | greeting = _greeting; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/hardhat/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "forceConsistentCasingInFileNames": true, 5 | "lib": ["es5", "es6"], 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "noImplicitAny": true, 9 | "outDir": "dist", 10 | "resolveJsonModule": true, 11 | "sourceMap": true, 12 | "strict": true, 13 | "target": "ES5" 14 | }, 15 | "exclude": ["node_modules"], 16 | "include": [ 17 | "artifacts/**/*", 18 | "artifacts/**/*.json", 19 | "deploy/**/*", 20 | "scripts/**/*", 21 | "tasks/**/*", 22 | "test/**/*", 23 | "typechain/**/*", 24 | "types/**/*", 25 | "hardhat.config.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/subgraph/truffle.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | require('babel-polyfill') 3 | const HDWalletProvider = require('truffle-hdwallet-provider') 4 | 5 | module.exports = { 6 | networks: { 7 | development: { 8 | host: '127.0.0.1', 9 | port: 8545, 10 | network_id: '*', 11 | }, 12 | ropsten: { 13 | provider: function() { 14 | return new HDWalletProvider( 15 | process.env.MNEMONIC, 16 | `https://ropsten.infura.io/v3/${process.env.ROPSTEN_INFURA_API_KEY}` 17 | ) 18 | }, 19 | network_id: '3', 20 | }, 21 | }, 22 | compilers: { 23 | solc: { 24 | version: '0.4.25' // Fetch exact version from solc-bin (default: truffle's version) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/next/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | // import App from "next/app"; 2 | import type { AppProps /*, AppContext */ } from 'next/app' 3 | 4 | function MyApp({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | 8 | // Only uncomment this method if you have blocking data requirements for 9 | // every single page in your application. This disables the ability to 10 | // perform automatic static optimization, causing every page in your app to 11 | // be server-side rendered. 12 | // 13 | // MyApp.getInitialProps = async (appContext: AppContext) => { 14 | // // calls page's `getInitialProps` and fills `appProps.pageProps` 15 | // const appProps = await App.getInitialProps(appContext); 16 | 17 | // return { ...appProps } 18 | // } 19 | 20 | export default MyApp -------------------------------------------------------------------------------- /packages/subgraph/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { NewGravatar, UpdatedGravatar } from '../generated/Gravity/Gravity' 2 | import { Gravatar } from '../generated/schema' 3 | 4 | export function handleNewGravatar(event: NewGravatar): void { 5 | let gravatar = new Gravatar(event.params.id.toHex()) 6 | gravatar.owner = event.params.owner 7 | gravatar.displayName = event.params.displayName 8 | gravatar.imageUrl = event.params.imageUrl 9 | gravatar.save() 10 | } 11 | 12 | export function handleUpdatedGravatar(event: UpdatedGravatar): void { 13 | let id = event.params.id.toHex() 14 | let gravatar = Gravatar.load(id) 15 | if (gravatar == null) { 16 | gravatar = new Gravatar(id) 17 | } 18 | gravatar.owner = event.params.owner 19 | gravatar.displayName = event.params.displayName 20 | gravatar.imageUrl = event.params.imageUrl 21 | gravatar.save() 22 | } 23 | -------------------------------------------------------------------------------- /packages/subgraph/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | description: Gravatar for Ethereum 3 | repository: https://github.com/graphprotocol/example-subgraph 4 | schema: 5 | file: ./schema.graphql 6 | dataSources: 7 | - kind: ethereum/contract 8 | name: Gravity 9 | network: mainnet 10 | source: 11 | address: '0x2E645469f354BB4F5c8a05B3b30A929361cf77eC' 12 | abi: Gravity 13 | mapping: 14 | kind: ethereum/events 15 | apiVersion: 0.0.4 16 | language: wasm/assemblyscript 17 | entities: 18 | - Gravatar 19 | abis: 20 | - name: Gravity 21 | file: ./abis/Gravity.json 22 | eventHandlers: 23 | - event: NewGravatar(uint256,address,string,string) 24 | handler: handleNewGravatar 25 | - event: UpdatedGravatar(uint256,address,string,string) 26 | handler: handleUpdatedGravatar 27 | file: ./src/mapping.ts 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hardhat Next Subgraph Mono 2 | 3 | Monorepo setup using: 4 | - Solidity Template by @TomAFrench and @paulrberg 5 | - NextJS with Typescript and EsLint 6 | - theGraph 7 | 8 | 9 | ## hardhat 10 | The contracts, with tests and tasks to publish new content, using Solidity Template 11 | 12 | ## next 13 | The UI for the website, to interact with the protocol and publish new content, using NextJS 14 | 15 | ## subgraph 16 | The subgraph code to track new posts, using TheGraph 17 | 18 | # Commands 19 | 20 | ## Shortcuts 21 | ``` 22 | yarn hardhat 23 | ``` 24 | ``` 25 | yarn next 26 | ``` 27 | ``` 28 | yarn subgraph 29 | ``` 30 | 31 | ### Example: Deploy with Hardhat 32 | ``` 33 | yarn hardhat deploy 34 | ``` 35 | 36 | ### Example Run NextJS in Development Mode 37 | ``` 38 | yarn next dev 39 | ``` 40 | 41 | # Setup Hardhat 42 | 43 | Rename `.env.example` to `.env` and fill in the details 44 | 45 | # Setup Subgraph 46 | 47 | Rename `YOU_GITHUB/SUB_GRAPHNAME` in `subgraph/package.json` -------------------------------------------------------------------------------- /packages/hardhat/LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright 2021 Tom French 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /packages/next/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /packages/subgraph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SUB_GRAPHNAME", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "build-contract": "solc contracts/Gravity.sol --abi -o abis --overwrite && solc contracts/Gravity.sol --bin -o bin --overwrite", 6 | "create": "graph create YOU_GITHUB/SUB_GRAPHNAME --node https://api.thegraph.com/deploy/", 7 | "create-local": "graph create YOU_GITHUB/SUB_GRAPHNAME --node http://127.0.0.1:8020", 8 | "codegen": "graph codegen", 9 | "build": "graph build", 10 | "deploy": "graph deploy YOU_GITHUB/SUB_GRAPHNAME --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/", 11 | "deploy-local": "graph deploy YOU_GITHUB/SUB_GRAPHNAME --ipfs http://localhost:5001 --node http://127.0.0.1:8020" 12 | }, 13 | "devDependencies": { 14 | "@graphprotocol/graph-cli": "^0.20.0", 15 | "@graphprotocol/graph-ts": "^0.20.0" 16 | }, 17 | "dependencies": { 18 | "babel-polyfill": "^6.26.0", 19 | "babel-register": "^6.26.0", 20 | "truffle": "^5.0.4", 21 | "truffle-contract": "^4.0.5", 22 | "truffle-hdwallet-provider": "^1.0.4" 23 | } 24 | } -------------------------------------------------------------------------------- /packages/subgraph/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 The Graph 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/subgraph/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .env 3 | 4 | .DS_Store 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # Optional npm cache directory 48 | .npm 49 | 50 | # Optional eslint cache 51 | .eslintcache 52 | 53 | # Optional REPL history 54 | .node_repl_history 55 | 56 | # Output of 'npm pack' 57 | *.tgz 58 | 59 | # Yarn Integrity file 60 | .yarn-integrity 61 | 62 | # dotenv environment variables file 63 | .env 64 | 65 | # next.js build output 66 | .next 67 | -------------------------------------------------------------------------------- /packages/hardhat/test/helpers/deploy.ts: -------------------------------------------------------------------------------- 1 | import { MockContract } from "ethereum-waffle"; 2 | import { Contract, Signer } from "ethers"; 3 | import { deployments, ethers, waffle } from "hardhat"; 4 | 5 | export async function deploy( 6 | deploymentName: string, 7 | { from, args, connect }: { from?: string; args: Array; connect?: Signer }, 8 | contractName: string = deploymentName, 9 | ): Promise { 10 | // Unless overridden, deploy from named address "deployer" 11 | if (from === undefined) { 12 | const deployer = await ethers.getNamedSigner("deployer"); 13 | // eslint-disable-next-line no-param-reassign 14 | from = deployer.address; 15 | } 16 | 17 | const deployment = await deployments.deploy(deploymentName, { 18 | from, 19 | contract: contractName, 20 | args, 21 | log: true, 22 | }); 23 | 24 | const instance = await ethers.getContractAt(deploymentName, deployment.address); 25 | 26 | return connect ? instance.connect(connect) : instance; 27 | } 28 | 29 | export async function deployMock(contractName: string, connect?: Signer): Promise { 30 | const artifact = await deployments.getArtifact(contractName); 31 | const deployer = await ethers.getNamedSigner("deployer"); 32 | return waffle.deployMockContract(connect ?? deployer, artifact.abi); 33 | } 34 | -------------------------------------------------------------------------------- /packages/next/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /packages/hardhat/test/Greeter.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable func-names */ 2 | import { expect } from "chai"; 3 | import { MockContract } from "ethereum-waffle"; 4 | import { deployments, ethers } from "hardhat"; 5 | import { Greeter } from "../typechain"; 6 | import { deploy, deployMock } from "./helpers"; 7 | 8 | const setup = deployments.createFixture(async () => { 9 | const admin = await ethers.getNamedSigner("admin"); 10 | const greeter = (await deploy("Greeter", { args: ["Hello, world!"], connect: admin })) as Greeter; 11 | const mockGreeter = await deployMock("Greeter", admin); 12 | 13 | return { 14 | greeter, 15 | mockGreeter, 16 | }; 17 | }); 18 | 19 | describe("Unit tests", function () { 20 | describe("Greeter", function () { 21 | let greeter: Greeter; 22 | let mockGreeter: MockContract; 23 | 24 | beforeEach(async function () { 25 | const deployment = await setup(); 26 | greeter = deployment.greeter; 27 | mockGreeter = deployment.mockGreeter; 28 | }); 29 | 30 | it("should return the new greeting once it's changed", async function () { 31 | expect(await greeter.greet()).to.equal("Hello, world!"); 32 | 33 | await greeter.setGreeting("Hola, mundo!"); 34 | expect(await greeter.greet()).to.equal("Hola, mundo!"); 35 | }); 36 | 37 | it("should return the expected greeting when mocked", async function () { 38 | // Not really a proper test, just demonstrating how to mock contracts 39 | await mockGreeter.mock.greet.returns("I'm a mock!"); 40 | expect(await mockGreeter.greet()).to.equal("I'm a mock!"); 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /packages/subgraph/abis/Gravity.json: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"_imageUrl","type":"string"}],"name":"updateGravatarImage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"setMythicalGravatar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"getGravatar","outputs":[{"name":"","type":"string"},{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"gravatarToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"ownerToGravatar","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_displayName","type":"string"}],"name":"updateGravatarName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_displayName","type":"string"},{"name":"_imageUrl","type":"string"}],"name":"createGravatar","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"gravatars","outputs":[{"name":"owner","type":"address"},{"name":"displayName","type":"string"},{"name":"imageUrl","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"displayName","type":"string"},{"indexed":false,"name":"imageUrl","type":"string"}],"name":"NewGravatar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"displayName","type":"string"},{"indexed":false,"name":"imageUrl","type":"string"}],"name":"UpdatedGravatar","type":"event"}] 2 | -------------------------------------------------------------------------------- /packages/hardhat/README.md: -------------------------------------------------------------------------------- 1 | # Solidity Template 2 | 3 | My favourite setup for writing Solidity smart contracts. 4 | 5 | - [Hardhat](https://github.com/nomiclabs/hardhat): compile and run the smart contracts on a local development network 6 | - [hardhat-deploy](https://github.com/wighawag/hardhat-deploy): intelligently manage contract deployments and Etherscan verification 7 | - [TypeChain](https://github.com/ethereum-ts/TypeChain): generate TypeScript types for smart contracts 8 | - [Ethers](https://github.com/ethers-io/ethers.js/): renowned Ethereum library and wallet implementation 9 | - [Waffle](https://github.com/EthWorks/Waffle): tooling for writing comprehensive smart contract tests 10 | - [Solhint](https://github.com/protofire/solhint): linter 11 | - [Solcover](https://github.com/sc-forks/solidity-coverage) code coverage 12 | - [Prettier Plugin Solidity](https://github.com/prettier-solidity/prettier-plugin-solidity): code formatter 13 | 14 | This is a GitHub template, which means you can reuse it as many times as you want. You can do that by clicking the "Use this 15 | template" button at the top of the page. 16 | 17 | ## Usage 18 | 19 | ### Pre Requisites 20 | 21 | Before running any command, make sure to install dependencies: 22 | 23 | ```sh 24 | yarn install 25 | ``` 26 | 27 | ### Compile 28 | 29 | Compile the smart contracts with Hardhat: 30 | 31 | ```sh 32 | yarn compile 33 | ``` 34 | 35 | ### TypeChain 36 | 37 | Compile the smart contracts and generate TypeChain artifacts: 38 | 39 | ```sh 40 | yarn build 41 | ``` 42 | 43 | ### Lint Solidity 44 | 45 | Lint the Solidity code: 46 | 47 | ```sh 48 | yarn lint:sol 49 | ``` 50 | 51 | ### Lint TypeScript 52 | 53 | Lint the TypeScript code: 54 | 55 | ```sh 56 | yarn lint:ts 57 | ``` 58 | 59 | ### Test 60 | 61 | Run the Mocha tests: 62 | 63 | ```sh 64 | yarn test 65 | ``` 66 | 67 | ### Coverage 68 | 69 | Generate the code coverage report: 70 | 71 | ```sh 72 | yarn coverage 73 | ``` 74 | 75 | ### Clean 76 | 77 | Delete the smart contract artifacts, the coverage reports and the Hardhat cache: 78 | 79 | ```sh 80 | yarn clean 81 | ``` 82 | -------------------------------------------------------------------------------- /packages/hardhat/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig } from "hardhat/config"; 2 | import { ChainId, getRemoteNetworkConfig, mnemonic } from "./config"; 3 | import "./tasks"; 4 | 5 | import "hardhat-deploy"; 6 | // To make hardhat-waffle compatible with hardhat-deploy 7 | // we have aliased hardhat-ethers to hardhat-ethers-deploy in package.json 8 | import "@nomiclabs/hardhat-waffle"; 9 | import "hardhat-gas-reporter"; 10 | import "@typechain/hardhat"; 11 | import "solidity-coverage"; 12 | import "@nomiclabs/hardhat-etherscan"; 13 | 14 | const accounts = { 15 | count: 10, 16 | initialIndex: 0, 17 | mnemonic, 18 | path: "m/44'/60'/0'/0", 19 | }; 20 | 21 | const config: HardhatUserConfig = { 22 | defaultNetwork: "hardhat", 23 | namedAccounts: { 24 | deployer: 0, // Do not use this account for testing 25 | admin: 1, 26 | }, 27 | networks: { 28 | hardhat: { 29 | chainId: ChainId.hardhat, 30 | saveDeployments: false, 31 | }, 32 | goerli: { accounts, ...getRemoteNetworkConfig("goerli") }, 33 | kovan: { accounts, ...getRemoteNetworkConfig("kovan") }, 34 | rinkeby: { accounts, ...getRemoteNetworkConfig("rinkeby") }, 35 | ropsten: { accounts, ...getRemoteNetworkConfig("ropsten") }, 36 | }, 37 | paths: { 38 | artifacts: "./artifacts", 39 | cache: "./cache", 40 | sources: "./contracts", 41 | tests: "./test", 42 | }, 43 | solidity: { 44 | version: "0.8.0", 45 | settings: { 46 | // https://hardhat.org/hardhat-network/#solidity-optimizer-support 47 | optimizer: { 48 | enabled: true, 49 | runs: 200, 50 | }, 51 | }, 52 | }, 53 | typechain: { 54 | outDir: "typechain", 55 | target: "ethers-v5", 56 | }, 57 | gasReporter: { 58 | currency: "USD", 59 | gasPrice: 100, 60 | excludeContracts: ["Mock", "ERC20"], 61 | }, 62 | etherscan: { 63 | apiKey: process.env.ETHERSCAN_API_KEY 64 | } 65 | }; 66 | 67 | export default config; 68 | -------------------------------------------------------------------------------- /packages/subgraph/contracts/Gravity.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract GravatarRegistry { 4 | event NewGravatar(uint id, address owner, string displayName, string imageUrl); 5 | event UpdatedGravatar(uint id, address owner, string displayName, string imageUrl); 6 | 7 | struct Gravatar { 8 | address owner; 9 | string displayName; 10 | string imageUrl; 11 | } 12 | 13 | Gravatar[] public gravatars; 14 | 15 | mapping (uint => address) public gravatarToOwner; 16 | mapping (address => uint) public ownerToGravatar; 17 | 18 | function createGravatar(string _displayName, string _imageUrl) public { 19 | require(ownerToGravatar[msg.sender] == 0); 20 | uint id = gravatars.push(Gravatar(msg.sender, _displayName, _imageUrl)) - 1; 21 | 22 | gravatarToOwner[id] = msg.sender; 23 | ownerToGravatar[msg.sender] = id; 24 | 25 | emit NewGravatar(id, msg.sender, _displayName, _imageUrl); 26 | } 27 | 28 | function getGravatar(address owner) public view returns (string, string) { 29 | uint id = ownerToGravatar[owner]; 30 | return (gravatars[id].displayName, gravatars[id].imageUrl); 31 | } 32 | 33 | function updateGravatarName(string _displayName) public { 34 | require(ownerToGravatar[msg.sender] != 0); 35 | require(msg.sender == gravatars[ownerToGravatar[msg.sender]].owner); 36 | 37 | uint id = ownerToGravatar[msg.sender]; 38 | 39 | gravatars[id].displayName = _displayName; 40 | emit UpdatedGravatar(id, msg.sender, _displayName, gravatars[id].imageUrl); 41 | } 42 | 43 | function updateGravatarImage(string _imageUrl) public { 44 | require(ownerToGravatar[msg.sender] != 0); 45 | require(msg.sender == gravatars[ownerToGravatar[msg.sender]].owner); 46 | 47 | uint id = ownerToGravatar[msg.sender]; 48 | 49 | gravatars[id].imageUrl = _imageUrl; 50 | emit UpdatedGravatar(id, msg.sender, gravatars[id].displayName, _imageUrl); 51 | } 52 | 53 | // the gravatar at position 0 of gravatars[] 54 | // is fake 55 | // it's a mythical gravatar 56 | // that doesn't really exist 57 | // dani will invoke this function once when this contract is deployed 58 | // but then no more 59 | function setMythicalGravatar() public { 60 | require(msg.sender == 0x8d3e809Fbd258083a5Ba004a527159Da535c8abA); 61 | gravatars.push(Gravatar(0x0, " ", " ")); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/hardhat/config/networks.ts: -------------------------------------------------------------------------------- 1 | import { infuraApiKey, maticVigilApiKey } from "./env"; 2 | 3 | export enum ChainId { 4 | ganache = 1337, 5 | goerli = 5, 6 | hardhat = 31337, 7 | kovan = 42, 8 | mainnet = 1, 9 | matic = 137, 10 | mumbai = 80001, 11 | rinkeby = 4, 12 | ropsten = 3, 13 | xdai = 100, 14 | } 15 | 16 | // Delegate requests for a network config to a provider specific function based on which networks they serve 17 | 18 | // Ethereum 19 | const infuraChains = ["goerli", "kovan", "mainnet", "rinkeby", "ropsten"] as const; 20 | type InfuraChain = typeof infuraChains[number]; 21 | const getInfuraConfig = (network: InfuraChain): { url: string; chainId: number } => { 22 | if (!process.env.INFURA_API_KEY) { 23 | throw new Error("Please set your INFURA_API_KEY in a .env file"); 24 | } 25 | return { 26 | url: `https://${network}.infura.io/v3/${infuraApiKey}`, 27 | chainId: ChainId[network], 28 | }; 29 | }; 30 | 31 | // Matic 32 | const maticVigilChains = ["matic", "mumbai"] as const; 33 | type MaticVigilChain = typeof maticVigilChains[number]; 34 | const getMaticVigilConfig = (network: MaticVigilChain): { url: string; chainId: number } => { 35 | if (!maticVigilApiKey) { 36 | throw new Error("Please set your MATICVIGIL_API_KEY in a .env file"); 37 | } 38 | return { 39 | url: `https://rpc-${network}.maticvigil.com/v1/${maticVigilApiKey}`, 40 | chainId: ChainId[network], 41 | }; 42 | }; 43 | 44 | // xDai 45 | const xDaiChains = ["xdai"] as const; 46 | type XDaiChain = typeof xDaiChains[number]; 47 | const getXDaiConfig = (network: XDaiChain): { url: string; chainId: number } => { 48 | return { 49 | url: `https://rpc.xdaichain.com/`, 50 | chainId: ChainId[network], 51 | }; 52 | }; 53 | 54 | export type RemoteChain = InfuraChain | MaticVigilChain | XDaiChain; 55 | export const getRemoteNetworkConfig = (network: RemoteChain): { url: string; chainId: number } => { 56 | if (infuraChains.includes(network as InfuraChain)) return getInfuraConfig(network as InfuraChain); 57 | if (maticVigilChains.includes(network as MaticVigilChain)) return getMaticVigilConfig(network as MaticVigilChain); 58 | if (xDaiChains.includes(network as XDaiChain)) return getXDaiConfig(network as XDaiChain); 59 | throw Error("Unknown network"); 60 | }; 61 | -------------------------------------------------------------------------------- /packages/next/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import styles from '../styles/Home.module.css' 3 | 4 | const Home:React.FC =() => { 5 | return ( 6 | 64 | ) 65 | } 66 | 67 | export default Home 68 | -------------------------------------------------------------------------------- /packages/next/styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | min-height: 100vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .main { 11 | padding: 5rem 0; 12 | flex: 1; 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | .footer { 20 | width: 100%; 21 | height: 100px; 22 | border-top: 1px solid #eaeaea; 23 | display: flex; 24 | justify-content: center; 25 | align-items: center; 26 | } 27 | 28 | .footer img { 29 | margin-left: 0.5rem; 30 | } 31 | 32 | .footer a { 33 | display: flex; 34 | justify-content: center; 35 | align-items: center; 36 | } 37 | 38 | .title a { 39 | color: #0070f3; 40 | text-decoration: none; 41 | } 42 | 43 | .title a:hover, 44 | .title a:focus, 45 | .title a:active { 46 | text-decoration: underline; 47 | } 48 | 49 | .title { 50 | margin: 0; 51 | line-height: 1.15; 52 | font-size: 4rem; 53 | } 54 | 55 | .title, 56 | .description { 57 | text-align: center; 58 | } 59 | 60 | .description { 61 | line-height: 1.5; 62 | font-size: 1.5rem; 63 | } 64 | 65 | .code { 66 | background: #fafafa; 67 | border-radius: 5px; 68 | padding: 0.75rem; 69 | font-size: 1.1rem; 70 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, 71 | Bitstream Vera Sans Mono, Courier New, monospace; 72 | } 73 | 74 | .grid { 75 | display: flex; 76 | align-items: center; 77 | justify-content: center; 78 | flex-wrap: wrap; 79 | max-width: 800px; 80 | margin-top: 3rem; 81 | } 82 | 83 | .card { 84 | margin: 1rem; 85 | flex-basis: 45%; 86 | padding: 1.5rem; 87 | text-align: left; 88 | color: inherit; 89 | text-decoration: none; 90 | border: 1px solid #eaeaea; 91 | border-radius: 10px; 92 | transition: color 0.15s ease, border-color 0.15s ease; 93 | } 94 | 95 | .card:hover, 96 | .card:focus, 97 | .card:active { 98 | color: #0070f3; 99 | border-color: #0070f3; 100 | } 101 | 102 | .card h3 { 103 | margin: 0 0 1rem 0; 104 | font-size: 1.5rem; 105 | } 106 | 107 | .card p { 108 | margin: 0; 109 | font-size: 1.25rem; 110 | line-height: 1.5; 111 | } 112 | 113 | .logo { 114 | height: 1em; 115 | } 116 | 117 | @media (max-width: 600px) { 118 | .grid { 119 | width: 100%; 120 | flex-direction: column; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /packages/hardhat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mono/hardhat", 3 | "description": "Setup for writing Solidity smart contracts", 4 | "version": "1.0.0", 5 | "contributors": [ 6 | { 7 | "name": "Tom French", 8 | "url": "https://github.com/TomAFrench" 9 | }, 10 | { 11 | "name": "Paul Razvan Berg", 12 | "url": "https://paulrberg.com" 13 | } 14 | ], 15 | "devDependencies": { 16 | "@commitlint/cli": "^9.1.2", 17 | "@commitlint/config-conventional": "^9.1.2", 18 | "@ethersproject/abstract-signer": "^5.0.6", 19 | "@ethersproject/bignumber": "^5.0.8", 20 | "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers", 21 | "@nomiclabs/hardhat-etherscan": "^2.1.1", 22 | "@nomiclabs/hardhat-waffle": "^2.0.1", 23 | "@typechain/ethers-v5": "^5.0.0", 24 | "@typechain/hardhat": "^1.0.1", 25 | "@types/chai": "^4.2.13", 26 | "@types/fs-extra": "^9.0.1", 27 | "@types/mocha": "^7.0.2", 28 | "@types/node": "^14.11.8", 29 | "@typescript-eslint/eslint-plugin": "^4.14.0", 30 | "chai": "^4.2.0", 31 | "commitizen": "^4.2.1", 32 | "cz-conventional-changelog": "^3.3.0", 33 | "dotenv": "^8.2.0", 34 | "eslint": "^7.11.0", 35 | "eslint-config-airbnb-base-typescript-prettier": "^4.1.0", 36 | "eslint-config-prettier": "^6.12.0", 37 | "eslint-plugin-import": "^2.22.1", 38 | "ethereum-waffle": "^3.2.2", 39 | "fs-extra": "^9.0.1", 40 | "hardhat": "^2.0.10", 41 | "hardhat-deploy": "^0.7.0-beta.45", 42 | "hardhat-deploy-ethers": "^0.3.0-beta.7", 43 | "hardhat-gas-reporter": "^1.0.4", 44 | "husky": "^4.3.0", 45 | "mocha": "^8.1.3", 46 | "prettier": "^2.1.2", 47 | "prettier-plugin-solidity": "^1.0.0-beta.1", 48 | "shelljs": "^0.8.4", 49 | "solhint": "^3.3.2", 50 | "solhint-plugin-prettier": "^0.0.5", 51 | "solidity-coverage": "^0.7.15", 52 | "ts-generator": "^0.1.1", 53 | "ts-node": "^9.1.1", 54 | "typechain": "^4.0.2", 55 | "typescript": "^3.9.7" 56 | }, 57 | "files": [ 58 | "/contracts" 59 | ], 60 | "keywords": [ 61 | "blockchain", 62 | "ethereum", 63 | "hardhat", 64 | "smart-contracts", 65 | "solidity" 66 | ], 67 | "license": "MIT", 68 | "publishConfig": { 69 | "access": "public" 70 | }, 71 | "scripts": { 72 | "clean": "hardhat clean", 73 | "commit": "git-cz", 74 | "compile": "hardhat compile", 75 | "coverage": "hardhat coverage --solcoverjs ./.solcover.js --temp artifacts --testfiles \"./test/**/*.ts\"", 76 | "lint": "yarn run lint:sol && yarn run lint:ts && yarn run prettier:list-different", 77 | "lint:sol": "solhint --config ./.solhint.json --max-warnings 0 \"contracts/**/*.sol\"", 78 | "lint:ts": "eslint --config ./.eslintrc.yaml --ignore-path ./.eslintignore --ext .js,.ts .", 79 | "prettier": "prettier --config .prettierrc --write \"**/*.{js,json,md,sol,ts}\"", 80 | "prettier:list-different": "prettier --config .prettierrc --list-different \"**/*.{js,json,md,sol,ts}\"", 81 | "test": "hardhat test", 82 | "typechain": "hardhat typechain" 83 | } 84 | } 85 | --------------------------------------------------------------------------------