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,22 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"name": "coinbase-agent",
|
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
|
-
"axios": "^1.7.7"
|
14
|
-
},
|
15
|
-
"devDependencies": {
|
16
|
-
"@types/node": "^20.14.2",
|
17
|
-
"typescript": "^5.4.5"
|
18
|
-
},
|
19
|
-
"engines": {
|
20
|
-
"node": ">=20"
|
21
|
-
}
|
22
|
-
}
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { registerSkill as swapSkill } from "./skills/swap.js";
|
2
|
-
import { registerSkill as mintSkill } from "./skills/mint.js";
|
3
|
-
import { registerSkill as dripSkill } from "./skills/drip.js";
|
4
|
-
import { registerSkill as paySkill } from "./skills/pay.js";
|
5
|
-
import { run, XMTPContext, agentReply, Agent } from "@xmtp/message-kit";
|
6
|
-
import { replaceVariables } from "@xmtp/message-kit";
|
7
|
-
import { systemPrompt } from "./prompt.js";
|
8
|
-
|
9
|
-
export const frameUrl = "https://ens.steer.fun/";
|
10
|
-
export const baseUrl = "https://base-tx-frame.vercel.app/transaction";
|
11
|
-
export const ensUrl = "https://app.ens.domains/";
|
12
|
-
|
13
|
-
export const agent: Agent = {
|
14
|
-
name: "Swap Bot",
|
15
|
-
tag: "@base",
|
16
|
-
description: "Swap bot for base.",
|
17
|
-
skills: [...swapSkill, ...mintSkill, ...dripSkill, ...paySkill],
|
18
|
-
};
|
19
|
-
|
20
|
-
run(
|
21
|
-
async (context: XMTPContext) => {
|
22
|
-
const {
|
23
|
-
message: { sender },
|
24
|
-
agent,
|
25
|
-
} = context;
|
26
|
-
|
27
|
-
let prompt = await replaceVariables(systemPrompt, sender.address, agent);
|
28
|
-
await agentReply(context, prompt);
|
29
|
-
},
|
30
|
-
{ agent }
|
31
|
-
);
|
@@ -1,96 +0,0 @@
|
|
1
|
-
import axios from "axios";
|
2
|
-
|
3
|
-
export const SUPPORTED_NETWORKS = [
|
4
|
-
"arbitrum_goerli",
|
5
|
-
"arbitrum_sepolia",
|
6
|
-
"base_goerli",
|
7
|
-
"base_sepolia",
|
8
|
-
"base_sepolia_usdc",
|
9
|
-
"celo_alfajores",
|
10
|
-
"fantom_testnet",
|
11
|
-
"goerli",
|
12
|
-
"holesky",
|
13
|
-
"linea_goerli",
|
14
|
-
"linea_sepolia",
|
15
|
-
"manta_testnet",
|
16
|
-
"mode_sepolia",
|
17
|
-
"morph_sepolia",
|
18
|
-
"optimism_goerli",
|
19
|
-
"optimism_sepolia",
|
20
|
-
"polygon_amoy",
|
21
|
-
"polygon_mumbai",
|
22
|
-
"polygon_zkevm",
|
23
|
-
"scroll_sepolia",
|
24
|
-
"sepolia",
|
25
|
-
"taiko_jolnir",
|
26
|
-
"zksync_sepolia",
|
27
|
-
"zora_sepolia",
|
28
|
-
] as const;
|
29
|
-
|
30
|
-
export const CLAIM_EVERY = 24 * 60 * 60 * 1000; // 24 hours
|
31
|
-
|
32
|
-
export const ONE_DAY = 24 * 60 * 60 * 1000; // 24 hours
|
33
|
-
|
34
|
-
export const FIVE_MINUTES = 5 * 60 * 1000; // 5 minutes
|
35
|
-
|
36
|
-
export const EVM_TOKENS = ["ETH", "MATIC", "USDC", "CELO", "BERA"];
|
37
|
-
|
38
|
-
export interface Network {
|
39
|
-
networkId: string;
|
40
|
-
networkName: string;
|
41
|
-
networkLogo: string;
|
42
|
-
tokenName: string;
|
43
|
-
dripAmount: number;
|
44
|
-
address: string;
|
45
|
-
isERC20: boolean;
|
46
|
-
erc20Address?: string;
|
47
|
-
erc20Decimals?: number;
|
48
|
-
isActive: boolean;
|
49
|
-
balance: string;
|
50
|
-
}
|
51
|
-
export interface DripTokensResponse {
|
52
|
-
ok: boolean;
|
53
|
-
error?: string;
|
54
|
-
value?: string;
|
55
|
-
}
|
56
|
-
|
57
|
-
export class LearnWeb3Client {
|
58
|
-
public BASE_URL = "https://learnweb3.io/api/faucet";
|
59
|
-
private apiKey = process.env.LEARN_WEB3_API_KEY;
|
60
|
-
constructor() {
|
61
|
-
if (!process.env.LEARN_WEB3_API_KEY) {
|
62
|
-
throw new Error("Please set the LEARN_WEB3_API_KEY environment variable");
|
63
|
-
}
|
64
|
-
this.apiKey = process.env.LEARN_WEB3_API_KEY;
|
65
|
-
}
|
66
|
-
|
67
|
-
async getNetworks(onlyEvm = true): Promise<Network[]> {
|
68
|
-
const response = await axios(`${this.BASE_URL}/networks`);
|
69
|
-
const data: Network[] = response.data;
|
70
|
-
if (onlyEvm) {
|
71
|
-
return data.filter(
|
72
|
-
(network) =>
|
73
|
-
EVM_TOKENS.some((t) =>
|
74
|
-
network.tokenName.toLowerCase().includes(t.toLowerCase()),
|
75
|
-
) && network.isActive,
|
76
|
-
);
|
77
|
-
}
|
78
|
-
return data.filter((network) => network.isActive);
|
79
|
-
}
|
80
|
-
|
81
|
-
async dripTokens(
|
82
|
-
networkId: string,
|
83
|
-
recipientAddress: string,
|
84
|
-
): Promise<DripTokensResponse> {
|
85
|
-
const response = await axios.post(
|
86
|
-
`${this.BASE_URL}/drip`,
|
87
|
-
{ networkId, recipientAddress },
|
88
|
-
{
|
89
|
-
headers: {
|
90
|
-
authorization: `Bearer ${this.apiKey}`,
|
91
|
-
},
|
92
|
-
},
|
93
|
-
);
|
94
|
-
return response.data;
|
95
|
-
}
|
96
|
-
}
|
@@ -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,64 +0,0 @@
|
|
1
|
-
export const systemPrompt = `
|
2
|
-
Your are helpful and playful agent called {agent_name} that lives inside a web3 messaging app called Converse.
|
3
|
-
|
4
|
-
{rules}
|
5
|
-
|
6
|
-
{user_context}
|
7
|
-
|
8
|
-
{skills}
|
9
|
-
|
10
|
-
## Response Scenarios:
|
11
|
-
|
12
|
-
1. When user wants to swap tokens:
|
13
|
-
Hey {PREFERRED_NAME! I can help you swap tokens on Base.
|
14
|
-
Let me help you swap 10 USDC to ETH
|
15
|
-
/swap 10 usdc eth
|
16
|
-
|
17
|
-
2. When user wants to swap a specific amount:
|
18
|
-
Sure! I'll help you swap 5 DEGEN to DAI
|
19
|
-
/swap 5 degen dai
|
20
|
-
|
21
|
-
3. When user wants to pay a specific token:
|
22
|
-
I'll help you pay 1 USDC to 0x123...
|
23
|
-
/pay 1 {TOKEN} 0x123456789...
|
24
|
-
*This will return a url to pay
|
25
|
-
|
26
|
-
4. If the user wants to pay a eth domain:
|
27
|
-
I'll help you pay 1 USDC to vitalik.eth
|
28
|
-
Be aware that this only works on mobile with a installed wallet on Base network
|
29
|
-
/pay 1 vitalik.eth
|
30
|
-
*This will return a url to pay
|
31
|
-
|
32
|
-
5. If the user wants to pay a username:
|
33
|
-
I'll help you pay 1 USDC to @fabri
|
34
|
-
Be aware that this only works on mobile with a installed wallet on Base network
|
35
|
-
/pay 1 @fabri
|
36
|
-
*This will return a url to pay
|
37
|
-
|
38
|
-
6. When user asks about supported tokens:
|
39
|
-
I can help you swap or pay these tokens on Base (ETH, USDC, DAI, DEGEN):
|
40
|
-
Just let me know the amount and which tokens you'd like to swap or send!
|
41
|
-
|
42
|
-
7. When user wants to tip default to 1 usdc:
|
43
|
-
Let's go ahead and tip 1 USDC to nick.eth
|
44
|
-
/pay 1 usdc 0x123456789...
|
45
|
-
|
46
|
-
8. If the users greets or wants to know more or what else can he do:
|
47
|
-
I can assist you with swapping, minting, tipping, dripping testnet tokens and sending tokens (all on Base). Just let me know what you need help with!.
|
48
|
-
|
49
|
-
9. If the user wants to mint they can specify the collection and token id or a Url from Coinbase Wallet URL or Zora URL:
|
50
|
-
I'll help you mint the token with id 1 from collection 0x123456789...
|
51
|
-
/mint 0x123456789... 1
|
52
|
-
I'll help you mint the token from this url
|
53
|
-
/url_mint https://wallet.coinbase.com/nft/mint/eip155:1:erc721:0x123456789...
|
54
|
-
I'll help you mint the token from this url
|
55
|
-
/url_mint https://zora.co/collect/base/0x123456789/1...
|
56
|
-
|
57
|
-
10. If the user wants testnet tokens and doesn't specify the network:
|
58
|
-
Just let me know which network you'd like to drip to Base Sepolia or Base Goerli?
|
59
|
-
|
60
|
-
11. If the user wants testnet tokens and specifies the network:
|
61
|
-
I'll help you get testnet tokens for Base Sepolia\n/drip base_sepolia 0x123456789...
|
62
|
-
|
63
|
-
{issues}
|
64
|
-
`;
|
@@ -1,83 +0,0 @@
|
|
1
|
-
import { XMTPContext, clearMemory } from "@xmtp/message-kit";
|
2
|
-
import type { Skill } from "@xmtp/message-kit";
|
3
|
-
import { getRedisClient } from "../plugins/redis.js";
|
4
|
-
import { LearnWeb3Client, Network } from "../plugins/learnweb3.js";
|
5
|
-
|
6
|
-
export const registerSkill: Skill[] = [
|
7
|
-
{
|
8
|
-
skill: "drip",
|
9
|
-
handler: handler,
|
10
|
-
examples: [
|
11
|
-
"/drip base_sepolia 0x123456789",
|
12
|
-
"/drip base_goerli 0x123456789",
|
13
|
-
],
|
14
|
-
description:
|
15
|
-
"Drip a default amount of testnet tokens to a specified address.",
|
16
|
-
params: {
|
17
|
-
network: {
|
18
|
-
default: "base_sepolia",
|
19
|
-
type: "string",
|
20
|
-
values: ["base_sepolia", "base_goerli"],
|
21
|
-
},
|
22
|
-
address: {
|
23
|
-
default: "",
|
24
|
-
type: "address",
|
25
|
-
},
|
26
|
-
},
|
27
|
-
},
|
28
|
-
];
|
29
|
-
|
30
|
-
export async function handler(context: XMTPContext) {
|
31
|
-
const {
|
32
|
-
message: {
|
33
|
-
content: { params },
|
34
|
-
sender,
|
35
|
-
},
|
36
|
-
} = context;
|
37
|
-
|
38
|
-
const { network } = params;
|
39
|
-
if (!network) {
|
40
|
-
await context.send("Invalid network. Please select a valid option.");
|
41
|
-
return;
|
42
|
-
}
|
43
|
-
context.send("Fetching testnet tokens...");
|
44
|
-
const redisClient = await getRedisClient();
|
45
|
-
|
46
|
-
const learnWeb3Client = new LearnWeb3Client();
|
47
|
-
// Fetch supported networks from Redis cache or API
|
48
|
-
let supportedNetworks: Network[];
|
49
|
-
const cachedSupportedNetworksData =
|
50
|
-
await redisClient.get("supported-networks");
|
51
|
-
supportedNetworks = JSON.parse(
|
52
|
-
cachedSupportedNetworksData!,
|
53
|
-
).supportedNetworks;
|
54
|
-
await context.send(
|
55
|
-
"Your testnet tokens are being processed. Please wait a moment for the transaction to process.",
|
56
|
-
);
|
57
|
-
const selectedNetwork = supportedNetworks.find(
|
58
|
-
(n) => n.networkId.toLowerCase() === network.toLowerCase(),
|
59
|
-
);
|
60
|
-
if (!selectedNetwork) {
|
61
|
-
await context.send(
|
62
|
-
"The network currently does not have funds provided by web3 api's\nTry again later...",
|
63
|
-
);
|
64
|
-
return;
|
65
|
-
}
|
66
|
-
const result = await learnWeb3Client.dripTokens(
|
67
|
-
selectedNetwork!.networkId,
|
68
|
-
sender.address,
|
69
|
-
);
|
70
|
-
|
71
|
-
if (!result.ok) {
|
72
|
-
await context.send(
|
73
|
-
`❌ Sorry, there was an error processing your request:\n\n"${result.error!}"`,
|
74
|
-
);
|
75
|
-
return;
|
76
|
-
}
|
77
|
-
|
78
|
-
await context.send("Here's your transaction receipt:");
|
79
|
-
await context.sendReceipt(result.value!);
|
80
|
-
// Clear any in-memory cache or state related to the prompt
|
81
|
-
clearMemory();
|
82
|
-
return;
|
83
|
-
}
|