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 CHANGED
@@ -19,16 +19,16 @@ program
19
19
  .name("byob")
20
20
  .description("CLI to initialize projects")
21
21
  .action(async () => {
22
- log.message(`\x1b[38;2;250;105;119m\
23
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
24
-
25
- ███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗██╗ ██╗██╗████████╗
26
- ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██║ ██╔╝██║╚══██╔══╝
27
- ██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ █████╔╝ ██║ ██║
28
- ██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ██╔═██╗ ██║ ██║
29
- ██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗██║ ██╗██║ ██║
30
- ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
31
- Powered by XMTP \x1b[0m`);
22
+ const coolLogo = `\x1b[38;2;250;105;119m\
23
+
24
+ ███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗██╗ ██╗██╗████████╗
25
+ ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝██║ ██╔╝██║╚══██╔══╝
26
+ ██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ █████╔╝ ██║ ██║
27
+ ██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ██╔═██╗ ██║ ██║
28
+ ██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗██║ ██╗██║ ██║
29
+ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
30
+ Powered by XMTP \x1b[0m`;
31
+ console.log(coolLogo);
32
32
 
33
33
  const { templateType, displayName, destDir } = await gatherProjectInfo();
34
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-message-kit",
3
- "version": "1.0.16",
3
+ "version": "1.0.19",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -1,52 +1,42 @@
1
1
  import { HandlerContext } from "@xmtp/message-kit";
2
- import { Client } from "@xmtp/xmtp-js";
3
- import { getUserInfo, getInfoCache, isOnXMTP } from "../lib/resolver.js";
4
- import { textGeneration, responseParser } from "../lib/openai.js";
2
+ import { getUserInfo, clearInfoCache, isOnXMTP } from "../lib/resolver.js";
3
+ import { textGeneration } from "../lib/openai.js";
4
+ import { processResponseWithSkill } from "../lib/openai.js";
5
+ import { isAddress } from "viem";
5
6
  import { ens_agent_prompt } from "../prompt.js";
6
- import type {
7
- ensDomain,
8
- converseUsername,
9
- tipAddress,
10
- chatHistories,
11
- tipDomain,
12
- } from "../lib/types.js";
13
- import { frameUrl, ensUrl, baseTxUrl, InfoCache } from "../lib/types.js";
14
-
15
- let tipAddress: tipAddress = {};
16
- let tipDomain: tipDomain = {};
17
- let ensDomain: ensDomain = {};
18
- let infoCache: InfoCache = {};
19
- let converseUsername: converseUsername = {};
20
- let chatHistories: chatHistories = {};
21
-
22
- // URL for the send transaction
7
+ import { clearChatHistories } from "../lib/openai.js";
8
+
9
+ export const frameUrl = "https://ens.steer.fun/";
10
+ export const ensUrl = "https://app.ens.domains/";
11
+ export const baseTxUrl = "https://base-tx-frame.vercel.app";
12
+
23
13
  export async function handleEns(context: HandlerContext) {
24
14
  const {
25
15
  message: {
26
16
  content: { command, params, sender },
27
17
  },
28
18
  } = context;
29
-
30
- if (command == "renew") {
19
+ if (command == "reset") {
20
+ clear();
21
+ return { code: 200, message: "Conversation reset." };
22
+ } else if (command == "renew") {
31
23
  // Destructure and validate parameters for the ens command
32
24
  const { domain } = params;
33
25
  // Check if the user holds the domain
34
26
  if (!domain) {
35
- context.reply("Missing required parameters. Please provide domain.");
36
- return;
27
+ return {
28
+ code: 400,
29
+ message: "Missing required parameters. Please provide domain.",
30
+ };
37
31
  }
38
32
 
39
- const { infoCache: retrievedInfoCache } = await getInfoCache(
40
- domain,
41
- infoCache,
42
- );
43
- infoCache = retrievedInfoCache;
44
- let data = infoCache[domain].info;
33
+ const data = await getUserInfo(domain);
45
34
 
46
- if (data?.address !== sender?.address) {
35
+ if (!data || data?.address !== sender?.address) {
47
36
  return {
48
37
  code: 403,
49
- message: "You do not hold this domain. Only the owner can renew it.",
38
+ message:
39
+ "Looks like this domain is not registered to you. Only the owner can renew it.",
50
40
  };
51
41
  }
52
42
 
@@ -69,22 +59,23 @@ export async function handleEns(context: HandlerContext) {
69
59
  } else if (command == "info") {
70
60
  const { domain } = params;
71
61
 
72
- const { infoCache: retrievedInfoCache } = await getInfoCache(
73
- domain,
74
- infoCache,
75
- );
76
- infoCache = retrievedInfoCache;
77
- let data = infoCache[domain].info;
62
+ const data = await getUserInfo(domain);
63
+ if (!data) {
64
+ return {
65
+ code: 404,
66
+ message: "Domain not found.",
67
+ };
68
+ }
78
69
 
79
70
  const formattedData = {
80
71
  Address: data?.address,
81
- "Avatar URL": data?.avatar_url,
82
- Description: data?.description,
83
- ENS: data?.ens,
84
- "Primary ENS": data?.ens_primary,
85
- GitHub: data?.github,
86
- Resolver: data?.resolverAddress,
87
- Twitter: data?.twitter,
72
+ "Avatar URL": data?.ensInfo?.avatar,
73
+ Description: data?.ensInfo?.description,
74
+ ENS: data?.ensDomain,
75
+ "Primary ENS": data?.ensInfo?.ens_primary,
76
+ GitHub: data?.ensInfo?.github,
77
+ Resolver: data?.ensInfo?.resolverAddress,
78
+ Twitter: data?.ensInfo?.twitter,
88
79
  URL: `${ensUrl}${domain}`,
89
80
  };
90
81
 
@@ -96,23 +87,20 @@ export async function handleEns(context: HandlerContext) {
96
87
  }
97
88
  message += `\n\nWould you like to tip the domain owner for getting there first 🤣?`;
98
89
  message = message.trim();
99
- if (await isOnXMTP(context.v2client, data?.ens, data?.address)) {
100
- context.send(
90
+ if (
91
+ await isOnXMTP(
92
+ context.v2client,
93
+ data?.ensInfo?.ens,
94
+ data?.ensInfo?.address,
95
+ )
96
+ ) {
97
+ await context.send(
101
98
  `Ah, this domains is in XMTP, you can message it directly: https://converse.xyz/dm/${domain}`,
102
99
  );
103
100
  }
104
101
  return { code: 200, message };
105
102
  } else if (command == "check") {
106
- console.log(params);
107
- const { domain, cool_alternatives } = params;
108
-
109
- const cool_alternativesFormat = cool_alternatives
110
- ?.split(",")
111
- .map(
112
- (alternative: string, index: number) =>
113
- `${index + 1}. ${alternative} ✨`,
114
- )
115
- .join("\n");
103
+ const { domain } = params;
116
104
 
117
105
  if (!domain) {
118
106
  return {
@@ -120,82 +108,46 @@ export async function handleEns(context: HandlerContext) {
120
108
  message: "Please provide a domain name to check.",
121
109
  };
122
110
  }
123
- const { infoCache: retrievedInfoCache } = await getInfoCache(
124
- domain,
125
- infoCache,
126
- );
127
- infoCache = retrievedInfoCache;
128
- let data = infoCache?.[domain]?.info;
111
+
112
+ const data = await getUserInfo(domain);
129
113
  if (!data?.address) {
130
- let message = `Looks like ${domain} is available! Do you want to register it? ${ensUrl}${domain}`;
114
+ let message = `Looks like ${domain} is available! Here you can register it: ${ensUrl}${domain} or would you like to see some cool alternatives?`;
131
115
  return {
132
116
  code: 200,
133
117
  message,
134
118
  };
135
119
  } else {
136
- let message = `Looks like ${domain} is already registered! What about these cool alternatives?\n\n${cool_alternativesFormat}`;
120
+ let message = `Looks like ${domain} is already registered!`;
121
+ await context.skill("/cool " + domain);
137
122
  return {
138
123
  code: 404,
139
124
  message,
140
125
  };
141
126
  }
142
127
  } else if (command == "tip") {
143
- // Destructure and validate parameters for the send command
144
128
  const { address } = params;
145
-
146
- const { infoCache: retrievedInfoCache } = await getInfoCache(
147
- address,
148
- infoCache,
149
- );
150
- infoCache = retrievedInfoCache;
151
- let data = infoCache[address].info;
152
-
153
- tipAddress[sender.address] = data?.address;
154
- tipDomain[sender.address] = data?.ens;
155
-
156
- if (!address || !tipAddress[sender.address]) {
157
- context.reply("Missing required parameters. Please provide address.");
158
- return;
129
+ if (!address) {
130
+ return {
131
+ code: 400,
132
+ message: "Please provide an address to tip.",
133
+ };
159
134
  }
160
- let txUrl = `${baseTxUrl}/transaction/?transaction_type=send&buttonName=Tip%20${tipDomain[sender.address]}&amount=1&token=USDC&receiver=${tipAddress[sender.address]}`;
161
- // Generate URL for the send transaction
162
- context.send(`Here is the url to send the tip:\n${txUrl}`);
135
+ const data = await getUserInfo(address);
136
+ let txUrl = `${baseTxUrl}/transaction/?transaction_type=send&buttonName=Tip%20${data?.ensDomain ?? ""}&amount=1&token=USDC&receiver=${
137
+ isAddress(address) ? address : data?.address
138
+ }`;
139
+ console.log(txUrl);
140
+ return {
141
+ code: 200,
142
+ message: txUrl,
143
+ };
163
144
  } else if (command == "cool") {
164
- return;
165
- }
166
- }
167
-
168
- export async function clearChatHistory() {
169
- chatHistories = {};
170
- }
171
-
172
- async function processResponseWithIntent(
173
- reply: string,
174
- context: any,
175
- senderAddress: string,
176
- ) {
177
- let messages = reply
178
- .split("\n")
179
- .map((message: string) => responseParser(message))
180
- .filter((message): message is string => message.length > 0);
181
-
182
- console.log(messages);
183
- for (const message of messages) {
184
- if (message.startsWith("/")) {
185
- const response = await context.intent(message);
186
- if (response && response.message) {
187
- let msg = responseParser(response.message);
188
-
189
- chatHistories[senderAddress].push({
190
- role: "system",
191
- content: msg,
192
- });
193
-
194
- await context.send(response.message);
195
- }
196
- } else {
197
- await context.send(message);
198
- }
145
+ const { domain } = params;
146
+ //What about these cool alternatives?\
147
+ return {
148
+ code: 200,
149
+ message: `${generateCoolAlternatives(domain)}`,
150
+ };
199
151
  }
200
152
  }
201
153
 
@@ -215,33 +167,45 @@ export async function ensAgent(context: HandlerContext) {
215
167
 
216
168
  try {
217
169
  let userPrompt = params?.prompt ?? content;
218
- const { converseUsername: newConverseUsername, ensDomain: newEnsDomain } =
219
- await getUserInfo(
220
- sender.address,
221
- ensDomain[sender.address],
222
- converseUsername[sender.address],
223
- );
224
-
225
- ensDomain[sender.address] = newEnsDomain;
226
- converseUsername[sender.address] = newConverseUsername;
227
- let txUrl = `${baseTxUrl}/transaction/?transaction_type=send&buttonName=Tip%20${tipDomain[sender.address]}&amount=1&token=USDC&receiver=${tipAddress[sender.address]}`;
228
-
229
- const { reply, history } = await textGeneration(
170
+ const userInfo = await getUserInfo(sender.address);
171
+ if (!userInfo) {
172
+ console.log("User info not found");
173
+ return;
174
+ }
175
+ const { reply } = await textGeneration(
176
+ sender.address,
230
177
  userPrompt,
231
- await ens_agent_prompt(
232
- sender.address,
233
- ensDomain[sender.address],
234
- converseUsername[sender.address],
235
- tipAddress[sender.address],
236
- txUrl,
237
- ),
238
- chatHistories[sender.address],
178
+ await ens_agent_prompt(userInfo),
239
179
  );
240
- if (!group) chatHistories[sender.address] = history; // Update chat history for the user
241
-
242
- await processResponseWithIntent(reply, context, sender.address);
180
+ await processResponseWithSkill(sender.address, reply, context);
243
181
  } catch (error) {
244
182
  console.error("Error during OpenAI call:", error);
245
183
  await context.send("An error occurred while processing your request.");
246
184
  }
247
185
  }
186
+
187
+ export const generateCoolAlternatives = (domain: string) => {
188
+ const suffixes = ["lfg", "cool", "degen", "moon", "base", "gm"];
189
+ const alternatives = [];
190
+ for (let i = 0; i < 5; i++) {
191
+ const randomPosition = Math.random() < 0.5;
192
+ const baseDomain = domain.replace(/\.eth$/, ""); // Remove any existing .eth suffix
193
+ alternatives.push(
194
+ randomPosition
195
+ ? `${suffixes[i]}${baseDomain}.eth`
196
+ : `${baseDomain}${suffixes[i]}.eth`,
197
+ );
198
+ }
199
+
200
+ const cool_alternativesFormat = alternatives
201
+ .map(
202
+ (alternative: string, index: number) => `${index + 1}. ${alternative} ✨`,
203
+ )
204
+ .join("\n");
205
+ return cool_alternativesFormat;
206
+ };
207
+
208
+ export async function clear() {
209
+ clearChatHistories();
210
+ clearInfoCache();
211
+ }
@@ -2,5 +2,9 @@ import { run, HandlerContext } from "@xmtp/message-kit";
2
2
  import { ensAgent } from "./handler/ens.js";
3
3
 
4
4
  run(async (context: HandlerContext) => {
5
- await ensAgent(context);
5
+ /*All the commands are handled through the commands file*/
6
+ /* If its just text, it will be handled by the ensAgent*/
7
+ /* If its a group message, it will be handled by the groupAgent*/
8
+
9
+ ensAgent(context);
6
10
  });
@@ -6,12 +6,16 @@ const openai = new OpenAI({
6
6
  apiKey: process.env.OPEN_AI_API_KEY,
7
7
  });
8
8
 
9
+ export type ChatHistoryEntry = { role: string; content: string };
10
+ export type ChatHistories = Record<string, ChatHistoryEntry[]>;
11
+
12
+ let chatHistories: ChatHistories = {};
9
13
  export async function textGeneration(
14
+ address: string,
10
15
  userPrompt: string,
11
16
  systemPrompt: string,
12
- chatHistory?: any[],
13
17
  ) {
14
- let messages = chatHistory ? [...chatHistory] : []; // Start with existing chat history
18
+ let messages = chatHistories[address] || [];
15
19
  if (messages.length === 0) {
16
20
  messages.push({
17
21
  role: "system",
@@ -33,7 +37,8 @@ export async function textGeneration(
33
37
  content: reply || "No response from OpenAI.",
34
38
  });
35
39
  const cleanedReply = responseParser(reply as string);
36
-
40
+ chatHistories[address] = messages;
41
+ console.log("messages.length", messages.length);
37
42
  return { reply: cleanedReply, history: messages };
38
43
  } catch (error) {
39
44
  console.error("Failed to fetch from OpenAI:", error);
@@ -78,6 +83,38 @@ export async function vision(imageData: Uint8Array, systemPrompt: string) {
78
83
  }
79
84
  }
80
85
 
86
+ export async function processResponseWithSkill(
87
+ address: string,
88
+ reply: string,
89
+ context: any,
90
+ ) {
91
+ let messages = reply
92
+ .split("\n")
93
+ .map((message: string) => responseParser(message))
94
+ .filter((message): message is string => message.length > 0);
95
+
96
+ console.log(messages);
97
+ for (const message of messages) {
98
+ if (message.startsWith("/")) {
99
+ const response = await context.skill(message);
100
+ if (response && response.message) {
101
+ let msg = responseParser(response.message);
102
+
103
+ if (!chatHistories[address]) {
104
+ chatHistories[address] = [];
105
+ }
106
+ chatHistories[address].push({
107
+ role: "system",
108
+ content: msg,
109
+ });
110
+
111
+ await context.send(response.message);
112
+ }
113
+ } else {
114
+ await context.send(message);
115
+ }
116
+ }
117
+ }
81
118
  export function responseParser(message: string) {
82
119
  let trimmedMessage = message;
83
120
  // Remove bold and underline markdown
@@ -94,32 +131,10 @@ export function responseParser(message: string) {
94
131
  trimmedMessage = trimmedMessage?.replace(/^\s+|\s+$/g, "");
95
132
  // Remove any remaining leading or trailing whitespace
96
133
  trimmedMessage = trimmedMessage.trim();
97
- return trimmedMessage;
98
- }
99
-
100
- // UNTESTED, recursive response parser
101
- export function responseParser2(message: string | string[]): string | string[] {
102
- // If message is an array, process each item individually
103
- if (Array.isArray(message)) {
104
- return message
105
- .map((item) => responseParser(item))
106
- .flat() // Flatten nested arrays
107
- .filter((item: string) => item.length > 0)
108
- .filter((item: string) => item !== "`");
109
- }
110
- let trimmedMessage = message;
111
- // Remove bold and underline markdown
112
- trimmedMessage = trimmedMessage?.replace(/(\*\*|__)(.*?)\1/g, "$2");
113
- // Remove markdown links, keeping only the URL
114
- trimmedMessage = trimmedMessage?.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$2");
115
- // Remove markdown headers
116
- trimmedMessage = trimmedMessage?.replace(/^#+\s*(.*)$/gm, "$1");
117
- // Remove inline code formatting
118
- trimmedMessage = trimmedMessage?.replace(/(`{1,3})(.*?)\1/g, "$2");
119
- // Remove leading and trailing whitespace
120
- trimmedMessage = trimmedMessage?.replace(/`/g, ""); // Remove single backticks
121
- // Remove any remaining leading or trailing whitespace
122
- trimmedMessage = trimmedMessage?.trim();
123
134
 
124
135
  return trimmedMessage;
125
136
  }
137
+
138
+ export const clearChatHistories = () => {
139
+ chatHistories = {};
140
+ };
@@ -1,76 +1,120 @@
1
- import type { EnsData } from "./types.js";
2
- import { endpointURL } from "./types.js";
3
1
  import { Client } from "@xmtp/xmtp-js";
4
- import { InfoCache } from "./types.js";
2
+ import { isAddress } from "viem";
5
3
 
6
- export async function getUserInfo(
7
- address: string,
8
- ensDomain: string | undefined,
9
- converseUsername: string | undefined,
10
- ) {
11
- if (!ensDomain) {
12
- const response = await fetch(`https://ensdata.net/${address}`);
13
- const data: EnsData = (await response.json()) as EnsData;
14
- ensDomain = data?.ens;
4
+ export const converseEndpointURL =
5
+ "https://converse-website-git-endpoit-ephemerahq.vercel.app";
6
+ //export const converseEndpointURL = "http://localhost:3000";
7
+
8
+ export type InfoCache = Map<string, UserInfo>;
9
+ export type ConverseProfile = {
10
+ address: string | null;
11
+ onXmtp: boolean;
12
+ avatar: string | null;
13
+ formattedName: string | null;
14
+ name: string | null;
15
+ };
16
+ export type UserInfo = {
17
+ ensDomain?: string | undefined;
18
+ address?: string | undefined;
19
+ converseUsername?: string | undefined;
20
+ ensInfo?: EnsData | undefined;
21
+ avatar?: string | undefined;
22
+ };
23
+ export interface EnsData {
24
+ address?: string;
25
+ avatar?: string;
26
+ avatar_small?: string;
27
+ converse?: string;
28
+ avatar_url?: string;
29
+ contentHash?: string;
30
+ description?: string;
31
+ ens?: string;
32
+ ens_primary?: string;
33
+ github?: string;
34
+ resolverAddress?: string;
35
+ twitter?: string;
36
+ url?: string;
37
+ wallets?: {
38
+ eth?: string;
39
+ };
40
+ }
41
+
42
+ let infoCache: InfoCache = new Map();
43
+
44
+ export const clearInfoCache = () => {
45
+ infoCache.clear();
46
+ };
47
+ export const getUserInfo = async (
48
+ key: string,
49
+ clientAddress?: string,
50
+ ): Promise<UserInfo | null> => {
51
+ let data: UserInfo = infoCache.get(key) || {
52
+ ensDomain: undefined,
53
+ address: undefined,
54
+ converseUsername: undefined,
55
+ ensInfo: undefined,
56
+ };
57
+ //console.log("Getting user info", key, clientAddress);
58
+ if (isAddress(clientAddress || "")) {
59
+ data.address = clientAddress;
60
+ } else if (isAddress(key || "")) {
61
+ data.address = key;
62
+ } else if (key.includes(".eth")) {
63
+ data.ensDomain = key;
64
+ } else if (key == "@user" || key == "@me" || key == "@bot") {
65
+ data.address = clientAddress;
66
+ data.ensDomain = key.replace("@", "") + ".eth";
67
+ data.converseUsername = key.replace("@", "");
68
+ } else if (key == "@alix") {
69
+ data.address = "0x3a044b218BaE80E5b9E16609443A192129A67BeA";
70
+ data.converseUsername = "alix";
71
+ } else if (key == "@bo") {
72
+ data.address = "0xbc3246461ab5e1682baE48fa95172CDf0689201a";
73
+ data.converseUsername = "bo";
74
+ } else {
75
+ data.converseUsername = key;
76
+ }
77
+
78
+ let keyToUse = data.address || data.ensDomain || data.converseUsername;
79
+ 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);
15
85
  }
16
- if (!converseUsername) {
17
- const response = await fetch(`${endpointURL}/profile/${address}`, {
86
+
87
+ if (keyToUse?.includes(".eth")) {
88
+ const response = await fetch(`https://ensdata.net/${keyToUse}`);
89
+ const ensData: EnsData = (await response.json()) as EnsData;
90
+ //console.log("Ens data", ensData);
91
+ if (ensData) {
92
+ data.ensInfo = ensData;
93
+ data.ensDomain = ensData?.ens;
94
+ data.address = ensData?.address;
95
+ }
96
+ } else if (keyToUse) {
97
+ keyToUse = keyToUse.replace("@", "");
98
+ const response = await fetch(`${converseEndpointURL}/profile/${keyToUse}`, {
18
99
  method: "POST",
19
100
  headers: {
20
101
  "Content-Type": "application/json",
21
102
  Accept: "application/json",
22
103
  },
23
- body: JSON.stringify({ address: address }),
104
+ body: JSON.stringify({
105
+ peer: keyToUse,
106
+ }),
24
107
  });
25
- const data = (await response.json()) as { name: string };
26
- converseUsername = data?.name;
27
- converseUsername = converseUsername.replace(".converse.xyz", "");
108
+ const converseData = (await response.json()) as ConverseProfile;
109
+ if (process.env.MSG_LOG)
110
+ console.log("Converse data", keyToUse, converseData);
111
+ data.converseUsername =
112
+ converseData?.formattedName || converseData?.name || undefined;
113
+ data.address = converseData?.address || undefined;
114
+ data.avatar = converseData?.avatar || undefined;
28
115
  }
29
- console.log("User info fetched for", {
30
- address,
31
- converseUsername,
32
- ensDomain,
33
- });
34
- return { converseUsername: converseUsername, ensDomain: ensDomain };
35
- }
36
-
37
- export const getInfoCache = async (
38
- key: string, // This can be either domain or address
39
- infoCache: InfoCache,
40
- ): Promise<{ domain: string; info: EnsData; infoCache: InfoCache }> => {
41
- if (infoCache[key]) {
42
- let data = {
43
- domain: key,
44
- info: infoCache[key].info,
45
- infoCache: infoCache,
46
- };
47
- return data;
48
- }
49
- try {
50
- const response = await fetch(`https://ensdata.net/${key}`);
51
- const data: EnsData = (await response.json()) as EnsData;
52
-
53
- // Assuming the data contains both domain and address
54
- const domain = data?.ens;
55
- const address = data?.address;
56
-
57
- // Store data in cache by both domain and address
58
- if (domain) infoCache[domain as string] = { info: data };
59
- if (address) infoCache[address as string] = { info: data };
60
-
61
- return { info: data, infoCache: infoCache, domain: domain as string };
62
- } catch (error) {
63
- console.error(error);
64
- return { info: {}, infoCache: infoCache, domain: "" };
65
- }
66
- };
67
- export const generateCoolAlternatives = (domain: string) => {
68
- const suffixes = ["lfg", "cool", "degen", "moon", "base", "gm"];
69
- const alternatives = suffixes.map((suffix) => {
70
- const randomPosition = Math.random() < 0.5;
71
- return randomPosition ? `${suffix}${domain}.eth` : `${domain}${suffix}.eth`;
72
- });
73
- return alternatives.join(",");
116
+ if (data.address) infoCache.set(data.address, data);
117
+ return data;
74
118
  };
75
119
  export const isOnXMTP = async (
76
120
  client: Client,