在 Web3 中,钱包是指一种数字应用程序,允许用户与区块链网络进行交互。钱包充当用户与去中心化区块链世界之间的桥梁。与使用电子邮件和密码组合或 OAuth 服务进行身份验证的传统 Web 应用程序不同,Web3 应用程序基于钱包所有权及其关联私钥对用户进行身份验证。"连接钱包"按钮将启动此身份验证过程。
在本教程中,我们将在 Next.js 应用中实现一个"连接钱包"按钮,用于启动与 MetaMask 钱包的身份验证过程。
前提条件: 熟悉 Next.js 和 React。
已安装 Node.js 和 npm/yarn。
已在浏览器中安装 MetaMask 扩展程序。
以上是本教程的一些前提条件,但最好的学习方式是直接上手,边做边学。
搭建 Next.js 项目: 要搭建 Next.js 项目,您需要在计算机上安装 Node.js。安装 Node.js 后,您可以打开终端并运行以下命令来创建新的 Next.js 应用程序:
npx create-next-app@latest我们将看到以下提示:
npx create-next-app@latest
✔ What is your project named? … next-metamask-template
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use ` src/` directory? … No / Yes
✔ Would you like to use App Router? ( recommended) … No / Yes
✔ Would you like to customize the default import alias ( @/*) ? … No / Yes此命令将使用指定的项目名称创建一个新文件夹,设置初始 Next.js 结构,并安装所有必要的依赖项。导航到您的文件夹。
cd next-metamask-template然后运行命令 npm run dev,该命令将以开发模式启动 Next.js 应用程序,您可以在浏览器中访问 http://localhost:3000 来查看您的应用程序。
创建用户界面 我们将为应用添加一个组件库。接下来安装 ShadcnUI 。
npx shadcn-ui@latest init我们将看到以下配置 components.json 的提示:
Would you like to use TypeScript ( recommended) ? no / yes
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › › app/globals.css
Do you want to use CSS variables for colors? › no / yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure the import alias for components: › @/components
Configure the import alias for utils: › @/lib/utils
Are you using React Server Components? › no / yes 在本教程中,我们将使用 ShadcnUI 组件库中的两个组件:Button 和 Popover 。
我们还将使用 @metamask/sdk-react,您可以从 MetaMask 文档 中了解更多相关信息。
安装 SDK:
npm i @metamask/sdk-react我们将创建一个名为 NavBar.tsx 的新组件,并添加"连接钱包"按钮和 SDK。我们的组件初始应如下所示:
"use client" ;
import Link from "next/link" ;
import WalletIcon from "../public/icons/WalletIcon" ;
import { Button } from "./ui/button" ;
import { useSDK, MetaMaskProvider } from "@metamask/sdk-react" ;
import { formatAddress } from "../lib/utils" ;
import {
Popover,
PopoverTrigger,
PopoverContent,
} from "@/components/ui/popover" ;
export const ConnectWalletButton = ( ) => {
const { sdk, connected, connecting, account } = useSDK ( ) ;
const connect = async ( ) => {
try {
await sdk?. connect ( ) ;
} catch ( err) {
console. warn ( ` No accounts found ` , err) ;
}
} ;
const disconnect = ( ) => {
if ( sdk) {
sdk. terminate ( ) ;
}
} ;
return (
< div className= "relative" >
{ connected ? (
< Popover>
< PopoverTrigger>
< Button> { formatAddress ( account) } < / Button>
< / PopoverTrigger>
< PopoverContent className= "mt-2 w-44 bg-gray-100 border rounded-md shadow-lg right-0 z-10 top-10" >
Disconnect
< / PopoverContent>
< / Popover>
) : (
< Button disabled= { connecting} onClick= { connect} >
< WalletIcon className= "mr-2 h-4 w-4" / > Connect Wallet
< / Button>
) }
< / div>
) ;
} ; 让我们来看看我们做了什么:
1. useSDK hook :首先,我们关注的是 useSDK hook,它允许访问 MetaMask SDK 的功能。该 hook 提供了一个用于与 MetaMask 交互的 SDK 对象、一个用于验证钱包是否已连接的 connected 布尔值、一个用于检查连接状态的 connecting 布尔值,以及一个用于访问用户账户地址的 account。
2. 连接和断开连接函数 :设置包含两个关键函数:connect 和 disconnect。connect 函数是一个异步操作,尝试使用 SDK 与 MetaMask 钱包建立连接。连接成功后,它将更新 useSDK hook 中的 connected 和 account 值。disconnect 函数则通过调用 sdk.terminate() 来断开钱包连接。
3. UI 元素 :我们的实现包含两个 UI 元素——按钮和弹出框。组件的渲染会根据连接状态而变化。连接后,将显示一个 Popover 组件,展示格式化的账户地址和断开连接的选项。未连接时,则显示"连接钱包"按钮,该按钮在连接尝试进行中时将被禁用。
现在,让我们为 NavBar 添加代码:
export const NavBar = ( ) => {
const host =
typeof window !== "undefined" ? window. location. host : "defaultHost" ;
const sdkOptions = {
logging : { developerMode : false } ,
checkInstallationImmediately : false ,
dappMetadata : {
name : "Next-Metamask-Boilerplate" ,
url : host,
} ,
} ;
return (
< nav className= "flex items-center justify-between max-w-screen-xl px-6 mx-auto py-7 rounded-xl" >
< Link href= "/" className= "flex gap-1 px-6" >
< span className= "hidden text-2xl font-bold sm:block" >
< span className= "text-gray-900" > Template< / span>
< / span>
< / Link>
< div className= "flex gap-4 px-6" >
< MetaMaskProvider debug= { false } sdkOptions= { sdkOptions} >
< ConnectWalletButton / >
< / MetaMaskProvider>
< / div>
< / nav>
) ;
} ;
export default NavBar; 让我们来看看我们做了什么:
Host 变量 :该变量用于确定当前窗口的主机地址,以供 SDK 选项使用。它包含一个条件检查,用于验证是否在浏览器环境中运行。
SDK 选项 :这些是 MetaMask SDK 的配置选项,用于设置日志记录和安装检查的偏好,并包含有关 dapp 的元数据。
NavBar 组件 :NavBar 包含一个指向主页的链接,并集成了 ConnectWalletButton 组件。为了提供 MetaMask SDK 所需的上下文,它使用从 @metamask/sdk-react 导入的 MetaMaskProvider 组件对 ConnectWalletButton 进行了包装。
钱包图标:为了获取钱包图标,我们使用了 SVGR ,这是一个将 SVG 图像转换为 React 组件的工具。
为了防止完整的钱包地址在 NavBar 中占用过多空间,我们将在 lib 文件夹中的 utils.ts 文件中进行调整,以确保地址以更简洁的格式显示。
import { clsx, type ClassValue } from "clsx" ;
import { twMerge } from "tailwind-merge" ;
export function cn ( ... inputs: ClassValue[ ] ) {
return twMerge ( clsx ( inputs) ) ;
} 添加以下代码行:
export const formatBalance = ( rawBalance : string) => {
const balance = ( parseInt ( rawBalance) / 1000000000000000000 ) . toFixed ( 2 ) ;
return balance;
} ;
export const formatChainAsNum = ( chainIdHex : string) => {
const chainIdNum = parseInt ( chainIdHex) ;
return chainIdNum;
} ;
export const formatAddress = ( addr : string | undefined ) => {
return ` ${ addr?. substring ( 0 , 8 ) } ... ` ;
} ; 上述函数——formatBalance、formatChainAsNum 和 formatAddress——旨在被导入并在整个 dApp 中使用,以统一格式化区块链数据并向用户展示。
在 NavBar 组件中,我们将按如下方式导入:
import { formatAddress } from "../lib/utils";并在按钮中使用:
{formatAddress(account)} 现在剩下的就是将 NavBar.tsx 导入到 layout.tsx 组件中。
运行开发服务器后,我们将看到对应用所做的更改。
总结 MetaMask SDK 在构建 DApp 方面真正便捷,堪称游戏规则的改变者。它使用户能够轻松连接到 MetaMask 浏览器扩展程序和 MetaMask 移动端。
这只是 MetaMask SDK 入门介绍,但我们还可以用它做更多事情,也可以在全栈应用程序中使用它。您可以在此处 的代码仓库中找到本项目的代码。
我还推荐查阅以下资源:
祝开发愉快。🚀