create-message-kit 1.2.14 → 1.2.16
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 +19 -17
- package/package.json +1 -1
- package/templates/coinbase-agent/.cursorrules +290 -0
- package/templates/coinbase-agent/.env.example +4 -0
- package/templates/coinbase-agent/.yarnrc.yml +9 -0
- package/templates/coinbase-agent/package.json +22 -0
- package/templates/coinbase-agent/src/index.ts +31 -0
- package/templates/coinbase-agent/src/plugins/learnweb3.ts +96 -0
- package/templates/coinbase-agent/src/plugins/redis.ts +15 -0
- package/templates/coinbase-agent/src/prompt.ts +64 -0
- package/templates/coinbase-agent/src/skills/drip.ts +83 -0
- package/templates/coinbase-agent/src/skills/mint.ts +99 -0
- package/templates/coinbase-agent/src/skills/pay.ts +35 -0
- package/templates/coinbase-agent/src/skills/swap.ts +52 -0
- package/templates/ens/.env.example +1 -0
- package/templates/ens/.yarnrc.yml +5 -0
- package/templates/ens/src/index.ts +1 -1
- package/templates/ens/src/prompt.ts +1 -14
- package/templates/faucet/.cursorrules +290 -0
- package/templates/faucet/.env.example +5 -0
- package/templates/faucet/.yarnrc.yml +9 -0
- package/templates/faucet/package.json +22 -0
- package/templates/faucet/src/index.ts +39 -0
- package/templates/faucet/src/plugins/learnweb3.ts +96 -0
- package/templates/faucet/src/plugins/redis.ts +15 -0
- package/templates/faucet/src/prompt.ts +11 -0
- package/templates/faucet/src/skills/faucet.ts +140 -0
- package/templates/gated-group/.cursorrules +290 -0
- package/templates/gated-group/.env.example +3 -0
- package/templates/gated-group/.yarnrc.yml +9 -0
- package/templates/gated-group/package.json +23 -0
- package/templates/gated-group/src/index.ts +17 -0
- package/templates/gated-group/src/plugins/alchemy.ts +27 -0
- package/templates/gated-group/src/plugins/xmtp.ts +137 -0
- package/templates/gated-group/src/prompt.ts +11 -0
- package/templates/gated-group/src/skills/gated.ts +88 -0
- package/templates/gm/.cursorrules +290 -0
- package/templates/gm/.env.example +2 -0
- package/templates/gm/.yarnrc.yml +9 -0
- package/templates/gm/package.json +20 -0
- package/templates/gm/src/index.ts +8 -0
- package/templates/playground/.cursorrules +290 -0
- package/templates/playground/.env.example +6 -0
- package/templates/playground/.yarnrc.yml +9 -0
- package/templates/playground/package.json +26 -0
- package/templates/playground/src/index.ts +40 -0
- package/templates/playground/src/plugins/alchemy.ts +27 -0
- package/templates/playground/src/plugins/minilog.ts +26 -0
- package/templates/playground/src/plugins/usdc.ts +99 -0
- package/templates/playground/src/plugins/xmtp.ts +137 -0
- package/templates/playground/src/prompt.ts +11 -0
- package/templates/playground/src/skills/broadcast.ts +39 -0
- package/templates/playground/src/skills/cash.ts +122 -0
- package/templates/playground/src/skills/cryptoPrice.ts +63 -0
- package/templates/playground/src/skills/dalle.ts +61 -0
- package/templates/playground/src/skills/gated.ts +88 -0
- package/templates/playground/src/skills/search.ts +159 -0
- package/templates/playground/src/skills/todo.ts +79 -0
- package/templates/playground/src/skills/token.ts +57 -0
- package/templates/playground/src/skills/web.ts +83 -0
- package/templates/playground/src/skills/wordle.ts +96 -0
- package/templates/simple/.env.example +1 -0
- package/templates/simple/.yarnrc.yml +5 -0
- package/templates/simple/src/index.ts +1 -1
- package/templates/simple/src/prompt.ts +2 -0
- package/templates/thegeneralstore/.cursorrules +290 -0
- package/templates/thegeneralstore/.env.example +9 -0
- package/templates/thegeneralstore/.yarnrc.yml +9 -0
- package/templates/thegeneralstore/package.json +24 -0
- package/templates/thegeneralstore/src/data/db.json +812 -0
- package/templates/thegeneralstore/src/index.ts +37 -0
- package/templates/thegeneralstore/src/plugins/learnweb3.ts +96 -0
- package/templates/thegeneralstore/src/plugins/lowdb.ts +11 -0
- package/templates/thegeneralstore/src/plugins/notion.ts +89 -0
- package/templates/thegeneralstore/src/plugins/redis.ts +15 -0
- package/templates/thegeneralstore/src/prompt.md +51 -0
- package/templates/thegeneralstore/src/prompt.ts +3 -0
- package/templates/thegeneralstore/src/skills/faucet.ts +114 -0
- package/templates/thegeneralstore/src/skills/notion.ts +17 -0
- package/templates/thegeneralstore/src/skills/poap.ts +48 -0
- package/templates/thegeneralstore/src/skills.ts +37 -0
- package/templates/toss/.cursorrules +290 -0
- package/templates/toss/.env.example +7 -0
- package/templates/toss/.yarnrc.yml +9 -0
- package/templates/toss/package.json +21 -0
- package/templates/toss/src/index.ts +33 -0
- package/templates/toss/src/plugins/helpers.ts +185 -0
- package/templates/toss/src/plugins/redis.ts +78 -0
- package/templates/toss/src/prompt.ts +54 -0
- package/templates/toss/src/skills/toss.ts +489 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
import { isOnXMTP, V3Client, V2Client } from "@xmtp/message-kit";
|
2
|
+
|
3
|
+
export async function createGroup(
|
4
|
+
client: V3Client,
|
5
|
+
senderAddress: string,
|
6
|
+
clientAddress: string,
|
7
|
+
) {
|
8
|
+
try {
|
9
|
+
let senderInboxId = "";
|
10
|
+
await client.conversations.sync();
|
11
|
+
const group = await client?.conversations.newGroup([
|
12
|
+
senderAddress,
|
13
|
+
clientAddress,
|
14
|
+
]);
|
15
|
+
console.log("Group created", group?.id);
|
16
|
+
const members = await group.members();
|
17
|
+
const senderMember = members.find((member) =>
|
18
|
+
member.accountAddresses.includes(senderAddress.toLowerCase()),
|
19
|
+
);
|
20
|
+
if (senderMember) {
|
21
|
+
senderInboxId = senderMember.inboxId;
|
22
|
+
console.log("Sender's inboxId:", senderInboxId);
|
23
|
+
} else {
|
24
|
+
console.log("Sender not found in members list");
|
25
|
+
}
|
26
|
+
await group.addSuperAdmin(senderInboxId);
|
27
|
+
console.log(
|
28
|
+
"Sender is superAdmin",
|
29
|
+
await group.isSuperAdmin(senderInboxId),
|
30
|
+
);
|
31
|
+
await group.send(`Welcome to the new group!`);
|
32
|
+
await group.send(`You are now the admin of this group as well as the bot`);
|
33
|
+
return group;
|
34
|
+
} catch (error) {
|
35
|
+
console.log("Error creating group", error);
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
export async function removeFromGroup(
|
41
|
+
groupId: string,
|
42
|
+
client: V3Client,
|
43
|
+
v2client: V2Client,
|
44
|
+
senderAddress: string,
|
45
|
+
): Promise<{ code: number; message: string }> {
|
46
|
+
try {
|
47
|
+
let lowerAddress = senderAddress.toLowerCase();
|
48
|
+
const { v2, v3 } = await isOnXMTP(client, v2client, lowerAddress);
|
49
|
+
console.warn("Checking if on XMTP: v2", v2, "v3", v3);
|
50
|
+
if (!v3)
|
51
|
+
return {
|
52
|
+
code: 400,
|
53
|
+
message: "You don't seem to have a v3 identity ",
|
54
|
+
};
|
55
|
+
const conversation =
|
56
|
+
await client.conversations.getConversationById(groupId);
|
57
|
+
console.warn("removing from group", conversation?.id);
|
58
|
+
await conversation?.sync();
|
59
|
+
await conversation?.removeMembers([lowerAddress]);
|
60
|
+
console.warn("Removed member from group");
|
61
|
+
await conversation?.sync();
|
62
|
+
const members = await conversation?.members();
|
63
|
+
console.warn("Number of members", members?.length);
|
64
|
+
|
65
|
+
let wasRemoved = true;
|
66
|
+
if (members) {
|
67
|
+
for (const member of members) {
|
68
|
+
let lowerMemberAddress = member.accountAddresses[0].toLowerCase();
|
69
|
+
if (lowerMemberAddress === lowerAddress) {
|
70
|
+
wasRemoved = false;
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
return {
|
76
|
+
code: wasRemoved ? 200 : 400,
|
77
|
+
message: wasRemoved
|
78
|
+
? "You have been removed from the group"
|
79
|
+
: "Failed to remove from group",
|
80
|
+
};
|
81
|
+
} catch (error) {
|
82
|
+
console.log("Error removing from group", error);
|
83
|
+
return {
|
84
|
+
code: 400,
|
85
|
+
message: "Failed to remove from group",
|
86
|
+
};
|
87
|
+
}
|
88
|
+
}
|
89
|
+
export async function addToGroup(
|
90
|
+
groupId: string,
|
91
|
+
client: V3Client,
|
92
|
+
address: string,
|
93
|
+
asAdmin: boolean = false,
|
94
|
+
): Promise<{ code: number; message: string }> {
|
95
|
+
try {
|
96
|
+
let lowerAddress = address.toLowerCase();
|
97
|
+
const { v2, v3 } = await isOnXMTP(client, null, lowerAddress);
|
98
|
+
if (!v3)
|
99
|
+
return {
|
100
|
+
code: 400,
|
101
|
+
message: "You don't seem to have a v3 identity ",
|
102
|
+
};
|
103
|
+
const group = await client.conversations.getConversationById(groupId);
|
104
|
+
console.warn("Adding to group", group?.id);
|
105
|
+
await group?.sync();
|
106
|
+
await group?.addMembers([lowerAddress]);
|
107
|
+
console.warn("Added member to group");
|
108
|
+
await group?.sync();
|
109
|
+
if (asAdmin) {
|
110
|
+
await group?.addSuperAdmin(lowerAddress);
|
111
|
+
}
|
112
|
+
const members = await group?.members();
|
113
|
+
console.warn("Number of members", members?.length);
|
114
|
+
|
115
|
+
if (members) {
|
116
|
+
for (const member of members) {
|
117
|
+
let lowerMemberAddress = member.accountAddresses[0].toLowerCase();
|
118
|
+
if (lowerMemberAddress === lowerAddress) {
|
119
|
+
console.warn("Member exists", lowerMemberAddress);
|
120
|
+
return {
|
121
|
+
code: 200,
|
122
|
+
message: "You have been added to the group",
|
123
|
+
};
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
return {
|
128
|
+
code: 400,
|
129
|
+
message: "Failed to add to group",
|
130
|
+
};
|
131
|
+
} catch (error) {
|
132
|
+
return {
|
133
|
+
code: 400,
|
134
|
+
message: "Failed to add to group",
|
135
|
+
};
|
136
|
+
}
|
137
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { XMTPContext, Skill, V3Client } from "@xmtp/message-kit";
|
2
|
+
import { createGroup } from "../plugins/xmtp.js";
|
3
|
+
import express from "express";
|
4
|
+
import { checkNft } from "../plugins/alchemy.js";
|
5
|
+
import { addToGroup } from "../plugins/xmtp.js";
|
6
|
+
export const gated: Skill[] = [
|
7
|
+
{
|
8
|
+
skill: "create",
|
9
|
+
examples: ["/create"],
|
10
|
+
handler: handler,
|
11
|
+
adminOnly: true,
|
12
|
+
description: "Create a new group.",
|
13
|
+
},
|
14
|
+
];
|
15
|
+
|
16
|
+
async function handler(context: XMTPContext) {
|
17
|
+
const {
|
18
|
+
message: {
|
19
|
+
sender,
|
20
|
+
content: { skill },
|
21
|
+
},
|
22
|
+
client,
|
23
|
+
} = context;
|
24
|
+
|
25
|
+
if (skill === "create") {
|
26
|
+
const group = await createGroup(
|
27
|
+
client,
|
28
|
+
sender.address,
|
29
|
+
client.accountAddress,
|
30
|
+
);
|
31
|
+
|
32
|
+
await context.send(
|
33
|
+
`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.`,
|
34
|
+
);
|
35
|
+
return;
|
36
|
+
} else {
|
37
|
+
await context.send(
|
38
|
+
"👋 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!",
|
39
|
+
);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
export function startGatedGroupServer(client: V3Client) {
|
44
|
+
async function addWalletToGroup(
|
45
|
+
walletAddress: string,
|
46
|
+
groupId: string,
|
47
|
+
): Promise<string> {
|
48
|
+
const verified = await checkNft(walletAddress, "XMTPeople");
|
49
|
+
if (!verified) {
|
50
|
+
console.log("User cant be added to the group");
|
51
|
+
return "not verified";
|
52
|
+
} else {
|
53
|
+
try {
|
54
|
+
const added = await addToGroup(groupId, client, walletAddress);
|
55
|
+
if (added.code === 200) {
|
56
|
+
console.log(`Added wallet address: ${walletAddress} to the group`);
|
57
|
+
return "success";
|
58
|
+
} else {
|
59
|
+
return added.message;
|
60
|
+
}
|
61
|
+
} catch (error: any) {
|
62
|
+
console.log(error.message);
|
63
|
+
return "error";
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
// Endpoint to add wallet address to a group from an external source
|
69
|
+
const app = express();
|
70
|
+
app.use(express.json());
|
71
|
+
app.post("/add-wallet", async (req, res) => {
|
72
|
+
try {
|
73
|
+
const { walletAddress, groupId } = req.body;
|
74
|
+
const result = await addWalletToGroup(walletAddress, groupId);
|
75
|
+
res.status(200).send(result);
|
76
|
+
} catch (error: any) {
|
77
|
+
res.status(400).send(error.message);
|
78
|
+
}
|
79
|
+
});
|
80
|
+
// Start the servfalcheer
|
81
|
+
const PORT = process.env.PORT || 3000;
|
82
|
+
const url = process.env.URL || `http://localhost:${PORT}`;
|
83
|
+
app.listen(PORT, () => {
|
84
|
+
console.warn(
|
85
|
+
`Use this endpoint to add a wallet to a group indicated by the groupId\n${url}/add-wallet <body: {walletAddress, groupId}>`,
|
86
|
+
);
|
87
|
+
});
|
88
|
+
}
|
@@ -0,0 +1,290 @@
|
|
1
|
+
# MessageKit Skill Template
|
2
|
+
|
3
|
+
## Examples
|
4
|
+
|
5
|
+
### Check if a Domain is Available
|
6
|
+
|
7
|
+
|
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",
|
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
|
+
|
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",
|
65
|
+
examples: [
|
66
|
+
"/pay 10 vitalik.eth",
|
67
|
+
"/pay 1 usdc to 0xC60E6Bb79322392761BFe3081E302aEB79B30B03",
|
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
|
+
## Types
|
117
|
+
|
118
|
+
import { XMTPContext } from "../plugins/xmtp.js";
|
119
|
+
import { ClientOptions, GroupMember } from "@xmtp/node-sdk";
|
120
|
+
import { ContentTypeId } from "@xmtp/content-type-primitives";
|
121
|
+
|
122
|
+
export type MessageAbstracted = {
|
123
|
+
id: string;
|
124
|
+
sent: Date;
|
125
|
+
content: {
|
126
|
+
text?: string | undefined;
|
127
|
+
reply?: string | undefined;
|
128
|
+
previousMsg?: string | undefined;
|
129
|
+
react?: string | undefined;
|
130
|
+
content?: any | undefined;
|
131
|
+
params?: any | undefined;
|
132
|
+
reference?: string | undefined;
|
133
|
+
skill?: string | undefined;
|
134
|
+
};
|
135
|
+
version: "v2" | "v3";
|
136
|
+
sender: AbstractedMember;
|
137
|
+
typeId: string;
|
138
|
+
};
|
139
|
+
export type GroupAbstracted = {
|
140
|
+
id: string;
|
141
|
+
sync: () => Promise<void>;
|
142
|
+
addMembers: (addresses: string[]) => Promise<void>;
|
143
|
+
addMembersByInboxId: (inboxIds: string[]) => Promise<void>;
|
144
|
+
send: (content: string, contentType?: ContentTypeId) => Promise<string>;
|
145
|
+
isAdmin: (inboxId: string) => boolean;
|
146
|
+
isSuperAdmin: (inboxId: string) => boolean;
|
147
|
+
admins: string[];
|
148
|
+
superAdmins: string[];
|
149
|
+
createdAt: Date;
|
150
|
+
members: GroupMember[];
|
151
|
+
};
|
152
|
+
export type SkillResponse = {
|
153
|
+
code: number;
|
154
|
+
message: string;
|
155
|
+
data?: any;
|
156
|
+
};
|
157
|
+
|
158
|
+
export type SkillHandler = (
|
159
|
+
context: XMTPContext,
|
160
|
+
) => Promise<SkillResponse | void>;
|
161
|
+
|
162
|
+
export type Handler = (context: XMTPContext) => Promise<void>;
|
163
|
+
|
164
|
+
export type RunConfig = {
|
165
|
+
// client options from XMTP client
|
166
|
+
client?: ClientOptions;
|
167
|
+
// private key to be used for the client, if not, default from env
|
168
|
+
privateKey?: string;
|
169
|
+
// if true, the init log message with messagekit logo and stuff will be hidden
|
170
|
+
experimental?: boolean;
|
171
|
+
// hide the init log message with messagekit logo and stuff
|
172
|
+
hideInitLogMessage?: boolean;
|
173
|
+
// if true, attachments will be enabled
|
174
|
+
attachments?: boolean;
|
175
|
+
// if true, member changes will be enabled, like adding members to the group
|
176
|
+
memberChange?: boolean;
|
177
|
+
// skills to be used
|
178
|
+
agent?: Agent;
|
179
|
+
// model to be used
|
180
|
+
gptModel?: string;
|
181
|
+
};
|
182
|
+
export interface SkillParamConfig {
|
183
|
+
default?: string | number | boolean;
|
184
|
+
type:
|
185
|
+
| "number"
|
186
|
+
| "string"
|
187
|
+
| "username"
|
188
|
+
| "quoted"
|
189
|
+
| "address"
|
190
|
+
| "prompt"
|
191
|
+
| "url";
|
192
|
+
plural?: boolean;
|
193
|
+
values?: string[]; // Accepted values for the parameter
|
194
|
+
}
|
195
|
+
|
196
|
+
export interface Frame {
|
197
|
+
title: string;
|
198
|
+
buttons: { content: string; action: string; target: string }[];
|
199
|
+
image: string;
|
200
|
+
}
|
201
|
+
export interface Agent {
|
202
|
+
name: string;
|
203
|
+
description: string;
|
204
|
+
tag: string;
|
205
|
+
skills: Skill[];
|
206
|
+
}
|
207
|
+
export interface Skill {
|
208
|
+
skill: string;
|
209
|
+
handler?: SkillHandler | undefined;
|
210
|
+
adminOnly?: boolean;
|
211
|
+
description: string;
|
212
|
+
examples: string[];
|
213
|
+
params: Record<string, SkillParamConfig>;
|
214
|
+
}
|
215
|
+
|
216
|
+
export interface AbstractedMember {
|
217
|
+
inboxId: string;
|
218
|
+
address: string;
|
219
|
+
accountAddresses: string[];
|
220
|
+
installationIds?: string[];
|
221
|
+
}
|
222
|
+
|
223
|
+
export type MetadataValue = string | number | boolean;
|
224
|
+
export type Metadata = Record<string, MetadataValue | MetadataValue[]>;
|
225
|
+
|
226
|
+
|
227
|
+
## Example final prompt
|
228
|
+
|
229
|
+
Your are a helpful and playful ens agent called @bot that lives inside a messaging app called Converse.
|
230
|
+
|
231
|
+
|
232
|
+
# Rules
|
233
|
+
- You can respond with multiple messages if needed. Each message should be separated by a newline character.
|
234
|
+
- You can trigger skills by only sending the command in a newline message.
|
235
|
+
- Each command starts with a slash (/).
|
236
|
+
- Never announce actions without using a command separated by a newline character.
|
237
|
+
- Never use markdown in your responses.
|
238
|
+
- Do not make guesses or assumptions
|
239
|
+
- Only answer if the verified information is in the prompt.
|
240
|
+
- Check that you are not missing a command
|
241
|
+
- Focus only on helping users with operations detailed below.
|
242
|
+
- Date: Fri, 06 Dec 2024 16:03:22 GMT
|
243
|
+
- When mentioning any action related to available skills, you MUST trigger the corresponding command in a new line
|
244
|
+
- If you suggest an action that has a command, you must trigger that command
|
245
|
+
|
246
|
+
|
247
|
+
## User context
|
248
|
+
- Start by fetch their domain from or Converse username
|
249
|
+
- Call the user by their name or domain, in case they have one
|
250
|
+
- Ask for a name (if they don't have one) so you can suggest domains.
|
251
|
+
- Message sent date: 2024-12-06T16:03:36.582Z
|
252
|
+
- Users address is: 0x40f08f0f853d1c42c61815652b7ccd5a50f0be09
|
253
|
+
- Users name is: ArizonaOregon
|
254
|
+
- Converse username is: ArizonaOregon
|
255
|
+
|
256
|
+
## Commands
|
257
|
+
/check [domain] - Check if a domain is available.
|
258
|
+
/cool [domain] - Get cool alternatives for a .eth domain.
|
259
|
+
/info [domain] - Get detailed information about an ENS domain including owner, expiry date, and resolver.
|
260
|
+
/register [domain] - Register a new ENS domain. Returns a URL to complete the registration process.
|
261
|
+
/renew [domain] - Extend the registration period of your ENS domain. Returns a URL to complete the renewal.
|
262
|
+
/reset - Reset the conversation clearing memory and usernames cache.
|
263
|
+
/pay [amount] [token] [username] [address] - Send a specified amount of a cryptocurrency to a destination address.
|
264
|
+
When tipping, you can asume its 1 usdc.
|
265
|
+
|
266
|
+
## Examples
|
267
|
+
/check vitalik.eth
|
268
|
+
/check fabri.base.eth
|
269
|
+
/cool vitalik.eth
|
270
|
+
/info nick.eth
|
271
|
+
/register vitalik.eth
|
272
|
+
/renew fabri.base.eth
|
273
|
+
/reset
|
274
|
+
/pay 10 vitalik.eth
|
275
|
+
/pay 1 usdc to 0xC60E6Bb79322392761BFe3081E302aEB79B30B03
|
276
|
+
|
277
|
+
## Scenarios
|
278
|
+
1. Missing commands in responses
|
279
|
+
**Issue**: Sometimes responses are sent without the required command.
|
280
|
+
**Example**:
|
281
|
+
Incorrect:
|
282
|
+
> "Looks like vitalik.eth is registered! What about these cool alternatives?"
|
283
|
+
Correct:
|
284
|
+
> "Looks like vitalik.eth is registered! What about these cool alternatives?
|
285
|
+
> /cool vitalik.eth"
|
286
|
+
|
287
|
+
Incorrect:
|
288
|
+
> Here is a summary of your TODOs. I will now send it via email.
|
289
|
+
Correct:
|
290
|
+
> /todo
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "gm-bot",
|
3
|
+
"private": true,
|
4
|
+
"type": "module",
|
5
|
+
"scripts": {
|
6
|
+
"build": "tsc",
|
7
|
+
"dev": "tsc -w & sleep 1 && NODE_NO_WARNINGS=1 node --watch dist/index.js",
|
8
|
+
"start": "node dist/index.js"
|
9
|
+
},
|
10
|
+
"dependencies": {
|
11
|
+
"@xmtp/message-kit": "workspace:*"
|
12
|
+
},
|
13
|
+
"devDependencies": {
|
14
|
+
"@types/node": "^20.14.2",
|
15
|
+
"typescript": "^5.4.5"
|
16
|
+
},
|
17
|
+
"engines": {
|
18
|
+
"node": ">=20"
|
19
|
+
}
|
20
|
+
}
|