create-message-kit 1.2.7 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +1 -1
- package/package.json +2 -3
- package/templates/agent/src/index.ts +0 -2
- package/templates/experimental/package.json +1 -0
- package/templates/experimental/src/index.ts +16 -4
- package/templates/experimental/src/lib/alchemy.ts +4 -4
- package/templates/experimental/src/lib/minilog.ts +26 -0
- package/templates/experimental/src/lib/xmtp.ts +10 -12
- package/templates/experimental/src/skills/broadcast.ts +3 -2
- package/templates/experimental/src/skills/gated.ts +14 -25
- package/templates/experimental/src/skills/todo.ts +2 -2
- package/templates/experimental/src/skills/wordle.ts +97 -0
- package/templates/agent/src/skills/game.ts +0 -58
package/index.js
CHANGED
@@ -7,7 +7,7 @@ import { default as fs } from "fs-extra";
|
|
7
7
|
import { isCancel } from "@clack/prompts";
|
8
8
|
import { detect } from "detect-package-manager";
|
9
9
|
import pc from "picocolors";
|
10
|
-
const defVersion = "1.2.
|
10
|
+
const defVersion = "1.2.8";
|
11
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
12
12
|
|
13
13
|
// Read package.json to get the version
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "create-message-kit",
|
3
|
-
"version": "1.2.
|
3
|
+
"version": "1.2.8",
|
4
4
|
"license": "MIT",
|
5
5
|
"type": "module",
|
6
6
|
"main": "index.js",
|
@@ -12,7 +12,6 @@
|
|
12
12
|
],
|
13
13
|
"scripts": {
|
14
14
|
"clean": "rm -rf .turbo && rm -rf node_modules",
|
15
|
-
"copy": "node copyTemplates.js",
|
16
15
|
"format": "yarn format:base -w .",
|
17
16
|
"format:base": "prettier --ignore-path ../../.gitignore",
|
18
17
|
"format:check": "yarn format:base -c ."
|
@@ -38,4 +37,4 @@
|
|
38
37
|
"access": "public",
|
39
38
|
"registry": "https://registry.npmjs.org/"
|
40
39
|
}
|
41
|
-
}
|
40
|
+
}
|
@@ -13,7 +13,6 @@ import { register } from "./skills/register.js";
|
|
13
13
|
import { renew } from "./skills/renew.js";
|
14
14
|
import { pay } from "./skills/pay.js";
|
15
15
|
import { reset } from "./skills/reset.js";
|
16
|
-
import { game } from "./skills/game.js";
|
17
16
|
import fs from "fs";
|
18
17
|
|
19
18
|
// [!region skills]
|
@@ -29,7 +28,6 @@ export const agent: Agent = {
|
|
29
28
|
...renew,
|
30
29
|
...reset,
|
31
30
|
...pay,
|
32
|
-
...game,
|
33
31
|
],
|
34
32
|
};
|
35
33
|
// [!endregion skills]
|
@@ -4,26 +4,38 @@ import {
|
|
4
4
|
replaceVariables,
|
5
5
|
XMTPContext,
|
6
6
|
Agent,
|
7
|
+
xmtpClient,
|
8
|
+
V3Client,
|
7
9
|
} from "@xmtp/message-kit";
|
8
|
-
import { systemPrompt } from "./prompt.js";
|
9
10
|
import fs from "fs";
|
10
|
-
|
11
|
+
import { systemPrompt } from "./prompt.js";
|
11
12
|
import { token } from "./skills/token.js";
|
12
13
|
import { todo } from "./skills/todo.js";
|
13
|
-
import { gated } from "./skills/gated.js";
|
14
|
+
import { gated, startGatedGroupServer } from "./skills/gated.js";
|
14
15
|
import { broadcast } from "./skills/broadcast.js";
|
16
|
+
import { wordle } from "./skills/wordle.js";
|
15
17
|
|
16
18
|
export const agent: Agent = {
|
17
19
|
name: "Experimental Agent",
|
18
|
-
tag: "@
|
20
|
+
tag: "@bot",
|
19
21
|
description: "An experimental agent with a lot of skills.",
|
20
22
|
skills: [
|
21
23
|
...token,
|
22
24
|
...(process?.env?.RESEND_API_KEY ? todo : []),
|
23
25
|
...(process?.env?.ALCHEMY_SDK ? gated : []),
|
24
26
|
...broadcast,
|
27
|
+
...wordle,
|
25
28
|
],
|
26
29
|
};
|
30
|
+
|
31
|
+
// [!region gated]
|
32
|
+
const { client } = await xmtpClient({
|
33
|
+
hideInitLogMessage: true,
|
34
|
+
});
|
35
|
+
|
36
|
+
startGatedGroupServer(client);
|
37
|
+
// [!endregion gated]
|
38
|
+
|
27
39
|
run(
|
28
40
|
async (context: XMTPContext) => {
|
29
41
|
const {
|
@@ -17,10 +17,10 @@ export async function checkNft(
|
|
17
17
|
(nft: any) =>
|
18
18
|
nft.contract.name.toLowerCase() === collectionSlug.toLowerCase(),
|
19
19
|
);
|
20
|
-
console.log(
|
21
|
-
|
22
|
-
|
23
|
-
);
|
20
|
+
// console.log(
|
21
|
+
// `NFTs owned on ${Network.BASE_MAINNET}:`,
|
22
|
+
// nfts.ownedNfts.length,
|
23
|
+
// );
|
24
24
|
console.log("is the nft owned: ", ownsNft);
|
25
25
|
return ownsNft as boolean;
|
26
26
|
} catch (error) {
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import fetch from "node-fetch";
|
2
|
+
|
3
|
+
export async function sendLog(title: string, description: string) {
|
4
|
+
const response = await fetch("https://api.minilog.dev/v1/logs/testlog", {
|
5
|
+
method: "POST",
|
6
|
+
headers: {
|
7
|
+
"Content-Type": "application/json",
|
8
|
+
Authorization: "Bearer pthsm38sccpux5acriqish7isz5inet7q73ef7br",
|
9
|
+
},
|
10
|
+
body: JSON.stringify({
|
11
|
+
application: "myapp-1",
|
12
|
+
severity: "DEBUG",
|
13
|
+
data: title,
|
14
|
+
metadata: {
|
15
|
+
title,
|
16
|
+
description,
|
17
|
+
},
|
18
|
+
}),
|
19
|
+
});
|
20
|
+
console.log(response);
|
21
|
+
if (!response.ok) {
|
22
|
+
console.error("Failed to send log:", response.statusText);
|
23
|
+
} else {
|
24
|
+
console.log("Log sent successfully");
|
25
|
+
}
|
26
|
+
}
|
@@ -20,7 +20,7 @@ export async function createGroup(
|
|
20
20
|
member.accountAddresses.includes(senderAddress.toLowerCase()),
|
21
21
|
);
|
22
22
|
if (senderMember) {
|
23
|
-
|
23
|
+
senderInboxId = senderMember.inboxId;
|
24
24
|
console.log("Sender's inboxId:", senderInboxId);
|
25
25
|
} else {
|
26
26
|
console.log("Sender not found in members list");
|
@@ -91,26 +91,24 @@ export async function removeFromGroup(
|
|
91
91
|
export async function addToGroup(
|
92
92
|
groupId: string,
|
93
93
|
client: V3Client,
|
94
|
-
|
95
|
-
senderAddress: string,
|
94
|
+
address: string,
|
96
95
|
): Promise<{ code: number; message: string }> {
|
97
96
|
try {
|
98
|
-
let lowerAddress =
|
99
|
-
const { v2, v3 } = await isOnXMTP(client,
|
97
|
+
let lowerAddress = address.toLowerCase();
|
98
|
+
const { v2, v3 } = await isOnXMTP(client, null, lowerAddress);
|
100
99
|
if (!v3)
|
101
100
|
return {
|
102
101
|
code: 400,
|
103
102
|
message: "You don't seem to have a v3 identity ",
|
104
103
|
};
|
105
|
-
const
|
106
|
-
|
107
|
-
|
108
|
-
await conversation?.sync();
|
104
|
+
const group = await client.conversations.getConversationById(groupId);
|
105
|
+
console.warn("Adding to group", group?.id);
|
106
|
+
await group?.sync();
|
109
107
|
//DON'T TOUCH THIS LINE
|
110
|
-
await
|
108
|
+
await group?.addMembers([lowerAddress]);
|
111
109
|
console.warn("Added member to group");
|
112
|
-
await
|
113
|
-
const members = await
|
110
|
+
await group?.sync();
|
111
|
+
const members = await group?.members();
|
114
112
|
console.warn("Number of members", members?.length);
|
115
113
|
|
116
114
|
if (members) {
|
@@ -18,12 +18,13 @@ export const broadcast: Skill[] = [
|
|
18
18
|
async function handler(context: XMTPContext) {
|
19
19
|
const {
|
20
20
|
message: {
|
21
|
-
content: {
|
21
|
+
content: {
|
22
|
+
params: { message },
|
23
|
+
},
|
22
24
|
},
|
23
25
|
} = context;
|
24
26
|
|
25
27
|
const fakeSubscribers = ["0x93E2fc3e99dFb1238eB9e0eF2580EFC5809C7204"];
|
26
|
-
const { message } = params;
|
27
28
|
await context.send("This is how your message will look like:");
|
28
29
|
await context.send(message);
|
29
30
|
const emailResponse = await context.awaitResponse(
|
@@ -2,7 +2,7 @@ import { XMTPContext, Skill, V3Client } from "@xmtp/message-kit";
|
|
2
2
|
import { createGroup } from "../lib/xmtp.js";
|
3
3
|
import express from "express";
|
4
4
|
import { checkNft } from "../lib/alchemy.js";
|
5
|
-
|
5
|
+
import { addToGroup } from "../lib/xmtp.js";
|
6
6
|
export const gated: Skill[] = [
|
7
7
|
{
|
8
8
|
skill: "/create",
|
@@ -12,14 +12,6 @@ export const gated: Skill[] = [
|
|
12
12
|
params: {},
|
13
13
|
description: "Create a new group.",
|
14
14
|
},
|
15
|
-
{
|
16
|
-
skill: "/id",
|
17
|
-
examples: ["/id"],
|
18
|
-
handler: handler,
|
19
|
-
adminOnly: true,
|
20
|
-
params: {},
|
21
|
-
description: "Get group id.",
|
22
|
-
},
|
23
15
|
];
|
24
16
|
|
25
17
|
async function handler(context: XMTPContext) {
|
@@ -29,23 +21,18 @@ async function handler(context: XMTPContext) {
|
|
29
21
|
content: { skill },
|
30
22
|
},
|
31
23
|
client,
|
32
|
-
group,
|
33
24
|
} = context;
|
34
25
|
|
35
|
-
if (skill
|
36
|
-
console.log(group?.id);
|
37
|
-
} else if (skill === "create") {
|
38
|
-
console.log(client, sender.address, client.accountAddress);
|
26
|
+
if (skill === "create") {
|
39
27
|
const group = await createGroup(
|
40
28
|
client,
|
41
29
|
sender.address,
|
42
30
|
client.accountAddress,
|
43
31
|
);
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
//startServer(client);
|
33
|
+
await context.send(
|
34
|
+
`Group created!\n- ID: ${group?.id}\n- Group Frame URL: https://converse.xyz/group/${group?.id}: \n- This url will deelink to the group inside Converse\n- Once in the other group you can share the invite with your friends.`,
|
35
|
+
);
|
49
36
|
return;
|
50
37
|
} else {
|
51
38
|
await context.send(
|
@@ -54,22 +41,24 @@ async function handler(context: XMTPContext) {
|
|
54
41
|
}
|
55
42
|
}
|
56
43
|
|
57
|
-
export function
|
44
|
+
export function startGatedGroupServer(client: V3Client) {
|
58
45
|
async function addWalletToGroup(
|
59
46
|
walletAddress: string,
|
60
47
|
groupId: string,
|
61
48
|
): Promise<string> {
|
62
|
-
const
|
63
|
-
await client.conversations.getConversationById(groupId);
|
64
|
-
const verified = await checkNft(walletAddress, "XMTPeople");
|
49
|
+
const verified = true; //await checkNft(walletAddress, "XMTPeople");
|
65
50
|
if (!verified) {
|
66
51
|
console.log("User cant be added to the group");
|
67
52
|
return "not verified";
|
68
53
|
} else {
|
69
54
|
try {
|
70
|
-
await
|
71
|
-
|
72
|
-
|
55
|
+
const added = await addToGroup(groupId, client, walletAddress);
|
56
|
+
if (added.code === 200) {
|
57
|
+
console.log(`Added wallet address: ${walletAddress} to the group`);
|
58
|
+
return "success";
|
59
|
+
} else {
|
60
|
+
return added.message;
|
61
|
+
}
|
73
62
|
} catch (error: any) {
|
74
63
|
console.log(error.message);
|
75
64
|
return "error";
|
@@ -54,9 +54,9 @@ export async function handler(context: XMTPContext) {
|
|
54
54
|
try {
|
55
55
|
let { reply } = await context.textGeneration(
|
56
56
|
email,
|
57
|
-
"Make this summary concise and to the point to be sent in an
|
57
|
+
"Make this summary concise and to the point to be sent in an email.\n msg: " +
|
58
58
|
previousMsg,
|
59
|
-
"You are an expert at summarizing to-dos.",
|
59
|
+
"You are an expert at summarizing to-dos. Return in format html and just the content inside the body tag. Dont return `html` or `body` tags",
|
60
60
|
);
|
61
61
|
if (typeof reply === "string") {
|
62
62
|
let content = {
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import { XMTPContext } from "@xmtp/message-kit";
|
2
|
+
import type { Skill } from "@xmtp/message-kit";
|
3
|
+
|
4
|
+
export const wordle: Skill[] = [
|
5
|
+
{
|
6
|
+
skill: "/wordle",
|
7
|
+
handler: handler,
|
8
|
+
examples: ["/wordle"],
|
9
|
+
description: "Play wordle.",
|
10
|
+
params: {},
|
11
|
+
},
|
12
|
+
{
|
13
|
+
skill: "/arena [word count] [audience size]",
|
14
|
+
examples: ["/arena 3 15"],
|
15
|
+
handler: handler,
|
16
|
+
description: "Play arena.",
|
17
|
+
params: {
|
18
|
+
wordCount: {
|
19
|
+
default: 3,
|
20
|
+
type: "number",
|
21
|
+
},
|
22
|
+
audienceSize: {
|
23
|
+
default: 15,
|
24
|
+
type: "number",
|
25
|
+
},
|
26
|
+
},
|
27
|
+
},
|
28
|
+
];
|
29
|
+
|
30
|
+
async function handler(context: XMTPContext) {
|
31
|
+
const {
|
32
|
+
message: {
|
33
|
+
content: { skill },
|
34
|
+
},
|
35
|
+
} = context;
|
36
|
+
|
37
|
+
if (skill === "arena") {
|
38
|
+
await handleArenaMessage(context);
|
39
|
+
} else if (skill === "wordle") {
|
40
|
+
await context.send("https://framedl.xyz");
|
41
|
+
} else if (skill === "help") {
|
42
|
+
await context.send(
|
43
|
+
"For using this bot you can use the following commands:\n\n" +
|
44
|
+
"/wordle, @wordle, 🔍, 🔎 - To start the game\n" +
|
45
|
+
"/arena <word count> <audience size> - To start the arena game\n" +
|
46
|
+
"/help - To see commands",
|
47
|
+
);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
async function handleArenaMessage(context: XMTPContext) {
|
51
|
+
const {
|
52
|
+
message: {
|
53
|
+
content: { text },
|
54
|
+
},
|
55
|
+
members,
|
56
|
+
} = context;
|
57
|
+
|
58
|
+
const apiKey = process.env.FRAMEDL_API_KEY;
|
59
|
+
if (!apiKey) {
|
60
|
+
console.log("FRAMEDL_API_KEY is not set");
|
61
|
+
await context.send("https://www.framedl.xyz/games/arena/create");
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
const participantCount = members && members.length ? members.length - 1 : 0;
|
65
|
+
const args = text?.split(" ") ?? [];
|
66
|
+
const wordCountArg = args[1] ? parseInt(args[1], 10) : 3;
|
67
|
+
const audienceSizeArg = args[2] ? parseInt(args[2], 10) : participantCount;
|
68
|
+
if (isNaN(wordCountArg) || isNaN(audienceSizeArg)) {
|
69
|
+
await context.send(
|
70
|
+
"usage: /arena <word count> <audience size>\n\n" +
|
71
|
+
"word count: number of words in the arena (default: 3, min: 1, max: 9)\n" +
|
72
|
+
"audience size: number of audience members (default: number of participants excluding wordle bot, min: 1, max: 15)",
|
73
|
+
);
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
const audienceSize = Math.max(1, Math.min(15, audienceSizeArg));
|
78
|
+
const wordCount = Math.max(1, Math.min(9, wordCountArg));
|
79
|
+
|
80
|
+
try {
|
81
|
+
const response = await fetch("https://www.framedl.xyz/api/arenas", {
|
82
|
+
method: "POST",
|
83
|
+
body: JSON.stringify({ wordCount, audienceSize }),
|
84
|
+
headers: {
|
85
|
+
"Content-Type": "application/json",
|
86
|
+
"x-framedl-api-key": apiKey,
|
87
|
+
},
|
88
|
+
});
|
89
|
+
|
90
|
+
const data = (await response.json()) as { arenaUrl: string };
|
91
|
+
|
92
|
+
await context.send(data.arenaUrl);
|
93
|
+
} catch (error) {
|
94
|
+
console.error(error);
|
95
|
+
await context.send("https://www.framedl.xyz/games/arena/create");
|
96
|
+
}
|
97
|
+
}
|
@@ -1,58 +0,0 @@
|
|
1
|
-
import { XMTPContext } from "@xmtp/message-kit";
|
2
|
-
import type { Skill } from "@xmtp/message-kit";
|
3
|
-
|
4
|
-
export const game: Skill[] = [
|
5
|
-
{
|
6
|
-
skill: "/game [game]",
|
7
|
-
handler: handler,
|
8
|
-
description: "Play a game.",
|
9
|
-
examples: ["/game wordle", "/game slot", "/game help"],
|
10
|
-
params: {
|
11
|
-
game: {
|
12
|
-
default: "",
|
13
|
-
type: "string",
|
14
|
-
values: ["wordle", "slot", "help"],
|
15
|
-
},
|
16
|
-
},
|
17
|
-
},
|
18
|
-
];
|
19
|
-
|
20
|
-
export async function handler(context: XMTPContext) {
|
21
|
-
const {
|
22
|
-
message: {
|
23
|
-
content: { skill, params, text },
|
24
|
-
},
|
25
|
-
} = context;
|
26
|
-
if (!skill) {
|
27
|
-
if (text === "🔎" || text === "🔍") {
|
28
|
-
// Send the URL for the requested game
|
29
|
-
context.reply("https://framedl.xyz/");
|
30
|
-
}
|
31
|
-
return;
|
32
|
-
}
|
33
|
-
// URLs for each game type
|
34
|
-
const gameUrls: { [key: string]: string } = {
|
35
|
-
wordle: "https://framedl.xyz",
|
36
|
-
slot: "https://slot-machine-frame.vercel.app",
|
37
|
-
};
|
38
|
-
let returnText = "";
|
39
|
-
switch (params.game) {
|
40
|
-
case "wordle":
|
41
|
-
case "slot":
|
42
|
-
// Retrieve the URL for the requested game using a simplified variable assignment
|
43
|
-
const gameUrl = gameUrls[params.game];
|
44
|
-
// Send the URL for the requested game
|
45
|
-
returnText = gameUrl;
|
46
|
-
break;
|
47
|
-
|
48
|
-
case "help":
|
49
|
-
returnText = "Available games: \n/game wordle\n/game slot";
|
50
|
-
break;
|
51
|
-
default:
|
52
|
-
// Inform the user about unrecognized skills and provide available options
|
53
|
-
returnText =
|
54
|
-
"Skill not recognized. Available games: wordle, slot, or help.";
|
55
|
-
break;
|
56
|
-
}
|
57
|
-
return { code: 200, message: returnText };
|
58
|
-
}
|