create-message-kit 1.0.21 → 1.1.5-beta.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
- import { Client } from "@xmtp/xmtp-js";
1
+ import type { Client } from "@xmtp/xmtp-js";
2
2
  import { isAddress } from "viem";
3
+ import type { HandlerContext } from "@xmtp/message-kit";
3
4
 
4
5
  export const converseEndpointURL =
5
6
  "https://converse-website-git-endpoit-ephemerahq.vercel.app";
@@ -16,6 +17,7 @@ export type ConverseProfile = {
16
17
  export type UserInfo = {
17
18
  ensDomain?: string | undefined;
18
19
  address?: string | undefined;
20
+ preferredName: string | undefined;
19
21
  converseUsername?: string | undefined;
20
22
  ensInfo?: EnsData | undefined;
21
23
  avatar?: string | undefined;
@@ -47,19 +49,20 @@ export const clearInfoCache = () => {
47
49
  export const getUserInfo = async (
48
50
  key: string,
49
51
  clientAddress?: string,
52
+ context?: HandlerContext,
50
53
  ): Promise<UserInfo | null> => {
51
54
  let data: UserInfo = infoCache.get(key) || {
52
55
  ensDomain: undefined,
53
56
  address: undefined,
54
57
  converseUsername: undefined,
55
58
  ensInfo: undefined,
59
+ preferredName: undefined,
56
60
  };
57
- //console.log("Getting user info", key, clientAddress);
58
61
  if (isAddress(clientAddress || "")) {
59
62
  data.address = clientAddress;
60
63
  } else if (isAddress(key || "")) {
61
64
  data.address = key;
62
- } else if (key.includes(".eth")) {
65
+ } else if (key?.includes(".eth")) {
63
66
  data.ensDomain = key;
64
67
  } else if (key == "@user" || key == "@me" || key == "@bot") {
65
68
  data.address = clientAddress;
@@ -74,16 +77,15 @@ export const getUserInfo = async (
74
77
  } else {
75
78
  data.converseUsername = key;
76
79
  }
77
-
80
+ data.preferredName = data.ensDomain || data.converseUsername || "Friend";
78
81
  let keyToUse = data.address || data.ensDomain || data.converseUsername;
79
82
  let cacheData = keyToUse && infoCache.get(keyToUse);
80
- if (cacheData) {
81
- //console.log("Getting user info", keyToUse, cacheData);
82
- return cacheData;
83
- } else {
84
- //console.log("Getting user info", keyToUse, data);
85
- }
83
+ //console.log("Getting user info", { cacheData, keyToUse, data });
84
+ if (cacheData) return cacheData;
86
85
 
86
+ context?.send(
87
+ "Hey there! Give me a sec while I fetch info about you first...",
88
+ );
87
89
  if (keyToUse?.includes(".eth")) {
88
90
  const response = await fetch(`https://ensdata.net/${keyToUse}`);
89
91
  const ensData: EnsData = (await response.json()) as EnsData;
@@ -113,6 +115,8 @@ export const getUserInfo = async (
113
115
  data.address = converseData?.address || undefined;
114
116
  data.avatar = converseData?.avatar || undefined;
115
117
  }
118
+
119
+ data.preferredName = data.ensDomain || data.converseUsername || "Friend";
116
120
  if (data.address) infoCache.set(data.address, data);
117
121
  return data;
118
122
  };
@@ -124,3 +128,24 @@ export const isOnXMTP = async (
124
128
  if (domain == "fabri.eth") return false;
125
129
  if (address) return (await client.canMessage([address])).length > 0;
126
130
  };
131
+
132
+ export const PROMPT_USER_CONTENT = (userInfo: UserInfo) => {
133
+ let { address, ensDomain, converseUsername, preferredName } = userInfo;
134
+ let prompt = `
135
+ User context:
136
+ - Start by fetch their domain from or Convese username
137
+ - Call the user by their name or domain, in case they have one
138
+ - Ask for a name (if they don't have one) so you can suggest domains.
139
+ - Users address is: ${address}`;
140
+ if (preferredName) prompt += `\n- Users name is: ${preferredName}`;
141
+ if (ensDomain) prompt += `\n- User ENS domain is: ${ensDomain}`;
142
+ if (converseUsername)
143
+ prompt += `\n- Converse username is: ${converseUsername}`;
144
+
145
+ prompt = prompt.replace("{ADDRESS}", address || "");
146
+ prompt = prompt.replace("{ENS_DOMAIN}", ensDomain || "");
147
+ prompt = prompt.replace("{CONVERSE_USERNAME}", converseUsername || "");
148
+ prompt = prompt.replace("{PREFERRED_NAME}", preferredName || "");
149
+
150
+ return prompt;
151
+ };
@@ -0,0 +1,42 @@
1
+ import "dotenv/config";
2
+
3
+ import OpenAI from "openai";
4
+ const openai = new OpenAI({
5
+ apiKey: process.env.OPEN_AI_API_KEY,
6
+ });
7
+
8
+ export async function vision(imageData: Uint8Array, systemPrompt: string) {
9
+ const base64Image = Buffer.from(imageData).toString("base64");
10
+ const dataUrl = `data:image/jpeg;base64,${base64Image}`;
11
+
12
+ // Create a new thread for each vision request
13
+ const visionMessages = [
14
+ {
15
+ role: "system",
16
+ content: systemPrompt,
17
+ },
18
+ {
19
+ role: "user",
20
+ content: [
21
+ { type: "text", text: systemPrompt },
22
+ {
23
+ type: "image_url",
24
+ image_url: {
25
+ url: dataUrl,
26
+ },
27
+ },
28
+ ],
29
+ },
30
+ ];
31
+
32
+ try {
33
+ const response = await openai.chat.completions.create({
34
+ model: "gpt-4o",
35
+ messages: visionMessages as any,
36
+ });
37
+ return response.choices[0].message.content;
38
+ } catch (error) {
39
+ console.error("Failed to interpret image with OpenAI:", error);
40
+ throw error;
41
+ }
42
+ }
@@ -14,6 +14,7 @@ export const skills: SkillGroup[] = [
14
14
  {
15
15
  command: "/tip [@usernames] [amount] [token]",
16
16
  triggers: ["/tip"],
17
+ examples: ["/tip @vitalik 10 usdc"],
17
18
  description: "Tip users in a specified token.",
18
19
  handler: tipping,
19
20
  params: {
@@ -37,6 +38,7 @@ export const skills: SkillGroup[] = [
37
38
  {
38
39
  command: "/send [amount] [token] [username]",
39
40
  triggers: ["/send"],
41
+ examples: ["/send 10 usdc @vitalik"],
40
42
  description:
41
43
  "Send a specified amount of a cryptocurrency to a destination address.",
42
44
  handler: transaction,
@@ -59,6 +61,7 @@ export const skills: SkillGroup[] = [
59
61
  {
60
62
  command: "/swap [amount] [token_from] [token_to]",
61
63
  triggers: ["/swap"],
64
+ examples: ["/swap 10 usdc eth"],
62
65
  description: "Exchange one type of cryptocurrency for another.",
63
66
  handler: transaction,
64
67
  params: {
@@ -81,6 +84,7 @@ export const skills: SkillGroup[] = [
81
84
  {
82
85
  command: "/show",
83
86
  triggers: ["/show"],
87
+ examples: ["/show"],
84
88
  handler: transaction,
85
89
  description: "Show the whole frame.",
86
90
  params: {},
@@ -113,6 +117,7 @@ export const skills: SkillGroup[] = [
113
117
  {
114
118
  command: "/points",
115
119
  triggers: ["/points"],
120
+ examples: ["/points"],
116
121
  handler: loyalty,
117
122
  description: "Check your points.",
118
123
  params: {},
@@ -134,6 +139,7 @@ export const skills: SkillGroup[] = [
134
139
  {
135
140
  command: "/agent [prompt]",
136
141
  triggers: ["/agent", "@agent", "@bot"],
142
+ examples: ["/agent @vitalik"],
137
143
  handler: agent,
138
144
  description: "Manage agent commands.",
139
145
  params: {
@@ -152,6 +158,7 @@ export const skills: SkillGroup[] = [
152
158
  {
153
159
  command: "/help",
154
160
  triggers: ["/help"],
161
+ examples: ["/help"],
155
162
  handler: helpHandler,
156
163
  description: "Get help with the bot.",
157
164
  params: {},