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,489 @@
|
|
1
|
+
import { Skill, XMTPContext, getUserInfo } from "@xmtp/message-kit";
|
2
|
+
import { TimeoutError } from "@coinbase/coinbase-sdk";
|
3
|
+
import { getRedisClient } from "../plugins/redis.js";
|
4
|
+
import {
|
5
|
+
checkTossCorrect,
|
6
|
+
extractWinners,
|
7
|
+
TossData,
|
8
|
+
generateTossMessage,
|
9
|
+
generateEndTossMessage,
|
10
|
+
generateTossStatusMessage,
|
11
|
+
DM_HELP_MESSAGE,
|
12
|
+
} from "../plugins/helpers.js";
|
13
|
+
|
14
|
+
const tossDBClient = await getRedisClient();
|
15
|
+
|
16
|
+
export const toss: Skill[] = [
|
17
|
+
{
|
18
|
+
skill: "/end [option]",
|
19
|
+
description: "End a toss.",
|
20
|
+
handler: handleEndToss,
|
21
|
+
examples: ["/end yes", "/end no"],
|
22
|
+
params: {
|
23
|
+
option: {
|
24
|
+
type: "string",
|
25
|
+
},
|
26
|
+
},
|
27
|
+
},
|
28
|
+
{
|
29
|
+
skill: "/create",
|
30
|
+
description: "Create an agent wallet.",
|
31
|
+
handler: handleDM,
|
32
|
+
examples: ["/create"],
|
33
|
+
params: {},
|
34
|
+
},
|
35
|
+
{
|
36
|
+
skill: "/fund [amount]",
|
37
|
+
description: "Fund your account.",
|
38
|
+
handler: handleDM,
|
39
|
+
examples: ["/fund 10"],
|
40
|
+
params: {
|
41
|
+
amount: {
|
42
|
+
type: "number",
|
43
|
+
},
|
44
|
+
},
|
45
|
+
},
|
46
|
+
{
|
47
|
+
skill: "/withdraw [amount]",
|
48
|
+
description: "Withdraw funds from your account.",
|
49
|
+
handler: handleDM,
|
50
|
+
examples: ["/withdraw 10"],
|
51
|
+
params: {
|
52
|
+
amount: {
|
53
|
+
type: "number",
|
54
|
+
},
|
55
|
+
},
|
56
|
+
},
|
57
|
+
{
|
58
|
+
skill: "/help",
|
59
|
+
description: "Get help with tossing.",
|
60
|
+
handler: handleDM,
|
61
|
+
examples: ["/help"],
|
62
|
+
params: {},
|
63
|
+
},
|
64
|
+
{
|
65
|
+
skill: "/cancel",
|
66
|
+
description: "Cancel a toss.",
|
67
|
+
handler: handleCancelToss,
|
68
|
+
examples: ["/cancel"],
|
69
|
+
params: {},
|
70
|
+
},
|
71
|
+
{
|
72
|
+
skill: "/balance",
|
73
|
+
description: "Check your balance.",
|
74
|
+
handler: handleDM,
|
75
|
+
examples: ["/balance"],
|
76
|
+
params: {},
|
77
|
+
},
|
78
|
+
{
|
79
|
+
skill: "/join [response]",
|
80
|
+
description: "Join a toss.",
|
81
|
+
params: {
|
82
|
+
response: {
|
83
|
+
type: "string",
|
84
|
+
},
|
85
|
+
},
|
86
|
+
handler: handleJoinToss,
|
87
|
+
examples: ["/join yes", "/join no"],
|
88
|
+
},
|
89
|
+
{
|
90
|
+
skill: "/status",
|
91
|
+
description: "Check the status of the toss.",
|
92
|
+
handler: handleTossStatus,
|
93
|
+
examples: ["/status"],
|
94
|
+
params: {},
|
95
|
+
},
|
96
|
+
{
|
97
|
+
skill:
|
98
|
+
"/toss [description] [options (separated by comma)] [amount] [judge(optional)] [endTime(optional)]",
|
99
|
+
description:
|
100
|
+
"Create a toss with a description, options, amount and judge(optional).",
|
101
|
+
handler: handleTossCreation,
|
102
|
+
examples: [
|
103
|
+
"/toss 'Shane vs John at pickeball' 'Yes,No' 10",
|
104
|
+
"/toss 'Will argentina win the world cup' 'Yes,No' 10",
|
105
|
+
"/toss 'Race to the end' 'Fabri,John' 10 @fabri",
|
106
|
+
"/toss 'Will argentina win the world cup' 'Yes,No' 5 '27 Oct 2023 23:59:59 GMT'",
|
107
|
+
"/toss 'Will the niks win on sunday?' 'Yes,No' 10 vitalik.eth '27 Oct 2023 23:59:59 GMT'",
|
108
|
+
"/toss 'Will it rain tomorrow' 'Yes,No' 0",
|
109
|
+
],
|
110
|
+
params: {
|
111
|
+
description: {
|
112
|
+
type: "quoted",
|
113
|
+
},
|
114
|
+
options: {
|
115
|
+
default: "Yes, No",
|
116
|
+
type: "quoted",
|
117
|
+
},
|
118
|
+
amount: {
|
119
|
+
type: "number",
|
120
|
+
},
|
121
|
+
judge: {
|
122
|
+
type: "username",
|
123
|
+
},
|
124
|
+
endTime: {
|
125
|
+
type: "quoted",
|
126
|
+
},
|
127
|
+
},
|
128
|
+
},
|
129
|
+
];
|
130
|
+
|
131
|
+
export async function handleTossCreation(context: XMTPContext) {
|
132
|
+
const {
|
133
|
+
message: {
|
134
|
+
content: { params },
|
135
|
+
sender,
|
136
|
+
},
|
137
|
+
walletService,
|
138
|
+
group,
|
139
|
+
} = context;
|
140
|
+
if (!group) {
|
141
|
+
await context.reply("This command can only be used in a group.");
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
|
145
|
+
if (params.description && params.options && !isNaN(Number(params.amount))) {
|
146
|
+
const keys = await tossDBClient.keys("*");
|
147
|
+
let tossId = keys.length + 1;
|
148
|
+
const createdTossWallet = await walletService.createTempWallet(
|
149
|
+
tossId.toString(),
|
150
|
+
);
|
151
|
+
|
152
|
+
let tossData: TossData = {
|
153
|
+
toss_id: tossId.toString(),
|
154
|
+
description: params.description,
|
155
|
+
options: params.options,
|
156
|
+
amount: params.amount,
|
157
|
+
group_id: group.id,
|
158
|
+
admin_name:
|
159
|
+
(await getUserInfo(params.judge ?? sender.address))?.preferredName ??
|
160
|
+
"",
|
161
|
+
admin_address: params.judge ?? sender.address,
|
162
|
+
created_at: new Date().toLocaleString(),
|
163
|
+
end_time: params.endTime
|
164
|
+
? new Date(params.endTime).toLocaleString()
|
165
|
+
: new Date(Date.now() + 24 * 60 * 60 * 1000).toLocaleString(),
|
166
|
+
encrypted_participants: [],
|
167
|
+
participants: [],
|
168
|
+
toss_wallet_address: createdTossWallet?.address,
|
169
|
+
};
|
170
|
+
await tossDBClient.set(
|
171
|
+
"toss:" + walletService.encrypt(tossId.toString()),
|
172
|
+
walletService.encrypt(tossData),
|
173
|
+
);
|
174
|
+
|
175
|
+
if (tossId !== undefined) {
|
176
|
+
await context.send(generateTossMessage(tossData));
|
177
|
+
} else {
|
178
|
+
await context.reply(
|
179
|
+
`An error occurred while creating the toss. ${JSON.stringify(tossId)}`,
|
180
|
+
);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
export async function handleJoinToss(context: XMTPContext) {
|
186
|
+
const tossData = await checkTossCorrect(context);
|
187
|
+
if (!tossData) {
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
|
191
|
+
const { toss_id, participants, encrypted_participants, amount } = tossData;
|
192
|
+
|
193
|
+
const {
|
194
|
+
message: {
|
195
|
+
sender,
|
196
|
+
content: {
|
197
|
+
params: { response },
|
198
|
+
},
|
199
|
+
},
|
200
|
+
group,
|
201
|
+
walletService,
|
202
|
+
} = context;
|
203
|
+
|
204
|
+
if (participants?.some((p) => p.address === sender.address)) {
|
205
|
+
await context.reply("You have already joined this toss.");
|
206
|
+
return;
|
207
|
+
}
|
208
|
+
|
209
|
+
const tossWallet = await walletService.getTempWallet(toss_id);
|
210
|
+
if (!tossWallet) {
|
211
|
+
await context.reply("Toss wallet not found");
|
212
|
+
return;
|
213
|
+
}
|
214
|
+
const balance = await walletService.checkBalance(sender.address);
|
215
|
+
|
216
|
+
if (balance < amount) {
|
217
|
+
await context.send("You need to fund your account. Check your DMs:");
|
218
|
+
await walletService.requestFunds(context, amount);
|
219
|
+
return;
|
220
|
+
}
|
221
|
+
|
222
|
+
try {
|
223
|
+
const senderWallet = await walletService.getUserWallet(sender.address);
|
224
|
+
if (!senderWallet) {
|
225
|
+
await context.reply("Sender wallet not found");
|
226
|
+
return;
|
227
|
+
}
|
228
|
+
const transfer = await walletService.transfer(
|
229
|
+
senderWallet,
|
230
|
+
tossWallet,
|
231
|
+
amount,
|
232
|
+
);
|
233
|
+
console.log("Transfer:", transfer.getTransactionHash());
|
234
|
+
const encryptedParticipant = walletService.encrypt({
|
235
|
+
address: sender.address,
|
236
|
+
agent_address: senderWallet.address,
|
237
|
+
response: response,
|
238
|
+
name:
|
239
|
+
(await context.getUserInfo(sender.address))?.preferredName ??
|
240
|
+
sender.address,
|
241
|
+
});
|
242
|
+
encrypted_participants.push(encryptedParticipant as string);
|
243
|
+
|
244
|
+
await tossDBClient.set(
|
245
|
+
`toss:${walletService.encrypt(toss_id)}`,
|
246
|
+
walletService.encrypt(
|
247
|
+
JSON.stringify({ ...tossData, encrypted_participants }),
|
248
|
+
),
|
249
|
+
);
|
250
|
+
|
251
|
+
await context.reply("Successfully joined the toss!");
|
252
|
+
await context.sendTo(
|
253
|
+
`Your balance was deducted by $${amount}. Now is $${balance - amount}. You can check your balance with /balance`,
|
254
|
+
[sender.address],
|
255
|
+
);
|
256
|
+
await context.executeSkill(`/status ${toss_id}`);
|
257
|
+
} catch (error) {
|
258
|
+
console.error(error);
|
259
|
+
await context.reply("Failed to process your entry. Please try again.");
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
export async function handleEndToss(context: XMTPContext) {
|
264
|
+
const tossData = await checkTossCorrect(context);
|
265
|
+
if (!tossData) return;
|
266
|
+
const { toss_id, admin_address, options, participants } = tossData;
|
267
|
+
|
268
|
+
const {
|
269
|
+
message: {
|
270
|
+
sender,
|
271
|
+
content: {
|
272
|
+
params: { option },
|
273
|
+
},
|
274
|
+
},
|
275
|
+
walletService,
|
276
|
+
} = context;
|
277
|
+
|
278
|
+
if (participants?.length === 0) {
|
279
|
+
await context.reply("No participants for this toss.");
|
280
|
+
return;
|
281
|
+
} else if (admin_address.toLowerCase() !== sender.address.toLowerCase()) {
|
282
|
+
await context.reply("Only the admin can end the toss.");
|
283
|
+
return;
|
284
|
+
} else if (
|
285
|
+
!options
|
286
|
+
.split(",")
|
287
|
+
.map((o) => o.toLowerCase())
|
288
|
+
.includes(option.toLowerCase())
|
289
|
+
) {
|
290
|
+
await context.reply("Invalid option selected.");
|
291
|
+
return;
|
292
|
+
}
|
293
|
+
const { winners, losers } = await extractWinners(participants ?? [], option);
|
294
|
+
|
295
|
+
if (winners.length === 0) {
|
296
|
+
await context.reply("No winners for this toss.");
|
297
|
+
return;
|
298
|
+
}
|
299
|
+
|
300
|
+
const prize =
|
301
|
+
(tossData.amount * (participants?.length ?? 0)) / (winners.length ?? 1);
|
302
|
+
|
303
|
+
try {
|
304
|
+
for (const winner of winners) {
|
305
|
+
const tossWallet = await walletService.getTempWallet(toss_id);
|
306
|
+
|
307
|
+
if (!tossWallet) {
|
308
|
+
await context.reply("Toss wallet not found");
|
309
|
+
return;
|
310
|
+
}
|
311
|
+
const winnerWallet = await walletService.getUserWallet(
|
312
|
+
winner.address,
|
313
|
+
winner.address,
|
314
|
+
);
|
315
|
+
if (!winnerWallet) {
|
316
|
+
await context.reply("Winner wallet not found");
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
const transfer = await walletService.transfer(
|
320
|
+
tossWallet,
|
321
|
+
winnerWallet,
|
322
|
+
prize,
|
323
|
+
);
|
324
|
+
console.log("Transfer:", transfer.getTransactionHash());
|
325
|
+
await tossDBClient.set(
|
326
|
+
`toss:${walletService.encrypt(toss_id)}`,
|
327
|
+
walletService.encrypt(
|
328
|
+
JSON.stringify({ ...tossData, status: "closed" }),
|
329
|
+
),
|
330
|
+
);
|
331
|
+
}
|
332
|
+
// Clean up
|
333
|
+
//await walletService.deleteTempWallet(tossWalletRedis, tossId.toString());
|
334
|
+
if (winners.length > 0) {
|
335
|
+
await context.reply(generateEndTossMessage(winners, losers, prize));
|
336
|
+
}
|
337
|
+
|
338
|
+
await context.sendTo(
|
339
|
+
`You received $${prize} from the toss! Check your balance with /balance`,
|
340
|
+
winners.map((w) => w.address),
|
341
|
+
);
|
342
|
+
} catch (error) {
|
343
|
+
await context.reply(`Failed to send prize to ${winners.length} winners`);
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
export async function handleCancelToss(context: XMTPContext) {
|
348
|
+
const tossData = await checkTossCorrect(context);
|
349
|
+
if (!tossData) return;
|
350
|
+
|
351
|
+
const { toss_id, admin_address, participants, amount } = tossData;
|
352
|
+
|
353
|
+
const {
|
354
|
+
message: { sender },
|
355
|
+
walletService,
|
356
|
+
} = context;
|
357
|
+
|
358
|
+
if (participants?.length === 0) {
|
359
|
+
await context.reply("No participants for this toss.");
|
360
|
+
return;
|
361
|
+
} else if (admin_address.toLowerCase() !== sender.address.toLowerCase()) {
|
362
|
+
await context.reply("Only the admin can cancel the toss.");
|
363
|
+
return;
|
364
|
+
}
|
365
|
+
|
366
|
+
for (const participant of participants ?? []) {
|
367
|
+
try {
|
368
|
+
const tossWallet = await walletService.getTempWallet(toss_id);
|
369
|
+
|
370
|
+
if (!tossWallet) {
|
371
|
+
await context.reply("Toss wallet not found");
|
372
|
+
return;
|
373
|
+
}
|
374
|
+
|
375
|
+
const participantWallet = await walletService.getUserWallet(
|
376
|
+
participant.address,
|
377
|
+
);
|
378
|
+
if (!participantWallet) {
|
379
|
+
await context.reply("Participant wallet not found");
|
380
|
+
return;
|
381
|
+
}
|
382
|
+
const transfer = await walletService.transfer(
|
383
|
+
tossWallet,
|
384
|
+
participantWallet,
|
385
|
+
amount,
|
386
|
+
);
|
387
|
+
console.log("Transfer:", transfer.getTransactionHash());
|
388
|
+
} catch (error) {
|
389
|
+
console.error(`Failed to send prize to ${participant.address}:`, error);
|
390
|
+
await context.reply(`Failed to send prize to ${participant.address}`);
|
391
|
+
}
|
392
|
+
}
|
393
|
+
|
394
|
+
// Clean up
|
395
|
+
//await walletService.deleteTempWallet(tossWalletRedis, tossId.toString());
|
396
|
+
|
397
|
+
await tossDBClient.set(
|
398
|
+
`toss:${walletService.encrypt(toss_id)}`,
|
399
|
+
walletService.encrypt(JSON.stringify({ ...tossData, status: "cancelled" })),
|
400
|
+
);
|
401
|
+
|
402
|
+
await context.reply(
|
403
|
+
`Toss cancelled successfully.\nFunds distributed to participants:\n
|
404
|
+
${participants?.map((p) => `${p.name} - $${amount}`).join("\n")}`,
|
405
|
+
);
|
406
|
+
}
|
407
|
+
export async function handleTossStatus(context: XMTPContext) {
|
408
|
+
const tossData = await checkTossCorrect(context);
|
409
|
+
if (!tossData) return;
|
410
|
+
await context.reply(await generateTossStatusMessage(tossData));
|
411
|
+
}
|
412
|
+
|
413
|
+
export async function handleDM(context: XMTPContext) {
|
414
|
+
const {
|
415
|
+
message: {
|
416
|
+
content: {
|
417
|
+
skill,
|
418
|
+
params: { amount },
|
419
|
+
},
|
420
|
+
sender,
|
421
|
+
},
|
422
|
+
group,
|
423
|
+
walletService,
|
424
|
+
} = context;
|
425
|
+
if (group && skill == "help") {
|
426
|
+
await context.reply("Check your DM's");
|
427
|
+
await context.sendTo(DM_HELP_MESSAGE, [sender.address]);
|
428
|
+
return;
|
429
|
+
}
|
430
|
+
if (skill === "help") {
|
431
|
+
await context.send(DM_HELP_MESSAGE);
|
432
|
+
} else if (skill === "create") {
|
433
|
+
const walletExist = await walletService.getUserWallet(sender.address);
|
434
|
+
if (walletExist) {
|
435
|
+
await context.reply("You already have an agent wallet.");
|
436
|
+
return;
|
437
|
+
}
|
438
|
+
const userWallet = await walletService.createUserWallet(sender.address);
|
439
|
+
await context.reply(
|
440
|
+
`Your agent wallet address is ${userWallet.address}\nBalance: $${await walletService.checkBalance(sender.address)}`,
|
441
|
+
);
|
442
|
+
} else if (skill === "balance") {
|
443
|
+
const userWallet = await walletService.getUserWallet(sender.address);
|
444
|
+
|
445
|
+
context.sendTo(
|
446
|
+
`Your agent wallet address is ${userWallet?.address}\nBalance: $${await walletService.checkBalance(sender.address)}`,
|
447
|
+
[sender.address],
|
448
|
+
);
|
449
|
+
} else if (skill === "fund") {
|
450
|
+
const balance = await walletService.checkBalance(sender.address);
|
451
|
+
if (balance === 10) {
|
452
|
+
await context.reply("You have maxed out your funds.");
|
453
|
+
return;
|
454
|
+
} else if (amount) {
|
455
|
+
if (amount + balance <= 10) {
|
456
|
+
await walletService.requestFunds(context, Number(amount));
|
457
|
+
return;
|
458
|
+
} else {
|
459
|
+
await context.send("Wrong amount. Max 10 USDC.");
|
460
|
+
return;
|
461
|
+
}
|
462
|
+
}
|
463
|
+
await context.reply(
|
464
|
+
`You have $${balance} in your account. You can fund up to $${10 - balance} more.`,
|
465
|
+
);
|
466
|
+
const options = Array.from({ length: Math.floor(10 - balance) }, (_, i) =>
|
467
|
+
(i + 1).toString(),
|
468
|
+
);
|
469
|
+
const response = await context.awaitResponse(
|
470
|
+
`Please specify the amount of USDC to prefund (1 to ${10 - balance}):`,
|
471
|
+
options,
|
472
|
+
);
|
473
|
+
await walletService.requestFunds(context, Number(response));
|
474
|
+
} else if (skill === "withdraw") {
|
475
|
+
const balance = await walletService.checkBalance(sender.address);
|
476
|
+
if (balance === 0) {
|
477
|
+
await context.reply("You have no funds to withdraw.");
|
478
|
+
return;
|
479
|
+
}
|
480
|
+
const options = Array.from({ length: Math.floor(balance) }, (_, i) =>
|
481
|
+
(i + 1).toString(),
|
482
|
+
);
|
483
|
+
const response = await context.awaitResponse(
|
484
|
+
`Please specify the amount of USDC to withdraw (1 to ${balance}):`,
|
485
|
+
options,
|
486
|
+
);
|
487
|
+
await walletService.withdrawFunds(sender.address, Number(response));
|
488
|
+
}
|
489
|
+
}
|