0.0.4 • Published 6 months ago

@xmtp/agent-starter v0.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

@xmtp/agent-starter

A convenient TypeScript wrapper around @xmtp/node-sdk simplifying agent delopment.

Install

yarn add @xmtp/agent-starter

See the available types

Overview

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

  • ENCRYPTION_KEY: The private key of the wallet that will be used to send or receive messages.
async function main() {
  const agent = await xmtpClient({
    encryptionKey: process.env.ENCRYPTION_KEY as string,
    onMessage: async (message: Message) => {
      console.log(
        `Decoded message: ${message.content.text} by ${message.sender.address}`,
      );

      // Your AI model response
      const response = await api("Hi, how are you?");

      //Send text message
      await agent.send({
        message: response,
        originalMessage: message,
      });
    },
  });

  console.log("Agent is up and running...");
}

main().catch(console.error);

Address availability

Returns true if an address has XMTP enabled

const isOnXMTP = await agent.canMessage(address);

Groups

To learn more about groups, read the XMTP documentation.

!TIP You need to add the agent to the group as a member.

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

const group = await agent?.conversations.newGroup([address1, address2]);

As an admin you can add members to the group.

// get the group
await group.sync();
//By address
await group.addMembers([0xaddresses]);

Encryption keys

  • ENCRYPTION_KEY: XMTP encryption keys can be managed in several ways. Here are the most common methods:

    1. Use an environment variable to provide the private key:

      • Store your private key in a .env file: ENCRYPTION_KEY=0xYOUR_PRIVATE_KEY
      const agent = await xmtpClient({
        encryptionKey: process.env.ENCRYPTION_KEY,
      });
  1. Generate the private key at runtime:

    • If no private key is provided, the agent can automatically generate a new one upon startup: ENCRYPTION_KEY=random_key
    • If exists in the .env file it will not generated a new key.
    • This method will save the key in the .env file for future use.

      const agent = await xmtpClient({});
  2. Assign a name (alias) to the randomly generated key:

    • Providing a "name" gives your key a meaningful identifier, aiding in organization and persistence. ENCRYPTION_KEY_agentA=0xYOUR_PRIVATE_KEY
    • This method will also save the key in the .env file for future use.

      const agent = await xmtpClient({
        name: "_agentA", // Optional alias for this agent
      });
  • FIXED_KEY: The fixed key is an additional security measure. It is not linked to the public address and can be randomly generated or shared across different agents. It will also be generated and saved in the .env file using the methods described above.

Receive messages

After passing the onMessage handler to your agent, the agent will start listening to incoming messages sent via the XMTP network. These messages can be of various different types explained below.

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

  if (typeId === "text") {
    // Do something with the text
  } else if (typeId === "reaction") {
    // Do something with the reaction
  } else if (typeId === "reply") {
    // Do something with the `reply`
  } else if (typeId === "attachment") {
    // Do something with the attachment data url
  } else if (typeId === "agent_message") {
    // Do something with the agent message
  } else if (typeId === "group_updated") {
    // Do something with the group updated metadata
  }
};

Content types

agent-starter provides an abstraction to XMTP content types to make it easier for devs to integrate different types of messages.

Text

See text content type for reference

let textMessage: agentMessage = {
  message: "Your message.",
  receivers: ["0x123..."], // optional
  originalMessage: message, // optional
};
await agent.send(textMessage);

Reaction

See reaction content type for reference

let reaction: agentMessage = {
  message: "😅",
  receivers: ["0x123..."], // optional
  originalMessage: message, // optional
  typeId: "reaction",
};
await agent.send(reaction);

Reply

See reply content type for reference

let reply: agentMessage = {
  message: "Your message.",
  receivers: ["0x123..."], // optional
  originalMessage: message, // optional
  typeId: "reply",
};
await agent.send(reply);

Attachment

See attachment content type for reference

let attachment: agentMessage = {
  message: "https://picsum.photos/200/300",
  receivers: ["0x123..."], // optional
  originalMessage: message, // optional
  typeId: "attachment",
};
await agent.send(attachment);

Agent

See agent content type for reference

let agentMessage: agentMessage = {
  message: "Would you like to approve this transaction?",
  metadata: {
    amount: "10",
    token: "USDC",
    chain: "base",
    destinationAddress: "0x123...789",
  },
  receivers: ["0x123..."], // optional
  originalMessage: message, // optional
  typeId: "agent_message",
};
await agent.send(agentMessage);

Open for feedback
You are welcome to provide feedback on this implementation by commenting on the Proposal for content type.