Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorials #14

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 61 additions & 155 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
<div align="center">

[![GitHub release](https://img.shields.io/github/release/ephemerahq/xmtp-agents.svg)](https://github.com/huggingface/smolagents/releases)
[![MIT License](https://img.shields.io/github/license/ephemerahq/xmtp-agents)](https://github.com/ephemerahq/xmtp-agents/blob/main/LICENSE)

<img src="media/logo.png" alt="Logo" width="60" />

# xmtp-agents

</div>

[`@xmtp/agent-starter`](https://github.com/ephemeraHQ/xmtp-agents/tree/main/packages/agent-starter).
is a library for building agents that communicate over the [XMTP](https://xmtp.org/) network.

#### Why XMTP?

- **End-to-end & compliant**: Data is encrypted in transit and at rest, meeting strict security and regulatory standards.
Expand All @@ -22,192 +14,95 @@ is a library for building agents that communicate over the [XMTP](https://xmtp.o

> See [FAQ](https://docs.xmtp.org/intro/faq) for more detailed information.

## Setup

```bash
yarn add @xmtp/agent-starter
```

#### Environment variables

To run your XMTP agent, you need two keys:

```bash
WALLET_KEY= # the private key of the wallet
ENCRYPTION_KEY= # a second fixed or random 32 bytes encryption key for the local db
```

> See [encryption keys](https://github.com/ephemeraHQ/xmtp-agents/tree/main/packages/agent-starter/README.md#encryption-keys) to learn more.

## Basic usage

These are the steps to initialize the XMTP listener and send messages.
## Groups

- `WALLET_KEY`: The private key of the wallet that will be used to send or receive messages.
> [!NOTE]
> You need to add the agent **as a member** to the group.

```tsx
import { xmtpClient } from "@xmtp/agent-starter";

async function main() {
const client = await xmtpClient({
walletKey: process.env.WALLET_KEY as string,
onMessage: async (message: Message) => {
console.log(`Decoded message: ${message.content.text} from ${message.sender.address}`)

// Your AI model response
const response = await api("Hi, how are you?");
// Create group
const group = await client?.conversations.newGroup([address1, address2]);

//Send text message
await client.send({
message: response,
originalMessage: message,
});
};
});
// Add member
await group.addMembers([0xaddresses]);

console.log("XMTP client is up and running on address " + client.address);
}
// Change group metadata
await group.name("New name")

main().catch(console.error);
// get group members
const members = await group.members();
```

#### Address availability

Returns `true` if an address is reachable on the xmtp network

```typescript
const isOnXMTP = await client.canMessage(address);
```
> To learn more about groups, read the [XMTP documentation](https://docs.xmtp.org).

## Examples
## Keys

Various examples and tutorials to help you get started with creating and deploying your own agents using XMTP.
By default, your bot will have a new address every time you start it up. That's ideal. If you have a private key, you can encode it to a hex string and set the KEY environment variable. Your bot will then use this key to connect to the network.

- [gated-group](/examples/gated-group/): Create a gated group chat that verifies NFT ownership using Alchemy.
- [gm](/examples/gm/): A simple agent that replies with `gm`.
- [gpt](/examples/gpt): A simple agent that interacts with OpenAI APIs.
- [express](/examples/express/): Communicate with traditional APIs using xmtp e2ee
XMTP uses two types of keys:

> See all the available [examples](/examples/).
1. **Wallet Key**:

## Deployment
- An Ethereum private key (e.g. `0x123...`) that defines your bot’s **on-chain identity** (its public address) (e.g. `hi.xmtp.eth`).
- By providing this key, messages sent from your bot will be tied to a consistent address.

Learn how to deploy with:
2. **Encryption Key**:
- Protects your **local database** of stored messages (it does not affect on-chain identity).
- If not provided, it’s created automatically and saved to your `.env`.

- [Railway](/examples/railway/)
- [Replit](/examples/replit/)
### 1. Provide a private key

## Groups
If you already have a key, place it in `.env`:

> [!NOTE]
> You need to add the agent **as a member** to the group.

To create a group from your agent, you can use the following code:

```tsx
const group = await client?.conversations.newGroup([address1, address2]);
```bash
WALLET_KEY=0xYOUR_PRIVATE_KEY
```

As an admin you can add members to the group.
**Usage**:

```tsx
// get the group
await group.sync();
//By address
await group.addMembers([0xaddresses]);
```ts
const agent = await createClient({
walletKey: process.env.WALLET_KEY,
});
```

> To learn more about groups, read the [XMTP documentation](https://docs.xmtp.org).

## Message handling
The bot reuses this key, retaining the same address each time it starts.

`agent-starter` provides an abstraction to XMTP [content types](https://github.com/xmtp/xmtp-js/tree/main/content-types) to make it easier for devs to integrate different types of messages.
---

### Receiving messages
### 2. Automatically generate a key

All new messages trigger the `onMessage` callback:
If you don’t set `WALLET_KEY`, the bot creates a new one at runtime:

```tsx
const onMessage = async (message: Message) => {
console.log(
`Decoded message: ${message.content.text} from ${message.sender.address}`,
);

// Your logic
};
```ts
const agent = await createClient();
```

### Sending messages

When you build an app with XMTP, all messages are encoded with a content type to ensure that an XMTP client knows how to encode and decode messages, ensuring interoperability and consistent display of messages across apps.
**Workflow**:

### Text
1. A fresh Ethereum private key is generated.
2. Key details are saved to your `.env` so the bot reuses them in future runs.

Sends a text message.
---

```tsx
let textMessage: clientMessage = {
message: "Your message.",
receivers: ["0x123..."], // optional
originalMessage: message, // optional
};
await client.send(textMessage);
```
### 3. Use a named key

### Agent message
When running multiple bots, each can have a distinct name to avoid overwriting each other’s keys:

Allows to send structured metadata over the network that is displayed as plain-text in ecosystem inboxes.

```tsx
let clientMessage: clientMessage = {
message: "Would you like to approve this transaction?",
metadata: {
amount: "10",
token: "USDC",
},
receivers: ["0x123..."], // optional
originalMessage: message, // optional
typeId: "agent_message",
};
await client.send(clientMessage);
```ts
const agent = await createClient({ name: "botA" });
```

> See [content-types](https://github.com/xmtp/xmtp-js/tree/main/content-types/content-type-reaction) for reference
In `.env`, this will be stored as `WALLET_KEY_botA=...`
**Benefit**: Simplifies managing multiple identities from one project.

## Web inbox

Interact with the XMTP protocol using [xmtp.chat](https://xmtp.chat) the official web inbox for developers using the latest version powered by MLS.

![](/media/chat.png)

> [!WARNING]
> This React app isn't a complete solution. For example, the list of conversations doesn't update when new messages arrive in existing conversations.

## Lookup library

This library helps you to lookup identities into EVM addresses compatible with XMTP.

```tsx
import { lookup } from "@xmtp/lookup";

const identifier = "vitalik.eth";
const info = await lookup(identifier);
```

Result:

```json
{
"ensDomain": "vitalik.eth",
"address": "0x1234...",
"preferredName": "vitalik.eth",
"converseUsername": "",
"avatar": "https://...",
"converseDeeplink": "https://converse.xyz/dm/..."
}
```
![](/chat.png)

> Learn more about [`lookup`](/packages/lookup/) library
> To learn more about dev tool visit the [official repo](https://github.com/xmtp/xmtp-js/tree/main/apps/xmtp.chat)

## Development

Expand All @@ -222,6 +117,17 @@ yarn install
# build
yarn build

# or run a specific example
yarn examples gm
# gm example
yarn gm
# or
cd examples
cd gm
yarn dev

# gated group example
yarn gated
# or
cd examples
cd gated-group
yarn dev
```
File renamed without changes
41 changes: 0 additions & 41 deletions examples/README.md

This file was deleted.

2 changes: 0 additions & 2 deletions examples/express/.env.example

This file was deleted.

22 changes: 0 additions & 22 deletions examples/express/.gitignore

This file was deleted.

Loading