forked from Dapp-Learning-DAO/Dapp-Learning
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
637 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
# Wagmi and Nextjs | ||
|
||
We will try to make a simple website of UniswapV2 by wagmi and nextjs. | ||
|
||
## tech stacks | ||
|
||
- React.js (hooks) | ||
- TypeScript | ||
- wagmi (React Hooks for Ethereum) | ||
- etehrs | ||
- Next.js (server-side rendering (SSR)) | ||
- rainbowkit (based on wagmi) | ||
- styled-components (react css package) | ||
|
||
### wagmi | ||
|
||
**wagmi**(We all gonna make it!) is a collection of React Hooks containing everything you need to start working with Ethereum. wagmi makes it easy to "Connect Wallet," display ENS and balance information, sign messages, interact with contracts, and much more — all with caching, request deduplication, and persistence. | ||
|
||
### Next.js | ||
|
||
Next.js aims to have best-in-class developer experience and many built-in features, such as: | ||
|
||
- An intuitive page-based routing system (with support for dynamic routes) | ||
- Pre-rendering, both static generation (SSG) and server-side rendering (SSR) are supported on a per-page basis | ||
- Automatic code splitting for faster page loads | ||
- Client-side routing with optimized prefetching | ||
- Built-in CSS and Sass support, and support for any CSS-in-JS library | ||
- Development environment with Fast Refresh support | ||
- API routes to build API endpoints with Serverless Functions | ||
- Fully extendable | ||
|
||
### Rainbow kit | ||
|
||
RainbowKit is a React library that makes it easy to add wallet connection to your dapp. It's intuitive, responsive and customizable. | ||
|
||
## Step-by-Step | ||
|
||
### installation | ||
|
||
Create dapp from templete which is base on react, typescript and styled-components. | ||
|
||
```sh | ||
yarn create next-app --example with-styled-components uniswap-v2-interface-wagmi | ||
``` | ||
|
||
After install npm package, we get a starter in ./uniswap-v2-interface-wagmi. Then enter folder, if it works well, you will see website run at localhost:3000. | ||
|
||
```sn | ||
cd uniswap-v2-interface-wagmi/ | ||
yarn dev | ||
``` | ||
|
||
Add wagmi, ethers, rainbowkit | ||
|
||
```sh | ||
yarn add wagmi ethers @rainbow-me/rainbowkit | ||
``` | ||
|
||
### Config Wagmi and Rainbowkit | ||
|
||
Let's config wagmi and rainbowkit, so that our web2 website would transfer to web3 dapp. | ||
|
||
import wagmi and rainbowkit. | ||
|
||
```tsx | ||
// pages/_app.tsx | ||
|
||
import { | ||
getDefaultWallets, | ||
RainbowKitProvider, | ||
} from '@rainbow-me/rainbowkit'; | ||
import { | ||
chain, | ||
configureChains, | ||
createClient, | ||
WagmiConfig, | ||
} from 'wagmi'; | ||
import { alchemyProvider } from 'wagmi/providers/alchemy'; | ||
import { publicProvider } from 'wagmi/providers/public'; | ||
import '@rainbow-me/rainbowkit/styles.css'; | ||
|
||
``` | ||
|
||
configure | ||
|
||
```tsx | ||
// pages/_app.tsx | ||
|
||
const { chains, provider } = configureChains( | ||
[chain.mainnet, chain.polygon, chain.optimism, chain.arbitrum], | ||
[ | ||
alchemyProvider({ apiKey: process.env.ALCHEMY_ID }), | ||
publicProvider() | ||
] | ||
); | ||
|
||
const { connectors } = getDefaultWallets({ | ||
appName: 'My RainbowKit App', | ||
chains | ||
}); | ||
|
||
const wagmiClient = createClient({ | ||
autoConnect: true, | ||
connectors, | ||
provider | ||
}) | ||
``` | ||
|
||
Add `<WagmiConfig>`, `<RainbowKitProvider>` to contain our page content in react node | ||
|
||
```tsx | ||
// pages/_app.tsx | ||
|
||
<ThemeProvider theme={theme}> | ||
<WagmiConfig client={wagmiClient}> | ||
<RainbowKitProvider chains={chains}> | ||
<GlobalStyle /> | ||
<Component {...pageProps} /> | ||
</RainbowKitProvider> | ||
</WagmiConfig> | ||
</ThemeProvider> | ||
``` | ||
|
||
Ofcourse, we also need to add ALCHEMY_ID in `.env` | ||
|
||
```sh | ||
ALCHEMY_ID=XXX | ||
``` | ||
|
||
Change some text content, rename page name and file name. | ||
|
||
- edit `components/cards.tsx`, make it to show multiple links | ||
- change `pages/index.tsx` text content | ||
- rename `abount.tsx` to `swap.tsx` | ||
|
||
```tsx | ||
// components/cards.tsx | ||
// replace export default part | ||
interface PageProp { | ||
href: string; | ||
name: string; | ||
} | ||
export default function Cards(props: { pages: PageProp[] }) { | ||
return ( | ||
<FlexContainer> | ||
<Card> | ||
{props.pages.map((item, index) => ( | ||
<StyledLink key={index} href={item.href} name={`${item.name}`} /> | ||
))} | ||
</Card> | ||
</FlexContainer> | ||
); | ||
} | ||
|
||
// pages/index.tsx | ||
// change text content whatever you want | ||
|
||
... | ||
|
||
// pass our swap page path into Cards component | ||
<Cards pages={[ | ||
{href: '/swap', name: 'Swap page'}, | ||
]} /> | ||
|
||
// rename `abount.tsx` to `swap.tsx` | ||
|
||
``` | ||
|
||
Then we get ready to make a uniswapv2 interface. | ||
|
||
## Swap Page | ||
|
||
First, add a connect wallet button. Just simply add it from rainbowkit, then our dapp already have connected wallet function, you could test it by clicking the button. | ||
|
||
```tsx | ||
// pages/swap.tsx | ||
|
||
import { ConnectButton } from '@rainbow-me/rainbowkit'; | ||
|
||
... | ||
<ConnectButton /> | ||
... | ||
``` | ||
|
||
## Reference | ||
|
||
- wagmi <https://wagmi.sh/> | ||
- Next.js <https://nextjs.org/docs/getting-started> | ||
- rainbowkit <https://www.rainbowkit.com/> | ||
- styled-components <https://github.com/styled-components/styled-components> | ||
- [Client-side vs. server-side rendering: why it’s not all black and white](https://www.freecodecamp.org/news/what-exactly-is-client-side-rendering-and-hows-it-different-from-server-side-rendering-bd5c786b340d/) |
1 change: 1 addition & 0 deletions
1
basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/.env.example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ALCHEMY_ID=XXX |
36 changes: 36 additions & 0 deletions
36
basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# 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* | ||
.pnpm-debug.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
86 changes: 86 additions & 0 deletions
86
basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Example app with styled-components | ||
|
||
This example features how you use a different styling solution than [styled-jsx](https://github.com/vercel/styled-jsx) that also supports universal styles. That means we can serve the required styles for the first render within the HTML and then load the rest in the client. In this case we are using [styled-components](https://github.com/styled-components/styled-components). | ||
|
||
This example uses the Rust-based [SWC](https://nextjs.org/docs/advanced-features/compiler#styled-components) in Next.js for better performance than Babel. | ||
|
||
Currently, only the `ssr` and `displayName` transforms have been implemented. These two transforms are the main requirement for using `styled-components` in Next.js. | ||
|
||
## Deploy your own | ||
|
||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-styled-components) | ||
|
||
[](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-styled-components&project-name=with-styled-components&repository-name=with-styled-components) | ||
|
||
## How to use | ||
|
||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: | ||
|
||
```bash | ||
npx create-next-app --example with-styled-components with-styled-components-app | ||
``` | ||
|
||
```bash | ||
yarn create next-app --example with-styled-components with-styled-components-app | ||
``` | ||
|
||
```bash | ||
pnpm create next-app --example with-styled-components with-styled-components-app | ||
``` | ||
|
||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). | ||
|
||
### Try it on CodeSandbox | ||
|
||
[Open this example on CodeSandbox](https://codesandbox.io/s/github/vercel/next.js/tree/canary/examples/with-styled-components) | ||
|
||
### Notes | ||
|
||
When wrapping a [Link](https://nextjs.org/docs/api-reference/next/link) from `next/link` within a styled-component, the [as](https://styled-components.com/docs/api#as-polymorphic-prop) prop provided by `styled` will collide with the Link's `as` prop and cause styled-components to throw an `Invalid tag` error. To avoid this, you can either use the recommended [forwardedAs](https://styled-components.com/docs/api#forwardedas-prop) prop from styled-components or use a different named prop to pass to a `styled` Link. | ||
|
||
<details> | ||
<summary>Click to expand workaround example</summary> | ||
<br /> | ||
|
||
**components/StyledLink.js** | ||
|
||
```javascript | ||
import Link from 'next/link' | ||
import styled from 'styled-components' | ||
|
||
const StyledLink = ({ as, children, className, href }) => ( | ||
<Link href={href} as={as} passHref> | ||
<a className={className}>{children}</a> | ||
</Link> | ||
) | ||
|
||
export default styled(StyledLink)` | ||
color: #0075e0; | ||
text-decoration: none; | ||
transition: all 0.2s ease-in-out; | ||
&:hover { | ||
color: #40a9ff; | ||
} | ||
&:focus { | ||
color: #40a9ff; | ||
outline: none; | ||
border: 0; | ||
} | ||
` | ||
``` | ||
|
||
**pages/index.js** | ||
|
||
```javascript | ||
import StyledLink from '../components/StyledLink' | ||
|
||
export default () => ( | ||
<StyledLink href="/post/[pid]" forwardedAs="/post/abc"> | ||
First post | ||
</StyledLink> | ||
) | ||
``` | ||
|
||
</details> |
55 changes: 55 additions & 0 deletions
55
basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/components/cards.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import styled from 'styled-components'; | ||
import Link from 'next/link'; | ||
|
||
export const FlexContainer = styled.div` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
flex-flow: column wrap; | ||
max-width: 800px; | ||
margin-top: 3rem; | ||
`; | ||
|
||
export const Card = styled.div` | ||
padding: 1.5rem; | ||
color: inherit; | ||
text-decoration: none; | ||
border: 1px solid black; | ||
border-radius: 10px; | ||
transition: color 0.15s ease, border-color 0.15s ease; | ||
width: 100%; | ||
&:hover, | ||
:focus, | ||
:active { | ||
color: #0070f3; | ||
border-color: #0070f3; | ||
} | ||
`; | ||
|
||
const StyledA = styled.a` | ||
margin: 0 0 1rem 0; | ||
font-size: 1.5rem; | ||
`; | ||
|
||
const StyledLink = ({ href, name }) => ( | ||
<Link href={href} passHref> | ||
<StyledA>{name}→</StyledA> | ||
</Link> | ||
); | ||
|
||
interface PageProp { | ||
href: string; | ||
name: string; | ||
} | ||
export default function Cards(props: { pages: PageProp[] }) { | ||
return ( | ||
<FlexContainer> | ||
<Card> | ||
{props.pages.map((item, index) => ( | ||
<StyledLink key={index} href={item.href} name={`${item.name}`} /> | ||
))} | ||
</Card> | ||
</FlexContainer> | ||
); | ||
} |
23 changes: 23 additions & 0 deletions
23
basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/components/globalstyles.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { createGlobalStyle } from 'styled-components' | ||
|
||
const GlobalStyle = createGlobalStyle` | ||
html, | ||
body { | ||
color: ${({ theme }) => theme.colors.primary}; | ||
padding: 0; | ||
margin: 0; | ||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, | ||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; | ||
} | ||
a { | ||
color: inherit; | ||
text-decoration: none; | ||
} | ||
* { | ||
box-sizing: border-box; | ||
} | ||
` | ||
|
||
export default GlobalStyle |
Oops, something went wrong.