如何在 Next.js 中實作 MetaMask SDK

了解如何在 Next.js 中整合 MetaMask 的「連接錢包」按鈕。本教學涵蓋設定、MetaMask SDK 使用方式,以及使用 ShadcnUI 建立 UI 介面,讓您...

6 分鐘閱讀
如何在 Next.js 中實作 MetaMask SDK

在 web3 中,錢包是指一種數位應用程式,讓使用者能夠與區塊鏈網路互動。錢包作為使用者與去中心化區塊鏈世界之間的橋樑。與使用電子郵件和密碼組合或 OAuth 服務進行身份驗證的傳統網路應用程式不同,web3 應用程式根據錢包及其相關私鑰的所有權來驗證使用者身份。「Connect Wallet」按鈕會啟動此身份驗證流程。

在本教學中,我們將在 Next.js 應用程式中實作一個「Connect Wallet」按鈕,以啟動與 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 的新元件,並加入「Connect Wallet」按鈕和 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。元件的渲染會根據連線狀態而改變。連線時,它會顯示一個 Popover 元件,顯示格式化的帳戶地址和中斷連線的選項。若未連線,則顯示「Connect Wallet」按鈕,在連線嘗試進行中時該按鈕會停用。

現在讓我們加入 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, // using the host constant defined above
    },
  };

  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;
複製

讓我們來看看我們在這裡做了什麼:

  1. Host 變數:此變數決定目前視窗的主機地址,以供 SDK 選項使用。它包含一個條件檢查,用於確認是否在瀏覽器環境中執行。

  2. SDK 選項:這些是 MetaMask SDK 的設定選項,用於設定日誌記錄和安裝檢查的偏好設定,並包含關於 dapp 的中繼資料。

  3. NavBar 元件:NavBar 包含一個指向首頁的連結,並整合了 ConnectWalletButton 元件。為了提供 MetaMask SDK 所需的 context,它使用從 @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";

我們在按鈕上這樣使用它:

現在剩下的就是將 NavBar.tsx 匯入我們的 layout.tsx 元件。

執行開發伺服器後,我們將看到對應用程式所做的變更。

結論

MetaMask SDK 在建構 DApp 方面確實非常便利,是一大革新。它讓使用者能夠輕鬆連線至 MetaMask 瀏覽器擴充功能和 MetaMask Mobile。

這是 MetaMask SDK 入門介紹,但我們還可以用它做更多事情,也可以在全端應用程式中使用它。您可以在這個儲存庫中找到此專案的程式碼。

我也建議查看以下資源:

祝建構愉快。🚀

AI 翻譯。可能包含錯誤。請務必核實資訊。

評價此翻譯