create-message-kit 1.2.22 ā 1.2.24
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 -5
- package/index.js +15 -15
- package/package.json +1 -2
- package/templates/ens/.cursorrules +0 -112
- package/templates/ens/package.json +1 -2
- package/templates/ens/src/index.ts +4 -38
- package/templates/ens/src/prompt.ts +1 -1
- package/templates/ens/src/skills/info.ts +6 -3
- package/templates/simple/.cursorrules +0 -112
- package/templates/simple/src/index.ts +10 -9
- package/templates/coinbase-agent/.cursorrules +0 -290
- package/templates/coinbase-agent/.env.example +0 -4
- package/templates/coinbase-agent/.yarnrc.yml +0 -9
- package/templates/coinbase-agent/package.json +0 -22
- package/templates/coinbase-agent/src/index.ts +0 -31
- package/templates/coinbase-agent/src/plugins/learnweb3.ts +0 -96
- package/templates/coinbase-agent/src/plugins/redis.ts +0 -15
- package/templates/coinbase-agent/src/prompt.ts +0 -64
- package/templates/coinbase-agent/src/skills/drip.ts +0 -83
- package/templates/coinbase-agent/src/skills/mint.ts +0 -99
- package/templates/coinbase-agent/src/skills/pay.ts +0 -35
- package/templates/coinbase-agent/src/skills/swap.ts +0 -52
- package/templates/faucet/.cursorrules +0 -290
- package/templates/faucet/.env.example +0 -5
- package/templates/faucet/.yarnrc.yml +0 -9
- package/templates/faucet/package.json +0 -22
- package/templates/faucet/src/index.ts +0 -39
- package/templates/faucet/src/plugins/learnweb3.ts +0 -96
- package/templates/faucet/src/plugins/redis.ts +0 -15
- package/templates/faucet/src/prompt.ts +0 -11
- package/templates/faucet/src/skills/faucet.ts +0 -140
- package/templates/gated-group/.cursorrules +0 -290
- package/templates/gated-group/.env.example +0 -3
- package/templates/gated-group/.yarnrc.yml +0 -9
- package/templates/gated-group/package.json +0 -23
- package/templates/gated-group/src/index.ts +0 -17
- package/templates/gated-group/src/plugins/alchemy.ts +0 -27
- package/templates/gated-group/src/plugins/xmtp.ts +0 -137
- package/templates/gated-group/src/prompt.ts +0 -11
- package/templates/gated-group/src/skills/gated.ts +0 -88
- package/templates/gm/.cursorrules +0 -290
- package/templates/gm/.env.example +0 -2
- package/templates/gm/.yarnrc.yml +0 -9
- package/templates/gm/package.json +0 -20
- package/templates/gm/src/index.ts +0 -8
- package/templates/playground/.cursorrules +0 -290
- package/templates/playground/.env.example +0 -6
- package/templates/playground/.yarnrc.yml +0 -9
- package/templates/playground/package.json +0 -26
- package/templates/playground/src/index.ts +0 -37
- package/templates/playground/src/plugins/alchemy.ts +0 -27
- package/templates/playground/src/plugins/minilog.ts +0 -26
- package/templates/playground/src/plugins/usdc.ts +0 -99
- package/templates/playground/src/plugins/xmtp.ts +0 -137
- package/templates/playground/src/prompt.ts +0 -11
- package/templates/playground/src/skills/broadcast.ts +0 -39
- package/templates/playground/src/skills/cash.ts +0 -122
- package/templates/playground/src/skills/cryptoPrice.ts +0 -63
- package/templates/playground/src/skills/dalle.ts +0 -61
- package/templates/playground/src/skills/gated.ts +0 -88
- package/templates/playground/src/skills/search.ts +0 -159
- package/templates/playground/src/skills/todo.ts +0 -79
- package/templates/playground/src/skills/token.ts +0 -57
- package/templates/playground/src/skills/web.ts +0 -83
- package/templates/playground/src/skills/wordle.ts +0 -96
- package/templates/toss/.cursorrules +0 -290
- package/templates/toss/.env.example +0 -6
- package/templates/toss/.yarnrc.yml +0 -9
- package/templates/toss/package.json +0 -21
- package/templates/toss/src/index.ts +0 -32
- package/templates/toss/src/plugins/helpers.ts +0 -174
- package/templates/toss/src/plugins/redis.ts +0 -15
- package/templates/toss/src/prompt.ts +0 -54
- package/templates/toss/src/skills/toss.ts +0 -432
- package/templates.json +0 -58
@@ -1,290 +0,0 @@
|
|
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
|
@@ -1,6 +0,0 @@
|
|
1
|
-
KEY= # the private key of the wallet
|
2
|
-
TEST_ENCRYPTION_KEY= # a different private key for encryption
|
3
|
-
OPENAI_API_KEY= # the API key for OpenAI
|
4
|
-
REDIS_CONNECTION_STRING= # the connection to the toss database in Redis
|
5
|
-
COINBASE_API_KEY_NAME= # the API key name for Coinbase
|
6
|
-
COINBASE_API_KEY_PRIVATE_KEY= # the private key for Coinbase
|
@@ -1,21 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"name": "toss",
|
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
|
-
"@redis/client": "^1.6.0",
|
12
|
-
"@xmtp/message-kit": "workspace:*"
|
13
|
-
},
|
14
|
-
"devDependencies": {
|
15
|
-
"@types/node": "^20.14.2",
|
16
|
-
"typescript": "^5.4.5"
|
17
|
-
},
|
18
|
-
"engines": {
|
19
|
-
"node": ">=20"
|
20
|
-
}
|
21
|
-
}
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
run,
|
3
|
-
agentReply,
|
4
|
-
replaceVariables,
|
5
|
-
XMTPContext,
|
6
|
-
Agent,
|
7
|
-
} from "@xmtp/message-kit";
|
8
|
-
|
9
|
-
import { systemPrompt } from "./prompt.js";
|
10
|
-
import { toss } from "./skills/toss.js";
|
11
|
-
import fs from "fs";
|
12
|
-
|
13
|
-
export const agent: Agent = {
|
14
|
-
name: "Toss Bot",
|
15
|
-
tag: "@toss",
|
16
|
-
description: "Create a coin toss.",
|
17
|
-
skills: [...toss],
|
18
|
-
};
|
19
|
-
|
20
|
-
run(
|
21
|
-
async (context: XMTPContext) => {
|
22
|
-
const {
|
23
|
-
message: { sender },
|
24
|
-
} = context;
|
25
|
-
|
26
|
-
let prompt = await replaceVariables(systemPrompt, sender.address, agent);
|
27
|
-
//This is only used for to update the docs.
|
28
|
-
fs.writeFileSync("example_prompt.md", prompt);
|
29
|
-
await agentReply(context, prompt);
|
30
|
-
},
|
31
|
-
{ agent },
|
32
|
-
);
|
@@ -1,174 +0,0 @@
|
|
1
|
-
import { XMTPContext } from "@xmtp/message-kit";
|
2
|
-
import { getRedisClient } from "./redis.js";
|
3
|
-
|
4
|
-
interface Participant {
|
5
|
-
response: string;
|
6
|
-
name: string;
|
7
|
-
address: string;
|
8
|
-
}
|
9
|
-
export interface TossData {
|
10
|
-
group_id: string;
|
11
|
-
admin_name: string;
|
12
|
-
admin_address: string;
|
13
|
-
options: string;
|
14
|
-
toss_id: string;
|
15
|
-
amount: number;
|
16
|
-
created_at: string;
|
17
|
-
end_time: string;
|
18
|
-
description: string;
|
19
|
-
participants: Participant[];
|
20
|
-
}
|
21
|
-
export async function checkTossCorrect(
|
22
|
-
context: XMTPContext,
|
23
|
-
): Promise<TossData | undefined> {
|
24
|
-
const {
|
25
|
-
message: {
|
26
|
-
content: { previousMsg },
|
27
|
-
},
|
28
|
-
group,
|
29
|
-
} = context;
|
30
|
-
|
31
|
-
if (!group) {
|
32
|
-
await context.reply("This command can only be used in a group.");
|
33
|
-
return undefined;
|
34
|
-
} else if (!previousMsg) {
|
35
|
-
await context.reply("You must reply to a toss.");
|
36
|
-
return undefined;
|
37
|
-
}
|
38
|
-
|
39
|
-
let toss_id = extractTossId(previousMsg);
|
40
|
-
if (!toss_id) {
|
41
|
-
await context.reply(
|
42
|
-
"Invalid toss ID. Be sure you are replying to a original toss.",
|
43
|
-
);
|
44
|
-
return undefined;
|
45
|
-
}
|
46
|
-
const tossDBClient = await getRedisClient();
|
47
|
-
const tossDataString = await tossDBClient.get(`toss:${toss_id}`);
|
48
|
-
let tossData = tossDataString ? JSON.parse(tossDataString) : null;
|
49
|
-
|
50
|
-
if (typeof tossData === "string") {
|
51
|
-
tossData = JSON.parse(tossData) as TossData;
|
52
|
-
}
|
53
|
-
|
54
|
-
if (!tossData) {
|
55
|
-
await context.reply("Toss not found");
|
56
|
-
return undefined;
|
57
|
-
} else if (tossData.status === "closed") {
|
58
|
-
await context.reply("Toss has already ended.");
|
59
|
-
return undefined;
|
60
|
-
} else if (tossData.group_id.toLowerCase() !== group.id.toLowerCase()) {
|
61
|
-
await context.reply("This toss is not in this group.");
|
62
|
-
return undefined;
|
63
|
-
}
|
64
|
-
|
65
|
-
return { ...tossData, toss_id };
|
66
|
-
}
|
67
|
-
|
68
|
-
export function extractTossId(message: string): string | null {
|
69
|
-
try {
|
70
|
-
const match = message.match(/ID:\s*(\d+)/);
|
71
|
-
return match ? match[1].toString() : null;
|
72
|
-
} catch (error) {
|
73
|
-
return null;
|
74
|
-
}
|
75
|
-
}
|
76
|
-
|
77
|
-
export async function extractWinners(
|
78
|
-
participants: Participant[],
|
79
|
-
option: string,
|
80
|
-
): Promise<{
|
81
|
-
winners: Participant[];
|
82
|
-
losers: Participant[];
|
83
|
-
}> {
|
84
|
-
let winners: Participant[] = [];
|
85
|
-
let losers: Participant[] = [];
|
86
|
-
|
87
|
-
await Promise.all(
|
88
|
-
participants.map(async (participant) => {
|
89
|
-
if (participant.response.toLowerCase() === option.toLowerCase()) {
|
90
|
-
winners.push(participant);
|
91
|
-
} else {
|
92
|
-
losers.push(participant);
|
93
|
-
}
|
94
|
-
}),
|
95
|
-
);
|
96
|
-
return { winners, losers };
|
97
|
-
}
|
98
|
-
|
99
|
-
export function generateTossMessage(tossData: TossData): string {
|
100
|
-
return `Here is your toss!\n
|
101
|
-
šŖ ${tossData.description.toUpperCase()}? - ${tossData.options.toUpperCase()} - $${tossData.amount}\n
|
102
|
-
- ID: ${tossData.toss_id}
|
103
|
-
- Judge: ${tossData.admin_name}
|
104
|
-
- Ends on: ${tossData.end_time}
|
105
|
-
|
106
|
-
How to toss:\n- The creator of the toss is one who can end or settle the toss. \n- The pool will be split evenly with the winners. \n- Remember, with great power comes great responsibility šŖ
|
107
|
-
|
108
|
-
\nš ļø Reply with:
|
109
|
-
@toss <option>
|
110
|
-
@toss end <option> - only the judge can end the toss
|
111
|
-
@toss cancel - only the creator can cancel the toss
|
112
|
-
@toss status - check the status of the toss
|
113
|
-
@toss help - for managing your toss via DMs`;
|
114
|
-
}
|
115
|
-
|
116
|
-
export function generateEndTossMessage(
|
117
|
-
winners: { name: string; address: string }[],
|
118
|
-
losers: { name: string; address: string }[],
|
119
|
-
prize: number,
|
120
|
-
): string {
|
121
|
-
if (!winners.length) {
|
122
|
-
return `The toss has been closed and no winners were found.`;
|
123
|
-
}
|
124
|
-
let message = `š Winners have been rewarded! š\n\nš Winners: \n${winners
|
125
|
-
.map((winner) => `- ${winner.name} - $${prize} š°\n`)
|
126
|
-
.join("")}`;
|
127
|
-
if (losers.length > 0) {
|
128
|
-
message += `\nš¢ Losers: \n${losers
|
129
|
-
.map((loser) => `- ${loser.name} š¢\n`)
|
130
|
-
.join("")}`;
|
131
|
-
}
|
132
|
-
return (
|
133
|
-
message +
|
134
|
-
`\nThe pool has been distributed among the winners. The toss has been closed now.`
|
135
|
-
);
|
136
|
-
}
|
137
|
-
|
138
|
-
export async function generateTossStatusMessage(
|
139
|
-
tossData: TossData,
|
140
|
-
): Promise<string> {
|
141
|
-
const participants = tossData.participants;
|
142
|
-
return `Here are the details:
|
143
|
-
- Amount: $${tossData.amount}
|
144
|
-
- Description: ${tossData.description}
|
145
|
-
- Judge: ${tossData.admin_name}
|
146
|
-
- End Time: ${tossData.end_time}
|
147
|
-
|
148
|
-
š Status:
|
149
|
-
š„ Participants:\n${participants
|
150
|
-
?.map(
|
151
|
-
(participant: any) =>
|
152
|
-
`- ${participant.name ?? participant.address} - ${participant.response}\n`,
|
153
|
-
)
|
154
|
-
.join("")}
|
155
|
-
š¦ Pool: $${(tossData?.participants?.length || 0) * tossData.amount}
|
156
|
-
š Options:
|
157
|
-
${tossData.options
|
158
|
-
.split(",")
|
159
|
-
.map((option: string) => {
|
160
|
-
const voteCount = participants?.filter(
|
161
|
-
(participant: any) =>
|
162
|
-
participant.response.toLowerCase() === option.toLowerCase(),
|
163
|
-
).length;
|
164
|
-
return `\t- ${option}: ${voteCount} votes`;
|
165
|
-
})
|
166
|
-
.join("\n")} `;
|
167
|
-
}
|
168
|
-
|
169
|
-
export const DM_HELP_MESSAGE = `Welcome to @toss! I'm your friendly neighbourhood toss bot.
|
170
|
-
/fund [amount] - You can fund your account with
|
171
|
-
/balance - Check your balance
|
172
|
-
/withdraw [amount] - You can withdraw funds to your wallet
|
173
|
-
/create - Create an agent wallet
|
174
|
-
/help - Get help with tossing`;
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import { createClient } from "@redis/client";
|
2
|
-
import { RedisClientType } from "@redis/client";
|
3
|
-
|
4
|
-
export const getRedisClient = async () => {
|
5
|
-
const client = createClient({
|
6
|
-
url: process.env.REDIS_CONNECTION_STRING,
|
7
|
-
});
|
8
|
-
|
9
|
-
client.on("error", (err) => {
|
10
|
-
console.error("Redis client error:", err);
|
11
|
-
});
|
12
|
-
|
13
|
-
await client.connect();
|
14
|
-
return client as RedisClientType;
|
15
|
-
};
|
@@ -1,54 +0,0 @@
|
|
1
|
-
export const systemPrompt = `You are a helpful agent, friendly toss master named @toss, always ready to flip the odds!
|
2
|
-
{rules}
|
3
|
-
|
4
|
-
## Game rules
|
5
|
-
- The token is always USDC. Ignore other tokens and default to usdc. Don't mention the token in the command.
|
6
|
-
- Infer the name of the toss from the prompt if it's not provided. It should be a short sentence summarizing the event, never mention the options.
|
7
|
-
- Tosses must always have two options. If options are not provided, assume "Yes" and "No."
|
8
|
-
- For sports events, ensure the options are the two teams or players, as inferred from the context.
|
9
|
-
- If the user provides unclear or incomplete information, infer and generate the correct toss format based on context.
|
10
|
-
- Maximum toss amount is 10. Default to 10 if nothing is provided. Minimum is 0.00 and its valid.
|
11
|
-
- Don't mention options in the toss name.
|
12
|
-
- Remove all emojis from the options.
|
13
|
-
- If toss is correct. Don't return anything else than the command. Ever.
|
14
|
-
- If the user asks about performing an action and it maps to a command, answer directly with the populated command. Always return commands with real values only.
|
15
|
-
- If the user's input doesn't clearly map to a command, respond with helpful information or a clarification question.
|
16
|
-
- Date needs to be formatted in UTC and in the future.
|
17
|
-
|
18
|
-
{user_context}
|
19
|
-
|
20
|
-
{skills}
|
21
|
-
|
22
|
-
## Examples scenarios
|
23
|
-
|
24
|
-
1. @toss will it rain tomorrow? yes,no 10
|
25
|
-
- /toss 'will it rain tomorrow' 'yes,no' 10 24h from now
|
26
|
-
2. @toss race to the end Fabri vs John? fabri,john 10
|
27
|
-
- /toss 'race to the end' 'fabri,john' 10
|
28
|
-
3. @toss will it rain tomorrow for 10 (keep the toss for 1 week), judge is @fabri
|
29
|
-
- /toss 'will it rain tomorrow' 'yes,no' 10 '24 hours from now' @fabri
|
30
|
-
4. @toss will the stock price of company X go up tomorrow? yes,no 5
|
31
|
-
- /toss 'will the stock price of company x go up tomorrow' 'yes,no' 5
|
32
|
-
5. @toss who will win the match? team A vs team B 10
|
33
|
-
- /toss 'who will win the match' 'team a,team b' 10
|
34
|
-
6. will the project be completed on time? yes,no 0
|
35
|
-
- /toss 'will the project be completed on time' 'yes,no' 0
|
36
|
-
7. @toss will the meeting be rescheduled? yes,no 2
|
37
|
-
- /toss 'will the meeting be rescheduled' 'yes,no' 2
|
38
|
-
8. will the product launch be successful? yes,no 7
|
39
|
-
- /toss 'will the product launch be successful' 'yes,no' 7
|
40
|
-
9. @toss will the team meet the deadline? yes,no 3
|
41
|
-
- /toss 'will the team meet the deadline' 'yes,no' 3
|
42
|
-
10. will the event be postponed? yes,no 1
|
43
|
-
- /toss 'will the event be postponed' 'yes,no' 1
|
44
|
-
11. @toss yes
|
45
|
-
- /join yes
|
46
|
-
12. @toss no
|
47
|
-
- /join no
|
48
|
-
13. @toss status
|
49
|
-
- /status
|
50
|
-
14. @toss end yes
|
51
|
-
- /end yes
|
52
|
-
|
53
|
-
{issues}
|
54
|
-
`;
|