create-message-kit 1.2.3 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/index.js +40 -27
  2. package/package.json +1 -1
  3. package/templates/agent/.cursorrules +227 -0
  4. package/templates/agent/src/index.ts +19 -26
  5. package/templates/agent/src/prompt.ts +1 -1
  6. package/templates/agent/src/{handlers → skills}/check.ts +5 -4
  7. package/templates/agent/src/{handlers → skills}/cool.ts +1 -1
  8. package/templates/agent/src/{handlers → skills}/game.ts +1 -1
  9. package/templates/agent/src/{handlers → skills}/info.ts +6 -5
  10. package/templates/agent/src/{handlers → skills}/pay.ts +20 -5
  11. package/templates/agent/src/{handlers → skills}/register.ts +2 -3
  12. package/templates/agent/src/{handlers → skills}/renew.ts +5 -4
  13. package/templates/agent/src/skills/reset.ts +26 -0
  14. package/templates/experimental/.cursorrules +227 -0
  15. package/templates/experimental/.env.example +2 -0
  16. package/templates/{gated → experimental}/package.json +5 -4
  17. package/templates/experimental/src/index.ts +41 -0
  18. package/templates/{gated/src/lib/nft.ts → experimental/src/lib/alchemy.ts} +4 -10
  19. package/templates/experimental/src/lib/xmtp.ts +138 -0
  20. package/templates/experimental/src/prompt.ts +24 -0
  21. package/templates/experimental/src/skills/broadcast.ts +38 -0
  22. package/templates/experimental/src/skills/gated.ts +100 -0
  23. package/templates/{agent/src/handlers → experimental/src/skills}/todo.ts +12 -8
  24. package/templates/{agent/src/handlers → experimental/src/skills}/token.ts +1 -1
  25. package/templates/gpt/.cursorrules +227 -0
  26. package/templates/gpt/src/index.ts +1 -0
  27. package/templates/agent/src/handlers/reset.ts +0 -19
  28. package/templates/gated/.env.example +0 -3
  29. package/templates/gated/src/index.ts +0 -64
  30. package/templates/gated/src/lib/gated.ts +0 -51
  31. package/templates/gated/src/skills.ts +0 -23
  32. /package/templates/{gated → experimental}/.yarnrc.yml +0 -0
@@ -0,0 +1,227 @@
1
+ # MessageKit Skill Template
2
+
3
+ ## Examples
4
+
5
+ ### Check if a Domain is Available
6
+
7
+ ```typescript
8
+ import { ensUrl } from "../index.js";
9
+ import { XMTPContext } from "@xmtp/message-kit";
10
+ import type { Skill } from "@xmtp/message-kit";
11
+
12
+ // Define Skill
13
+ export const checkDomain: Skill[] = [
14
+ {
15
+ skill: "/check [domain]",
16
+ handler: handler,
17
+ examples: ["/check vitalik.eth", "/check fabri.base.eth"],
18
+ description: "Check if a domain is available.",
19
+ params: {
20
+ domain: {
21
+ type: "string",
22
+ },
23
+ },
24
+ },
25
+ ];
26
+
27
+ // Handler Implementation
28
+ export async function handler(context: XMTPContext) {
29
+ const {
30
+ message: {
31
+ content: {
32
+ params: { domain },
33
+ },
34
+ },
35
+ } = context;
36
+
37
+ const data = await context.getUserInfo(domain);
38
+
39
+ if (!data?.address) {
40
+ let message = `Looks like ${domain} is available! Here you can register it: ${ensUrl}${domain} or would you like to see some cool alternatives?`;
41
+ return {
42
+ code: 200,
43
+ message,
44
+ };
45
+ } else {
46
+ let message = `Looks like ${domain} is already registered!`;
47
+ await context.executeSkill("/cool " + domain);
48
+ return {
49
+ code: 404,
50
+ message,
51
+ };
52
+ }
53
+ }
54
+
55
+ ### Generate a payment request
56
+
57
+ ```typescript
58
+ import { XMTPContext } from "@xmtp/message-kit";
59
+ import type { Skill } from "@xmtp/message-kit";
60
+
61
+ // Define Skill
62
+ export const paymentRequest: Skill[] = [
63
+ {
64
+ skill: "/pay [amount] [token] [username] [address]",
65
+ examples: [
66
+ "/pay 10 vitalik.eth",
67
+ "/pay 1 usdc to 0xc9925662D36DE3e1bF0fD64e779B2e5F0Aead964",
68
+ ],
69
+ description:
70
+ "Send a specified amount of a cryptocurrency to a destination address. \nWhen tipping, you can assume it's 1 USDC.",
71
+ handler: handler,
72
+ params: {
73
+ amount: {
74
+ default: 10,
75
+ type: "number",
76
+ },
77
+ token: {
78
+ default: "usdc",
79
+ type: "string",
80
+ values: ["eth", "dai", "usdc", "degen"], // Accepted tokens
81
+ },
82
+ username: {
83
+ default: "",
84
+ type: "username",
85
+ },
86
+ address: {
87
+ default: "",
88
+ type: "address",
89
+ },
90
+ },
91
+ },
92
+ ];
93
+
94
+ // Handler Implementation
95
+ export async function handler(context: XMTPContext) {
96
+ const {
97
+ message: {
98
+ content: {
99
+ params: { amount, token, username, address },
100
+ },
101
+ },
102
+ } = context;
103
+ let receiverAddress = address;
104
+ if (username) {
105
+ receiverAddress = (await context.getUserInfo(username))?.address;
106
+ }
107
+ if (address) {
108
+ // Prioritize address over username
109
+ receiverAddress = address;
110
+ }
111
+
112
+ await context.requestPayment(amount, token, receiverAddress);
113
+ }
114
+ ```
115
+
116
+
117
+ ## Types
118
+
119
+ ```typescript
120
+ import { XMTPContext } from "../lib/xmtp.js";
121
+ import { ClientOptions, GroupMember } from "@xmtp/node-sdk";
122
+ import { ContentTypeId } from "@xmtp/content-type-primitives";
123
+
124
+ export type MessageAbstracted = {
125
+ id: string;
126
+ sent: Date;
127
+ content: {
128
+ text?: string | undefined;
129
+ reply?: string | undefined;
130
+ previousMsg?: string | undefined;
131
+ react?: string | undefined;
132
+ content?: any | undefined;
133
+ params?: any | undefined;
134
+ reference?: string | undefined;
135
+ skill?: string | undefined;
136
+ };
137
+ version: "v2" | "v3";
138
+ sender: AbstractedMember;
139
+ typeId: string;
140
+ };
141
+ export type GroupAbstracted = {
142
+ id: string;
143
+ sync: () => Promise<void>;
144
+ addMembers: (addresses: string[]) => Promise<void>;
145
+ addMembersByInboxId: (inboxIds: string[]) => Promise<void>;
146
+ send: (content: string, contentType?: ContentTypeId) => Promise<string>;
147
+ isAdmin: (inboxId: string) => boolean;
148
+ isSuperAdmin: (inboxId: string) => boolean;
149
+ admins: string[];
150
+ superAdmins: string[];
151
+ createdAt: Date;
152
+ members: GroupMember[];
153
+ };
154
+ export type SkillResponse = {
155
+ code: number;
156
+ message: string;
157
+ data?: any;
158
+ };
159
+
160
+ export type SkillHandler = (
161
+ context: XMTPContext,
162
+ ) => Promise<SkillResponse | void>;
163
+
164
+ export type Handler = (context: XMTPContext) => Promise<void>;
165
+
166
+ export type RunConfig = {
167
+ // client options from XMTP client
168
+ client?: ClientOptions;
169
+ // private key to be used for the client, if not, default from env
170
+ privateKey?: string;
171
+ // if true, the init log message with messagekit logo and stuff will be hidden
172
+ experimental?: boolean;
173
+ // hide the init log message with messagekit logo and stuff
174
+ hideInitLogMessage?: boolean;
175
+ // if true, attachments will be enabled
176
+ attachments?: boolean;
177
+ // if true, member changes will be enabled, like adding members to the group
178
+ memberChange?: boolean;
179
+ // skills to be used
180
+ agent?: Agent;
181
+ // model to be used
182
+ gptModel?: string;
183
+ };
184
+ export interface SkillParamConfig {
185
+ default?: string | number | boolean;
186
+ type:
187
+ | "number"
188
+ | "string"
189
+ | "username"
190
+ | "quoted"
191
+ | "address"
192
+ | "prompt"
193
+ | "url";
194
+ plural?: boolean;
195
+ values?: string[]; // Accepted values for the parameter
196
+ }
197
+
198
+ export interface Frame {
199
+ title: string;
200
+ buttons: { content: string; action: string; target: string }[];
201
+ image: string;
202
+ }
203
+ export interface Agent {
204
+ name: string;
205
+ description: string;
206
+ tag: string;
207
+ skills: Skill[];
208
+ }
209
+ export interface Skill {
210
+ skill: string;
211
+ handler?: SkillHandler | undefined;
212
+ adminOnly?: boolean;
213
+ description: string;
214
+ examples: string[];
215
+ params: Record<string, SkillParamConfig>;
216
+ }
217
+
218
+ export interface AbstractedMember {
219
+ inboxId: string;
220
+ address: string;
221
+ accountAddresses: string[];
222
+ installationIds?: string[];
223
+ }
224
+
225
+ export type MetadataValue = string | number | boolean;
226
+ export type Metadata = Record<string, MetadataValue | MetadataValue[]>;
227
+ ```
@@ -7,6 +7,7 @@ import {
7
7
  } from "@xmtp/message-kit";
8
8
 
9
9
  import { systemPrompt } from "./prompt.js";
10
+
10
11
  export const agent: Agent = {
11
12
  name: "GPT Bot",
12
13
  tag: "@bot",
@@ -1,19 +0,0 @@
1
- import { clearInfoCache, clearMemory } from "@xmtp/message-kit";
2
- import { XMTPContext } from "@xmtp/message-kit";
3
-
4
- import type { Skill } from "@xmtp/message-kit";
5
-
6
- export const registerSkill: Skill[] = [
7
- {
8
- skill: "/reset",
9
- examples: ["/reset"],
10
- handler: handler,
11
- description: "Reset the conversation.",
12
- params: {},
13
- },
14
- ];
15
- export async function handler(context: XMTPContext) {
16
- clearMemory();
17
- clearInfoCache();
18
- return { code: 200, message: "Conversation reset." };
19
- }
@@ -1,3 +0,0 @@
1
- KEY= # the private key of the bot wallet
2
- PORT= # the port of the server
3
- ALCHEMY_API_KEY= # the alchemy api key
@@ -1,64 +0,0 @@
1
- import { run, xmtpClient, XMTPContext } from "@xmtp/message-kit";
2
- import { Client } from "@xmtp/node-sdk";
3
- import { startServer } from "./lib/gated.js";
4
- import { verifiedRequest } from "./lib/nft.js";
5
- const { client } = await xmtpClient({ hideInitLogMessage: true });
6
- startServer(client, verifiedRequest);
7
-
8
- run(async (context: XMTPContext) => {
9
- const {
10
- message: {
11
- sender,
12
- content: { skill },
13
- },
14
- client,
15
- group,
16
- } = context;
17
-
18
- if (skill == "id") {
19
- console.log(group?.id);
20
- } else if (skill === "create") {
21
- await context.send("Creating group...");
22
- const group = await createGroup(
23
- client,
24
- sender.address,
25
- client.accountAddress,
26
- );
27
-
28
- await context.send(
29
- `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.`,
30
- );
31
- return;
32
- } else {
33
- await context.send(
34
- "👋 Welcome to the Gated Bot Group!\nTo get started, type /create to set up a new group. 🚀\nThis example will check if the user has a particular nft and add them to the group if they do.\nOnce your group is created, you'll receive a unique Group ID and URL.\nShare the URL with friends to invite them to join your group!",
35
- );
36
- }
37
- });
38
-
39
- async function createGroup(
40
- client: Client,
41
- senderAddress: string,
42
- clientAddress: string,
43
- ) {
44
- let senderInboxId = "";
45
- const group = await client?.conversations.newGroup([
46
- senderAddress,
47
- clientAddress,
48
- ]);
49
- const members = await group.members();
50
- const senderMember = members.find((member) =>
51
- member.accountAddresses.includes(senderAddress.toLowerCase()),
52
- );
53
- if (senderMember) {
54
- const senderInboxId = senderMember.inboxId;
55
- console.log("Sender's inboxId:", senderInboxId);
56
- } else {
57
- console.log("Sender not found in members list");
58
- }
59
- await group.addSuperAdmin(senderInboxId);
60
- console.log("Sender is superAdmin", await group.isSuperAdmin(senderInboxId));
61
- await group.send(`Welcome to the new group!`);
62
- await group.send(`You are now the admin of this group as well as the bot`);
63
- return group;
64
- }
@@ -1,51 +0,0 @@
1
- // Import necessary modules
2
- import express from "express";
3
- import { Client } from "@xmtp/node-sdk";
4
-
5
- export function startServer(
6
- client: Client,
7
- verifiedRequest: (walletAddress: string, groupId: string) => Promise<boolean>,
8
- ) {
9
- async function addWalletToGroup(
10
- walletAddress: string,
11
- groupId: string,
12
- ): Promise<string> {
13
- const conversation =
14
- await client.conversations.getConversationById(groupId);
15
- const verified = await verifiedRequest(walletAddress, groupId);
16
- if (!verified) {
17
- console.log("User cant be added to the group");
18
- return "not verified";
19
- } else {
20
- try {
21
- await conversation?.addMembers([walletAddress]);
22
- console.log(`Added wallet address: ${walletAddress} to the group`);
23
- return "success";
24
- } catch (error: any) {
25
- console.log(error.message);
26
- return "error";
27
- }
28
- }
29
- }
30
-
31
- // Endpoint to add wallet address to a group from an external source
32
- const app = express();
33
- app.use(express.json());
34
- app.post("/add-wallet", async (req, res) => {
35
- try {
36
- const { walletAddress, groupId } = req.body;
37
- const result = await addWalletToGroup(walletAddress, groupId);
38
- res.status(200).send(result);
39
- } catch (error: any) {
40
- res.status(400).send(error.message);
41
- }
42
- });
43
- // Start the server
44
- const PORT = process.env.PORT || 3000;
45
- const url = process.env.URL || `http://localhost:${PORT}`;
46
- app.listen(PORT, () => {
47
- console.warn(
48
- `Use this endpoint to add a wallet to a group indicated by the groupId\n${url}/add-wallet <body: {walletAddress, groupId}>`,
49
- );
50
- });
51
- }
@@ -1,23 +0,0 @@
1
- import type { Agent } from "@xmtp/message-kit";
2
-
3
- export const agent: Agent = {
4
- name: "Group Id",
5
- tag: "@bot",
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
- };
File without changes