create-message-kit 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/index.js +12 -3
  2. package/package.json +2 -2
  3. package/templates/agent/.env.example +2 -0
  4. package/{examples/one-to-one → templates/agent}/package.json +2 -4
  5. package/templates/agent/src/handler/ens.ts +211 -0
  6. package/templates/agent/src/index.ts +14 -0
  7. package/{examples/group → templates/agent}/src/lib/openai.ts +42 -4
  8. package/templates/agent/src/lib/resolver.ts +126 -0
  9. package/templates/agent/src/prompt.ts +81 -0
  10. package/templates/agent/src/skills.ts +93 -0
  11. package/templates/gm/.env.example +1 -0
  12. package/{examples → templates}/gm/package.json +1 -0
  13. package/templates/group/.env.example +3 -0
  14. package/{examples → templates}/group/package.json +1 -0
  15. package/{examples → templates}/group/src/handler/agent.ts +18 -10
  16. package/{examples → templates}/group/src/handler/game.ts +2 -2
  17. package/{examples → templates}/group/src/handler/loyalty.ts +3 -11
  18. package/{examples → templates}/group/src/handler/splitpayment.ts +18 -11
  19. package/{examples → templates}/group/src/handler/tipping.ts +10 -6
  20. package/{examples → templates}/group/src/handler/transaction.ts +11 -40
  21. package/templates/group/src/index.ts +57 -0
  22. package/templates/group/src/lib/openai.ts +137 -0
  23. package/templates/group/src/lib/resolver.ts +126 -0
  24. package/{examples/group/src/commands.ts → templates/group/src/skills.ts} +24 -26
  25. package/examples/gm/.env.example +0 -1
  26. package/examples/group/.env.example +0 -3
  27. package/examples/group/src/index.ts +0 -68
  28. package/examples/one-to-one/.env.example +0 -2
  29. package/examples/one-to-one/src/index.ts +0 -72
  30. package/examples/one-to-one/src/lib/cron.ts +0 -34
  31. package/examples/one-to-one/src/lib/redis.ts +0 -15
  32. /package/{examples → templates}/gm/src/index.ts +0 -0
  33. /package/{examples → templates}/group/src/lib/stack.ts +0 -0
@@ -1,23 +1,25 @@
1
- import type { CommandGroup } from "@xmtp/message-kit";
1
+ import type { SkillGroup } from "@xmtp/message-kit";
2
2
  import { handler as tipping } from "./handler/tipping.js";
3
3
  import { handler as agent } from "./handler/agent.js";
4
4
  import { handler as transaction } from "./handler/transaction.js";
5
5
  import { handler as games } from "./handler/game.js";
6
6
  import { handler as loyalty } from "./handler/loyalty.js";
7
+ import { helpHandler } from "./index.js";
7
8
 
8
- export const commands: CommandGroup[] = [
9
+ export const skills: SkillGroup[] = [
9
10
  {
10
11
  name: "Tipping",
11
12
  description: "Tip tokens via emoji, replies or command.",
12
- triggers: ["/tip", "🎩", "@tip"],
13
- commands: [
13
+ skills: [
14
14
  {
15
- command: "/tip [@users] [amount] [token]",
15
+ command: "/tip [@usernames] [amount] [token]",
16
+ triggers: ["/tip"],
16
17
  description: "Tip users in a specified token.",
17
18
  handler: tipping,
18
19
  params: {
19
20
  username: {
20
21
  default: "",
22
+ plural: true,
21
23
  type: "username",
22
24
  },
23
25
  amount: {
@@ -30,11 +32,11 @@ export const commands: CommandGroup[] = [
30
32
  },
31
33
  {
32
34
  name: "Transactions",
33
- triggers: ["@send", "/send", "@swap", "/swap", "/show"],
34
35
  description: "Multipurpose transaction frame built onbase.",
35
- commands: [
36
+ skills: [
36
37
  {
37
- command: "/send [amount] [token] [@username]",
38
+ command: "/send [amount] [token] [username]",
39
+ triggers: ["/send"],
38
40
  description:
39
41
  "Send a specified amount of a cryptocurrency to a destination address.",
40
42
  handler: transaction,
@@ -56,6 +58,7 @@ export const commands: CommandGroup[] = [
56
58
  },
57
59
  {
58
60
  command: "/swap [amount] [token_from] [token_to]",
61
+ triggers: ["/swap"],
59
62
  description: "Exchange one type of cryptocurrency for another.",
60
63
  handler: transaction,
61
64
  params: {
@@ -77,6 +80,7 @@ export const commands: CommandGroup[] = [
77
80
  },
78
81
  {
79
82
  command: "/show",
83
+ triggers: ["/show"],
80
84
  handler: transaction,
81
85
  description: "Show the whole frame.",
82
86
  params: {},
@@ -85,11 +89,11 @@ export const commands: CommandGroup[] = [
85
89
  },
86
90
  {
87
91
  name: "Games",
88
- triggers: ["/game", "@game", "🔎", "🔍"],
89
92
  description: "Provides various gaming experiences.",
90
- commands: [
93
+ skills: [
91
94
  {
92
95
  command: "/game [game]",
96
+ triggers: ["/game", "🔎", "🔍"],
93
97
  handler: games,
94
98
  description: "Play a game.",
95
99
  params: {
@@ -104,17 +108,19 @@ export const commands: CommandGroup[] = [
104
108
  },
105
109
  {
106
110
  name: "Loyalty",
107
- triggers: ["/points", "@points", "/leaderboard", "@leaderboard"],
108
111
  description: "Manage group members and metadata.",
109
- commands: [
112
+ skills: [
110
113
  {
111
114
  command: "/points",
115
+ triggers: ["/points"],
112
116
  handler: loyalty,
113
117
  description: "Check your points.",
114
118
  params: {},
115
119
  },
116
120
  {
117
121
  command: "/leaderboard",
122
+ triggers: ["/leaderboard"],
123
+ adminOnly: true,
118
124
  handler: loyalty,
119
125
  description: "Check the points of a user.",
120
126
  params: {},
@@ -123,11 +129,11 @@ export const commands: CommandGroup[] = [
123
129
  },
124
130
  {
125
131
  name: "Agent",
126
- triggers: ["/agent", "@agent", "@bot"],
127
132
  description: "Manage agent commands.",
128
- commands: [
133
+ skills: [
129
134
  {
130
135
  command: "/agent [prompt]",
136
+ triggers: ["/agent", "@agent", "@bot"],
131
137
  handler: agent,
132
138
  description: "Manage agent commands.",
133
139
  params: {
@@ -139,22 +145,14 @@ export const commands: CommandGroup[] = [
139
145
  },
140
146
  ],
141
147
  },
142
- {
143
- name: "Split Payments",
144
- image: true,
145
- triggers: [],
146
- description: "Split payments between users.",
147
- commands: [],
148
- },
149
148
  {
150
149
  name: "Help",
151
- triggers: ["/help"],
152
-
153
- description: "Get help with the bot.",
154
- commands: [
150
+ description: "Get help with the bot.",
151
+ skills: [
155
152
  {
156
153
  command: "/help",
157
- handler: undefined,
154
+ triggers: ["/help"],
155
+ handler: helpHandler,
158
156
  description: "Get help with the bot.",
159
157
  params: {},
160
158
  },
@@ -1 +0,0 @@
1
- KEY= # 0x... the private key of the bot wallet (with the 0x prefix)
@@ -1,3 +0,0 @@
1
- KEY= # 0x... the private key of the bot wallet (with the 0x prefix)
2
- OPEN_AI_API_KEY= # openai api key
3
- STACK_API_KEY= # stack api key
@@ -1,68 +0,0 @@
1
- import { run, HandlerContext } from "@xmtp/message-kit";
2
- import { handler as tipping } from "./handler/tipping.js";
3
- import { handler as agent } from "./handler/agent.js";
4
- import { handler as splitpayment } from "./handler/splitpayment.js";
5
-
6
- // Main function to run the app
7
- run(async (context: HandlerContext) => {
8
- const {
9
- message: { typeId },
10
- } = context;
11
- switch (typeId) {
12
- case "reply":
13
- handleReply(context);
14
- break;
15
- case "remoteStaticAttachment":
16
- handleAttachment(context);
17
- break;
18
- case "text":
19
- handleTextMessage(context);
20
- break;
21
- }
22
- });
23
- async function handleReply(context: HandlerContext) {
24
- const {
25
- v2client,
26
- getReplyChain,
27
- version,
28
- message: {
29
- content: { reference },
30
- },
31
- } = context;
32
-
33
- const { chain, isSenderInChain } = await getReplyChain(
34
- reference,
35
- version,
36
- v2client.address,
37
- );
38
- console.log(chain);
39
- handleTextMessage(context);
40
- }
41
-
42
- // Handle attachment messages
43
- async function handleAttachment(context: HandlerContext) {
44
- await splitpayment(context);
45
- }
46
-
47
- // Handle text messages
48
- async function handleTextMessage(context: HandlerContext) {
49
- const {
50
- content: { content: text },
51
- } = context.message;
52
- if (text.includes("/help")) {
53
- await helpHandler(context);
54
- } else if (text.startsWith("@agent")) {
55
- await agent(context);
56
- } else await context.intent(text);
57
- }
58
- async function helpHandler(context: HandlerContext) {
59
- const { commands = [] } = context;
60
- const intro =
61
- "Available experiences:\n" +
62
- commands
63
- .flatMap((app) => app.commands)
64
- .map((command) => `${command.command} - ${command.description}`)
65
- .join("\n") +
66
- "\nUse these commands to interact with specific apps.";
67
- context.send(intro);
68
- }
@@ -1,2 +0,0 @@
1
- KEY= # 0x... the private key of the bot wallet (with the 0x prefix)
2
- REDIS_CONNECTION_STRING= # redis db connection string
@@ -1,72 +0,0 @@
1
- import { getRedisClient } from "./lib/redis.js";
2
- import { run, HandlerContext } from "@xmtp/message-kit";
3
- import { startCron } from "./lib/cron.js";
4
- import { RedisClientType } from "@redis/client";
5
-
6
- //Tracks conversation steps
7
- const inMemoryCacheStep = new Map<string, number>();
8
-
9
- //List of words to stop or unsubscribe.
10
- const stopWords = ["stop", "unsubscribe", "cancel", "list"];
11
-
12
- const redisClient: RedisClientType = await getRedisClient();
13
-
14
- let clientInitialized = false;
15
- run(async (context: HandlerContext) => {
16
- const {
17
- v2client,
18
- message: {
19
- content: { content: text },
20
- typeId,
21
- sender,
22
- },
23
- } = context;
24
-
25
- if (!clientInitialized) {
26
- startCron(redisClient, v2client);
27
- clientInitialized = true;
28
- }
29
- if (typeId !== "text") {
30
- /* If the input is not text do nothing */
31
- return;
32
- }
33
-
34
- const lowerContent = text?.toLowerCase();
35
-
36
- //Handles unsubscribe and resets step
37
- if (stopWords.some((word) => lowerContent.includes(word))) {
38
- inMemoryCacheStep.set(sender.address, 0);
39
- await redisClient.del(sender.address);
40
- await context.reply(
41
- "You are now unsubscribed. You will no longer receive updates!.",
42
- );
43
- return;
44
- }
45
-
46
- const cacheStep = inMemoryCacheStep.get(sender.address) || 0;
47
- let message = "";
48
- if (cacheStep === 0) {
49
- message = "Welcome! Choose an option:\n1. Info\n2. Subscribe";
50
- // Move to the next step
51
- inMemoryCacheStep.set(sender.address, cacheStep + 1);
52
- } else if (cacheStep === 1) {
53
- if (text === "1") {
54
- message = "Here is the info.";
55
- } else if (text === "2") {
56
- await redisClient.set(sender.address, "subscribed"); //test
57
- message =
58
- "You are now subscribed. You will receive updates.\n\ntype 'stop' to unsubscribe";
59
- //reset the app to the initial step
60
- inMemoryCacheStep.set(sender.address, 0);
61
- } else {
62
- message = "Invalid option. Please choose 1 for Info or 2 to Subscribe.";
63
- // Keep the same step to allow for re-entry
64
- }
65
- } else {
66
- message = "Invalid option. Please start again.";
67
- inMemoryCacheStep.set(sender.address, 0);
68
- }
69
-
70
- //Send the message
71
- await context.reply(message);
72
- });
@@ -1,34 +0,0 @@
1
- import cron from "node-cron";
2
- import { Client } from "@xmtp/xmtp-js";
3
- import { RedisClientType } from "@redis/client";
4
-
5
- export async function startCron(
6
- redisClient: RedisClientType,
7
- v2client: Client,
8
- ) {
9
- console.log("Starting daily cron");
10
- const conversations = await v2client.conversations.list();
11
- cron.schedule(
12
- "0 0 * * *", // Daily or every 5 seconds in debug mode
13
- async () => {
14
- const keys = await redisClient.keys("*");
15
- console.log(`Running daily task. ${keys.length} subscribers.`);
16
- for (const address of keys) {
17
- const subscriptionStatus = await redisClient.get(address);
18
- if (subscriptionStatus === "subscribed") {
19
- console.log(`Sending daily update to ${address}`);
20
- // Logic to send daily updates to each subscriber
21
- const targetConversation = conversations.find(
22
- (conv) => conv.peerAddress === address,
23
- );
24
- if (targetConversation)
25
- await targetConversation.send("Here is your daily update!");
26
- }
27
- }
28
- },
29
- {
30
- scheduled: true,
31
- timezone: "UTC",
32
- },
33
- );
34
- }
@@ -1,15 +0,0 @@
1
- import { createClient } from "@redis/client";
2
- import { RedisClientType } from "@redis/client";
3
-
4
- export const getRedisClient = async () => {
5
- const client = createClient({
6
- url: process.env.REDIS_CONNECTION_STRING,
7
- });
8
-
9
- client.on("error", (err) => {
10
- console.error("Redis client error:", err);
11
- });
12
-
13
- await client.connect();
14
- return client as RedisClientType;
15
- };
File without changes
File without changes