Skip to content

Commit

Permalink
init uniswapV2-interface-wagmi
Browse files Browse the repository at this point in the history
  • Loading branch information
0x-stan committed Oct 20, 2022
1 parent fedc87e commit 034aaa6
Show file tree
Hide file tree
Showing 16 changed files with 637 additions and 0 deletions.
191 changes: 191 additions & 0 deletions basic/59-wagmi-and-nextjs/README.md
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/)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALCHEMY_ID=XXX
36 changes: 36 additions & 0 deletions basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/.gitignore
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 basic/59-wagmi-and-nextjs/uniswap-v2-interface-wagmi/README.md
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)

[![Deploy with Vercel](https://vercel.com/button)](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>
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}&rarr;</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>
);
}
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
Loading

0 comments on commit 034aaa6

Please sign in to comment.