【Wagmi v2版】wagmiを使ってMetamaskをNextjsアプリにつないでみた。

今回の記事は昨年投稿した記事の修正版です。

私が使用していたwagmiライブラリがv2になり大幅な変更があったのでそれも書いておきます。

# 概要

いきなりですが、四年生専門学校の学生である私は最近来年から課題の準備をはじめていて、今回はWeb3向けのWebアプリを開発していこうかと思っています。

なのでまずはこの記事でMetamaskのウォレットを接続するためのロジックを作っていきます。

# wagmiとは

https://wagmi.sh/

今回使用するのがこちらになります。
ほかにもいろいろありますが最初に見つけたのがこれなので。
あと対応してるウォレットが多いのも理由です。

## フレームワーク
今回は
- Nextjs 13.4 
- Wagmi 2.2.1

のバージョンを使用します。

wagmi が　v1 -> v2になりました。

# いざ実装
まずはwagmiの設定とプロバイダーを設定していきます。

```config.ts
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(),
  },
})
```

```provider.tsx
'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を無効化しないとエラーになります。おそらくウォレットの接続をクライアントで行うからだと思います。

```tsx
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)との相性はよくなさそうです💦