> 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[​](#prerequisites "Direct link to 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 the [MetaMask faucet](/developer-tools/faucet/) to get Linea Sepolia ETH.

## Steps[​](#steps "Direct link to Steps")

### 1\. Set up the project[​](#1-set-up-the-project "Direct link to 1. Set up the project")

1. Clone the [Consensys/wallet-agent](#) repository:  
```  
git clone git@github.com:Consensys/wallet-agent.git  
```
2. Switch to the `initial-setup` branch:  
```  
cd wallet-agent && git switch initial-setup  
```
3. Install dependencies:  
```  
npm install  
```
4. Create a `.env.local` file:  
```  
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  
```  
OPENAI_API_KEY=<YOUR-API-KEY>  
```

### 2\. Create the dapp interface[​](#2-create-the-dapp-interface "Direct link to 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

```
+ "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/):

```
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[​](#3-create-a-public-client "Direct link to 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

```
+ 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[​](#4-create-a-tool-to-get-the-balance "Direct link to 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

```
+ 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[​](#5-create-a-tool-to-send-transactions "Direct link to 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
- components/Chat.tsx

```
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,
};

```

```
// ...
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[​](#resources "Direct link to 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)
