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

Updated comments and readme #35

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
15 changes: 14 additions & 1 deletion examples/gated-group/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,17 @@ async function checkNft(
3. Once you have the group ID, you can add members using `/add <group_id> <wallet_address>`
4. The bot will verify NFT ownership and add the wallet if they own the required NFT

The bot will automatically make the group creator a super admin and can optionally make new members admins as well.
## Run the agent

```bash
# git clone repo
git clone https://github.com/ephemeraHQ/xmtp-agent-examples.git
# go to the folder
cd xmtp-agent-examples
# install packages
yarn
# generate random keys (optional)
yarn gen:keys
# run the example
yarn examples:gpt
```
34 changes: 31 additions & 3 deletions examples/gated-group/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { Client, type XmtpEnv } from "@xmtp/node-sdk";
import { Alchemy, Network } from "alchemy-sdk";
import { createSigner, getEncryptionKeyFromHex } from "@/helpers";

/* Set the Alchemy API key and network */
const settings = {
apiKey: process.env.ALCHEMY_API_KEY, // Replace with your Alchemy API key
network: Network.BASE_MAINNET, // Use the appropriate network
apiKey: process.env.ALCHEMY_API_KEY,
network: Network.BASE_MAINNET,
};

/* Get the wallet key associated to the public key of
* the agent and the encryption key for the local db
* that stores your agent's messages */
const { WALLET_KEY, ENCRYPTION_KEY } = process.env;

if (!WALLET_KEY) {
Expand All @@ -17,28 +21,37 @@ if (!ENCRYPTION_KEY) {
throw new Error("ENCRYPTION_KEY must be set");
}

/* Create the signer using viem and parse the encryption key for the local db */
const signer = createSigner(WALLET_KEY);
const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);

/* Set the environment to dev or production */
const env: XmtpEnv = "dev";

/**
* Main function to run the agent
*/
async function main() {
console.log(`Creating client on the '${env}' network...`);
/* Initialize the xmtp client */
const client = await Client.create(signer, encryptionKey, {
env,
});

console.log("Syncing conversations...");
/* Sync the conversations from the network to update the local db */
await client.conversations.sync();

console.log(
`Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`,
);

console.log("Waiting for messages...");
/* Stream all messages from the network */
const stream = client.conversations.streamAllMessages();

for await (const message of await stream) {
/* Ignore messages from the same agent or non-text messages */
if (
message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
message?.contentType?.typeId !== "text"
Expand All @@ -50,6 +63,7 @@ async function main() {
`Received message: ${message.content as string} by ${message.senderInboxId}`,
);

/* Get the conversation from the local db */
const conversation = client.conversations.getConversationById(
message.conversationId,
);
Expand All @@ -58,7 +72,10 @@ async function main() {
console.log("Unable to find conversation, skipping");
continue;
}

/* If the message is to create a new group */
if (message.content === "/create") {
/* Create a new group */
console.log("Creating group");
const group = await client.conversations.newGroup([]);
console.log("Group created", group.id);
Expand All @@ -82,33 +99,38 @@ async function main() {
typeof message.content === "string" &&
message.content.startsWith("/add")
) {
/* Extract the group id and wallet address from the message */
const groupId = message.content.split(" ")[1];
if (!groupId) {
await conversation.send("Please provide a group id");
return;
}
/* Get the group from the local db */
const group = client.conversations.getConversationById(groupId);
if (!group) {
await conversation.send("Please provide a valid group id");
return;
}
/* Extract the wallet address from the message */
const walletAddress = message.content.split(" ")[2];
if (!walletAddress) {
await conversation.send("Please provide a wallet address");
return;
}

/* Check if the user has the NFT */
const result = await checkNft(walletAddress, "XMTPeople");
if (!result) {
console.log("User can't be added to the group");
return;
} else {
/* Add the user to the group */
await group.addMembers([walletAddress]);
await conversation.send(
`User added to the group\n- Group ID: ${groupId}\n- Wallet Address: ${walletAddress}`,
);
}
} else {
/* Send a welcome message to the user */
await conversation.send(
"👋 Welcome to the Gated Bot Group!\nTo get started, type /create to set up a new group. 🚀\nThis example will check if the user has a particular nft and add them to the group if they do.\nOnce your group is created, you'll receive a unique Group ID and URL.\nShare the URL with friends to invite them to join your group!",
);
Expand All @@ -118,6 +140,12 @@ async function main() {

main().catch(console.error);

/**
* Check if the user has the NFT
* @param walletAddress - The wallet address of the user
* @param collectionSlug - The slug of the collection
* @returns true if the user has the NFT, false otherwise
*/
async function checkNft(
walletAddress: string,
collectionSlug: string,
Expand Down
15 changes: 15 additions & 0 deletions examples/gm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,18 @@ async function main() {

main().catch(console.error);
```

## Run the agent

```bash
# git clone repo
git clone https://github.com/ephemeraHQ/xmtp-agent-examples.git
# go to the folder
cd xmtp-agent-examples
# install packages
yarn
# generate random keys (optional)
yarn gen:keys
# run the example
yarn examples:gpt
```
35 changes: 33 additions & 2 deletions examples/gpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,55 @@ import { createSigner, getEncryptionKeyFromHex } from "@/helpers";

const { WALLET_KEY, ENCRYPTION_KEY, OPENAI_API_KEY } = process.env;

/* Check if the environment variables are set */
if (!WALLET_KEY) {
throw new Error("WALLET_KEY must be set");
}

/* Check if the encryption key is set */
if (!ENCRYPTION_KEY) {
throw new Error("ENCRYPTION_KEY must be set");
}

/* Check if the OpenAI API key is set */
if (!OPENAI_API_KEY) {
throw new Error("OPENAI_API_KEY must be set");
}

/* Create the signer using viem and parse the encryption key for the local db */
const signer = createSigner(WALLET_KEY);
const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);

/* Initialize the OpenAI client */
const openai = new OpenAI({ apiKey: OPENAI_API_KEY });

/* Set the environment to dev or production */
const env: XmtpEnv = "dev";

/**
* Main function to run the agent
*/
async function main() {
console.log(`Creating client on the '${env}' network...`);
/* Initialize the xmtp client */
const client = await Client.create(signer, encryptionKey, {
env,
});

console.log("Syncing conversations...");
/* Sync the conversations from the network to update the local db */
await client.conversations.sync();

console.log(
`Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`,
);

console.log("Waiting for messages...");
/* Stream all messages from the network */
const stream = client.conversations.streamAllMessages();

for await (const message of await stream) {
/* Ignore messages from the same agent or non-text messages */
if (
message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
message?.contentType?.typeId !== "text"
Expand All @@ -76,25 +90,31 @@ async function main() {
`Received message: ${message.content as string} by ${message.senderInboxId}`,
);

/* Get the conversation from the local db */
const conversation = client.conversations.getConversationById(
message.conversationId,
);

/* If the conversation is not found, skip the message */
if (!conversation) {
console.log("Unable to find conversation, skipping");
continue;
}

try {
/* Get the AI response */
const completion = await openai.chat.completions.create({
messages: [{ role: "user", content: message.content as string }],
model: "gpt-3.5-turbo",
});

/* Get the AI response */
const response =
completion.choices[0]?.message?.content ||
"I'm not sure how to respond to that.";

console.log(`Sending AI response: ${response}`);
/* Send the AI response to the conversation */
await conversation.send(response);
} catch (error) {
console.error("Error getting AI response:", error);
Expand All @@ -110,6 +130,17 @@ async function main() {
main().catch(console.error);
```

Run the agent and send a test message from [xmtp.chat](https://xmtp.chat).
## Run the agent

Enjoy your GPT-powered XMTP agent!
```bash
# git clone repo
git clone https://github.com/ephemeraHQ/xmtp-agent-examples.git
# go to the folder
cd xmtp-agent-examples
# install packages
yarn
# generate random keys (optional)
yarn gen:keys
# run the example
yarn examples:gpt
```
20 changes: 20 additions & 0 deletions examples/gpt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,55 @@ import { createSigner, getEncryptionKeyFromHex } from "@/helpers";

const { WALLET_KEY, ENCRYPTION_KEY, OPENAI_API_KEY } = process.env;

/* Check if the environment variables are set */
if (!WALLET_KEY) {
throw new Error("WALLET_KEY must be set");
}

/* Check if the encryption key is set */
if (!ENCRYPTION_KEY) {
throw new Error("ENCRYPTION_KEY must be set");
}

/* Check if the OpenAI API key is set */
if (!OPENAI_API_KEY) {
throw new Error("OPENAI_API_KEY must be set");
}

/* Create the signer using viem and parse the encryption key for the local db */
const signer = createSigner(WALLET_KEY);
const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);

/* Initialize the OpenAI client */
const openai = new OpenAI({ apiKey: OPENAI_API_KEY });

/* Set the environment to dev or production */
const env: XmtpEnv = "dev";

/**
* Main function to run the agent
*/
async function main() {
console.log(`Creating client on the '${env}' network...`);
/* Initialize the xmtp client */
const client = await Client.create(signer, encryptionKey, {
env,
});

console.log("Syncing conversations...");
/* Sync the conversations from the network to update the local db */
await client.conversations.sync();

console.log(
`Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`,
);

console.log("Waiting for messages...");
/* Stream all messages from the network */
const stream = client.conversations.streamAllMessages();

for await (const message of await stream) {
/* Ignore messages from the same agent or non-text messages */
if (
message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
message?.contentType?.typeId !== "text"
Expand All @@ -50,25 +64,31 @@ async function main() {
`Received message: ${message.content as string} by ${message.senderInboxId}`,
);

/* Get the conversation from the local db */
const conversation = client.conversations.getConversationById(
message.conversationId,
);

/* If the conversation is not found, skip the message */
if (!conversation) {
console.log("Unable to find conversation, skipping");
continue;
}

try {
/* Get the AI response */
const completion = await openai.chat.completions.create({
messages: [{ role: "user", content: message.content as string }],
model: "gpt-3.5-turbo",
});

/* Get the AI response */
const response =
completion.choices[0]?.message?.content ||
"I'm not sure how to respond to that.";

console.log(`Sending AI response: ${response}`);
/* Send the AI response to the conversation */
await conversation.send(response);
} catch (error) {
console.error("Error getting AI response:", error);
Expand Down
Loading
Loading