Next.js+Wagmi+rainbowkit构建以太坊合约交互模版

  • Verin
  • 发布于 14小时前
  • 阅读 99

前言三年前写了一个类似的模板Nextjs+wagmi+rainbowkit构建的Dapp开发模板+使用案例,现在来看,有些方式已经过时,组装的也有些复杂,最近查看了各个repo,以最轻量化的方式来构造一个模板来快速启动一个以太坊dapp开发的项目框架,主要包括:钱包连接合约读写两个

前言

三年前写了一个类似的模板# Nextjs+wagmi+rainbowkit构建的Dapp开发模板+使用案例 ,现在来看,有些方式已经过时,组装的也有些复杂,最近查看了各个repo,以最轻量化的方式来构造一个模板来快速启动一个以太坊dapp开发的项目框架,主要包括:

  1. 钱包连接
  2. 合约读写

两个基本功能。

技术栈

  1. Next.js v15
  2. Wagmi v2
  3. Rainbowkit

项目介绍

模板地址:<https://github.com/0xverin/Nextjs-Wagmi-QuickStart>

├── app/                    # Next.js 应用目录
├── config/                 # 配置文件
│   └── contracts/          # 合约相关配置
│       ├── abi/            # 合约 ABI
│       └── addresses.ts    # 合约地址
├── hooks/                  # 自定义 React Hooks
│   └── contracts/          # 合约相关 hooks
├── utils/                  # 工具函数
│   ├── addressHelpers.ts   # 地址相关工具
│   └── contractHelpers.ts  # 合约相关工具
└── ...

本地运行

首先去WalletConnect Cloud申请一个project id,然后根据env.example创建一个本地env.local,写入NEXT_PUBLIC_PROJECT_ID=YOUR_PROJECT_ID。

pnpm install
pnpm dev

wagmi配置

主要是根据官网教程自行配置:

import { getDefaultConfig, WalletList } from "@rainbow-me/rainbowkit";
import { http } from "wagmi";
import { mainnet, sepolia } from "wagmi/chains";
import { metaMaskWallet, okxWallet } from "@rainbow-me/rainbowkit/wallets";

const wallets: WalletList = [
  {
    groupName: "Wallets",
    wallets: [okxWallet, metaMaskWallet],
  },
];
const chains = [mainnet, sepolia] as const;

const metadata = {
  name: "Nextjs Wagmi Quickstart",
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID || "",
};
const config = getDefaultConfig({
  appName: metadata.name,
  projectId: metadata.projectId,
  chains,
  transports: {
    [chains[0].id]: http(),
    [chains[1].id]: http(),
  },
  ssr: true,
  wallets,
});

export const wagmiConfig = config;

export const defaultNetwork = chains[1];

合约调用封装:

读合约:

// read example
export const useReadTestTokenContract = (address?: Address) => {
  const chainId = useChainId();
  const contract = getTestTokenContract(chainId);

  const contracts = [
    {
      ...contract,
      functionName: "balanceOf",
      args: [address],
    },
    {
      ...contract,
      functionName: "decimals",
    },
    {
      ...contract,
      functionName: "name",
    },
    {
      ...contract,
      functionName: "symbol",
    },
    {
      ...contract,
      functionName: "totalSupply",
    },
  ];

  const { data, error, isLoading, isError, refetch } = useReadContracts({
    contracts: contracts.map((contract) => ({
      ...contract,
      abi: contract.abi as Abi,
    })),
    query: {
      enabled: !!address,
    },
  });

  const [
    balanceOfAddress = BigInt(0),
    decimals = 0,
    name = "",
    symbol = "",
    totalSupply = BigInt(0),
  ] = data?.map((d) => d.result) ?? [];

  const res = {
    balanceOfAddress,
    decimals,
    name,
    symbol,
    totalSupply,
  };
  return {
    data: res,
    error,
    isLoading,
    isError,
    refetch,
  };
};

写合约:

// write example
export const useMintTestToken = () => {
  const chainId = useChainId();
  const contract = getTestTokenContract(chainId);
  const {
    data: hash,
    isPending,
    writeContractAsync,
    error: executionError,
  } = useWriteContract();
  const {
    isLoading: isConfirming,
    isSuccess: isConfirmed,
    error: callError,
  } = useWaitForTransactionReceipt({
    hash,
  });
  const write = async (address: Address, amount: bigint) => {
    return await writeContractAsync({
      ...contract,
      functionName: "mint",
      args: [address, amount],
    });
  };
  return {
    isPending,
    hash,
    writeContract: write,
    executionError,
    isConfirming,
    isConfirmed,
    callError,
  };
};

基本上这两个简单封装能覆盖大部分的合约交互功能,后续可能会更新更多的case,比如multicall等等。

这个template没有使用css包和其他复杂的包,只封装合约调用,对于合约拿到的数据需要再处理的工具函数也没有添加,可能后续会添加,目的是让有些强迫症的开发用起来舒服,比如:

  1. 我不想封装一堆provider,弄的很繁琐,wagmi v2版本已经做了很多封装。
  2. 我不想用这个ui组件,可能有的人喜欢elemnt-ui,有的人喜欢shadcn-ui。
  3. 使用rainbowkit钱包组件主要是看在他轻量化也能自定义,虽然现在reown很丰富,但是他有些功能没法自定义,我可能就需要一个hooks,但是他的hooks在触发的时候非要有一个自己的frame page的广告,我很反感。

demo演示

<https://nextjs-wagmi-quick-start.vercel.app/>

image.png

如果觉得好用,还请给个star。谢谢!

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Verin
Verin
discord:Verin#2256 v: daqingchong-pro 备注来意