Skip to content

Commit b75a969

Browse files
authored
Update xmtp docs (#360)
* Update agent SDK usage in docs * "Update docs and env variable names" * Refactor deeplink message logic * Update XMTP_ENV comments
1 parent 2d83329 commit b75a969

File tree

4 files changed

+201
-265
lines changed

4 files changed

+201
-265
lines changed

docs/base-app/agents/chat-agents.mdx

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Real Examples:
2424

2525
• 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.
2626

27+
2728
## Getting started
2829

2930
This guide will walk you through creating, testing, and deploying your first XMTP messaging agent. By the end, you'll have a fully functional agent that can send and receive messages on the XMTP messaging network.
@@ -38,8 +39,8 @@ This guide will walk you through creating, testing, and deploying your first XMT
3839

3940
- [Getting Started with XMTP (Video)](https://www.youtube.com/watch?v=djRLnWUvwIA)
4041
- [Building Agents on XMTP](https://github.com/ephemeraHQ/xmtp-agent-examples)
41-
- [Cursor Rules](https://github.com/ephemeraHQ/xmtp-agent-examples/blob/main/.cursor/rules/xmtp.md)
42-
- [XMTP Documentation](https://docs.xmtp.org/)
42+
- [Cursor Rules](https://github.com/ephemeraHQ/xmtp-agent-examples/blob/main/.cursor/rules/xmtp.mdc)
43+
- [XMTP Documentation](https://docs.xmtp.org/agents)
4344
- [Faucets](https://portal.cdp.coinbase.com/products/faucet)
4445

4546
**STEP 1: SET UP YOUR DEVELOPMENT ENVIRONMENT**
@@ -70,8 +71,8 @@ npm run gen:keys
7071
This creates a .env file with:
7172

7273
```bash
73-
WALLET_KEY=0x... # Your agent's private key
74-
ENCRYPTION_KEY=... # Encryption key for local database
74+
XMTP_WALLET_KEY=0x... # Your agent's private key
75+
XMTP_DB_ENCRYPTION_KEY=... # Encryption key for local database
7576
XMTP_ENV=dev # Environment (local, dev, production)
7677
```
7778

@@ -80,29 +81,24 @@ XMTP_ENV=dev # Environment (local, dev, production)
8081
Create a basic agent that responds to messages:
8182

8283
```javascript
83-
// import the xmtp sdk
84-
import { Client, type XmtpEnv, type Signer } from "@xmtp/node-sdk";
85-
86-
// encryption key, must be consistent across runs
87-
const encryptionKey: Uint8Array = ...;
88-
const signer: Signer = ...;
89-
const env: XmtpEnv = "dev";
90-
91-
// create the client
92-
const client = await Client.create(signer, {encryptionKey, env });
93-
// sync the client to get the latest messages
94-
await client.conversations.sync();
95-
96-
// listen to all messages
97-
const stream = await client.conversations.streamAllMessages();
98-
for await (const message of stream) {
99-
// ignore messages from the agent
100-
if (message?.senderInboxId === client.inboxId ) continue;
101-
// get the conversation by id
102-
const conversation = await client.conversations.getConversationById(message.conversationId);
103-
// send a message from the agent
104-
await conversation.send("gm");
105-
}
84+
import { Agent, getTestUrl } from "@xmtp/agent-sdk";
85+
86+
// 2. Spin up the agent
87+
const agent = await Agent.createFromEnv({
88+
env: "dev", // or 'production' for base app
89+
});
90+
91+
// 3. Respond to text messages
92+
agent.on("text", async (ctx) => {
93+
await ctx.sendText("Hello from my XMTP Agent! 👋");
94+
});
95+
96+
// 4. Log when we're ready
97+
agent.on("start", () => {
98+
console.log(`We are online: ${getTestUrl(agent)}`);
99+
});
100+
101+
await agent.start();
106102
```
107103

108104
Then run your agent:
@@ -116,20 +112,26 @@ npm run dev
116112
Each user has a unique inboxId for retrieving their associated addresses (identifiers). One inboxId can have multiple identifiers like passkeys or EVM wallet addresses.
117113

118114
```tsx
119-
const inboxState = await client.preferences.inboxStateFromInboxIds([
120-
message.senderInboxId,
121-
]);
122-
const addressFromInboxId = inboxState[0].identifiers[0].identifier;
115+
agent.on("text", async (ctx) => {
116+
const message = ctx.message.content;
117+
const senderAddress = ctx.getSenderAddress();
118+
});
123119
```
124120

125121
You can also explore example implementations in the `/examples` folder, including:
126122

127-
- [xmtp-gm](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gm): A simple agent that replies to all text messages with "gm".
128-
- [xmtp-gpt](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gpt): An example using GPT API's to answer messages.
129-
- [xmtp-nft-gated-group](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-nft-gated-group): Add members to a group based on an NFT
130-
- [xmtp-coinbase-agentkit](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-coinbase-agentkit): Agent that uses a CDP for gassless USDC on base
131-
- [xmtp-transactions](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-transactions): Use XMTP content types to send transactions
123+
- [xmtp-gm](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gm): A simple agent that replies to all text messages with "gm"
124+
- [xmtp-gpt](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gpt): An example using GPT API's to answer messages
125+
- [xmtp-gated-group](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gated-group): Add members to a group based on arbitrary criteria
126+
- [xmtp-coinbase-agentkit](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-coinbase-agentkit): Agent that uses a CDP for gasless USDC on base
127+
- [xmtp-transactions](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-transactions): Allow transactions between users and agents
128+
- [xmtp-gaia](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-gaia): Agent that uses a CDP for gasless USDC on base
132129
- [xmtp-smart-wallet](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-smart-wallet): Agent that uses a smart wallet to send messages
130+
- [xmtp-attachments](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-attachments): Agent that sends and receives images
131+
- [xmtp-inline-actions](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-inline-actions): An example using inline actions (dynamic buttons)
132+
- [xmtp-thinking-reaction](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-thinking-reaction): Agent that reacts to messages with a thinking emoji
133+
- [xmtp-queue-dual-client](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-queue-dual-client): Agent that uses two clients to send and receive messages
134+
- [xmtp-welcome-message](https://github.com/ephemeraHQ/xmtp-agent-examples/tree/main/examples/xmtp-welcome-message): Agent that sends a welcome message when its added and to new members
133135

134136
**STEP 5: TEST YOUR AGENT**
135137

@@ -153,7 +155,7 @@ npm run dev
153155
1. Update environment:
154156

155157
```javascript
156-
XMTP_ENV = production;
158+
XMTP_ENV = production; // for base app
157159
```
158160

159161
2. Test on Base App:
@@ -188,8 +190,8 @@ Give your agent a human-readable name:
188190
• Connect your GitHub repository
189191
• Add environment variables in Railway dashboard:
190192
\- XMTP_ENV=production
191-
\- WALLET_KEY=your_agent_private_key
192-
\- ENCRYPTION_KEY=your_agent_encryption_key
193+
\- XMTP_WALLET_KEY=your_agent_private_key
194+
\- XMTP_DB_ENCRYPTION_KEY=your_agent_encryption_key
193195
• Deploy and monitor logs
194196

195197
**Option 2: Other Platforms**
@@ -207,32 +209,6 @@ Heroku, Vercel, or any Node.js hosting platform:
207209
3. Rate Limiting: Respect XMTP rate limits in your agent logic
208210
4. Security: Never expose private keys; use environment variables
209211

210-
**Monitoring**
211-
212-
Add to your agent for basic monitoring:
213-
214-
```javascript
215-
const inboxState = await client.preferences.inboxState();
216-
const address = inboxState.identifiers[0].identifier;
217-
const inboxId = client.inboxId;
218-
const installationId = client.installationId;
219-
const conversations = await client.conversations.list();
220-
221-
console.log(`
222-
✓ XMTP Client:
223-
• InboxId: ${inboxId}
224-
• Address: ${address}
225-
• Conversations: ${conversations.length}
226-
• Installations: ${inboxState.installations.length}
227-
• InstallationId: ${installationId}
228-
• Network: ${process.env.XMTP_ENV}`);
229-
230-
* console.log(\`Agent started. Address: ${xmtp.address}\`)
231-
* console.log(\`Environment: ${process.env.XMTP\_ENV}\`)
232-
* console.log(\`Listening for messages...\`)
233-
234-
```
235-
236212
## Content types
237213

238214
Base App supports various XMTP content types for rich messaging capabilities. This document outlines all supported content types, including custom types for Quick Actions and Intent.

docs/base-app/agents/deeplinks.mdx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,23 @@ export function DeeplinkButton({
9696
**Agent Message with Deeplink:**
9797

9898
```typescript
99-
import { Client } from "@xmtp/node-sdk";
100-
101-
async function sendDeeplinkMessage(conversation: any, agentAddress: string) {
99+
async function sendDeeplinkMessage(ctx: MessageContext, agentAddress: string) {
102100
const deeplink = `cbwallet://messaging/${agentAddress}`;
103-
104-
await conversation.send(
105-
`💬 Want to chat privately? Tap here to start a direct conversation:\n\n${deeplink}`
101+
102+
await ctx.sendText(
103+
`💬 Want to chat privately? Tap here to start a direct conversation:\n\n${deeplink}`,
106104
);
107105
}
108106

109-
// Usage in agent logic
110-
if (message.content.includes("/private") || message.content.includes("/dm")) {
111-
await sendDeeplinkMessage(conversation, process.env.AGENT_ADDRESS);
112-
}
107+
agent.on("text", async (ctx) => {
108+
// Usage in agent logic
109+
if (
110+
ctx.message.content?.includes("/private") ||
111+
ctx.message.content?.includes("/dm")
112+
) {
113+
await sendDeeplinkMessage(ctx, ctx.getClientAddress() || "");
114+
}
115+
});
113116
```
114117

115118
## Advanced Implementation Patterns

0 commit comments

Comments
 (0)