create-message-kit 1.0.16 → 1.0.19

Sign up to get free protection for your applications and to get access to all the features.
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,