create-message-kit 1.2.7 → 1.2.8
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 +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
|
-
}
|