使用Next.js和wagmi构建NFT铸造DApp全指南

📅 2026/7/4 19:13:29
使用Next.js和wagmi构建NFT铸造DApp全指南
1. 项目概述最近在Web3开发领域Next.js和wagmi的组合正在成为构建去中心化应用(DApp)的热门技术栈。作为一名从2017年就开始接触以太坊开发的老兵我发现这套组合特别适合想要快速上手区块链开发的JavaScript开发者。今天我就带大家从零开始用Next.js和wagmi搭建一个完整的NFT铸造DApp。这个项目将实现以下核心功能连接主流以太坊钱包如MetaMask显示用户钱包地址和ETH余额调用智能合约完成NFT铸造实时显示铸造交易状态展示用户拥有的NFT列表2. 技术选型解析2.1 为什么选择Next.jsNext.js作为React的元框架为DApp开发提供了几个关键优势内置路由系统简化了多页面DApp的路由管理API路由方便集成后端服务虽然我们这次用不到SSR支持改善SEO和首屏加载体验TypeScript原生支持对区块链开发特别重要提示虽然Create React App也能用但Next.js的文件系统路由和API路由对DApp开发更友好。2.2 wagmi的核心价值wagmi是一套专为以太坊开发的React Hooks它解决了Web3开发的几个痛点钱包连接标准化统一处理各种钱包提供商MetaMask、WalletConnect等智能合约交互简化用React Hooks的方式调用合约方法实时状态管理自动同步链上数据变化TypeScript支持完整的类型定义减少开发错误3. 开发环境准备3.1 基础工具安装首先确保你的开发环境已经安装# 检查Node.js版本推荐16.x以上 node -v # 检查npm/yarn npm -v yarn -v3.2 创建Next.js项目使用以下命令创建新项目npx create-next-applatest nft-minting-dapp --typescript cd nft-minting-dapp3.3 安装依赖库安装核心依赖npm install wagmi viem rainbow-me/rainbowkit关键依赖说明wagmi: 核心Web3交互库viem: 以太坊TypeScript接口rainbowkit: 钱包连接UI组件4. 项目结构设计4.1 目录结构规划/src /components Navbar.tsx MintButton.tsx NFTGallery.tsx /pages index.tsx /api (暂时不需要) /contracts NFTContract.json /styles globals.css4.2 核心组件设计Navbar: 包含钱包连接按钮和网络切换MintButton: 处理NFT铸造逻辑NFTGallery: 展示用户拥有的NFT5. 钱包连接实现5.1 配置wagmi客户端在_app.tsx中设置import { WagmiConfig, createConfig, configureChains } from wagmi import { publicProvider } from wagmi/providers/public import { mainnet, goerli } from wagmi/chains const { chains, publicClient, webSocketPublicClient } configureChains( [mainnet, goerli], [publicProvider()] ) const config createConfig({ autoConnect: true, publicClient, webSocketPublicClient, }) function MyApp({ Component, pageProps }: AppProps) { return ( WagmiConfig config{config} Component {...pageProps} / /WagmiConfig ) }5.2 添加RainbowKit钱包连接import { RainbowKitProvider } from rainbow-me/rainbowkit import rainbow-me/rainbowkit/styles.css // 在WagmiConfig内部包裹RainbowKitProvider RainbowKitProvider chains{chains} Component {...pageProps} / /RainbowKitProvider6. NFT合约交互实现6.1 准备智能合约我们使用一个简单的ERC-721合约核心方法function mintNFT() public payable { require(msg.value 0.01 ether, Need to send 0.01 ETH); _safeMint(msg.sender, totalSupply()); }6.2 配置合约ABI在/contracts/NFTContract.json中保存合约ABI然后在组件中导入import NFT_ABI from ../contracts/NFTContract.json const contractConfig { address: 0xYourContractAddress, abi: NFT_ABI, }6.3 实现铸造功能使用wagmi的useContractWriteHook:const { write: mint, isLoading } useContractWrite({ ...contractConfig, functionName: mintNFT, value: parseEther(0.01), })7. 前端界面开发7.1 主页面布局export default function Home() { return ( div classNamecontainer Navbar / main h1NFT铸造DApp/h1 MintButton / NFTGallery / /main /div ) }7.2 MintButton组件function MintButton() { const { isConnected } useAccount() if (!isConnected) return ConnectButton / return ( button onClick{() mint?.()} disabled{isLoading} {isLoading ? 铸造中... : 铸造NFT (0.01 ETH)} /button ) }8. 交易状态跟踪8.1 使用wagmi监听交易const { data: txData } useWaitForTransaction({ hash: txHash, onSuccess(data) { console.log(交易成功, data) refetchNFTs() }, })8.2 实现NFT展示function NFTGallery() { const { address } useAccount() const { data: nfts } useContractRead({ ...contractConfig, functionName: balanceOf, args: [address], watch: true }) return ( div h2我的NFT ({nfts?.toString()})/h2 {/* 这里可以添加NFT图片展示 */} /div ) }9. 项目优化与部署9.1 添加加载状态const { data: balance, isLoading: isBalanceLoading } useBalance({ address, })9.2 错误处理const { error, write: mint } useContractWrite({ ...contractConfig, functionName: mintNFT, value: parseEther(0.01), onError(error) { console.error(铸造错误, error) }, })9.3 Vercel部署在项目根目录创建next.config.js:module.exports { reactStrictMode: true, webpack: (config) { config.resolve.fallback { fs: false, net: false, tls: false } return config }, }连接GitHub仓库到Vercel设置环境变量如合约地址10. 常见问题与解决方案10.1 钱包连接问题问题: 钱包连接后页面不更新状态解决: 确保WagmiConfig包裹了整个应用并设置了autoConnect: true10.2 合约调用失败问题: 交易一直pending或失败检查:确保钱包切换到正确的网络检查gas费是否足够确认合约方法参数正确10.3 NFT显示延迟问题: 铸造成功后NFT列表不立即更新解决: 使用watch: true选项或手动调用refetch方法11. 项目扩展思路添加白名单功能: 使用Merkle Proof验证铸造权限多链支持: 添加Polygon、Arbitrum等链的配置NFT元数据: 集成IPFS存储NFT元数据拍卖功能: 添加二级市场交易功能这个项目虽然基础但涵盖了DApp开发的核心流程。在实际开发中我建议先从测试网开始充分测试后再部署到主网。另外对于生产环境的应用一定要考虑添加更多的错误处理和用户反馈机制。