# Wagmi

## Getting Started

If you are interested in using WAGMI in your brand new react application, follow the instructions [here](https://wagmi.sh/react/getting-started) to initialize your app with the CLI. Otherwise, follow the instructions below.

First you will need to install [WAGMI](https://wagmi.sh/react/installation)

```shell
pnpm add wagmi viem@2.x @tanstack/react-query
```

## WAGMI Config Setup

Next you will need to create a wagmi config file:\
In this example you can find it under `wagmi-config.ts`

Here you need to create the default WAGMI config, and under connector, add a\
Magic Eden Wallet Injector.

This is necessary to have WAGMI pick up the Magic Eden Wallet option,\
and add it to the Wallet Options a user can choose from.

```jsx
import { http, createConfig } from "wagmi";
import { mainnet, sepolia } from "wagmi/chains";
import { coinbaseWallet, injected } from "wagmi/connectors";

// Extend the global Window interface directly in this file
declare global {
  interface Window {
    magicEden?: {
      ethereum?: {
        request: (args: { method: string; params?: any[] }) => Promise<any>;
        on: (event: string, handler: (...args: any[]) => void) => void;
        removeAllListeners: () => void;
        // Add other methods and properties as needed
      };
    };
  }
}

// Define the Magic Eden Wallet Connector
const ME_CONNECT = injected({
  target() {
    const provider =
      typeof window !== "undefined" ? window.magicEden?.ethereum : undefined;
    return {
      id: "Magic Eden",
      name: "Magic Eden",
      provider: provider as any, // We still use `any` here to bypass strict type checking for the provider from WAGMI
    };
  },
});

// Create the configuration
export const config = createConfig({
  chains: [mainnet, sepolia],
  connectors: [ME_CONNECT, coinbaseWallet({ appName: "Create Wagmi" })],
  ssr: true,
  transports: {
    [mainnet.id]: http(),
    [sepolia.id]: http(),
  },
});

// Declare the module to register the config type with wagmi
declare module "wagmi" {
  interface Register {
    config: typeof config;
  }
}

```

## Setup WAGMI Provider and QueryClient

Once you have the config setup, you need to wrap your page or app with\
`WagmiProvider` using the config object we previously created, and `QueryClient`.

> If using NextJS 14 with App Router, make sure you add `use client;` at the top of the file.

```jsx
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

export default function EvmDemoPage() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <div className="flex min-h-screen flex-col items-center justify-between p-24">
          {wallet component will go here}
        </div>
      </QueryClientProvider>
    </WagmiProvider>
  );
}
```

## Display Wallet Options Component

Once we have the page setup, we need to create components that handle:

1. Detects Wallet Options from WAGMI.
2. Shows Wallet Options.
3. Handles selecting and authenticating a wallet.
4. Handles disconnecting a wallet.

### Update Imports

Start by updating your imports:

```jsx
"use client";
import {
  Connector,
  WagmiProvider,
  useAccount,
  useConnect,
  useDisconnect,
  useEnsAvatar,
  useEnsName,
} from "wagmi";
import { config } from "../../../wagmi-config";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, useEffect } from "react";
```

### Display Wallet Options

Next create a component that detects and displays all wallets available.

This code creates a `WalletOptions` component that uses the `useConnect` hook from the `wagmi` library to get a list of available wallet connectors. It then maps over these connectors to create a `WalletOption` component for each one.

The `WalletOption` component takes a `connector` and an `onClick` function as props. It uses the `useState` and `useEffect` hooks from React to check if the provider for the given connector is ready. If the provider is ready, it enables a button that displays the name of the connector and calls the `onClick` function when clicked.

This allows users to see all available wallet options and connect to their chosen wallet.

```jsx
export function WalletOptions() {
  const { connectors, connect } = useConnect();

  return connectors.map((connector) => (
    <WalletOption
      key={connector.uid}
      connector={connector}
      onClick={() => connect({ connector })}
    />
  ));
}

function WalletOption({
  connector,
  onClick,
}: {
  connector: Connector;
  onClick: () => void;
}) {
  const [ready, setReady] = useState(false);

  useEffect(() => {
    (async () => {
      const provider = await connector.getProvider();
      setReady(!!provider);
    })();
  }, [connector]);

  return (
    <button
      disabled={!ready}
      onClick={onClick}
      className="px-4 py-2 rounded border"
    >
      {connector.name}
    </button>
  );
}
```

### Connect an active wallet

Now create a component that handles a wallet being connected and displays the account

This `Account` component handles the display of the connected wallet's account information. It uses the `useAccount` hook from the `wagmi` library to get the address of the connected wallet. It also uses the `useDisconnect` hook to provide a function that can be called to disconnect the wallet.

The `useEnsName` and `useEnsAvatar` hooks are used to get the ENS name and avatar for the connected wallet, if they exist. The ENS name and avatar are then displayed along with the wallet's address.

A button is then provided to allow the user to disconnect their wallet. When this button is clicked, the `disconnect` function provided by the `useDisconnect` hook is called.

This component is designed to be used once a wallet has been connected. If no wallet is connected, it will not display anything.

```jsx
const queryClient = new QueryClient();

export function Account() {
  const { address } = useAccount();
  const { disconnect } = useDisconnect();
  const { data: ensName } = useEnsName({ address });
  const { data: ensAvatar } = useEnsAvatar({ name: ensName! });

  return (
    <div>
      {ensAvatar && <img alt="ENS Avatar" src={ensAvatar} />}
      {address && (
        <div className="px-4 py-2 rounded border">
          {ensName ? `${ensName} (${address})` : address}
        </div>
      )}
      <button onClick={() => disconnect()} className="px-4 py-2 rounded border">
        Disconnect
      </button>
    </div>
  );
}
```

### Create a Connect Wallet Component

Now, create a component that detects when a wallet is present, and if none are connected\
displays all available wallet options.

This `ConnectWallet` component checks if a wallet is already connected using the `isConnected` property from the `useAccount` hook. If a wallet is connected, it returns the `Account` component which displays the connected wallet's account information and provides a disconnect button. If no wallet is connected, it returns the `WalletOptions` component which displays all available wallet options for the user to connect to.

```jsx
function ConnectWallet() {
  const { isConnected } = useAccount();
  if (isConnected) return <Account />;
  return (
    <div className="flex space-x-4">
      <WalletOptions />
    </div>
  );
}
```

### Add Wallet Button to Page or Component

Finally, add your `ConnectWallet` component to your page, and you should now be able to see all wallet options. Select Magic Eden Wallet and use it to transact.

```jsx
export default function EvmDemoPage() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <div className="flex min-h-screen flex-col items-center justify-between p-24">
          <ConnectWallet />
        </div>
      </QueryClientProvider>
    </WagmiProvider>
  );
}
```

## Full Page

```jsx
"use client";
import {
  Connector,
  WagmiProvider,
  useAccount,
  useConnect,
  useDisconnect,
  useEnsAvatar,
  useEnsName,
} from "wagmi";
import { config } from "../../../wagmi-config";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, useEffect } from "react";

const queryClient = new QueryClient();

export function WalletOptions() {
  const { connectors, connect } = useConnect();

  return connectors.map((connector) => (
    <WalletOption
      key={connector.uid}
      connector={connector}
      onClick={() => connect({ connector })}
    />
  ));
}

function WalletOption({
  connector,
  onClick,
}: {
  connector: Connector;
  onClick: () => void;
}) {
  const [ready, setReady] = useState(false);

  useEffect(() => {
    (async () => {
      const provider = await connector.getProvider();
      setReady(!!provider);
    })();
  }, [connector]);

  return (
    <button
      disabled={!ready}
      onClick={onClick}
      className="px-4 py-2 rounded border"
    >
      {connector.name}
    </button>
  );
}

export function Account() {
  const { address } = useAccount();
  const { disconnect } = useDisconnect();
  const { data: ensName } = useEnsName({ address });
  const { data: ensAvatar } = useEnsAvatar({ name: ensName! });

  return (
    <div>
      {ensAvatar && <img alt="ENS Avatar" src={ensAvatar} />}
      {address && (
        <div className="px-4 py-2 rounded border">
          {ensName ? `${ensName} (${address})` : address}
        </div>
      )}
      <button onClick={() => disconnect()} className="px-4 py-2 rounded border">
        Disconnect
      </button>
    </div>
  );
}

function ConnectWallet() {
  const { isConnected } = useAccount();
  if (isConnected) return <Account />;
  return (
    <div className="flex space-x-4">
      <WalletOptions />
    </div>
  );
}

export default function EvmDemoPage() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <div className="flex min-h-screen flex-col items-center justify-between p-24">
          <ConnectWallet />
        </div>
      </QueryClientProvider>
    </WagmiProvider>
  );
}
```

Congratulations! You should now be able to select and use Magic Eden Wallet in your React app!
