create-message-kit 1.1.10 → 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
package/index.js CHANGED
@@ -71,7 +71,10 @@ async function updatePackagejson(destDir, templateType) {
71
71
 
72
72
  packageTemplate.dependencies["@xmtp/message-kit"] = "latest";
73
73
  //Add for yarn in general
74
- packageTemplate.packageManager = `yarn@4.5.1`;
74
+ packageTemplate.scripts.postinstall = "tsc";
75
+ if (packageTemplate?.packageManager?.startsWith("yarn")) {
76
+ packageTemplate.packageManager = "yarn@4.5.1";
77
+ }
75
78
 
76
79
  fs.writeJsonSync(resolve(destDir, "package.json"), packageTemplate, {
77
80
  spaces: 2,
@@ -80,8 +83,8 @@ async function updatePackagejson(destDir, templateType) {
80
83
 
81
84
  async function gatherProjectInfo() {
82
85
  const templateOptions = [
86
+ { value: "agent", label: "Web3 Agent" },
83
87
  { value: "gpt", label: "Simple Gpt" },
84
- { value: "agent", label: "ENS Agent" },
85
88
  { value: "group", label: "Group bot" },
86
89
  { value: "gated", label: "Gated Group" },
87
90
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-message-kit",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,2 +1,2 @@
1
1
  KEY= # the private key of the wallet
2
- OPEN_AI_API_KEY= # sk-proj-...
2
+ OPENAI_API_KEY= # sk-proj-...
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc",
7
- "dev": "tsc -w & sleep 1 && node --watch dist/index.js",
7
+ "dev": "tsc -w & sleep 1 && NODE_NO_WARNINGS=1 node --watch dist/index.js",
8
8
  "start": "node dist/index.js"
9
9
  },
10
10
  "dependencies": {
@@ -1,12 +1,12 @@
1
1
  import { ensUrl } from "../index.js";
2
2
  import { XMTPContext, getUserInfo } from "@xmtp/message-kit";
3
+ import type { Skill } from "@xmtp/message-kit";
3
4
 
4
- import type { skillAction } from "@xmtp/message-kit";
5
-
6
- export const registerSkill: skillAction[] = [
5
+ // [!region define]
6
+ export const registerSkill: Skill[] = [
7
7
  {
8
8
  skill: "/check [domain]",
9
- handler: handleCheck,
9
+ handler: handler,
10
10
  examples: ["/check vitalik.eth", "/check fabri.base.eth"],
11
11
  description: "Check if a domain is available.",
12
12
  params: {
@@ -16,7 +16,10 @@ export const registerSkill: skillAction[] = [
16
16
  },
17
17
  },
18
18
  ];
19
- export async function handleCheck(context: XMTPContext) {
19
+ // [!endregion define]
20
+
21
+ // [!region handle]
22
+ export async function handler(context: XMTPContext) {
20
23
  const {
21
24
  message: {
22
25
  content: {
@@ -26,6 +29,7 @@ export async function handleCheck(context: XMTPContext) {
26
29
  } = context;
27
30
 
28
31
  const data = await getUserInfo(domain);
32
+
29
33
  if (!data?.address) {
30
34
  let message = `Looks like ${domain} is available! Here you can register it: ${ensUrl}${domain} or would you like to see some cool alternatives?`;
31
35
  return {
@@ -41,3 +45,4 @@ export async function handleCheck(context: XMTPContext) {
41
45
  };
42
46
  }
43
47
  }
48
+ // [!endregion handle]
@@ -1,12 +1,12 @@
1
1
  import { XMTPContext } from "@xmtp/message-kit";
2
2
 
3
- import type { skillAction } from "@xmtp/message-kit";
3
+ import type { Skill } from "@xmtp/message-kit";
4
4
 
5
- export const registerSkill: skillAction[] = [
5
+ export const registerSkill: Skill[] = [
6
6
  {
7
7
  skill: "/cool [domain]",
8
8
  examples: ["/cool vitalik.eth"],
9
- handler: handleCool,
9
+ handler: handler,
10
10
  description: "Get cool alternatives for a .eth domain.",
11
11
  params: {
12
12
  domain: {
@@ -15,7 +15,7 @@ export const registerSkill: skillAction[] = [
15
15
  },
16
16
  },
17
17
  ];
18
- export async function handleCool(context: XMTPContext) {
18
+ export async function handler(context: XMTPContext) {
19
19
  const {
20
20
  message: {
21
21
  content: {
@@ -0,0 +1,57 @@
1
+ import { XMTPContext } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
+
4
+ export const registerSkill: 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
+ // Respond with the appropriate game URL or an error message
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
+ context.send(gameUrl);
46
+ break;
47
+
48
+ case "help":
49
+ context.send("Available games: \n/game wordle\n/game slot");
50
+ break;
51
+ default:
52
+ // Inform the user about unrecognized skills and provide available options
53
+ context.send(
54
+ "Skill not recognized. Available games: wordle, slot, or help.",
55
+ );
56
+ }
57
+ }
@@ -1,12 +1,12 @@
1
1
  import { ensUrl } from "../index.js";
2
2
  import { XMTPContext, getUserInfo, isOnXMTP } from "@xmtp/message-kit";
3
3
 
4
- import type { skillAction } from "@xmtp/message-kit";
4
+ import type { Skill } from "@xmtp/message-kit";
5
5
 
6
- export const registerSkill: skillAction[] = [
6
+ export const registerSkill: Skill[] = [
7
7
  {
8
8
  skill: "/info [domain]",
9
- handler: handleInfo,
9
+ handler: handler,
10
10
  description:
11
11
  "Get detailed information about an ENS domain including owner, expiry date, and resolver.",
12
12
  examples: ["/info nick.eth"],
@@ -18,7 +18,7 @@ export const registerSkill: skillAction[] = [
18
18
  },
19
19
  ];
20
20
 
21
- export async function handleInfo(context: XMTPContext) {
21
+ export async function handler(context: XMTPContext) {
22
22
  const {
23
23
  message: {
24
24
  sender,
@@ -35,31 +35,22 @@ export async function handleInfo(context: XMTPContext) {
35
35
  message: "Domain not found.",
36
36
  };
37
37
  }
38
-
39
- const formattedData = {
40
- Address: data?.address,
41
- "Avatar URL": data?.ensInfo?.avatar,
42
- Description: data?.ensInfo?.description,
43
- ENS: data?.ensDomain,
44
- "Primary ENS": data?.ensInfo?.ens_primary,
45
- GitHub: data?.ensInfo?.github,
46
- Resolver: data?.ensInfo?.resolverAddress,
47
- Twitter: data?.ensInfo?.twitter,
48
- URL: `${ensUrl}${domain}`,
49
- };
50
-
51
- let message = "Domain information:\n\n";
52
- for (const [key, value] of Object.entries(formattedData)) {
53
- if (value) {
54
- message += `${key}: ${value}\n`;
55
- }
56
- }
38
+ let message = `Domain information:\n\n`;
39
+ message += `Address: ${data?.address}\n`;
40
+ message += `Avatar URL: ${data?.ensInfo?.avatar}\n`;
41
+ message += `Description: ${data?.ensInfo?.description}\n`;
42
+ message += `ENS: ${data?.ensDomain}\n`;
43
+ message += `Primary ENS: ${data?.ensInfo?.ens_primary}\n`;
44
+ message += `GitHub: ${data?.ensInfo?.github}\n`;
57
45
  message += `\n\nWould you like to tip the domain owner for getting there first 🤣?`;
58
46
  message = message.trim();
47
+
59
48
  if (await isOnXMTP(context.client, context.v2client, sender?.address)) {
60
49
  await context.send(
61
- `Ah, this domains is in XMTP, you can message it directly: https://converse.xyz/dm/${domain}`,
50
+ `Ah, this domains is in XMTP, you can message it directly`,
62
51
  );
52
+ await context.sendConverseDmFrame(domain);
63
53
  }
54
+
64
55
  return { code: 200, message };
65
56
  }
@@ -0,0 +1,38 @@
1
+ import { XMTPContext } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
+
4
+ export const registerSkill: Skill[] = [
5
+ {
6
+ skill: "/pay [amount] [token] [username]",
7
+ examples: ["/pay 10 vitalik.eth"],
8
+ description:
9
+ "Send a specified amount of a cryptocurrency to a destination address.",
10
+ handler: handler,
11
+ params: {
12
+ amount: {
13
+ default: 10,
14
+ type: "number",
15
+ },
16
+ token: {
17
+ default: "usdc",
18
+ type: "string",
19
+ values: ["eth", "dai", "usdc", "degen"], // Accepted tokens
20
+ },
21
+ username: {
22
+ default: "",
23
+ type: "username",
24
+ },
25
+ },
26
+ },
27
+ ];
28
+ export async function handler(context: XMTPContext) {
29
+ const {
30
+ message: {
31
+ content: {
32
+ params: { address },
33
+ },
34
+ },
35
+ } = context;
36
+
37
+ await context.requestPayment(1, "USDC", address);
38
+ }
@@ -1,12 +1,12 @@
1
1
  import { ensUrl } from "../index.js";
2
2
  import { XMTPContext } from "@xmtp/message-kit";
3
3
 
4
- import type { skillAction } from "@xmtp/message-kit";
4
+ import type { Skill } from "@xmtp/message-kit";
5
5
 
6
- export const registerSkill: skillAction[] = [
6
+ export const registerSkill: Skill[] = [
7
7
  {
8
8
  skill: "/register [domain]",
9
- handler: handleRegister,
9
+ handler: handler,
10
10
  description:
11
11
  "Register a new ENS domain. Returns a URL to complete the registration process.",
12
12
  examples: ["/register vitalik.eth"],
@@ -18,7 +18,7 @@ export const registerSkill: skillAction[] = [
18
18
  },
19
19
  ];
20
20
 
21
- export async function handleRegister(context: XMTPContext) {
21
+ export async function handler(context: XMTPContext) {
22
22
  const {
23
23
  message: {
24
24
  content: {
@@ -1,12 +1,12 @@
1
1
  import { frameUrl } from "../index.js";
2
2
  import { getUserInfo, XMTPContext } from "@xmtp/message-kit";
3
3
 
4
- import type { skillAction } from "@xmtp/message-kit";
4
+ import type { Skill } from "@xmtp/message-kit";
5
5
 
6
- export const registerSkill: skillAction[] = [
6
+ export const registerSkill: Skill[] = [
7
7
  {
8
8
  skill: "/renew [domain]",
9
- handler: handleRenew,
9
+ handler: handler,
10
10
  description:
11
11
  "Extend the registration period of your ENS domain. Returns a URL to complete the renewal.",
12
12
  examples: ["/renew fabri.base.eth"],
@@ -18,7 +18,7 @@ export const registerSkill: skillAction[] = [
18
18
  },
19
19
  ];
20
20
 
21
- export async function handleRenew(context: XMTPContext) {
21
+ export async function handler(context: XMTPContext) {
22
22
  const {
23
23
  message: {
24
24
  sender,
@@ -1,18 +1,18 @@
1
1
  import { clearInfoCache, clearMemory } from "@xmtp/message-kit";
2
2
  import { XMTPContext } from "@xmtp/message-kit";
3
3
 
4
- import type { skillAction } from "@xmtp/message-kit";
4
+ import type { Skill } from "@xmtp/message-kit";
5
5
 
6
- export const registerSkill: skillAction[] = [
6
+ export const registerSkill: Skill[] = [
7
7
  {
8
8
  skill: "/reset",
9
9
  examples: ["/reset"],
10
- handler: handleReset,
10
+ handler: handler,
11
11
  description: "Reset the conversation.",
12
12
  params: {},
13
13
  },
14
14
  ];
15
- export async function handleReset(context: XMTPContext) {
15
+ export async function handler(context: XMTPContext) {
16
16
  clearMemory();
17
17
  clearInfoCache();
18
18
  return { code: 200, message: "Conversation reset." };
@@ -0,0 +1,57 @@
1
+ import { XMTPContext } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
+
4
+ export const registerSkill: Skill[] = [
5
+ {
6
+ skill: "/token [symbol]",
7
+ handler: handler,
8
+ examples: ["/token bitcoin", "/token ethereum"],
9
+ description: "Get real time price of a any token.",
10
+ params: {
11
+ symbol: {
12
+ type: "string",
13
+ },
14
+ },
15
+ },
16
+ ];
17
+ export async function handler(context: XMTPContext) {
18
+ const {
19
+ message: {
20
+ content: {
21
+ params: { symbol },
22
+ },
23
+ },
24
+ } = context;
25
+ const response = await fetch(
26
+ `https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${symbol}`,
27
+ );
28
+ if (!response.ok) {
29
+ context.send("Token not found");
30
+ context.send("try with its full name, instead of btc it would be bitcoin");
31
+ return;
32
+ }
33
+ const data = (await response.json()) as any;
34
+ const token = data[0];
35
+
36
+ const tokenInfo = {
37
+ name: token.name,
38
+ symbol: token.symbol.toUpperCase(),
39
+ price: token.current_price,
40
+ image: token.image,
41
+ link: `https://www.coingecko.com/en/coins/${token.id}`,
42
+ };
43
+
44
+ let frame = {
45
+ title: tokenInfo.name,
46
+ buttons: [
47
+ { content: "Buy", action: "link", target: tokenInfo.link },
48
+ {
49
+ content: `Price (${tokenInfo.price})`,
50
+ action: "link",
51
+ target: tokenInfo.link,
52
+ },
53
+ ],
54
+ image: tokenInfo.image,
55
+ };
56
+ await context.sendCustomFrame(frame);
57
+ }
@@ -3,6 +3,7 @@ import {
3
3
  agentReply,
4
4
  replaceVariables,
5
5
  XMTPContext,
6
+ Agent,
6
7
  } from "@xmtp/message-kit";
7
8
  import { systemPrompt } from "./prompt.js";
8
9
  import { registerSkill as checkSkill } from "./handlers/check.js";
@@ -10,46 +11,49 @@ import { registerSkill as coolSkill } from "./handlers/cool.js";
10
11
  import { registerSkill as infoSkill } from "./handlers/info.js";
11
12
  import { registerSkill as registerSkill } from "./handlers/register.js";
12
13
  import { registerSkill as renewSkill } from "./handlers/renew.js";
14
+ import { registerSkill as paySkill } from "./handlers/pay.js";
13
15
  import { registerSkill as resetSkill } from "./handlers/reset.js";
14
- import { registerSkill as tipSkill } from "./handlers/tip.js";
16
+ import { registerSkill as tokenSkill } from "./handlers/token.js";
17
+ import { registerSkill as gameSkill } from "./handlers/game.js";
15
18
  import fs from "fs";
16
19
 
17
20
  export const frameUrl = "https://ens.steer.fun/";
18
21
  export const ensUrl = "https://app.ens.domains/";
19
22
  export const txpayUrl = "https://txpay.vercel.app";
20
23
 
21
- export const skills = [
22
- {
23
- name: "Ens Domain Bot",
24
- tag: "@ens",
25
- description: "Register ENS domains.",
26
- skills: [
27
- ...checkSkill,
28
- ...coolSkill,
29
- ...infoSkill,
30
- ...registerSkill,
31
- ...renewSkill,
32
- ...resetSkill,
33
- ...tipSkill,
34
- ],
35
- },
36
- ];
24
+ // [!region skills]
25
+ export const agent: Agent = {
26
+ name: "Web3 Agent",
27
+ tag: "@bot",
28
+ description: "A web3 agent with a lot of skills.",
29
+ skills: [
30
+ ...checkSkill,
31
+ ...coolSkill,
32
+ ...infoSkill,
33
+ ...registerSkill,
34
+ ...renewSkill,
35
+ ...resetSkill,
36
+ ...paySkill,
37
+ ...tokenSkill,
38
+ ...gameSkill,
39
+ ],
40
+ };
41
+ // [!endregion skills]
37
42
 
43
+ // [!region run]
38
44
  run(
39
45
  async (context: XMTPContext) => {
40
46
  const {
41
47
  message: { sender },
42
- skills,
48
+ agent,
43
49
  } = context;
44
50
 
45
- let prompt = await replaceVariables(
46
- systemPrompt,
47
- sender.address,
48
- skills,
49
- "@ens",
50
- );
51
+ let prompt = await replaceVariables(systemPrompt, sender.address, agent);
52
+
51
53
  fs.writeFileSync("example_prompt.md", prompt);
52
54
  await agentReply(context, prompt);
53
55
  },
54
- { skills },
56
+ { agent },
55
57
  );
58
+
59
+ // [!endregion run]
@@ -1,5 +1,5 @@
1
1
  export const systemPrompt = `
2
- Your are helpful and playful agent called {agent_name} that lives inside a web3 messaging app called Converse.
2
+ Your are helpful and playful web3 agent called {agent_name} that lives inside a messaging app called Converse.
3
3
 
4
4
  {rules}
5
5
 
@@ -34,7 +34,7 @@ Your are helpful and playful agent called {agent_name} that lives inside a web3
34
34
  /register [domain]
35
35
  7. If the user wants to directly tip the ENS domain owner:
36
36
  Here is the URL to send the tip:
37
- /tip [address]
37
+ /pay 1 usdc [address]
38
38
  8. If the user wants to get information about the ENS domain:
39
39
  Hello! I'll help you get info about [domain].
40
40
  Give me a moment.
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc",
7
- "dev": "tsc -w & sleep 1 && node --watch dist/index.js",
7
+ "dev": "tsc -w & sleep 1 && NODE_NO_WARNINGS=1 node --watch dist/index.js",
8
8
  "start": "node dist/index.js"
9
9
  },
10
10
  "dependencies": {
@@ -1,24 +1,22 @@
1
- import type { SkillGroup } from "@xmtp/message-kit";
1
+ import type { Agent } from "@xmtp/message-kit";
2
2
 
3
- export const skills: SkillGroup[] = [
4
- {
5
- name: "Group Id",
6
- description: "Create and get group id.",
7
- skills: [
8
- {
9
- skill: "/create",
10
- examples: ["/create"],
11
- adminOnly: true,
12
- params: {},
13
- description: "Create a new group.",
14
- },
15
- {
16
- skill: "/id",
17
- examples: ["/id"],
18
- adminOnly: true,
19
- params: {},
20
- description: "Get group id.",
21
- },
22
- ],
23
- },
24
- ];
3
+ export const agent: Agent = {
4
+ name: "Group Id",
5
+ description: "Create and get group id.",
6
+ skills: [
7
+ {
8
+ skill: "/create",
9
+ examples: ["/create"],
10
+ adminOnly: true,
11
+ params: {},
12
+ description: "Create a new group.",
13
+ },
14
+ {
15
+ skill: "/id",
16
+ examples: ["/id"],
17
+ adminOnly: true,
18
+ params: {},
19
+ description: "Get group id.",
20
+ },
21
+ ],
22
+ };
@@ -1,2 +1,2 @@
1
1
  KEY= # the private key of the agent wallet
2
- OPEN_AI_API_KEY= # the API key for OpenAI
2
+ OPENAI_API_KEY= # the API key for OpenAI
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc",
7
- "dev": "tsc -w & sleep 1 && node --watch dist/index.js",
7
+ "dev": "tsc -w & sleep 1 && NODE_NO_WARNINGS=1 node --watch dist/index.js",
8
8
  "start": "node dist/index.js"
9
9
  },
10
10
  "dependencies": {
@@ -3,15 +3,22 @@ import {
3
3
  agentReply,
4
4
  replaceVariables,
5
5
  XMTPContext,
6
+ Agent,
6
7
  } from "@xmtp/message-kit";
7
8
 
8
9
  import { systemPrompt } from "./prompt.js";
10
+ export const agent: Agent = {
11
+ name: "GPT Bot",
12
+ tag: "@bot",
13
+ description: "Use GPT to answer questions.",
14
+ skills: [],
15
+ };
9
16
 
10
17
  run(async (context: XMTPContext) => {
11
18
  const {
12
19
  message: { sender },
13
20
  } = context;
14
21
 
15
- let prompt = await replaceVariables(systemPrompt, sender.address, [], "@bot");
22
+ let prompt = await replaceVariables(systemPrompt, sender.address, skills);
16
23
  await agentReply(context, prompt);
17
24
  });
@@ -3,8 +3,5 @@ You are a helpful and playful agent called {agent_name} that lives inside a web3
3
3
 
4
4
  {rules}
5
5
 
6
- {skills}
7
-
8
6
  {user_context}
9
-
10
7
  `;
@@ -1,2 +1,2 @@
1
1
  KEY= # the private key of the agent wallet
2
- OPEN_AI_API_KEY= # openai api key
2
+ OPENAI_API_KEY= # openai api key
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc",
7
- "dev": "tsc -w & sleep 1 && node --watch dist/index.js",
7
+ "dev": "tsc -w & sleep 1 && NODE_NO_WARNINGS=1 node --watch dist/index.js",
8
8
  "start": "node dist/index.js"
9
9
  },
10
10
  "dependencies": {
@@ -1,10 +1,10 @@
1
1
  import { XMTPContext } from "@xmtp/message-kit";
2
- import type { skillAction } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
3
 
4
- export const registerSkill: skillAction[] = [
4
+ export const registerSkill: Skill[] = [
5
5
  {
6
6
  skill: "/game [game]",
7
- handler: handleGames,
7
+ handler: handler,
8
8
  description: "Play a game.",
9
9
  examples: ["/game wordle", "/game slot", "/game help"],
10
10
  params: {
@@ -17,7 +17,7 @@ export const registerSkill: skillAction[] = [
17
17
  },
18
18
  ];
19
19
 
20
- export async function handleGames(context: XMTPContext) {
20
+ export async function handler(context: XMTPContext) {
21
21
  const {
22
22
  message: {
23
23
  content: { skill, params, text },
@@ -1,8 +1,8 @@
1
1
  import { XMTPContext } from "@xmtp/message-kit";
2
2
 
3
- import type { skillAction } from "@xmtp/message-kit";
3
+ import type { Skill } from "@xmtp/message-kit";
4
4
 
5
- export const registerSkill: skillAction[] = [
5
+ export const registerSkill: Skill[] = [
6
6
  {
7
7
  skill: "/help",
8
8
  examples: ["/help"],
@@ -25,14 +25,13 @@ export async function handleHelp(context: XMTPContext) {
25
25
  content: { skill },
26
26
  },
27
27
  group,
28
- skills,
28
+ agent,
29
29
  } = context;
30
30
 
31
31
  if (skill == "help") {
32
32
  const intro =
33
33
  "Available experiences:\n" +
34
- skills
35
- ?.flatMap((app) => app.skills)
34
+ agent?.skills
36
35
  .map((skill) => `${skill.skill} - ${skill.description}`)
37
36
  .join("\n") +
38
37
  "\nUse these skills to interact with specific apps.";
@@ -0,0 +1,38 @@
1
+ import { XMTPContext } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
+
4
+ export const registerSkill: Skill[] = [
5
+ {
6
+ skill: "/pay [amount] [token] [username]",
7
+ examples: ["/pay 10 vitalik.eth"],
8
+ description:
9
+ "Send a specified amount of a cryptocurrency to a destination address.",
10
+ handler: handler,
11
+ params: {
12
+ amount: {
13
+ default: 10,
14
+ type: "number",
15
+ },
16
+ token: {
17
+ default: "usdc",
18
+ type: "string",
19
+ values: ["eth", "dai", "usdc", "degen"], // Accepted tokens
20
+ },
21
+ username: {
22
+ default: "",
23
+ type: "username",
24
+ },
25
+ },
26
+ },
27
+ ];
28
+ export async function handler(context: XMTPContext) {
29
+ const {
30
+ message: {
31
+ content: {
32
+ params: { address },
33
+ },
34
+ },
35
+ } = context;
36
+
37
+ await context.requestPayment(1, "USDC", address);
38
+ }
@@ -1,7 +1,7 @@
1
1
  import { getUserInfo, AbstractedMember, XMTPContext } from "@xmtp/message-kit";
2
- import type { skillAction } from "@xmtp/message-kit";
2
+ import type { Skill } from "@xmtp/message-kit";
3
3
 
4
- export const registerSkill: skillAction[] = [
4
+ export const registerSkill: Skill[] = [
5
5
  {
6
6
  skill: "/tip [usernames] [amount] [token]",
7
7
  examples: ["/tip @vitalik 10 usdc"],
@@ -3,36 +3,30 @@ import {
3
3
  agentReply,
4
4
  XMTPContext,
5
5
  replaceVariables,
6
+ Agent,
6
7
  } from "@xmtp/message-kit";
7
8
  import { registerSkill as tippingSkill } from "./handlers/tipping.js";
8
- import { registerSkill as paymentSkill } from "./handlers/payment.js";
9
+ import { registerSkill as paymentSkill } from "./handlers/pay.js";
9
10
  import { registerSkill as gameSkill } from "./handlers/game.js";
10
11
  import { registerSkill as helperSkill } from "./handlers/helpers.js";
11
12
  import { systemPrompt } from "./prompt.js";
12
13
 
13
- export const skills = [
14
- {
15
- name: "Group bot",
16
- tag: "@bot",
17
- description: "Group agent for tipping payments, games and more.",
18
- skills: [...tippingSkill, ...paymentSkill, ...gameSkill, ...helperSkill],
19
- },
20
- ];
14
+ export const agent: Agent = {
15
+ name: "Group bot",
16
+ tag: "@bot",
17
+ description: "Group agent for tipping payments, games and more.",
18
+ skills: [...tippingSkill, ...paymentSkill, ...gameSkill, ...helperSkill],
19
+ };
21
20
 
22
21
  run(
23
22
  async (context: XMTPContext) => {
24
23
  const {
25
24
  message: { sender },
26
- skills,
25
+ agent,
27
26
  } = context;
28
27
 
29
- let prompt = await replaceVariables(
30
- systemPrompt,
31
- sender.address,
32
- skills,
33
- "@bot",
34
- );
28
+ let prompt = await replaceVariables(systemPrompt, sender.address, agent);
35
29
  await agentReply(context, prompt);
36
30
  },
37
- { skills },
31
+ { agent },
38
32
  );
@@ -1,42 +0,0 @@
1
- import { txpayUrl } from "../index.js";
2
- import { XMTPContext, getUserInfo } from "@xmtp/message-kit";
3
-
4
- import type { skillAction } from "@xmtp/message-kit";
5
-
6
- export const registerSkill: skillAction[] = [
7
- {
8
- skill: "/tip [address]",
9
- description: "Show a URL for tipping a domain owner.",
10
- handler: handleTip,
11
- examples: ["/tip 0x1234567890123456789012345678901234567890"],
12
- params: {
13
- address: {
14
- type: "string",
15
- },
16
- },
17
- },
18
- ];
19
- export async function handleTip(context: XMTPContext) {
20
- const {
21
- message: {
22
- content: {
23
- params: { address },
24
- },
25
- },
26
- } = context;
27
-
28
- if (!address) {
29
- return {
30
- code: 400,
31
- message: "Please provide an address to tip.",
32
- };
33
- }
34
- const data = await getUserInfo(address);
35
-
36
- let sendUrl = `${txpayUrl}/?&amount=1&token=USDC&receiver=${address}`;
37
-
38
- return {
39
- code: 200,
40
- message: sendUrl,
41
- };
42
- }
@@ -1,51 +0,0 @@
1
- import { getUserInfo, XMTPContext } from "@xmtp/message-kit";
2
- import type { skillAction } from "@xmtp/message-kit";
3
- export const registerSkill: skillAction[] = [
4
- {
5
- skill: "/pay [amount] [token] [username]",
6
- examples: ["/pay 10 usdc vitalik.eth", "/pay 1 @alix"],
7
- description:
8
- "Send a specified amount of a cryptocurrency to a destination address.",
9
- handler: handlePay,
10
- params: {
11
- amount: {
12
- default: 10,
13
- type: "number",
14
- },
15
- token: {
16
- default: "usdc",
17
- type: "string",
18
- values: ["eth", "dai", "usdc", "degen"], // Accepted tokens
19
- },
20
- username: {
21
- default: "",
22
- type: "username",
23
- },
24
- },
25
- },
26
- ];
27
-
28
- export async function handlePay(context: XMTPContext) {
29
- const {
30
- message: {
31
- content: { params },
32
- },
33
- } = context;
34
- const txpayUrl = "https://txpay.vercel.app";
35
-
36
- const { amount: amountSend, token: tokenSend, username } = params;
37
- let senderInfo = await getUserInfo(username);
38
- if (!amountSend || !tokenSend || !senderInfo) {
39
- context.reply(
40
- "Missing required parameters. Please provide amount, token, and username.",
41
- );
42
- return {
43
- code: 400,
44
- message:
45
- "Missing required parameters. Please provide amount, token, and username.",
46
- };
47
- }
48
-
49
- let sendUrl = `${txpayUrl}/?&amount=${amountSend}&token=${tokenSend}&receiver=${senderInfo.address}`;
50
- await context.send(`${sendUrl}`);
51
- }