├── .gitignore ├── vue-app ├── .browserslistrc ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── img │ │ └── icons │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── mstile-150x150.png │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon-60x60.png │ │ │ ├── apple-touch-icon-76x76.png │ │ │ ├── apple-touch-icon-120x120.png │ │ │ ├── apple-touch-icon-152x152.png │ │ │ ├── apple-touch-icon-180x180.png │ │ │ ├── msapplication-icon-144x144.png │ │ │ ├── android-chrome-maskable-192x192.png │ │ │ ├── android-chrome-maskable-512x512.png │ │ │ └── safari-pinned-tab.svg │ └── index.html ├── cypress.json ├── babel.config.js ├── src │ ├── shims-vue.d.ts │ ├── assets │ │ └── logo.png │ ├── views │ │ ├── About.vue │ │ └── Home.vue │ ├── store │ │ └── index.ts │ ├── main.ts │ ├── shims-tsx.d.ts │ ├── App.vue │ ├── router │ │ └── index.ts │ ├── registerServiceWorker.ts │ └── components │ │ └── HelloWorld.vue ├── tests │ ├── e2e │ │ ├── .eslintrc.js │ │ ├── specs │ │ │ └── test.js │ │ ├── support │ │ │ ├── index.js │ │ │ └── commands.js │ │ └── plugins │ │ │ └── index.js │ └── unit │ │ └── example.spec.ts ├── .gitignore ├── README.md ├── .eslintrc.js ├── tsconfig.json └── package.json ├── contracts ├── .gitattributes ├── .gitignore ├── networks.js ├── buidler.config.ts ├── tsconfig.json ├── .openzeppelin │ └── project.json ├── scripts │ └── deploy.js ├── contracts │ └── Counter.sol ├── tests │ └── counter.spec.ts └── package.json ├── .vscode ├── extensions.json └── settings.json ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /vue-app/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /contracts/.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /vue-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /vue-app/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /vue-app/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"] 3 | }; 4 | -------------------------------------------------------------------------------- /vue-app/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import Vue from "vue"; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /vue-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/favicon.ico -------------------------------------------------------------------------------- /vue-app/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/src/assets/logo.png -------------------------------------------------------------------------------- /contracts/.gitignore: -------------------------------------------------------------------------------- 1 | # Build specific files 2 | .openzeppelin/.session 3 | .openzeppelin/dev-*.json 4 | build 5 | cache 6 | node_modules -------------------------------------------------------------------------------- /vue-app/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /vue-app/public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/android-chrome-maskable-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/android-chrome-maskable-192x192.png -------------------------------------------------------------------------------- /vue-app/public/img/icons/android-chrome-maskable-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/proofoftom/buidler-waffle-typechain-oz-vue/HEAD/vue-app/public/img/icons/android-chrome-maskable-512x512.png -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "juanblanco.solidity", 6 | "ms-vscode.vscode-typescript-tslint-plugin" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /vue-app/tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["cypress"], 3 | env: { 4 | mocha: true, 5 | "cypress/globals": true 6 | }, 7 | rules: { 8 | strict: "off" 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /vue-app/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | 4 | Vue.use(Vuex); 5 | 6 | export default new Vuex.Store({ 7 | state: {}, 8 | mutations: {}, 9 | actions: {}, 10 | modules: {} 11 | }); 12 | -------------------------------------------------------------------------------- /contracts/networks.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | networks: { 3 | development: { 4 | protocol: "http", 5 | host: "localhost", 6 | port: 8545, 7 | gas: 5000000, 8 | gasPrice: 5e9, 9 | networkId: "*" 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /vue-app/tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe("My First Test", () => { 4 | it("Visits the app root url", () => { 5 | cy.visit("/"); 6 | cy.contains("h1", "Welcome to Your Vue.js + TypeScript App"); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /vue-app/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import "./registerServiceWorker"; 4 | import router from "./router"; 5 | import store from "./store"; 6 | 7 | Vue.config.productionTip = false; 8 | 9 | new Vue({ 10 | router, 11 | store, 12 | render: h => h(App) 13 | }).$mount("#app"); 14 | -------------------------------------------------------------------------------- /vue-app/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | /tests/e2e/videos/ 6 | /tests/e2e/screenshots/ 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /vue-app/src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from "vue"; 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /vue-app/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 19 | -------------------------------------------------------------------------------- /vue-app/tests/unit/example.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { shallowMount } from "@vue/test-utils"; 3 | import HelloWorld from "@/components/HelloWorld.vue"; 4 | 5 | describe("HelloWorld.vue", () => { 6 | it("renders props.msg when passed", () => { 7 | const msg = "new message"; 8 | const wrapper = shallowMount(HelloWorld, { 9 | propsData: { msg } 10 | }); 11 | expect(wrapper.text()).to.include(msg); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /contracts/buidler.config.ts: -------------------------------------------------------------------------------- 1 | import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config"; 2 | 3 | usePlugin("@nomiclabs/buidler-waffle"); 4 | usePlugin("buidler-typechain"); 5 | 6 | const config: BuidlerConfig = { 7 | paths: { 8 | artifacts: "build/contracts", 9 | tests: "tests" 10 | }, 11 | solc: { 12 | version: "0.6.4" 13 | }, 14 | typechain: { 15 | outDir: "build/types", 16 | target: "ethers" 17 | } 18 | }; 19 | 20 | export default config; -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll": true 4 | }, 5 | "editor.defaultFormatter": "esbenp.prettier-vscode", 6 | "eslint.packageManager": "yarn", 7 | "eslint.validate": [ 8 | "vue", 9 | "json", 10 | "javascript", 11 | "javascriptreact", 12 | "typescript", 13 | "typescriptreact" 14 | ], 15 | "solidity.compileUsingRemoteVersion": "0.6.4+commit.1dca32f3", 16 | "solidity.packageDefaultDependenciesContractsDirectory": "" 17 | } 18 | -------------------------------------------------------------------------------- /contracts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "resolveJsonModule": true 9 | }, 10 | "include": ["./scripts", "./tests"], 11 | "files": [ 12 | "./buidler.config.ts", 13 | "./node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts", 14 | "./node_modules/@nomiclabs/buidler-waffle/src/type-extensions.d.ts", 15 | "./node_modules/buidler-typechain/src/type-extensions.d.ts" 16 | ] 17 | } -------------------------------------------------------------------------------- /vue-app/README.md: -------------------------------------------------------------------------------- 1 | # vue-app 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Run your unit tests 19 | ``` 20 | yarn test:unit 21 | ``` 22 | 23 | ### Run your end-to-end tests 24 | ``` 25 | yarn test:e2e 26 | ``` 27 | 28 | ### Lints and fixes files 29 | ``` 30 | yarn lint 31 | ``` 32 | 33 | ### Customize configuration 34 | See [Configuration Reference](https://cli.vuejs.org/config/). 35 | -------------------------------------------------------------------------------- /contracts/.openzeppelin/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestVersion": "2.2", 3 | "contracts": { 4 | "Counter": "Counter" 5 | }, 6 | "dependencies": {}, 7 | "name": "@my-app/contracts", 8 | "version": "0.1.0", 9 | "compiler": { 10 | "compilerSettings": { 11 | "optimizer": { 12 | "enabled": false, 13 | "runs": "200" 14 | } 15 | }, 16 | "typechain": { 17 | "enabled": true, 18 | "outDir": "build/types", 19 | "target": "ethers" 20 | }, 21 | "manager": "openzeppelin", 22 | "solcVersion": "0.6.4", 23 | "artifactsDir": "build/contracts", 24 | "contractsDir": "contracts" 25 | }, 26 | "telemetryOptIn": true 27 | } 28 | -------------------------------------------------------------------------------- /vue-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vue-app/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 33 | -------------------------------------------------------------------------------- /vue-app/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import VueRouter from "vue-router"; 3 | import Home from "../views/Home.vue"; 4 | 5 | Vue.use(VueRouter); 6 | 7 | const routes = [ 8 | { 9 | path: "/", 10 | name: "Home", 11 | component: Home 12 | }, 13 | { 14 | path: "/about", 15 | name: "About", 16 | // route level code-splitting 17 | // this generates a separate chunk (about.[hash].js) for this route 18 | // which is lazy-loaded when the route is visited. 19 | component: () => 20 | import(/* webpackChunkName: "about" */ "../views/About.vue") 21 | } 22 | ]; 23 | 24 | const router = new VueRouter({ 25 | mode: "history", 26 | base: process.env.BASE_URL, 27 | routes 28 | }); 29 | 30 | export default router; 31 | -------------------------------------------------------------------------------- /vue-app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: [ 7 | "plugin:vue/essential", 8 | "eslint:recommended", 9 | "@vue/typescript/recommended", 10 | "@vue/prettier", 11 | "@vue/prettier/@typescript-eslint" 12 | ], 13 | parserOptions: { 14 | ecmaVersion: 2020 15 | }, 16 | rules: { 17 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 18 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 19 | }, 20 | overrides: [ 21 | { 22 | files: [ 23 | "**/__tests__/*.{j,t}s?(x)", 24 | "**/tests/unit/**/*.spec.{j,t}s?(x)" 25 | ], 26 | env: { 27 | mocha: true 28 | } 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /vue-app/tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import "./commands"; 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /contracts/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | import { ethers } from "@nomiclabs/buidler"; 2 | 3 | async function main() { 4 | const factory = await ethers.getContract("Counter"); 5 | 6 | // If we had constructor arguments, they would be passed into deploy() 7 | const contract = await factory.deploy(); 8 | 9 | // The address that the Contract WILL have once mined 10 | console.log(contract.address); 11 | 12 | // The transaction that was sent to the network to deploy the Contract 13 | console.log(contract.deployTransaction.hash); 14 | 15 | // The contract is NOT deployed yet; we must wait until it is mined 16 | await contract.deployed(); 17 | } 18 | 19 | main() 20 | .then(() => process.exit(0)) 21 | .catch(error => { 22 | console.error(error); 23 | process.exit(1); 24 | }); 25 | -------------------------------------------------------------------------------- /vue-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "types": [ 15 | "webpack-env", 16 | "mocha", 17 | "chai" 18 | ], 19 | "paths": { 20 | "@/*": [ 21 | "src/*" 22 | ] 23 | }, 24 | "lib": [ 25 | "esnext", 26 | "dom", 27 | "dom.iterable", 28 | "scripthost" 29 | ] 30 | }, 31 | "include": [ 32 | "src/**/*.ts", 33 | "src/**/*.tsx", 34 | "src/**/*.vue", 35 | "tests/**/*.ts", 36 | "tests/**/*.tsx" 37 | ], 38 | "exclude": [ 39 | "node_modules" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /contracts/contracts/Counter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.4; 2 | 3 | import "@nomiclabs/buidler/console.sol"; 4 | 5 | contract Counter { 6 | uint256 public count; 7 | 8 | event CountedTo(uint256 number); 9 | 10 | function initialize() public { 11 | // Use this as you would typically use a constructor. 12 | } 13 | 14 | function countUp() public returns (uint256) { 15 | uint256 newCount = count + 1; 16 | console.log("countUp: newCount =", newCount); 17 | require(newCount > count, "uint256 overflow"); 18 | 19 | count = newCount; 20 | 21 | emit CountedTo(count); 22 | return count; 23 | } 24 | 25 | function countDown() public returns (uint256) { 26 | uint256 newCount = count - 1; 27 | console.log("countDown: newCount =", newCount); 28 | require(newCount < count, "uint256 underflow"); 29 | 30 | count = newCount; 31 | 32 | emit CountedTo(count); 33 | return count; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vue-app/tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /vue-app/tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable arrow-body-style */ 2 | // https://docs.cypress.io/guides/guides/plugins-guide.html 3 | 4 | // if you need a custom webpack configuration you can uncomment the following import 5 | // and then use the `file:preprocessor` event 6 | // as explained in the cypress docs 7 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples 8 | 9 | // /* eslint-disable import/no-extraneous-dependencies, global-require */ 10 | // const webpack = require('@cypress/webpack-preprocessor') 11 | 12 | module.exports = (on, config) => { 13 | // on('file:preprocessor', webpack({ 14 | // webpackOptions: require('@vue/cli-service/webpack.config'), 15 | // watchOptions: {} 16 | // })) 17 | 18 | return Object.assign({}, config, { 19 | fixturesFolder: "tests/e2e/fixtures", 20 | integrationFolder: "tests/e2e/specs", 21 | screenshotsFolder: "tests/e2e/screenshots", 22 | videosFolder: "tests/e2e/videos", 23 | supportFile: "tests/e2e/support/index.js" 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /vue-app/src/registerServiceWorker.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from "register-service-worker"; 4 | 5 | if (process.env.NODE_ENV === "production") { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready() { 8 | console.log( 9 | "App is being served from cache by a service worker.\n" + 10 | "For more details, visit https://goo.gl/AFskqB" 11 | ); 12 | }, 13 | registered() { 14 | console.log("Service worker has been registered."); 15 | }, 16 | cached() { 17 | console.log("Content has been cached for offline use."); 18 | }, 19 | updatefound() { 20 | console.log("New content is downloading."); 21 | }, 22 | updated() { 23 | console.log("New content is available; please refresh."); 24 | }, 25 | offline() { 26 | console.log( 27 | "No internet connection found. App is running in offline mode." 28 | ); 29 | }, 30 | error(error) { 31 | console.error("Error during service worker registration:", error); 32 | } 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-app/monorepo", 3 | "private": true, 4 | "workspaces": { 5 | "packages": ["contracts", "vue-app"], 6 | "nohoist": [ 7 | "**/@nomiclabs/**", 8 | "**/typescript", 9 | "**/ts-node", 10 | "**/@vue/**", 11 | "**/@openzeppelin/cli" 12 | ] 13 | }, 14 | "scripts": { 15 | "build": "yarn workspaces run build", 16 | "build:contracts": "yarn workspace @my-app/contracts run build", 17 | "build:web": "yarn workspace @my-app/vue-app run build", 18 | "start:dev": "yarn deploy:local && yarn start:web", 19 | "start:node": "yarn workspace @my-app/contracts run node", 20 | "start:web": "yarn workspace @my-app/vue-app run serve", 21 | "test": "yarn workspaces run test", 22 | "test:contracts": "yarn workspace @my-app/contracts run test", 23 | "test:web": "yarn workspace @my-app/vue-app run test", 24 | "deploy:local": "yarn workspace @my-app/contracts run deploy:local", 25 | "upgrade:local": "yarn workspace @my-app/contracts run upgrade:local", 26 | "lint:web": "yarn workspace @my-app/vue-app run lint" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/tests/counter.spec.ts: -------------------------------------------------------------------------------- 1 | import { waffle } from "@nomiclabs/buidler"; 2 | import chai from "chai"; 3 | import { deployContract, solidity } from "ethereum-waffle"; 4 | 5 | import CounterArtifact from "../build/contracts/Counter.json"; 6 | import { Counter } from "../build/types/Counter"; 7 | 8 | chai.use(solidity); 9 | const { expect } = chai; 10 | 11 | describe("Counter", () => { 12 | const provider = waffle.provider; 13 | const [wallet] = provider.getWallets(); 14 | 15 | // use contract type 16 | let counter: Counter; 17 | 18 | beforeEach(async () => { 19 | // cast as type 20 | counter = (await deployContract(wallet, CounterArtifact)) as Counter; 21 | 22 | // function name is available as part of types 23 | const initialCount = await counter.count(); 24 | 25 | expect(initialCount).to.eq(0); 26 | expect(counter.address).to.properAddress; 27 | }); 28 | 29 | it("should count up", async () => { 30 | await counter.countUp(); 31 | let count = await counter.count(); 32 | expect(count).to.eq(1); 33 | 34 | await counter.countUp(); 35 | count = await counter.count(); 36 | expect(count).to.eq(2); 37 | }); 38 | 39 | it("should count down", async () => { 40 | await counter.countUp(); 41 | let count = await counter.count(); 42 | expect(count).to.eq(1); 43 | 44 | await counter.countDown(); 45 | count = await counter.count(); 46 | expect(count).to.eq(0); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /contracts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-app/contracts", 3 | "version": "0.1.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "oz compile", 8 | "node": "npx buidler node", 9 | "deploy:local": "yarn clean && yarn build && oz create Counter --skip-compile -n development --init", 10 | "upgrade:local": "yarn build && oz upgrade Counter --skip-compile -n development --init", 11 | "deploy:goerli": "yarn clean && yarn build && oz create Counter --skip-compile -n goerli --init", 12 | "upgrade:goerli": "yarn build && oz upgrade Counter --skip-compile -n goerli --init", 13 | "test": "buidler typechain && buidler test", 14 | "clean": "rm -rf cache && rm -rf build && rm -f .openzeppelin/.session && rm -f .openzeppelin/dev-*.json" 15 | }, 16 | "devDependencies": { 17 | "@nomiclabs/buidler": "^1.2.0", 18 | "@nomiclabs/buidler-ethers": "^1.2.0", 19 | "@nomiclabs/buidler-truffle5": "^1.2.0", 20 | "@nomiclabs/buidler-waffle": "^1.2.0", 21 | "@nomiclabs/buidler-web3": "^1.2.0", 22 | "@openzeppelin/cli": "^2.7.2", 23 | "@types/chai": "^4.2.11", 24 | "@types/mocha": "^7.0.2", 25 | "@types/node": "^13.9.2", 26 | "@typescript-eslint/eslint-plugin": "^2.24.0", 27 | "@typescript-eslint/parser": "^2.24.0", 28 | "buidler-typechain": "^0.0.5", 29 | "chai": "^4.2.0", 30 | "ethereum-waffle": "^2.4.0", 31 | "ethers": "^4.0.46", 32 | "ts-generator": "^0.0.8", 33 | "ts-node": "^8.8.1", 34 | "typechain": "^1.0.5", 35 | "typechain-target-ethers": "^1.0.3", 36 | "typechain-target-truffle": "^1.0.2", 37 | "typechain-target-web3-v1": "^1.0.4", 38 | "typescript": "^3.8.3", 39 | "web3": "^1.2.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vue-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-app/vue-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "test": "yarn test:unit && yarn test:e2e", 9 | "test:unit": "vue-cli-service test:unit", 10 | "test:e2e": "vue-cli-service test:e2e", 11 | "lint": "vue-cli-service lint" 12 | }, 13 | "dependencies": { 14 | "core-js": "^3.6.4", 15 | "register-service-worker": "^1.6.2", 16 | "vue": "^2.6.11", 17 | "vue-class-component": "^7.2.2", 18 | "vue-property-decorator": "^8.3.0", 19 | "vue-router": "^3.1.5", 20 | "vuex": "^3.1.2" 21 | }, 22 | "devDependencies": { 23 | "@types/chai": "^4.2.8", 24 | "@types/mocha": "^5.2.4", 25 | "@typescript-eslint/eslint-plugin": "^2.18.0", 26 | "@typescript-eslint/parser": "^2.18.0", 27 | "@vue/cli-plugin-babel": "~4.2.0", 28 | "@vue/cli-plugin-e2e-cypress": "~4.2.0", 29 | "@vue/cli-plugin-eslint": "~4.2.0", 30 | "@vue/cli-plugin-pwa": "~4.2.0", 31 | "@vue/cli-plugin-router": "~4.2.0", 32 | "@vue/cli-plugin-typescript": "~4.2.0", 33 | "@vue/cli-plugin-unit-mocha": "~4.2.0", 34 | "@vue/cli-plugin-vuex": "~4.2.0", 35 | "@vue/cli-service": "~4.2.0", 36 | "@vue/eslint-config-prettier": "^6.0.0", 37 | "@vue/eslint-config-typescript": "^5.0.1", 38 | "@vue/test-utils": "1.0.0-beta.31", 39 | "chai": "^4.1.2", 40 | "eslint": "^6.7.2", 41 | "eslint-plugin-prettier": "^3.1.1", 42 | "eslint-plugin-vue": "^6.1.2", 43 | "lint-staged": "^9.5.0", 44 | "prettier": "^1.19.1", 45 | "sass": "^1.25.0", 46 | "sass-loader": "^8.0.2", 47 | "typescript": "~3.7.5", 48 | "vue-template-compiler": "^2.6.11" 49 | }, 50 | "gitHooks": { 51 | "pre-commit": "lint-staged" 52 | }, 53 | "lint-staged": { 54 | "*.{js,jsx,vue,ts,tsx}": [ 55 | "vue-cli-service lint", 56 | "git add" 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Buidler + Waffle + TypeChain + OpenZeppelin CLI + Vue (TypeScript) 2 | 3 | Inspired by [The New Solidity Dev Stack: Buidler + Ethers + Waffle + Typescript](https://medium.com/@rahulsethuram/the-new-solidity-dev-stack-buidler-ethers-waffle-typescript-tutorial-f07917de48ae), this is a pre-configured starter kit that uses the latest and greatest tool set to go from zero to hero 💪 in a quarter of the time, with 10x the type safety 🛡️ and debugging 🐞 capabilities. 4 | 5 | Leverage best practice tools such as: Buidler 🔨 for stack traces and `console.log` in contracts, TypeChain 🔗 for contract and front end type definitions, Waffle 🥞 for type safe ethers.js contract testing, and Vue with TypeScript/TypeChain support 🎀 to round out the stack. 6 | 7 | If that's not enough: hit the ground running with test driven development 🧪 following the examples provided for contract, unit, and end to end testing. Objectively know when functionality is complete ✅ while catching bugs in updates before releasing. 8 | 9 | As an added bonus: easily deploy upgradeable contracts - where one can update their contract logic 📝 while maintaining its state 🔒 - using the built-in OpenZeppelin CLI. Never worry about migrating again! 10 | 11 | Finally, there's lots of under the hood goodies that come pre-configured to build beautiful Progressive Web Apps 🦋 that include state management and routing; with more features being released rapidly! 12 | 13 | Next on deck: gasless transactions ⛽🔥 14 | 15 | Ready to develop like the pros? [Use this template to get started!](https://github.com/proofoftom/buidler-waffle-typechain-vue/generate) 🚀 16 | 17 | ## Using the template 18 | 19 | Once you've [generated a project](https://github.com/proofoftom/buidler-waffle-typechain-vue/generate) and cloned it locally: 20 | 21 | ### Install the dependencies 22 | ``` 23 | yarn 24 | ``` 25 | 26 | #### Compile and generate type definitions for your contracts 27 | ``` 28 | yarn build:contracts 29 | ``` 30 | 31 | #### Run your Waffle tests with stack traces 32 | ``` 33 | yarn test:contracts 34 | ``` 35 | 36 | #### Start the frontend app in development mode (hot-code contract reloading, revert reporting, etc.) 37 | ``` 38 | yarn start:node 39 | ``` 40 | and in a new terminal 41 | ``` 42 | yarn start:dev 43 | ``` 44 | then open the app running [locally](http://localhost:8080) in your favorite browser. 45 | 46 | #### Upgrade your contracts locally 47 | ``` 48 | yarn upgrade:local 49 | ``` 50 | 51 | #### Start the frontend sans a local blockchain 52 | ``` 53 | yarn start:web 54 | ``` 55 | 56 | #### Lint and fix files 57 | ``` 58 | yarn lint 59 | ``` 60 | 61 | #### Build the dApp for production 62 | ``` 63 | yarn build 64 | ``` 65 | 66 | #### Run your unit tests 67 | ``` 68 | yarn test:unit 69 | ``` 70 | 71 | #### Run your end-to-end tests 72 | ``` 73 | yarn test:e2e 74 | ``` 75 | 76 | #### Run ALL the tests! 77 | ``` 78 | yarn test 79 | ``` 80 | 81 | #### Customize Vue configuration 82 | See [Configuration Reference](https://cli.vuejs.org/config). 83 | 84 | #### Other Documentation 85 | * [Buidler](https://buidler.dev/getting-started) 86 | * [Waffle](https://ethereum-waffle.readthedocs.io) 87 | * [ethers.js](https://docs.ethers.io/ethers.js/html) 88 | * [TypeChain](https://github.com/ethereum-ts/TypeChain) 89 | * [OpenZeppelin CLI](https://docs.openzeppelin.com/cli/2.7) 90 | * [Vuetify](https://vuetifyjs.com/getting-started/quick-start) 91 | -------------------------------------------------------------------------------- /vue-app/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 136 | 137 | 145 | 146 | 147 | 163 | -------------------------------------------------------------------------------- /vue-app/public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | --------------------------------------------------------------------------------