create-message-kit 1.1.7-beta.9 → 1.1.8-beta.1
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/README.md +2 -2
- package/index.js +62 -50
- package/package.json +1 -1
- package/templates/agent/src/handler/ens.ts +14 -12
- package/templates/agent/src/index.ts +4 -17
- package/templates/agent/src/prompt.ts +15 -32
- package/templates/agent/src/skills.ts +7 -20
- package/templates/gm/.env.example +1 -1
- package/templates/gm/src/index.ts +1 -5
- package/templates/group/.env.example +2 -3
- package/templates/group/src/handler/game.ts +4 -5
- package/templates/group/src/handler/helpers.ts +10 -6
- package/templates/group/src/handler/payment.ts +29 -0
- package/templates/group/src/handler/tipping.ts +17 -35
- package/templates/group/src/index.ts +17 -26
- package/templates/group/src/prompt.ts +28 -0
- package/templates/group/src/skills.ts +22 -107
- package/templates/agent/package.json +0 -22
- package/templates/agent/src/lib/gpt.ts +0 -161
- package/templates/agent/src/lib/openai.ts +0 -174
- package/templates/agent/src/lib/resolver.ts +0 -151
- package/templates/gm/package.json +0 -21
- package/templates/group/package.json +0 -23
- package/templates/group/src/handler/agent.ts +0 -67
- package/templates/group/src/handler/group.ts +0 -24
- package/templates/group/src/handler/loyalty.ts +0 -46
- package/templates/group/src/handler/splitpayment.ts +0 -65
- package/templates/group/src/handler/transaction.ts +0 -50
- package/templates/group/src/lib/gpt.ts +0 -161
- package/templates/group/src/lib/openai.ts +0 -174
- package/templates/group/src/lib/resolver.ts +0 -151
- package/templates/group/src/lib/stack.ts +0 -18
- package/templates/group/src/lib/vision.ts +0 -42
package/README.md
CHANGED
@@ -9,7 +9,7 @@ bun create message-kit
|
|
9
9
|
```
|
10
10
|
|
11
11
|
```bash
|
12
|
-
npx create-message-kit
|
12
|
+
npx create-message-kit
|
13
13
|
```
|
14
14
|
|
15
15
|
```bash
|
@@ -17,5 +17,5 @@ yarn create message-kit
|
|
17
17
|
```
|
18
18
|
|
19
19
|
```bash [npm]
|
20
|
-
npm init message-kit
|
20
|
+
npm init message-kit
|
21
21
|
```
|
package/index.js
CHANGED
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
|
|
5
5
|
import { log, outro, text, select } from "@clack/prompts";
|
6
6
|
import { default as fs } from "fs-extra";
|
7
7
|
import { isCancel } from "@clack/prompts";
|
8
|
+
import { detect } from "detect-package-manager";
|
8
9
|
import pc from "picocolors";
|
9
10
|
|
10
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
@@ -15,9 +16,14 @@ const packageJson = JSON.parse(
|
|
15
16
|
);
|
16
17
|
const version = packageJson.version;
|
17
18
|
program
|
18
|
-
.name("
|
19
|
+
.name("message-kit")
|
19
20
|
.description("CLI to initialize projects")
|
20
21
|
.action(async () => {
|
22
|
+
// Add Yarn 4 check at the start of the action
|
23
|
+
const pkgManager = await detectPackageManager();
|
24
|
+
|
25
|
+
log.info(pc.cyan(`pkgManager detected: ${pkgManager}`));
|
26
|
+
|
21
27
|
log.info(pc.cyan(`Welcome to MessageKit CLI v${version}!`));
|
22
28
|
const coolLogo = `
|
23
29
|
███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗██╗ ██╗██╗████████╗
|
@@ -32,9 +38,6 @@ Powered by XMTP`;
|
|
32
38
|
|
33
39
|
const { templateType, displayName, destDir } = await gatherProjectInfo();
|
34
40
|
|
35
|
-
// Replace dot files
|
36
|
-
//replaceDotfiles(destDir);
|
37
|
-
|
38
41
|
// Create .gitignore
|
39
42
|
createGitignore(destDir);
|
40
43
|
|
@@ -44,13 +47,11 @@ Powered by XMTP`;
|
|
44
47
|
// Create tsconfig.json file
|
45
48
|
createTsconfig(destDir);
|
46
49
|
|
47
|
-
// Replace package.json properties
|
48
|
-
updatePackageJson(destDir, displayName);
|
49
|
-
|
50
50
|
// Wrap up
|
51
51
|
log.success(`Project launched in ${pc.red(destDir)}!`);
|
52
52
|
|
53
|
-
|
53
|
+
// Add package.json
|
54
|
+
addPackagejson(destDir, displayName, pkgManager);
|
54
55
|
|
55
56
|
// Create README.md file
|
56
57
|
createReadme(destDir, templateType, displayName, pkgManager);
|
@@ -63,6 +64,41 @@ Powered by XMTP`;
|
|
63
64
|
|
64
65
|
program.parse(process.argv);
|
65
66
|
|
67
|
+
async function addPackagejson(destDir, name, pkgManager) {
|
68
|
+
// Create package.json based on the template
|
69
|
+
let packageTemplate = {
|
70
|
+
name: name,
|
71
|
+
private: true,
|
72
|
+
type: "module",
|
73
|
+
scripts: {
|
74
|
+
build: "tsc",
|
75
|
+
dev: "tsc -w & sleep 1 && node --watch dist/index.js",
|
76
|
+
start: "node dist/index.js",
|
77
|
+
postinstall: "tsc",
|
78
|
+
},
|
79
|
+
dependencies: {
|
80
|
+
"@xmtp/message-kit": "latest",
|
81
|
+
},
|
82
|
+
engines: {
|
83
|
+
node: ">=20",
|
84
|
+
},
|
85
|
+
};
|
86
|
+
|
87
|
+
if (pkgManager.startsWith("yarn")) {
|
88
|
+
packageTemplate.packageManager = `${pkgManager}`;
|
89
|
+
// Add .yarnrc.yml to disable PnP mode
|
90
|
+
}
|
91
|
+
|
92
|
+
fs.writeFileSync(
|
93
|
+
resolve(destDir, ".yarnrc.yml"),
|
94
|
+
"nodeLinker: node-modules\n",
|
95
|
+
);
|
96
|
+
|
97
|
+
fs.writeJsonSync(resolve(destDir, "package.json"), packageTemplate, {
|
98
|
+
spaces: 2,
|
99
|
+
});
|
100
|
+
}
|
101
|
+
|
66
102
|
async function gatherProjectInfo() {
|
67
103
|
const templateOptions = [
|
68
104
|
{ value: "gm", label: "GM" },
|
@@ -108,24 +144,6 @@ async function gatherProjectInfo() {
|
|
108
144
|
return { templateType, displayName, destDir, templateDir };
|
109
145
|
}
|
110
146
|
|
111
|
-
function updateDependenciesToLatest(pkgJson) {
|
112
|
-
const updateToLatest = (deps) => {
|
113
|
-
for (const key in deps) {
|
114
|
-
if (deps[key].startsWith("workspace:")) {
|
115
|
-
deps[key] = "latest";
|
116
|
-
}
|
117
|
-
}
|
118
|
-
};
|
119
|
-
|
120
|
-
if (pkgJson.dependencies) {
|
121
|
-
updateToLatest(pkgJson.dependencies);
|
122
|
-
}
|
123
|
-
|
124
|
-
if (pkgJson.devDependencies) {
|
125
|
-
updateToLatest(pkgJson.devDependencies);
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
147
|
function createTsconfig(destDir) {
|
130
148
|
const tsconfigContent = {
|
131
149
|
include: ["src/**/*"],
|
@@ -151,22 +169,6 @@ function createTsconfig(destDir) {
|
|
151
169
|
spaces: 2,
|
152
170
|
});
|
153
171
|
}
|
154
|
-
function replaceDotfiles(destDir) {
|
155
|
-
for (const file of fs.readdirSync(destDir)) {
|
156
|
-
if (!file.startsWith("_")) continue;
|
157
|
-
fs.renameSync(
|
158
|
-
resolve(destDir, file),
|
159
|
-
resolve(destDir, `.${file.slice(1)}`),
|
160
|
-
);
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
function updatePackageJson(destDir, name) {
|
165
|
-
const pkgJson = fs.readJsonSync(resolve(destDir, "package.json"));
|
166
|
-
pkgJson.name = name;
|
167
|
-
updateDependenciesToLatest(pkgJson);
|
168
|
-
fs.writeJsonSync(resolve(destDir, "package.json"), pkgJson, { spaces: 2 });
|
169
|
-
}
|
170
172
|
|
171
173
|
function logNextSteps(name) {
|
172
174
|
log.message("Next steps:");
|
@@ -202,14 +204,24 @@ yarn-error.log*
|
|
202
204
|
fs.writeFileSync(resolve(destDir, ".gitignore"), gitignoreContent.trim());
|
203
205
|
}
|
204
206
|
|
205
|
-
function detectPackageManager() {
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
207
|
+
async function detectPackageManager() {
|
208
|
+
try {
|
209
|
+
const pkgManager = await detect();
|
210
|
+
const userAgent = process.env.npm_config_user_agent;
|
211
|
+
let version = "";
|
212
|
+
|
213
|
+
if (userAgent && pkgManager === "yarn") {
|
214
|
+
const parts = userAgent.split(" ")[0]?.split("/");
|
215
|
+
if (parts && parts.length > 1) {
|
216
|
+
version = `@${parts[1]}`;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
return pkgManager + version;
|
221
|
+
} catch (error) {
|
222
|
+
// Fallback to npm if detection fails
|
223
|
+
return "npm";
|
224
|
+
}
|
213
225
|
}
|
214
226
|
|
215
227
|
function kebabcase(str) {
|
package/package.json
CHANGED
@@ -9,17 +9,19 @@ export const baseTxUrl = "https://base-tx-frame.vercel.app";
|
|
9
9
|
|
10
10
|
export async function handleEns(
|
11
11
|
context: HandlerContext,
|
12
|
-
): Promise<SkillResponse> {
|
12
|
+
): Promise<SkillResponse | undefined> {
|
13
13
|
const {
|
14
14
|
message: {
|
15
|
-
|
15
|
+
sender,
|
16
|
+
content: { skill, params },
|
16
17
|
},
|
17
18
|
} = context;
|
18
|
-
|
19
|
+
|
20
|
+
if (skill == "reset") {
|
19
21
|
clearMemory();
|
20
22
|
return { code: 200, message: "Conversation reset." };
|
21
|
-
} else if (
|
22
|
-
// Destructure and validate parameters for the ens
|
23
|
+
} else if (skill == "renew") {
|
24
|
+
// Destructure and validate parameters for the ens
|
23
25
|
const { domain } = params;
|
24
26
|
// Check if the user holds the domain
|
25
27
|
if (!domain) {
|
@@ -42,8 +44,8 @@ export async function handleEns(
|
|
42
44
|
// Generate URL for the ens
|
43
45
|
let url_ens = frameUrl + "frames/manage?name=" + domain;
|
44
46
|
return { code: 200, message: `${url_ens}` };
|
45
|
-
} else if (
|
46
|
-
// Destructure and validate parameters for the ens
|
47
|
+
} else if (skill == "register") {
|
48
|
+
// Destructure and validate parameters for the ens
|
47
49
|
const { domain } = params;
|
48
50
|
|
49
51
|
if (!domain) {
|
@@ -55,7 +57,7 @@ export async function handleEns(
|
|
55
57
|
// Generate URL for the ens
|
56
58
|
let url_ens = ensUrl + domain;
|
57
59
|
return { code: 200, message: `${url_ens}` };
|
58
|
-
} else if (
|
60
|
+
} else if (skill == "info") {
|
59
61
|
const { domain } = params;
|
60
62
|
|
61
63
|
const data = await getUserInfo(domain);
|
@@ -92,7 +94,7 @@ export async function handleEns(
|
|
92
94
|
);
|
93
95
|
}
|
94
96
|
return { code: 200, message };
|
95
|
-
} else if (
|
97
|
+
} else if (skill == "check") {
|
96
98
|
const { domain } = params;
|
97
99
|
|
98
100
|
if (!domain) {
|
@@ -117,7 +119,7 @@ export async function handleEns(
|
|
117
119
|
message,
|
118
120
|
};
|
119
121
|
}
|
120
|
-
} else if (
|
122
|
+
} else if (skill == "tip") {
|
121
123
|
const { address } = params;
|
122
124
|
if (!address) {
|
123
125
|
return {
|
@@ -134,7 +136,7 @@ export async function handleEns(
|
|
134
136
|
code: 200,
|
135
137
|
message: txUrl,
|
136
138
|
};
|
137
|
-
} else if (
|
139
|
+
} else if (skill == "cool") {
|
138
140
|
const { domain } = params;
|
139
141
|
//What about these cool alternatives?\
|
140
142
|
return {
|
@@ -142,7 +144,7 @@ export async function handleEns(
|
|
142
144
|
message: `${generateCoolAlternatives(domain)}`,
|
143
145
|
};
|
144
146
|
} else {
|
145
|
-
return { code: 400, message: "
|
147
|
+
return { code: 400, message: "Skill not found." };
|
146
148
|
}
|
147
149
|
}
|
148
150
|
|
@@ -1,35 +1,22 @@
|
|
1
1
|
import { run, HandlerContext } from "@xmtp/message-kit";
|
2
2
|
import { textGeneration, processMultilineResponse } from "@xmtp/message-kit";
|
3
3
|
import { agent_prompt } from "./prompt.js";
|
4
|
-
import { getUserInfo } from "@xmtp/message-kit";
|
5
4
|
|
6
5
|
run(async (context: HandlerContext) => {
|
7
|
-
/*All the skills are handled through the skills file*/
|
8
|
-
/* If its just text, it will be handled by the ensAgent*/
|
9
|
-
/* If its a group message, it will be handled by the groupAgent*/
|
10
|
-
if (!process?.env?.OPEN_AI_API_KEY) {
|
11
|
-
console.warn("No OPEN_AI_API_KEY found in .env");
|
12
|
-
return;
|
13
|
-
}
|
14
|
-
|
15
6
|
const {
|
16
7
|
message: {
|
17
|
-
content: {
|
8
|
+
content: { text, params },
|
18
9
|
sender,
|
19
10
|
},
|
20
11
|
} = context;
|
21
12
|
|
22
13
|
try {
|
23
|
-
let userPrompt = params?.prompt ??
|
24
|
-
|
25
|
-
if (!userInfo) {
|
26
|
-
console.log("User info not found");
|
27
|
-
return;
|
28
|
-
}
|
14
|
+
let userPrompt = params?.prompt ?? text;
|
15
|
+
|
29
16
|
const { reply } = await textGeneration(
|
30
17
|
sender.address,
|
31
18
|
userPrompt,
|
32
|
-
await agent_prompt(
|
19
|
+
await agent_prompt(sender.address),
|
33
20
|
);
|
34
21
|
await processMultilineResponse(sender.address, reply, context);
|
35
22
|
} catch (error) {
|
@@ -1,57 +1,39 @@
|
|
1
1
|
import { skills } from "./skills.js";
|
2
|
-
import {
|
3
|
-
getUserInfo,
|
4
|
-
UserInfo,
|
5
|
-
PROMPT_USER_CONTENT,
|
6
|
-
PROMPT_RULES,
|
7
|
-
PROMPT_SKILLS_AND_EXAMPLES,
|
8
|
-
} from "@xmtp/message-kit";
|
9
|
-
|
10
|
-
export async function agent_prompt(userInfo: UserInfo) {
|
11
|
-
let { address, ensDomain, converseUsername, preferredName } = userInfo;
|
12
|
-
|
13
|
-
//Update the name of the agent with predefined prompt
|
14
|
-
let systemPrompt = PROMPT_RULES.replace("{NAME}", skills?.[0]?.tag ?? "@ens");
|
15
|
-
|
16
|
-
//Add user context to the prompt
|
17
|
-
systemPrompt += PROMPT_USER_CONTENT(userInfo);
|
18
|
-
|
19
|
-
//Add skills and examples to the prompt
|
20
|
-
systemPrompt += PROMPT_SKILLS_AND_EXAMPLES(skills, "@ens");
|
21
|
-
|
22
|
-
systemPrompt += `
|
2
|
+
import { defaultPromptTemplate } from "@xmtp/message-kit";
|
23
3
|
|
4
|
+
export async function agent_prompt(senderAddress: string) {
|
5
|
+
let fineTunning = `
|
24
6
|
## Example responses:
|
25
7
|
|
26
8
|
1. Check if the user does not have a ENS domain
|
27
|
-
Hey
|
9
|
+
Hey {PREFERRED_NAME}! it looks like you don't have a ENS domain yet! \n\Let me start by checking your Converse username with the .eth suffix\n/check {CONVERSE_USERNAME}.eth
|
28
10
|
|
29
11
|
2. If the user has a ENS domain
|
30
|
-
Hello
|
12
|
+
Hello {PREFERRED_NAME} ! I'll help you get your ENS domain.\n Let's start by checking your ENS domain {ENS_DOMAIN}. Give me a moment.\n/check {ENS_DOMAIN}
|
31
13
|
|
32
14
|
3. Check if the ENS domain is available
|
33
|
-
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain
|
15
|
+
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain {ENS_DOMAIN}. Give me a moment.\n/check {ENS_DOMAIN}
|
34
16
|
|
35
17
|
4. If the ENS domain is available,
|
36
|
-
Looks like
|
18
|
+
Looks like {ENS_DOMAIN} is available! Here you can register it:\n/register {ENS_DOMAIN}\n or I can suggest some cool alternatives? Le me know!
|
37
19
|
|
38
20
|
5. If the ENS domain is already registered, let me suggest 5 cool alternatives
|
39
|
-
Looks like
|
21
|
+
Looks like {ENS_DOMAIN} is already registered!\n What about these cool alternatives?\n/cool {ENS_DOMAIN}
|
40
22
|
|
41
23
|
6. If the user wants to register a ENS domain, use the command "/register [domain]"
|
42
|
-
Looks like
|
24
|
+
Looks like {ENS_DOMAIN} is available! Let me help you register it\n/register {ENS_DOMAIN}
|
43
25
|
|
44
26
|
7. If the user wants to directly to tip to the ENS domain owner, use directly the command "/tip [domain]", this will return a url but a button to send the tip
|
45
|
-
Here is the url to send the tip:\n/tip
|
27
|
+
Here is the url to send the tip:\n/tip {ENS_DOMAIN}
|
46
28
|
|
47
29
|
8. If the user wants to get information about the ENS domain, use the command "/info [domain]"
|
48
|
-
Hello! I'll help you get info about
|
30
|
+
Hello! I'll help you get info about {ENS_DOMAIN}.\n Give me a moment.\n/info {ENS_DOMAIN}
|
49
31
|
|
50
32
|
9. If the user wants to renew their domain, use the command "/renew [domain]"
|
51
|
-
Hello! I'll help you get your ENS domain.\n Let's start by checking your ENS domain
|
33
|
+
Hello! I'll help you get your ENS domain.\n Let's start by checking your ENS domain {ENS_DOMAIN}. Give me a moment.\n/renew {ENS_DOMAIN}
|
52
34
|
|
53
35
|
10. If the user wants cool suggestions about a domain, use the command "/cool [domain]"
|
54
|
-
Here are some cool suggestions for your domain.\n/cool
|
36
|
+
Here are some cool suggestions for your domain.\n/cool {ENS_DOMAIN}
|
55
37
|
|
56
38
|
## Most common bugs
|
57
39
|
|
@@ -59,5 +41,6 @@ export async function agent_prompt(userInfo: UserInfo) {
|
|
59
41
|
But you forgot to add the command at the end of the message.
|
60
42
|
You should have said something like: "Looks like vitalik.eth is registered! What about these cool alternatives?\n/cool vitalik.eth
|
61
43
|
`;
|
62
|
-
|
44
|
+
|
45
|
+
return defaultPromptTemplate(fineTunning, senderAddress, skills, "@ens");
|
63
46
|
}
|
@@ -8,7 +8,7 @@ export const skills: SkillGroup[] = [
|
|
8
8
|
description: "Register ENS domains.",
|
9
9
|
skills: [
|
10
10
|
{
|
11
|
-
|
11
|
+
skill: "/register [domain]",
|
12
12
|
triggers: ["/register"],
|
13
13
|
handler: handleEns,
|
14
14
|
description:
|
@@ -21,20 +21,7 @@ export const skills: SkillGroup[] = [
|
|
21
21
|
},
|
22
22
|
},
|
23
23
|
{
|
24
|
-
|
25
|
-
adminOnly: true,
|
26
|
-
examples: ["/exists"],
|
27
|
-
handler: handleEns,
|
28
|
-
triggers: ["/exists"],
|
29
|
-
description: "Check if an address is onboarded.",
|
30
|
-
params: {
|
31
|
-
address: {
|
32
|
-
type: "address",
|
33
|
-
},
|
34
|
-
},
|
35
|
-
},
|
36
|
-
{
|
37
|
-
command: "/info [domain]",
|
24
|
+
skill: "/info [domain]",
|
38
25
|
triggers: ["/info"],
|
39
26
|
handler: handleEns,
|
40
27
|
description:
|
@@ -47,7 +34,7 @@ export const skills: SkillGroup[] = [
|
|
47
34
|
},
|
48
35
|
},
|
49
36
|
{
|
50
|
-
|
37
|
+
skill: "/renew [domain]",
|
51
38
|
triggers: ["/renew"],
|
52
39
|
handler: handleEns,
|
53
40
|
description:
|
@@ -60,7 +47,7 @@ export const skills: SkillGroup[] = [
|
|
60
47
|
},
|
61
48
|
},
|
62
49
|
{
|
63
|
-
|
50
|
+
skill: "/check [domain]",
|
64
51
|
triggers: ["/check"],
|
65
52
|
handler: handleEns,
|
66
53
|
examples: ["/check vitalik.eth", "/check fabri.base.eth"],
|
@@ -72,7 +59,7 @@ export const skills: SkillGroup[] = [
|
|
72
59
|
},
|
73
60
|
},
|
74
61
|
{
|
75
|
-
|
62
|
+
skill: "/cool [domain]",
|
76
63
|
triggers: ["/cool"],
|
77
64
|
examples: ["/cool vitalik.eth"],
|
78
65
|
handler: handleEns,
|
@@ -84,7 +71,7 @@ export const skills: SkillGroup[] = [
|
|
84
71
|
},
|
85
72
|
},
|
86
73
|
{
|
87
|
-
|
74
|
+
skill: "/reset",
|
88
75
|
triggers: ["/reset"],
|
89
76
|
examples: ["/reset"],
|
90
77
|
handler: handleEns,
|
@@ -92,7 +79,7 @@ export const skills: SkillGroup[] = [
|
|
92
79
|
params: {},
|
93
80
|
},
|
94
81
|
{
|
95
|
-
|
82
|
+
skill: "/tip [address]",
|
96
83
|
description: "Show a URL for tipping a domain owner.",
|
97
84
|
triggers: ["/tip"],
|
98
85
|
handler: handleEns,
|
@@ -1 +1 @@
|
|
1
|
-
KEY= # the private key of the
|
1
|
+
KEY= # the private key of the agent wallet
|
@@ -1,9 +1,5 @@
|
|
1
1
|
import { run, HandlerContext } from "@xmtp/message-kit";
|
2
2
|
|
3
3
|
run(async (context: HandlerContext) => {
|
4
|
-
|
5
|
-
const { content, sender } = context.message;
|
6
|
-
|
7
|
-
// To reply, just call `reply` on the HandlerContext
|
8
|
-
await context.send(`gm`);
|
4
|
+
context.send("gm");
|
9
5
|
});
|
@@ -1,3 +1,2 @@
|
|
1
|
-
KEY= # the private key of the
|
2
|
-
OPEN_AI_API_KEY= # openai api key
|
3
|
-
STACK_API_KEY= # stack api key
|
1
|
+
KEY= # the private key of the agent wallet
|
2
|
+
OPEN_AI_API_KEY= # openai api key
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import { HandlerContext } from "@xmtp/message-kit";
|
2
2
|
|
3
|
-
// Handler function to process game-related
|
3
|
+
// Handler function to process game-related
|
4
4
|
export async function handler(context: HandlerContext) {
|
5
5
|
const {
|
6
6
|
message: {
|
7
|
-
content: {
|
7
|
+
content: { skill, params, text },
|
8
8
|
},
|
9
9
|
} = context;
|
10
|
-
if (!
|
11
|
-
const { content: text } = context?.message?.content;
|
10
|
+
if (!skill) {
|
12
11
|
if (text === "🔎" || text === "🔍") {
|
13
12
|
// Send the URL for the requested game
|
14
13
|
context.reply("https://framedl.xyz/");
|
@@ -36,7 +35,7 @@ export async function handler(context: HandlerContext) {
|
|
36
35
|
default:
|
37
36
|
// Inform the user about unrecognized skills and provide available options
|
38
37
|
context.send(
|
39
|
-
"
|
38
|
+
"Skill not recognized. Available games: wordle, slot, or help.",
|
40
39
|
);
|
41
40
|
}
|
42
41
|
}
|
@@ -3,22 +3,26 @@ import { HandlerContext } from "@xmtp/message-kit";
|
|
3
3
|
export async function handler(context: HandlerContext) {
|
4
4
|
const {
|
5
5
|
skills,
|
6
|
-
group,
|
7
6
|
message: {
|
8
|
-
content: {
|
7
|
+
content: { skill },
|
9
8
|
},
|
9
|
+
group,
|
10
10
|
} = context;
|
11
11
|
|
12
|
-
if (
|
12
|
+
if (skill == "help") {
|
13
13
|
const intro =
|
14
14
|
"Available experiences:\n" +
|
15
15
|
skills
|
16
16
|
?.flatMap((app) => app.skills)
|
17
|
-
.map((skill) => `${skill.
|
17
|
+
.map((skill) => `${skill.skill} - ${skill.description}`)
|
18
18
|
.join("\n") +
|
19
19
|
"\nUse these skills to interact with specific apps.";
|
20
20
|
context.send(intro);
|
21
|
-
} else if (
|
22
|
-
|
21
|
+
} else if (skill == "id") {
|
22
|
+
if (!group?.id) {
|
23
|
+
context.send("This skill only works in group chats.");
|
24
|
+
return;
|
25
|
+
}
|
26
|
+
context.send(group?.id);
|
23
27
|
}
|
24
28
|
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { getUserInfo, HandlerContext } from "@xmtp/message-kit";
|
2
|
+
|
3
|
+
export async function handler(context: HandlerContext) {
|
4
|
+
const {
|
5
|
+
message: {
|
6
|
+
content: { skill, params },
|
7
|
+
},
|
8
|
+
} = context;
|
9
|
+
const baseUrl = "https://txpay.vercel.app";
|
10
|
+
|
11
|
+
if (skill === "pay") {
|
12
|
+
const { amount: amountSend, token: tokenSend, username } = params;
|
13
|
+
console.log("username", username);
|
14
|
+
let senderInfo = await getUserInfo(username);
|
15
|
+
if (!amountSend || !tokenSend || !senderInfo) {
|
16
|
+
context.reply(
|
17
|
+
"Missing required parameters. Please provide amount, token, and username.",
|
18
|
+
);
|
19
|
+
return {
|
20
|
+
code: 400,
|
21
|
+
message:
|
22
|
+
"Missing required parameters. Please provide amount, token, and username.",
|
23
|
+
};
|
24
|
+
}
|
25
|
+
|
26
|
+
let sendUrl = `${baseUrl}/?&amount=${amountSend}&token=${tokenSend}&receiver=${senderInfo.address}`;
|
27
|
+
await context.send(`${sendUrl}`);
|
28
|
+
}
|
29
|
+
}
|
@@ -1,49 +1,31 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
HandlerContext,
|
3
|
+
AbstractedMember,
|
4
|
+
SkillResponse,
|
5
|
+
} from "@xmtp/message-kit";
|
2
6
|
import { getUserInfo } from "@xmtp/message-kit";
|
3
7
|
|
4
8
|
export async function handler(context: HandlerContext) {
|
5
9
|
const {
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
message: {
|
11
|
+
content: {
|
12
|
+
skill,
|
13
|
+
params: { amount, username },
|
14
|
+
},
|
15
|
+
sender,
|
16
|
+
},
|
9
17
|
} = context;
|
10
|
-
|
11
|
-
const replyReceiver = members?.find(
|
12
|
-
(member) => member.inboxId === msg?.senderInboxId,
|
13
|
-
);
|
14
|
-
let amount: number = 0,
|
15
|
-
receivers: AbstractedMember[] = [];
|
16
|
-
// Handle different types of messages
|
17
|
-
if (typeId === "reply" && replyReceiver) {
|
18
|
-
const { content: reply } = content;
|
19
|
-
|
20
|
-
if (reply.includes("degen")) {
|
21
|
-
receivers = [replyReceiver];
|
22
|
-
const match = reply.match(/(\d+)/);
|
23
|
-
if (match)
|
24
|
-
amount = parseInt(match[0]); // Extract amount from reply
|
25
|
-
else amount = 10;
|
26
|
-
}
|
27
|
-
} else if (typeId === "text") {
|
28
|
-
const { content: text, params } = content;
|
29
|
-
if (text.startsWith("/tip") && params) {
|
30
|
-
// Process text skills starting with "/tip"
|
31
|
-
const {
|
32
|
-
params: { amount: extractedAmount, username },
|
33
|
-
} = content;
|
34
|
-
amount = extractedAmount || 10; // Default amount if not specified
|
18
|
+
let receivers: AbstractedMember[] = [];
|
35
19
|
|
36
|
-
|
37
|
-
|
38
|
-
)
|
39
|
-
|
20
|
+
if (skill === "tip") {
|
21
|
+
receivers = await Promise.all(
|
22
|
+
username.map((username: string) => getUserInfo(username)),
|
23
|
+
);
|
40
24
|
}
|
41
25
|
if (!sender || receivers.length === 0 || amount === 0) {
|
42
26
|
context.reply("Sender or receiver or amount not found.");
|
43
|
-
return;
|
44
27
|
}
|
45
28
|
const receiverAddresses = receivers.map((receiver) => receiver.address);
|
46
|
-
// Process sending tokens to each receiver
|
47
29
|
|
48
30
|
context.sendTo(
|
49
31
|
`You received ${amount} tokens from ${sender.address}.`,
|