# Part 2: Wallet Integration

## Weld Wallet Integration Overview

Weld is a universal Cardano wallet connector library that simplifies wallet integration by providing:

* A unified interface for multiple Cardano wallets
* TypeScript support with full type safety
* React hooks for state management
* Server-side rendering compatibility

See the [Weld documentation](https://github.com/Cardano-Forge/weld) for more information.

## Implementation Steps

### 1. Create the Weld Provider Component

First, we need to create a provider component that will make Weld available throughout your application. This component will handle wallet connectivity state and server/client hydration:

```tsx
// src/components/WeldProvider.tsx
"use client";

import { WeldProvider, type WeldProviderProps } from "@ada-anvil/weld/react";

export function ClientWeldProvider({
  children,
  lastConnectedWallet,
}: {
  children: React.ReactNode;
  lastConnectedWallet?: NonNullable<
    WeldProviderProps["wallet"]
  >["tryToReconnectTo"];
}) {
  return (
    <WeldProvider
      updateInterval={30_000} // 30 seconds
      wallet={{ tryToReconnectTo: lastConnectedWallet }} // Restore wallet connection state
    >
      {children}
    </WeldProvider>
  );
}
```

{% hint style="info" %}
The `updateInterval` option (set to 30 seconds) helps maintain active wallet connections during longer user sessions.
{% endhint %}

### 2. Integrate the Provider in Your Layout

Next, we'll update the app layout to use our `ClientWeldProvider`. Notice that we include the `lastConnectedWallet` prop to restore wallet connection state between server and client. This is important for maintaining wallet connectivity during page navigation, and preventing React hydration errors due to server-side rendering being inconsistent with client-side rendering.

See the [Server-Side Rendering (SSR) section in the Weld documentation](https://github.com/Cardano-Forge/weld?tab=readme-ov-file#server-side-rendering) for more information.

```tsx
// src/app/layout.tsx
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

// Add the three imports.
import { ClientWeldProvider } from "@/components/WeldProvider";
import { cookies } from "next/headers";
import { STORAGE_KEYS } from "@ada-anvil/weld/server";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Cardano Transaction App",
  description: "Send Cardano transactions using the Anvil API",
};

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {

  // Add the cookie retrieval logic.
  const cookieStore = await cookies();
  const wallet = cookieStore.get(STORAGE_KEYS.connectedWallet)?.value;
  const changeAddress = cookieStore.get(STORAGE_KEYS.connectedChange)?.value;
  const stakeAddress = cookieStore.get(STORAGE_KEYS.connectedStake)?.value;
  const lastConnectedWallet = wallet ? { wallet, changeAddress, stakeAddress } : undefined;

  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {/* Wrap the children with the ClientWeldProvider component. */}
        <ClientWeldProvider lastConnectedWallet={lastConnectedWallet}>
          {children}
        </ClientWeldProvider>
      </body>
    </html>
  );
}
```

### 3. Understanding SSR with Weld

Our implementation addresses three critical aspects of wallet integration in Next.js with SSR:

1. **Hydration Consistency**: By retrieving wallet connection data from cookies during server-side rendering, we ensure the initial client-side state matches what was rendered on the server, preventing React hydration errors.
2. **Connection Persistence**: The `updateInterval` configuration keeps an active wallet connection stable through periodic state checks.
3. **Seamless Reconnection**: The `tryToReconnectTo` property provides a smooth user experience by maintaining wallet connections across page refreshes.

### 4. Create a Wallet Connector Component

Now let's create a UI component that users will interact with to connect their wallets:

```tsx
// src/components/WalletConnector.tsx
"use client";
import { useState } from "react";

// Import Weld hooks to get wallet and user extensions. 
import { useWallet, useExtensions } from "@ada-anvil/weld/react";

// Import supported wallets from Weld.
import { SUPPORTED_WALLETS } from "@ada-anvil/weld";

// Helper function to truncate address for display
const truncateAddress = (address: string) => {
  if (!address) return "";
  return `${address.slice(0, 8)}...${address.slice(-8)}`;
};

// Component to display wallet info
const WalletInfo = ({ label, value }: { label: string; value: string }) => (
  <div>
    <span>{label} </span>
    <span>
      <b>{value}</b>
    </span>
  </div>
);

export default function WalletConnector() {
  const wallet = useWallet();
  const { supportedMap: installedWallets, isLoading } = useExtensions(
    "supportedMap",
    "isLoading",
  );
  const availableWallets = SUPPORTED_WALLETS.filter((w) =>
    installedWallets.has(w.key),
  );
  const [selectedWallet, setSelectedWallet] = useState<string>("");

  // Reset connection state if wallet selection changes
  const handleWalletSelection = (value: string) => {
    if (wallet.isConnectingTo && value !== wallet.isConnectingTo) {
      // Cancel any pending connection
      wallet
        .disconnect()
        .catch((err) => console.error("Failed to disconnect wallet:", err));
    }
    setSelectedWallet(value);
  };

  const handleConnect = async (walletKey?: string) => {
    if (!walletKey) return;
    try {
      await wallet.connectAsync(walletKey);
    } catch (error) {
      console.error("Failed to connect wallet:", error);
    }
  };

  return (
    <section className="paper">
      <h2>Wallet</h2>

      {wallet.isConnected ? (
        // Connected state - show wallet info and disconnect button
        <>
          <WalletInfo label="Connected to:" value={wallet.displayName || ""} />
          <WalletInfo
            label="Address:"
            value={truncateAddress(wallet.changeAddressBech32 || "")}
          />
          <WalletInfo
            label="Balance:"
            value={`${wallet.balanceAda?.toFixed(2) || "0.00"} ADA`}
          />

          <button
            onClick={() =>
              wallet
                .disconnect()
                .catch((err) =>
                  console.error("Failed to disconnect wallet:", err),
                )
            }
            className="btn mt-4"
          >
            Disconnect
          </button>
        </>
      ) : // Disconnected state - show wallet selector and connect button
      isLoading ? (
        <div>Detecting wallet extensions...</div>
      ) : (
        <div>
          <select
            className="custom-rounded mb-4"
            name="wallet-key"
            value={selectedWallet}
            onChange={(e) => handleWalletSelection(e.target.value)}
          >
            {availableWallets.length === 0 ? (
              <option value="">No wallets</option>
            ) : (
              <>
                <option value="">Select a wallet</option>
                {availableWallets.map((w) => (
                  <option key={w.key} value={w.key}>
                    {w.displayName}
                  </option>
                ))}
              </>
            )}
          </select>
          <button
            onClick={() => selectedWallet && handleConnect(selectedWallet)}
            className="btn text-center"
            disabled={wallet.isConnecting || availableWallets.length === 0}
          >
            {wallet.isConnecting
              ? `Connecting to ${wallet.isConnectingTo}...`
              : selectedWallet
                ? "Connect Wallet"
                : "Select a Wallet"}
          </button>
        </div>
      )}
    </section>
  );
}
```

### 5. Update the Home Page

Now that we have created the component. Lets update your home page to include the wallet connector component:

```tsx
// src/app/page.tsx
import WalletConnector from "@/components/WalletConnector";

export default function Home() {
  return (
    <main className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-6">Cardano Transaction App</h1>
      <div className="max-w-md mx-auto">
        <WalletConnector />
      </div>
    </main>
  );
}
```

## Testing Your Wallet Integration

Now let's test the wallet integration to ensure it's working correctly:

1. **Start your development server**:

```bash
npm run dev
```

2. **Navigate to your application** (usually at <http://localhost:3000>)
3. **Test the wallet connection flow**:
   * Verify that available wallets are correctly detected in the dropdown
   * Select a wallet and click "Connect Wallet"
   * Confirm that the wallet popup appears requesting connection
   * After approving, verify that wallet information is displayed:
     * Connected wallet name
     * Truncated wallet address
     * ADA balance
4. **Test disconnection**:
   * Click the "Disconnect" button
   * Verify that the UI returns to the wallet selection state

{% hint style="warning" %}
If wallet connection fails, check your browser console for errors. Common issues include:

* Wallet extension not properly installed
* Wallet needs to be enabled for dApp interactions.
* Wallet locked (needs to be unlocked first)
* Incompatible wallet versions
  {% endhint %}

## Troubleshooting

### No Wallets Detected

If no wallets are appearing in the dropdown list:

1. Make sure you have wallet extensions installed (Eternl, Lace, etc.)
2. Refresh the page after installing a new wallet extension
3. Check your browser console for any errors

## What's Next?

Now that you have a working wallet integration, you're ready to implement transaction functionality. In [Part 3: Building Transactions](/guides/transaction/create-basic-transaction/nextjs-with-weld/nextjs-with-weld-transactions.md), we'll create the components and API routes needed to build and submit Cardano transactions.

{% hint style="success" %}
Congratulations! You've completed Part 2 of the guide. Your application can now detect wallets, connect to them, and display wallet information.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ada-anvil.io/guides/transaction/create-basic-transaction/nextjs-with-weld/nextjs-with-weld-wallet.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
