今回の記事は昨年投稿した記事の修正版です。
私が使用していたwagmiライブラリがv2になり大幅な変更があったのでそれも書いておきます。
概要
いきなりですが、四年生専門学校の学生である私は最近来年から課題の準備をはじめていて、今回はWeb3向けのWebアプリを開発していこうかと思っています。
なのでまずはこの記事でMetamaskのウォレットを接続するためのロジックを作っていきます。
wagmiとは
今回使用するのがこちらになります。
ほかにもいろいろありますが最初に見つけたのがこれなので。
あと対応してるウォレットが多いのも理由です。
フレームワーク
今回は
- Nextjs 13.4
- Wagmi 2.2.1
のバージョンを使用します。
wagmi が v1 -> v2になりました。
いざ実装
まずはwagmiの設定とプロバイダーを設定していきます。
import { http, createConfig } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
export const config = createConfig({
chains: [mainnet, sepolia],
ssr: true,
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
})
'use client'
// for react-query and wagmi sh
// this component is client side rendered
// wagmi version2
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import * as React from 'react'
import { WagmiProvider } from 'wagmi'
import { config } from '../scripts/metamaskConfig'
export default function Providers(props: { children: React.ReactNode }) {
const [queryClient] = React.useState(() => new QueryClient())
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{props.children}
</QueryClientProvider>
</WagmiProvider>
)
}
WagmiConfig コンポーネントが廃止になり、WagmiProviderに変更になりました。
またTansreact-query
のQueryClientProvider
を入れるように変更になりました。
またProvider.tsx
で"use client"
をつけてSSRを無効化しないとエラーになります。おそらくウォレットの接続をクライアントで行うからだと思います。
import Layout from '../layout/main';
import { ReactNode } from "react";
// chakra uiコンポーネント
import { Box, Grid, GridItem, Button, Center } from "@chakra-ui/react";
import HMeta from 'components/headmeta';
import * as React from 'react'
// wagmiコンポーネント
import { Connector, useConnect, useDisconnect, useAccount } from 'wagmi';
import Image from 'next/image';
// 対応するウォレットプロバイダーの取得
function WalletOption({
connector,
onClick,
}: {
connector: Connector
onClick: () => void
}) {
const [ready, setReady] = React.useState(false)
React.useEffect(() => {
; (async () => {
const provider = await connector.getProvider()
setReady(!!provider)
})()
}, [connector])
return (
<Box
w={400}
p={"20px 0px 20px 0px"}
>
<Center>
<Button
w={200}
borderRadius={6}
disabled={!ready}
onClick={onClick}>
{connector.name}
</Button>
</Center>
</Box>
)
}
// 対応するウォレットプロバイダーのリスト表示
export function WalletOptions() {
const { connectors, connect } = useConnect()
return connectors.map((connector) => (
<WalletOption
key={connector.uid}
connector={connector}
onClick={() => connect({ connector })}
/>
))
}
// ユーザー情報の表示
export default function Dash() {
const account = useAccount()
// isConnected: ウォレットが接続されているかどうか
const { address, isConnected } = useAccount()
const { disconnect } = useDisconnect()
return (
<>
<HMeta pageTitle='Dashboard - v1' />
<Box>
{isConnected ? (
<div>
<p>addres</p>
<div>{address}</div>
<p>Wallet Provider</p>
<div>{account.connector.name}</div>
<Button onClick={() => disconnect()}>Disconnect</Button>
</div>
) : (
<div>
<WalletOptions />
</div>
)}
</Box>
</>
)
}
Dash.getLayout = (page: ReactNode) => {
return (
<Layout>
{page}
</Layout>
)
}
今回のバージョンから対応しているプロバイダーを自動で取得してリスト表示できるようになりました。
ただしタグの位置を工夫しないとNext Hydration failed
が発生する可能性があるので注意です。
まとめ
v2になっていきなりエラーだらけでびっくりしました。
正直NextJS(SSR)との相性はよくなさそうです💦