diff --git a/docs/base-app/agents/building-quality-agents.mdx b/docs/base-app/agents/building-quality-agents.mdx deleted file mode 100644 index f63ec37e9..000000000 --- a/docs/base-app/agents/building-quality-agents.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: 'UX Guidelines' -description: Learn the best practices and guidelines for creating quality agents -sidebarTitle: 'UX Guidelines' ---- - -As you start building, review these guidelines to understand what makes an agent successful in the Base app. We recommend trying out existing agents in the app first to get a feel for the quality bar, what works well, and areas for improvement. - -## Build a high quality foundation - -Your agent should provide a seamless, professional experience that users will want to engage with repeatedly. Here are the core requirements: - -### Responding to messages - -**Multi-Channel Support** -- Respond to both DMs and group chats appropriately -- Maintain consistent functionality across different conversation types - -**Immediate Feedback** -- React to messages with a simple reaction (๐Ÿ‘€, ๐Ÿ‘, โŒ›, etc.) to show acknowledgment -- This gives users confidence their message was received while processing - -**Fast Response Times** -- Provide responses quickly (< 5 seconds) -- Users expect near-instant communication in messaging apps - -### Group Chat Etiquette - -In group chats, agents should only respond when: - -1. **Mentioned directly** with "@" + agent name (e.g., @bankr) -2. **Replied to directly** when a user replies to the agent's message using the reply content type - -This prevents spam and ensures agents participate naturally in group conversations. - -### Communication Style - -**Sound Human** -- Use conversational, fun, and clear language -- Keep responses polished but not robotic -- Match the energy and tone of the conversation - -**Privacy Conscious** -- Only ask for personal information when absolutely necessary -- Always explain why the information is needed -- Respect user privacy and data minimization principles - -## Craft compelling onboarding - -Your agent's first impression is critical. The onboarding message should immediately communicate value and give users a clear path forward. - -### Great Onboarding Message Structure - -1. **Introduce the agent** - Quick, friendly greeting with the agent's name -2. **Explain capabilities** - Clear, specific examples of what it can do -4. **Use quick select buttons** - Make it easy for users to select an action to take with the agent - -### Example: High-Quality Onboarding - -``` -hey, i'm bankr. i can help you trade, transfer, and manage your crypto. here's the rundown: - -โ€ข trade anything: buy, sell, swap tokens on base, polygon, and mainnet. try "buy 0.1 eth of degen." -โ€ข send it: transfer crypto to anyone on x, farcaster, or a wallet address. -โ€ข get alpha: token recs, market data, charts. -โ€ข automate: set up recurring buys/sells. e.g. "buy $10 of $bnkr every week." - -what do you want to do first? -``` - -**Why this works:** -- Friendly, conversational tone -- Specific feature examples with concrete commands -- Clear value propositions -- Ends with a direct call-to-action - -### Example: Poor Onboarding - -``` -Gm! What can I help you with? -``` - -**Why this fails:** -- Generic greeting with no context -- No explanation of capabilities -- Puts burden on user to figure out what to do -- No clear value proposition - -## Showcase unique value - -### Solve Real Problems - -Your agent should: -- **Address a unique pain point** or bring a delightful twist to an existing space -- **Help users accomplish tasks** more easily than existing solutions -- **Provide clear benefits** that users can understand immediately - -### Enable User Success - -Focus on helping users: -- **Earn** - Generate income, rewards, or value -- **Connect** - Build relationships or communities -- **Have fun** - Provide entertainment or engaging experiences -- **Complete tasks** - Streamline workflows or processes - -### Design for Engagement - -**Build Natural Growth Loops** -- Include features that encourage sharing, re-engagement, and habit forming -- Make it beneficial for users to invite others -- Create ongoing value that brings users back - -**Plan the User Journey** -1. **Define the ideal user experience first** -2. **Craft agent messages around that journey** -3. **Guide users through progressive value discovery** - -### Continuous Engagement Strategy - -As users complete actions with your agent: - -- **Show clear next steps** - Always give users something else to try -- **Highlight ongoing value** - Explain how continued use benefits them -- **Create habit loops** - Design features that encourage regular interaction -- **Prevent one-and-done usage** - Build features that require return visits - -### Examples of Engagement Features - -- **Progressive features** - Unlock new capabilities as users engage more -- **Personalization** - Learn user preferences and customize experiences -- **Social elements** - Enable sharing achievements or inviting friends -- **Recurring value** - Automated tasks, alerts, or regular check-ins -- **Gamification** - Points, levels, or achievement systems - - diff --git a/docs/base-app/agents/chat-agents.mdx b/docs/base-app/agents/chat-agents.mdx deleted file mode 100644 index 378a363f5..000000000 --- a/docs/base-app/agents/chat-agents.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: 'Chat Agents in Base App' -description: Learn how to build chat agents for Base App, using XMTP -sidebarTitle: 'Overview' ---- - -This guide will cover how you can get started building messaging agents for Base App, using XMTP, a decentralized messaging protocol. Discover a fast, easy way to build and get distribution in Base App. - -- Why agents? -- Getting started with XMTP -- Getting featured in Base App - -## Why agents? - -Messaging is the largest use-case in the world, but itโ€™s more than just conversationsโ€”itโ€™s a secure, programmable channel for financial and social innovation. When combined with the onchain capabilities of Base App, builders have a new surface area to build 10X better messaging experiences not currently possible on legacy platforms like WhatsApp or Messenger. - -Real Examples: - -โ€ข Smart Payment Assistant: Text "split dinner $200 4 ways" and everyone gets paid instantly with sub-cent fees, no app switching or Venmo delays. - -โ€ข AI Trading Companion: Message "buy $100 ETH when it hits $3,000" and your agent executes trades 24/7 while you sleep. - -โ€ข Travel Planning Agent: "Book flight LAX to NYC under $300" and get instant booking with crypto payments, all in your group chat - -โ€ข Base App & XMTP are combining AI, crypto, and mini apps with secure messaging โ€“ to unlock use-cases never before possible. Secure group chats & DMs are the new surface area for developers. - - -## XMTP Documentation - -Learn more about [XMTP](https://docs.xmtp.org/agents/get-started/build-an-agent) secure decentralized messaging network. - diff --git a/docs/base-app/agents/deeplinks.mdx b/docs/base-app/agents/deeplinks.mdx deleted file mode 100644 index dfc22ade7..000000000 --- a/docs/base-app/agents/deeplinks.mdx +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 'Deeplinks for Agent Interactions' -description: 'Learn how to use deeplinks to create seamless agent experiences and direct user interactions within Base App.' -sidebarTitle: 'Deeplinks' ---- - -> **What you'll learn** -> By the end of this guide, you'll be able to: -> - Implement deeplinks for direct messaging with agents -> - Create seamless user flows between group and private conversations -> - Follow best practices for deeplink implementation -> - Handle fallbacks and cross-client compatibility - -## Overview - -Deeplinks enable seamless navigation within Base App, allowing agents to create more engaging and intuitive user experiences. The most common use case is directing users to start a private conversation with an agent from a group chat context. - -## Direct Message Deeplinks - -### Use Case - -Your miniapp has an agent and you want to encourage people to chat with the agent directly. Or, your agent exists in a group chat context and wants users to interact with it privately. You could add a button like "Chat with me" and use this deeplink. - -### Syntax - -``` -cbwallet://messaging/address -``` - -### Parameters - -- **address** โ€” The 0x address of the user you want to chat with (in hex format, e.g., `0xabc...1234`) - -### Implementation Examples - -**Basic Button Implementation:** - -```typescript - -``` - -**React Component with Error Handling:** - -```typescript -import { useState } from 'react'; - -interface DeeplinkButtonProps { - agentAddress: string; - label?: string; - className?: string; -} - -export function DeeplinkButton({ - agentAddress, - label = "Direct Message", - className = "btn-primary" -}: DeeplinkButtonProps) { - const [isLoading, setIsLoading] = useState(false); - - const handleDeeplink = async () => { - setIsLoading(true); - try { - const deeplink = `cbwallet://messaging/${agentAddress}`; - - // Check if running in supported environment - if (typeof window !== 'undefined') { - window.location.href = deeplink; - } else { - // Fallback for server-side rendering - console.warn('Deeplink not supported in this environment'); - } - } catch (error) { - console.error('Failed to open deeplink:', error); - } finally { - setIsLoading(false); - } - }; - - return ( - - ); -} -``` diff --git a/docs/base-app/agents/getting-started.mdx b/docs/base-app/agents/getting-started.mdx deleted file mode 100644 index c6730c066..000000000 --- a/docs/base-app/agents/getting-started.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: 'Getting Started with Chat Agents' -description: 'Step-by-step guide to creating, testing, and deploying your first XMTP messaging agent' -sidebarTitle: 'Getting Started' ---- - -Build powerful chat agents that integrate seamlessly with Base App using the XMTP messaging protocol. - - -For the complete guide, visit [XMTP documentation](https://docs.xmtp.org/agents/get-started/build-an-agent) - - -## Installation - - - -```bash npm -npm install @xmtp/agent-sdk -``` - -```bash pnpm -pnpm add @xmtp/agent-sdk -``` - -```bash yarn -yarn add @xmtp/agent-sdk -``` - - - -## Usage - -This example shows how to create an agent that sends a message when it receives a text message. - -```ts [Node] -import { Agent } from '@xmtp/agent-sdk'; - -// 2. Spin up the agent -const agent = await Agent.createFromEnv({ - env: 'production', // base app works only on production -}); - -// 3. Respond to text messages -agent.on('text', async (ctx) => { - await ctx.sendText('Hello from my Base App Agent! ๐Ÿ‘‹'); -}); - -// 4. Log when we're ready -agent.on('start', () => { - console.log(`Waiting for messages...`); - console.log(`Address: ${agent.address}`); -}); - -await agent.start(); -``` - -### Set environment variables - -To run an example XMTP agent, you must create a `.env` file with the following variables: - -```bash -XMTP_WALLET_KEY= # the private key of the wallet -XMTP_DB_ENCRYPTION_KEY= # encryption key for the local database -XMTP_ENV=production # local, dev, production -``` - -## Get a basename for your agent - -Give your agent a human-readable name: - -**1. Import agent wallet to Base App extension:** - - โ€ข Install Base App browser extension - - โ€ข Import using your agent's private key - -**2. Purchase a basename:** - -โ€ข Visit https://base.org/names - -โ€ข Connect your agent's wallet - -โ€ข Search and purchase your desired basename (e.g., myagent.base.eth) - -โ€ข Set as primary name - -**3. Verify setup:** - -โ€ข Your agent can now be reached via the basename instead of the long address - -โ€ข Users can message myagent.base.eth instead of 0x123... - - -For the complete guide, visit [XMTP documentation](https://docs.xmtp.org/agents/get-started/build-an-agent) - \ No newline at end of file diff --git a/docs/base-app/agents/mini-apps-and-agents.mdx b/docs/base-app/agents/mini-apps-and-agents.mdx deleted file mode 100644 index e86cb6463..000000000 --- a/docs/base-app/agents/mini-apps-and-agents.mdx +++ /dev/null @@ -1,288 +0,0 @@ ---- -title: 'Mini Apps & Agents' -description: 'Learn how to integrate Mini Apps with chat agents for seamless in-conversation experiences that drive engagement and virality.' -sidebarTitle: 'Mini Apps & Agents' ---- - -> **What you'll learn** -> By the end of this guide, you'll be able to: -> - Integrate Mini Apps with chat agents for seamless in-conversation experiences -> - Share Mini Apps directly through agent messages with rich previews -> - Create engaging group experiences using agents and Mini Apps together -> - Implement user mentions and social features in agent-driven Mini App experiences -> - Build viral, conversational Mini App distribution through chat - -## Why Mini Apps & Agents Together? - -Mini Apps can live inside conversations, letting friends play, trade, plan, and coordinate together without ever leaving the chat. - -This means that you can have virality spread through natural conversation ("try this right here") along with sharing in larger settings. When combined with intelligent agents, you create powerful experiences that spread through natural conversation. - -This integration unlocks unique distribution and engagement patterns: - -**Natural virality:** "Try this right here" moments spread organically through conversation - -**Contextual engagement:** Agents can introduce Mini Apps at the perfect moment - -**Group coordination:** Agents orchestrate multiplayer experiences and keep everyone engaged - -**Persistent presence:** Agents maintain engagement between Mini App sessions - -**Real Examples:** - - โ€ข **Group Gaming:** Agent coordinates a multiplayer quiz, announces winners, and keeps score across sessions - โ€ข **Event Planning:** Agent shares planning Mini App when someone mentions meeting up, handles RSVPs and updates - โ€ข **Trading Competitions:** Agent creates trading challenges, shares leaderboards, and celebrates wins - โ€ข **Social Polls:** Agent launches polls when decisions need to be made, tallies results, and announces outcomes - - -## How Integration Works - -### 1. Share Mini Apps in App - -Every Mini App has a shareable URL that agents can send directly in chat. When dropped into a conversation, the link automatically unfurls into a rich preview card that others can tap to launch instantly. - - -**Share Flow:** -1. **Agent triggers share** โ€” Based on conversation context or user request -2. **Link generates preview** โ€” Platform fetches Mini App metadata and creates rich embed -3. **Users engage** โ€” Tap preview to launch Mini App directly in conversation -4. **Agent coordinates** โ€” Continues engagement, shares updates, mentions participants - -### Technical Implementation - -**Basic Mini App Sharing:** - -```typescript -agent.on("text", async (ctx) => { - const description = "๐ŸŽฏ Ready for a quick quiz challenge?"; - const appUrl = "https://your-miniapp.com/quiz"; - await ctx.sendText(`${description}\n\n${appUrl}`); -} -``` - -**Advanced Integration with Context:** - -```typescript -// Agent detects conversation context and shares relevant Mini App -async function handleMessage(message, conversation) { - const text = message.content.toLowerCase(); - - if (text.includes("game") || text.includes("play")) { - await shareMiniApp( - conversation, - "https://your-miniapp.com/games", - "๐ŸŽฎ Let's play! Choose your game:" - ); - } else if (text.includes("vote") || text.includes("decide")) { - await shareMiniApp( - conversation, - "https://your-miniapp.com/poll", - "๐Ÿ—ณ๏ธ Let's settle this with a poll:" - ); - } -} -``` - -## User Engagement & Mentions - -### 2. Engage & Mention Users - -Agents on XMTP only have access to the 0x addresses. If you're building a group chat experience with Mini Apps, you'll want to use human-readable mentions like display names (like @jesse) for a more social, intuitive experience. - -This API from Neynar will give your agent access to this data: - -**Getting Display Names:** - -```typescript -import { NeynarAPIClient } from "@neynar/nodejs-sdk"; - -const neynar = new NeynarAPIClient("YOUR_API_KEY"); - -async function getDisplayName(address) { - try { - const users = await neynar.lookupUserByVerification(address); - return users.result.users[0]?.display_name || address.slice(0, 8); - } catch (error) { - return address.slice(0, 8); // Fallback to truncated address - } -} - -// Usage in agent messages -async function announceWinner(conversation, winnerAddress, gameType) { - const displayName = await getDisplayName(winnerAddress); - await conversation.send(`๐Ÿ† @${displayName} wins the ${gameType}! Amazing job!`); -} -``` - -### Creating Social Group Experiences - -**Example: Multiplayer Game Coordination** - -```typescript -class GameAgent { - private activeGames = new Map(); - - async handleGameMessage(message, conversation) { - const gameId = conversation.id; - - if (message.content.includes("/start")) { - await this.startGame(conversation, gameId); - } else if (message.content.includes("/join")) { - await this.joinGame(conversation, gameId, message.senderAddress); - } else if (message.content.includes("/results")) { - await this.shareResults(conversation, gameId); - } - } - - async startGame(conversation, gameId) { - const gameUrl = `https://your-miniapp.com/game/${gameId}`; - this.activeGames.set(gameId, { players: [], started: Date.now() }); - - await conversation.send( - `๐ŸŽฎ New game starting! Tap to join:\n\n${gameUrl}\n\nType /join to register` - ); - } - - async joinGame(conversation, gameId, playerAddress) { - const game = this.activeGames.get(gameId); - if (!game.players.includes(playerAddress)) { - game.players.push(playerAddress); - - const displayName = await getDisplayName(playerAddress); - await conversation.send(`โœ… @${displayName} joined the game! ${game.players.length} players ready`); - } - } - - async shareResults(conversation, gameId) { - const game = this.activeGames.get(gameId); - const results = await fetchGameResults(gameId); // Your game API - - let message = "๐Ÿ† Game Results:\n\n"; - for (let i = 0; i < results.length; i++) { - const displayName = await getDisplayName(results[i].address); - message += `${i + 1}. @${displayName} - ${results[i].score} points\n`; - } - - await conversation.send(message); - } -} -``` - -## Agent Spotlight - -[Squabble](https://github.com/builders-garden/squabble) uses Mini Apps in a social, fun way, with the agent coordinating the multiplayer experience. Check out their GitHub repo for guidance! - -The agent sends a Mini App to the group, and broadcasts to the group updates as people join and compete in the game. They mention the usernames of the people who have joined the game and won the game. The game happens inside the Mini App, which provides a more interactive, visual experience. - -### How Squabble Works - - - - Agent detects gaming context in conversation and shares the Squabble Mini App URL, which unfurls as a rich preview card. - - - - Users tap the preview to launch the Mini App, join the game, and start playing the interactive word game. - - - - Agent monitors game progress and broadcasts updates to the group as players join and compete. - - - - Agent mentions winners by username, shares final scores, and encourages replay for ongoing engagement. - - - -**Key Features:** -- **Rich mentions** โ€” Agent uses display names (@username) instead of wallet addresses -- **Real-time updates** โ€” Broadcasts join notifications and game progress to maintain group engagement -- **Social celebration** โ€” Announces winners and achievements to drive continued participation -- **Contextual triggers** โ€” Responds to gaming-related conversation with relevant Mini App shares - - -## Best Practices - -### Agent Behavior - - - -- **Smart triggers** โ€” Share Mini Apps when conversation context suggests engagement opportunity -- **Avoid spam** โ€” Don't share the same Mini App repeatedly in short timeframes -- **Read the room** โ€” Gauge group interest before introducing games or activities -- **Natural integration** โ€” Make Mini App shares feel like helpful suggestions, not advertisements - - - -- **Direct messages** โ€” Automatically share relevant Mini Apps based on user requests -- **Group messages** โ€” Only share Mini Apps when mentioned (@agentname) or when replying to agent messages -- **React to acknowledge** โ€” Use emoji reactions (๐Ÿ‘€, โŒ›) to show message received while processing -- **Coordinate experience** โ€” In groups, act as facilitator for multiplayer Mini App experiences - - - -- **Use display names** โ€” Always resolve addresses to human-readable names for mentions -- **Celebrate achievements** โ€” Announce wins, completions, and milestones to drive engagement -- **Maintain context** โ€” Remember ongoing games/activities and provide relevant updates -- **Enable discovery** โ€” Suggest related Mini Apps based on user interests and behavior - - - -### Technical Implementation - -- **Error handling** โ€” Gracefully handle Mini App load failures or API timeouts -- **Rate limiting** โ€” Respect XMTP message limits and avoid overwhelming conversations -- **State management** โ€” Track active Mini App sessions and user participation across conversations -- **Privacy** โ€” Only access necessary user data and respect privacy preferences - -## Implementation Guide - -### Setting Up Mini App Integration - - - - Set up your agent with a catalog of Mini App URLs and their associated triggers or contexts. - - ```typescript - const miniApps = { - games: "https://your-miniapp.com/games", - polls: "https://your-miniapp.com/polls", - trading: "https://your-miniapp.com/trading", - events: "https://your-miniapp.com/events" - }; - ``` - - - - Create logic to detect when sharing a Mini App would be valuable based on conversation content. - - ```typescript - function detectMiniAppContext(message) { - const content = message.content.toLowerCase(); - if (content.includes("game") || content.includes("play")) return "games"; - if (content.includes("vote") || content.includes("poll")) return "polls"; - return null; - } - ``` - - - - Integrate with Neynar API or similar service to resolve addresses to display names for better UX. - - - - Verify Mini App previews render correctly and agent coordination works across different conversation types. - - - -### Next Steps - -Ready to build your Mini App & Agent integration? - -- **Study the [Squabble example](https://github.com/builders-garden/squabble)** โ€” See real implementation patterns -- **Review [Chat Agents guide](/base-app/agents/chat-agents)** โ€” Understand XMTP agent fundamentals -- **Explore [Mini Apps documentation](/base-app/miniapps/mini-apps)** โ€” Learn Mini App development -- **Join [XMTP community](https://community.xmtp.org/)** โ€” Get help and share your builds - -By combining Mini Apps with intelligent agents, you create engaging, viral experiences that spread naturally through conversation while providing rich, interactive functionality that keeps users coming back. diff --git a/docs/base-app/agents/quick-actions.mdx b/docs/base-app/agents/quick-actions.mdx deleted file mode 100644 index 916f6dd3b..000000000 --- a/docs/base-app/agents/quick-actions.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: 'Quick Actions for Chat Agents' -description: 'Learn about supported XMTP content types and how to use them in your chat agent' -sidebarTitle: 'Quick Actions' ---- - -## Quick Actions - -While Base App supports all standard XMTP content types for rich messaging capabilities, this document focuses specifically on **Base-developed content types** that enhance agent interactions within Base App. - -These Base-specific content types (Quick Actions and Intent) provide unique functionality that may not be supported by other XMTP clients. For standard XMTP content types like reactions, attachments, and transactions, see the [XMTP documentation](https://docs.xmtp.org/agents/content-types/content-types). - -## Base App Content Types - -There are content types developed by the Base App team for agents in Base App. Other XMTP clients may not support these content types. - -**Quick Actions (coinbase.com/actions:1.0)** - -Purpose: Present interactive buttons in a message - -Structure: - -```typescript -type ActionsContent = { - id: string; - description: string; - actions: Action[]; - expiresAt?: string; -}; - -type Action = { - id: string; - label: string; - imageUrl?: string; - style?: 'primary' | 'secondary' | 'danger'; - expiresAt?: string; -}; -``` - -Validation Rules: - -- `id`, `description` are required -- `actions` must be 1โ€“10 items with unique IDs -- Style must be one of: `primary`, `secondary`, `danger` - -Fallback: - -``` -[Description] - -[1] [Action Label 1] -[2] [Action Label 2] -... -Reply with the number to select -``` - -Example: Payment Options - -```json -{ - "id": "payment_alice_123", - "description": "Choose amount to send to Alice", - "actions": [ - { "id": "send_10", "label": "Send $10", "style": "primary" }, - { "id": "send_20", "label": "Send $20", "style": "primary" }, - { "id": "custom_amount", "label": "Custom Amount", "style": "secondary" } - ], - "expiresAt": "2024-12-31T23:59:59Z" -} -``` - - - Manifest Embed Example - - -**Intent (coinbase.com/intent:1.0)** - -Purpose: User expresses choice from Quick Actions - -Structure: - -```typescript -type IntentContent = { - id: string; - actionId: string; - metadata?: Record; -}; -``` - -Validation Rules: - -- `id`, `actionId` required -- Must match corresponding Actions -- `metadata` is optional, `<10KB` - -Fallback: - -``` -User selected action: [actionId] -``` - -Example: Intent Message - -```json -{ - id: 'payment_alice_123', - actionId: 'send_10', - metadata: { - timestamp: Date.now(), - actionLabel: 'Send $10' - } -} -``` - - - Analytics dashboard with charts - diff --git a/docs/base-app/agents/transaction-trays.mdx b/docs/base-app/agents/transaction-trays.mdx deleted file mode 100644 index 24f9010ba..000000000 --- a/docs/base-app/agents/transaction-trays.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 'Custom Transaction Trays' -description: 'Learn how to customize transaction trays with agent branding and information' -sidebarTitle: 'Transaction Trays' ---- - -## Custom Transaction Trays - -If you would like to display agent information such as favicon and branded title, utilize the metadata property of wallet send calls data. - -#### **Example: Display agent information** - -```ts -// example of wallet send calls data shape{ - version: "1.0", - from: request.from as `0x${string}`, - chainId: this.networkConfig.chainId, - calls: [ - { - ... - metadata: { - description: "Transfer token", - ...other fields, - hostname: "tba.chat", - faviconUrl: "https://tba.chat/favicon", - title: "Your favorite Agent" - } - } - ] -} -``` - - - Transaction tray - - -You can send "GM" to **tbachat.base.eth** to get more details about message content types we support and get the firsthand experience on by interacting with our agent - -Our agent repo is found [here](https://github.com/siwan-cb/tba-chat-example-bot) diff --git a/docs/base-app/agents/x402-agents.mdx b/docs/base-app/agents/x402-agents.mdx deleted file mode 100644 index 30f6707b8..000000000 --- a/docs/base-app/agents/x402-agents.mdx +++ /dev/null @@ -1,501 +0,0 @@ ---- -title: 'Building Autonomous Payment Agents with x402' -description: Learn how to integrate x402 payment protocol with XMTP chat agents to enable autonomous economic transactions -sidebarTitle: 'x402 & Agents' ---- - -x402 is a revolutionary open payment protocol developed by Coinbase that enables instant, automatic stablecoin payments directly over HTTP. It empowers AI agents to autonomously pay for services without subscriptions or API keys, unlocking truly autonomous, monetized chat agents capable of reasoning, transacting, and delivering value seamlessly. - -## What is x402? - -x402 transforms how agents interact with paid services by embedding payments directly into HTTP requests. Instead of managing API keys or subscriptions, your agents can pay for exactly what they use, when they use it. - -### Key Benefits - -- **Autonomous economic transactions** - Agents can transact without human intervention -- **Pay-as-you-go monetization** - Only pay for the services you actually use -- **Minimal setup** - Often requires just one middleware line -- **Instant settlement** - Payments are verified on-chain in real-time - -## Protocol Flow - -Understanding the x402 payment flow is essential for building autonomous agents: - - - - Client requests access to a protected resource. - - - - Server returns HTTP 402 status with payment details including: - - Payment amount - - Recipient address - - Payment reference - - - - Client sends payment payload via HTTP header (e.g., `X-PAYMENT`). - - - The payment facilitator handles the on-chain settlement verification automatically. - - - - - Client retries the original request, and server responds with: - - Requested content - - Payment confirmation header (e.g., `X-PAYMENT-RESPONSE`) - - - -## Integrating x402 with XMTP Agents - -Combining x402 with XMTP chat agents creates powerful autonomous economic agents. Here's how to implement this integration: - -### Agent Architecture - -Your agent needs to handle three main scenarios: - -1. **Free requests** - Standard queries that don't require payment -2. **Payment-gated requests** - Premium features that trigger x402 payments -3. **Payment failures** - Graceful handling when payments fail - -### Basic Implementation - -Here's how your agent handles payment-gated requests using the agent SDK: - -```typescript -import { Agent } from '@xmtp/agent-sdk'; -import { PaymentFacilitator } from '@coinbase/x402-sdk'; - -// Create agent -const agent = await Agent.createFromEnv({ - env: 'production', -}); - -// Handle text messages with premium features -agent.on('text', async (ctx) => { - const message = ctx.message.content; - - // Check if user is requesting premium feature - if (message.includes('floor price')) { - await handlePremiumRequest(ctx); - } -}); - -// Initialize payment facilitator -const facilitator = new PaymentFacilitator({ - privateKey: process.env.XMTP_WALLET_KEY!, - network: process.env.NETWORK || 'base' -}); - -// Agent handles payment-gated requests -async function handlePremiumRequest(ctx: any) { - try { - const endpoint = "/premium-api/nft-floor-price"; - const response = await fetch(endpoint); - - // Check if payment is required - if (response.status === 402) { - const paymentDetails = await response.json(); - - // Notify user about payment requirement - await ctx.sendText(`๐Ÿ’ฐ Payment required: ${paymentDetails.amount} USDC. Processing...`); - - // Execute payment - const payment = await facilitator.createPayment({ - amount: paymentDetails.amount, - recipient: paymentDetails.recipient, - reference: paymentDetails.reference, - currency: 'USDC' - }); - - // Retry request with payment - const retryResponse = await fetch(endpoint, { - headers: { "X-PAYMENT": payment.payload } - }); - - if (retryResponse.ok) { - const data = await retryResponse.json(); - await ctx.sendText(`๐Ÿ“Š NFT floor price: ${data.floorPrice} ETH`); - } else { - await ctx.sendText("โŒ Payment processed but service unavailable. Please try again."); - } - } else if (response.ok) { - // Handle free-tier response - const data = await response.json(); - await ctx.sendText(`๐Ÿ“Š NFT floor price: ${data.floorPrice} ETH`); - } - } catch (error) { - await ctx.sendText("โŒ Unable to fetch data. Please try again later."); - } -} -``` - -### Environment Setup - -Make sure to set up your environment variables: - -```bash -XMTP_WALLET_KEY= # the private key of the wallet -XMTP_DB_ENCRYPTION_KEY= # encryption key for the local database -XMTP_ENV=production # local, dev, production -NETWORK=base # blockchain network for payments -``` - -### Complete Agent Example - -Here's a full implementation combining XMTP with x402: - - -```typescript Complete Agent -import { Agent } from '@xmtp/agent-sdk'; -import { PaymentFacilitator } from '@coinbase/x402-sdk'; - -// Initialize payment facilitator -const facilitator = new PaymentFacilitator({ - privateKey: process.env.XMTP_WALLET_KEY!, - network: process.env.NETWORK || 'base' -}); - -// Create the agent -const agent = await Agent.createFromEnv({ - env: 'production', // base app works only on production -}); - -// Handle text messages -agent.on('text', async (ctx) => { - const content = ctx.message.content.toLowerCase(); - - // Route messages based on content - if (content.includes('floor price')) { - await handleFloorPriceRequest(ctx, content); - } else if (content.includes('market data')) { - await handleMarketDataRequest(ctx, content); - } else { - await ctx.sendText("Hi! I can help with:\nโ€ข NFT floor prices\nโ€ข Market data\n\nJust ask!"); - } -}); - -// Handle NFT floor price requests -async function handleFloorPriceRequest(ctx: any, content: string) { - // Extract collection name from message - const collection = extractCollection(content); - - if (!collection) { - await ctx.sendText("Please specify an NFT collection name."); - return; - } - - try { - const response = await fetch(`/api/nft-floor/${collection}`); - - if (response.status === 402) { - await processPaymentAndRetry( - ctx, - `/api/nft-floor/${collection}`, - `๐Ÿ“Š Floor price for ${collection}:` - ); - } else if (response.ok) { - const data = await response.json(); - await ctx.sendText(`๐Ÿ“Š ${collection} floor price: ${data.floorPrice} ETH`); - } - } catch (error) { - await ctx.sendText("โŒ Unable to fetch floor price data."); - } -} - -// Handle market data requests -async function handleMarketDataRequest(ctx: any, content: string) { - const symbol = extractSymbol(content); - - if (!symbol) { - await ctx.sendText("Please specify a token symbol (e.g., BTC, ETH)."); - return; - } - - try { - const response = await fetch(`/api/market-data/${symbol}`); - - if (response.status === 402) { - await processPaymentAndRetry( - ctx, - `/api/market-data/${symbol}`, - `๐Ÿ’น Market data for ${symbol.toUpperCase()}:` - ); - } else if (response.ok) { - const data = await response.json(); - await ctx.sendText(`๐Ÿ’น ${symbol.toUpperCase()} - Price: $${data.price} | 24h: ${data.change24h}%`); - } - } catch (error) { - await ctx.sendText("โŒ Unable to fetch market data."); - } -} - -// Process payment and retry request -async function processPaymentAndRetry(ctx: any, endpoint: string, successPrefix: string) { - try { - // Initial request to get payment details - const response = await fetch(endpoint); - const paymentDetails = await response.json(); - - // Notify user of payment - await ctx.sendText(`๐Ÿ’ฐ Payment required: ${paymentDetails.amount} USDC. Processing...`); - - // Execute payment - const payment = await facilitator.createPayment({ - amount: paymentDetails.amount, - recipient: paymentDetails.recipient, - reference: paymentDetails.reference, - currency: 'USDC' - }); - - // Retry with payment - const retryResponse = await fetch(endpoint, { - headers: { "X-PAYMENT": payment.payload } - }); - - if (retryResponse.ok) { - const data = await retryResponse.json(); - await ctx.sendText(`${successPrefix} ${JSON.stringify(data, null, 2)}`); - } else { - await ctx.sendText("โŒ Payment processed but service error occurred."); - } - } catch (error) { - await ctx.sendText(`โŒ Payment failed: ${error.message}`); - } -} - -// Extract collection name from message -function extractCollection(content: string): string | null { - const words = content.toLowerCase().split(' '); - const collectionIndex = words.findIndex(word => - ['cryptopunks', 'bayc', 'azuki', 'pudgypenguins'].includes(word) - ); - return collectionIndex !== -1 ? words[collectionIndex] : null; -} - -// Extract token symbol from message -function extractSymbol(content: string): string | null { - const words = content.toLowerCase().split(' '); - const symbolIndex = words.findIndex(word => - ['btc', 'eth', 'usdc', 'base'].includes(word) - ); - return symbolIndex !== -1 ? words[symbolIndex] : null; -} - -// Start the agent -agent.on('start', () => { - console.log('Autonomous Payment Agent started!'); - console.log(`Agent address: ${agent.address}`); -}); - -await agent.start(); -``` - -```typescript Server Setup -import express from 'express'; -import { paymentMiddleware } from '@coinbase/x402-middleware'; - -const app = express(); - -// Apply x402 middleware -app.use(paymentMiddleware(process.env.PAYMENT_ADDRESS, { - "/api/nft-floor/*": "$0.01", - "/api/market-data/*": "$0.005" -})); - -// Protected endpoints -app.get('/api/nft-floor/:collection', (req, res) => { - // This endpoint is now payment-gated - const mockData = { - collection: req.params.collection, - floorPrice: (Math.random() * 10).toFixed(3), - currency: 'ETH', - timestamp: new Date().toISOString() - }; - - res.json(mockData); -}); - -app.get('/api/market-data/:symbol', (req, res) => { - const mockData = { - symbol: req.params.symbol, - price: (Math.random() * 1000).toFixed(2), - change24h: ((Math.random() - 0.5) * 20).toFixed(2), - volume: Math.floor(Math.random() * 1000000) - }; - - res.json(mockData); -}); - -app.listen(3000, () => { - console.log('x402-enabled API server running on port 3000'); -}); -``` - - -## Real-World Examples - -Several projects have successfully implemented x402 with XMTP agents: - -### Stableburn x402 - -A live implementation showcasing: -- XMTP v4 integration -- AgentKit functionality -- x402-based micro-payments ($0.001โ€“$0.005 per request) -- Automatic revenue burning via on-chain token swaps - - - Autonomous agent that monetizes premium endpoints with micro-payments - - -### Crossmint Worldstore Agent - -An XMTP chat agent for shopping featuring: -- x402 payment integration -- EIP-3009 gasless USDC transactions -- Base network integration -- Interactive content types in chat - - - Shopping agent with embedded x402 payments and commerce functionality - - -## Best Practices - -### Payment UX Guidelines - - -Always inform users about payment requirements before executing transactions. Transparency builds trust with your agent. - - -- **Clear pricing** - Display exact costs upfront -- **Payment confirmation** - Confirm successful payments -- **Graceful failures** - Handle payment errors elegantly -- **Value communication** - Explain what users get for their payment - -### Error Handling - -Implement comprehensive error handling for common scenarios: - -```typescript -async function robustPaymentHandler(ctx: any, endpoint: string) { - try { - const response = await fetch(endpoint); - - if (response.status === 402) { - const paymentDetails = await response.json(); - - // Validate payment details - if (!paymentDetails.amount || !paymentDetails.recipient) { - await ctx.sendText("โŒ Invalid payment request from service."); - return; - } - - // Check if amount is reasonable - if (parseFloat(paymentDetails.amount) > 1.0) { - await ctx.sendText(`โš ๏ธ High payment amount: ${paymentDetails.amount} USDC. Skipping for safety.`); - return; - } - - // Process payment with timeout - const paymentPromise = facilitator.createPayment({ - amount: paymentDetails.amount, - recipient: paymentDetails.recipient, - reference: paymentDetails.reference, - currency: 'USDC' - }); - const timeoutPromise = new Promise((_, reject) => - setTimeout(() => reject(new Error('Payment timeout')), 30000) - ); - - const payment = await Promise.race([paymentPromise, timeoutPromise]); - - // Retry with payment - const retryResponse = await fetch(endpoint, { - headers: { "X-PAYMENT": payment.payload } - }); - - if (retryResponse.ok) { - const data = await retryResponse.json(); - await ctx.sendText(`โœ… Payment successful! ${JSON.stringify(data)}`); - } else { - await ctx.sendText("โŒ Payment processed but service unavailable."); - } - } - } catch (error) { - if (error.message.includes('timeout')) { - await ctx.sendText("โฑ๏ธ Payment timed out. Please try again."); - } else if (error.message.includes('insufficient funds')) { - await ctx.sendText("๐Ÿ’ธ Insufficient funds for payment."); - } else { - await ctx.sendText(`โŒ Payment error: ${error.message}`); - } - } -} -``` - -### Security Considerations - - -Never expose private keys in your code. Always use environment variables and secure key management practices. - - -- **Key management** - Use secure environment variables -- **Payment limits** - Set maximum payment thresholds -- **Rate limiting** - Prevent payment spam attacks -- **Audit trails** - Log all payment activities -- **Network validation** - Verify on-chain settlement - -## Resources - - - - Complete x402 protocol specification and implementation guide - - - - Official x402 protocol website with examples and tools - - - - Official Coinbase x402 SDK for JavaScript/TypeScript - - - - XMTP protocol documentation for messaging integration - - - -## Next Steps - -Ready to build your autonomous payment agent? Here's your roadmap: - - - - Install the x402 SDK and XMTP agent SDK: - ```bash - npm i @xmtp/agent-sdk @coinbase/x402-sdk - ``` - - - - Start with a simple XMTP agent following our [Getting Started guide](/base-app/agents/getting-started). - - - - Integrate x402 payment handling using the examples above. - - - - Test payment flows on testnet before deploying to production. - - - - Deploy your agent and monitor payment transactions and user interactions. - - - -The future of autonomous agents is here. With x402 and XMTP, you can build agents that truly operate independently in the digital economy. diff --git a/docs/base-app/introduction/beta-faq.mdx b/docs/base-app/introduction/beta-faq.mdx deleted file mode 100644 index 62b8271cd..000000000 --- a/docs/base-app/introduction/beta-faq.mdx +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: Base App Beta -description: Frequently asked questions about the Base Wallet limited beta ---- - - -Welcome to the Base app beta. Coinbase Wallet is now Base, an everything app to create, earn, trade, discover apps, and chat with friends all in one place.Here are answers to some frequently asked questions about the beta! Thank you for building with us. - -## What is Base App - -Base is the new name for Coinbase Wallet. A new experience is coming, with a current beta for some users. You can continue using the same Coinbase Wallet features in Base App. - - -## Who can participate in the beta? - -The beta is currently open to a limited group of testers. Weโ€™ll be rolling out to more users on our waitlist soon. - -## How do I get access to the beta app? -Join the waitlist at [base.app](http://www.base.app) - -## Basenames - - - -A wallet can use multiple basenames. Sign up with a new basename, then transfer your existing basename to this new wallet. Here are the steps to transfer and use your existing basename. - -1. [Transfer the basename between wallets](https://docs.base.org/identity/basenames/basenames-faq#10-how-do-i-transfer-my-basename-to-another-address). -2. [Set the basename as the primary name on your new wallet.](https://docs.base.org/identity/basenames/basenames-faq#9-how-do-i-set-my-basename-as-my-primary-name-for-my-address) - - -Your basename will only be visible from users in the Base beta. Interaction from other clients will display your Farcaster username if you connected an account. If you create a new account your base name is set as the username on Farcaster. - - - - -## Wallet and Funds - -### I logged into the beta, but donโ€™t see my funds from my previous Coinbase Wallet. -The Base beta currently only supports smart wallets. Your funds are safe and still in the app. If you created a new smart wallet during the onboarding process, then your previous Externally Owned Account (EOA) wallet will only be available in the classic . - -You can return to your previous wallet by toggling beta mode off. -Navigate to the Social tab (first icon), tap your profile pic, and toggle โ€œbeta modeโ€ off. - -### Smart Wallet - -What is a smart wallet? -A smart wallet is a passkey-secured, self-custodial onchain wallet that's embedded in the app. It's designed for easy onboarding and better user experience. No browser extensions, no app switching. - -If you don't have a smart wallet, you will create one in the onboarding flow for the new beta app. - -**I have Base, but how do I know if I have a smart wallet?** - -If you use a passkey to sign onchain transactions, you have a smart wallet. If you don't know or you have a 12 word recovery phrase backed up somewhere, you use an EOA (externally owned account), not a smart wallet. - -From the in-app browser, go to wallet.coinbase.com and log in. If you have a smart wallet, you'll see it say "smart wallet" in your account details. - -You'll be asked to create or import a smart wallet on the way into the beta. If you are uncertain, create a new wallet. - -**Do I need a smart wallet for the beta?** -Yes. The beta is smart wallet only - - -### Common Issues - - - -The Base beta currently only supports smart wallets. Your funds are safe and still in the app. If you created a new smart wallet during the onboarding process, then your previous Externally Owned Account (EOA) wallet will only be available in the classic . - - -You can return to your previous wallet by toggling beta mode off. -Navigate to the Social tab (first icon), tap your profile pic, and toggle "beta mode" off. - - - - -## Farcaster Integration - - - -Open the social tab and engage with any post (tap like or recast). Youโ€™ll be prompted to open the Farcaster app to connect your account. Follow the prompts to link Base Wallet to Farcaster. - - - -When signing up to the beta experience, you will be prompted to create a social account. - - - -## Beta Management - -### Toggling Beta Mode - -**How can I toggle the beta off in Base again:** Navigate to the Social tab (first icon), tap your profile photo, and toggle โ€œbeta modeโ€ off. - -**I toggled beta mode off - how do I rejoin?** Navigate to the Assets tab (last tab on the right), select the settings icon in the upper right, and toggle โ€œBeta modeโ€. - - - -### Additional Questions - - - -Unfortunately, our invites are one time use. If you uninstall the app, we arenโ€™t able to add you back into the beta. However, all your wallets will still be available as long as you have your passkeys, backups, and recovery phrases. - - - -## Launch Timeline - - - -We will announce the official app launch date soon - thanks for being a part of the beta! - - diff --git a/docs/base-app/llms-full.txt b/docs/base-app/llms-full.txt deleted file mode 100644 index 3775fd02e..000000000 --- a/docs/base-app/llms-full.txt +++ /dev/null @@ -1,130 +0,0 @@ -# https://docs.base.org/base-app/llms-full.txt - -## Base App โ€” Deep Guide for LLMs - -> Base App (formerly Coinbase Wallet) is a social, onchain everything app. Builders can create Mini Apps and chatโ€‘based agents that interact with users and safely execute onchain actions. - -### What you can build -- XMTP messaging agents with safe onchain actions (transaction trays) -- Mini Apps discoverable in Base App (via MiniKit and manifests) - - For full context of mini apps, review the [mini apps llms.txt file](../mini-apps/llms.txt) - -## Minimal Critical Code (agents) -```ts -// XMTP client skeleton used across examples -import { Client, type XmtpEnv, type Signer } from '@xmtp/node-sdk' - -const encryptionKey: Uint8Array = /* stable key for history */ -const signer: Signer = /* your wallet signer */ -const env: XmtpEnv = 'dev' - -const client = await Client.create(signer, { encryptionKey, env }) -await client.conversations.sync() -for await (const msg of await client.conversations.streamAllMessages()) { - if (msg?.senderInboxId === client.inboxId) continue - const convo = await client.conversations.getConversationById(msg.conversationId) - await convo.send('gm') -} -``` - -## Navigation (with brief descriptions) - -### Introduction -- [Beta FAQ](https://docs.base.org/base-app/introduction/beta-faq.md) โ€” Beta scope, access, smart wallet notes - -### Chat Agents -- [Why Agents](https://docs.base.org/base-app/agents/why-agents.md) โ€” Rationale and examples -- [Getting Started](https://docs.base.org/base-app/agents/getting-started.md) โ€” Setup and first agent -- [Content Types](https://docs.base.org/base-app/agents/content-types.md) โ€” Messaging schemas -- [Transaction Trays](https://docs.base.org/base-app/agents/transaction-trays.md) โ€” Onchain UX in chat -- [Best Practices](https://docs.base.org/base-app/agents/best-practices.md) โ€” Implementation guidance -- [Getting Featured](https://docs.base.org/base-app/agents/getting-featured.md) โ€” Distribution checklist - - -## Quickstart (excerpts) - -Source: `https://docs.base.org/base-app/agents/getting-started.md` - -Create an XMTP agent that can receive messages and reply, then evolve it to surface transaction trays for safe onchain actions. - -Skeleton: - -```ts -import { Client, type XmtpEnv, type Signer } from '@xmtp/node-sdk' - -const signer: Signer = /* your signer */ -const encryptionKey: Uint8Array = /* stable key for history */ -const env: XmtpEnv = 'dev' - -const client = await Client.create(signer, { encryptionKey, env }) -await client.conversations.sync() -for await (const msg of await client.conversations.streamAllMessages()) { - if (msg?.senderInboxId === client.inboxId) continue - const convo = await client.conversations.getConversationById(msg.conversationId) - await convo.send('gm') -} -``` - -Source: `https://docs.base.org/base-app/agents/transaction-trays.md` - -Transaction trays let you surface predefined, safe actions. Users approve inโ€‘app; your agent never holds keys. - - -## Key Concepts (excerpts) - -Source: `https://docs.base.org/base-app/agents/why-agents.md` - -- Safety: Agents propose actions; users approve in Base App with a smart wallet. No private keys leave the client. -- UX: Transaction trays standardize onchain actions, reduce phishing, and help users understand intent. -- Content types: Structured messages ensure predictable parsing and rendering across clients. - - Source: `https://docs.base.org/base-app/agents/content-types.md` -- Distribution: Follow the featuring checklist to maximize discovery. - - Source: `https://docs.base.org/base-app/agents/getting-featured.md` - - -## API and Schemas (pruned) - -Message content types (subset): -- Text, Button, Form, Transaction Tray - - Source: `https://docs.base.org/base-app/agents/content-types.md` - -Transaction tray schema (conceptual): - -```json -{ - "type": "transaction_tray", - "title": "Buy", - "actions": [ - { "label": "Confirm purchase", "calls": [{ "to": "0x...", "data": "0x..." }] } - ] -} -``` - - -## Examples (common flows) - -Example: Simple echo agent with guardrails - -Source: `https://docs.base.org/base-app/agents/best-practices.md` - -```ts -if (!isSupportedContentType(msg)) return -const text = parseText(msg) -if (text.length > MAX_LEN) return convo.send('Message too long') -await convo.send(text) -``` - -Example: Surface a checkout action as a transaction tray - -Source: `https://docs.base.org/base-app/agents/transaction-trays.md` - -```ts -await convo.send({ - type: 'transaction_tray', - title: 'Checkout', - actions: [ - { label: 'Pay', calls: [{ to: USDC, data: erc20.transfer(MERCHANT, AMOUNT) }] } - ] -}) -``` - diff --git a/docs/base-app/llms.txt b/docs/base-app/llms.txt deleted file mode 100644 index 58acfaaff..000000000 --- a/docs/base-app/llms.txt +++ /dev/null @@ -1,20 +0,0 @@ -# https://docs.base.org/base-app/llms.txt - -## Base App Documentation - -> Base App is a social, onchain everything app (formerly Coinbase Wallet) that lets users discover Mini Apps and chat with AI messaging agents, with built-in smart-wallet transactions. - -## Introduction -- [Beta FAQ](https://docs.base.org/base-app/introduction/beta-faq.md) โ€” Beta overview, smart wallet behavior, and access - -## Chat Agents -- [Getting Started](https://docs.base.org/base-app/agents/getting-started.md) โ€” Create, test, and deploy an XMTP agent for Base App -- [Content Types](https://docs.base.org/base-app/agents/content-types.md) โ€” Message schemas and payload formats for agents -- [Transaction Trays](https://docs.base.org/base-app/agents/transaction-trays.md) โ€” Surface safe onchain actions in chat -- [Best Practices](https://docs.base.org/base-app/agents/best-practices.md) โ€” Guidance for robust, user-safe agents - -## Optional -- [Why Agents](https://docs.base.org/base-app/agents/why-agents.md) โ€” Rationale and examples for messaging agents -- [Getting Featured](https://docs.base.org/base-app/agents/getting-featured.md) โ€” How to get listed and discovered in Base App - - diff --git a/docs/docs.json b/docs/docs.json index 8f8998bd9..775a9236f 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -423,28 +423,6 @@ ] } }, - { - "tab": "Base App", - "groups": [ - { - "group": "Introduction", - "pages": ["base-app/introduction/beta-faq"] - }, - { - "group": "Chat Agents", - "pages": [ - "base-app/agents/chat-agents", - "base-app/agents/building-quality-agents", - "base-app/agents/getting-started", - "base-app/agents/quick-actions", - "base-app/agents/transaction-trays", - "base-app/agents/deeplinks", - "base-app/agents/x402-agents", - "base-app/agents/mini-apps-and-agents" - ] - } - ] - }, { "tab": "Mini Apps", "groups": [ @@ -476,7 +454,8 @@ "mini-apps/technical-guides/sign-manifest", "mini-apps/technical-guides/dynamic-embeds", "mini-apps/technical-guides/neynar-notifications", - "mini-apps/technical-guides/accept-payments" + "mini-apps/technical-guides/accept-payments", + "mini-apps/technical-guides/building-chat-agents" ] }, { @@ -1546,8 +1525,44 @@ "destination": "/base-chain/network-information/bridges" }, { - "source": "base-app/agents/getting-featured", - "destination": "base-app/agents/building-quality-agents" + "source": "/base-app/introduction/beta-faq", + "destination": "https://help.coinbase.com/en/base" + }, + { + "source": "/base-app/agents/chat-agents", + "destination": "/mini-apps/technical-guides/building-chat-agents" + }, + { + "source": "/base-app/agents/getting-started", + "destination": "/mini-apps/technical-guides/building-chat-agents#getting-started" + }, + { + "source": "/base-app/agents/building-quality-agents", + "destination": "/mini-apps/technical-guides/building-chat-agents#best-practices" + }, + { + "source": "/base-app/agents/getting-featured", + "destination": "/mini-apps/technical-guides/building-chat-agents#best-practices" + }, + { + "source": "/base-app/agents/quick-actions", + "destination": "/mini-apps/technical-guides/building-chat-agents#quick-actions" + }, + { + "source": "/base-app/agents/transaction-trays", + "destination": "/mini-apps/technical-guides/building-chat-agents#transaction-trays" + }, + { + "source": "/base-app/agents/deeplinks", + "destination": "/mini-apps/technical-guides/building-chat-agents#deeplinks" + }, + { + "source": "/base-app/agents/x402-agents", + "destination": "/mini-apps/technical-guides/building-chat-agents#payment-agents-x402" + }, + { + "source": "/base-app/agents/mini-apps-and-agents", + "destination": "/mini-apps/technical-guides/building-chat-agents#mini-app-integration" }, { "source": "/mini-apps/technical-guides/search-discovery", diff --git a/docs/mini-apps/technical-guides/building-chat-agents.mdx b/docs/mini-apps/technical-guides/building-chat-agents.mdx new file mode 100644 index 000000000..5d12fc189 --- /dev/null +++ b/docs/mini-apps/technical-guides/building-chat-agents.mdx @@ -0,0 +1,709 @@ +--- +title: "Building Chat Agents" +description: "Build conversational chat agents for Base App using XMTP messaging protocol" +--- + +import { GithubRepoCard } from "/snippets/GithubRepoCard.mdx" + +This guide covers how to build messaging agents for Base App using XMTP, a decentralized messaging protocol. Discover a fast, easy way to build and get distribution in Base App. + +## Why agents? + +Messaging is the largest use-case in the world, but it's more than just conversationsโ€”it's a secure, programmable channel for financial and social innovation. When combined with the onchain capabilities of Base App, builders have a new surface area to build 10X better messaging experiences not currently possible on legacy platforms like WhatsApp or Messenger. + +Real Examples: + +- **Smart Payment Assistant:** Text "split dinner $200 4 ways" and everyone gets paid instantly with sub-cent fees, no app switching or Venmo delays. +- **AI Trading Companion:** Message "buy 100 dollars of ETH when it hits $3,000" and your agent executes trades 24/7 while you sleep. +- **Travel Planning Agent:** "Book flight LAX to NYC under $300" and get instant booking with crypto payments, all in your group chat. + +Base App & XMTP are combining AI, crypto, and mini apps with secure messaging to unlock use-cases never before possible. Secure group chats & DMs are the new surface area for developers. + +## Getting started + +Build powerful chat agents that integrate seamlessly with Base App using the XMTP messaging protocol. + + +For more detailed information, visit [XMTP documentation](https://docs.xmtp.org/agents/get-started/build-an-agent) + + +### Installation + + + +```bash npm +npm install @xmtp/agent-sdk +``` + +```bash pnpm +pnpm add @xmtp/agent-sdk +``` + +```bash yarn +yarn add @xmtp/agent-sdk +``` + + + +### Usage + +This example shows how to create an agent that sends a message when it receives a text message. + +```ts agent.ts +import { Agent } from '@xmtp/agent-sdk'; + +// 2. Spin up the agent +const agent = await Agent.createFromEnv({ + env: 'production', // base app works only on production +}); + +// 3. Respond to text messages +agent.on('text', async (ctx) => { + await ctx.sendText('Hello from my Base App Agent! ๐Ÿ‘‹'); +}); + +// 4. Log when we're ready +agent.on('start', () => { + console.log(`Waiting for messages...`); + console.log(`Address: ${agent.address}`); +}); + +await agent.start(); +``` + +### Set environment variables + +To run an example XMTP agent, you must create a `.env` file with the following variables: + +```bash .env +XMTP_WALLET_KEY= # the private key of the wallet +XMTP_DB_ENCRYPTION_KEY= # encryption key for the local database +XMTP_ENV=production # local, dev, production +``` + +### Get a basename for your agent + +Give your agent a human-readable name: + +**1. Import agent wallet to Base App extension:** + +- Install Base App browser extension +- Import using your agent's private key + +**2. Purchase a basename:** + +- Visit https://base.org/names +- Connect your agent's wallet +- Search and purchase your desired basename (e.g., myagent.base.eth) +- Set as primary name + +**3. Verify setup:** + +- Your agent can now be reached via the basename instead of the long address +- Users can message myagent.base.eth instead of 0x123... + +## Quick actions + +While Base App supports all standard XMTP content types for rich messaging capabilities, this section focuses specifically on **Base-developed content types** that enhance agent interactions within Base App. + +These Base-specific content types (Quick Actions and Intent) provide unique functionality that may not be supported by other XMTP clients. For standard XMTP content types like reactions, attachments, and transactions, see the [XMTP documentation](https://docs.xmtp.org/agents/content-types/content-types). + +### Base App content types + +There are content types developed by the Base App team for agents in Base App. Other XMTP clients may not support these content types. + +**Quick Actions (coinbase.com/actions:1.0)** + +Purpose: Present interactive buttons in a message + +Structure: + +```typescript ActionsContent +type ActionsContent = { + id: string; + description: string; + actions: Action[]; + expiresAt?: string; +}; + +type Action = { + id: string; + label: string; + imageUrl?: string; + style?: 'primary' | 'secondary' | 'danger'; + expiresAt?: string; +}; +``` + +Validation Rules: + +- `id`, `description` are required +- `actions` must be 1โ€“10 items with unique IDs +- Style must be one of: `primary`, `secondary`, `danger` + +Fallback: + +```text Fallback format +[Description] + +[1] [Action Label 1] +[2] [Action Label 2] +... +Reply with the number to select +``` + +Example: Payment Options + +```json Payment options +{ + "id": "payment_alice_123", + "description": "Choose amount to send to Alice", + "actions": [ + { "id": "send_10", "label": "Send $10", "style": "primary" }, + { "id": "send_20", "label": "Send $20", "style": "primary" }, + { "id": "custom_amount", "label": "Custom Amount", "style": "secondary" } + ], + "expiresAt": "2024-12-31T23:59:59Z" +} +``` + + + Manifest Embed Example + + +**Intent (coinbase.com/intent:1.0)** + +Purpose: User expresses choice from Quick Actions + +Structure: + +```typescript IntentContent +type IntentContent = { + id: string; + actionId: string; + metadata?: Record; +}; +``` + +Validation Rules: + +- `id`, `actionId` required +- Must match corresponding Actions +- `metadata` is optional, `<10KB` + +Fallback: + +```text Fallback format +User selected action: [actionId] +``` + +Example: Intent Message + +```json Intent message +{ + id: 'payment_alice_123', + actionId: 'send_10', + metadata: { + timestamp: Date.now(), + actionLabel: 'Send $10' + } +} +``` + + + Analytics dashboard with charts + + + +## Transaction trays + +If you would like to display agent information such as favicon and branded title, utilize the metadata property of wallet send calls data. + +**Example: Display agent information** + +```ts Wallet send calls data +// example of wallet send calls data shape +{ + version: "1.0", + from: request.from as `0x${string}`, + chainId: this.networkConfig.chainId, + calls: [ + { + ... + metadata: { + description: "Transfer token", + ...other fields, + hostname: "tba.chat", + faviconUrl: "https://tba.chat/favicon", + title: "Your favorite Agent" + } + } + ] +} +``` + + + Transaction tray + + +You can send "GM" to **tbachat.base.eth** to get more details about message content types we support and get the firsthand experience on by interacting with our agent + + + +## Deeplinks + +Deeplinks enable seamless navigation within Base App, allowing agents to create more engaging and intuitive user experiences. The most common use case is directing users to start a private conversation with an agent from a group chat context. + +### Direct message deeplinks + +#### Use case + +Your miniapp has an agent and you want to encourage people to chat with the agent directly. Or, your agent exists in a group chat context and wants users to interact with it privately. You could add a button like "Chat with me" and use this deeplink. + +#### Syntax + +```text Deeplink syntax +cbwallet://messaging/address +``` + +#### Parameters + +- **address** โ€” The 0x address of the user you want to chat with (in hex format, e.g., `0xabc...1234`) + +### Implementation examples + +**Basic Button Implementation:** + +```typescript Basic button + +``` + +**React Component with Error Handling:** + +```typescript DeeplinkButton.tsx expandable +import { useState } from 'react'; + +interface DeeplinkButtonProps { + agentAddress: string; + label?: string; + className?: string; +} + +export function DeeplinkButton({ + agentAddress, + label = "Direct Message", + className = "btn-primary" +}: DeeplinkButtonProps) { + const [isLoading, setIsLoading] = useState(false); + + const handleDeeplink = async () => { + setIsLoading(true); + try { + const deeplink = `cbwallet://messaging/${agentAddress}`; + + // Check if running in supported environment + if (typeof window !== 'undefined') { + window.location.href = deeplink; + } else { + // Fallback for server-side rendering + console.warn('Deeplink not supported in this environment'); + } + } catch (error) { + console.error('Failed to open deeplink:', error); + } finally { + setIsLoading(false); + } + }; + + return ( + + ); +} +``` + +## Payment agents (x402) + +x402 is an open payment protocol developed by Coinbase that enables instant, automatic stablecoin payments directly over HTTP. It empowers AI agents to autonomously pay for services without subscriptions or API keys. + +### Key benefits + +- **Autonomous economic transactions** - Agents can transact without human intervention +- **Pay-as-you-go monetization** - Only pay for the services you actually use +- **Minimal setup** - Often requires just one middleware line +- **Instant settlement** - Payments are verified on-chain in real-time + +### Basic integration + +Here's how your agent handles payment-gated requests: + +```typescript x402-agent.ts expandable +import { Agent } from '@xmtp/agent-sdk'; +import { PaymentFacilitator } from '@coinbase/x402-sdk'; + +// Create agent +const agent = await Agent.createFromEnv({ + env: 'production', +}); + +// Initialize payment facilitator +const facilitator = new PaymentFacilitator({ + privateKey: process.env.XMTP_WALLET_KEY!, + network: process.env.NETWORK || 'base' +}); + +// Handle text messages with premium features +agent.on('text', async (ctx) => { + const message = ctx.message.content; + + // Check if user is requesting premium feature + if (message.includes('floor price')) { + const response = await fetch("/premium-api/nft-floor-price"); + + // Check if payment is required + if (response.status === 402) { + const paymentDetails = await response.json(); + + // Notify user about payment requirement + await ctx.sendText(`๐Ÿ’ฐ Payment required: ${paymentDetails.amount} USDC. Processing...`); + + // Execute payment + const payment = await facilitator.createPayment({ + amount: paymentDetails.amount, + recipient: paymentDetails.recipient, + reference: paymentDetails.reference, + currency: 'USDC' + }); + + // Retry request with payment + const retryResponse = await fetch("/premium-api/nft-floor-price", { + headers: { "X-PAYMENT": payment.payload } + }); + + if (retryResponse.ok) { + const data = await retryResponse.json(); + await ctx.sendText(`๐Ÿ“Š NFT floor price: ${data.floorPrice} ETH`); + } + } + } +}); + +await agent.start(); +``` + +### UX considerations + + +Always inform users about payment requirements before executing transactions. Transparency builds trust with your agent. + + +- **Clear pricing** - Display exact costs upfront +- **Payment confirmation** - Confirm successful payments +- **Graceful failures** - Handle payment errors elegantly +- **Value communication** - Explain what users get for their payment + + +Never expose private keys in your code. Always use environment variables and secure key management practices. + + +For complete x402 documentation, implementation examples, and SDK reference, see the [CDP x402 documentation](https://docs.cdp.coinbase.com/x402/welcome). + +## Mini app integration + +Mini Apps can live inside conversations, letting friends play, trade, plan, and coordinate together without ever leaving the chat. + +This means that you can have virality spread through natural conversation ("try this right here") along with sharing in larger settings. When combined with intelligent agents, you create powerful experiences that spread through natural conversation. + +This integration unlocks unique distribution and engagement patterns: + +- **Natural virality:** "Try this right here" moments spread organically through conversation +- **Contextual engagement:** Agents can introduce Mini Apps at the perfect moment +- **Group coordination:** Agents orchestrate multiplayer experiences and keep everyone engaged +- **Persistent presence:** Agents maintain engagement between Mini App sessions + +**Real Examples:** + +- **Group Gaming:** Agent coordinates a multiplayer quiz, announces winners, and keeps score across sessions +- **Event Planning:** Agent shares planning Mini App when someone mentions meeting up, handles RSVPs and updates +- **Trading Competitions:** Agent creates trading challenges, shares leaderboards, and celebrates wins +- **Social Polls:** Agent launches polls when decisions need to be made, tallies results, and announces outcomes + +### Share Mini Apps in App + +Every Mini App has a shareable URL that agents can send directly in chat. When dropped into a conversation, the link automatically unfurls into a rich preview card that others can tap to launch instantly. + +**Share Flow:** +1. **Agent triggers share** โ€” Based on conversation context or user request +2. **Link generates preview** โ€” Platform fetches Mini App metadata and creates rich embed +3. **Users engage** โ€” Tap preview to launch Mini App directly in conversation +4. **Agent coordinates** โ€” Continues engagement, shares updates, mentions participants + +**Basic Mini App Sharing:** + +```typescript Basic sharing +agent.on("text", async (ctx) => { + const description = "๐ŸŽฏ Ready for a quick quiz challenge?"; + const appUrl = "https://your-miniapp.com/quiz"; + await ctx.sendText(`${description}\n\n${appUrl}`); +} +``` + +**Advanced Integration with Context:** + +```typescript Context-aware sharing +// Agent detects conversation context and shares relevant Mini App +async function handleMessage(message, conversation) { + const text = message.content.toLowerCase(); + + if (text.includes("game") || text.includes("play")) { + await shareMiniApp( + conversation, + "https://your-miniapp.com/games", + "๐ŸŽฎ Let's play! Choose your game:" + ); + } else if (text.includes("vote") || text.includes("decide")) { + await shareMiniApp( + conversation, + "https://your-miniapp.com/poll", + "๐Ÿ—ณ๏ธ Let's settle this with a poll:" + ); + } +} +``` + +### User engagement and mentions + +Agents on XMTP only have access to the 0x addresses. If you're building a group chat experience with Mini Apps, you'll want to use human-readable mentions like display names (like @jesse) for a more social, intuitive experience. + +This API from Neynar will give your agent access to this data: + +**Getting Display Names:** + +```typescript neynar.ts +import { NeynarAPIClient } from "@neynar/nodejs-sdk"; + +const neynar = new NeynarAPIClient("YOUR_API_KEY"); + +async function getDisplayName(address) { + try { + const users = await neynar.lookupUserByVerification(address); + return users.result.users[0]?.display_name || address.slice(0, 8); + } catch (error) { + return address.slice(0, 8); // Fallback to truncated address + } +} + +// Usage in agent messages +async function announceWinner(conversation, winnerAddress, gameType) { + const displayName = await getDisplayName(winnerAddress); + await conversation.send(`๐Ÿ† @${displayName} wins the ${gameType}! Amazing job!`); +} +``` + +### Agent spotlight: Squabble + +[Squabble](https://github.com/builders-garden/squabble) uses Mini Apps in a social, fun way, with the agent coordinating the multiplayer experience. + +The agent sends a Mini App to the group, and broadcasts to the group updates as people join and compete in the game. They mention the usernames of the people who have joined the game and won the game. The game happens inside the Mini App, which provides a more interactive, visual experience. + +**Key Features:** +- **Rich mentions** โ€” Agent uses display names (@username) instead of wallet addresses +- **Real-time updates** โ€” Broadcasts join notifications and game progress to maintain group engagement +- **Social celebration** โ€” Announces winners and achievements to drive continued participation +- **Contextual triggers** โ€” Responds to gaming-related conversation with relevant Mini App shares + +### Best practices for agent behavior + + + +- **Smart triggers** โ€” Share Mini Apps when conversation context suggests engagement opportunity +- **Avoid spam** โ€” Don't share the same Mini App repeatedly in short timeframes +- **Read the room** โ€” Gauge group interest before introducing games or activities +- **Natural integration** โ€” Make Mini App shares feel like helpful suggestions, not advertisements + + + +- **Direct messages** โ€” Automatically share relevant Mini Apps based on user requests +- **Group messages** โ€” Only share Mini Apps when mentioned (@agentname) or when replying to agent messages +- **React to acknowledge** โ€” Use emoji reactions (๐Ÿ‘€, โŒ›) to show message received while processing +- **Coordinate experience** โ€” In groups, act as facilitator for multiplayer Mini App experiences + + + +- **Use display names** โ€” Always resolve addresses to human-readable names for mentions +- **Celebrate achievements** โ€” Announce wins, completions, and milestones to drive engagement +- **Maintain context** โ€” Remember ongoing games/activities and provide relevant updates +- **Enable discovery** โ€” Suggest related Mini Apps based on user interests and behavior + + + + +## Best practices + +As you start building, review these guidelines to understand what makes an agent successful in the Base app. We recommend trying out existing agents in the app first to get a feel for the quality bar, what works well, and areas for improvement. + +### Build a high quality foundation + +Your agent should provide a seamless, professional experience that users will want to engage with repeatedly. Here are the core requirements: + +#### Responding to messages + +**Multi-Channel Support** +- Respond to both DMs and group chats appropriately +- Maintain consistent functionality across different conversation types + +**Immediate Feedback** +- React to messages with a simple reaction (๐Ÿ‘€, ๐Ÿ‘, โŒ›, etc.) to show acknowledgment +- This gives users confidence their message was received while processing + +**Fast Response Times** +- Provide responses quickly (< 5 seconds) +- Users expect near-instant communication in messaging apps + +#### Group chat etiquette + +In group chats, agents should only respond when: + +1. **Mentioned directly** with "@" + agent name (e.g., @bankr) +2. **Replied to directly** when a user replies to the agent's message using the reply content type + +This prevents spam and ensures agents participate naturally in group conversations. + +#### Communication style + +**Sound Human** +- Use conversational, fun, and clear language +- Keep responses polished but not robotic +- Match the energy and tone of the conversation + +**Privacy Conscious** +- Only ask for personal information when absolutely necessary +- Always explain why the information is needed +- Respect user privacy and data minimization principles + +### Craft compelling onboarding + +Your agent's first impression is critical. The onboarding message should immediately communicate value and give users a clear path forward. + +#### Great onboarding message structure + +1. **Introduce the agent** - Quick, friendly greeting with the agent's name +2. **Explain capabilities** - Clear, specific examples of what it can do +3. **Use quick select buttons** - Make it easy for users to select an action to take with the agent + +**Example: High-Quality Onboarding** + +```text Good onboarding +hey, i'm bankr. i can help you trade, transfer, and manage your crypto. here's the rundown: + +โ€ข trade anything: buy, sell, swap tokens on base, polygon, and mainnet. try "buy 0.1 eth of degen." +โ€ข send it: transfer crypto to anyone on x, farcaster, or a wallet address. +โ€ข get alpha: token recs, market data, charts. +โ€ข automate: set up recurring buys/sells. e.g. "buy $10 of $bnkr every week." + +what do you want to do first? +``` + +**Why this works:** +- Friendly, conversational tone +- Specific feature examples with concrete commands +- Clear value propositions +- Ends with a direct call-to-action + +**Example: Poor Onboarding** + +```text Bad onboarding +Gm! What can I help you with? +``` + +**Why this fails:** +- Generic greeting with no context +- No explanation of capabilities +- Puts burden on user to figure out what to do +- No clear value proposition + +### Showcase unique value + +#### Solve real problems + +Your agent should: +- **Address a unique pain point** or bring a delightful twist to an existing space +- **Help users accomplish tasks** more easily than existing solutions +- **Provide clear benefits** that users can understand immediately + +#### Enable user success + +Focus on helping users: +- **Earn** - Generate income, rewards, or value +- **Connect** - Build relationships or communities +- **Have fun** - Provide entertainment or engaging experiences +- **Complete tasks** - Streamline workflows or processes + +#### Design for engagement + +**Build Natural Growth Loops** +- Include features that encourage sharing, re-engagement, and habit forming +- Make it beneficial for users to invite others +- Create ongoing value that brings users back + +**Plan the User Journey** +1. **Define the ideal user experience first** +2. **Craft agent messages around that journey** +3. **Guide users through progressive value discovery** + +#### Continuous engagement strategy + +As users complete actions with your agent: + +- **Show clear next steps** - Always give users something else to try +- **Highlight ongoing value** - Explain how continued use benefits them +- **Create habit loops** - Design features that encourage regular interaction +- **Prevent one-and-done usage** - Build features that require return visits + +#### Examples of engagement features + +- **Progressive features** - Unlock new capabilities as users engage more +- **Personalization** - Learn user preferences and customize experiences +- **Social elements** - Enable sharing achievements or inviting friends +- **Recurring value** - Automated tasks, alerts, or regular check-ins +- **Gamification** - Points, levels, or achievement systems + +## Resources + + + + Complete XMTP protocol documentation for messaging integration + + + + Complete x402 protocol specification and implementation guide + + + + Reference implementation for Base App chat agents + + + + Multiplayer game agent with Mini App integration + +