Skip to content
This repository has been archived by the owner on Jun 6, 2024. It is now read-only.

Commit

Permalink
start scaffold
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Feb 19, 2022
0 parents commit b23ec4d
Show file tree
Hide file tree
Showing 88 changed files with 59,326 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["prettier"],
"plugins": ["prettier", "simple-import-sort", "import"],
"rules": {
"prettier/prettier": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error"
}
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
*debug.log

.vercel
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16
13 changes: 13 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"dbaeumer.vscode-eslint"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [

]
}
15 changes: 15 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
// improve monorepo handling
"eslint.workingDirectories": [{"mode":"auto"}]
}
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# web3 dApp scaffold

_Quickly get up and running on web3_

This scaffold is set up as a monorepo using the incredibly fast [pnpm](https://pnpm.io/), with packages for each part of the dApp. All of these packages use a common [Typescript](https://www.typescriptlang.org/) foundation with [linting](https://eslint.org/) and [autoformatting](https://prettier.io/) and is best used with [VSCode](https://code.visualstudio.com/). It assumes you'll be deploying to an [EVM-compatible blockchain](https://chainlist.org/).

## Packages

### app

This is the frontend of your dApp. It's built on [Next.js](https://nextjs.org/) app using [Tailwind CSS](https://tailwindcss.com/). Data is read from the smart contract via a subgraph (below) using [urql](https://formidable.com/open-source/urql/) and autogenerated Typescript definitions with [GraphQL Code Generator](https://www.graphql-code-generator.com/).

### contracts

This is where your smart contracts live. They're written in [Solidity](https://docs.soliditylang.org/) using [Hardhat](https://hardhat.org/) to compile, test, and deploy. Types are generated with [TypeChain](https://github.com/dethcrypto/TypeChain).

### subgraph

This is the read-only backend for your dApp and where you can offload a lot of the computationally heavy lifting to minimize gas costs. It's written in [AssemblyScript](https://www.assemblyscript.org/) and deployed to [The Graph](https://thegraph.com/).
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "web3-dapp-scaffold",
"private": true,
"scripts": {},
"devDependencies": {
"eslint": "^8.4.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"prettier": "^2.5.1"
}
}
2 changes: 2 additions & 0 deletions packages/app/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NEXT_PUBLIC_ETHEREUM_RPC_ENDPOINT=
NEXT_PUBLIC_POLYGON_RPC_ENDPOINT=
3 changes: 3 additions & 0 deletions packages/app/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["next/core-web-vitals", "../../.eslintrc.json"]
}
37 changes: 37 additions & 0 deletions packages/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel

# typescript
*.tsbuildinfo
34 changes: 34 additions & 0 deletions packages/app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.

[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.ts`.

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.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

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.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
14 changes: 14 additions & 0 deletions packages/app/codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
schema: https://api.thegraph.com/subgraphs/name/holic/example-nft
documents: 'src/**/*.{ts,tsx,graphql}'
generates:
./src/codegen/subgraph.ts:
plugins:
- '@graphql-codegen/typescript'
- '@graphql-codegen/typescript-operations'
- '@graphql-codegen/typescript-urql'
config:
gqlImport: urql#gql
immutableTypes: true
hooks:
afterAllFileWrite:
- eslint --fix
5 changes: 5 additions & 0 deletions packages/app/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
14 changes: 14 additions & 0 deletions packages/app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/** @type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,

// Allow importing .ts files
webpack: (config, options) => {
config.module.rules.push({
test: /\.tsx?$/,
use: [options.defaultLoaders.babel],
});

return config;
},
};
39 changes: 39 additions & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@web3-dapp-scaffold/app",
"private": true,
"scripts": {
"dev": "next dev & graphql-codegen --watch",
"build": "next build",
"start": "next start",
"lint": "next lint",
"codegen": "graphql-codegen"
},
"dependencies": {
"@web3-dapp-scaffold/contracts": "workspace:*",
"@ethersproject/address": "^5.5.0",
"@ethersproject/contracts": "^5.5.0",
"@ethersproject/providers": "^5.5.0",
"classnames": "^2.3.1",
"graphql": "^16.2.0",
"next": "12.0.7",
"react": "17.0.2",
"react-dom": "17.0.2",
"urql": "^2.0.6",
"web3modal": "^1.9.4",
"zustand": "^3.6.7"
},
"devDependencies": {
"@graphql-codegen/cli": "^2.3.1",
"@graphql-codegen/typescript": "^2.4.2",
"@graphql-codegen/typescript-operations": "^2.2.2",
"@graphql-codegen/typescript-urql": "^3.4.2",
"@types/node": "17.0.0",
"@types/react": "17.0.37",
"autoprefixer": "^10.4.0",
"eslint": "8.4.1",
"eslint-config-next": "12.0.7",
"postcss": "^8.4.5",
"tailwindcss": "^3.0.5",
"typescript": "4.5.4"
}
}
6 changes: 6 additions & 0 deletions packages/app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Empty file added packages/app/public/robots.txt
Empty file.
22 changes: 22 additions & 0 deletions packages/app/src/cachedFetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const cache: Partial<Record<string, Promise<Response>>> = {};

export const cachedFetch = async (
...args: ConstructorParameters<typeof Request>
) => {
const req = new Request(...args);
if (req.method !== "GET") {
throw new Error("cachedFetch does not support methods other than GET");
}

const key = req.url;
const cached = cache[key];
if (cached) return cached.then((res) => res.clone());

const res = fetch(req);
cache[key] = res;

// unset cache if fetch fails
res.catch(() => delete cache[key]);

return res.then((res) => res.clone());
};
63 changes: 63 additions & 0 deletions packages/app/src/chainConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
type ChainConfig = {
chainId: string;
chainName: string;
nativeCurrency: {
name: string;
symbol: string;
decimals: number;
};
rpcUrls: string[];
blockExplorerUrls: string[];
};

export const chainConfig = (network: string): [number, ChainConfig] => {
if (network === "matic") {
const chainId = 137;
return [
chainId,
{
chainId: `0x${chainId.toString(16)}`,
chainName: "Polygon Mainnet",
nativeCurrency: {
name: "MATIC",
symbol: "MATIC",
decimals: 18,
},
rpcUrls: [
"https://polygon-rpc.com/",
"https://rpc-mainnet.matic.network",
"https://matic-mainnet.chainstacklabs.com",
"https://rpc-mainnet.maticvigil.com",
"https://rpc-mainnet.matic.quiknode.pro",
"https://matic-mainnet-full-rpc.bwarelabs.com",
],
blockExplorerUrls: ["https://polygonscan.com/"],
},
];
}

if (network === "mumbai") {
const chainId = 80001;
return [
chainId,
{
chainId: `0x${chainId.toString(16)}`,
chainName: "Polygon Testnet",
nativeCurrency: {
name: "MATIC",
symbol: "MATIC",
decimals: 18,
},
rpcUrls: [
"https://rpc-mumbai.matic.today",
"https://matic-mumbai.chainstacklabs.com",
"https://rpc-mumbai.maticvigil.com/",
"https://matic-testnet-archive-rpc.bwarelabs.com",
],
blockExplorerUrls: ["https://mumbai.polygonscan.com/"],
},
];
}

throw new Error(`Unsupported network: ${network}`);
};
11 changes: 11 additions & 0 deletions packages/app/src/contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import deploys from "@web3-dapp-scaffold/contracts/deploys.json";
import { ExampleNFT__factory } from "@web3-dapp-scaffold/contracts/typechain-types";

import { polygonProvider } from "./providers";

const network = process.env.NODE_ENV === "production" ? "matic" : "mumbai";

export const exampleNFTContract = ExampleNFT__factory.connect(
deploys[network].ExampleNFT.address,
polygonProvider
);
3 changes: 3 additions & 0 deletions packages/app/src/firstParam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const firstParam = (param: string | string[] | undefined) => {
return Array.isArray(param) ? param[0] : param;
};
9 changes: 9 additions & 0 deletions packages/app/src/formatAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getAddress } from "@ethersproject/address";

export const formatAddress = (address: string) => {
try {
return getAddress(address);
} catch (error) {
return address;
}
};
21 changes: 21 additions & 0 deletions packages/app/src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import "tailwindcss/tailwind.css";

import type { AppProps } from "next/app";
import {
createClient as createGraphClient,
Provider as GraphProvider,
} from "urql";

export const graphClient = createGraphClient({
url: "https://api.thegraph.com/subgraphs/name/holic/example-nft",
});

const MyApp = ({ Component, pageProps }: AppProps) => {
return (
<GraphProvider value={graphClient}>
<Component {...pageProps} />
</GraphProvider>
);
};

export default MyApp;
16 changes: 16 additions & 0 deletions packages/app/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { NextPage } from "next";
import Head from "next/head";

const HomePage: NextPage = () => {
return (
<>
<Head>
<title>Example NFT</title>
</Head>

<div>Example NFT</div>
</>
);
};

export default HomePage;
Loading

0 comments on commit b23ec4d

Please sign in to comment.