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.
- package/index.js +12 -3
- package/package.json +2 -2
- package/templates/agent/.env.example +2 -0
- package/{examples/one-to-one → templates/agent}/package.json +2 -4
- package/templates/agent/src/handler/ens.ts +211 -0
- package/templates/agent/src/index.ts +14 -0
- package/{examples/group → templates/agent}/src/lib/openai.ts +42 -4
- package/templates/agent/src/lib/resolver.ts +126 -0
- package/templates/agent/src/prompt.ts +81 -0
- package/templates/agent/src/skills.ts +93 -0
- package/templates/gm/.env.example +1 -0
- package/{examples → templates}/gm/package.json +1 -0
- package/templates/group/.env.example +3 -0
- package/{examples → templates}/group/package.json +1 -0
- package/{examples → templates}/group/src/handler/agent.ts +18 -10
- package/{examples → templates}/group/src/handler/game.ts +2 -2
- package/{examples → templates}/group/src/handler/loyalty.ts +3 -11
- package/{examples → templates}/group/src/handler/splitpayment.ts +18 -11
- package/{examples → templates}/group/src/handler/tipping.ts +10 -6
- package/{examples → templates}/group/src/handler/transaction.ts +11 -40
- package/templates/group/src/index.ts +57 -0
- package/templates/group/src/lib/openai.ts +137 -0
- package/templates/group/src/lib/resolver.ts +126 -0
- package/{examples/group/src/commands.ts → templates/group/src/skills.ts} +24 -26
- package/examples/gm/.env.example +0 -1
- package/examples/group/.env.example +0 -3
- package/examples/group/src/index.ts +0 -68
- package/examples/one-to-one/.env.example +0 -2
- package/examples/one-to-one/src/index.ts +0 -72
- package/examples/one-to-one/src/lib/cron.ts +0 -34
- package/examples/one-to-one/src/lib/redis.ts +0 -15
- /package/{examples → templates}/gm/src/index.ts +0 -0
- /package/{examples → templates}/group/src/lib/stack.ts +0 -0
@@ -1,23 +1,25 @@
|
|
1
|
-
import type {
|
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
|
9
|
+
export const skills: SkillGroup[] = [
|
9
10
|
{
|
10
11
|
name: "Tipping",
|
11
12
|
description: "Tip tokens via emoji, replies or command.",
|
12
|
-
|
13
|
-
commands: [
|
13
|
+
skills: [
|
14
14
|
{
|
15
|
-
command: "/tip [@
|
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
|
-
|
36
|
+
skills: [
|
36
37
|
{
|
37
|
-
command: "/send [amount] [token] [
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
154
|
+
triggers: ["/help"],
|
155
|
+
handler: helpHandler,
|
158
156
|
description: "Get help with the bot.",
|
159
157
|
params: {},
|
160
158
|
},
|
package/examples/gm/.env.example
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
KEY= # 0x... the private key of the bot wallet (with the 0x prefix)
|
@@ -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,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
|