├── .gitignore
├── LICENSE
├── README.md
├── contracts
├── .gitkeep
└── Example.sol
├── deploy
├── .gitignore
├── compile.js
├── deploy.js
├── package-lock.json
└── package.json
├── package.json
├── pages
├── _app.js
├── _document.js
├── about.js
└── index.js
├── public
├── favicon.ico
├── icons
│ ├── icon-192x192.png
│ └── icon-512x512.png
├── img
│ └── background.png
├── logo.svg
├── manifest.json
└── robots.txt
├── src
├── components
│ ├── ConnectWallet.jsx
│ └── Navbar.jsx
├── contracts
│ └── Example.js
├── hooks
│ └── web3.js
└── utils
│ └── theme.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # misc
7 | .DS_Store
8 | .env.local
9 | .env.development.local
10 | .env.test.local
11 | .env.production.local
12 |
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 |
17 | # Next.js
18 | /.next
19 |
20 | .env
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Aman Raj
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Next.js Web3 template
3 |
4 | 🏗️ Next.js + Material UI + dark mode + web3 starter template ⚡
5 |
6 | This is a starter boilerplate Ethereum dapp using Next.js and material UI with dark mode. There are many web3 template available but most of them depends of web3-react. I tried to use minimum dependencies possible.
7 |
8 | ### Quick start
9 |
10 | The first things you need to do is clone repo.
11 |
12 | To compile and deploy contract
13 |
14 | ```bash
15 | cd deploy
16 | npm i
17 | npm start
18 | ```
19 |
20 | Run the client on base directory
21 |
22 | ```bash
23 | yarn install
24 | yarn run dev
25 | ```
26 |
27 | #### Project Structure
28 |
29 | ```
30 | ├── contracts // All solidity files
31 | │ ├── Example.sol
32 | ├── deploy
33 | │ ├── compile.js // compiles contracts
34 | │ ├── deploy.js // deploy and get abi and bytecode
35 | │ ├── package.json
36 | ├── pages // All pages of nextjs
37 | │ ├── _app.js
38 | │ ├── _documesnt.js
39 | ├── public // contains static files
40 | │ ├── img
41 | │ ├── icons
42 | ├── src
43 | │ ├── contracts // here we store abi and bytecodes of contracts
44 | │ ├── components // react components
45 | │ ├── hooks // web and imp hooks
46 | │ ├── utils // theme and other lib files
47 | ├── .env
48 | ├── .gitignore
49 | ├── package.json
50 | └── README.md
51 | ```
52 |
--------------------------------------------------------------------------------
/contracts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmanRaj1608/nextjs-web3-template/d3b73ea56c7f2c7e54c2df39e11b800fcb72ecd9/contracts/.gitkeep
--------------------------------------------------------------------------------
/contracts/Example.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0
2 |
3 | pragma solidity >=0.7.0 <0.8.3;
4 |
5 | contract Example {
6 | uint256 number;
7 |
8 | function store(uint256 num) public {
9 | number = num;
10 | }
11 |
12 | function retrieve() public view returns (uint256) {
13 | return number;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/deploy/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | .env
3 |
--------------------------------------------------------------------------------
/deploy/compile.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 | const solc = require('solc');
4 |
5 | const contractPath = path.resolve(__dirname, '../contracts', 'Example.sol');
6 | const source = fs.readFileSync(contractPath, 'utf8');
7 | // console.log(source);
8 |
9 | const input = {
10 | language: 'Solidity',
11 | sources: {
12 | 'Example.sol': {
13 | content: source
14 | }
15 | },
16 | settings: {
17 | outputSelection: {
18 | '*': {
19 | '*': ['*']
20 | }
21 | }
22 | }
23 | }
24 | const result = JSON.parse(solc.compile(JSON.stringify(input))).contracts['Example.sol'].Example;
25 | // console.log(result);
26 |
27 | const { abi: interface, evm: { bytecode: { object } } } = result;
28 | // console.log(interface, object);
29 |
30 | module.exports = { interface, object }; // object is the actual name of the bytecode
31 |
--------------------------------------------------------------------------------
/deploy/deploy.js:
--------------------------------------------------------------------------------
1 | const Web3 = require('web3');
2 | const HDWalletProvider = require('@truffle/hdwallet-provider');
3 |
4 | const { interface, object } = require('./compile');
5 |
6 | const privateKey = '6ad90a424022be35f9a95ae44143db08c894ba44ed0de90b67199288e06924d5';
7 | const rpcUrl = 'https://rinkeby.infura.io/v3/196440d5d02d41dfa2a8ee5bfd2e96bd';
8 |
9 | const provider = new HDWalletProvider(privateKey, rpcUrl);
10 | const web3 = new Web3(provider);
11 |
12 | const deploy = async () => {
13 | const accounts = await web3.eth.getAccounts();
14 |
15 | console.log('Attempting to deploy from account', accounts[0]);
16 |
17 | const result = await new web3.eth.Contract(interface)
18 | .deploy({ data: object })
19 | .send({ gas: '1000000', from: accounts[0] });
20 |
21 | console.log('Contract deployed to', result.options.address);
22 | };
23 |
24 | deploy();
25 |
--------------------------------------------------------------------------------
/deploy/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-web3-deploy",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "deploy.js",
6 | "scripts": {
7 | "start": "node deploy.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/AmanRaj1608/nextjs-web3-template.git"
12 | },
13 | "keywords": [
14 | "nextjs-web3-starter"
15 | ],
16 | "author": "Aman Raj ",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/AmanRaj1608/nextjs-web3-template/issues"
20 | },
21 | "homepage": "https://github.com/AmanRaj1608/nextjs-web3-template#readme",
22 | "dependencies": {
23 | "@truffle/hdwallet-provider": "^1.2.2",
24 | "solc": "^0.8.2",
25 | "web3": "^1.3.4"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs-web3-starter",
3 | "version": "1.0.0",
4 | "author": "Aman Raj ",
5 | "scripts": {
6 | "dev": "next",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "homepage": "https://github.com/AmanRaj1608/nextjs-web3-template",
11 | "license": "MIT",
12 | "dependencies": {
13 | "next": "^10.0.6",
14 | "react": "^17.0.1",
15 | "react-dom": "^17.0.1",
16 | "@material-ui/core": "^4.11.0",
17 | "@material-ui/icons": "^4.9.1",
18 | "web3": "^1.3.4",
19 | "ethers": "^5.0.31",
20 | "web3modal": "^1.9.3",
21 | "react-blockies": "^1.4.1",
22 | "@walletconnect/web3-provider": "^1.3.6"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import Head from 'next/head';
3 |
4 | import { ThemeProvider } from '@material-ui/core/styles';
5 | import CssBaseline from '@material-ui/core/CssBaseline';
6 |
7 | import { darkTheme, lightTheme } from '../src/utils/theme';
8 | import Navbar from '../src/components/Navbar';
9 |
10 | const App = ({ Component, pageProps }) => {
11 | const [darkMode, setDarkMode] = useState(0);
12 | const [isMobile, setIsMobile] = useState(false);
13 |
14 | useEffect(() => {
15 | // Remove the server-side injected CSS.
16 | const jssStyles = document.querySelector('#jss-server-side');
17 | if (jssStyles) {
18 | jssStyles.parentElement.removeChild(jssStyles);
19 | }
20 | // Setup darkmode
21 | setDarkMode(
22 | localStorage.getItem('mode')
23 | ? parseInt(localStorage.getItem('mode'))
24 | : 0
25 | )
26 | // Naive check for mobile
27 | setIsMobile(
28 | navigator.userAgent.match(
29 | /(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i
30 | )
31 | )
32 | }, []);
33 |
34 | const toggleMode = () => {
35 | localStorage.setItem('mode', (1 - darkMode).toString())
36 | setDarkMode(1 - darkMode)
37 | }
38 |
39 | const muiTheme = darkMode ? lightTheme : darkTheme;
40 |
41 | return (
42 |
43 |
44 | Nextjs Web3 starter
45 |
46 |
47 |
48 | {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
49 |
50 |
55 |
59 |
60 |
61 | );
62 | }
63 |
64 | export default App;
--------------------------------------------------------------------------------
/pages/_document.js:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Document, { Html, Head, Main, NextScript } from 'next/document';
3 |
4 | import { ServerStyleSheets } from '@material-ui/core/styles';
5 |
6 | export default class MyDocument extends Document {
7 | render() {
8 | return (
9 |
10 | {/* SEO Part */}
11 |
12 |
13 | {/* Template by https://amanraj.dev/ */}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 | }
37 |
38 | MyDocument.getInitialProps = async (ctx) => {
39 | const sheets = new ServerStyleSheets();
40 | const originalRenderPage = ctx.renderPage;
41 |
42 | ctx.renderPage = () =>
43 | originalRenderPage({
44 | enhanceApp: (App) => (props) => sheets.collect( ),
45 | });
46 |
47 | const initialProps = await Document.getInitialProps(ctx);
48 |
49 | return {
50 | ...initialProps,
51 | // Styles fragment is rendered after the app and page rendering finish.
52 | styles: [
53 | ...React.Children.toArray(initialProps.styles),
54 | sheets.getStyleElement(),
55 | ],
56 | };
57 | };
58 |
--------------------------------------------------------------------------------
/pages/about.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import Link from 'next/link';
3 |
4 | import Typography from '@material-ui/core/Typography';
5 | import { makeStyles } from '@material-ui/core/styles';
6 |
7 | const Index = () => {
8 | const classes = useStyles();
9 |
10 | return (
11 |
12 |
13 |
14 | Web3 starter template
15 |
16 |
17 | Next.js + Material UI + dark mode + web3 starter template. Boilerplate to get starter quickly.
18 |
19 |
20 |
21 | Home
22 |
23 |
24 | );
25 | }
26 |
27 | const useStyles = makeStyles((theme) => ({
28 | main: {
29 | width: '100%',
30 | margin: '100px auto',
31 | maxWidth: 1100,
32 | textAlign: 'center'
33 | },
34 | text: {
35 | fontSize: 18
36 | }
37 | }));
38 |
39 | export default Index;
40 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import Link from 'next/link';
3 |
4 | import Typography from '@material-ui/core/Typography';
5 | import { makeStyles } from '@material-ui/core/styles';
6 |
7 | const Index = () => {
8 | const classes = useStyles();
9 |
10 | return (
11 |
12 |
13 |
14 | Web3 starter template
15 |
16 |
17 | Next.js + Material UI + dark mode + web3 starter template. Boilerplate to get starter quickly.
18 |
19 |
20 |
21 | About
22 |
23 |
24 | );
25 | }
26 |
27 | const useStyles = makeStyles((theme) => ({
28 | main: {
29 | width: '100%',
30 | margin: '100px auto',
31 | maxWidth: 1100,
32 | textAlign: 'center'
33 | },
34 | text: {
35 | fontSize: 18
36 | }
37 | }));
38 |
39 | export default Index;
40 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmanRaj1608/nextjs-web3-template/d3b73ea56c7f2c7e54c2df39e11b800fcb72ecd9/public/favicon.ico
--------------------------------------------------------------------------------
/public/icons/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmanRaj1608/nextjs-web3-template/d3b73ea56c7f2c7e54c2df39e11b800fcb72ecd9/public/icons/icon-192x192.png
--------------------------------------------------------------------------------
/public/icons/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmanRaj1608/nextjs-web3-template/d3b73ea56c7f2c7e54c2df39e11b800fcb72ecd9/public/icons/icon-512x512.png
--------------------------------------------------------------------------------
/public/img/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AmanRaj1608/nextjs-web3-template/d3b73ea56c7f2c7e54c2df39e11b800fcb72ecd9/public/img/background.png
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "NextJS Web3 Starter",
3 | "short_name": "NextWeb3",
4 | "start_url": "/",
5 | "lang": "en-US",
6 | "display": "standalone",
7 | "background_color": "#000000",
8 | "theme_color": "#000000",
9 | "icons": [
10 | {
11 | "src": "/icons/icon-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png",
14 | "purpose": "any maskable"
15 | },
16 | {
17 | "src": "/icons/icon-512x512.png",
18 | "sizes": "512x512",
19 | "type": "image/png",
20 | "purpose": "any"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
4 | Sitemap:
5 |
--------------------------------------------------------------------------------
/src/components/ConnectWallet.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import Blockies from "react-blockies";
3 |
4 | import { makeStyles } from '@material-ui/core/styles';
5 |
6 | import { useWeb3Modal } from "../hooks/web3";
7 |
8 | const truncateAddress = (address) => {
9 | return address.slice(0, 6) + "..." + address.slice(-4);
10 | };
11 |
12 | const ConnectWallet = () => {
13 | const classes = useStyles();
14 |
15 | const [signerAddress, setSignerAddress] = useState("");
16 | // const [isWaiting, setWaiting] = useState(false)
17 | // const [isSent, setSent] = useState(false)
18 | // const [walletNotDetected, setWalletNotDetected] = useState(false)
19 |
20 | const { connectWallet, disconnectWallet, provider, error } = useWeb3Modal();
21 |
22 | useEffect(() => {
23 | const getAddress = async () => {
24 | const signer = provider.getSigner();
25 | const address = await signer.getAddress();
26 | setSignerAddress(address);
27 | }
28 | if (provider) getAddress();
29 | else setSignerAddress("");
30 | }, [provider]);
31 |
32 | const handleClickConnect = async () => {
33 | await connectWallet();
34 | };
35 |
36 | const handleClickAddress = () => {
37 | disconnectWallet();
38 | };
39 |
40 | return (
41 |
44 |
50 |
51 | {signerAddress ? truncateAddress(signerAddress) : "Connect Wallet"}
52 |
53 |
54 | );
55 | }
56 |
57 | const useStyles = makeStyles((theme) => ({
58 | btn: {
59 | background: 'rgb(183,192,238)',
60 | cursor: 'pointer',
61 | border: 0,
62 | outline: 'none',
63 | borderRadius: 9999,
64 | height: 35,
65 | display: 'flex',
66 | alignItems: 'center'
67 | },
68 | img: {
69 | borderRadius: 999,
70 | marginRight: 5
71 | }
72 | }));
73 |
74 | export default ConnectWallet;
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import AppBar from '@material-ui/core/AppBar';
4 | import Toolbar from '@material-ui/core/Toolbar';
5 | import Typography from '@material-ui/core/Typography';
6 | import IconButton from '@material-ui/core/IconButton';
7 | import {
8 | Brightness4Outlined as ToggleDarkModeIcon,
9 | Brightness5Outlined as ToggleLightModeIcon,
10 | } from "@material-ui/icons/";
11 | import { makeStyles, useTheme } from '@material-ui/core/styles';
12 |
13 | import dynamic from "next/dynamic";
14 | const ConnectWallet = dynamic(() => import("./ConnectWallet"), {
15 | ssr: false,
16 | });
17 |
18 | const Navbar = ({ toggleMode, darkMode }) => {
19 | const classes = useStyles();
20 | const theme = useTheme();
21 |
22 | return (
23 |
24 |
25 |
26 |
27 |
28 | Next.js Web3 starter
29 |
30 |
31 |
38 | {darkMode ? : }
39 |
40 |
41 |
42 |
43 |
44 | )
45 | }
46 |
47 | const useStyles = makeStyles((theme) => ({
48 | root: {
49 | flexGrow: 1,
50 | margin: 'auto',
51 | maxWidth: 1100,
52 | boxShadow: 'none'
53 | },
54 | img: {
55 | width: 50,
56 | marginRight: 20
57 | },
58 | title: {
59 | flexGrow: 1,
60 | // color: '#784ffe',
61 | [theme.breakpoints.down('xs')]: {
62 | fontSize: 0,
63 | // display: 'none'
64 | },
65 | },
66 | toggleBtn: {
67 | marginRight: 20,
68 | [theme.breakpoints.down('xs')]: {
69 | marginRight: 5,
70 | },
71 | }
72 | }));
73 |
74 | export default Navbar;
--------------------------------------------------------------------------------
/src/contracts/Example.js:
--------------------------------------------------------------------------------
1 | export const abi = [
2 | {
3 | "inputs": [],
4 | "name": "retrieve",
5 | "outputs": [
6 | {
7 | "internalType": "uint256",
8 | "name": "",
9 | "type": "uint256"
10 | }
11 | ],
12 | "stateMutability": "view",
13 | "type": "function"
14 | },
15 | {
16 | "inputs": [
17 | {
18 | "internalType": "uint256",
19 | "name": "num",
20 | "type": "uint256"
21 | }
22 | ],
23 | "name": "store",
24 | "outputs": [],
25 | "stateMutability": "nonpayable",
26 | "type": "function"
27 | }
28 | ];
29 |
30 | export const bytecode = {
31 | "generatedSources": [],
32 | "linkReferences": {},
33 | "object": "608060405234801561001057600080fd5b5060c78061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80632e64cec11460375780636057361d146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506087565b005b60008054905090565b806000819055505056fea26469706673582212209c3e0e66a7777942989215a6ccd2dc78a71a81a3f0a819541fddad256ac53d8664736f6c63430007040033",
34 | "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0xC7 DUP1 PUSH2 0x1F PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x2E64CEC1 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x6057361D EQ PUSH1 0x53 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3D PUSH1 0x7E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x7C PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x67 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH1 0x87 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP13 RETURNDATACOPY 0xE PUSH7 0xA7777942989215 0xA6 0xCC 0xD2 0xDC PUSH25 0xA71A81A3F0A819541FDDAD256AC53D8664736F6C6343000704 STOP CALLER ",
35 | "sourceMap": "74:206:0:-:0;;;;;;;;;;;;;;;;;;;"
36 | };
37 |
--------------------------------------------------------------------------------
/src/hooks/web3.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { ethers } from "ethers";
3 | import Web3Modal from "web3modal";
4 | import WalletConnectProvider from "@walletconnect/web3-provider";
5 |
6 | const providerOptions = {
7 | walletconnect: {
8 | package: WalletConnectProvider,
9 | options: {
10 | infuraId: '196440d5d02d41dfa2a8ee5bfd2e96bd',
11 | },
12 | },
13 | };
14 |
15 | const web3Modal = new Web3Modal({
16 | network: "kovan",
17 | cacheProvider: true,
18 | providerOptions,
19 | });
20 |
21 | export function useWeb3Modal() {
22 | const [provider, setProvider] = useState(undefined);
23 | const [error, setError] = useState(null);
24 |
25 | // Automatically connect if the provider is cashed but has not yet
26 | // been set (e.g. page refresh)
27 | if (web3Modal.cachedProvider && !provider) {
28 | connectWallet();
29 | }
30 |
31 | async function connectWallet() {
32 | try {
33 | const externalProvider = await web3Modal.connect();
34 | const ethersProvider = new ethers.providers.Web3Provider(externalProvider);
35 |
36 | setProvider(ethersProvider);
37 | } catch(e) {
38 | setError('NO_WALLET_CONNECTED');
39 | console.log('NO_WALLET_CONNECTED', e);
40 | }
41 | }
42 |
43 | function disconnectWallet() {
44 | web3Modal.clearCachedProvider();
45 | setProvider(undefined);
46 | }
47 |
48 | return { connectWallet, disconnectWallet, provider, error }
49 | }
50 |
--------------------------------------------------------------------------------
/src/utils/theme.js:
--------------------------------------------------------------------------------
1 | import { red, amber, grey } from "@material-ui/core/colors";
2 | import { createMuiTheme, responsiveFontSizes } from "@material-ui/core/styles";
3 |
4 | const fontFamilyRoboto = {
5 | fontFamily: [
6 | "Roboto",
7 | "Arial",
8 | "sans-serif",
9 | '"Apple Color Emoji"',
10 | '"Segoe UI Emoji"',
11 | '"Segoe UI Symbol"'
12 | ].join(",")
13 | };
14 |
15 | const fontFamilyMetropolis = {
16 | fontFamily: [
17 | "Metropolis",
18 | "Arial",
19 | "sans-serif",
20 | '"Apple Color Emoji"',
21 | '"Segoe UI Emoji"',
22 | '"Segoe UI Symbol"'
23 | ].join(","),
24 | letterSpacing: "0.015rem"
25 | };
26 |
27 | // A custom theme for this app
28 | const lightMuiTheme = createMuiTheme({
29 | type: "light",
30 | palette: {
31 | primary: {
32 | main: "#FFF"
33 | },
34 | secondary: {
35 | main: amber[500],
36 | light: "#feefc3"
37 | },
38 | error: {
39 | main: red.A400
40 | },
41 | background: {
42 | default: "#FFF",
43 | highlight: "#F1F3F4"
44 | }
45 | },
46 | typography: {
47 | ...fontFamilyRoboto,
48 | overline: {
49 | fontWeight: 500,
50 | fontSize: "0.7rem"
51 | }
52 | },
53 | shape: {
54 | borderRadius: "0.5rem"
55 | },
56 | zIndex: {
57 | appBar: 1200,
58 | drawer: 1100
59 | },
60 | mixins: {
61 | drawer: {
62 | minWidth: 280
63 | }
64 | },
65 | overrides: {
66 | // MuiCssBaseline: {
67 | // "@global": {
68 | // "@font-face": [
69 | // Fonts.MetropolisRegular,
70 | // Fonts.MetropolisBold,
71 | // Fonts.RobotoRegular,
72 | // Fonts.RobotoMedium,
73 | // Fonts.RobotoBold
74 | // ]
75 | // }
76 | // },
77 | MuiListItemText: {
78 | primary: {
79 | ...fontFamilyMetropolis,
80 | fontWeight: 500,
81 | fontSize: "0.87rem"
82 | }
83 | }
84 | },
85 | custom: {
86 | fontFamily: {
87 | roboto: fontFamilyRoboto,
88 | metropolis: fontFamilyMetropolis
89 | },
90 | palette: {
91 | iconColor: "#5f6368",
92 | itemBorderColor: "#DDDDDD",
93 | iconHighlight: grey[900],
94 | notesCheckbox: grey[700],
95 | profilePopColor: "#FFF",
96 | noteBackground: {
97 | default: "#0000",
98 | red: "#F28B82",
99 | orange: "#FBBC04",
100 | yellow: "#FFF475",
101 | green: "#CCFF90",
102 | cyan: "#A7FFEB",
103 | lightblue: "#CBF0F8",
104 | darkblue: "#AECBFA",
105 | purple: "#D7AEFB",
106 | pink: "#FDCFE8",
107 | brown: "#E6C9A8",
108 | grey: "#E8EAED"
109 | },
110 | noteColorCheck: "#0007",
111 | labelBackground: "#0002"
112 | }
113 | }
114 | });
115 |
116 | const darkMuiTheme = createMuiTheme({
117 | type: "dark",
118 | palette: {
119 | primary: {
120 | main: "#212121"
121 | },
122 | secondary: {
123 | main: amber[500],
124 | light: "#41331C"
125 | },
126 | error: {
127 | main: red.A400
128 | },
129 | background: {
130 | default: "#212121",
131 | highlight: "#535456"
132 | },
133 | text: {
134 | primary: "#E8EAED",
135 | secondary: "#FFFFFFDE"
136 | }
137 | },
138 | typography: {
139 | ...fontFamilyRoboto,
140 | overline: {
141 | fontWeight: 500,
142 | fontSize: "0.7rem"
143 | }
144 | },
145 | shape: {
146 | borderRadius: "0.5rem"
147 | },
148 | zIndex: {
149 | appBar: 1200,
150 | drawer: 1100
151 | },
152 | mixins: {
153 | drawer: {
154 | minWidth: 280
155 | }
156 | },
157 | overrides: {
158 | // MuiCssBaseline: {
159 | // "@global": {
160 | // "@font-face": [
161 | // Fonts.MetropolisRegular,
162 | // Fonts.MetropolisBold,
163 | // Fonts.RobotoRegular,
164 | // Fonts.RobotoMedium,
165 | // Fonts.RobotoBold
166 | // ]
167 | // }
168 | // },
169 | MuiListItemText: {
170 | primary: {
171 | ...fontFamilyMetropolis,
172 | fontWeight: 500,
173 | fontSize: "0.87rem"
174 | }
175 | }
176 | },
177 | custom: {
178 | fontFamily: {
179 | roboto: fontFamilyRoboto,
180 | metropolis: fontFamilyMetropolis
181 | },
182 | palette: {
183 | iconColor: "#949596",
184 | itemBorderColor: "#5F6368",
185 | iconHighlight: "#888A8B",
186 | notesCheckbox: "#5F6368",
187 | profilePopColor: "#2D2E30",
188 | noteBackground: {
189 | default: "#0000",
190 | red: "#5C2B29",
191 | orange: "#614A19",
192 | yellow: "#635D18",
193 | green: "#345920",
194 | cyan: "#16504B",
195 | lightblue: "#2D555E",
196 | darkblue: "#1E3A5F",
197 | purple: "#42275E",
198 | pink: "#5B2245",
199 | brown: "#442F19",
200 | grey: "#3C3F43"
201 | },
202 | noteColorCheck: "#FFF7",
203 | labelBackground: "#0002"
204 | }
205 | }
206 | });
207 |
208 | export const lightTheme = responsiveFontSizes(lightMuiTheme);
209 | export const darkTheme = responsiveFontSizes(darkMuiTheme);
--------------------------------------------------------------------------------