1. 启动 Next.js 前端项目

NextJS 应用路由器(TypeScript)+ TailwindCSS + Shadcn UI

Next.js Pages/App Router 是一个全栈 React 框架。该框架灵活多变,助您构建大小规模的 React 应用程序。要开始创建新的 Next.js 项目,请在终端中运行以下命令:

npx create-next-app@latest my-app --typescript --tailwind --eslint

您将在终端中看到以下提示:

您的项目名称是什么?my-app
是否使用TypeScript? 否 / 是
是否使用ESLint? 否 / 是
是否使用Tailwind CSS? 否 / 是
是否使用 `src/` 目录? 否 / 是
是否使用应用路由器?(推荐) 否 / 是
是否 自定义默认  导入别名(@/*)? 否 / 是
您希望配置哪个导入别名? @/*

对于每个提示,您将选择以下选项:

您的项目名称是什么?my-app
是否使用 TypeScript? 是 # TypeScript 目前是首选
是否使用 ESLint? 是 # ESLint 用于代码检查
是否使用 Tailwind CSS? 是 # Tailwind CSS 用于 快速编写界面
是否使用 `src/` 目录? 否 # 因非必需,不使用src目录
是否使用应用路由器?(推荐) 是 # 启用应用路由器  利用最新Next.js功能
是否 自定义默认  导入别名(@/*)? 否 # 不自定义,使用默认设置

如遇问题,请访问 Next.JS 文档:https://nextjs.org/docs

cd 进入你的目录 (我的应用 或您选择的任何名称)并运行以下命令安装Shadcn UI:

npx shadcn-ui@latest init

您将看到以下设置提示: 组件.json:

您想使用哪种样式?› 默认
您想使用哪种颜色 作为 基础色?› 板岩灰
是否使用 CSS 变量 作为 颜色? › 否 / 是

你可以根据自己的喜好选择,但本次训练营你将选择:

您想使用哪种样式?› 默认
您想使用哪种颜色 作为 基础色?› 板岩灰
是否使用 CSS 变量 作为 颜色? › 是

通过ShadcnUI教程了解更多:https://ui.shadcn.com/docs/installation/next

Shadcn UI 的一个特殊功能是,该库将创建一个 组件 文件夹直接放在项目中如下所示:

└── components
    ├── ui
    │   ├── button.tsx
    │   ├── input.tsx
    │   ├── card.tsx
    │   └── form.tsx  
    └── authentication-menu.tsx

您将使用其中的组件 ui 文件夹,用于构建您自己的 自定义组件例如上文所述,你使用了4个组件 按钮.tsx, 输入.tsx, 卡片.tsx 以及 form.tsx 创建自定义组件 身份验证菜单.tsx.

2. 在WalletConnect上创建项目

访问https://cloud.walletconnect.com/sign-in

创建账户并按照仪表盘上的说明设置项目ID。

WalletConnect 将使用您的项目 ID 来追踪连接请求。

Wagmi + Rainbowkit + Tanstack React查询

Wagmi 是一个用于快速构建界面的 React Hook 库。它特别提供了便捷的 React Hooks,能够管理交易的完整生命周期——从连接钱包、发起交易,到等待节点返回结果并处理错误或成功状态。完善管理交易生命周期有助于提升用户体验,帮助用户清晰了解自身操作。

您将把 wagmi 库与 Rainbowkit 一起安装。

npm install @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query

接下来,你创建 服务提供商.tsx 文件在 应用程序 目录

'use client';

import * as React from 'react';
import {
  RainbowKitProvider,
  getDefaultWallets,
  getDefaultConfig,
} from '@rainbow-me/rainbowkit';
import {
  trustWallet,
  ledgerWallet,
} from '@rainbow-me/rainbowkit/wallets';
import {
  klaytn, // import klaytn mainnet
  klaytnBaobab, // import klaytn testnet
} from 'wagmi/chains';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { WagmiProvider, http } from 'wagmi';
// import according to docs

const { wallets } = getDefaultWallets();
// initialize and destructure wallets object

const config = getDefaultConfig({
  appName: 'MY_APP', // Name your app
  projectId: "WALLETCONNECT_PROJECT_ID", // Enter your WalletConnect Project ID here
  wallets: [
    ...wallets,
    {
      groupName: 'Other',
      wallets: [trustWallet, ledgerWallet],
    },
  ],
  chains: [
    klaytn,
    klaytnBaobab
  ],
  transports: {
    [klaytn.id]: http('https://rpc.ankr.com/klaytn'), // Select RPC provider Ankr instead of the default
    [klaytnBaobab.id]: http('https://rpc.ankr.com/klaytn_testnet'), // Select RPC provider Ankr instead of the default
  },
  ssr: true, // Because it is Nextjs's App router, you need to declare ssr as true
});

const queryClient = new QueryClient();

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider>
          {children}
        </RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
}

接下来,将此代码添加到 next.config.mjs 文件:

/** @type {import('next').NextConfig} */
const nextConfig = {
  ...
  reactStrictMode: true,
  webpack: config => {
    config.externals.push('pino-pretty', 'lokijs', 'encoding');
    return config;
  },
};

export default nextConfig;

接下来,包裹 <Providers> 周围 孩子们 在你的 布局.tsx 文件至此:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import '@rainbow-me/rainbowkit/styles.css';
import { Providers } from './providers';

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Klaytn DApp Bootcamp Frontends",
  description: "Interactive frontend for Klaytn DApp bootcamp contracts",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  );
}

3. 连接钱包按钮

然后你可以导入 <ConnectButton /> 进入您的应用程序

import { ConnectButton } from '@rainbow-me/rainbowkit';

export default function Home() {

  return (
    <div className="flex flex-col gap-8 items-center justify-center py-12 px-4 p-48:lg">
      <ConnectButton />
    </div>
  );
}

访问 Rainbowkit 文档以了解有关设置的更多信息:https://www.rainbowkit.com/docs/installation

Github上的完整源代码链接