> For the complete documentation index, see [llms.txt](/llms.txt).

# Create an AI agent using MetaMask Connect

`MetaMask Connect` `AI agent` `Vercel` `Wagmi` `Next.js` `OpenAI`MetaMask Developer Relations | May 2, 2025

Open in Claude

This tutorial walks you through creating an AI agent dapp that can display your wallet balance and initiate transactions from your wallet, on the Linea Sepolia network. You will use a provided template, which sets up MetaMask Connect and [Vercel's AI SDK](https://sdk.vercel.ai/) with a [Next.js](https://nextjs.org/docs) and [Wagmi](https://wagmi.sh/) dapp.

## Prerequisites

- [Node.js](https://nodejs.org/) version 18 or later and [pnpm](https://pnpm.io/installation) installed
- An [OpenAI](https://platform.openai.com/docs/overview) API key, with some credit balance available
- [MetaMask](https://metamask.io/) installed, with an account that has Linea Sepolia ETH  
note  
You can use a public Linea Sepolia faucet to get testnet ETH.

## Steps

### 1. Set up the project

1. Clone the [Consensys/wallet-agent](#) repository:  
```bash  
git clone git@github.com:Consensys/wallet-agent.git  
```
2. Switch to the `initial-setup` branch:  
```bash  
cd wallet-agent && git switch initial-setup  
```
3. Install dependencies:  
```bash  
npm install  
```
4. Create a `.env.local` file:  
```bash  
touch .env.local  
```
5. In `.env.local`, add an `OPENAI_API_KEY` environment variable, replacing `<YOUR-API-KEY>` with your [OpenAI](https://platform.openai.com/docs/overview) API key. Vercel's AI SDK will use this environment variable to authenticate your dapp with the OpenAI service.  
.env.local  
```text  
OPENAI_API_KEY=<YOUR-API-KEY>  
```

### 2. Create the dapp interface

In `app/page.tsx`, use the `useAccount`, `useConnect`, and `useDisconnect` hooks from Wagmi, along with the Wagmi [MetaMask connector](https://wagmi.sh/react/api/connectors/metaMask) to create a button to connect and disconnect your MetaMask wallet.

Use the `Chat` component to display the AI agent chat interface.

page.tsx

```tsx
+ "use client";

+ import { useAccount, useConnect, useDisconnect } from "wagmi";
+ import { metaMask } from "wagmi/connectors";
+ import { Button } from "@/components/ui/button";
+ import { Chat } from "@/components/Chat";
import Image from "next/image";

+ const ConnectButton = () => {
+   const { connect } = useConnect();
+   const { address, isConnected } = useAccount();
+   const { disconnect } = useDisconnect();
+
+   return (
+     <div className="mx-auto">
+       {isConnected ? (
+         <Button onClick={() => disconnect()}>Disconnect {address}</Button>
+       ) : (
+         <Button onClick={() => connect({ connector: metaMask() })}>Connect</Button>
+       )}
+     </div>
+   );
+ };

export default function Home() {
+ const { isConnected } = useAccount();
  return (
    <div className="h-screen w-full overflow-y-auto grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <main className="gap-8 row-start-2 sm:items-start h-full w-full">
        <h1>Wallet Agent setup</h1>
+       <ConnectButton />
+       { isConnected ? <Chat /> : null}
      </main>
      // ...

```

To test the interface, run the development server and navigate to [http://localhost:3000](http://localhost:3000/):

```bash
npm run dev

```

Test that the button works to connect and disconnect from your MetaMask wallet. When connected, the AI agent chat interface displays with your connected wallet address. You can test the AI functionality by sending messages in the chat:

![SDK AI agent initial setup](/assets/images/sdk-ai-agent-52e915bc2b897c7ac55a9660d2fba1ce.png)

### 3. Create a Public Client

In `wagmi.config.ts`, initialize a [Viem Public Client](https://viem.sh/docs/clients/public)with the Linea Sepolia chain. This Public Client will enable the AI agent to access public JSON-RPC API methods such as retrieving balances:

wagmi.config.ts

```ts
+ import { createPublicClient } from "viem";
import { createConfig, http, cookieStorage, createStorage } from "wagmi";
import { lineaSepolia, linea, mainnet } from "wagmi/chains";
import { metaMask } from "wagmi/connectors";

+ export const publicClient = createPublicClient({
+   chain: lineaSepolia,
+   transport: http(),
+ });

export function getConfig() {
// ...

```

### 4. Create a tool to get the balance

Use the AI SDK's [tools](https://sdk.vercel.ai/docs/foundations/tools) feature to enable the AI agent to perform specific tasks.

In `ai/tools.ts`, update or remove the example tool. Use the [getBalance](https://viem.sh/docs/actions/public/getBalance) method of your configured Public Client, and Viem's [formatEther](https://viem.sh/docs/utilities/formatEther) function to create a tool that retrieves the ether balance of the connected wallet:

tools.ts

```ts
+ import { publicClient } from "@/wagmi.config";
+ import { formatEther } from "viem";
import { tool as createTool } from "ai";
import { z } from "zod";

- const tool = createTool({
-   description: "Example tool",
-   parameters: z.object({
-     name: z.string().describe("The name of the user"),
-   }),
-   execute: async ({ name }) => {
-     return { name };
-   },
- });
+ const balanceTool = createTool({
+   description: "Get the balance of the connected wallet",
+   parameters: z.object({
+     address: z.string().describe("The address of the user"),
+   }),
+   execute: async ({ address }) => {
+     const balance = await publicClient.getBalance({
+       address: address as `0x${string}`,
+     });
+     return { balance: formatEther(balance) };
+   },
+ });

export const tools = {
-   example: tool,
+   displayBalance: balanceTool,
};

```

In the development server, test that this tool works to get your current Linea Sepolia ETH balance:

![SDK AI agent get balance](/assets/images/sdk-ai-agent-get-balance-f13b264b808eb23536cf79164701d328.png)

### 5. Create a tool to send transactions

In `ai/tools.ts`, create another tool to send transactions. In this example, the tool and the `Chat.tsx` component are configured to initiate a transaction and provide a button for you to send the transaction. You only need to make the following changes to the `tools.ts` file:

**ai/tools.ts**

```ts
import { publicClient } from "@/wagmi.config";
import { formatEther } from "viem";
import { tool as createTool } from "ai";
import { z } from "zod";

const balanceTool = createTool({
  // ...
});

+ const sendTransactionTool = createTool({
+   description: "Initiate a transaction to the provided wallet address",
+   parameters: z.object({
+     to: z.string().describe("The wallet address of the user"),
+     amount: z.string().describe("The amount of ether to send"),
+   }),
+   execute: async ({ to, amount }) => {
+     return { to, amount };
+   },
+ });

export const tools = {
  displayBalance: balanceTool,
+ sendTransaction: sendTransactionTool,
};

```

**components/Chat.tsx**

```tsx
// ...
if (toolName === 'sendTransaction') {
  const { result }: { result: { to: string; amount: string } } = toolInvocation

  if (isLoading) {
    return (
      <div key={toolCallId}>
        <p>Loading...</p>
      </div>
    )
  }

  return (
    <div key={toolCallId}>
      <Button
        className="bg-orange-600 text-orange-100 py-2 px-5 rounded-sm w-fit"
        onClick={() =>
          sendTransaction({
            to: result.to as `0x${string}`,
            value: parseEther(result.amount),
          })
        }>
        Send Transaction
      </Button>
      <p>{hash ? `Transaction sent: ${hash}` : 'Transaction not sent'}</p>
    </div>
  )
}
// ...

```

In the development server, test that this tool works to send Linea Sepolia ETH from your connected address to the address you provide.

When you request the agent to send a transaction, it will provide a button for you to send the transaction, but it will not send it for you:

![NFT confirmation](/assets/images/sdk-ai-agent-txn-not-sent-301256d816b24ddecb825c29d7cf26a6.png)

When you select the button and confirm the transaction in MetaMask, the transaction will be sent:

![Multiple NFTs confirmation](/assets/images/sdk-ai-agent-txn-sent-982803e002eecdd72f9035e4dd0daaf5.png)

You can check the status of the transaction in the [Linea Sepolia block explorer](https://sepolia.lineascan.build/).

note

You can configure the AI agent to directly send the transaction using a [Viem Wallet Client](https://viem.sh/docs/clients/wallet).

## Resources

- Watch the [live coding session](https://www.youtube.com/watch?v=ZVuOaKuAhBQ) on YouTube, in which the MetaMask DevRel team walks through creating a wallet AI agent from the initial template.

[Share](https://www.facebook.com/sharer/sharer.php?https://metamask.io/tutorials/create-wallet-ai-agent)[Tweet](http://twitter.com/share?text=Checkout Create an AI agent using MetaMask Connect published by @MetaMask&url=https://metamask.io/tutorials/create-wallet-ai-agent)Copy

On this page
- [Prerequisites](#prerequisites)
- [Steps](#steps)
  - [1. Set up the project](#1-set-up-the-project)
  - [2. Create the dapp interface](#2-create-the-dapp-interface)
  - [3. Create a Public Client](#3-create-a-public-client)
  - [4. Create a tool to get the balance](#4-create-a-tool-to-get-the-balance)
  - [5. Create a tool to send transactions](#5-create-a-tool-to-send-transactions)
- [Resources](#resources)
