diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5f94f08 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +WEBSOCKET=ws://127.0.0.1:8545 +ZKOPRU_ADDRESS=0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE +CHAINID=31337 diff --git a/.gitignore b/.gitignore index e9bcb8d..3c0ca02 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ wrangler.toml workers-site .vercel + +# dev module +zkopru diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c1e7dc8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "zkopru"] + path = zkopru + url = https://github.com/zkopru-network/zkopru diff --git a/README.md b/README.md index ff0785a..53ee5c2 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,34 @@ Draft accessible [here](https://alpha.wallet.zkopru.network/). Install modules as usual with `npm install`. -Additionally we need the `@zkopru/client` package. This needs to be linked locally because it's not published on npm. This can be done using yarn by running the following: - -- First in `zkopru/packages/client`: `yarn link` -- Then in `zkopru-web`: `yarn link @zkopru/client` +It will download `@zkopru/client` module which is published on npm. ## Development A development server with hot reload can be started with `npm run dev` it will be accessible at `localhost:8080`. + +## Development setup + +There are two options to using local `@zkopru/client` package without downloading from npm. + +1. Using `yarn link` + + This can be done using yarn by running the following: + + - First in `zkopru/packages/client`: `yarn link` + - Then in `zkopru-web`: `yarn link @zkopru/client` + + > Note that, you must unlink at some point. + +2. Using script + + For more convenience to develop alongside @zkopru/client, It would be better to use a client package that is locally cloned. + + For that, you can run `npm run install-dev`. It will run the script that clones the zkopru repo with the main branch then setup and build. + + If you are using the default hardhat node configuration in local environment, It would not need to load `.env` file. + + In some cases, you have to create `.env` (using `.env.example`) and then modify the hardhat node url, zkopru contract address and the chainId in the env file for connecting your hardhat node. + And please do not forget to build with `npm run build:dev` for applying the variables to the web server. + + To revert this setup, you can simply overwrite `package.json` with `package-prod.json` and then install it again. diff --git a/package-dev.json b/package-dev.json new file mode 100644 index 0000000..8165530 --- /dev/null +++ b/package-dev.json @@ -0,0 +1,67 @@ +{ + "name": "zkopru-webapp", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "NODE_ENV=development node server.js", + "dev": "webpack-dev-server", + "buildnum": "node scripts/buildversion", + "build": "webpack --config webpack.prod.js --progress", + "clean": "rm -rf build", + "server": "node server", + "ipfs": "npm run clean && npm run build && node scripts/ipfsify.js", + "stats": " webpack --profile --json > stats.json", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Chance Hudson", + "license": "MIT", + "dependencies": { + "axios": "^0.20.0", + "compression": "^1.7.4", + "dayjs": "^1.10.6", + "especial": "0.0.4", + "eth-ens-namehash": "^2.0.8", + "express": "^4.17.1", + "js-sha512": "^0.8.0", + "lottie-web": "^5.8.1", + "route-cache": "^0.4.5", + "vue": "^2.6.12", + "vue-class-component": "^7.2.5", + "vue-meta": "^2.4.0", + "vue-router": "^3.4.9", + "vuex": "^3.5.1" + }, + "devDependencies": { + "@babel/core": "^7.11.6", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-decorators": "^7.10.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@zkopru/client": "file:./zkopru/packages/client", + "babel-loader": "^8.1.0", + "chokidar": "^3.4.2", + "cidbadge": "^0.0.7", + "css-loader": "^3.2.0", + "dotenv-webpack": "^8.0.1", + "file-loader": "^6.1.0", + "has-tostringtag": "^1.0.0", + "html-webpack-inline-source-plugin": "0.0.10", + "html-webpack-plugin": "^4.4.1", + "husky": "^6.0.0", + "ipfs-unixfs-importer": "^9.0.6", + "memory-fs": "^0.5.0", + "svgo-loader": "^3.0.0", + "vue-loader": "^15.9.3", + "vue-server-renderer": "^2.6.12", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.6.12", + "webpack": "^4.44.1", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0", + "webpack-hot-middleware": "^2.25.0", + "webpack-merge": "^5.1.4", + "webpack-node-externals": "^2.5.2" + } +} diff --git a/package-prod.json b/package-prod.json new file mode 100644 index 0000000..ef8e422 --- /dev/null +++ b/package-prod.json @@ -0,0 +1,69 @@ +{ + "name": "zkopru-webapp", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "install-dev": "npm install --no-package-lock --no-save shelljs && node scripts/setupLocaldev.js && npm install", + "start": "NODE_ENV=development node server.js", + "dev": "webpack-dev-server", + "buildnum": "node scripts/buildversion", + "build": "webpack --config webpack.prod.js --progress", + "build:dev": "webpack --progress", + "clean": "rm -rf build", + "server": "node server", + "ipfs": "npm run clean && npm run build && node scripts/ipfsify.js", + "stats": " webpack --profile --json > stats.json", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Chance Hudson", + "license": "MIT", + "dependencies": { + "axios": "^0.20.0", + "compression": "^1.7.4", + "dayjs": "^1.10.6", + "especial": "0.0.4", + "eth-ens-namehash": "^2.0.8", + "express": "^4.17.1", + "js-sha512": "^0.8.0", + "lottie-web": "^5.8.1", + "route-cache": "^0.4.5", + "vue": "^2.6.12", + "vue-class-component": "^7.2.5", + "vue-meta": "^2.4.0", + "vue-router": "^3.4.9", + "vuex": "^3.5.1" + }, + "devDependencies": { + "@babel/core": "^7.11.6", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-decorators": "^7.10.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@zkopru/client": "^2.0.0-beta.5", + "babel-loader": "^8.1.0", + "chokidar": "^3.4.2", + "cidbadge": "^0.0.7", + "css-loader": "^3.2.0", + "dotenv-webpack": "^8.0.1", + "file-loader": "^6.1.0", + "has-tostringtag": "^1.0.0", + "html-webpack-inline-source-plugin": "0.0.10", + "html-webpack-plugin": "^4.4.1", + "husky": "^6.0.0", + "ipfs-unixfs-importer": "^9.0.6", + "memory-fs": "^0.5.0", + "svgo-loader": "^3.0.0", + "vue-loader": "^15.9.3", + "vue-server-renderer": "^2.6.12", + "vue-style-loader": "^4.1.2", + "vue-template-compiler": "^2.6.12", + "webpack": "^4.44.1", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0", + "webpack-hot-middleware": "^2.25.0", + "webpack-merge": "^5.1.4", + "webpack-node-externals": "^2.5.2" + } +} diff --git a/package.json b/package.json index d382f4b..ef8e422 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,12 @@ "description": "", "main": "index.js", "scripts": { + "install-dev": "npm install --no-package-lock --no-save shelljs && node scripts/setupLocaldev.js && npm install", "start": "NODE_ENV=development node server.js", "dev": "webpack-dev-server", "buildnum": "node scripts/buildversion", "build": "webpack --config webpack.prod.js --progress", + "build:dev": "webpack --progress", "clean": "rm -rf build", "server": "node server", "ipfs": "npm run clean && npm run build && node scripts/ipfsify.js", @@ -44,6 +46,7 @@ "chokidar": "^3.4.2", "cidbadge": "^0.0.7", "css-loader": "^3.2.0", + "dotenv-webpack": "^8.0.1", "file-loader": "^6.1.0", "has-tostringtag": "^1.0.0", "html-webpack-inline-source-plugin": "0.0.10", diff --git a/scripts/setupLocaldev.js b/scripts/setupLocaldev.js new file mode 100644 index 0000000..29d6975 --- /dev/null +++ b/scripts/setupLocaldev.js @@ -0,0 +1,18 @@ +// import shell from 'shelljs'; +var shell = require('shelljs'); + +if (!shell.which('git')) { + shell.echo('Sorry, this script requires git'); + shell.exit(1); +} + +// clone zkopru repo for `@zkopru/client` package +shell.echo(`Clone and build zkopru`) +shell.exec(`git submodule update --init`); +shell.cd(`zkopru`); +shell.exec(`yarn && yarn build:ts:serial`); +shell.cd(`..`); + +// copy package file which is replaced local path +shell.echo(`Override package.json for using client package in local`); +shell.cp(`-f`, `package-dev.json`, `package.json`); diff --git a/src/stores/zkopru.js b/src/stores/zkopru.js index 9db636c..8748ea8 100644 --- a/src/stores/zkopru.js +++ b/src/stores/zkopru.js @@ -1,5 +1,4 @@ import { fromWei } from '../utils/wei' -import dayjs from 'dayjs' import BN from 'bn.js' const DEFAULT_NETWORKS = { @@ -21,22 +20,26 @@ const DEFAULT_NETWORKS = { blockExplorerUrls: ['https://goerli.etherscan.io'] } }, - '69': { - NAME: 'Optimism testnet', - WEBSOCKET: 'wss://optimism-kovan.zkopru.network', +} + +if (process.env.NODE_ENV == "development") { + let chainId = '0x7A69' // 31337 + if (process.env.CHAINID) chainId = `0x${parseInt(process.env.CHAINID).toString(16)}` + + DEFAULT_NETWORKS[process.env.CHAINID ?? '31337'] = { + NAME: 'hardhat node', + WEBSOCKET: process.env.WEBSOCKET ?? 'ws://localhost:8546', ZKOPRU_ADDRESSES: [ - '0x31f3E51Fc7BE2BD24F258af92B0E371fa0A48762' // minimum stake amount 1 ETH + process.env.ZKOPRU_ADDRESS ?? '0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE' // ], METAMASK_PARAMS: { - chainId: '0x45', - chainName: 'Optimism-kovan', + chainId, + chainName: 'testnet', nativeCurrency: { - name: 'Optimism ETH', + name: 'hardhat ETH', symbol: 'ETH', decimals: 18 }, - rpcUrls: ['https://kovan.optimism.io'], - blockExplorerUrls: ['https://kovan-optimistic.etherscan.io'] } } } @@ -134,9 +137,9 @@ export default { // Error code 4902 - no added network in metamask if (error.code == 4902 || error.code) { try { - await window.ethereum.request({ - method: 'wallet_addEthereumChain', - params: [DEFAULT_NETWORKS[chainId].METAMASK_PARAMS] + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [DEFAULT_NETWORKS[chainId].METAMASK_PARAMS] }) rootState.chainId = chainId } catch (error) { diff --git a/webpack.config.js b/webpack.config.js index b041ae2..0581f50 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,13 +1,11 @@ const { merge } = require('webpack-merge') const common = require('./webpack.common') const path = require('path') -// const VueSSRClientPlugin = require('vue-server-renderer/client-plugin') +const Dotenv = require('dotenv-webpack') module.exports = merge(common, { mode: 'development', - plugins: [ - // new VueSSRClientPlugin(), - ], + plugins: [new Dotenv()], devServer: { contentBase: path.join(__dirname, 'build'), publicPath: '/', @@ -16,5 +14,5 @@ module.exports = merge(common, { rewrites: [{ from: /^\/[0-9A-Za-z-/]+$/, to: '/index.html' }], index: 'index.html', }, - }, + } }) diff --git a/zkopru b/zkopru new file mode 160000 index 0000000..d6a30a9 --- /dev/null +++ b/zkopru @@ -0,0 +1 @@ +Subproject commit d6a30a9494a634e25e45dbd496f07c85c59ff8cc