XMTP AI
AI is transforming consumer tech, with messaging becoming the main channel for interacting with agent services. This shift will scale message traffic astronomically, analogous to the web’s rise in the 2000s. Just as Cloud-flare secured web traffic, messaging will need robust scalable end-to-end encrypted messages to protect sensitive communications.
Risks
Risks of not using end-to-end encryption:
Man in the Middle Attacks (MITM): Intercept requests in between to alter or manipulate data sent or received by the AI service or user.
- Phishing: Messages can be intercepted and manipulated.
- Privacy: Sensitive information read by unwanted parties.
- Tampering: Content can be altered without detection.
Anonymity
Using ephemeral addresses can enhance security by allowing users to message agents anonymously, protecting their identities from exposure.
Backend
You can use the xmtp
package to create wrapper around the messages sent and received by the AI agent.
Installation
Install the xmtp
package
bun install xmtp
Usage
This is how you can use the xmtp
package to create a client and handle messages.
import { XMTP } from "xmtp";
const xmtp = await XMTP(onMessage, {
encryptionKey: process.env.WALLET_PRIVATE_KEY,
});
const onMessage = async (message, user) => {
console.log(`Decoded message: ${message.content.text} by ${user.address}`);
// Your AI model response
await xmtp.sendMessage(response);
};
Gpt example
handleMessage
: Triggered each time a new message is received from XMTP.client.send()
: Used to send messages (e.g., AI prompts and responses) back to the XMTP network.
In this example, when handleMessage
is invoked, it takes the incoming user message, passes it to the AI model (OpenAI's Chat Completion API), and then sends the AI's response back over XMTP.
import { XMTP } from "xmtp";
import { OpenAI } from "openai";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const xmtp = await XMTP(onMessage, {
encryptionKey: process.env.LOCAL_KEY,
});
const onMessage = async (message, user) => {
console.log(`Decoded message: ${response} by ${user}`);
// Prepare conversation history or context as needed
const history = [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: message },
];
// Call the OpenAI API to process the user's message
const response = await openai.createChatCompletion({
model: process.env.GPT_MODEL || "gpt-4",
messages: history,
});
const response = response.data.choices[0].message.content.trim();
// Send the AI-generated response back to the XMTP network
xmtp.send(response);
};
Frontend
Same as the backend, you can use the xmtp-web
package to create a client that decrypts and encrypts messages locally.
Installation
Install the xmtp-web
package compatible with your frontend framework.
bun install xmtp-web
Usage
import { XMTP, Message } from "xmtp-web";
const xmtp = await XMTP(onMessage, {
encryptionKey: process.env.LOCAL_KEY,
});
const onSend = async (text) => {
return message;
};
const onMessage = async (message, agentAddress) => {
console.log(`Decoded message: ${message} by ${agentAddress}`);
let response; // Your ai model response
await xmtp.sendMessage(response, agentAddress);
};
React example
This is how you can use the xmtp-web
package to create a client and handle messages.
import { createClient, XMTP, Message } from "xmtp-web";
// ... other imports ...
function Chat({ user }: { user: UserInfo }) {
const [messages, setMessages] = useState<Message[]>([]);
const [newMessage, setNewMessage] = useState("");
const [xmtp, setXmtp] = useState<XMTP | undefined>(undefined);
const [isLoading, setIsLoading] = useState(true);
// ... other state variables ...
useEffect(() => {
const init = async () => {
const newWallet = Wallet.createRandom();
// ... set wallet and recipient info ...
try {
if (user?.address) {
await initXmtp(newWallet);
}
} catch (error) {
console.error("Error resolving recipient:", error);
setIsLoading(false);
}
};
init();
}, [user.address]);
const onMessage = async (message: Message | undefined) => {
if (message) {
setMessages((prevMessages) => [...prevMessages, message]);
}
};
const initXmtp = async (wallet: any) => {
try {
const xmtpClient = await createClient(onMessage, {
privateKey: wallet.privateKey,
});
setXmtp(xmtpClient);
setIsLoading(false);
} catch (error) {
console.error("Error initializing XMTP:", error);
setIsLoading(false);
}
};
const sendMessage = async (e: React.FormEvent) => {
e.preventDefault();
if (!xmtp || !newMessage || !recipientInfo?.address) return;
try {
const message = await xmtp.sendMessage(newMessage, user.address);
setMessages((prevMessages) => [...prevMessages, message]);
setNewMessage("");
} catch (error) {
console.error("Error sending message:", error);
}
};
return <div className={styles.chatContainer}>{/* Render chat UI */}</div>;
}
export default React.memo(Chat);