create-message-kit 1.0.16 → 1.0.19
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 +10 -10
- package/package.json +1 -1
- package/templates/agent/src/handler/ens.ts +105 -141
- package/templates/agent/src/index.ts +5 -1
- package/templates/agent/src/lib/openai.ts +44 -29
- package/templates/agent/src/lib/resolver.ts +107 -63
- package/templates/agent/src/prompt.ts +31 -53
- package/templates/agent/src/skills.ts +95 -0
- package/templates/gm/src/index.ts +6 -13
- package/templates/group/src/handler/agent.ts +17 -10
- package/templates/group/src/handler/loyalty.ts +3 -11
- package/templates/group/src/handler/splitpayment.ts +17 -10
- package/templates/group/src/handler/tipping.ts +10 -6
- package/templates/group/src/handler/transaction.ts +10 -39
- package/templates/group/src/index.ts +24 -20
- package/templates/group/src/lib/openai.ts +44 -3
- package/templates/group/src/lib/resolver.ts +126 -0
- package/templates/group/src/{commands.ts → skills.ts} +17 -16
- package/templates/agent/src/commands.ts +0 -69
- package/templates/agent/src/lib/types.ts +0 -33
- package/templates/gm/src/commands.ts +0 -18
- package/templates/gm/src/handler.ts +0 -6
@@ -1,93 +1,71 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
txUrl?: string,
|
9
|
-
) {
|
10
|
-
const userName = domain ?? name ?? "";
|
11
|
-
const commonAlternatives = generateCoolAlternatives(userName);
|
12
|
-
const systemPrompt = `You are a helpful and playful agent that lives inside a web3 messaging app.
|
1
|
+
import { skills } from "./skills.js";
|
2
|
+
import type { UserInfo } from "./lib/resolver.js";
|
3
|
+
|
4
|
+
export async function ens_agent_prompt(userInfo: UserInfo) {
|
5
|
+
let { address, ensDomain, converseUsername } = userInfo;
|
6
|
+
|
7
|
+
const systemPrompt = `You are a helpful and playful agent called @ens that lives inside a web3 messaging app called Converse.
|
13
8
|
- You can respond with multiple messages if needed. Each message should be separated by a newline character.
|
14
9
|
- You can trigger commands by only sending the command in a newline message.
|
15
10
|
- Never announce actions without using a command separated by a newline character.
|
16
11
|
- Only provide answers based on verified information.
|
12
|
+
- Dont answer in markdown format, just answer in plaintext.
|
17
13
|
- Do not make guesses or assumptions
|
18
14
|
- CHECK that you are not missing a command
|
19
15
|
|
20
16
|
User context:
|
21
17
|
- Users address is: ${address}
|
22
|
-
${
|
23
|
-
${
|
18
|
+
${ensDomain != undefined ? `- User ENS domain is: ${ensDomain}` : ""}
|
19
|
+
${converseUsername != undefined ? `- Converse username is: ${converseUsername}` : ""}
|
24
20
|
|
25
21
|
## Task
|
26
22
|
- Start by fetch their domain from or Convese username
|
27
23
|
- Call the user by their name or domain, in case they have one
|
28
24
|
- Ask for a name (if they don't have one) so you can suggest domains.
|
29
|
-
- Use "/check [domain] [cool_alternatives]" to see if a domain is available and offer cool alternatives
|
30
|
-
- To check the information about the domain by using the command "/info [domain]".
|
31
|
-
- To register a domain use the command "/register [domain]".
|
32
|
-
- To trigger renewal: "/renew [domain]".
|
33
|
-
- To tip the domain owner: "/tip [address]".
|
34
25
|
|
35
26
|
Commands:
|
36
|
-
|
37
|
-
- /check [domain] [cool_alternatives]: Check if a domain is available and send cool alternatives
|
38
|
-
- /register [domain]: Register a domain
|
39
|
-
- /renew [domain]: Renew a domain
|
40
|
-
- /tip [address]: Tip the domain owner
|
27
|
+
${skills.map((skill) => skill.skills.map((s) => s.command).join("\n")).join("\n")}
|
41
28
|
|
42
29
|
Examples:
|
43
|
-
|
44
|
-
|
45
|
-
- /register vitalik.eth
|
46
|
-
- /renew fabri.base.eth
|
47
|
-
- /tip 0xf0EA7663233F99D0c12370671abBb6Cca980a490
|
30
|
+
${skills.map((skill) => skill.skills.map((s) => s.example).join("\n")).join("\n")}
|
31
|
+
|
48
32
|
|
49
|
-
## Example
|
33
|
+
## Example responses:
|
50
34
|
|
51
35
|
1. Check if the user does not have a ENS domain
|
52
|
-
Hey ${
|
36
|
+
Hey ${converseUsername}! it looks like you don't have a ENS domain yet! \n\Let me start by checking your Converse username with the .eth suffix\n/check ${converseUsername}.eth
|
53
37
|
|
54
38
|
2. If the user has a ENS domain
|
55
|
-
Hello ${
|
39
|
+
Hello ${ensDomain} ! I'll help you get your ENS domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/check ${ensDomain}
|
56
40
|
|
57
41
|
3. Check if the ENS domain is available
|
58
|
-
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain ${
|
42
|
+
Hello! I'll help you get your domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/check ${ensDomain}
|
59
43
|
|
60
44
|
4. If the ENS domain is available,
|
61
|
-
Looks like ${
|
45
|
+
Looks like ${ensDomain} is available! Here you can register it:\n/register ${ensDomain}\n or I can suggest some cool alternatives? Le me know!
|
62
46
|
|
63
47
|
5. If the ENS domain is already registered, let me suggest 5 cool alternatives
|
64
|
-
Looks like ${
|
48
|
+
Looks like ${ensDomain} is already registered!\n What about these cool alternatives?\n/cool ${ensDomain}
|
65
49
|
|
66
50
|
6. If the user wants to register a ENS domain, use the command "/register [domain]"
|
67
|
-
Looks like ${
|
51
|
+
Looks like ${ensDomain} is available! Let me help you register it\n/register ${ensDomain}
|
68
52
|
|
69
|
-
7. If the user wants to tip the ENS domain owner, use the command "/tip [
|
70
|
-
|
71
|
-
|
72
|
-
8. When sending a tip, the url will be returned in the message.
|
73
|
-
Here is the url to send the tip:\n${txUrl}
|
74
|
-
|
75
|
-
9. If the user wants to get information about the ENS domain, use the command "/info [domain]"
|
76
|
-
Hello! I'll help you get info about ${domain}.\n Give me a moment.\n/info ${domain}
|
53
|
+
7. If the user wants to directly to tip to the ENS domain owner, use directly the command "/tip [domain]", this will return a url but a button to send the tip
|
54
|
+
Here is the url to send the tip:\n/tip ${ensDomain}
|
77
55
|
|
78
|
-
|
79
|
-
Hello! I'll help you get
|
56
|
+
8. If the user wants to get information about the ENS domain, use the command "/info [domain]"
|
57
|
+
Hello! I'll help you get info about ${ensDomain}.\n Give me a moment.\n/info ${ensDomain}
|
80
58
|
|
81
|
-
|
82
|
-
|
59
|
+
9. If the user wants to renew their domain, use the command "/renew [domain]"
|
60
|
+
Hello! I'll help you get your ENS domain.\n Let's start by checking your ENS domain ${ensDomain}. Give me a moment.\n/renew ${ensDomain}
|
83
61
|
|
84
|
-
|
85
|
-
Here are some cool suggestions for
|
62
|
+
10. If the user wants cool suggestions about a domain, use the command "/cool [domain]"
|
63
|
+
Here are some cool suggestions for your domain.\n/cool ${ensDomain}
|
86
64
|
|
87
65
|
## Most common bug
|
88
|
-
Some times you will say something like: "Looks like vitalik.eth is registered! What about these cool alternatives?"
|
89
|
-
But you forgot to add the command at the end of the message.
|
90
|
-
You should have said something like: "Looks like vitalik.eth is registered! What about these cool alternatives?\n/
|
66
|
+
Some times you will say something like: "Looks like vitalik.eth is registered! What about these cool alternatives?"
|
67
|
+
But you forgot to add the command at the end of the message.
|
68
|
+
You should have said something like: "Looks like vitalik.eth is registered! What about these cool alternatives?\n/cool vitalik.eth
|
91
69
|
`;
|
92
70
|
return systemPrompt;
|
93
71
|
}
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import { handleEns, ensAgent } from "./handler/ens.js";
|
2
|
+
import type { SkillGroup } from "@xmtp/message-kit";
|
3
|
+
|
4
|
+
export const skills: SkillGroup[] = [
|
5
|
+
{
|
6
|
+
name: "Ens Domain Bot",
|
7
|
+
tag: "@ens",
|
8
|
+
tagHandler: ensAgent,
|
9
|
+
description: "Register ENS domains.",
|
10
|
+
skills: [
|
11
|
+
{
|
12
|
+
command: "/register [domain]",
|
13
|
+
triggers: ["/register"],
|
14
|
+
handler: handleEns,
|
15
|
+
description:
|
16
|
+
"Register a new ENS domain. Returns a URL to complete the registration process.",
|
17
|
+
example: "/register vitalik.eth",
|
18
|
+
params: {
|
19
|
+
domain: {
|
20
|
+
type: "string",
|
21
|
+
},
|
22
|
+
},
|
23
|
+
},
|
24
|
+
{
|
25
|
+
command: "/info [domain]",
|
26
|
+
triggers: ["/info"],
|
27
|
+
handler: handleEns,
|
28
|
+
description:
|
29
|
+
"Get detailed information about an ENS domain including owner, expiry date, and resolver.",
|
30
|
+
example: "/info nick.eth",
|
31
|
+
params: {
|
32
|
+
domain: {
|
33
|
+
type: "string",
|
34
|
+
},
|
35
|
+
},
|
36
|
+
},
|
37
|
+
{
|
38
|
+
command: "/renew [domain]",
|
39
|
+
triggers: ["/renew"],
|
40
|
+
handler: handleEns,
|
41
|
+
description:
|
42
|
+
"Extend the registration period of your ENS domain. Returns a URL to complete the renewal.",
|
43
|
+
example: "/renew fabri.base.eth",
|
44
|
+
params: {
|
45
|
+
domain: {
|
46
|
+
type: "string",
|
47
|
+
},
|
48
|
+
},
|
49
|
+
},
|
50
|
+
{
|
51
|
+
command: "/check [domain] [cool_alternatives]",
|
52
|
+
triggers: ["/check"],
|
53
|
+
handler: handleEns,
|
54
|
+
description: "Check if a domain is available.",
|
55
|
+
params: {
|
56
|
+
domain: {
|
57
|
+
type: "string",
|
58
|
+
},
|
59
|
+
cool_alternatives: {
|
60
|
+
type: "quoted",
|
61
|
+
},
|
62
|
+
},
|
63
|
+
},
|
64
|
+
{
|
65
|
+
command: "/cool [domain]",
|
66
|
+
triggers: ["/cool"],
|
67
|
+
handler: handleEns,
|
68
|
+
description: "Get cool alternatives for a .eth domain.",
|
69
|
+
params: {
|
70
|
+
domain: {
|
71
|
+
type: "string",
|
72
|
+
},
|
73
|
+
},
|
74
|
+
},
|
75
|
+
{
|
76
|
+
command: "/reset",
|
77
|
+
triggers: ["/reset"],
|
78
|
+
handler: handleEns,
|
79
|
+
description: "Reset the conversation.",
|
80
|
+
params: {},
|
81
|
+
},
|
82
|
+
{
|
83
|
+
command: "/tip [address]",
|
84
|
+
description: "Show a URL for tipping a domain owner.",
|
85
|
+
triggers: ["/tip"],
|
86
|
+
handler: handleEns,
|
87
|
+
params: {
|
88
|
+
address: {
|
89
|
+
type: "string",
|
90
|
+
},
|
91
|
+
},
|
92
|
+
},
|
93
|
+
],
|
94
|
+
},
|
95
|
+
];
|
@@ -1,16 +1,9 @@
|
|
1
1
|
import { run, HandlerContext } from "@xmtp/message-kit";
|
2
2
|
|
3
|
-
run(
|
4
|
-
|
5
|
-
|
6
|
-
const { content, sender } = context.message;
|
3
|
+
run(async (context: HandlerContext) => {
|
4
|
+
// Get the message and the address from the sender
|
5
|
+
const { content, sender } = context.message;
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
{
|
12
|
-
memberChange: true,
|
13
|
-
attachments: true,
|
14
|
-
experimental: true,
|
15
|
-
},
|
16
|
-
);
|
7
|
+
// To reply, just call `reply` on the HandlerContext
|
8
|
+
await context.send(`gm`);
|
9
|
+
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { HandlerContext,
|
1
|
+
import { HandlerContext, AbstractedMember } from "@xmtp/message-kit";
|
2
2
|
import { textGeneration } from "../lib/openai.js";
|
3
3
|
|
4
4
|
export async function handler(context: HandlerContext) {
|
@@ -9,19 +9,21 @@ export async function handler(context: HandlerContext) {
|
|
9
9
|
|
10
10
|
const {
|
11
11
|
message: {
|
12
|
+
sender,
|
12
13
|
content: { content, params },
|
13
14
|
},
|
14
15
|
} = context;
|
15
16
|
|
16
17
|
const systemPrompt = generateSystemPrompt(context);
|
17
|
-
console.log("systemPrompt", systemPrompt);
|
18
18
|
try {
|
19
19
|
let userPrompt = params?.prompt ?? content;
|
20
|
-
console.log("userPrompt", userPrompt);
|
21
20
|
|
22
|
-
const { reply } = await textGeneration(
|
23
|
-
|
24
|
-
|
21
|
+
const { reply } = await textGeneration(
|
22
|
+
sender.address,
|
23
|
+
userPrompt,
|
24
|
+
systemPrompt,
|
25
|
+
);
|
26
|
+
context.skill(reply);
|
25
27
|
} catch (error) {
|
26
28
|
console.error("Error during OpenAI call:", error);
|
27
29
|
await context.reply("An error occurred while processing your request.");
|
@@ -31,7 +33,7 @@ export async function handler(context: HandlerContext) {
|
|
31
33
|
function generateSystemPrompt(context: HandlerContext) {
|
32
34
|
const {
|
33
35
|
members,
|
34
|
-
|
36
|
+
skills,
|
35
37
|
message: { sender },
|
36
38
|
} = context;
|
37
39
|
|
@@ -40,10 +42,15 @@ function generateSystemPrompt(context: HandlerContext) {
|
|
40
42
|
|
41
43
|
You are a helpful bot agent that lives inside a web3 messaging group that helps interpret user requests and execute commands.
|
42
44
|
#### Users
|
43
|
-
${JSON.stringify(
|
45
|
+
${JSON.stringify(
|
46
|
+
members?.map((member: AbstractedMember) => ({
|
47
|
+
...member,
|
48
|
+
username: `@${member.accountAddresses[0]}`,
|
49
|
+
})),
|
50
|
+
)}\n
|
44
51
|
#### Commands
|
45
|
-
${JSON.stringify(
|
46
|
-
The message was sent by @${sender?.
|
52
|
+
${JSON.stringify(skills)}\n
|
53
|
+
The message was sent by @${sender?.address}
|
47
54
|
|
48
55
|
### Examples
|
49
56
|
prompt /agent tip alix and bo
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { HandlerContext,
|
1
|
+
import { HandlerContext, AbstractedMember } from "@xmtp/message-kit";
|
2
2
|
import { getStackClient } from "../lib/stack.js";
|
3
3
|
|
4
4
|
export async function handler(context: HandlerContext, fake?: boolean) {
|
@@ -6,15 +6,8 @@ export async function handler(context: HandlerContext, fake?: boolean) {
|
|
6
6
|
const {
|
7
7
|
members,
|
8
8
|
group,
|
9
|
-
|
10
|
-
message: {
|
11
|
-
content,
|
12
|
-
content: { command },
|
13
|
-
sender,
|
14
|
-
typeId,
|
15
|
-
},
|
9
|
+
message: { sender, typeId, content },
|
16
10
|
} = context;
|
17
|
-
console.log(command);
|
18
11
|
if (typeId === "text" && group) {
|
19
12
|
const { command } = content;
|
20
13
|
if (command === "points") {
|
@@ -40,14 +33,13 @@ export async function handler(context: HandlerContext, fake?: boolean) {
|
|
40
33
|
} else if (typeId === "group_updated" && group) {
|
41
34
|
const { initiatedByInboxId, addedInboxes } = content;
|
42
35
|
const adminAddress = members?.find(
|
43
|
-
(member:
|
36
|
+
(member: AbstractedMember) => member.inboxId === initiatedByInboxId,
|
44
37
|
);
|
45
38
|
if (addedInboxes && addedInboxes.length > 0) {
|
46
39
|
//if add someone to the group
|
47
40
|
await stack?.track("referral", {
|
48
41
|
points: 10,
|
49
42
|
account: adminAddress?.address ?? "",
|
50
|
-
uniqueId: adminAddress?.username ?? "",
|
51
43
|
});
|
52
44
|
}
|
53
45
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { HandlerContext } from "@xmtp/message-kit";
|
2
2
|
import { vision, textGeneration } from "../lib/openai.js";
|
3
|
+
import { getUserInfo } from "../lib/resolver.js";
|
3
4
|
|
4
5
|
export async function handler(context: HandlerContext) {
|
5
6
|
if (!process?.env?.OPEN_AI_API_KEY) {
|
@@ -8,7 +9,7 @@ export async function handler(context: HandlerContext) {
|
|
8
9
|
}
|
9
10
|
const {
|
10
11
|
members,
|
11
|
-
|
12
|
+
skills,
|
12
13
|
message: {
|
13
14
|
typeId,
|
14
15
|
content: { attachment },
|
@@ -16,8 +17,12 @@ export async function handler(context: HandlerContext) {
|
|
16
17
|
},
|
17
18
|
} = context;
|
18
19
|
|
20
|
+
if (!members) {
|
21
|
+
return;
|
22
|
+
}
|
23
|
+
let senderInfo = await getUserInfo(sender.address);
|
19
24
|
if (attachment && typeId === "remoteStaticAttachment") {
|
20
|
-
const { data
|
25
|
+
const { data } = attachment;
|
21
26
|
const response = await vision(
|
22
27
|
data,
|
23
28
|
"This image is the bill of a restaurant dinner. Return the total. If you can't find the total, return 'undefined'.",
|
@@ -31,9 +36,6 @@ export async function handler(context: HandlerContext) {
|
|
31
36
|
}
|
32
37
|
if (response) {
|
33
38
|
const prompt = `You a split wise agent that splits the bill between the members of this group except for the sender and bot.\n
|
34
|
-
These are the users of the group: ${JSON.stringify(members?.map((member) => ({ ...member, username: `@${member.username}` })))}\n
|
35
|
-
This group app has many commands available: ${JSON.stringify(commands)}\n
|
36
|
-
|
37
39
|
|
38
40
|
## Instructions:
|
39
41
|
When you receive the totals you should split the bill between the members of the group and send to each one a transaction frame
|
@@ -44,18 +46,23 @@ export async function handler(context: HandlerContext) {
|
|
44
46
|
Example:
|
45
47
|
[
|
46
48
|
"This are the details: Total: $49.52. Tip (20%): $9.90",
|
47
|
-
"All users owe X USDC to @${
|
48
|
-
"/send @${
|
49
|
+
"All users owe X USDC to @${senderInfo?.converseUsername}. Pay here:",
|
50
|
+
"/send @${senderInfo?.converseUsername} $9.90"
|
49
51
|
]
|
50
52
|
`;
|
51
53
|
|
52
54
|
//I want the reply to be an array of messages so the bot feels like is sending multuple ones
|
53
|
-
const { reply } = await textGeneration(
|
55
|
+
const { reply } = await textGeneration(
|
56
|
+
sender.address,
|
57
|
+
response,
|
58
|
+
prompt,
|
59
|
+
true,
|
60
|
+
);
|
54
61
|
let splitMessages = JSON.parse(reply);
|
55
62
|
for (const message of splitMessages) {
|
56
63
|
let msg = message as string;
|
57
|
-
if (msg.startsWith("/")) await context.
|
58
|
-
else await context.
|
64
|
+
if (msg.startsWith("/")) await context.skill(msg);
|
65
|
+
else await context.send(msg);
|
59
66
|
}
|
60
67
|
}
|
61
68
|
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import { HandlerContext,
|
1
|
+
import { HandlerContext, AbstractedMember } from "@xmtp/message-kit";
|
2
|
+
import { getUserInfo } from "../lib/resolver.js";
|
2
3
|
|
3
4
|
export async function handler(context: HandlerContext) {
|
4
5
|
const {
|
@@ -6,16 +7,15 @@ export async function handler(context: HandlerContext) {
|
|
6
7
|
getMessageById,
|
7
8
|
message: { content, sender, typeId },
|
8
9
|
} = context;
|
10
|
+
console.log(sender);
|
9
11
|
const msg = await getMessageById(content.reference);
|
10
12
|
const replyReceiver = members?.find(
|
11
13
|
(member) => member.inboxId === msg?.senderInboxId,
|
12
14
|
);
|
13
15
|
let amount: number = 0,
|
14
|
-
receivers:
|
16
|
+
receivers: AbstractedMember[] = [];
|
15
17
|
// Handle different types of messages
|
16
18
|
if (typeId === "reply" && replyReceiver) {
|
17
|
-
// Process reply messages/
|
18
|
-
//ha
|
19
19
|
const { content: reply } = content;
|
20
20
|
|
21
21
|
if (reply.includes("degen")) {
|
@@ -31,18 +31,22 @@ export async function handler(context: HandlerContext) {
|
|
31
31
|
// Process text commands starting with "/tip"
|
32
32
|
const {
|
33
33
|
params: { amount: extractedAmount, username },
|
34
|
-
content: text,
|
35
34
|
} = content;
|
36
35
|
amount = extractedAmount || 10; // Default amount if not specified
|
37
|
-
|
36
|
+
|
37
|
+
receivers = await Promise.all(
|
38
|
+
username.map((username: string) => getUserInfo(username)),
|
39
|
+
);
|
38
40
|
}
|
39
41
|
}
|
40
42
|
if (!sender || receivers.length === 0 || amount === 0) {
|
41
43
|
context.reply("Sender or receiver or amount not found.");
|
42
44
|
return;
|
43
45
|
}
|
46
|
+
console.log(receivers);
|
44
47
|
const receiverAddresses = receivers.map((receiver) => receiver.address);
|
45
48
|
// Process sending tokens to each receiver
|
49
|
+
|
46
50
|
context.sendTo(
|
47
51
|
`You received ${amount} tokens from ${sender.address}.`,
|
48
52
|
receiverAddresses,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { HandlerContext } from "@xmtp/message-kit";
|
2
|
+
import { getUserInfo } from "../lib/resolver.js";
|
2
3
|
|
3
4
|
// Main handler function for processing commands
|
4
5
|
export async function handler(context: HandlerContext) {
|
@@ -13,20 +14,17 @@ export async function handler(context: HandlerContext) {
|
|
13
14
|
case "send":
|
14
15
|
// Destructure and validate parameters for the send command
|
15
16
|
const { amount: amountSend, token: tokenSend, username } = params; // [!code hl] // [!code focus]
|
16
|
-
|
17
|
-
if (!amountSend || !tokenSend || !
|
17
|
+
let senderInfo = await getUserInfo(username);
|
18
|
+
if (!amountSend || !tokenSend || !senderInfo) {
|
18
19
|
context.reply(
|
19
20
|
"Missing required parameters. Please provide amount, token, and username.",
|
20
21
|
);
|
21
22
|
return;
|
22
23
|
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
receiver: username[0]?.address,
|
28
|
-
});
|
29
|
-
context.reply(`${url_send}`);
|
24
|
+
let name = senderInfo.converseUsername || senderInfo.address;
|
25
|
+
|
26
|
+
let sendUrl = `${baseUrl}/?transaction_type=send&amount=${amountSend}&token=${tokenSend}&receiver=${senderInfo.address}`;
|
27
|
+
context.send(`${sendUrl}`);
|
30
28
|
break;
|
31
29
|
case "swap":
|
32
30
|
// Destructure and validate parameters for the swap command
|
@@ -38,13 +36,9 @@ export async function handler(context: HandlerContext) {
|
|
38
36
|
);
|
39
37
|
return;
|
40
38
|
}
|
41
|
-
|
42
|
-
let
|
43
|
-
|
44
|
-
token_from,
|
45
|
-
token_to,
|
46
|
-
});
|
47
|
-
context.reply(`${url_swap}`);
|
39
|
+
|
40
|
+
let swapUrl = `${baseUrl}/?transaction_type=swap&token_from=${token_from}&token_to=${token_to}&amount=${amount}`;
|
41
|
+
context.send(`${swapUrl}`);
|
48
42
|
break;
|
49
43
|
case "show": // [!code hl] // [!code focus]
|
50
44
|
// Show the base URL without the transaction path
|
@@ -55,26 +49,3 @@ export async function handler(context: HandlerContext) {
|
|
55
49
|
context.reply("Unknown command. Use help to see all available commands.");
|
56
50
|
}
|
57
51
|
}
|
58
|
-
|
59
|
-
// Function to generate a URL with query parameters for transactions
|
60
|
-
function generateFrameURL(
|
61
|
-
baseUrl: string,
|
62
|
-
transaction_type: string,
|
63
|
-
params: { [key: string]: string | number | string[] | undefined },
|
64
|
-
) {
|
65
|
-
// Filter out undefined parameters
|
66
|
-
let filteredParams: {
|
67
|
-
[key: string]: string | number | string[] | undefined;
|
68
|
-
} = {};
|
69
|
-
|
70
|
-
for (const key in params) {
|
71
|
-
if (params[key] !== undefined) {
|
72
|
-
filteredParams[key] = params[key];
|
73
|
-
}
|
74
|
-
}
|
75
|
-
let queryParams = new URLSearchParams({
|
76
|
-
transaction_type,
|
77
|
-
...filteredParams,
|
78
|
-
}).toString();
|
79
|
-
return `${baseUrl}?${queryParams}`;
|
80
|
-
}
|
@@ -1,22 +1,26 @@
|
|
1
1
|
import { run, HandlerContext } from "@xmtp/message-kit";
|
2
|
-
import { handler as tipping } from "./handler/tipping.js";
|
3
|
-
import { handler as agent } from "./handler/agent.js";
|
4
2
|
import { handler as splitpayment } from "./handler/splitpayment.js";
|
5
3
|
|
6
4
|
// Main function to run the app
|
7
|
-
run(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
5
|
+
run(
|
6
|
+
async (context: HandlerContext) => {
|
7
|
+
const {
|
8
|
+
message: { typeId },
|
9
|
+
} = context;
|
10
|
+
switch (typeId) {
|
11
|
+
case "reply":
|
12
|
+
handleReply(context);
|
13
|
+
break;
|
14
|
+
case "remoteStaticAttachment":
|
15
|
+
handleAttachment(context);
|
16
|
+
break;
|
17
|
+
}
|
18
|
+
if (!context.group) {
|
19
|
+
context.send("This is a group bot, add this address to a group");
|
20
|
+
}
|
21
|
+
},
|
22
|
+
{ attachments: true },
|
23
|
+
);
|
20
24
|
async function handleReply(context: HandlerContext) {
|
21
25
|
const {
|
22
26
|
v2client,
|
@@ -32,7 +36,7 @@ async function handleReply(context: HandlerContext) {
|
|
32
36
|
version,
|
33
37
|
v2client.address,
|
34
38
|
);
|
35
|
-
//await context.
|
39
|
+
//await context.skill(chain);
|
36
40
|
}
|
37
41
|
|
38
42
|
// Handle attachment messages
|
@@ -41,12 +45,12 @@ async function handleAttachment(context: HandlerContext) {
|
|
41
45
|
}
|
42
46
|
|
43
47
|
export async function helpHandler(context: HandlerContext) {
|
44
|
-
const {
|
48
|
+
const { skills } = context;
|
45
49
|
const intro =
|
46
50
|
"Available experiences:\n" +
|
47
|
-
|
48
|
-
|
49
|
-
.map((
|
51
|
+
skills
|
52
|
+
?.flatMap((app) => app.skills)
|
53
|
+
.map((skill) => `${skill.command} - ${skill.description}`)
|
50
54
|
.join("\n") +
|
51
55
|
"\nUse these commands to interact with specific apps.";
|
52
56
|
context.send(intro);
|