├── .babelrc.js
├── .husky
└── pre-commit
├── .vscode
└── settings.json
├── .prettierrc.json
├── src
├── utils
│ └── connection.ts
├── components
│ ├── Header.tsx
│ ├── Connect.tsx
│ └── SendSol.tsx
├── pages
│ ├── index.tsx
│ ├── _document.tsx
│ └── _app.tsx
├── theme.tsx
└── providers
│ └── WalletConnectionProvider.tsx
├── next-env.d.ts
├── .eslintrc.json
├── lint-staged.config.js
├── .gitignore
├── tsconfig.json
├── next.config.js
├── package.json
└── README.md
/.babelrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [["next/babel"]],
3 | };
4 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | yarn lint-staged
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/.next": true,
4 | "**/node_modules": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "trailingComma": "es5",
4 | "singleQuote": true,
5 | "tabWidth": 2,
6 | "useTabs": false
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/connection.ts:
--------------------------------------------------------------------------------
1 | import { Connection } from '@solana/web3.js'
2 |
3 | export const appConnection = new Connection('https://api.devnet.solana.com')
4 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 |
5 | // NOTE: This file should not be edited
6 | // see https://nextjs.org/docs/basic-features/typescript for more information.
7 |
--------------------------------------------------------------------------------
/src/components/Header.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Text } from '@chakra-ui/react'
2 | import { Connect } from './Connect'
3 |
4 | export const Header = () => (
5 |
6 | Template
7 |
8 |
9 | )
10 |
--------------------------------------------------------------------------------
/src/components/Connect.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | WalletMultiButton,
3 | WalletModalProvider,
4 | } from '@solana/wallet-adapter-react-ui'
5 |
6 | export const Connect = () => (
7 |
8 |
13 |
14 | )
15 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["@typescript-eslint"],
3 | "extends": [
4 | "next/core-web-vitals",
5 | "plugin:@typescript-eslint/recommended",
6 | "prettier"
7 | ],
8 | "rules": {
9 | // I suggest you add those two rules:
10 | "@typescript-eslint/no-unused-vars": "error",
11 | "@typescript-eslint/no-explicit-any": "error"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { Stack } from '@chakra-ui/layout'
2 | import { Header } from '../components/Header'
3 | import { SendSol } from '../components/SendSol'
4 |
5 | const Index = () => {
6 | return (
7 |
8 |
9 |
13 |
14 | )
15 | }
16 |
17 | export default Index
18 |
--------------------------------------------------------------------------------
/src/theme.tsx:
--------------------------------------------------------------------------------
1 | import { extendTheme } from '@chakra-ui/react'
2 | import { createBreakpoints } from '@chakra-ui/theme-tools'
3 |
4 | const fonts = { mono: `'Menlo', monospace` }
5 |
6 | const breakpoints = createBreakpoints({
7 | sm: '40em',
8 | md: '52em',
9 | lg: '64em',
10 | xl: '80em',
11 | })
12 |
13 | const theme = extendTheme({
14 | colors: {
15 | black: '#16161D',
16 | },
17 | fonts,
18 | breakpoints,
19 | })
20 |
21 | export default theme
22 |
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // Type check TypeScript files
3 | '**/*.(ts|tsx)': () => 'yarn tsc --noEmit',
4 |
5 | // Lint then format TypeScript and JavaScript files
6 | '**/*.(ts|tsx|js)': (filenames) => [
7 | `yarn eslint --fix ${filenames.join(' ')}`,
8 | `yarn prettier --write ${filenames.join(' ')}`,
9 | ],
10 |
11 | // Format MarkDown and JSON
12 | '**/*.(md|json)': (filenames) =>
13 | `yarn prettier --write ${filenames.join(' ')}`,
14 | }
15 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
2 | import { ColorModeScript } from '@chakra-ui/react'
3 |
4 | export default class Document extends NextDocument {
5 | render() {
6 | return (
7 |
8 |
10 | {/* Make Color mode to persists when you refresh the page. */}
11 |
12 |
13 |
14 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve"
16 | },
17 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
18 | "exclude": ["node_modules"]
19 | }
20 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-var-requires
2 | const withTM = require('next-transpile-modules')([
3 | '@solana/wallet-adapter-base',
4 | '@solana/wallet-adapter-react',
5 | '@solana/wallet-adapter-react-ui',
6 | '@solana/wallet-adapter-bitpie',
7 | '@solana/wallet-adapter-blocto',
8 | '@solana/wallet-adapter-wallets',
9 | '@blocto/sdk',
10 | ])
11 |
12 | /** @type {import('next').NextConfig} */
13 | module.exports = withTM({
14 | reactStrictMode: true,
15 | webpack5: true,
16 | webpack: (config, { isServer }) => {
17 | if (!isServer) {
18 | config.resolve.fallback.fs = false
19 | }
20 | return config
21 | },
22 | })
23 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { ChakraProvider } from '@chakra-ui/react'
2 | import { AppProps } from 'next/app'
3 | import theme from '../theme'
4 | import dynamic from 'next/dynamic'
5 |
6 | require('@solana/wallet-adapter-react-ui/styles.css')
7 |
8 | const WalletConnectionProvider = dynamic(
9 | () => import('../providers/WalletConnectionProvider'),
10 | {
11 | ssr: false,
12 | }
13 | )
14 |
15 | function MyApp({ Component, pageProps }: AppProps) {
16 | return (
17 |
18 |
19 |
20 |
21 |
22 | )
23 | }
24 |
25 | export default MyApp
26 |
--------------------------------------------------------------------------------
/src/providers/WalletConnectionProvider.tsx:
--------------------------------------------------------------------------------
1 | import { WalletAdapterNetwork } from '@solana/wallet-adapter-base'
2 | import {
3 | ConnectionProvider,
4 | WalletProvider,
5 | } from '@solana/wallet-adapter-react'
6 | import { getPhantomWallet } from '@solana/wallet-adapter-wallets'
7 | import { clusterApiUrl } from '@solana/web3.js'
8 | import { useMemo } from 'react'
9 |
10 | const WalletConnectionProvider = ({ children }) => {
11 | const network = WalletAdapterNetwork.Devnet
12 | const endpoint = useMemo(() => clusterApiUrl(network), [network])
13 |
14 | const wallets = useMemo(() => [getPhantomWallet()], [])
15 |
16 | return (
17 |
18 |
19 | {children}
20 |
21 |
22 | )
23 | }
24 |
25 | export default WalletConnectionProvider
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "next",
5 | "build": "next build",
6 | "start": "next start",
7 | "lint": "next lint"
8 | },
9 | "dependencies": {
10 | "@chakra-ui/icons": "^1.0.5",
11 | "@chakra-ui/react": "^1.4.2",
12 | "@chakra-ui/theme-tools": "1.1.2",
13 | "@emotion/react": "11.1.5",
14 | "@emotion/styled": "11.1.5",
15 | "@solana/wallet-adapter-base": "^0.7.0",
16 | "@solana/wallet-adapter-react": "^0.13.1",
17 | "@solana/wallet-adapter-react-ui": "^0.6.0",
18 | "@solana/wallet-adapter-wallets": "^0.11.3",
19 | "@solana/web3.js": "^1.30.2",
20 | "framer-motion": "^4.0.3",
21 | "next": "latest",
22 | "react": "^17.0.2",
23 | "react-dom": "^17.0.2"
24 | },
25 | "devDependencies": {
26 | "@types/node": "^14.6.0",
27 | "@types/react": "^17.0.3",
28 | "@types/react-dom": "^17.0.3",
29 | "@typescript-eslint/eslint-plugin": "^5.5.0",
30 | "babel-plugin-import": "^1.13.3",
31 | "eslint": "^7.32.0",
32 | "eslint-config-next": "12.0.4",
33 | "eslint-config-prettier": "^8.3.0",
34 | "husky": "^7.0.4",
35 | "lint-staged": "^12.1.2",
36 | "next-transpile-modules": "^9.0.0",
37 | "prettier": "^2.5.0",
38 | "typescript": "4.3.2"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/SendSol.tsx:
--------------------------------------------------------------------------------
1 | import { useWallet } from '@solana/wallet-adapter-react'
2 | import {
3 | LAMPORTS_PER_SOL,
4 | PublicKey,
5 | SystemProgram,
6 | Transaction,
7 | } from '@solana/web3.js'
8 | import React, { useCallback } from 'react'
9 | import { Text, Button, useToast } from '@chakra-ui/react'
10 | import { appConnection } from '../utils/connection'
11 |
12 | interface TransferProps {
13 | destination: string
14 | amount: number
15 | }
16 |
17 | export const SendSol = ({ amount, destination }: TransferProps) => {
18 | const { publicKey, sendTransaction, connected } = useWallet()
19 | const toast = useToast()
20 |
21 | const onClick = useCallback(async () => {
22 | try {
23 | const receiver = new PublicKey(destination)
24 |
25 | const transaction = new Transaction().add(
26 | SystemProgram.transfer({
27 | fromPubkey: publicKey,
28 | toPubkey: receiver,
29 | lamports: amount * LAMPORTS_PER_SOL,
30 | })
31 | )
32 |
33 | const tx = await sendTransaction(transaction, appConnection)
34 |
35 | console.log({ tx })
36 |
37 | toast({
38 | title: 'Success!',
39 | description: `Donation sent.`,
40 | status: 'success',
41 | duration: 7000,
42 | isClosable: true,
43 | })
44 | } catch (error) {
45 | toast({
46 | title: 'Error!',
47 | description: error.message,
48 | status: 'error',
49 | duration: 7000,
50 | isClosable: true,
51 | })
52 | }
53 | }, [publicKey, sendTransaction, amount, destination, toast])
54 |
55 | if (connected)
56 | return (
57 |
60 | )
61 |
62 | return Connect to a wallet to send 1 lamport to a random address!
63 | }
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Example app with [chakra-ui](https://github.com/chakra-ui/chakra-ui) and TypeScript
2 |
3 | This example features how to use [chakra-ui](https://github.com/chakra-ui/chakra-ui) as the component library within a Next.js app with TypeScript.
4 |
5 | Next.js and chakra-ui have built-in TypeScript declarations, so we'll get autocompletion for their modules straight away.
6 |
7 | We are connecting the Next.js `_app.js` with `chakra-ui`'s Provider and theme so the pages can have app-wide dark/light mode. We are also creating some components which shows the usage of `chakra-ui`'s style props.
8 |
9 | ## Preview
10 |
11 | Preview the example live on [StackBlitz](http://stackblitz.com/):
12 |
13 | [](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript)
14 |
15 | ## Deploy your own
16 |
17 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
18 |
19 | [](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript&project-name=with-chakra-ui-typescript&repository-name=with-chakra-ui-typescript)
20 |
21 | ## How to use
22 |
23 | ### Using `create-next-app`
24 |
25 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
26 |
27 | ```bash
28 | npx create-next-app --example with-chakra-ui-typescript with-chakra-ui-typescript-app
29 | # or
30 | yarn create next-app --example with-chakra-ui-typescript with-chakra-ui-typescript-app
31 | ```
32 |
33 | 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)).
34 |
35 | ## Notes
36 |
37 | Chakra has supported Gradients and RTL in `v1.1`. To utilize RTL, [add RTL direction and swap](https://chakra-ui.com/docs/features/rtl-support).
38 |
39 | If you don't have multi-direction app, you should make `` inside `_document.ts`.
40 |
--------------------------------------------------------------------------------