MetaMask SDK mit Next.js implementieren

Erfahre, wie du einen „Wallet verbinden"-Button mit MetaMask in Next.js integrierst. Dieses Tutorial behandelt Setup, MetaMask SDK-Nutzung und UI-Erstellung mit ShadcnUI für ...

6 Min. Lesezeit
MetaMask SDK mit Next.js implementieren

Im Web3-Bereich bezeichnet ein Wallet eine digitale Anwendung, die es Nutzern ermöglicht, mit Blockchain-Netzwerken zu interagieren. Wallets fungieren als Brücke zwischen den Nutzern und der dezentralen Welt der Blockchain. Im Gegensatz zu herkömmlichen Webanwendungen, die zur Authentifizierung E-Mail- und Passwortkombinationen oder OAuth-Dienste verwenden, authentifizieren Web3-Apps Nutzer anhand des Besitzes eines Wallets und der zugehörigen privaten Schlüssel. Der „Connect Wallet"-Button leitet diesen Authentifizierungsprozess ein.

In diesem Tutorial implementieren wir einen „Connect Wallet"-Button in einer Next.js-App, der den Authentifizierungsprozess mit dem MetaMask Wallet initiiert.

Voraussetzungen:

  • Kenntnisse in Next.js und React.

  • Node.js und npm/yarn müssen installiert sein.

  • MetaMask-Erweiterung muss im Browser installiert sein.

Obwohl dies einige Voraussetzungen für dieses Tutorial sind, ist der beste Weg zu lernen, direkt anzufangen und dabei zu lernen.

Einrichten des Next.js-Projekts:

Um ein Next.js-Projekt einzurichten, muss Node.js auf deinem Rechner installiert sein. Sobald Node.js installiert ist, kannst du eine neue Next.js-Anwendung erstellen, indem du dein Terminal öffnest und den folgenden Befehl ausführst:

npx create-next-app@latest

Wir sehen die folgenden Eingabeaufforderungen:

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
Kopieren

Dieser Befehl erstellt einen neuen Ordner mit dem angegebenen Projektnamen, richtet die grundlegende Next.js-Struktur ein und installiert alle erforderlichen Abhängigkeiten. Navigiere zu deinem Ordner.

cd next-metamask-template

und führe den folgenden Befehl aus: npm run dev. Dieser Befehl startet die Next.js-Anwendung im Entwicklungsmodus, und du kannst deine Anwendung aufrufen, indem du in deinem Webbrowser zu http://localhost:3000 navigierst.

Erstellen der Benutzeroberfläche

Wir werden unserer App eine Komponentenbibliothek hinzufügen. Lass uns ShadcnUI installieren.

npx shadcn-ui@latest init

Wir sehen die folgenden Eingabeaufforderungen zur Konfiguration von 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
Kopieren

Aus der ShadcnUI-Komponentenbibliothek verwenden wir für dieses Tutorial zwei Komponenten: Button und Popover.

Wir werden außerdem @metamask/sdk-react verwenden. Weitere Informationen dazu findest du in der MetaMask-Dokumentation.

Lass uns das SDK installieren:

npm i @metamask/sdk-react

Wir erstellen eine neue Komponente namens NavBar.tsx und fügen den „Connect Wallet"-Button sowie das SDK hinzu. Unsere Komponente sollte zunächst so aussehen:

"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>
  );
};
Kopieren

Schauen wir uns an, was wir hier gemacht haben:

1. useSDK-Hook: Zunächst konzentrieren wir uns auf den useSDK-Hook, der den Zugriff auf die Funktionen des MetaMask SDK ermöglicht. Dieser Hook stellt ein SDK-Objekt für die Interaktion mit MetaMask bereit, einen booleschen Wert connected, um zu prüfen, ob das Wallet verbunden ist, einen booleschen Wert connecting, um den Verbindungsstatus zu überprüfen, sowie ein account-Objekt für den Zugriff auf die Kontoadresse des Nutzers.

2. Connect- und Disconnect-Funktionen: Die Einrichtung umfasst zwei zentrale Funktionen: connect und disconnect. Die connect-Funktion ist ein asynchroner Vorgang, der versucht, mithilfe des SDK eine Verbindung mit dem MetaMask Wallet herzustellen. Bei einer erfolgreichen Verbindung aktualisiert sie die Werte connected und account aus dem useSDK-Hook. Die disconnect-Funktion hingegen wird verwendet, um das Wallet durch den Aufruf von sdk.terminate() zu trennen.

3. UI-Elemente: Unsere Implementierung umfasst zwei UI-Elemente – einen Button und ein Popover. Die Darstellung der Komponente ändert sich je nach Verbindungsstatus. Wenn eine Verbindung besteht, wird eine Popover-Komponente angezeigt, die die formatierte Kontoadresse und eine Option zum Trennen der Verbindung enthält. Ist keine Verbindung vorhanden, wird ein „Connect Wallet"-Button angezeigt, der während eines laufenden Verbindungsversuchs deaktiviert ist.

Jetzt fügen wir den Code für die NavBar hinzu:

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;
Kopieren

Schauen wir uns an, was wir hier gemacht haben:

  1. Host-Variable: Diese Variable ermittelt die Host-Adresse des aktuellen Fensters zur Verwendung in den SDK-Optionen. Sie enthält eine bedingte Prüfung, um festzustellen, ob sie in einer Browserumgebung ausgeführt wird.

  2. SDK-Optionen: Dies sind die Konfigurationsoptionen für das MetaMask SDK, mit denen Präferenzen für Logging und Installationsprüfungen festgelegt sowie Metadaten zur dApp hinterlegt werden.

  3. NavBar-Komponente: Die NavBar enthält einen Link zur Startseite und bindet die ConnectWalletButton-Komponente ein. Um den notwendigen Kontext des MetaMask SDK bereitzustellen, wird der ConnectWalletButton mit der MetaMaskProvider-Komponente umschlossen, die aus @metamask/sdk-react importiert wird.

  • Wallet-Icon: Um das Wallet-Icon zu erhalten, haben wir SVGR verwendet, ein Tool, das SVG-Bilder in React-Komponenten umwandelt.

Um zu verhindern, dass die vollständige Wallet-Adresse zu viel Platz in der NavBar einnimmt, nehmen wir Anpassungen in der Datei utils.ts im lib-Ordner vor. Dadurch wird sichergestellt, dass die Adresse in einem kompakteren Format angezeigt wird.

import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}
Kopieren

Füge die folgenden Zeilen hinzu:

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)}...`;
};
Kopieren

Die oben genannten Funktionen – formatBalance, formatChainAsNum und formatAddress – sind dafür ausgelegt, in einer dApp importiert und verwendet zu werden, um Blockchain-Daten einheitlich zu formatieren und den Nutzern anzuzeigen.

In der NavBar-Komponente importieren wir sie folgendermaßen:

import { formatAddress } from "../lib/utils";

Und wir haben sie hier im Button verwendet:

Jetzt müssen wir nur noch NavBar.tsx in unsere layout.tsx-Komponente importieren.

Wenn wir unseren Entwicklungsserver starten, sehen wir die Änderungen, die wir an unserer App vorgenommen haben.

Fazit

Das MetaMask SDK ist wirklich praktisch und ein echter Gamechanger beim Entwickeln von DApps. Es ermöglicht Nutzern, sich einfach mit der MetaMask-Browsererweiterung und MetaMask Mobile zu verbinden.

Dies war eine Einführung in die ersten Schritte mit dem MetaMask SDK – damit lässt sich jedoch noch viel mehr erreichen, und es kann auch in Fullstack-Anwendungen eingesetzt werden. Den Code für dieses Projekt findest du in diesem Repository hier.

Ich empfehle außerdem, die folgenden Ressourcen zu besuchen:

Viel Spaß beim Entwickeln. 🚀

KI-übersetzt. Kann Fehler enthalten. Bitte überprüfen Sie die Informationen stets.

Bewerten Sie die Übersetzung