@hybrd/xmtp 1.2.8 โ†’ 1.3.1

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../scripts/revoke-installations.ts","../src/constants.ts","../src/lib/message-listener.ts","../src/resolver/address-resolver.ts","../src/resolver/basename-resolver.ts","../src/abi/l2_resolver.ts","../src/resolver/ens-resolver.ts","../src/resolver/xmtp-resolver.ts","../src/resolver/resolver.ts","../src/lib/subjects.ts","../src/service-client.ts","../src/index.ts"],"sourcesContent":["import { ReactionCodec } from \"@xmtp/content-type-reaction\"\nimport { ReplyCodec } from \"@xmtp/content-type-reply\"\nimport { TransactionReferenceCodec } from \"@xmtp/content-type-transaction-reference\"\nimport { WalletSendCallsCodec } from \"@xmtp/content-type-wallet-send-calls\"\nimport { Client, IdentifierKind, type Signer, XmtpEnv } from \"@xmtp/node-sdk\"\nimport { getRandomValues } from \"node:crypto\"\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { fromString, toString as uint8arraysToString } from \"uint8arrays\"\nimport { createWalletClient, http, toBytes } from \"viem\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { sepolia } from \"viem/chains\"\nimport { revokeOldInstallations } from \"../scripts/revoke-installations\"\nimport { XmtpClient } from \"./types\"\n\n// ===================================================================\n// Module Setup\n// ===================================================================\n// ES module equivalent of __dirname\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// ===================================================================\n// Type Definitions\n// ===================================================================\ninterface User {\n\tkey: `0x${string}`\n\taccount: ReturnType<typeof privateKeyToAccount>\n\twallet: any // Simplified to avoid deep type instantiation\n}\n\n// ===================================================================\n// User and Signer Creation\n// ===================================================================\nexport const createUser = (key: string): User => {\n\tconst account = privateKeyToAccount(key as `0x${string}`)\n\treturn {\n\t\tkey: key as `0x${string}`,\n\t\taccount,\n\t\twallet: createWalletClient({\n\t\t\taccount,\n\t\t\tchain: sepolia,\n\t\t\ttransport: http()\n\t\t})\n\t}\n}\n\nexport const createSigner = (key: string): Signer => {\n\tif (!key || typeof key !== \"string\") {\n\t\tthrow new Error(\"XMTP wallet key must be a non-empty string\")\n\t}\n\tconst sanitizedKey = key.startsWith(\"0x\") ? key : `0x${key}`\n\tconst user = createUser(sanitizedKey)\n\treturn {\n\t\ttype: \"EOA\",\n\t\tgetIdentifier: () => ({\n\t\t\tidentifierKind: 0 as IdentifierKind.Ethereum, // Use numeric value to avoid ambient const enum issue\n\t\t\tidentifier: user.account.address.toLowerCase()\n\t\t}),\n\t\tsignMessage: async (message: string) => {\n\t\t\tconst signature = await user.wallet.signMessage({\n\t\t\t\tmessage,\n\t\t\t\taccount: user.account\n\t\t\t})\n\t\t\treturn toBytes(signature)\n\t\t}\n\t}\n}\n\n// XMTP XmtpClient setup\n// const xmtpClient: XmtpClient | null = null\n\n// Function to clear XMTP database when hitting installation limits\nasync function clearXMTPDatabase(address: string, env: string) {\n\tconsole.log(\"๐Ÿงน Clearing XMTP database to resolve installation limit...\")\n\n\t// Get the storage directory using the same logic as getDbPath\n\tconst getStorageDirectory = () => {\n\t\tconst customStoragePath = process.env.XMTP_STORAGE_PATH\n\n\t\tif (customStoragePath) {\n\t\t\treturn path.isAbsolute(customStoragePath)\n\t\t\t\t? customStoragePath\n\t\t\t\t: path.resolve(process.cwd(), customStoragePath)\n\t\t}\n\n\t\t// Use existing logic as fallback\n\t\tconst projectRoot =\n\t\t\tprocess.env.PROJECT_ROOT || path.resolve(__dirname, \"../../..\")\n\n\t\treturn path.join(projectRoot, \".data/xmtp\") // Local development\n\t}\n\n\t// Clear local database files\n\tconst dbPattern = `${env}-${address}.db3`\n\tconst storageDir = getStorageDirectory()\n\n\t// Primary storage directory\n\tconst possiblePaths = [\n\t\tstorageDir,\n\t\t// Legacy fallback paths for backward compatibility\n\t\tpath.join(process.cwd(), \".data\", \"xmtp\"),\n\t\tpath.join(process.cwd(), \"..\", \".data\", \"xmtp\"),\n\t\tpath.join(process.cwd(), \"..\", \"..\", \".data\", \"xmtp\")\n\t]\n\n\tfor (const dir of possiblePaths) {\n\t\ttry {\n\t\t\tif (fs.existsSync(dir)) {\n\t\t\t\tconst files = fs.readdirSync(dir)\n\t\t\t\tconst matchingFiles = files.filter(\n\t\t\t\t\t(file) =>\n\t\t\t\t\t\tfile.includes(dbPattern) ||\n\t\t\t\t\t\tfile.includes(address) ||\n\t\t\t\t\t\tfile.includes(`xmtp-${env}-${address}`)\n\t\t\t\t)\n\n\t\t\t\tfor (const file of matchingFiles) {\n\t\t\t\t\tconst fullPath = path.join(dir, file)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfs.unlinkSync(fullPath)\n\t\t\t\t\t\tconsole.log(`โœ… Removed: ${fullPath}`)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.log(`โš ๏ธ Could not remove ${fullPath}:`, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Ignore errors when checking directories\n\t\t}\n\t}\n}\n\nexport async function createXMTPClient(\n\t// signer: Signer,\n\tprivateKey: string,\n\topts?: {\n\t\tpersist?: boolean\n\t\tmaxRetries?: number\n\t\tstoragePath?: string\n\t}\n): Promise<XmtpClient> {\n\tconst { persist = true, maxRetries = 3, storagePath } = opts ?? {}\n\tlet attempt = 0\n\n\t// Extract common variables for error handling\n\t// const actualSigner = signer\n\tconst signer = createSigner(privateKey)\n\n\tif (!signer) {\n\t\tthrow new Error(\n\t\t\t\"No signer provided and XMTP_WALLET_KEY environment variable is not set\"\n\t\t)\n\t}\n\n\tconst { XMTP_ENCRYPTION_KEY, XMTP_ENV } = process.env\n\n\t// Get the wallet address to use the correct database\n\tconst identifier = await signer.getIdentifier()\n\tconst address = identifier.identifier\n\n\twhile (attempt < maxRetries) {\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ”„ Attempt ${attempt + 1}/${maxRetries} to create XMTP client...`\n\t\t\t)\n\n\t\t\t// Always require encryption key and persistence - no stateless mode\n\t\t\tif (!persist) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Stateless mode is not supported. XMTP client must run in persistent mode \" +\n\t\t\t\t\t\t\"to properly receive and process messages. Set persist: true or remove the persist option \" +\n\t\t\t\t\t\t\"to use the default persistent mode.\"\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!XMTP_ENCRYPTION_KEY) {\n\t\t\t\tthrow new Error(\"XMTP_ENCRYPTION_KEY must be set for persistent mode\")\n\t\t\t}\n\n\t\t\tconst dbEncryptionKey = getEncryptionKeyFromHex(XMTP_ENCRYPTION_KEY)\n\t\t\tconst dbPath = await getDbPath(\n\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`,\n\t\t\t\tstoragePath\n\t\t\t)\n\t\t\tconsole.log(`๐Ÿ“ Using database path: ${dbPath}`)\n\n\t\t\t// Always create a fresh client and sync it\n\t\t\tconst client = await Client.create(signer, {\n\t\t\t\tdbEncryptionKey,\n\t\t\t\tenv: XMTP_ENV as XmtpEnv,\n\t\t\t\tdbPath,\n\t\t\t\tcodecs: [\n\t\t\t\t\tnew ReplyCodec(),\n\t\t\t\t\tnew ReactionCodec(),\n\t\t\t\t\tnew WalletSendCallsCodec(),\n\t\t\t\t\tnew TransactionReferenceCodec()\n\t\t\t\t]\n\t\t\t})\n\n\t\t\t// Force sync conversations to ensure we have the latest data\n\t\t\tconsole.log(\"๐Ÿ“ก Syncing conversations to ensure latest state...\")\n\t\t\tawait client.conversations.sync()\n\n\t\t\tawait backupDbToPersistentStorage(\n\t\t\t\tdbPath,\n\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`\n\t\t\t)\n\n\t\t\tconsole.log(\"โœ… XMTP XmtpClient created\")\n\t\t\tconsole.log(`๐Ÿ”‘ Wallet address: ${address}`)\n\t\t\tconsole.log(`๐ŸŒ Environment: ${XMTP_ENV || \"dev\"}`)\n\t\t\tconsole.log(`๐Ÿ’พ Storage mode: persistent`)\n\n\t\t\treturn client\n\t\t} catch (error) {\n\t\t\tattempt++\n\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"5/5 installations\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ’ฅ Installation limit reached (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\t// Get wallet address for database clearing\n\t\t\t\t\tconst identifier = await signer.getIdentifier()\n\t\t\t\t\tconst address = identifier.identifier\n\n\t\t\t\t\t// Extract inboxId from the error message\n\t\t\t\t\tconst inboxIdMatch = error.message.match(/InboxID ([a-f0-9]+)/)\n\t\t\t\t\tconst inboxId = inboxIdMatch ? inboxIdMatch[1] : undefined\n\n\t\t\t\t\t// First try to revoke old installations\n\t\t\t\t\tconst revocationSuccess = await revokeOldInstallations(\n\t\t\t\t\t\tsigner,\n\t\t\t\t\t\tinboxId\n\t\t\t\t\t)\n\n\t\t\t\t\tif (revocationSuccess) {\n\t\t\t\t\t\tconsole.log(\"๐ŸŽฏ Installations revoked, retrying connection...\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โš ๏ธ Installation revocation failed or not needed, clearing database...\"\n\t\t\t\t\t\t)\n\t\t\t\t\t\t// Clear database as fallback\n\t\t\t\t\t\tawait clearXMTPDatabase(address, process.env.XMTP_ENV || \"dev\")\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait a bit before retrying\n\t\t\t\t\tconst delay = Math.pow(2, attempt) * 1000 // Exponential backoff\n\t\t\t\t\tconsole.log(`โณ Waiting ${delay}ms before retry...`)\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay))\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"โŒ Failed to resolve installation limit after all retries\"\n\t\t\t\t\t)\n\t\t\t\t\tconsole.error(\"๐Ÿ’ก Possible solutions:\")\n\t\t\t\t\tconsole.error(\" 1. Use a different wallet (generate new keys)\")\n\t\t\t\t\tconsole.error(\" 2. Switch XMTP environments (dev <-> production)\")\n\t\t\t\t\tconsole.error(\" 3. Wait and try again later\")\n\t\t\t\t\tconsole.error(\" 4. Contact XMTP support for manual intervention\")\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"Association error: Missing identity update\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ Identity association error detected (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconsole.log(\"๐Ÿ”ง Attempting automatic identity refresh...\")\n\n\t\t\t\t\t// Try to refresh identity by creating a persistent client first\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ Creating persistent client to refresh identity...\")\n\t\t\t\t\t\tconst tempEncryptionKey = XMTP_ENCRYPTION_KEY\n\t\t\t\t\t\t\t? getEncryptionKeyFromHex(XMTP_ENCRYPTION_KEY)\n\t\t\t\t\t\t\t: getEncryptionKeyFromHex(generateEncryptionKeyHex())\n\t\t\t\t\t\tconst tempClient = await Client.create(signer, {\n\t\t\t\t\t\t\tdbEncryptionKey: tempEncryptionKey,\n\t\t\t\t\t\t\tenv: XMTP_ENV as XmtpEnv,\n\t\t\t\t\t\t\tdbPath: await getDbPath(\n\t\t\t\t\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`,\n\t\t\t\t\t\t\t\tstoragePath\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tcodecs: [\n\t\t\t\t\t\t\t\tnew ReplyCodec(),\n\t\t\t\t\t\t\t\tnew ReactionCodec(),\n\t\t\t\t\t\t\t\tnew WalletSendCallsCodec(),\n\t\t\t\t\t\t\t\tnew TransactionReferenceCodec()\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ก Syncing identity and conversations...\")\n\t\t\t\t\t\tawait tempClient.conversations.sync()\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โœ… Identity refresh successful, retrying original request...\"\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Wait a bit before retrying\n\t\t\t\t\t\tconst delay = Math.pow(2, attempt) * 1000 // Exponential backoff\n\t\t\t\t\t\tconsole.log(`โณ Waiting ${delay}ms before retry...`)\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay))\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\tconsole.log(`โŒ Identity refresh failed:`, refreshError)\n\t\t\t\t\t\t// Continue to the retry logic\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"โŒ Failed to resolve identity association error after all retries\"\n\t\t\t\t\t)\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"๐Ÿ’ก Try running: pnpm with-env pnpm --filter @hybrd/xmtp refresh:identity\"\n\t\t\t\t\t)\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For other errors, don't retry\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(\"Max retries exceeded\")\n}\n\n// ===================================================================\n// Encryption Key Management\n// ===================================================================\n/**\n * Generate a random encryption key\n * @returns The encryption key as a hex string\n */\nexport const generateEncryptionKeyHex = () => {\n\tconst uint8Array = getRandomValues(new Uint8Array(32))\n\treturn uint8arraysToString(uint8Array, \"hex\")\n}\n\n/**\n * Get the encryption key from a hex string\n * @param hex - The hex string\n * @returns The encryption key as Uint8Array\n */\nexport const getEncryptionKeyFromHex = (hex: string): Uint8Array => {\n\treturn fromString(hex, \"hex\")\n}\n\n// ===================================================================\n// Database Path Management\n// ===================================================================\nexport const getDbPath = async (description = \"xmtp\", storagePath?: string) => {\n\t// Allow custom storage path via environment variable\n\tconst customStoragePath = process.env.XMTP_STORAGE_PATH\n\n\tlet volumePath: string\n\n\tif (customStoragePath) {\n\t\t// Use custom storage path if provided\n\t\tvolumePath = path.isAbsolute(customStoragePath)\n\t\t\t? customStoragePath\n\t\t\t: path.resolve(process.cwd(), customStoragePath)\n\t} else if (storagePath) {\n\t\tvolumePath = path.isAbsolute(storagePath)\n\t\t\t? storagePath\n\t\t\t: path.resolve(process.cwd(), storagePath)\n\t} else {\n\t\t// Use existing logic as fallback\n\t\tconst projectRoot =\n\t\t\tprocess.env.PROJECT_ROOT || path.resolve(__dirname, \"../../..\")\n\n\t\t// Default storage path for local development\n\t\tvolumePath = path.join(projectRoot, \".data/xmtp\")\n\t}\n\n\tconst dbPath = `${volumePath}/${description}.db3`\n\n\tif (typeof globalThis !== \"undefined\" && \"XMTP_STORAGE\" in globalThis) {\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ“ฆ Using Cloudflare R2 storage for: ${dbPath}`)\n\n\t\t\tconst r2Bucket = (globalThis as any).XMTP_STORAGE\n\t\t\tconst remotePath = `xmtp-databases/${description}.db3`\n\n\t\t\ttry {\n\t\t\t\tconst existingObject = await r2Bucket.head(remotePath)\n\t\t\t\tif (existingObject) {\n\t\t\t\t\tconsole.log(`๐Ÿ“ฅ Downloading existing database from R2 storage...`)\n\n\t\t\t\t\tif (!fs.existsSync(volumePath)) {\n\t\t\t\t\t\tfs.mkdirSync(volumePath, { recursive: true })\n\t\t\t\t\t}\n\n\t\t\t\t\tconst object = await r2Bucket.get(remotePath)\n\t\t\t\t\tif (object) {\n\t\t\t\t\t\tconst fileData = await object.arrayBuffer()\n\t\t\t\t\t\tfs.writeFileSync(dbPath, new Uint8Array(fileData))\n\t\t\t\t\t\tconsole.log(`โœ… Database downloaded from R2 storage`)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`๐Ÿ“ No existing database found in R2 storage`)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.log(`โš ๏ธ Failed to download database from R2 storage:`, error)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ R2 storage not available:`, error)\n\t\t}\n\t}\n\n\tif (!fs.existsSync(volumePath)) {\n\t\tfs.mkdirSync(volumePath, { recursive: true })\n\t}\n\n\treturn dbPath\n}\n\nexport const backupDbToPersistentStorage = async (\n\tdbPath: string,\n\tdescription: string\n) => {\n\tif (\n\t\ttypeof globalThis !== \"undefined\" &&\n\t\t\"XMTP_STORAGE\" in globalThis &&\n\t\tfs.existsSync(dbPath)\n\t) {\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ“ฆ Backing up database to R2 storage: ${dbPath}`)\n\n\t\t\tconst r2Bucket = (globalThis as any).XMTP_STORAGE\n\t\t\tconst remotePath = `xmtp-databases/${description}.db3`\n\n\t\t\tconst fileData = fs.readFileSync(dbPath)\n\t\t\tawait r2Bucket.put(remotePath, fileData)\n\t\t\tconsole.log(`โœ… Database backed up to R2 storage: ${remotePath}`)\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ Failed to backup database to R2 storage:`, error)\n\t\t}\n\t}\n}\n\n// ===================================================================\n// Logging and Debugging\n// ===================================================================\nexport const logAgentDetails = async (\n\tclients: XmtpClient | XmtpClient[]\n): Promise<void> => {\n\tconst clientsByAddress = Array.isArray(clients)\n\t\t? clients.reduce<Record<string, XmtpClient[]>>((acc, XmtpClient) => {\n\t\t\t\tconst address = XmtpClient.accountIdentifier?.identifier ?? \"\"\n\t\t\t\tacc[address] = acc[address] ?? []\n\t\t\t\tacc[address].push(XmtpClient)\n\t\t\t\treturn acc\n\t\t\t}, {})\n\t\t: {\n\t\t\t\t[clients.accountIdentifier?.identifier ?? \"\"]: [clients]\n\t\t\t}\n\n\tfor (const [address, clientGroup] of Object.entries(clientsByAddress)) {\n\t\tconst firstClient = clientGroup[0]\n\t\tconst inboxId = firstClient?.inboxId\n\t\tconst environments = clientGroup\n\t\t\t.map((c) => c.options?.env ?? \"dev\")\n\t\t\t.join(\", \")\n\t\tconsole.log(`\\x1b[38;2;252;76;52m\n โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— \n โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ•šโ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—\n โ•šโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•\n โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ•โ•โ• \n โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ•šโ•โ• โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ \n โ•šโ•โ• โ•šโ•โ•โ•šโ•โ• โ•šโ•โ• โ•šโ•โ• โ•šโ•โ• \n \\x1b[0m`)\n\n\t\tconst urls = [`http://xmtp.chat/dm/${address}`]\n\n\t\tconst conversations = await firstClient?.conversations.list()\n\n\t\tconsole.log(`\n โœ“ XMTP XmtpClient:\n โ€ข Address: ${address}\n โ€ข Conversations: ${conversations?.length}\n โ€ข InboxId: ${inboxId}\n โ€ข Networks: ${environments}\n ${urls.map((url) => `โ€ข URL: ${url}`).join(\"\\n\")}`)\n\t}\n}\n\n// ===================================================================\n// Environment Validation\n// ===================================================================\nexport function validateEnvironment(vars: string[]): Record<string, string> {\n\tconst missing = vars.filter((v) => !process.env[v])\n\n\tif (missing.length) {\n\t\ttry {\n\t\t\tconst envPath = path.resolve(process.cwd(), \".env\")\n\t\t\tif (fs.existsSync(envPath)) {\n\t\t\t\tconst envVars = fs\n\t\t\t\t\t.readFileSync(envPath, \"utf-8\")\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.filter((line) => line.trim() && !line.startsWith(\"#\"))\n\t\t\t\t\t.reduce<Record<string, string>>((acc, line) => {\n\t\t\t\t\t\tconst [key, ...val] = line.split(\"=\")\n\t\t\t\t\t\tif (key && val.length) acc[key.trim()] = val.join(\"=\").trim()\n\t\t\t\t\t\treturn acc\n\t\t\t\t\t}, {})\n\n\t\t\t\tmissing.forEach((v) => {\n\t\t\t\t\tif (envVars[v]) process.env[v] = envVars[v]\n\t\t\t\t})\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\t/* ignore errors */\n\t\t}\n\n\t\tconst stillMissing = vars.filter((v) => !process.env[v])\n\t\tif (stillMissing.length) {\n\t\t\tconsole.error(\"Missing env vars:\", stillMissing.join(\", \"))\n\t\t\tprocess.exit(1)\n\t\t}\n\t}\n\n\treturn vars.reduce<Record<string, string>>((acc, key) => {\n\t\tacc[key] = process.env[key] as string\n\t\treturn acc\n\t}, {})\n}\n\n/**\n * Diagnose XMTP environment and identity issues\n */\nexport async function diagnoseXMTPIdentityIssue(\n\tclient: XmtpClient,\n\tinboxId: string,\n\tenvironment: string\n): Promise<{\n\tcanResolve: boolean\n\tsuggestions: string[]\n\tdetails: Record<string, any>\n}> {\n\tconst suggestions: string[] = []\n\tconst details: Record<string, any> = {\n\t\tenvironment,\n\t\tinboxId,\n\t\ttimestamp: new Date().toISOString()\n\t}\n\n\ttry {\n\t\t// Try to resolve the inbox state\n\t\tconst inboxState = await client.preferences.inboxStateFromInboxIds([\n\t\t\tinboxId\n\t\t])\n\n\t\tif (inboxState.length === 0) {\n\t\t\tsuggestions.push(\n\t\t\t\t`Inbox ID ${inboxId} not found in ${environment} environment`\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Try switching XMTP_ENV to 'dev' if currently 'production' or vice versa\"\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Verify the user has created an identity on this XMTP network\"\n\t\t\t)\n\t\t\tdetails.inboxStateFound = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\tconst inbox = inboxState[0]\n\t\tif (!inbox) {\n\t\t\tsuggestions.push(\"Inbox state returned empty data\")\n\t\t\tdetails.inboxStateFound = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\tdetails.inboxStateFound = true\n\t\tdetails.identifierCount = inbox.identifiers?.length || 0\n\n\t\tif (!inbox.identifiers || inbox.identifiers.length === 0) {\n\t\t\tsuggestions.push(\"Inbox found but has no identifiers\")\n\t\t\tsuggestions.push(\"This indicates incomplete identity registration\")\n\t\t\tsuggestions.push(\"User may need to re-register their identity on XMTP\")\n\t\t\tdetails.hasIdentifiers = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\t// Successfully resolved\n\t\tdetails.hasIdentifiers = true\n\t\tdetails.resolvedAddress = inbox.identifiers[0]?.identifier\n\t\treturn {\n\t\t\tcanResolve: true,\n\t\t\tsuggestions: [\"Identity resolved successfully\"],\n\t\t\tdetails\n\t\t}\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\tdetails.error = errorMessage\n\n\t\tif (errorMessage.includes(\"Association error\")) {\n\t\t\tsuggestions.push(\"XMTP identity association error detected\")\n\t\t\tsuggestions.push(\n\t\t\t\t\"Check if user exists on the correct XMTP environment (dev vs production)\"\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Identity may need to be recreated on the current environment\"\n\t\t\t)\n\t\t}\n\n\t\tif (errorMessage.includes(\"Missing identity update\")) {\n\t\t\tsuggestions.push(\"Missing identity updates in XMTP network\")\n\t\t\tsuggestions.push(\"This can indicate network sync issues\")\n\t\t\tsuggestions.push(\"Wait a few minutes and retry, or recreate identity\")\n\t\t}\n\n\t\tif (errorMessage.includes(\"database\") || errorMessage.includes(\"storage\")) {\n\t\t\tsuggestions.push(\"XMTP local database/storage issue\")\n\t\t\tsuggestions.push(\"Try clearing XMTP database and resyncing\")\n\t\t\tsuggestions.push(\"Check .data/xmtp directory permissions\")\n\t\t}\n\n\t\tsuggestions.push(\"Consider testing with a fresh XMTP identity\")\n\t\treturn { canResolve: false, suggestions, details }\n\t}\n}\n\n// ===================================================================\n// Enhanced Connection Management & Health Monitoring\n// ===================================================================\n\nexport interface XMTPConnectionConfig {\n\tmaxRetries?: number\n\tretryDelayMs?: number\n\thealthCheckIntervalMs?: number\n\tconnectionTimeoutMs?: number\n\treconnectOnFailure?: boolean\n}\n\nexport interface XMTPConnectionHealth {\n\tisConnected: boolean\n\tlastHealthCheck: Date\n\tconsecutiveFailures: number\n\ttotalReconnects: number\n\tavgResponseTime: number\n}\n\nexport class XMTPConnectionManager {\n\tprivate client: XmtpClient | null = null\n\tprivate privateKey: string\n\tprivate config: Required<XMTPConnectionConfig>\n\tprivate health: XMTPConnectionHealth\n\tprivate healthCheckTimer: NodeJS.Timeout | null = null\n\tprivate isReconnecting = false\n\n\tconstructor(privateKey: string, config: XMTPConnectionConfig = {}) {\n\t\tthis.privateKey = privateKey\n\t\tthis.config = {\n\t\t\tmaxRetries: config.maxRetries ?? 5,\n\t\t\tretryDelayMs: config.retryDelayMs ?? 1000,\n\t\t\thealthCheckIntervalMs: config.healthCheckIntervalMs ?? 30000,\n\t\t\tconnectionTimeoutMs: config.connectionTimeoutMs ?? 10000,\n\t\t\treconnectOnFailure: config.reconnectOnFailure ?? true\n\t\t}\n\n\t\tthis.health = {\n\t\t\tisConnected: false,\n\t\t\tlastHealthCheck: new Date(),\n\t\t\tconsecutiveFailures: 0,\n\t\t\ttotalReconnects: 0,\n\t\t\tavgResponseTime: 0\n\t\t}\n\t}\n\n\tasync connect(persist = false): Promise<XmtpClient> {\n\t\tif (this.client && this.health.isConnected) {\n\t\t\treturn this.client\n\t\t}\n\n\t\tlet attempt = 0\n\t\twhile (attempt < this.config.maxRetries) {\n\t\t\ttry {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ XMTP connection attempt ${attempt + 1}/${this.config.maxRetries}`\n\t\t\t\t)\n\n\t\t\t\tthis.client = await createXMTPClient(this.privateKey, { persist })\n\t\t\t\tthis.health.isConnected = true\n\t\t\t\tthis.health.consecutiveFailures = 0\n\n\t\t\t\t// Start health monitoring\n\t\t\t\tthis.startHealthMonitoring()\n\n\t\t\t\tconsole.log(\"โœ… XMTP client connected successfully\")\n\t\t\t\treturn this.client\n\t\t\t} catch (error) {\n\t\t\t\tattempt++\n\t\t\t\tthis.health.consecutiveFailures++\n\n\t\t\t\tconsole.error(`โŒ XMTP connection attempt ${attempt} failed:`, error)\n\n\t\t\t\tif (attempt < this.config.maxRetries) {\n\t\t\t\t\tconst delay = this.config.retryDelayMs * Math.pow(2, attempt - 1)\n\t\t\t\t\tconsole.log(`โณ Retrying in ${delay}ms...`)\n\t\t\t\t\tawait this.sleep(delay)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Failed to connect to XMTP after ${this.config.maxRetries} attempts`\n\t\t)\n\t}\n\n\t// private async createClientWithTimeout(persist: boolean): Promise<XmtpClient> {\n\t// const timeoutPromise = new Promise<never>((_, reject) => {\n\t// setTimeout(\n\t// () => reject(new Error(\"Connection timeout\")),\n\t// this.config.connectionTimeoutMs\n\t// )\n\t// })\n\n\t// const clientPromise = createXMTPClient(this.signer, { persist })\n\n\t// return Promise.race([clientPromise, timeoutPromise])\n\t// }\n\n\tprivate startHealthMonitoring(): void {\n\t\tif (this.healthCheckTimer) {\n\t\t\tclearInterval(this.healthCheckTimer)\n\t\t}\n\n\t\tthis.healthCheckTimer = setInterval(() => {\n\t\t\tthis.performHealthCheck()\n\t\t}, this.config.healthCheckIntervalMs)\n\t}\n\n\tprivate async performHealthCheck(): Promise<void> {\n\t\tif (!this.client) return\n\n\t\tconst startTime = Date.now()\n\n\t\ttry {\n\t\t\t// Simple health check: try to list conversations\n\t\t\tawait this.client.conversations.list()\n\n\t\t\tconst responseTime = Date.now() - startTime\n\t\t\tthis.health.avgResponseTime =\n\t\t\t\t(this.health.avgResponseTime + responseTime) / 2\n\t\t\tthis.health.lastHealthCheck = new Date()\n\t\t\tthis.health.consecutiveFailures = 0\n\t\t\tthis.health.isConnected = true\n\n\t\t\tconsole.log(`๐Ÿ’“ XMTP health check passed (${responseTime}ms)`)\n\t\t} catch (error) {\n\t\t\tthis.health.consecutiveFailures++\n\t\t\tthis.health.isConnected = false\n\n\t\t\tconsole.error(`๐Ÿ’” XMTP health check failed:`, error)\n\n\t\t\t// Trigger reconnection if enabled\n\t\t\tif (this.config.reconnectOnFailure && !this.isReconnecting) {\n\t\t\t\tthis.handleConnectionFailure()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async handleConnectionFailure(): Promise<void> {\n\t\tif (this.isReconnecting) return\n\n\t\tthis.isReconnecting = true\n\t\tthis.health.totalReconnects++\n\n\t\tconsole.log(\"๐Ÿ”„ XMTP connection lost, attempting to reconnect...\")\n\n\t\ttry {\n\t\t\tthis.client = null\n\t\t\tawait this.connect()\n\t\t\tconsole.log(\"โœ… XMTP reconnection successful\")\n\t\t} catch (error) {\n\t\t\tconsole.error(\"โŒ XMTP reconnection failed:\", error)\n\t\t} finally {\n\t\t\tthis.isReconnecting = false\n\t\t}\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n\n\tgetHealth(): XMTPConnectionHealth {\n\t\treturn { ...this.health }\n\t}\n\n\tgetClient(): XmtpClient | null {\n\t\treturn this.client\n\t}\n\n\tasync disconnect(): Promise<void> {\n\t\tif (this.healthCheckTimer) {\n\t\t\tclearInterval(this.healthCheckTimer)\n\t\t\tthis.healthCheckTimer = null\n\t\t}\n\n\t\tthis.client = null\n\t\tthis.health.isConnected = false\n\t\tconsole.log(\"๐Ÿ”Œ XMTP client disconnected\")\n\t}\n}\n\n// Enhanced client creation with connection management\nexport async function createXMTPConnectionManager(\n\tprivateKey: string,\n\tconfig?: XMTPConnectionConfig\n): Promise<XMTPConnectionManager> {\n\tconst manager = new XMTPConnectionManager(privateKey, config)\n\tawait manager.connect()\n\treturn manager\n}\n\n// ===================================================================\n// User Address Resolution with Auto-Refresh\n// ===================================================================\n\n/**\n * Resolve user address from inbox ID with automatic identity refresh on association errors\n */\nexport async function resolveUserAddress(\n\tclient: XmtpClient,\n\tsenderInboxId: string,\n\tmaxRetries = 2\n): Promise<string> {\n\tlet attempt = 0\n\n\twhile (attempt < maxRetries) {\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” Resolving user address (attempt ${attempt + 1}/${maxRetries})...`\n\t\t\t)\n\n\t\t\tconst inboxState = await client.preferences.inboxStateFromInboxIds([\n\t\t\t\tsenderInboxId\n\t\t\t])\n\n\t\t\tconst firstInbox = inboxState[0]\n\t\t\tif (\n\t\t\t\tinboxState.length > 0 &&\n\t\t\t\tfirstInbox?.identifiers &&\n\t\t\t\tfirstInbox.identifiers.length > 0\n\t\t\t) {\n\t\t\t\tconst userAddress = firstInbox.identifiers[0]?.identifier\n\t\t\t\tif (userAddress) {\n\t\t\t\t\tconsole.log(\"โœ… Resolved user address:\", userAddress)\n\t\t\t\t\treturn userAddress\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\"โš ๏ธ No identifiers found in inbox state\")\n\t\t\treturn \"unknown\"\n\t\t} catch (error) {\n\t\t\tattempt++\n\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"Association error: Missing identity update\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ Identity association error during address resolution (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"๐Ÿ”ง Attempting automatic identity refresh for address resolution...\"\n\t\t\t\t\t)\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Force a conversation sync to refresh identity state\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ก Syncing conversations to refresh identity...\")\n\t\t\t\t\t\tawait client.conversations.sync()\n\n\t\t\t\t\t\t// Small delay before retry\n\t\t\t\t\t\tconsole.log(\"โณ Waiting 2s before retry...\")\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 2000))\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โœ… Identity sync completed, retrying address resolution...\"\n\t\t\t\t\t\t)\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\tconsole.log(`โŒ Identity refresh failed:`, refreshError)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"โŒ Failed to resolve user address after all retries\")\n\t\t\t\t\tconsole.error(\"๐Ÿ’ก Identity association issue persists\")\n\n\t\t\t\t\t// Run diagnostic\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst diagnosis = await diagnoseXMTPIdentityIssue(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tsenderInboxId,\n\t\t\t\t\t\t\tprocess.env.XMTP_ENV || \"dev\"\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tconsole.log(\"๐Ÿ” XMTP Identity Diagnosis:\")\n\t\t\t\t\t\tdiagnosis.suggestions.forEach((suggestion) => {\n\t\t\t\t\t\t\tconsole.error(`๐Ÿ’ก ${suggestion}`)\n\t\t\t\t\t\t})\n\t\t\t\t\t} catch (diagError) {\n\t\t\t\t\t\tconsole.warn(\"โš ๏ธ Could not run XMTP identity diagnosis:\", diagError)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn \"unknown\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For other errors, don't retry\n\t\t\t\tconsole.error(\"โŒ Error resolving user address:\", error)\n\t\t\t\treturn \"unknown\"\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"unknown\"\n}\n\nexport const startPeriodicBackup = (\n\tdbPath: string,\n\tdescription: string,\n\tintervalMs = 300000\n) => {\n\treturn setInterval(async () => {\n\t\ttry {\n\t\t\tawait backupDbToPersistentStorage(dbPath, description)\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ Periodic backup failed:`, error)\n\t\t}\n\t}, intervalMs)\n}\n","import { Client, Signer, createSigner } from \"../src/index\"\n\n// Function to revoke old installations when hitting the limit\nexport async function revokeOldInstallations(signer: Signer, inboxId?: string) {\n console.log(\"๐Ÿ”ง Attempting to revoke old installations...\")\n\n try {\n // If we don't have the inboxId, we need to extract it from a temporary client attempt\n if (!inboxId) {\n console.log(\"โ„น๏ธ No inboxId provided, cannot revoke installations\")\n return false\n }\n\n const inboxStates = await Client.inboxStateFromInboxIds(\n [inboxId],\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n if (!inboxStates[0]) {\n console.log(\"โŒ No inbox state found for the provided inboxId\")\n return false\n }\n\n const toRevokeInstallationBytes = inboxStates[0].installations.map(\n (i) => i.bytes\n )\n\n await Client.revokeInstallations(\n signer,\n inboxId,\n toRevokeInstallationBytes,\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n const resultingStates = await Client.inboxStateFromInboxIds(\n [inboxId],\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n console.log(\n `๐Ÿ“‹ Revoked installations: ${toRevokeInstallationBytes.length} installations`\n )\n console.log(\n `๐Ÿ“‹ Resulting state: ${resultingStates[0]?.installations.length || 0} installations`\n )\n\n return true\n } catch (error) {\n console.error(\"โŒ Error during installation revocation:\", error)\n return false\n }\n}\n\n// CLI script to revoke installations\nasync function main() {\n const { XMTP_WALLET_KEY } = process.env\n const inboxId = process.argv[2]\n\n if (!XMTP_WALLET_KEY) {\n console.error(\"โŒ XMTP_WALLET_KEY is required\")\n process.exit(1)\n }\n\n if (!inboxId) {\n console.error(\"โŒ InboxID is required as CLI argument\")\n console.error(\"Usage: tsx revoke-installations.ts <inboxId>\")\n process.exit(1)\n }\n\n const signer = createSigner(XMTP_WALLET_KEY)\n const identifier = await signer.getIdentifier()\n const address = identifier.identifier\n\n console.log(`๐Ÿ”‘ Wallet Address: ${address}`)\n console.log(`๐Ÿ“‹ Inbox ID: ${inboxId}`)\n\n // Try to revoke installations\n const success = await revokeOldInstallations(signer, inboxId)\n\n if (success) {\n console.log(\"โœ… Successfully revoked installations\")\n } else {\n console.log(\"โŒ Failed to revoke installations\")\n process.exit(1)\n }\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((error) => {\n console.error(\"๐Ÿ’ฅ Fatal error:\", error)\n process.exit(1)\n })\n}\n","// ===================================================================\n// Betting Configuration\n// ===================================================================\nexport const DEFAULT_OPTIONS = [\"yes\", \"no\"]\nexport const DEFAULT_AMOUNT = \"0.1\"\nexport const MAX_USDC_AMOUNT = 10 // Maximum allowed USDC transaction amount\n","import { EventEmitter } from \"node:events\"\nimport { Reaction } from \"@xmtp/content-type-reaction\"\nimport { Reply } from \"@xmtp/content-type-reply\"\nimport { http, PublicClient, createPublicClient } from \"viem\"\nimport { mainnet } from \"viem/chains\"\nimport { Resolver } from \"../resolver/resolver\"\nimport type { MessageEvent, XmtpClient, XmtpMessage } from \"../types\"\n\n// Configuration for the message listener\nexport interface MessageListenerConfig {\n\tpublicClient: PublicClient\n\txmtpClient: XmtpClient\n\t/**\n\t * Filter function to determine which messages to process\n\t * Return true to process the message, false to skip\n\t */\n\tfilter?: (\n\t\tevent: Pick<MessageEvent, \"conversation\" | \"message\" | \"rootMessage\">\n\t) => Promise<boolean> | boolean\n\t/**\n\t * Heartbeat interval in milliseconds (default: 5 minutes)\n\t */\n\theartbeatInterval?: number\n\t/**\n\t * Conversation check interval in milliseconds (default: 30 seconds)\n\t */\n\tconversationCheckInterval?: number\n\t/**\n\t * Environment variable key for XMTP environment (default: \"XMTP_ENV\")\n\t */\n\tenvKey?: string\n}\n\n// Enriched message data with resolved address\n\n// Define the event signature for type safety\nexport interface MessageListenerEvents {\n\tmessage: [data: MessageEvent]\n\terror: [error: Error]\n\tstarted: []\n\tstopped: []\n\theartbeat: [stats: { messageCount: number; conversationCount: number }]\n}\n\n/**\n * A flexible XMTP message listener that can be configured for different applications\n */\nexport class MessageListener extends EventEmitter {\n\tprivate xmtpClient: XmtpClient\n\tprivate resolver: Resolver\n\tprivate filter?: (\n\t\tevent: Pick<MessageEvent, \"conversation\" | \"message\" | \"rootMessage\">\n\t) => Promise<boolean> | boolean\n\tprivate heartbeatInterval?: NodeJS.Timeout\n\tprivate fallbackCheckInterval?: NodeJS.Timeout\n\tprivate messageCount = 0\n\tprivate conversations: any[] = []\n\tprivate readonly config: Required<\n\t\tPick<\n\t\t\tMessageListenerConfig,\n\t\t\t\"heartbeatInterval\" | \"conversationCheckInterval\" | \"envKey\"\n\t\t>\n\t>\n\n\tconstructor(config: MessageListenerConfig) {\n\t\tsuper()\n\t\tthis.xmtpClient = config.xmtpClient\n\n\t\t// Create mainnet client for ENS resolution\n\t\tconst mainnetClient = createPublicClient({\n\t\t\tchain: mainnet,\n\t\t\ttransport: http()\n\t\t})\n\n\t\t// Create unified resolver with all capabilities\n\t\tthis.resolver = new Resolver({\n\t\t\txmtpClient: this.xmtpClient,\n\t\t\tmainnetClient,\n\t\t\tbaseClient: config.publicClient,\n\t\t\tmaxCacheSize: 1000,\n\t\t\tcacheTtl: 86400000 // 24 hours\n\t\t})\n\n\t\tthis.filter = config.filter\n\t\tthis.config = {\n\t\t\theartbeatInterval: config.heartbeatInterval ?? 300000, // 5 minutes\n\t\t\tconversationCheckInterval: config.conversationCheckInterval ?? 30000, // 30 seconds\n\t\t\tenvKey: config.envKey ?? \"XMTP_ENV\"\n\t\t}\n\t}\n\n\t// Type-safe event emitter methods\n\ton<U extends keyof MessageListenerEvents>(\n\t\tevent: U,\n\t\tlistener: (...args: MessageListenerEvents[U]) => void\n\t): this {\n\t\treturn super.on(event, listener)\n\t}\n\n\temit<U extends keyof MessageListenerEvents>(\n\t\tevent: U,\n\t\t...args: MessageListenerEvents[U]\n\t): boolean {\n\t\treturn super.emit(event, ...args)\n\t}\n\n\tasync start(): Promise<void> {\n\t\tconst XMTP_ENV = process.env[this.config.envKey]\n\n\t\t// Pre-populate address cache from existing conversations\n\t\tawait this.resolver?.prePopulateAllCaches()\n\n\t\tconsole.log(\"๐Ÿ“ก Syncing conversations...\")\n\t\tawait this.xmtpClient.conversations.sync()\n\n\t\tconst address = this.xmtpClient.accountIdentifier?.identifier\n\n\t\t// List existing conversations for debugging\n\t\tthis.conversations = await this.xmtpClient.conversations.list()\n\n\t\tconsole.log(`๐Ÿค– XMTP[${XMTP_ENV}] Listening on ${address} ...`)\n\n\t\t// Emit started event\n\t\tthis.emit(\"started\")\n\n\t\t// Stream all messages and emit events for processing\n\t\ttry {\n\t\t\tconst stream = await this.xmtpClient.conversations.streamAllMessages()\n\n\t\t\t// Add a heartbeat to show the listener is active\n\t\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\t\tthis.emit(\"heartbeat\", {\n\t\t\t\t\tmessageCount: this.messageCount,\n\t\t\t\t\tconversationCount: this.conversations.length\n\t\t\t\t})\n\t\t\t\tif (this.messageCount > 0) {\n\t\t\t\t\tconsole.log(`๐Ÿ’“ Active - processed ${this.messageCount} messages`)\n\t\t\t\t}\n\t\t\t}, this.config.heartbeatInterval)\n\n\t\t\t// Check for new conversations\n\t\t\tthis.fallbackCheckInterval = setInterval(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst latestConversations = await this.xmtpClient.conversations.list()\n\t\t\t\t\tif (latestConversations.length > this.conversations.length) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`๐Ÿ†• Detected ${latestConversations.length - this.conversations.length} new conversations`\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthis.conversations.push(\n\t\t\t\t\t\t\t...latestConversations.slice(this.conversations.length)\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"โŒ Error checking for new conversations:\", error)\n\t\t\t\t\tthis.emit(\"error\", error as Error)\n\t\t\t\t}\n\t\t\t}, this.config.conversationCheckInterval)\n\n\t\t\ttry {\n\t\t\t\tfor await (const message of stream) {\n\t\t\t\t\tthis.messageCount++\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Skip messages from self or null messages\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!message ||\n\t\t\t\t\t\t\tmessage.senderInboxId.toLowerCase() ===\n\t\t\t\t\t\t\t\tthis.xmtpClient.inboxId.toLowerCase()\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`๐Ÿ“จ Received message \"${JSON.stringify(message)}\" in ${message.conversationId}`\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Get conversation details\n\t\t\t\t\t\tconst conversation =\n\t\t\t\t\t\t\tawait this.xmtpClient.conversations.getConversationById(\n\t\t\t\t\t\t\t\tmessage.conversationId\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (!conversation) {\n\t\t\t\t\t\t\tconsole.log(\"โŒ Could not find conversation for message\")\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contentTypeId = message.contentType?.typeId\n\n\t\t\t\t\t\t// Extract message content for processing\n\t\t\t\t\t\tlet messageContent: string\n\t\t\t\t\t\tif (contentTypeId === \"reply\") {\n\t\t\t\t\t\t\tconst replyContent = message.content as any\n\t\t\t\t\t\t\tmessageContent = (replyContent?.content || \"\").toString()\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tcontentTypeId === \"remoteStaticAttachment\" ||\n\t\t\t\t\t\t\tcontentTypeId === \"attachment\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// For attachments, use the fallback message or filename\n\t\t\t\t\t\t\tmessageContent =\n\t\t\t\t\t\t\t\t(message as any).fallback ||\n\t\t\t\t\t\t\t\t(message.content as any)?.filename ||\n\t\t\t\t\t\t\t\t\"[Attachment]\"\n\t\t\t\t\t\t} else if (contentTypeId === \"reaction\") {\n\t\t\t\t\t\t\t// For reactions, use a simple representation\n\t\t\t\t\t\t\tconst reactionContent = message.content as Reaction\n\t\t\t\t\t\t\tmessageContent = `[Reaction: ${reactionContent.content || \"\"}]`\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// For text and other content types, safely convert to string\n\t\t\t\t\t\t\tmessageContent = message.content ? String(message.content) : \"\"\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Find root message for replies and reactions\n\t\t\t\t\t\tlet rootMessage: XmtpMessage | null = message\n\t\t\t\t\t\tlet parentMessage: XmtpMessage | null = null\n\n\t\t\t\t\t\tif (contentTypeId === \"reply\") {\n\t\t\t\t\t\t\tconst { reference } = message.content as Reply\n\t\t\t\t\t\t\trootMessage = await this.resolver.findRootMessage(reference)\n\t\t\t\t\t\t\tparentMessage = await this.resolver.findMessage(reference)\n\t\t\t\t\t\t} else if (contentTypeId === \"reaction\") {\n\t\t\t\t\t\t\tconst { reference } = message.content as Reaction\n\t\t\t\t\t\t\trootMessage = await this.resolver.findRootMessage(reference)\n\t\t\t\t\t\t\tparentMessage = await this.resolver.findMessage(reference)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// For text messages and attachments, they are root messages\n\t\t\t\t\t\t\trootMessage = message\n\t\t\t\t\t\t\tparentMessage = null\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Skip if we couldn't find the root message\n\t\t\t\t\t\tif (!rootMessage) {\n\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t`โš ๏ธ [MessageListener] Could not find root message for: ${message.id}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Apply custom message filter if provided\n\t\t\t\t\t\tif (this.filter) {\n\t\t\t\t\t\t\tconst shouldProcess = await this.filter({\n\t\t\t\t\t\t\t\tconversation,\n\t\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\t\trootMessage\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tif (!shouldProcess) {\n\t\t\t\t\t\t\t\tconsole.log(\"๐Ÿ”„ Skipping message:\", message.id)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create sender using unified resolver\n\t\t\t\t\t\tconst sender = await this.resolver.createXmtpSender(\n\t\t\t\t\t\t\tmessage.senderInboxId,\n\t\t\t\t\t\t\tmessage.conversationId\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Extract and resolve subjects (basenames and ENS names mentioned in message)\n\t\t\t\t\t\t// TODO: Update extractSubjects to work with unified resolver\n\t\t\t\t\t\tconst subjects = {}\n\n\t\t\t\t\t\t// Create enriched message with resolved address, name, subjects, root message, and parent message\n\t\t\t\t\t\tconst messageEvent: MessageEvent = {\n\t\t\t\t\t\t\tconversation,\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\trootMessage: rootMessage as XmtpMessage, // We already checked it's not null above\n\t\t\t\t\t\t\tparentMessage: parentMessage || undefined,\n\t\t\t\t\t\t\tsender,\n\t\t\t\t\t\t\tsubjects\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Emit the enriched message\n\t\t\t\t\t\tthis.emit(\"message\", messageEvent)\n\t\t\t\t\t} catch (messageError) {\n\t\t\t\t\t\tconsole.error(\"โŒ Error processing message:\", messageError)\n\t\t\t\t\t\tthis.emit(\"error\", messageError as Error)\n\t\t\t\t\t\t// Continue processing other messages instead of crashing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (streamError) {\n\t\t\t\tconsole.error(\"โŒ Error in message stream:\", streamError)\n\t\t\t\tthis.cleanup()\n\t\t\t\tthis.emit(\"error\", streamError as Error)\n\t\t\t\tconsole.log(\"๐Ÿ”„ Attempting to restart stream...\")\n\n\t\t\t\t// Wait a bit before restarting to avoid tight restart loops\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5000))\n\n\t\t\t\t// Recursively restart the message listener\n\t\t\t\treturn this.start()\n\t\t\t}\n\t\t} catch (streamSetupError) {\n\t\t\tconsole.error(\"โŒ Error setting up message stream:\", streamSetupError)\n\t\t\tthis.emit(\"error\", streamSetupError as Error)\n\t\t\tthrow streamSetupError\n\t\t}\n\t}\n\n\tprivate cleanup() {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval)\n\t\t}\n\t\tif (this.fallbackCheckInterval) {\n\t\t\tclearInterval(this.fallbackCheckInterval)\n\t\t}\n\t}\n\n\tstop() {\n\t\tthis.cleanup()\n\t\tthis.emit(\"stopped\")\n\t\tconsole.log(\"๐Ÿ›‘ Message listener stopped\")\n\t\tthis.removeAllListeners()\n\t}\n\n\t/**\n\t * Get current statistics\n\t */\n\tgetStats() {\n\t\treturn {\n\t\t\tmessageCount: this.messageCount,\n\t\t\tconversationCount: this.conversations.length,\n\t\t\tisActive: !!this.heartbeatInterval\n\t\t}\n\t}\n}\n\n/**\n * Helper function to start a message listener\n */\nexport async function startMessageListener(\n\tconfig: MessageListenerConfig\n): Promise<MessageListener> {\n\tconst listener = new MessageListener(config)\n\tawait listener.start()\n\treturn listener\n}\n\n/**\n * Factory function to create a message listener with common filters\n */\nexport function createMessageListener(config: MessageListenerConfig) {\n\treturn new MessageListener(config)\n}\n","import type { XmtpClient } from \"../types\"\n\ninterface AddressResolverOptions {\n /**\n * Maximum number of addresses to cache\n * @default 1000\n */\n maxCacheSize?: number\n /**\n * Cache TTL in milliseconds\n * @default 86400000 (24 hours)\n */\n cacheTtl?: number\n}\n\ninterface CacheEntry {\n address: string\n timestamp: number\n}\n\nexport class AddressResolver {\n private cache = new Map<string, CacheEntry>()\n private readonly maxCacheSize: number\n private readonly cacheTtl: number\n\n constructor(\n private client: XmtpClient,\n options: AddressResolverOptions = {}\n ) {\n this.maxCacheSize = options.maxCacheSize ?? 1000\n this.cacheTtl = options.cacheTtl ?? 86400000 // 24 hours\n }\n\n /**\n * Resolve user address from inbox ID with caching\n */\n async resolveAddress(\n inboxId: string,\n conversationId?: string\n ): Promise<`0x${string}` | null> {\n // Check cache first (fastest)\n const cached = this.getCachedAddress(inboxId)\n if (cached) {\n console.log(`โœ… Resolved user address from cache: ${cached}`)\n return cached\n }\n\n let userAddress = undefined\n\n try {\n // Try conversation members lookup first (faster than network call)\n if (conversationId) {\n const conversation =\n await this.client.conversations.getConversationById(conversationId)\n if (conversation) {\n userAddress = await this.resolveFromConversation(\n conversation,\n inboxId\n )\n if (userAddress) {\n this.setCachedAddress(inboxId, userAddress)\n console.log(`โœ… Resolved user address: ${userAddress}`)\n return userAddress\n }\n }\n }\n\n // Fallback to inboxStateFromInboxIds\n userAddress = await this.resolveFromInboxState(inboxId)\n if (userAddress) {\n this.setCachedAddress(inboxId, userAddress)\n console.log(`โœ… Resolved user address via fallback: ${userAddress}`)\n return userAddress\n }\n\n console.log(`โš ๏ธ No identifiers found for inbox ${inboxId}`)\n return null\n } catch (error) {\n console.error(`โŒ Error resolving user address for ${inboxId}:`, error)\n return null\n }\n }\n\n /**\n * Resolve address from conversation members\n */\n private async resolveFromConversation(\n conversation: any,\n inboxId: string\n ): Promise<`0x${string}` | null> {\n try {\n const members = await conversation.members()\n const sender = members.find(\n (member: any) => member.inboxId.toLowerCase() === inboxId.toLowerCase()\n )\n\n if (sender) {\n const ethIdentifier = sender.accountIdentifiers.find(\n (id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n )\n if (ethIdentifier) {\n return ethIdentifier.identifier\n } else {\n console.log(`โš ๏ธ No Ethereum identifier found for inbox ${inboxId}`)\n }\n } else {\n console.log(\n `โš ๏ธ Sender not found in conversation members for inbox ${inboxId}`\n )\n }\n } catch (error) {\n console.error(`โŒ Error resolving from conversation members:`, error)\n }\n\n return null\n }\n\n /**\n * Resolve address from inbox state (network fallback)\n */\n private async resolveFromInboxState(inboxId: string): Promise<`0x${string}` | null> {\n try {\n const inboxState = await this.client.preferences.inboxStateFromInboxIds([\n inboxId\n ])\n const firstState = inboxState?.[0]\n if (firstState?.identifiers && firstState.identifiers.length > 0) {\n const firstIdentifier = firstState.identifiers[0]\n return firstIdentifier?.identifier as `0x${string}`\n }\n } catch (error) {\n console.error(`โŒ Error resolving from inbox state:`, error)\n }\n\n return null\n }\n\n /**\n * Get cached address if not expired\n */\n private getCachedAddress(inboxId: string): `0x${string}` | null {\n const entry = this.cache.get(inboxId)\n if (!entry) return null\n\n const now = Date.now()\n if (now - entry.timestamp > this.cacheTtl) {\n this.cache.delete(inboxId)\n return null\n }\n\n return entry.address as `0x${string}`\n }\n\n /**\n * Cache address with LRU eviction\n */\n private setCachedAddress(inboxId: string, address: `0x${string}`): void {\n // Simple LRU: if cache is full, remove oldest entry\n if (this.cache.size >= this.maxCacheSize) {\n const firstKey = this.cache.keys().next().value\n if (firstKey) {\n this.cache.delete(firstKey)\n }\n }\n\n this.cache.set(inboxId, {\n address,\n timestamp: Date.now()\n })\n }\n\n /**\n * Pre-populate cache from existing conversations\n */\n async prePopulateCache(): Promise<void> {\n console.log(\"๐Ÿ”„ Pre-populating address cache...\")\n try {\n const conversations = await this.client.conversations.list()\n let cachedCount = 0\n\n for (const conversation of conversations) {\n try {\n const members = await conversation.members()\n for (const member of members) {\n const ethIdentifier = member.accountIdentifiers.find(\n (id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n )\n if (ethIdentifier) {\n this.setCachedAddress(member.inboxId, ethIdentifier.identifier as `0x${string}`)\n cachedCount++\n }\n }\n } catch (error) {\n console.error(\"Error pre-caching conversation members:\", error)\n }\n }\n\n console.log(`โœ… Pre-cached ${cachedCount} address mappings`)\n } catch (error) {\n console.error(\"Error pre-populating cache:\", error)\n }\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.cache.clear()\n console.log(\"๐Ÿ—‘๏ธ Address cache cleared\")\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; maxSize: number; hitRate?: number } {\n return {\n size: this.cache.size,\n maxSize: this.maxCacheSize\n }\n }\n}\n","import {\n\ttype Address,\n\tPublicClient,\n\tencodePacked,\n\tkeccak256,\n\tnamehash\n} from \"viem\"\nimport { mainnet } from \"viem/chains\"\nimport { L2ResolverAbi } from \"../abi/l2_resolver\"\n\n// Base L2 Resolver Address mapping by chain ID\n// const BASENAME_L2_RESOLVER_ADDRESSES: Record<number, Address> = {\n// \t[mainnet.id]: \"0x0000000000000000000000000000000000000000\", // Mainnet (1)\n// \t[base.id]: \"0xC6d566A56A1aFf6508b41f6c90ff131615583BCD\", // Base Mainnet (8453)\n// \t[baseSepolia.id]: \"0x6533C94869D28fAA8dF77cc63f9e2b2D6Cf77eBA\" // Base Sepolia (84532)\n// } as const\n\nconst BASENAME_L2_RESOLVER_ADDRESS =\n\t\"0xC6d566A56A1aFf6508b41f6c90ff131615583BCD\"\n\n// Basename text record keys for metadata\nexport const BasenameTextRecordKeys = {\n\tEmail: \"email\",\n\tUrl: \"url\",\n\tAvatar: \"avatar\",\n\tDescription: \"description\",\n\tNotice: \"notice\",\n\tKeywords: \"keywords\",\n\tTwitter: \"com.twitter\",\n\tGithub: \"com.github\",\n\tDiscord: \"com.discord\",\n\tTelegram: \"org.telegram\",\n\tSnapshot: \"snapshot\",\n\tLocation: \"location\"\n} as const\n\nexport type BasenameTextRecordKey =\n\t(typeof BasenameTextRecordKeys)[keyof typeof BasenameTextRecordKeys]\nexport type BaseName = string\n\ninterface BasenameResolverOptions {\n\t/**\n\t * Maximum number of basenames to cache\n\t * @default 500\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n\n\t/**\n\t * Public client\n\t * @default null\n\t */\n\tpublicClient: PublicClient\n}\n\ninterface CacheEntry {\n\tbasename: string\n\ttimestamp: number\n}\n\ninterface TextRecordCacheEntry {\n\tvalue: string\n\ttimestamp: number\n}\n\n/**\n * Convert an chainId to a coinType hex for reverse chain resolution\n */\nexport const convertChainIdToCoinType = (chainId: number): string => {\n\t// L1 resolvers to addr\n\tif (chainId === mainnet.id) {\n\t\treturn \"addr\"\n\t}\n\n\tconst cointype = (0x80000000 | chainId) >>> 0\n\treturn cointype.toString(16).toLocaleUpperCase()\n}\n\n/**\n * Helper function to convert an address to its reverse node for ENS lookups\n */\nexport const convertReverseNodeToBytes = (\n\taddress: Address,\n\tchainId: number\n) => {\n\tconst addressFormatted = address.toLocaleLowerCase() as Address\n\tconst addressNode = keccak256(addressFormatted.substring(2) as Address)\n\tconst chainCoinType = convertChainIdToCoinType(chainId)\n\tconst baseReverseNode = namehash(\n\t\t`${chainCoinType.toLocaleUpperCase()}.reverse`\n\t)\n\tconst addressReverseNode = keccak256(\n\t\tencodePacked([\"bytes32\", \"bytes32\"], [baseReverseNode, addressNode])\n\t)\n\treturn addressReverseNode\n}\n\n/**\n * Helper function to convert a basename to its node hash\n */\nfunction convertBasenameToNode(basename: string): `0x${string}` {\n\treturn namehash(basename)\n}\n\n/**\n * Get the resolver address for a given chain ID\n */\nfunction getResolverAddress(): Address {\n\tconst resolverAddress = BASENAME_L2_RESOLVER_ADDRESS\n\treturn resolverAddress\n}\n\nexport class BasenameResolver {\n\tprivate cache = new Map<string, CacheEntry>()\n\tprivate textRecordCache = new Map<string, Map<string, TextRecordCacheEntry>>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly baseClient: PublicClient\n\tprivate resolverAddress: Address | null = null\n\tprivate chainId: number | null = null\n\n\tconstructor(options: BasenameResolverOptions) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 500\n\t\tthis.cacheTtl = options.cacheTtl ?? 3600000 // 1 hour\n\n\t\t// Create a public client for Base network\n\t\tthis.baseClient = options.publicClient\n\n\t\t// Initialize resolver address lazily on first use\n\t\tthis.initializeResolver()\n\t}\n\n\t/**\n\t * Initialize the resolver address based on the client's chain ID\n\t */\n\tprivate async initializeResolver(): Promise<void> {\n\t\tif (this.resolverAddress && this.chainId) {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ”„ BasenameResolver already initialized for chain ${this.chainId} with resolver ${this.resolverAddress}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(\"๐Ÿ”„ Initializing BasenameResolver...\")\n\t\t\tthis.chainId = await this.baseClient.getChainId()\n\t\t\tconsole.log(`๐Ÿ”— Chain ID detected: ${this.chainId}`)\n\n\t\t\tthis.resolverAddress = getResolverAddress()\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“ Resolver address for chain ${this.chainId}: ${this.resolverAddress}`\n\t\t\t)\n\n\t\t\tconsole.log(\n\t\t\t\t`โœ… Initialized BasenameResolver for chain ${this.chainId} with resolver ${this.resolverAddress}`\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"โŒ Failed to initialize BasenameResolver:\", error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get the resolver address, initializing if necessary\n\t */\n\tprivate async getResolverAddress(): Promise<Address> {\n\t\tawait this.initializeResolver()\n\t\tif (!this.resolverAddress) {\n\t\t\tthrow new Error(\"Failed to initialize resolver address\")\n\t\t}\n\t\treturn this.resolverAddress\n\t}\n\n\t/**\n\t * Resolve a basename from an Ethereum address\n\t */\n\tasync getBasename(address: Address): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ” Starting basename resolution for address: ${address}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedBasename(address)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved basename from cache: ${cached}`)\n\t\t\t\treturn cached\n\t\t\t}\n\t\t\tconsole.log(`๐Ÿ“ญ No cached basename found for address: ${address}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting chain ID...\")\n\t\t\tconst chainId = await this.baseClient.getChainId()\n\t\t\tconsole.log(`๐Ÿ”— Chain ID: ${chainId}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting address to reverse node...\")\n\t\t\tconst addressReverseNode = convertReverseNodeToBytes(\n\t\t\t\t// address.toUpperCase() as `0x${string}`,\n\t\t\t\taddress as `0x${string}`,\n\t\t\t\tchainId\n\t\t\t)\n\t\t\tconsole.log(`๐Ÿ”— Reverse node: ${addressReverseNode}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Reading contract to resolve basename...\")\n\t\t\tconst basename = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"name\",\n\t\t\t\targs: [addressReverseNode]\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“‹ Contract returned basename: \"${basename}\" (length: ${basename?.length || 0})`\n\t\t\t)\n\n\t\t\tif (basename && basename.length > 0) {\n\t\t\t\tthis.setCachedBasename(address, basename)\n\t\t\t\tconsole.log(`โœ… Resolved basename: ${basename} for address: ${address}`)\n\t\t\t\treturn basename as BaseName\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No basename found for address: ${address} (empty or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving basename for address ${address}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get the avatar URL for a basename\n\t */\n\tasync getBasenameAvatar(basename: BaseName): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ–ผ๏ธ Getting avatar for basename: ${basename}`)\n\t\treturn this.getBasenameTextRecord(basename, BasenameTextRecordKeys.Avatar)\n\t}\n\n\t/**\n\t * Get a text record for a basename\n\t */\n\tasync getBasenameTextRecord(\n\t\tbasename: BaseName,\n\t\tkey: BasenameTextRecordKey\n\t): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ“ Getting text record \"${key}\" for basename: ${basename}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedTextRecord(basename, key)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved text record from cache: ${key}=${cached}`)\n\t\t\t\treturn cached\n\t\t\t}\n\t\t\tconsole.log(`๐Ÿ“ญ No cached text record found for ${basename}.${key}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting basename to node...\")\n\t\t\tconst node = convertBasenameToNode(basename)\n\t\t\tconsole.log(`๐Ÿ”— Node hash: ${node}`)\n\n\t\t\tconsole.log(`๐Ÿ”„ Reading contract for text record \"${key}\"...`)\n\t\t\tconst textRecord = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"text\",\n\t\t\t\targs: [node, key]\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“‹ Contract returned text record: \"${textRecord}\" (length: ${textRecord?.length || 0})`\n\t\t\t)\n\n\t\t\tif (textRecord && textRecord.length > 0) {\n\t\t\t\tthis.setCachedTextRecord(basename, key, textRecord)\n\t\t\t\tconsole.log(`โœ… Resolved text record: ${key}=${textRecord}`)\n\t\t\t\treturn textRecord\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No text record found for ${basename}.${key} (empty or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving text record ${key} for ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get the Ethereum address that owns a basename\n\t */\n\tasync getBasenameAddress(basename: BaseName): Promise<Address | null> {\n\t\tconsole.log(`๐Ÿ” Getting address for basename: ${basename}`)\n\n\t\ttry {\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting basename to node...\")\n\t\t\tconst node = convertBasenameToNode(basename)\n\t\t\tconsole.log(`๐Ÿ”— Node hash: ${node}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Reading contract to resolve address...\")\n\t\t\tconst address = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"addr\",\n\t\t\t\targs: [node]\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ Contract returned address: \"${address}\"`)\n\n\t\t\tif (address && address !== \"0x0000000000000000000000000000000000000000\") {\n\t\t\t\tconsole.log(`โœ… Resolved address: ${address} for basename: ${basename}`)\n\t\t\t\treturn address as Address\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No address found for basename: ${basename} (zero address or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving address for basename ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get all basic metadata for a basename\n\t */\n\tasync getBasenameMetadata(basename: BaseName) {\n\t\tconsole.log(`๐Ÿ“Š Getting metadata for basename: ${basename}`)\n\n\t\ttry {\n\t\t\tconst [avatar, description, twitter, github, url] = await Promise.all([\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Avatar),\n\t\t\t\tthis.getBasenameTextRecord(\n\t\t\t\t\tbasename,\n\t\t\t\t\tBasenameTextRecordKeys.Description\n\t\t\t\t),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Twitter),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Github),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Url)\n\t\t\t])\n\n\t\t\tconst metadata = {\n\t\t\t\tbasename,\n\t\t\t\tavatar,\n\t\t\t\tdescription,\n\t\t\t\ttwitter,\n\t\t\t\tgithub,\n\t\t\t\turl\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… Resolved metadata for ${basename}:`, metadata)\n\t\t\treturn metadata\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving metadata for basename ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Resolve a full basename profile (name + metadata) from an address\n\t */\n\tasync resolveBasenameProfile(address: Address) {\n\t\tconsole.log(`๐Ÿ‘ค Resolving full basename profile for address: ${address}`)\n\n\t\ttry {\n\t\t\tconst basename = await this.getBasename(address)\n\t\t\tif (!basename) {\n\t\t\t\tconsole.log(`โŒ No basename found for address: ${address}`)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ”„ Getting metadata for resolved basename: ${basename}`)\n\t\t\tconst metadata = await this.getBasenameMetadata(basename)\n\n\t\t\tconst profile = {\n\t\t\t\taddress,\n\t\t\t\t...metadata\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… Resolved full profile for ${address}:`, profile)\n\t\t\treturn profile\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving basename profile for ${address}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get cached basename if not expired\n\t */\n\tprivate getCachedBasename(address: Address): string | null {\n\t\tconst entry = this.cache.get(address.toLowerCase())\n\t\tif (!entry) {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“ญ No cache entry found for address: ${address.toLowerCase()}`\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst age = now - entry.timestamp\n\t\tconsole.log(`๐Ÿ• Cache entry age: ${age}ms (TTL: ${this.cacheTtl}ms)`)\n\n\t\tif (age > this.cacheTtl) {\n\t\t\tconsole.log(\n\t\t\t\t`โฐ Cache entry expired for address: ${address.toLowerCase()}`\n\t\t\t)\n\t\t\tthis.cache.delete(address.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`โœ… Valid cache entry found for ${address.toLowerCase()}: \"${entry.basename}\"`\n\t\t)\n\t\treturn entry.basename\n\t}\n\n\t/**\n\t * Cache basename with LRU eviction\n\t */\n\tprivate setCachedBasename(address: Address, basename: string): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.cache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.cache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tconsole.log(`๐Ÿ—‘๏ธ Cache full, removing oldest entry: ${firstKey}`)\n\t\t\t\tthis.cache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`๐Ÿ’พ Caching basename \"${basename}\" for address: ${address.toLowerCase()}`\n\t\t)\n\t\tthis.cache.set(address.toLowerCase(), {\n\t\t\tbasename,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached text record if not expired\n\t */\n\tprivate getCachedTextRecord(basename: string, key: string): string | null {\n\t\tconst basenameCache = this.textRecordCache.get(basename)\n\t\tif (!basenameCache) {\n\t\t\tconsole.log(`๐Ÿ“ญ No text record cache found for basename: ${basename}`)\n\t\t\treturn null\n\t\t}\n\n\t\tconst entry = basenameCache.get(key)\n\t\tif (!entry) {\n\t\t\tconsole.log(`๐Ÿ“ญ No cached text record found for ${basename}.${key}`)\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst age = now - entry.timestamp\n\t\tconsole.log(\n\t\t\t`๐Ÿ• Text record cache entry age: ${age}ms (TTL: ${this.cacheTtl}ms)`\n\t\t)\n\n\t\tif (age > this.cacheTtl) {\n\t\t\tconsole.log(`โฐ Text record cache entry expired for ${basename}.${key}`)\n\t\t\tbasenameCache.delete(key)\n\t\t\treturn null\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`โœ… Valid text record cache entry found for ${basename}.${key}: \"${entry.value}\"`\n\t\t)\n\t\treturn entry.value\n\t}\n\n\t/**\n\t * Cache text record\n\t */\n\tprivate setCachedTextRecord(\n\t\tbasename: string,\n\t\tkey: string,\n\t\tvalue: string\n\t): void {\n\t\tlet basenameCache = this.textRecordCache.get(basename)\n\t\tif (!basenameCache) {\n\t\t\tconsole.log(`๐Ÿ“ Creating new text record cache for basename: ${basename}`)\n\t\t\tbasenameCache = new Map()\n\t\t\tthis.textRecordCache.set(basename, basenameCache)\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`๐Ÿ’พ Caching text record \"${key}\" = \"${value}\" for basename: ${basename}`\n\t\t)\n\t\tbasenameCache.set(key, {\n\t\t\tvalue,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tconst basenameCount = this.cache.size\n\t\tconst textRecordCount = this.textRecordCache.size\n\n\t\tthis.cache.clear()\n\t\tthis.textRecordCache.clear()\n\n\t\tconsole.log(`๐Ÿ—‘๏ธ Basename cache cleared (${basenameCount} entries removed)`)\n\t\tconsole.log(\n\t\t\t`๐Ÿ—‘๏ธ Text record cache cleared (${textRecordCount} basename caches removed)`\n\t\t)\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats(): {\n\t\tbasenameCache: { size: number; maxSize: number }\n\t\ttextRecordCache: { size: number }\n\t\tchainId: number | null\n\t\tresolverAddress: Address | null\n\t} {\n\t\treturn {\n\t\t\tbasenameCache: {\n\t\t\t\tsize: this.cache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\ttextRecordCache: {\n\t\t\t\tsize: this.textRecordCache.size\n\t\t\t},\n\t\t\tchainId: this.chainId,\n\t\t\tresolverAddress: this.resolverAddress\n\t\t}\n\t}\n}\n","export const L2ResolverAbi = [\n {\n inputs: [\n { internalType: \"contract ENS\", name: \"ens_\", type: \"address\" },\n {\n internalType: \"address\",\n name: \"registrarController_\",\n type: \"address\",\n },\n { internalType: \"address\", name: \"reverseRegistrar_\", type: \"address\" },\n { internalType: \"address\", name: \"owner_\", type: \"address\" },\n ],\n stateMutability: \"nonpayable\",\n type: \"constructor\",\n },\n { inputs: [], name: \"AlreadyInitialized\", type: \"error\" },\n { inputs: [], name: \"CantSetSelfAsDelegate\", type: \"error\" },\n { inputs: [], name: \"CantSetSelfAsOperator\", type: \"error\" },\n { inputs: [], name: \"NewOwnerIsZeroAddress\", type: \"error\" },\n { inputs: [], name: \"NoHandoverRequest\", type: \"error\" },\n { inputs: [], name: \"Unauthorized\", type: \"error\" },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"contentType\",\n type: \"uint256\",\n },\n ],\n name: \"ABIChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"address\", name: \"a\", type: \"address\" },\n ],\n name: \"AddrChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"coinType\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"newAddress\",\n type: \"bytes\",\n },\n ],\n name: \"AddressChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"owner\",\n type: \"address\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"operator\",\n type: \"address\",\n },\n { indexed: false, internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"ApprovalForAll\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: \"address\",\n name: \"owner\",\n type: \"address\",\n },\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"address\",\n name: \"delegate\",\n type: \"address\",\n },\n { indexed: true, internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"Approved\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"ContenthashChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"name\", type: \"bytes\" },\n {\n indexed: false,\n internalType: \"uint16\",\n name: \"resource\",\n type: \"uint16\",\n },\n { indexed: false, internalType: \"bytes\", name: \"record\", type: \"bytes\" },\n ],\n name: \"DNSRecordChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"name\", type: \"bytes\" },\n {\n indexed: false,\n internalType: \"uint16\",\n name: \"resource\",\n type: \"uint16\",\n },\n ],\n name: \"DNSRecordDeleted\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"lastzonehash\",\n type: \"bytes\",\n },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"zonehash\",\n type: \"bytes\",\n },\n ],\n name: \"DNSZonehashChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"bytes4\",\n name: \"interfaceID\",\n type: \"bytes4\",\n },\n {\n indexed: false,\n internalType: \"address\",\n name: \"implementer\",\n type: \"address\",\n },\n ],\n name: \"InterfaceChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"string\", name: \"name\", type: \"string\" },\n ],\n name: \"NameChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"pendingOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipHandoverCanceled\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"pendingOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipHandoverRequested\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"oldOwner\",\n type: \"address\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"newOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipTransferred\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n name: \"PubkeyChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"newRegistrarController\",\n type: \"address\",\n },\n ],\n name: \"RegistrarControllerUpdated\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"newReverseRegistrar\",\n type: \"address\",\n },\n ],\n name: \"ReverseRegistrarUpdated\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"string\",\n name: \"indexedKey\",\n type: \"string\",\n },\n { indexed: false, internalType: \"string\", name: \"key\", type: \"string\" },\n { indexed: false, internalType: \"string\", name: \"value\", type: \"string\" },\n ],\n name: \"TextChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"uint64\",\n name: \"newVersion\",\n type: \"uint64\",\n },\n ],\n name: \"VersionChanged\",\n type: \"event\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"contentTypes\", type: \"uint256\" },\n ],\n name: \"ABI\",\n outputs: [\n { internalType: \"uint256\", name: \"\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"\", type: \"bytes\" },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"addr\",\n outputs: [{ internalType: \"address payable\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"coinType\", type: \"uint256\" },\n ],\n name: \"addr\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"approve\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"cancelOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"clearRecords\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"pendingOwner\", type: \"address\" },\n ],\n name: \"completeOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"contenthash\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"name\", type: \"bytes32\" },\n { internalType: \"uint16\", name: \"resource\", type: \"uint16\" },\n ],\n name: \"dnsRecord\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"ens\",\n outputs: [{ internalType: \"contract ENS\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"name\", type: \"bytes32\" },\n ],\n name: \"hasDNSRecords\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" },\n ],\n name: \"interfaceImplementer\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"owner\", type: \"address\" },\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n ],\n name: \"isApprovedFor\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"account\", type: \"address\" },\n { internalType: \"address\", name: \"operator\", type: \"address\" },\n ],\n name: \"isApprovedForAll\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes[]\", name: \"data\", type: \"bytes[]\" }],\n name: \"multicall\",\n outputs: [{ internalType: \"bytes[]\", name: \"results\", type: \"bytes[]\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"nodehash\", type: \"bytes32\" },\n { internalType: \"bytes[]\", name: \"data\", type: \"bytes[]\" },\n ],\n name: \"multicallWithNodeCheck\",\n outputs: [{ internalType: \"bytes[]\", name: \"results\", type: \"bytes[]\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"name\",\n outputs: [{ internalType: \"string\", name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"owner\",\n outputs: [{ internalType: \"address\", name: \"result\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"pendingOwner\", type: \"address\" },\n ],\n name: \"ownershipHandoverExpiresAt\",\n outputs: [{ internalType: \"uint256\", name: \"result\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"pubkey\",\n outputs: [\n { internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"\", type: \"bytes32\" }],\n name: \"recordVersions\",\n outputs: [{ internalType: \"uint64\", name: \"\", type: \"uint64\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"registrarController\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"renounceOwnership\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"requestOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes\", name: \"\", type: \"bytes\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"resolve\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"reverseRegistrar\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"contentType\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"setABI\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"coinType\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"a\", type: \"bytes\" },\n ],\n name: \"setAddr\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"a\", type: \"address\" },\n ],\n name: \"setAddr\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"operator\", type: \"address\" },\n { internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"setApprovalForAll\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"setContenthash\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"setDNSRecords\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" },\n { internalType: \"address\", name: \"implementer\", type: \"address\" },\n ],\n name: \"setInterface\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"newName\", type: \"string\" },\n ],\n name: \"setName\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n name: \"setPubkey\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n {\n internalType: \"address\",\n name: \"registrarController_\",\n type: \"address\",\n },\n ],\n name: \"setRegistrarController\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"reverseRegistrar_\", type: \"address\" },\n ],\n name: \"setReverseRegistrar\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"key\", type: \"string\" },\n { internalType: \"string\", name: \"value\", type: \"string\" },\n ],\n name: \"setText\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"setZonehash\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" }],\n name: \"supportsInterface\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"key\", type: \"string\" },\n ],\n name: \"text\",\n outputs: [{ internalType: \"string\", name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"address\", name: \"newOwner\", type: \"address\" }],\n name: \"transferOwnership\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"zonehash\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;","import { type Address, PublicClient } from \"viem\"\n\ninterface ENSResolverOptions {\n\t/**\n\t * Maximum number of ENS names to cache\n\t * @default 500\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n\t/**\n\t * Mainnet public client for ENS resolution\n\t */\n\tmainnetClient: PublicClient\n}\n\ninterface CacheEntry {\n\taddress: string\n\ttimestamp: number\n}\n\ninterface ReverseCacheEntry {\n\tensName: string\n\ttimestamp: number\n}\n\n/**\n * ENS Resolver for mainnet .eth names\n * Handles resolution of ENS names to addresses and reverse resolution\n */\nexport class ENSResolver {\n\tprivate cache = new Map<string, CacheEntry>()\n\tprivate reverseCache = new Map<string, ReverseCacheEntry>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly mainnetClient: PublicClient\n\n\tconstructor(options: ENSResolverOptions) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 500\n\t\tthis.cacheTtl = options.cacheTtl ?? 3600000 // 1 hour\n\t\tthis.mainnetClient = options.mainnetClient\n\t}\n\n\t/**\n\t * Resolve an ENS name to an Ethereum address\n\t */\n\tasync resolveENSName(ensName: string): Promise<Address | null> {\n\t\tconsole.log(`๐Ÿ” Resolving ENS name: ${ensName}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedAddress(ensName)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved ENS from cache: ${ensName} โ†’ ${cached}`)\n\t\t\t\treturn cached as Address\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ“ญ No cached address found for ENS: ${ensName}`)\n\n\t\t\t// Resolve using mainnet ENS\n\t\t\tconsole.log(\"๐Ÿ”„ Reading ENS contract...\")\n\t\t\tconst address = await this.mainnetClient.getEnsAddress({\n\t\t\t\tname: ensName\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ ENS contract returned address: \"${address}\"`)\n\n\t\t\tif (address && address !== \"0x0000000000000000000000000000000000000000\") {\n\t\t\t\tthis.setCachedAddress(ensName, address)\n\t\t\t\tconsole.log(`โœ… Resolved ENS: ${ensName} โ†’ ${address}`)\n\t\t\t\treturn address\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No address found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error resolving ENS name ${ensName}:`, error)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Resolve an address to its primary ENS name (reverse resolution)\n\t */\n\tasync resolveAddressToENS(address: Address): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ” Reverse resolving address to ENS: ${address}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedENSName(address)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… Resolved ENS from reverse cache: ${address} โ†’ ${cached}`\n\t\t\t\t)\n\t\t\t\treturn cached\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ“ญ No cached ENS name found for address: ${address}`)\n\n\t\t\t// Reverse resolve using mainnet ENS\n\t\t\tconsole.log(\"๐Ÿ”„ Reading ENS reverse resolver...\")\n\t\t\tconst ensName = await this.mainnetClient.getEnsName({\n\t\t\t\taddress: address\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ ENS reverse resolver returned: \"${ensName}\"`)\n\n\t\t\tif (ensName && ensName.length > 0) {\n\t\t\t\tthis.setCachedENSName(address, ensName)\n\t\t\t\tconsole.log(`โœ… Reverse resolved: ${address} โ†’ ${ensName}`)\n\t\t\t\treturn ensName\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No ENS name found for address: ${address}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error reverse resolving address ${address}:`, error)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get ENS avatar for a name\n\t */\n\tasync getENSAvatar(ensName: string): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ–ผ๏ธ Getting ENS avatar for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst avatar = await this.mainnetClient.getEnsAvatar({\n\t\t\t\tname: ensName\n\t\t\t})\n\n\t\t\tif (avatar) {\n\t\t\t\tconsole.log(`โœ… Found ENS avatar: ${avatar}`)\n\t\t\t\treturn avatar\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No avatar found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error getting ENS avatar for ${ensName}:`, error)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get ENS text record\n\t */\n\tasync getENSTextRecord(ensName: string, key: string): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ“ Getting ENS text record \"${key}\" for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst textRecord = await this.mainnetClient.getEnsText({\n\t\t\t\tname: ensName,\n\t\t\t\tkey: key\n\t\t\t})\n\n\t\t\tif (textRecord && textRecord.length > 0) {\n\t\t\t\tconsole.log(`โœ… Found ENS text record: ${key}=${textRecord}`)\n\t\t\t\treturn textRecord\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No text record \"${key}\" found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error getting ENS text record ${key} for ${ensName}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get comprehensive ENS profile\n\t */\n\tasync getENSProfile(ensName: string) {\n\t\tconsole.log(`๐Ÿ‘ค Getting ENS profile for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst [address, avatar, description, twitter, github, url] =\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.resolveENSName(ensName),\n\t\t\t\t\tthis.getENSAvatar(ensName),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"description\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"com.twitter\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"com.github\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"url\")\n\t\t\t\t])\n\n\t\t\tconst profile = {\n\t\t\t\tensName,\n\t\t\t\taddress,\n\t\t\t\tavatar,\n\t\t\t\tdescription,\n\t\t\t\ttwitter,\n\t\t\t\tgithub,\n\t\t\t\turl\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… ENS profile for ${ensName}:`, profile)\n\t\t\treturn profile\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error getting ENS profile for ${ensName}:`, error)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Check if a name is a valid ENS name (.eth)\n\t */\n\tisENSName(name: string): boolean {\n\t\treturn name.endsWith(\".eth\") && !name.endsWith(\".base.eth\")\n\t}\n\n\t/**\n\t * Get cached address if not expired\n\t */\n\tprivate getCachedAddress(ensName: string): string | null {\n\t\tconst entry = this.cache.get(ensName.toLowerCase())\n\t\tif (!entry) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.cache.delete(ensName.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.address\n\t}\n\n\t/**\n\t * Cache address with LRU eviction\n\t */\n\tprivate setCachedAddress(ensName: string, address: string): void {\n\t\tif (this.cache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.cache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.cache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.cache.set(ensName.toLowerCase(), {\n\t\t\taddress,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached ENS name if not expired\n\t */\n\tprivate getCachedENSName(address: Address): string | null {\n\t\tconst entry = this.reverseCache.get(address.toLowerCase())\n\t\tif (!entry) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.reverseCache.delete(address.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.ensName\n\t}\n\n\t/**\n\t * Cache ENS name with LRU eviction\n\t */\n\tprivate setCachedENSName(address: Address, ensName: string): void {\n\t\tif (this.reverseCache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.reverseCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.reverseCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.reverseCache.set(address.toLowerCase(), {\n\t\t\tensName,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tconst addressCount = this.cache.size\n\t\tconst ensCount = this.reverseCache.size\n\n\t\tthis.cache.clear()\n\t\tthis.reverseCache.clear()\n\n\t\tconsole.log(`๐Ÿ—‘๏ธ ENS address cache cleared (${addressCount} entries removed)`)\n\t\tconsole.log(`๐Ÿ—‘๏ธ ENS reverse cache cleared (${ensCount} entries removed)`)\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats() {\n\t\treturn {\n\t\t\taddressCache: {\n\t\t\t\tsize: this.cache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\treverseCache: {\n\t\t\t\tsize: this.reverseCache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { XmtpClient, XmtpMessage } from \"../types\"\n\ninterface XmtpResolverOptions {\n\t/**\n\t * Maximum number of addresses to cache\n\t * @default 1000\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 86400000 (24 hours)\n\t */\n\tcacheTtl?: number\n\t/**\n\t * Maximum number of messages to cache\n\t * @default 1000\n\t */\n\tmaxMessageCacheSize?: number\n\t/**\n\t * Message cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tmessageCacheTtl?: number\n}\n\ninterface AddressCacheEntry {\n\taddress: string\n\ttimestamp: number\n}\n\ninterface MessageCacheEntry {\n\tmessage: XmtpMessage | null\n\ttimestamp: number\n}\n\nexport class XmtpResolver {\n\tprivate addressCache = new Map<string, AddressCacheEntry>()\n\tprivate messageCache = new Map<string, MessageCacheEntry>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly maxMessageCacheSize: number\n\tprivate readonly messageCacheTtl: number\n\n\tconstructor(\n\t\tprivate client: XmtpClient,\n\t\toptions: XmtpResolverOptions = {}\n\t) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 1000\n\t\tthis.cacheTtl = options.cacheTtl ?? 86400000 // 24 hours\n\t\tthis.maxMessageCacheSize = options.maxMessageCacheSize ?? 1000\n\t\tthis.messageCacheTtl = options.messageCacheTtl ?? 3600000 // 1 hour\n\t}\n\n\t/**\n\t * Resolve user address from inbox ID with caching\n\t */\n\tasync resolveAddress(\n\t\tinboxId: string,\n\t\tconversationId?: string\n\t): Promise<`0x${string}` | null> {\n\t\t// Check cache first (fastest)\n\t\tconst cached = this.getCachedAddress(inboxId)\n\t\tif (cached) {\n\t\t\tconsole.log(\n\t\t\t\t`โœ… [XmtpResolver] Resolved user address from cache: ${cached}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\tlet userAddress = undefined\n\n\t\ttry {\n\t\t\t// Try conversation members lookup first (faster than network call)\n\t\t\tif (conversationId) {\n\t\t\t\tconst conversation =\n\t\t\t\t\tawait this.client.conversations.getConversationById(conversationId)\n\t\t\t\tif (conversation) {\n\t\t\t\t\tuserAddress = await this.resolveFromConversation(\n\t\t\t\t\t\tconversation,\n\t\t\t\t\t\tinboxId\n\t\t\t\t\t)\n\t\t\t\t\tif (userAddress) {\n\t\t\t\t\t\tthis.setCachedAddress(inboxId, userAddress)\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`โœ… [XmtpResolver] Resolved user address: ${userAddress}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn userAddress\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fallback to inboxStateFromInboxIds\n\t\t\tuserAddress = await this.resolveFromInboxState(inboxId)\n\t\t\tif (userAddress) {\n\t\t\t\tthis.setCachedAddress(inboxId, userAddress)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… [XmtpResolver] Resolved user address via fallback: ${userAddress}`\n\t\t\t\t)\n\t\t\t\treturn userAddress\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] No identifiers found for inbox ${inboxId}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving user address for ${inboxId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Find any message by ID with caching\n\t */\n\tasync findMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\t// Check cache first\n\t\tconst cached = this.getCachedMessage(messageId)\n\t\tif (cached !== undefined) {\n\t\t\tconsole.log(\n\t\t\t\tcached\n\t\t\t\t\t? `โœ… [XmtpResolver] Found message from cache: ${cached.id}`\n\t\t\t\t\t: `โœ… [XmtpResolver] Found cached null message for: ${messageId}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ” [XmtpResolver] Finding message: ${messageId}`)\n\t\t\tconst message = await this.client.conversations.getMessageById(messageId)\n\n\t\t\tif (message) {\n\t\t\t\tthis.setCachedMessage(messageId, message)\n\t\t\t\tconsole.log(`โœ… [XmtpResolver] Found and cached message: ${message.id}`)\n\t\t\t\treturn message\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] Message not found: ${messageId}`)\n\t\t\tthis.setCachedMessage(messageId, null)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error finding message ${messageId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tthis.setCachedMessage(messageId, null)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Find root message with caching\n\t */\n\tasync findRootMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\t// Check if we already have the root cached with a special key\n\t\tconst rootCacheKey = `root:${messageId}`\n\t\tconst cached = this.getCachedMessage(rootCacheKey)\n\t\tif (cached !== undefined) {\n\t\t\tconsole.log(\n\t\t\t\tcached\n\t\t\t\t\t? `โœ… [XmtpResolver] Found root message from cache: ${cached.id}`\n\t\t\t\t\t: `โœ… [XmtpResolver] Found cached null root for: ${messageId}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ” [XmtpResolver] Finding root message for: ${messageId}`)\n\t\t\tconst rootMessage = await this.findRootMessageRecursive(messageId)\n\n\t\t\tif (rootMessage) {\n\t\t\t\tthis.setCachedMessage(rootCacheKey, rootMessage)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… [XmtpResolver] Found and cached root message: ${rootMessage.id}`\n\t\t\t\t)\n\t\t\t\treturn rootMessage\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] No root message found for: ${messageId}`)\n\t\t\tthis.setCachedMessage(rootCacheKey, null)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error finding root message for ${messageId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tthis.setCachedMessage(rootCacheKey, null)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Recursively finds the root message in a reply chain by following reply references\n\t */\n\tprivate async findRootMessageRecursive(\n\t\tmessageId: string,\n\t\tvisitedIds = new Set<string>()\n\t): Promise<XmtpMessage | null> {\n\t\t// Prevent infinite loops\n\t\tif (visitedIds.has(messageId)) {\n\t\t\tconsole.warn(\n\t\t\t\t`โš ๏ธ Circular reference detected in message chain at ${messageId}`\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t\tvisitedIds.add(messageId)\n\n\t\tconst message = await this.client.conversations.getMessageById(messageId)\n\n\t\tif (!message) {\n\t\t\tconsole.warn(`โš ๏ธ [findRootMessage] Message not found: ${messageId}`)\n\t\t\treturn null\n\t\t}\n\n\t\t// Debug: Log the raw message structure as returned by XMTP client\n\t\tconsole.log(`๐Ÿ” [findRootMessage] Raw message ${messageId}:`, {\n\t\t\tid: message.id,\n\t\t\tcontentType: message.contentType,\n\t\t\tcontent: message.content,\n\t\t\tsentAt: message.sentAt\n\t\t})\n\n\t\t// Method 1: Try the parameters (as seen in webhook data)\n\t\tif ((message as any).content?.reference) {\n\t\t\treturn this.findRootMessageRecursive(\n\t\t\t\t(message as any).content.reference,\n\t\t\t\tvisitedIds\n\t\t\t)\n\t\t}\n\n\t\treturn message\n\t}\n\n\t/**\n\t * Resolve address from conversation members\n\t */\n\tprivate async resolveFromConversation(\n\t\tconversation: any,\n\t\tinboxId: string\n\t): Promise<`0x${string}` | null> {\n\t\ttry {\n\t\t\tconst members = await conversation.members()\n\t\t\tconst sender = members.find(\n\t\t\t\t(member: any) => member.inboxId.toLowerCase() === inboxId.toLowerCase()\n\t\t\t)\n\n\t\t\tif (sender) {\n\t\t\t\tconst ethIdentifier = sender.accountIdentifiers.find(\n\t\t\t\t\t(id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n\t\t\t\t)\n\t\t\t\tif (ethIdentifier) {\n\t\t\t\t\treturn ethIdentifier.identifier\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`โš ๏ธ [XmtpResolver] No Ethereum identifier found for inbox ${inboxId}`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โš ๏ธ [XmtpResolver] Sender not found in conversation members for inbox ${inboxId}`\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving from conversation members:`,\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\n\t\treturn null\n\t}\n\n\t/**\n\t * Resolve address from inbox state (network fallback)\n\t */\n\tprivate async resolveFromInboxState(\n\t\tinboxId: string\n\t): Promise<`0x${string}` | null> {\n\t\ttry {\n\t\t\tconst inboxState = await this.client.preferences.inboxStateFromInboxIds([\n\t\t\t\tinboxId\n\t\t\t])\n\t\t\tconst firstState = inboxState?.[0]\n\t\t\tif (firstState?.identifiers && firstState.identifiers.length > 0) {\n\t\t\t\tconst firstIdentifier = firstState.identifiers[0]\n\t\t\t\treturn firstIdentifier?.identifier as `0x${string}`\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving from inbox state:`,\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\n\t\treturn null\n\t}\n\n\t/**\n\t * Get cached address if not expired\n\t */\n\tprivate getCachedAddress(inboxId: string): `0x${string}` | null {\n\t\tconst entry = this.addressCache.get(inboxId)\n\t\tif (!entry) return null\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.addressCache.delete(inboxId)\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.address as `0x${string}`\n\t}\n\n\t/**\n\t * Cache address with LRU eviction\n\t */\n\tprivate setCachedAddress(inboxId: string, address: `0x${string}`): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.addressCache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.addressCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.addressCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.addressCache.set(inboxId, {\n\t\t\taddress,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached message if not expired\n\t */\n\tprivate getCachedMessage(messageId: string): XmtpMessage | null | undefined {\n\t\tconst entry = this.messageCache.get(messageId)\n\t\tif (!entry) return undefined\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.messageCacheTtl) {\n\t\t\tthis.messageCache.delete(messageId)\n\t\t\treturn undefined\n\t\t}\n\n\t\treturn entry.message\n\t}\n\n\t/**\n\t * Cache message with LRU eviction\n\t */\n\tprivate setCachedMessage(\n\t\tmessageId: string,\n\t\tmessage: XmtpMessage | null\n\t): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.messageCache.size >= this.maxMessageCacheSize) {\n\t\t\tconst firstKey = this.messageCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.messageCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.messageCache.set(messageId, {\n\t\t\tmessage,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Pre-populate address cache from existing conversations\n\t */\n\tasync prePopulateCache(): Promise<void> {\n\t\tconsole.log(\"๐Ÿ”„ [XmtpResolver] Pre-populating address cache...\")\n\t\ttry {\n\t\t\tconst conversations = await this.client.conversations.list()\n\t\t\tlet cachedCount = 0\n\n\t\t\tfor (const conversation of conversations) {\n\t\t\t\ttry {\n\t\t\t\t\tconst members = await conversation.members()\n\t\t\t\t\tfor (const member of members) {\n\t\t\t\t\t\tconst ethIdentifier = member.accountIdentifiers.find(\n\t\t\t\t\t\t\t(id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (ethIdentifier) {\n\t\t\t\t\t\t\tthis.setCachedAddress(\n\t\t\t\t\t\t\t\tmember.inboxId,\n\t\t\t\t\t\t\t\tethIdentifier.identifier as `0x${string}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcachedCount++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"[XmtpResolver] Error pre-caching conversation members:\",\n\t\t\t\t\t\terror\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โœ… [XmtpResolver] Pre-cached ${cachedCount} address mappings`\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[XmtpResolver] Error pre-populating cache:\", error)\n\t\t}\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tthis.addressCache.clear()\n\t\tthis.messageCache.clear()\n\t\tconsole.log(\"๐Ÿ—‘๏ธ [XmtpResolver] All caches cleared\")\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats(): {\n\t\taddress: { size: number; maxSize: number }\n\t\tmessage: { size: number; maxSize: number }\n\t} {\n\t\treturn {\n\t\t\taddress: {\n\t\t\t\tsize: this.addressCache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\tmessage: {\n\t\t\t\tsize: this.messageCache.size,\n\t\t\t\tmaxSize: this.maxMessageCacheSize\n\t\t\t}\n\t\t}\n\t}\n}\n","import { type Address, type PublicClient } from \"viem\"\nimport type { XmtpClient, XmtpMessage, XmtpSender } from \"../types\"\nimport { AddressResolver } from \"./address-resolver\"\nimport {\n\ttype BaseName,\n\tBasenameResolver,\n\ttype BasenameTextRecordKey\n} from \"./basename-resolver\"\nimport { ENSResolver } from \"./ens-resolver\"\nimport { XmtpResolver } from \"./xmtp-resolver\"\n\ninterface ResolverOptions {\n\t/**\n\t * XMTP Client for message and address resolution\n\t */\n\txmtpClient: XmtpClient\n\t/**\n\t * Mainnet public client for ENS resolution\n\t */\n\tmainnetClient: PublicClient\n\t/**\n\t * Base network public client for basename resolution\n\t */\n\tbaseClient: PublicClient\n\t/**\n\t * Maximum cache size for each resolver\n\t * @default 1000\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n}\n\n/**\n * Master Resolver that wraps all individual resolvers\n * Provides a unified interface for basename, ENS, address, and XMTP resolution\n */\nexport class Resolver {\n\tprivate addressResolver: AddressResolver\n\tprivate ensResolver: ENSResolver\n\tprivate basenameResolver: BasenameResolver\n\tprivate xmtpResolver: XmtpResolver\n\n\tconstructor(options: ResolverOptions) {\n\t\tconst resolverOptions = {\n\t\t\tmaxCacheSize: options.maxCacheSize ?? 1000,\n\t\t\tcacheTtl: options.cacheTtl ?? 3600000\n\t\t}\n\n\t\tthis.addressResolver = new AddressResolver(\n\t\t\toptions.xmtpClient,\n\t\t\tresolverOptions\n\t\t)\n\t\tthis.xmtpResolver = new XmtpResolver(options.xmtpClient, resolverOptions)\n\n\t\t// Type assertions needed due to viem version differences across monorepo packages\n\t\t// Both clients are PublicClient-compatible but TypeScript sees them as incompatible types\n\t\tthis.ensResolver = new ENSResolver({\n\t\t\t...resolverOptions,\n\t\t\tmainnetClient: options.mainnetClient as PublicClient\n\t\t})\n\t\tthis.basenameResolver = new BasenameResolver({\n\t\t\t...resolverOptions,\n\t\t\tpublicClient: options.baseClient as PublicClient\n\t\t})\n\t}\n\n\t// === Address Resolution Methods ===\n\n\t/**\n\t * Resolve user address from inbox ID with caching\n\t * Uses both AddressResolver and XmtpResolver for redundancy\n\t */\n\tasync resolveAddress(\n\t\tinboxId: string,\n\t\tconversationId?: string\n\t): Promise<`0x${string}` | null> {\n\t\t// Try AddressResolver first, fallback to XmtpResolver\n\t\tlet result = await this.addressResolver.resolveAddress(\n\t\t\tinboxId,\n\t\t\tconversationId\n\t\t)\n\t\tif (!result) {\n\t\t\tresult = await this.xmtpResolver.resolveAddress(inboxId, conversationId)\n\t\t}\n\t\treturn result\n\t}\n\n\t// === ENS Resolution Methods ===\n\n\t/**\n\t * Resolve an ENS name to an Ethereum address\n\t */\n\tasync resolveENSName(ensName: string): Promise<Address | null> {\n\t\treturn this.ensResolver.resolveENSName(ensName)\n\t}\n\n\t/**\n\t * Resolve an address to its primary ENS name (reverse resolution)\n\t */\n\tasync resolveAddressToENS(address: Address): Promise<string | null> {\n\t\treturn this.ensResolver.resolveAddressToENS(address)\n\t}\n\n\t/**\n\t * Get ENS avatar for a given ENS name\n\t */\n\tasync getENSAvatar(ensName: string): Promise<string | null> {\n\t\treturn this.ensResolver.getENSAvatar(ensName)\n\t}\n\n\t/**\n\t * Get ENS text record for a given ENS name and key\n\t */\n\tasync getENSTextRecord(ensName: string, key: string): Promise<string | null> {\n\t\treturn this.ensResolver.getENSTextRecord(ensName, key)\n\t}\n\n\t/**\n\t * Get complete ENS profile for a given ENS name\n\t */\n\tasync getENSProfile(ensName: string) {\n\t\treturn this.ensResolver.getENSProfile(ensName)\n\t}\n\n\t// === Basename Resolution Methods ===\n\n\t/**\n\t * Get basename from an Ethereum address\n\t */\n\tasync getBasename(address: Address): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasename(address)\n\t}\n\n\t/**\n\t * Get basename avatar for a given basename\n\t */\n\tasync getBasenameAvatar(basename: BaseName): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasenameAvatar(basename)\n\t}\n\n\t/**\n\t * Get basename text record for a given basename and key\n\t */\n\tasync getBasenameTextRecord(\n\t\tbasename: BaseName,\n\t\tkey: BasenameTextRecordKey\n\t): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasenameTextRecord(basename, key)\n\t}\n\n\t/**\n\t * Resolve basename to an Ethereum address\n\t */\n\tasync getBasenameAddress(basename: BaseName): Promise<Address | null> {\n\t\treturn this.basenameResolver.getBasenameAddress(basename)\n\t}\n\n\t/**\n\t * Get basename metadata for a given basename\n\t */\n\tasync getBasenameMetadata(basename: BaseName) {\n\t\treturn this.basenameResolver.getBasenameMetadata(basename)\n\t}\n\n\t/**\n\t * Get complete basename profile for a given address\n\t */\n\tasync resolveBasenameProfile(address: Address) {\n\t\treturn this.basenameResolver.resolveBasenameProfile(address)\n\t}\n\n\t// === XMTP Message Methods ===\n\n\t/**\n\t * Find any message by ID with caching\n\t */\n\tasync findMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\treturn this.xmtpResolver.findMessage(messageId)\n\t}\n\n\t/**\n\t * Find root message by ID (traverses reply chain)\n\t */\n\tasync findRootMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\treturn this.xmtpResolver.findRootMessage(messageId)\n\t}\n\n\t// === Universal Resolution Methods ===\n\n\t/**\n\t * Universal name resolution - tries to resolve any name (ENS or basename) to an address\n\t */\n\tasync resolveName(name: string): Promise<Address | null> {\n\t\t// Try ENS first (more common)\n\t\tif (name.endsWith(\".eth\")) {\n\t\t\treturn this.resolveENSName(name)\n\t\t}\n\n\t\t// Try basename\n\t\tif (name.endsWith(\".base.eth\")) {\n\t\t\treturn this.getBasenameAddress(name)\n\t\t}\n\n\t\t// If no TLD, try both\n\t\tconst ensResult = await this.resolveENSName(name)\n\t\tif (ensResult) {\n\t\t\treturn ensResult\n\t\t}\n\n\t\treturn this.getBasenameAddress(name)\n\t}\n\n\t/**\n\t * Universal reverse resolution - tries to resolve an address to any name (ENS or basename)\n\t */\n\tasync resolveAddressToName(address: Address): Promise<string | null> {\n\t\t// Try basename first (more relevant for this project)\n\t\tconst basename = await this.getBasename(address)\n\t\tif (basename) {\n\t\t\treturn basename\n\t\t}\n\n\t\t// Try ENS as fallback\n\t\treturn this.resolveAddressToENS(address)\n\t}\n\n\t/**\n\t * Get complete profile for an address (combines ENS and basename data)\n\t */\n\tasync getCompleteProfile(address: Address) {\n\t\tconst [ensName, basename, ensProfile, basenameProfile] =\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.resolveAddressToENS(address),\n\t\t\t\tthis.getBasename(address),\n\t\t\t\tthis.resolveAddressToENS(address).then((name) =>\n\t\t\t\t\tname ? this.getENSProfile(name) : null\n\t\t\t\t),\n\t\t\t\tthis.resolveBasenameProfile(address)\n\t\t\t])\n\n\t\treturn {\n\t\t\taddress,\n\t\t\tensName: ensName.status === \"fulfilled\" ? ensName.value : null,\n\t\t\tbasename: basename.status === \"fulfilled\" ? basename.value : null,\n\t\t\tensProfile: ensProfile.status === \"fulfilled\" ? ensProfile.value : null,\n\t\t\tbasenameProfile:\n\t\t\t\tbasenameProfile.status === \"fulfilled\" ? basenameProfile.value : null\n\t\t}\n\t}\n\n\t// === Cache Management Methods ===\n\n\t/**\n\t * Pre-populate all resolver caches\n\t */\n\tasync prePopulateAllCaches(): Promise<void> {\n\t\tawait Promise.allSettled([\n\t\t\tthis.addressResolver.prePopulateCache(),\n\t\t\tthis.xmtpResolver.prePopulateCache()\n\t\t])\n\t}\n\n\t/**\n\t * Create a complete XmtpSender object from an address or inboxId\n\t * Uses the resolver to get the best available name and profile information\n\t */\n\tasync createXmtpSender(\n\t\taddressOrInboxId: string,\n\t\tconversationId?: string\n\t): Promise<XmtpSender> {\n\t\tlet address: `0x${string}` | null = null\n\t\tlet inboxId = addressOrInboxId\n\n\t\t// Check if input looks like an Ethereum address\n\t\tif (addressOrInboxId.startsWith(\"0x\") && addressOrInboxId.length === 42) {\n\t\t\taddress = addressOrInboxId as `0x${string}`\n\t\t\t// When we have an address, we need to find the actual inboxId\n\t\t\t// For now, use address as fallback but this should be resolved from XMTP\n\t\t\tinboxId = addressOrInboxId // This will be improved when we have proper address->inboxId resolution\n\t\t} else {\n\t\t\t// Assume it's an inboxId, try to resolve to address\n\t\t\taddress = await this.resolveAddress(addressOrInboxId, conversationId)\n\t\t}\n\n\t\t// Get the best available name using universal resolution\n\t\tlet name = \"Unknown\"\n\t\tlet basename: string | undefined\n\n\t\tif (address) {\n\t\t\t// Try basename first since that's what we expect for this address\n\t\t\tconst basenameResult = await this.getBasename(address)\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” [RESOLVER] Direct basename lookup for ${address}:`,\n\t\t\t\tbasenameResult\n\t\t\t)\n\n\t\t\t// Try to get a human-readable name\n\t\t\tconst resolvedName = await this.resolveAddressToName(address)\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” [RESOLVER] Universal name resolution for ${address}:`,\n\t\t\t\tresolvedName\n\t\t\t)\n\n\t\t\tif (resolvedName) {\n\t\t\t\tname = resolvedName\n\t\t\t\t// Check if it's a basename specifically\n\t\t\t\tif (resolvedName.endsWith(\".base.eth\")) {\n\t\t\t\t\tbasename = resolvedName\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Fallback to shortened address\n\t\t\t\tname = `${address.slice(0, 6)}...${address.slice(-4)}`\n\t\t\t}\n\n\t\t\t// Always try to get basename even if ENS was found\n\t\t\tif (!basename) {\n\t\t\t\tconst resolvedBasename = await this.getBasename(address)\n\t\t\t\tbasename = resolvedBasename || undefined\n\t\t\t}\n\t\t} else {\n\t\t\t// No address resolution available, use inboxId\n\t\t\tname = `${inboxId.slice(0, 8)}...${inboxId.slice(-4)}`\n\t\t}\n\n\t\treturn {\n\t\t\taddress: address || addressOrInboxId,\n\t\t\tinboxId,\n\t\t\tname,\n\t\t\tbasename\n\t\t}\n\t}\n}\n","import type { BasenameResolver } from \"../resolver/basename-resolver\"\nimport type { ENSResolver } from \"../resolver/ens-resolver\"\n\n/**\n * Extract basenames/ENS names from message content using @mention pattern\n * @param content The message content to parse\n * @returns Array of unique names found in the message\n */\nexport function extractMentionedNames(content: string): string[] {\n\t// Match @basename.eth and @basename.base.eth patterns (case insensitive)\n\tconst nameRegex = /@([a-zA-Z0-9-_]+\\.(?:base\\.)?eth)\\b/gi\n\tconst matches = content.match(nameRegex)\n\n\tif (!matches) {\n\t\treturn []\n\t}\n\n\t// Remove @ symbol and deduplicate\n\tconst names = matches.map((match) => match.slice(1).toLowerCase())\n\treturn [...new Set(names)]\n}\n\n/**\n * Resolve mentioned names to addresses and return as subjects object\n * @param mentionedNames Array of names to resolve\n * @param basenameResolver Basename resolver instance\n * @param ensResolver ENS resolver instance\n * @returns Promise that resolves to subjects object mapping names to addresses\n */\nexport async function resolveSubjects(\n\tmentionedNames: string[],\n\tbasenameResolver: BasenameResolver,\n\tensResolver: ENSResolver\n): Promise<Record<string, `0x${string}`>> {\n\tconst subjects: Record<string, `0x${string}`> = {}\n\n\tif (mentionedNames.length === 0) {\n\t\treturn subjects\n\t}\n\n\tconsole.log(\n\t\t`๐Ÿ” Found ${mentionedNames.length} name mentions:`,\n\t\tmentionedNames\n\t)\n\n\tfor (const mentionedName of mentionedNames) {\n\t\ttry {\n\t\t\tlet resolvedAddress: string | null = null\n\n\t\t\t// Check if it's an ENS name (.eth but not .base.eth)\n\t\t\tif (ensResolver.isENSName(mentionedName)) {\n\t\t\t\tconsole.log(`๐Ÿ” Resolving ENS name: ${mentionedName}`)\n\t\t\t\tresolvedAddress = await ensResolver.resolveENSName(mentionedName)\n\t\t\t} else {\n\t\t\t\t// It's a basename (.base.eth or other format)\n\t\t\t\tconsole.log(`๐Ÿ” Resolving basename: ${mentionedName}`)\n\t\t\t\tresolvedAddress =\n\t\t\t\t\tawait basenameResolver.getBasenameAddress(mentionedName)\n\t\t\t}\n\n\t\t\tif (resolvedAddress) {\n\t\t\t\tsubjects[mentionedName] = resolvedAddress as `0x${string}`\n\t\t\t\tconsole.log(`โœ… Resolved ${mentionedName} โ†’ ${resolvedAddress}`)\n\t\t\t} else {\n\t\t\t\tconsole.log(`โŒ Could not resolve address for: ${mentionedName}`)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error resolving ${mentionedName}:`, error)\n\t\t}\n\t}\n\n\treturn subjects\n}\n\n/**\n * Extract subjects from message content (combines extraction and resolution)\n * @param content The message content to parse\n * @param basenameResolver Basename resolver instance\n * @param ensResolver ENS resolver instance\n * @returns Promise that resolves to subjects object mapping names to addresses\n */\nexport async function extractSubjects(\n\tcontent: string,\n\tbasenameResolver: BasenameResolver,\n\tensResolver: ENSResolver\n): Promise<Record<string, `0x${string}`>> {\n\tconst mentionedNames = extractMentionedNames(content)\n\treturn await resolveSubjects(mentionedNames, basenameResolver, ensResolver)\n}\n","/**\n * @fileoverview XMTP Service Client Library\n *\n * Clean, reusable client for making HTTP calls to the XMTP listener service.\n * Handles authentication, request formatting, and error handling.\n *\n * This is different from the direct XMTP client - this is for external services\n * talking to our XMTP listener service.\n */\n\nimport type {\n\tGetMessageParams,\n\tSendMessageParams,\n\tSendMessageResponse,\n\tSendReactionParams,\n\tSendReactionResponse,\n\tSendReplyParams,\n\tSendReplyResponse,\n\tSendTransactionParams,\n\tSendTransactionResponse,\n\tXmtpServiceClientConfig,\n\tXmtpServiceMessage,\n\tXmtpServiceResponse\n} from \"./types\"\n\nexport class XmtpServiceClient {\n\tprivate config: XmtpServiceClientConfig\n\n\tconstructor(config: XmtpServiceClientConfig) {\n\t\tthis.config = config\n\t}\n\n\tprivate async request<T = unknown>(\n\t\tendpoint: string,\n\t\tbody?: Record<string, unknown>,\n\t\tmethod: \"GET\" | \"POST\" = \"POST\"\n\t): Promise<XmtpServiceResponse<T>> {\n\t\ttry {\n\t\t\tconst baseUrl = this.config.serviceUrl.replace(/\\/+$/, \"\")\n\n\t\t\t// Use Authorization header for xmtp-tools endpoints, query parameter for others\n\t\t\tconst isXmtpToolsEndpoint = endpoint.startsWith(\"/xmtp-tools/\")\n\t\t\tconst url = `${baseUrl}${endpoint}?token=${this.config.serviceToken}`\n\n\t\t\tconst headers: Record<string, string> = {\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t}\n\n\t\t\t// Add Authorization header for xmtp-tools endpoints\n\t\t\tif (isXmtpToolsEndpoint) {\n\t\t\t\theaders.Authorization = `Bearer ${this.config.serviceToken}`\n\t\t\t}\n\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod,\n\t\t\t\theaders\n\t\t\t}\n\n\t\t\tif (method === \"POST\" && body) {\n\t\t\t\tfetchOptions.body = JSON.stringify(body)\n\t\t\t}\n\n\t\t\tconst response = await fetch(url, fetchOptions)\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`\n\t\t\t\ttry {\n\t\t\t\t\tconst responseText = await response.text()\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst errorData = JSON.parse(responseText) as { error?: string }\n\t\t\t\t\t\terrorMessage = errorData.error || errorMessage\n\t\t\t\t\t} catch {\n\t\t\t\t\t\terrorMessage = responseText || errorMessage\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If we can't read the response at all, use the status\n\t\t\t\t}\n\t\t\t\tthrow new Error(errorMessage)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: (await response.json()) as T\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpServiceClient] Request to ${endpoint} failed:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error.message : \"Unknown error\"\n\t\t\t}\n\t\t}\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendMessageParams\n\t): Promise<XmtpServiceResponse<SendMessageResponse>> {\n\t\treturn this.request<SendMessageResponse>(\"/xmtp-tools/send\", {\n\t\t\tcontent: params.content\n\t\t})\n\t}\n\n\tasync sendReply(\n\t\tparams: SendReplyParams\n\t): Promise<XmtpServiceResponse<SendReplyResponse>> {\n\t\treturn this.request<SendReplyResponse>(\"/xmtp-tools/reply\", {\n\t\t\tcontent: params.content,\n\t\t\tmessageId: params.messageId\n\t\t})\n\t}\n\n\tasync sendReaction(\n\t\tparams: SendReactionParams\n\t): Promise<XmtpServiceResponse<SendReactionResponse>> {\n\t\treturn this.request<SendReactionResponse>(\"/xmtp-tools/react\", {\n\t\t\tmessageId: params.messageId,\n\t\t\temoji: params.emoji,\n\t\t\taction: params.action\n\t\t})\n\t}\n\n\tasync sendTransaction(\n\t\tparams: SendTransactionParams\n\t): Promise<XmtpServiceResponse<SendTransactionResponse>> {\n\t\treturn this.request<SendTransactionResponse>(\"/xmtp-tools/transaction\", {\n\t\t\tfromAddress: params.fromAddress,\n\t\t\tchainId: params.chainId,\n\t\t\tcalls: params.calls.map((call) => ({\n\t\t\t\tto: call.to,\n\t\t\t\tdata: call.data,\n\t\t\t\t...(call.gas && { gas: call.gas }),\n\t\t\t\tvalue: call.value || \"0x0\",\n\t\t\t\tmetadata: {\n\t\t\t\t\t...call.metadata,\n\t\t\t\t\tchainId: params.chainId,\n\t\t\t\t\tfrom: params.fromAddress,\n\t\t\t\t\tversion: \"1\"\n\t\t\t\t}\n\t\t\t}))\n\t\t})\n\t}\n\n\t/**\n\t * Get a single message by ID\n\t */\n\tasync getMessage(\n\t\tparams: GetMessageParams\n\t): Promise<XmtpServiceResponse<XmtpServiceMessage>> {\n\t\treturn this.request<XmtpServiceMessage>(\n\t\t\t`/xmtp-tools/messages/${params.messageId}`,\n\t\t\tundefined,\n\t\t\t\"GET\"\n\t\t)\n\t}\n\n\t// getConversationMessages removed - superseded by thread-based approach\n}\n\n/**\n * Create an XMTP service client from runtime context\n * Expects the runtime context to have xmtpServiceUrl and xmtpServiceToken\n */\nexport function createXmtpServiceClient(\n\tserviceUrl: string,\n\tserviceToken: string\n): XmtpServiceClient {\n\tif (!serviceUrl || !serviceToken) {\n\t\tthrow new Error(\"Missing XMTP service URL or token from runtime context\")\n\t}\n\n\treturn new XmtpServiceClient({\n\t\tserviceUrl,\n\t\tserviceToken\n\t})\n}\n\nexport interface XmtpAuthConfig {\n\tserviceUrl: string\n\tserviceToken: string\n\tsource: \"callback\" | \"environment\"\n}\n\n/**\n * Get XMTP authentication configuration from multiple sources\n * Priority: callback credentials > environment credentials\n */\nexport function getXmtpAuthConfig(\n\tcallbackUrl?: string,\n\tcallbackToken?: string\n): XmtpAuthConfig | null {\n\t// Priority 1: Use callback credentials if available\n\tif (callbackUrl && callbackToken) {\n\t\tconsole.log(\"๐Ÿ”‘ [XmtpAuth] Using callback-provided credentials\")\n\t\treturn {\n\t\t\tserviceUrl: callbackUrl,\n\t\t\tserviceToken: callbackToken,\n\t\t\tsource: \"callback\"\n\t\t}\n\t}\n\n\t// Priority 2: Use environment credentials\n\tconst envUrl = process.env.XMTP_HOST\n\tconst envToken = process.env.XMTP_API_KEY\n\n\tif (envUrl && envToken) {\n\t\tconsole.log(\"๐Ÿ”‘ [XmtpAuth] Using environment credentials\")\n\t\treturn {\n\t\t\tserviceUrl: envUrl,\n\t\t\tserviceToken: envToken,\n\t\t\tsource: \"environment\"\n\t\t}\n\t}\n\n\t// No valid credentials found\n\tconsole.error(\n\t\t\"โŒ [XmtpAuth] No XMTP credentials found in callback or environment\"\n\t)\n\tconsole.error(\n\t\t\"๐Ÿ’ก [XmtpAuth] Expected: XMTP_HOST + XMTP_API_KEY or callback credentials\"\n\t)\n\treturn null\n}\n\n/**\n * Create an authenticated XMTP service client\n * Handles both callback and environment credential sources\n */\nexport function createAuthenticatedXmtpClient(\n\tcallbackUrl?: string,\n\tcallbackToken?: string\n): XmtpServiceClient {\n\tconst authConfig = getXmtpAuthConfig(callbackUrl, callbackToken)\n\n\tif (!authConfig) {\n\t\tthrow new Error(\"No XMTP credentials found\")\n\t}\n\n\tconsole.log(\n\t\t`๐Ÿ”— [XmtpAuth] Creating XMTP client (${authConfig.source} credentials)`\n\t)\n\n\treturn createXmtpServiceClient(authConfig.serviceUrl, authConfig.serviceToken)\n}\n\n/**\n * Constructs a URL for XMTP tools API endpoints with token authentication\n *\n * @param {string} baseUrl - The base URL of the XMTP service (e.g., \"https://api.example.com\")\n * @param {string} action - The specific action/endpoint to call (e.g., \"send\", \"receive\", \"status\")\n * @param {string} token - Authentication token (either JWT or API key)\n * @returns {string} Complete URL with token as query parameter\n *\n * @description\n * Builds URLs for XMTP tools endpoints using query parameter authentication.\n * The token is appended as a query parameter for GET request authentication,\n * following the pattern: `/xmtp-tools/{action}?token={token}`\n *\n * @example\n * ```typescript\n * const url = getXMTPToolsUrl(\n * \"https://api.hybrid.dev\",\n * \"send\",\n * \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n * );\n * // Returns: \"https://api.hybrid.dev/xmtp-tools/send?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n * ```\n *\n * @example\n * ```typescript\n * // Using with API key\n * const url = getXMTPToolsUrl(\n * process.env.XMTP_BASE_URL,\n * \"status\",\n * process.env.XMTP_API_KEY\n * );\n * ```\n */\nexport function getXMTPToolsUrl(\n\tbaseUrl: string,\n\taction: string,\n\ttoken: string\n): string {\n\treturn `${baseUrl}/xmtp-tools/${action}?token=${token}`\n}\n","// ===================================================================\n// XMTP Package - Main Entry Point\n// ===================================================================\n// This package provides a clean interface to XMTP functionality\n// Re-exports core XMTP SDK types and utilities\n\nexport * from \"./client\"\nexport * from \"./constants\"\nexport * from \"./lib/message-listener\"\nexport * from \"./lib/subjects\"\nexport * from \"./resolver\"\nexport * from \"./resolver/basename-resolver\"\nexport * from \"./resolver/ens-resolver\"\nexport * from \"./resolver/xmtp-resolver\"\nexport * from \"./service-client\"\nexport * from \"./types\"\n\n// ===================================================================\n// Enhanced XMTP Client & Connection Management\n// ===================================================================\nexport {\n\tcreateXMTPConnectionManager,\n\t// Enhanced connection management\n\tXMTPConnectionManager,\n\ttype XMTPConnectionConfig,\n\ttype XMTPConnectionHealth\n} from \"./client\"\n\n// ===================================================================\n// XMTP Service Client (for external service communication)\n// ===================================================================\nexport {\n\tcreateXmtpServiceClient,\n\tXmtpServiceClient\n} from \"./service-client\"\n\n// Service Client Types\nexport type {\n\tGetMessageParams,\n\tGetRootMessageParams,\n\t// Function parameter types\n\tSendMessageParams,\n\t// Response types\n\tSendMessageResponse,\n\tSendReactionParams,\n\tSendReactionResponse,\n\tSendReplyParams,\n\tSendReplyResponse,\n\tSendTransactionParams,\n\tSendTransactionResponse,\n\tTransactionCall,\n\tTransactionRequest,\n\tXmtpRootMessageResponse,\n\tXmtpServiceClientConfig,\n\tXmtpServiceMessage,\n\tXmtpServiceResponse\n} from \"./types\"\n\n// ===================================================================\n// XMTP Core SDK Exports\n// ===================================================================\nexport {\n\tClient,\n\tIdentifierKind,\n\t// type Conversation,\n\ttype DecodedMessage,\n\ttype Dm,\n\t// type Group,\n\ttype LogLevel,\n\ttype Signer,\n\ttype XmtpEnv\n} from \"@xmtp/node-sdk\"\n\n// ===================================================================\n// XMTP Content Types\n// ===================================================================\nexport {\n\tContentTypeTransactionReference,\n\ttype TransactionReference\n} from \"@xmtp/content-type-transaction-reference\"\n\nexport { ContentTypeText, type TextParameters } from \"@xmtp/content-type-text\"\n\nexport {\n\tContentTypeReaction,\n\ttype Reaction\n} from \"@xmtp/content-type-reaction\"\n\nexport {\n\tContentTypeReply,\n\tReplyCodec,\n\ttype Reply\n} from \"@xmtp/content-type-reply\"\n\nexport {\n\tContentTypeGroupUpdated,\n\tGroupUpdatedCodec,\n\ttype GroupUpdated\n} from \"@xmtp/content-type-group-updated\"\n\nexport {\n\tContentTypeWalletSendCalls,\n\ttype WalletSendCallsParams\n} from \"@xmtp/content-type-wallet-send-calls\"\n\n// ===================================================================\n// Local Client Utilities\n// ===================================================================\nexport {\n\tbackupDbToPersistentStorage,\n\tcreateSigner,\n\tcreateUser,\n\tcreateXMTPClient,\n\tdiagnoseXMTPIdentityIssue,\n\tgenerateEncryptionKeyHex,\n\tgetEncryptionKeyFromHex,\n\tlogAgentDetails,\n\tstartPeriodicBackup,\n\tvalidateEnvironment\n} from \"./client\"\n\n// ===================================================================\n// Application Constants\n// ===================================================================\nexport {\n\tDEFAULT_AMOUNT,\n\tDEFAULT_OPTIONS,\n\tMAX_USDC_AMOUNT\n} from \"./constants\"\n"],"mappings":"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","names":["Client","Client","identifier","address","http","mainnet","mainnet","http","IdentifierKind","ReplyCodec"]}
1
+ {"version":3,"sources":["../src/client.ts","../scripts/revoke-installations.ts","../src/constants.ts","../src/lib/message-listener.ts","../src/resolver/address-resolver.ts","../src/resolver/basename-resolver.ts","../src/abi/l2_resolver.ts","../src/resolver/ens-resolver.ts","../src/resolver/xmtp-resolver.ts","../src/resolver/resolver.ts","../src/lib/subjects.ts","../src/service-client.ts","../src/endpoints.ts","../src/lib/jwt.ts","../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { ReactionCodec } from \"@xmtp/content-type-reaction\"\nimport { ReplyCodec } from \"@xmtp/content-type-reply\"\nimport { TransactionReferenceCodec } from \"@xmtp/content-type-transaction-reference\"\nimport { WalletSendCallsCodec } from \"@xmtp/content-type-wallet-send-calls\"\nimport { Client, IdentifierKind, type Signer, XmtpEnv } from \"@xmtp/node-sdk\"\nimport { getRandomValues } from \"node:crypto\"\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { fromString, toString as uint8arraysToString } from \"uint8arrays\"\nimport { createWalletClient, http, toBytes } from \"viem\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { sepolia } from \"viem/chains\"\nimport { revokeOldInstallations } from \"../scripts/revoke-installations\"\nimport { XmtpClient } from \"./types\"\n\n// ===================================================================\n// Module Setup\n// ===================================================================\n// ES module equivalent of __dirname\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// ===================================================================\n// Type Definitions\n// ===================================================================\ninterface User {\n\tkey: `0x${string}`\n\taccount: ReturnType<typeof privateKeyToAccount>\n\twallet: any // Simplified to avoid deep type instantiation\n}\n\n// ===================================================================\n// User and Signer Creation\n// ===================================================================\nexport const createUser = (key: string): User => {\n\tconst account = privateKeyToAccount(key as `0x${string}`)\n\treturn {\n\t\tkey: key as `0x${string}`,\n\t\taccount,\n\t\twallet: createWalletClient({\n\t\t\taccount,\n\t\t\tchain: sepolia,\n\t\t\ttransport: http()\n\t\t})\n\t}\n}\n\nexport const createSigner = (key: string): Signer => {\n\tif (!key || typeof key !== \"string\") {\n\t\tthrow new Error(\"XMTP wallet key must be a non-empty string\")\n\t}\n\tconst sanitizedKey = key.startsWith(\"0x\") ? key : `0x${key}`\n\tconst user = createUser(sanitizedKey)\n\treturn {\n\t\ttype: \"EOA\",\n\t\tgetIdentifier: () => ({\n\t\t\tidentifierKind: 0 as IdentifierKind.Ethereum, // Use numeric value to avoid ambient const enum issue\n\t\t\tidentifier: user.account.address.toLowerCase()\n\t\t}),\n\t\tsignMessage: async (message: string) => {\n\t\t\tconst signature = await user.wallet.signMessage({\n\t\t\t\tmessage,\n\t\t\t\taccount: user.account\n\t\t\t})\n\t\t\treturn toBytes(signature)\n\t\t}\n\t}\n}\n\n// XMTP XmtpClient setup\n// const xmtpClient: XmtpClient | null = null\n\n// Function to clear XMTP database when hitting installation limits\nasync function clearXMTPDatabase(address: string, env: string) {\n\tconsole.log(\"๐Ÿงน Clearing XMTP database to resolve installation limit...\")\n\n\t// Get the storage directory using the same logic as getDbPath\n\tconst getStorageDirectory = () => {\n\t\tconst customStoragePath = process.env.XMTP_STORAGE_PATH\n\n\t\tif (customStoragePath) {\n\t\t\treturn path.isAbsolute(customStoragePath)\n\t\t\t\t? customStoragePath\n\t\t\t\t: path.resolve(process.cwd(), customStoragePath)\n\t\t}\n\n\t\t// Use existing logic as fallback\n\t\tconst projectRoot =\n\t\t\tprocess.env.PROJECT_ROOT || path.resolve(__dirname, \"../../..\")\n\n\t\treturn path.join(projectRoot, \".data/xmtp\") // Local development\n\t}\n\n\t// Clear local database files\n\tconst dbPattern = `${env}-${address}.db3`\n\tconst storageDir = getStorageDirectory()\n\n\t// Primary storage directory\n\tconst possiblePaths = [\n\t\tstorageDir,\n\t\t// Legacy fallback paths for backward compatibility\n\t\tpath.join(process.cwd(), \".data\", \"xmtp\"),\n\t\tpath.join(process.cwd(), \"..\", \".data\", \"xmtp\"),\n\t\tpath.join(process.cwd(), \"..\", \"..\", \".data\", \"xmtp\")\n\t]\n\n\tfor (const dir of possiblePaths) {\n\t\ttry {\n\t\t\tif (fs.existsSync(dir)) {\n\t\t\t\tconst files = fs.readdirSync(dir)\n\t\t\t\tconst matchingFiles = files.filter(\n\t\t\t\t\t(file) =>\n\t\t\t\t\t\tfile.includes(dbPattern) ||\n\t\t\t\t\t\tfile.includes(address) ||\n\t\t\t\t\t\tfile.includes(`xmtp-${env}-${address}`)\n\t\t\t\t)\n\n\t\t\t\tfor (const file of matchingFiles) {\n\t\t\t\t\tconst fullPath = path.join(dir, file)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfs.unlinkSync(fullPath)\n\t\t\t\t\t\tconsole.log(`โœ… Removed: ${fullPath}`)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.log(`โš ๏ธ Could not remove ${fullPath}:`, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Ignore errors when checking directories\n\t\t}\n\t}\n}\n\nexport async function createXMTPClient(\n\t// signer: Signer,\n\tprivateKey: string,\n\topts?: {\n\t\tpersist?: boolean\n\t\tmaxRetries?: number\n\t\tstoragePath?: string\n\t}\n): Promise<XmtpClient> {\n\tconst { persist = true, maxRetries = 3, storagePath } = opts ?? {}\n\tlet attempt = 0\n\n\t// Extract common variables for error handling\n\t// const actualSigner = signer\n\tconst signer = createSigner(privateKey)\n\n\tif (!signer) {\n\t\tthrow new Error(\n\t\t\t\"No signer provided and XMTP_WALLET_KEY environment variable is not set\"\n\t\t)\n\t}\n\n\tconst { XMTP_ENCRYPTION_KEY, XMTP_ENV } = process.env\n\n\t// Get the wallet address to use the correct database\n\tconst identifier = await signer.getIdentifier()\n\tconst address = identifier.identifier\n\n\twhile (attempt < maxRetries) {\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ”„ Attempt ${attempt + 1}/${maxRetries} to create XMTP client...`\n\t\t\t)\n\n\t\t\t// Always require encryption key and persistence - no stateless mode\n\t\t\tif (!persist) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Stateless mode is not supported. XMTP client must run in persistent mode \" +\n\t\t\t\t\t\t\"to properly receive and process messages. Set persist: true or remove the persist option \" +\n\t\t\t\t\t\t\"to use the default persistent mode.\"\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!XMTP_ENCRYPTION_KEY) {\n\t\t\t\tthrow new Error(\"XMTP_ENCRYPTION_KEY must be set for persistent mode\")\n\t\t\t}\n\n\t\t\tconst dbEncryptionKey = getEncryptionKeyFromHex(XMTP_ENCRYPTION_KEY)\n\t\t\tconst dbPath = await getDbPath(\n\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`,\n\t\t\t\tstoragePath\n\t\t\t)\n\t\t\tconsole.log(`๐Ÿ“ Using database path: ${dbPath}`)\n\n\t\t\t// Always create a fresh client and sync it\n\t\t\tconst client = await Client.create(signer, {\n\t\t\t\tdbEncryptionKey,\n\t\t\t\tenv: XMTP_ENV as XmtpEnv,\n\t\t\t\tdbPath,\n\t\t\t\tcodecs: [\n\t\t\t\t\tnew ReplyCodec(),\n\t\t\t\t\tnew ReactionCodec(),\n\t\t\t\t\tnew WalletSendCallsCodec(),\n\t\t\t\t\tnew TransactionReferenceCodec()\n\t\t\t\t]\n\t\t\t})\n\n\t\t\t// Force sync conversations to ensure we have the latest data\n\t\t\tconsole.log(\"๐Ÿ“ก Syncing conversations to ensure latest state...\")\n\t\t\tawait client.conversations.sync()\n\n\t\t\tawait backupDbToPersistentStorage(\n\t\t\t\tdbPath,\n\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`\n\t\t\t)\n\n\t\t\tconsole.log(\"โœ… XMTP XmtpClient created\")\n\t\t\tconsole.log(`๐Ÿ”‘ Wallet address: ${address}`)\n\t\t\tconsole.log(`๐ŸŒ Environment: ${XMTP_ENV || \"dev\"}`)\n\t\t\tconsole.log(`๐Ÿ’พ Storage mode: persistent`)\n\n\t\t\treturn client\n\t\t} catch (error) {\n\t\t\tattempt++\n\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"5/5 installations\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ’ฅ Installation limit reached (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\t// Get wallet address for database clearing\n\t\t\t\t\tconst identifier = await signer.getIdentifier()\n\t\t\t\t\tconst address = identifier.identifier\n\n\t\t\t\t\t// Extract inboxId from the error message\n\t\t\t\t\tconst inboxIdMatch = error.message.match(/InboxID ([a-f0-9]+)/)\n\t\t\t\t\tconst inboxId = inboxIdMatch ? inboxIdMatch[1] : undefined\n\n\t\t\t\t\t// First try to revoke old installations\n\t\t\t\t\tconst revocationSuccess = await revokeOldInstallations(\n\t\t\t\t\t\tsigner,\n\t\t\t\t\t\tinboxId\n\t\t\t\t\t)\n\n\t\t\t\t\tif (revocationSuccess) {\n\t\t\t\t\t\tconsole.log(\"๐ŸŽฏ Installations revoked, retrying connection...\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โš ๏ธ Installation revocation failed or not needed, clearing database...\"\n\t\t\t\t\t\t)\n\t\t\t\t\t\t// Clear database as fallback\n\t\t\t\t\t\tawait clearXMTPDatabase(address, process.env.XMTP_ENV || \"dev\")\n\t\t\t\t\t}\n\n\t\t\t\t\t// Wait a bit before retrying\n\t\t\t\t\tconst delay = Math.pow(2, attempt) * 1000 // Exponential backoff\n\t\t\t\t\tconsole.log(`โณ Waiting ${delay}ms before retry...`)\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay))\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"โŒ Failed to resolve installation limit after all retries\"\n\t\t\t\t\t)\n\t\t\t\t\tconsole.error(\"๐Ÿ’ก Possible solutions:\")\n\t\t\t\t\tconsole.error(\" 1. Use a different wallet (generate new keys)\")\n\t\t\t\t\tconsole.error(\" 2. Switch XMTP environments (dev <-> production)\")\n\t\t\t\t\tconsole.error(\" 3. Wait and try again later\")\n\t\t\t\t\tconsole.error(\" 4. Contact XMTP support for manual intervention\")\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"Association error: Missing identity update\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ Identity association error detected (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconsole.log(\"๐Ÿ”ง Attempting automatic identity refresh...\")\n\n\t\t\t\t\t// Try to refresh identity by creating a persistent client first\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ Creating persistent client to refresh identity...\")\n\t\t\t\t\t\tconst tempEncryptionKey = XMTP_ENCRYPTION_KEY\n\t\t\t\t\t\t\t? getEncryptionKeyFromHex(XMTP_ENCRYPTION_KEY)\n\t\t\t\t\t\t\t: getEncryptionKeyFromHex(generateEncryptionKeyHex())\n\t\t\t\t\t\tconst tempClient = await Client.create(signer, {\n\t\t\t\t\t\t\tdbEncryptionKey: tempEncryptionKey,\n\t\t\t\t\t\t\tenv: XMTP_ENV as XmtpEnv,\n\t\t\t\t\t\t\tdbPath: await getDbPath(\n\t\t\t\t\t\t\t\t`${XMTP_ENV || \"dev\"}-${address}`,\n\t\t\t\t\t\t\t\tstoragePath\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tcodecs: [\n\t\t\t\t\t\t\t\tnew ReplyCodec(),\n\t\t\t\t\t\t\t\tnew ReactionCodec(),\n\t\t\t\t\t\t\t\tnew WalletSendCallsCodec(),\n\t\t\t\t\t\t\t\tnew TransactionReferenceCodec()\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ก Syncing identity and conversations...\")\n\t\t\t\t\t\tawait tempClient.conversations.sync()\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โœ… Identity refresh successful, retrying original request...\"\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Wait a bit before retrying\n\t\t\t\t\t\tconst delay = Math.pow(2, attempt) * 1000 // Exponential backoff\n\t\t\t\t\t\tconsole.log(`โณ Waiting ${delay}ms before retry...`)\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, delay))\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\tconsole.log(`โŒ Identity refresh failed:`, refreshError)\n\t\t\t\t\t\t// Continue to the retry logic\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"โŒ Failed to resolve identity association error after all retries\"\n\t\t\t\t\t)\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"๐Ÿ’ก Try running: pnpm with-env pnpm --filter @hybrd/xmtp refresh:identity\"\n\t\t\t\t\t)\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For other errors, don't retry\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(\"Max retries exceeded\")\n}\n\n// ===================================================================\n// Encryption Key Management\n// ===================================================================\n/**\n * Generate a random encryption key\n * @returns The encryption key as a hex string\n */\nexport const generateEncryptionKeyHex = () => {\n\tconst uint8Array = getRandomValues(new Uint8Array(32))\n\treturn uint8arraysToString(uint8Array, \"hex\")\n}\n\n/**\n * Get the encryption key from a hex string\n * @param hex - The hex string\n * @returns The encryption key as Uint8Array\n */\nexport const getEncryptionKeyFromHex = (hex: string): Uint8Array => {\n\treturn fromString(hex, \"hex\")\n}\n\n// ===================================================================\n// Database Path Management\n// ===================================================================\nexport const getDbPath = async (description = \"xmtp\", storagePath?: string) => {\n\t// Allow custom storage path via environment variable\n\tconst customStoragePath = process.env.XMTP_STORAGE_PATH\n\n\tlet volumePath: string\n\n\tif (customStoragePath) {\n\t\t// Use custom storage path if provided\n\t\tvolumePath = path.isAbsolute(customStoragePath)\n\t\t\t? customStoragePath\n\t\t\t: path.resolve(process.cwd(), customStoragePath)\n\t} else if (storagePath) {\n\t\tvolumePath = path.isAbsolute(storagePath)\n\t\t\t? storagePath\n\t\t\t: path.resolve(process.cwd(), storagePath)\n\t} else {\n\t\t// Use existing logic as fallback\n\t\tconst projectRoot =\n\t\t\tprocess.env.PROJECT_ROOT || path.resolve(__dirname, \"../../..\")\n\n\t\t// Default storage path for local development\n\t\tvolumePath = path.join(projectRoot, \".data/xmtp\")\n\t}\n\n\tconst dbPath = `${volumePath}/${description}.db3`\n\n\tif (typeof globalThis !== \"undefined\" && \"XMTP_STORAGE\" in globalThis) {\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ“ฆ Using Cloudflare R2 storage for: ${dbPath}`)\n\n\t\t\tconst r2Bucket = (globalThis as any).XMTP_STORAGE\n\t\t\tconst remotePath = `xmtp-databases/${description}.db3`\n\n\t\t\ttry {\n\t\t\t\tconst existingObject = await r2Bucket.head(remotePath)\n\t\t\t\tif (existingObject) {\n\t\t\t\t\tconsole.log(`๐Ÿ“ฅ Downloading existing database from R2 storage...`)\n\n\t\t\t\t\tif (!fs.existsSync(volumePath)) {\n\t\t\t\t\t\tfs.mkdirSync(volumePath, { recursive: true })\n\t\t\t\t\t}\n\n\t\t\t\t\tconst object = await r2Bucket.get(remotePath)\n\t\t\t\t\tif (object) {\n\t\t\t\t\t\tconst fileData = await object.arrayBuffer()\n\t\t\t\t\t\tfs.writeFileSync(dbPath, new Uint8Array(fileData))\n\t\t\t\t\t\tconsole.log(`โœ… Database downloaded from R2 storage`)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`๐Ÿ“ No existing database found in R2 storage`)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.log(`โš ๏ธ Failed to download database from R2 storage:`, error)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ R2 storage not available:`, error)\n\t\t}\n\t}\n\n\tif (!fs.existsSync(volumePath)) {\n\t\tfs.mkdirSync(volumePath, { recursive: true })\n\t}\n\n\treturn dbPath\n}\n\nexport const backupDbToPersistentStorage = async (\n\tdbPath: string,\n\tdescription: string\n) => {\n\tif (\n\t\ttypeof globalThis !== \"undefined\" &&\n\t\t\"XMTP_STORAGE\" in globalThis &&\n\t\tfs.existsSync(dbPath)\n\t) {\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ“ฆ Backing up database to R2 storage: ${dbPath}`)\n\n\t\t\tconst r2Bucket = (globalThis as any).XMTP_STORAGE\n\t\t\tconst remotePath = `xmtp-databases/${description}.db3`\n\n\t\t\tconst fileData = fs.readFileSync(dbPath)\n\t\t\tawait r2Bucket.put(remotePath, fileData)\n\t\t\tconsole.log(`โœ… Database backed up to R2 storage: ${remotePath}`)\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ Failed to backup database to R2 storage:`, error)\n\t\t}\n\t}\n}\n\n// ===================================================================\n// Logging and Debugging\n// ===================================================================\nexport const logAgentDetails = async (\n\tclients: XmtpClient | XmtpClient[]\n): Promise<void> => {\n\tconst clientsByAddress = Array.isArray(clients)\n\t\t? clients.reduce<Record<string, XmtpClient[]>>((acc, XmtpClient) => {\n\t\t\t\tconst address = XmtpClient.accountIdentifier?.identifier ?? \"\"\n\t\t\t\tacc[address] = acc[address] ?? []\n\t\t\t\tacc[address].push(XmtpClient)\n\t\t\t\treturn acc\n\t\t\t}, {})\n\t\t: {\n\t\t\t\t[clients.accountIdentifier?.identifier ?? \"\"]: [clients]\n\t\t\t}\n\n\tfor (const [address, clientGroup] of Object.entries(clientsByAddress)) {\n\t\tconst firstClient = clientGroup[0]\n\t\tconst inboxId = firstClient?.inboxId\n\t\tconst environments = clientGroup\n\t\t\t.map((c) => c.options?.env ?? \"dev\")\n\t\t\t.join(\", \")\n\t\tconsole.log(`\\x1b[38;2;252;76;52m\n โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— \n โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ•šโ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—\n โ•šโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•\n โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ•โ•โ• \n โ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ•šโ•โ• โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ \n โ•šโ•โ• โ•šโ•โ•โ•šโ•โ• โ•šโ•โ• โ•šโ•โ• โ•šโ•โ• \n \\x1b[0m`)\n\n\t\tconst urls = [`http://xmtp.chat/dm/${address}`]\n\n\t\tconst conversations = await firstClient?.conversations.list()\n\n\t\tconsole.log(`\n โœ“ XMTP XmtpClient:\n โ€ข Address: ${address}\n โ€ข Conversations: ${conversations?.length}\n โ€ข InboxId: ${inboxId}\n โ€ข Networks: ${environments}\n ${urls.map((url) => `โ€ข URL: ${url}`).join(\"\\n\")}`)\n\t}\n}\n\n// ===================================================================\n// Environment Validation\n// ===================================================================\nexport function validateEnvironment(vars: string[]): Record<string, string> {\n\tconst missing = vars.filter((v) => !process.env[v])\n\n\tif (missing.length) {\n\t\ttry {\n\t\t\tconst envPath = path.resolve(process.cwd(), \".env\")\n\t\t\tif (fs.existsSync(envPath)) {\n\t\t\t\tconst envVars = fs\n\t\t\t\t\t.readFileSync(envPath, \"utf-8\")\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.filter((line) => line.trim() && !line.startsWith(\"#\"))\n\t\t\t\t\t.reduce<Record<string, string>>((acc, line) => {\n\t\t\t\t\t\tconst [key, ...val] = line.split(\"=\")\n\t\t\t\t\t\tif (key && val.length) acc[key.trim()] = val.join(\"=\").trim()\n\t\t\t\t\t\treturn acc\n\t\t\t\t\t}, {})\n\n\t\t\t\tmissing.forEach((v) => {\n\t\t\t\t\tif (envVars[v]) process.env[v] = envVars[v]\n\t\t\t\t})\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\t/* ignore errors */\n\t\t}\n\n\t\tconst stillMissing = vars.filter((v) => !process.env[v])\n\t\tif (stillMissing.length) {\n\t\t\tconsole.error(\"Missing env vars:\", stillMissing.join(\", \"))\n\t\t\tprocess.exit(1)\n\t\t}\n\t}\n\n\treturn vars.reduce<Record<string, string>>((acc, key) => {\n\t\tacc[key] = process.env[key] as string\n\t\treturn acc\n\t}, {})\n}\n\n/**\n * Diagnose XMTP environment and identity issues\n */\nexport async function diagnoseXMTPIdentityIssue(\n\tclient: XmtpClient,\n\tinboxId: string,\n\tenvironment: string\n): Promise<{\n\tcanResolve: boolean\n\tsuggestions: string[]\n\tdetails: Record<string, any>\n}> {\n\tconst suggestions: string[] = []\n\tconst details: Record<string, any> = {\n\t\tenvironment,\n\t\tinboxId,\n\t\ttimestamp: new Date().toISOString()\n\t}\n\n\ttry {\n\t\t// Try to resolve the inbox state\n\t\tconst inboxState = await client.preferences.inboxStateFromInboxIds([\n\t\t\tinboxId\n\t\t])\n\n\t\tif (inboxState.length === 0) {\n\t\t\tsuggestions.push(\n\t\t\t\t`Inbox ID ${inboxId} not found in ${environment} environment`\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Try switching XMTP_ENV to 'dev' if currently 'production' or vice versa\"\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Verify the user has created an identity on this XMTP network\"\n\t\t\t)\n\t\t\tdetails.inboxStateFound = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\tconst inbox = inboxState[0]\n\t\tif (!inbox) {\n\t\t\tsuggestions.push(\"Inbox state returned empty data\")\n\t\t\tdetails.inboxStateFound = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\tdetails.inboxStateFound = true\n\t\tdetails.identifierCount = inbox.identifiers?.length || 0\n\n\t\tif (!inbox.identifiers || inbox.identifiers.length === 0) {\n\t\t\tsuggestions.push(\"Inbox found but has no identifiers\")\n\t\t\tsuggestions.push(\"This indicates incomplete identity registration\")\n\t\t\tsuggestions.push(\"User may need to re-register their identity on XMTP\")\n\t\t\tdetails.hasIdentifiers = false\n\t\t\treturn { canResolve: false, suggestions, details }\n\t\t}\n\n\t\t// Successfully resolved\n\t\tdetails.hasIdentifiers = true\n\t\tdetails.resolvedAddress = inbox.identifiers[0]?.identifier\n\t\treturn {\n\t\t\tcanResolve: true,\n\t\t\tsuggestions: [\"Identity resolved successfully\"],\n\t\t\tdetails\n\t\t}\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\tdetails.error = errorMessage\n\n\t\tif (errorMessage.includes(\"Association error\")) {\n\t\t\tsuggestions.push(\"XMTP identity association error detected\")\n\t\t\tsuggestions.push(\n\t\t\t\t\"Check if user exists on the correct XMTP environment (dev vs production)\"\n\t\t\t)\n\t\t\tsuggestions.push(\n\t\t\t\t\"Identity may need to be recreated on the current environment\"\n\t\t\t)\n\t\t}\n\n\t\tif (errorMessage.includes(\"Missing identity update\")) {\n\t\t\tsuggestions.push(\"Missing identity updates in XMTP network\")\n\t\t\tsuggestions.push(\"This can indicate network sync issues\")\n\t\t\tsuggestions.push(\"Wait a few minutes and retry, or recreate identity\")\n\t\t}\n\n\t\tif (errorMessage.includes(\"database\") || errorMessage.includes(\"storage\")) {\n\t\t\tsuggestions.push(\"XMTP local database/storage issue\")\n\t\t\tsuggestions.push(\"Try clearing XMTP database and resyncing\")\n\t\t\tsuggestions.push(\"Check .data/xmtp directory permissions\")\n\t\t}\n\n\t\tsuggestions.push(\"Consider testing with a fresh XMTP identity\")\n\t\treturn { canResolve: false, suggestions, details }\n\t}\n}\n\n// ===================================================================\n// Enhanced Connection Management & Health Monitoring\n// ===================================================================\n\nexport interface XMTPConnectionConfig {\n\tmaxRetries?: number\n\tretryDelayMs?: number\n\thealthCheckIntervalMs?: number\n\tconnectionTimeoutMs?: number\n\treconnectOnFailure?: boolean\n}\n\nexport interface XMTPConnectionHealth {\n\tisConnected: boolean\n\tlastHealthCheck: Date\n\tconsecutiveFailures: number\n\ttotalReconnects: number\n\tavgResponseTime: number\n}\n\nexport class XMTPConnectionManager {\n\tprivate client: XmtpClient | null = null\n\tprivate privateKey: string\n\tprivate config: Required<XMTPConnectionConfig>\n\tprivate health: XMTPConnectionHealth\n\tprivate healthCheckTimer: NodeJS.Timeout | null = null\n\tprivate isReconnecting = false\n\n\tconstructor(privateKey: string, config: XMTPConnectionConfig = {}) {\n\t\tthis.privateKey = privateKey\n\t\tthis.config = {\n\t\t\tmaxRetries: config.maxRetries ?? 5,\n\t\t\tretryDelayMs: config.retryDelayMs ?? 1000,\n\t\t\thealthCheckIntervalMs: config.healthCheckIntervalMs ?? 30000,\n\t\t\tconnectionTimeoutMs: config.connectionTimeoutMs ?? 10000,\n\t\t\treconnectOnFailure: config.reconnectOnFailure ?? true\n\t\t}\n\n\t\tthis.health = {\n\t\t\tisConnected: false,\n\t\t\tlastHealthCheck: new Date(),\n\t\t\tconsecutiveFailures: 0,\n\t\t\ttotalReconnects: 0,\n\t\t\tavgResponseTime: 0\n\t\t}\n\t}\n\n\tasync connect(persist = false): Promise<XmtpClient> {\n\t\tif (this.client && this.health.isConnected) {\n\t\t\treturn this.client\n\t\t}\n\n\t\tlet attempt = 0\n\t\twhile (attempt < this.config.maxRetries) {\n\t\t\ttry {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ XMTP connection attempt ${attempt + 1}/${this.config.maxRetries}`\n\t\t\t\t)\n\n\t\t\t\tthis.client = await createXMTPClient(this.privateKey, { persist })\n\t\t\t\tthis.health.isConnected = true\n\t\t\t\tthis.health.consecutiveFailures = 0\n\n\t\t\t\t// Start health monitoring\n\t\t\t\tthis.startHealthMonitoring()\n\n\t\t\t\tconsole.log(\"โœ… XMTP client connected successfully\")\n\t\t\t\treturn this.client\n\t\t\t} catch (error) {\n\t\t\t\tattempt++\n\t\t\t\tthis.health.consecutiveFailures++\n\n\t\t\t\tconsole.error(`โŒ XMTP connection attempt ${attempt} failed:`, error)\n\n\t\t\t\tif (attempt < this.config.maxRetries) {\n\t\t\t\t\tconst delay = this.config.retryDelayMs * Math.pow(2, attempt - 1)\n\t\t\t\t\tconsole.log(`โณ Retrying in ${delay}ms...`)\n\t\t\t\t\tawait this.sleep(delay)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Failed to connect to XMTP after ${this.config.maxRetries} attempts`\n\t\t)\n\t}\n\n\t// private async createClientWithTimeout(persist: boolean): Promise<XmtpClient> {\n\t// const timeoutPromise = new Promise<never>((_, reject) => {\n\t// setTimeout(\n\t// () => reject(new Error(\"Connection timeout\")),\n\t// this.config.connectionTimeoutMs\n\t// )\n\t// })\n\n\t// const clientPromise = createXMTPClient(this.signer, { persist })\n\n\t// return Promise.race([clientPromise, timeoutPromise])\n\t// }\n\n\tprivate startHealthMonitoring(): void {\n\t\tif (this.healthCheckTimer) {\n\t\t\tclearInterval(this.healthCheckTimer)\n\t\t}\n\n\t\tthis.healthCheckTimer = setInterval(() => {\n\t\t\tthis.performHealthCheck()\n\t\t}, this.config.healthCheckIntervalMs)\n\t}\n\n\tprivate async performHealthCheck(): Promise<void> {\n\t\tif (!this.client) return\n\n\t\tconst startTime = Date.now()\n\n\t\ttry {\n\t\t\t// Simple health check: try to list conversations\n\t\t\tawait this.client.conversations.list()\n\n\t\t\tconst responseTime = Date.now() - startTime\n\t\t\tthis.health.avgResponseTime =\n\t\t\t\t(this.health.avgResponseTime + responseTime) / 2\n\t\t\tthis.health.lastHealthCheck = new Date()\n\t\t\tthis.health.consecutiveFailures = 0\n\t\t\tthis.health.isConnected = true\n\n\t\t\tconsole.log(`๐Ÿ’“ XMTP health check passed (${responseTime}ms)`)\n\t\t} catch (error) {\n\t\t\tthis.health.consecutiveFailures++\n\t\t\tthis.health.isConnected = false\n\n\t\t\tconsole.error(`๐Ÿ’” XMTP health check failed:`, error)\n\n\t\t\t// Trigger reconnection if enabled\n\t\t\tif (this.config.reconnectOnFailure && !this.isReconnecting) {\n\t\t\t\tthis.handleConnectionFailure()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async handleConnectionFailure(): Promise<void> {\n\t\tif (this.isReconnecting) return\n\n\t\tthis.isReconnecting = true\n\t\tthis.health.totalReconnects++\n\n\t\tconsole.log(\"๐Ÿ”„ XMTP connection lost, attempting to reconnect...\")\n\n\t\ttry {\n\t\t\tthis.client = null\n\t\t\tawait this.connect()\n\t\t\tconsole.log(\"โœ… XMTP reconnection successful\")\n\t\t} catch (error) {\n\t\t\tconsole.error(\"โŒ XMTP reconnection failed:\", error)\n\t\t} finally {\n\t\t\tthis.isReconnecting = false\n\t\t}\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n\n\tgetHealth(): XMTPConnectionHealth {\n\t\treturn { ...this.health }\n\t}\n\n\tgetClient(): XmtpClient | null {\n\t\treturn this.client\n\t}\n\n\tasync disconnect(): Promise<void> {\n\t\tif (this.healthCheckTimer) {\n\t\t\tclearInterval(this.healthCheckTimer)\n\t\t\tthis.healthCheckTimer = null\n\t\t}\n\n\t\tthis.client = null\n\t\tthis.health.isConnected = false\n\t\tconsole.log(\"๐Ÿ”Œ XMTP client disconnected\")\n\t}\n}\n\n// Enhanced client creation with connection management\nexport async function createXMTPConnectionManager(\n\tprivateKey: string,\n\tconfig?: XMTPConnectionConfig\n): Promise<XMTPConnectionManager> {\n\tconst manager = new XMTPConnectionManager(privateKey, config)\n\tawait manager.connect()\n\treturn manager\n}\n\n// ===================================================================\n// User Address Resolution with Auto-Refresh\n// ===================================================================\n\n/**\n * Resolve user address from inbox ID with automatic identity refresh on association errors\n */\nexport async function resolveUserAddress(\n\tclient: XmtpClient,\n\tsenderInboxId: string,\n\tmaxRetries = 2\n): Promise<string> {\n\tlet attempt = 0\n\n\twhile (attempt < maxRetries) {\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” Resolving user address (attempt ${attempt + 1}/${maxRetries})...`\n\t\t\t)\n\n\t\t\tconst inboxState = await client.preferences.inboxStateFromInboxIds([\n\t\t\t\tsenderInboxId\n\t\t\t])\n\n\t\t\tconst firstInbox = inboxState[0]\n\t\t\tif (\n\t\t\t\tinboxState.length > 0 &&\n\t\t\t\tfirstInbox?.identifiers &&\n\t\t\t\tfirstInbox.identifiers.length > 0\n\t\t\t) {\n\t\t\t\tconst userAddress = firstInbox.identifiers[0]?.identifier\n\t\t\t\tif (userAddress) {\n\t\t\t\t\tconsole.log(\"โœ… Resolved user address:\", userAddress)\n\t\t\t\t\treturn userAddress\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\"โš ๏ธ No identifiers found in inbox state\")\n\t\t\treturn \"unknown\"\n\t\t} catch (error) {\n\t\t\tattempt++\n\n\t\t\tif (\n\t\t\t\terror instanceof Error &&\n\t\t\t\terror.message.includes(\"Association error: Missing identity update\")\n\t\t\t) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`๐Ÿ”„ Identity association error during address resolution (attempt ${attempt}/${maxRetries})`\n\t\t\t\t)\n\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"๐Ÿ”ง Attempting automatic identity refresh for address resolution...\"\n\t\t\t\t\t)\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Force a conversation sync to refresh identity state\n\t\t\t\t\t\tconsole.log(\"๐Ÿ“ก Syncing conversations to refresh identity...\")\n\t\t\t\t\t\tawait client.conversations.sync()\n\n\t\t\t\t\t\t// Small delay before retry\n\t\t\t\t\t\tconsole.log(\"โณ Waiting 2s before retry...\")\n\t\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 2000))\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\"โœ… Identity sync completed, retrying address resolution...\"\n\t\t\t\t\t\t)\n\t\t\t\t\t} catch (refreshError) {\n\t\t\t\t\t\tconsole.log(`โŒ Identity refresh failed:`, refreshError)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"โŒ Failed to resolve user address after all retries\")\n\t\t\t\t\tconsole.error(\"๐Ÿ’ก Identity association issue persists\")\n\n\t\t\t\t\t// Run diagnostic\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst diagnosis = await diagnoseXMTPIdentityIssue(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tsenderInboxId,\n\t\t\t\t\t\t\tprocess.env.XMTP_ENV || \"dev\"\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tconsole.log(\"๐Ÿ” XMTP Identity Diagnosis:\")\n\t\t\t\t\t\tdiagnosis.suggestions.forEach((suggestion) => {\n\t\t\t\t\t\t\tconsole.error(`๐Ÿ’ก ${suggestion}`)\n\t\t\t\t\t\t})\n\t\t\t\t\t} catch (diagError) {\n\t\t\t\t\t\tconsole.warn(\"โš ๏ธ Could not run XMTP identity diagnosis:\", diagError)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn \"unknown\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For other errors, don't retry\n\t\t\t\tconsole.error(\"โŒ Error resolving user address:\", error)\n\t\t\t\treturn \"unknown\"\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"unknown\"\n}\n\nexport const startPeriodicBackup = (\n\tdbPath: string,\n\tdescription: string,\n\tintervalMs = 300000\n) => {\n\treturn setInterval(async () => {\n\t\ttry {\n\t\t\tawait backupDbToPersistentStorage(dbPath, description)\n\t\t} catch (error) {\n\t\t\tconsole.log(`โš ๏ธ Periodic backup failed:`, error)\n\t\t}\n\t}, intervalMs)\n}\n","import { Client, Signer, createSigner } from \"../src/index\"\n\n// Function to revoke old installations when hitting the limit\nexport async function revokeOldInstallations(signer: Signer, inboxId?: string) {\n console.log(\"๐Ÿ”ง Attempting to revoke old installations...\")\n\n try {\n // If we don't have the inboxId, we need to extract it from a temporary client attempt\n if (!inboxId) {\n console.log(\"โ„น๏ธ No inboxId provided, cannot revoke installations\")\n return false\n }\n\n const inboxStates = await Client.inboxStateFromInboxIds(\n [inboxId],\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n if (!inboxStates[0]) {\n console.log(\"โŒ No inbox state found for the provided inboxId\")\n return false\n }\n\n const toRevokeInstallationBytes = inboxStates[0].installations.map(\n (i) => i.bytes\n )\n\n await Client.revokeInstallations(\n signer,\n inboxId,\n toRevokeInstallationBytes,\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n const resultingStates = await Client.inboxStateFromInboxIds(\n [inboxId],\n process.env.XMTP_ENV as \"dev\" | \"production\"\n )\n\n console.log(\n `๐Ÿ“‹ Revoked installations: ${toRevokeInstallationBytes.length} installations`\n )\n console.log(\n `๐Ÿ“‹ Resulting state: ${resultingStates[0]?.installations.length || 0} installations`\n )\n\n return true\n } catch (error) {\n console.error(\"โŒ Error during installation revocation:\", error)\n return false\n }\n}\n\n// CLI script to revoke installations\nasync function main() {\n const { XMTP_WALLET_KEY } = process.env\n const inboxId = process.argv[2]\n\n if (!XMTP_WALLET_KEY) {\n console.error(\"โŒ XMTP_WALLET_KEY is required\")\n process.exit(1)\n }\n\n if (!inboxId) {\n console.error(\"โŒ InboxID is required as CLI argument\")\n console.error(\"Usage: tsx revoke-installations.ts <inboxId>\")\n process.exit(1)\n }\n\n const signer = createSigner(XMTP_WALLET_KEY)\n const identifier = await signer.getIdentifier()\n const address = identifier.identifier\n\n console.log(`๐Ÿ”‘ Wallet Address: ${address}`)\n console.log(`๐Ÿ“‹ Inbox ID: ${inboxId}`)\n\n // Try to revoke installations\n const success = await revokeOldInstallations(signer, inboxId)\n\n if (success) {\n console.log(\"โœ… Successfully revoked installations\")\n } else {\n console.log(\"โŒ Failed to revoke installations\")\n process.exit(1)\n }\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main().catch((error) => {\n console.error(\"๐Ÿ’ฅ Fatal error:\", error)\n process.exit(1)\n })\n}\n","// ===================================================================\n// Betting Configuration\n// ===================================================================\nexport const DEFAULT_OPTIONS = [\"yes\", \"no\"]\nexport const DEFAULT_AMOUNT = \"0.1\"\nexport const MAX_USDC_AMOUNT = 10 // Maximum allowed USDC transaction amount\n","import { EventEmitter } from \"node:events\"\nimport { Reaction } from \"@xmtp/content-type-reaction\"\nimport { Reply } from \"@xmtp/content-type-reply\"\nimport { http, PublicClient, createPublicClient } from \"viem\"\nimport { mainnet } from \"viem/chains\"\nimport { Resolver } from \"../resolver/resolver\"\nimport type { MessageEvent, XmtpClient, XmtpMessage } from \"../types\"\n\n// Configuration for the message listener\nexport interface MessageListenerConfig {\n\tpublicClient: PublicClient\n\txmtpClient: XmtpClient\n\t/**\n\t * Filter function to determine which messages to process\n\t * Return true to process the message, false to skip\n\t */\n\tfilter?: (\n\t\tevent: Pick<MessageEvent, \"conversation\" | \"message\" | \"rootMessage\">\n\t) => Promise<boolean> | boolean\n\t/**\n\t * Heartbeat interval in milliseconds (default: 5 minutes)\n\t */\n\theartbeatInterval?: number\n\t/**\n\t * Conversation check interval in milliseconds (default: 30 seconds)\n\t */\n\tconversationCheckInterval?: number\n\t/**\n\t * Environment variable key for XMTP environment (default: \"XMTP_ENV\")\n\t */\n\tenvKey?: string\n}\n\n// Enriched message data with resolved address\n\n// Define the event signature for type safety\nexport interface MessageListenerEvents {\n\tmessage: [data: MessageEvent]\n\terror: [error: Error]\n\tstarted: []\n\tstopped: []\n\theartbeat: [stats: { messageCount: number; conversationCount: number }]\n}\n\n/**\n * A flexible XMTP message listener that can be configured for different applications\n */\nexport class MessageListener extends EventEmitter {\n\tprivate xmtpClient: XmtpClient\n\tprivate resolver: Resolver\n\tprivate filter?: (\n\t\tevent: Pick<MessageEvent, \"conversation\" | \"message\" | \"rootMessage\">\n\t) => Promise<boolean> | boolean\n\tprivate heartbeatInterval?: NodeJS.Timeout\n\tprivate fallbackCheckInterval?: NodeJS.Timeout\n\tprivate messageCount = 0\n\tprivate conversations: any[] = []\n\tprivate readonly config: Required<\n\t\tPick<\n\t\t\tMessageListenerConfig,\n\t\t\t\"heartbeatInterval\" | \"conversationCheckInterval\" | \"envKey\"\n\t\t>\n\t>\n\n\tconstructor(config: MessageListenerConfig) {\n\t\tsuper()\n\t\tthis.xmtpClient = config.xmtpClient\n\n\t\t// Create mainnet client for ENS resolution\n\t\tconst mainnetClient = createPublicClient({\n\t\t\tchain: mainnet,\n\t\t\ttransport: http()\n\t\t})\n\n\t\t// Create unified resolver with all capabilities\n\t\tthis.resolver = new Resolver({\n\t\t\txmtpClient: this.xmtpClient,\n\t\t\tmainnetClient,\n\t\t\tbaseClient: config.publicClient,\n\t\t\tmaxCacheSize: 1000,\n\t\t\tcacheTtl: 86400000 // 24 hours\n\t\t})\n\n\t\tthis.filter = config.filter\n\t\tthis.config = {\n\t\t\theartbeatInterval: config.heartbeatInterval ?? 300000, // 5 minutes\n\t\t\tconversationCheckInterval: config.conversationCheckInterval ?? 30000, // 30 seconds\n\t\t\tenvKey: config.envKey ?? \"XMTP_ENV\"\n\t\t}\n\t}\n\n\t// Type-safe event emitter methods\n\ton<U extends keyof MessageListenerEvents>(\n\t\tevent: U,\n\t\tlistener: (...args: MessageListenerEvents[U]) => void\n\t): this {\n\t\treturn super.on(event, listener)\n\t}\n\n\temit<U extends keyof MessageListenerEvents>(\n\t\tevent: U,\n\t\t...args: MessageListenerEvents[U]\n\t): boolean {\n\t\treturn super.emit(event, ...args)\n\t}\n\n\tasync start(): Promise<void> {\n\t\tconst XMTP_ENV = process.env[this.config.envKey]\n\n\t\t// Pre-populate address cache from existing conversations\n\t\tawait this.resolver?.prePopulateAllCaches()\n\n\t\tconsole.log(\"๐Ÿ“ก Syncing conversations...\")\n\t\tawait this.xmtpClient.conversations.sync()\n\n\t\tconst address = this.xmtpClient.accountIdentifier?.identifier\n\n\t\t// List existing conversations for debugging\n\t\tthis.conversations = await this.xmtpClient.conversations.list()\n\n\t\tconsole.log(`๐Ÿค– XMTP[${XMTP_ENV}] Listening on ${address} ...`)\n\n\t\t// Emit started event\n\t\tthis.emit(\"started\")\n\n\t\t// Stream all messages and emit events for processing\n\t\ttry {\n\t\t\tconst stream = await this.xmtpClient.conversations.streamAllMessages()\n\n\t\t\t// Add a heartbeat to show the listener is active\n\t\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\t\tthis.emit(\"heartbeat\", {\n\t\t\t\t\tmessageCount: this.messageCount,\n\t\t\t\t\tconversationCount: this.conversations.length\n\t\t\t\t})\n\t\t\t\tif (this.messageCount > 0) {\n\t\t\t\t\tconsole.log(`๐Ÿ’“ Active - processed ${this.messageCount} messages`)\n\t\t\t\t}\n\t\t\t}, this.config.heartbeatInterval)\n\n\t\t\t// Check for new conversations\n\t\t\tthis.fallbackCheckInterval = setInterval(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst latestConversations = await this.xmtpClient.conversations.list()\n\t\t\t\t\tif (latestConversations.length > this.conversations.length) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`๐Ÿ†• Detected ${latestConversations.length - this.conversations.length} new conversations`\n\t\t\t\t\t\t)\n\t\t\t\t\t\tthis.conversations.push(\n\t\t\t\t\t\t\t...latestConversations.slice(this.conversations.length)\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"โŒ Error checking for new conversations:\", error)\n\t\t\t\t\tthis.emit(\"error\", error as Error)\n\t\t\t\t}\n\t\t\t}, this.config.conversationCheckInterval)\n\n\t\t\ttry {\n\t\t\t\tfor await (const message of stream) {\n\t\t\t\t\tthis.messageCount++\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Skip messages from self or null messages\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!message ||\n\t\t\t\t\t\t\tmessage.senderInboxId.toLowerCase() ===\n\t\t\t\t\t\t\t\tthis.xmtpClient.inboxId.toLowerCase()\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`๐Ÿ“จ Received message \"${JSON.stringify(message)}\" in ${message.conversationId}`\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Get conversation details\n\t\t\t\t\t\tconst conversation =\n\t\t\t\t\t\t\tawait this.xmtpClient.conversations.getConversationById(\n\t\t\t\t\t\t\t\tmessage.conversationId\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (!conversation) {\n\t\t\t\t\t\t\tconsole.log(\"โŒ Could not find conversation for message\")\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst contentTypeId = message.contentType?.typeId\n\n\t\t\t\t\t\t// Extract message content for processing\n\t\t\t\t\t\tlet messageContent: string\n\t\t\t\t\t\tif (contentTypeId === \"reply\") {\n\t\t\t\t\t\t\tconst replyContent = message.content as any\n\t\t\t\t\t\t\tmessageContent = (replyContent?.content || \"\").toString()\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tcontentTypeId === \"remoteStaticAttachment\" ||\n\t\t\t\t\t\t\tcontentTypeId === \"attachment\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// For attachments, use the fallback message or filename\n\t\t\t\t\t\t\tmessageContent =\n\t\t\t\t\t\t\t\t(message as any).fallback ||\n\t\t\t\t\t\t\t\t(message.content as any)?.filename ||\n\t\t\t\t\t\t\t\t\"[Attachment]\"\n\t\t\t\t\t\t} else if (contentTypeId === \"reaction\") {\n\t\t\t\t\t\t\t// For reactions, use a simple representation\n\t\t\t\t\t\t\tconst reactionContent = message.content as Reaction\n\t\t\t\t\t\t\tmessageContent = `[Reaction: ${reactionContent.content || \"\"}]`\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// For text and other content types, safely convert to string\n\t\t\t\t\t\t\tmessageContent = message.content ? String(message.content) : \"\"\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Find root message for replies and reactions\n\t\t\t\t\t\tlet rootMessage: XmtpMessage | null = message\n\t\t\t\t\t\tlet parentMessage: XmtpMessage | null = null\n\n\t\t\t\t\t\tif (contentTypeId === \"reply\") {\n\t\t\t\t\t\t\tconst { reference } = message.content as Reply\n\t\t\t\t\t\t\trootMessage = await this.resolver.findRootMessage(reference)\n\t\t\t\t\t\t\tparentMessage = await this.resolver.findMessage(reference)\n\t\t\t\t\t\t} else if (contentTypeId === \"reaction\") {\n\t\t\t\t\t\t\tconst { reference } = message.content as Reaction\n\t\t\t\t\t\t\trootMessage = await this.resolver.findRootMessage(reference)\n\t\t\t\t\t\t\tparentMessage = await this.resolver.findMessage(reference)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// For text messages and attachments, they are root messages\n\t\t\t\t\t\t\trootMessage = message\n\t\t\t\t\t\t\tparentMessage = null\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Skip if we couldn't find the root message\n\t\t\t\t\t\tif (!rootMessage) {\n\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t`โš ๏ธ [MessageListener] Could not find root message for: ${message.id}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Apply custom message filter if provided\n\t\t\t\t\t\tif (this.filter) {\n\t\t\t\t\t\t\tconst shouldProcess = await this.filter({\n\t\t\t\t\t\t\t\tconversation,\n\t\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\t\trootMessage\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tif (!shouldProcess) {\n\t\t\t\t\t\t\t\tconsole.log(\"๐Ÿ”„ Skipping message:\", message.id)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create sender using unified resolver\n\t\t\t\t\t\tconst sender = await this.resolver.createXmtpSender(\n\t\t\t\t\t\t\tmessage.senderInboxId,\n\t\t\t\t\t\t\tmessage.conversationId\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\t// Extract and resolve subjects (basenames and ENS names mentioned in message)\n\t\t\t\t\t\t// TODO: Update extractSubjects to work with unified resolver\n\t\t\t\t\t\tconst subjects = {}\n\n\t\t\t\t\t\t// Create enriched message with resolved address, name, subjects, root message, and parent message\n\t\t\t\t\t\tconst messageEvent: MessageEvent = {\n\t\t\t\t\t\t\tconversation,\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\trootMessage: rootMessage as XmtpMessage, // We already checked it's not null above\n\t\t\t\t\t\t\tparentMessage: parentMessage || undefined,\n\t\t\t\t\t\t\tsender,\n\t\t\t\t\t\t\tsubjects\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Emit the enriched message\n\t\t\t\t\t\tthis.emit(\"message\", messageEvent)\n\t\t\t\t\t} catch (messageError) {\n\t\t\t\t\t\tconsole.error(\"โŒ Error processing message:\", messageError)\n\t\t\t\t\t\tthis.emit(\"error\", messageError as Error)\n\t\t\t\t\t\t// Continue processing other messages instead of crashing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (streamError) {\n\t\t\t\tconsole.error(\"โŒ Error in message stream:\", streamError)\n\t\t\t\tthis.cleanup()\n\t\t\t\tthis.emit(\"error\", streamError as Error)\n\t\t\t\tconsole.log(\"๐Ÿ”„ Attempting to restart stream...\")\n\n\t\t\t\t// Wait a bit before restarting to avoid tight restart loops\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 5000))\n\n\t\t\t\t// Recursively restart the message listener\n\t\t\t\treturn this.start()\n\t\t\t}\n\t\t} catch (streamSetupError) {\n\t\t\tconsole.error(\"โŒ Error setting up message stream:\", streamSetupError)\n\t\t\tthis.emit(\"error\", streamSetupError as Error)\n\t\t\tthrow streamSetupError\n\t\t}\n\t}\n\n\tprivate cleanup() {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval)\n\t\t}\n\t\tif (this.fallbackCheckInterval) {\n\t\t\tclearInterval(this.fallbackCheckInterval)\n\t\t}\n\t}\n\n\tstop() {\n\t\tthis.cleanup()\n\t\tthis.emit(\"stopped\")\n\t\tconsole.log(\"๐Ÿ›‘ Message listener stopped\")\n\t\tthis.removeAllListeners()\n\t}\n\n\t/**\n\t * Get current statistics\n\t */\n\tgetStats() {\n\t\treturn {\n\t\t\tmessageCount: this.messageCount,\n\t\t\tconversationCount: this.conversations.length,\n\t\t\tisActive: !!this.heartbeatInterval\n\t\t}\n\t}\n}\n\n/**\n * Helper function to start a message listener\n */\nexport async function startMessageListener(\n\tconfig: MessageListenerConfig\n): Promise<MessageListener> {\n\tconst listener = new MessageListener(config)\n\tawait listener.start()\n\treturn listener\n}\n\n/**\n * Factory function to create a message listener with common filters\n */\nexport function createMessageListener(config: MessageListenerConfig) {\n\treturn new MessageListener(config)\n}\n","import type { XmtpClient } from \"../types\"\n\ninterface AddressResolverOptions {\n /**\n * Maximum number of addresses to cache\n * @default 1000\n */\n maxCacheSize?: number\n /**\n * Cache TTL in milliseconds\n * @default 86400000 (24 hours)\n */\n cacheTtl?: number\n}\n\ninterface CacheEntry {\n address: string\n timestamp: number\n}\n\nexport class AddressResolver {\n private cache = new Map<string, CacheEntry>()\n private readonly maxCacheSize: number\n private readonly cacheTtl: number\n\n constructor(\n private client: XmtpClient,\n options: AddressResolverOptions = {}\n ) {\n this.maxCacheSize = options.maxCacheSize ?? 1000\n this.cacheTtl = options.cacheTtl ?? 86400000 // 24 hours\n }\n\n /**\n * Resolve user address from inbox ID with caching\n */\n async resolveAddress(\n inboxId: string,\n conversationId?: string\n ): Promise<`0x${string}` | null> {\n // Check cache first (fastest)\n const cached = this.getCachedAddress(inboxId)\n if (cached) {\n console.log(`โœ… Resolved user address from cache: ${cached}`)\n return cached\n }\n\n let userAddress = undefined\n\n try {\n // Try conversation members lookup first (faster than network call)\n if (conversationId) {\n const conversation =\n await this.client.conversations.getConversationById(conversationId)\n if (conversation) {\n userAddress = await this.resolveFromConversation(\n conversation,\n inboxId\n )\n if (userAddress) {\n this.setCachedAddress(inboxId, userAddress)\n console.log(`โœ… Resolved user address: ${userAddress}`)\n return userAddress\n }\n }\n }\n\n // Fallback to inboxStateFromInboxIds\n userAddress = await this.resolveFromInboxState(inboxId)\n if (userAddress) {\n this.setCachedAddress(inboxId, userAddress)\n console.log(`โœ… Resolved user address via fallback: ${userAddress}`)\n return userAddress\n }\n\n console.log(`โš ๏ธ No identifiers found for inbox ${inboxId}`)\n return null\n } catch (error) {\n console.error(`โŒ Error resolving user address for ${inboxId}:`, error)\n return null\n }\n }\n\n /**\n * Resolve address from conversation members\n */\n private async resolveFromConversation(\n conversation: any,\n inboxId: string\n ): Promise<`0x${string}` | null> {\n try {\n const members = await conversation.members()\n const sender = members.find(\n (member: any) => member.inboxId.toLowerCase() === inboxId.toLowerCase()\n )\n\n if (sender) {\n const ethIdentifier = sender.accountIdentifiers.find(\n (id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n )\n if (ethIdentifier) {\n return ethIdentifier.identifier\n } else {\n console.log(`โš ๏ธ No Ethereum identifier found for inbox ${inboxId}`)\n }\n } else {\n console.log(\n `โš ๏ธ Sender not found in conversation members for inbox ${inboxId}`\n )\n }\n } catch (error) {\n console.error(`โŒ Error resolving from conversation members:`, error)\n }\n\n return null\n }\n\n /**\n * Resolve address from inbox state (network fallback)\n */\n private async resolveFromInboxState(inboxId: string): Promise<`0x${string}` | null> {\n try {\n const inboxState = await this.client.preferences.inboxStateFromInboxIds([\n inboxId\n ])\n const firstState = inboxState?.[0]\n if (firstState?.identifiers && firstState.identifiers.length > 0) {\n const firstIdentifier = firstState.identifiers[0]\n return firstIdentifier?.identifier as `0x${string}`\n }\n } catch (error) {\n console.error(`โŒ Error resolving from inbox state:`, error)\n }\n\n return null\n }\n\n /**\n * Get cached address if not expired\n */\n private getCachedAddress(inboxId: string): `0x${string}` | null {\n const entry = this.cache.get(inboxId)\n if (!entry) return null\n\n const now = Date.now()\n if (now - entry.timestamp > this.cacheTtl) {\n this.cache.delete(inboxId)\n return null\n }\n\n return entry.address as `0x${string}`\n }\n\n /**\n * Cache address with LRU eviction\n */\n private setCachedAddress(inboxId: string, address: `0x${string}`): void {\n // Simple LRU: if cache is full, remove oldest entry\n if (this.cache.size >= this.maxCacheSize) {\n const firstKey = this.cache.keys().next().value\n if (firstKey) {\n this.cache.delete(firstKey)\n }\n }\n\n this.cache.set(inboxId, {\n address,\n timestamp: Date.now()\n })\n }\n\n /**\n * Pre-populate cache from existing conversations\n */\n async prePopulateCache(): Promise<void> {\n console.log(\"๐Ÿ”„ Pre-populating address cache...\")\n try {\n const conversations = await this.client.conversations.list()\n let cachedCount = 0\n\n for (const conversation of conversations) {\n try {\n const members = await conversation.members()\n for (const member of members) {\n const ethIdentifier = member.accountIdentifiers.find(\n (id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n )\n if (ethIdentifier) {\n this.setCachedAddress(member.inboxId, ethIdentifier.identifier as `0x${string}`)\n cachedCount++\n }\n }\n } catch (error) {\n console.error(\"Error pre-caching conversation members:\", error)\n }\n }\n\n console.log(`โœ… Pre-cached ${cachedCount} address mappings`)\n } catch (error) {\n console.error(\"Error pre-populating cache:\", error)\n }\n }\n\n /**\n * Clear the cache\n */\n clearCache(): void {\n this.cache.clear()\n console.log(\"๐Ÿ—‘๏ธ Address cache cleared\")\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats(): { size: number; maxSize: number; hitRate?: number } {\n return {\n size: this.cache.size,\n maxSize: this.maxCacheSize\n }\n }\n}\n","import {\n\ttype Address,\n\tPublicClient,\n\tencodePacked,\n\tkeccak256,\n\tnamehash\n} from \"viem\"\nimport { mainnet } from \"viem/chains\"\nimport { L2ResolverAbi } from \"../abi/l2_resolver\"\n\n// Base L2 Resolver Address mapping by chain ID\n// const BASENAME_L2_RESOLVER_ADDRESSES: Record<number, Address> = {\n// \t[mainnet.id]: \"0x0000000000000000000000000000000000000000\", // Mainnet (1)\n// \t[base.id]: \"0xC6d566A56A1aFf6508b41f6c90ff131615583BCD\", // Base Mainnet (8453)\n// \t[baseSepolia.id]: \"0x6533C94869D28fAA8dF77cc63f9e2b2D6Cf77eBA\" // Base Sepolia (84532)\n// } as const\n\nconst BASENAME_L2_RESOLVER_ADDRESS =\n\t\"0xC6d566A56A1aFf6508b41f6c90ff131615583BCD\"\n\n// Basename text record keys for metadata\nexport const BasenameTextRecordKeys = {\n\tEmail: \"email\",\n\tUrl: \"url\",\n\tAvatar: \"avatar\",\n\tDescription: \"description\",\n\tNotice: \"notice\",\n\tKeywords: \"keywords\",\n\tTwitter: \"com.twitter\",\n\tGithub: \"com.github\",\n\tDiscord: \"com.discord\",\n\tTelegram: \"org.telegram\",\n\tSnapshot: \"snapshot\",\n\tLocation: \"location\"\n} as const\n\nexport type BasenameTextRecordKey =\n\t(typeof BasenameTextRecordKeys)[keyof typeof BasenameTextRecordKeys]\nexport type BaseName = string\n\ninterface BasenameResolverOptions {\n\t/**\n\t * Maximum number of basenames to cache\n\t * @default 500\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n\n\t/**\n\t * Public client\n\t * @default null\n\t */\n\tpublicClient: PublicClient\n}\n\ninterface CacheEntry {\n\tbasename: string\n\ttimestamp: number\n}\n\ninterface TextRecordCacheEntry {\n\tvalue: string\n\ttimestamp: number\n}\n\n/**\n * Convert an chainId to a coinType hex for reverse chain resolution\n */\nexport const convertChainIdToCoinType = (chainId: number): string => {\n\t// L1 resolvers to addr\n\tif (chainId === mainnet.id) {\n\t\treturn \"addr\"\n\t}\n\n\tconst cointype = (0x80000000 | chainId) >>> 0\n\treturn cointype.toString(16).toLocaleUpperCase()\n}\n\n/**\n * Helper function to convert an address to its reverse node for ENS lookups\n */\nexport const convertReverseNodeToBytes = (\n\taddress: Address,\n\tchainId: number\n) => {\n\tconst addressFormatted = address.toLocaleLowerCase() as Address\n\tconst addressNode = keccak256(addressFormatted.substring(2) as Address)\n\tconst chainCoinType = convertChainIdToCoinType(chainId)\n\tconst baseReverseNode = namehash(\n\t\t`${chainCoinType.toLocaleUpperCase()}.reverse`\n\t)\n\tconst addressReverseNode = keccak256(\n\t\tencodePacked([\"bytes32\", \"bytes32\"], [baseReverseNode, addressNode])\n\t)\n\treturn addressReverseNode\n}\n\n/**\n * Helper function to convert a basename to its node hash\n */\nfunction convertBasenameToNode(basename: string): `0x${string}` {\n\treturn namehash(basename)\n}\n\n/**\n * Get the resolver address for a given chain ID\n */\nfunction getResolverAddress(): Address {\n\tconst resolverAddress = BASENAME_L2_RESOLVER_ADDRESS\n\treturn resolverAddress\n}\n\nexport class BasenameResolver {\n\tprivate cache = new Map<string, CacheEntry>()\n\tprivate textRecordCache = new Map<string, Map<string, TextRecordCacheEntry>>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly baseClient: PublicClient\n\tprivate resolverAddress: Address | null = null\n\tprivate chainId: number | null = null\n\n\tconstructor(options: BasenameResolverOptions) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 500\n\t\tthis.cacheTtl = options.cacheTtl ?? 3600000 // 1 hour\n\n\t\t// Create a public client for Base network\n\t\tthis.baseClient = options.publicClient\n\n\t\t// Initialize resolver address lazily on first use\n\t\tthis.initializeResolver()\n\t}\n\n\t/**\n\t * Initialize the resolver address based on the client's chain ID\n\t */\n\tprivate async initializeResolver(): Promise<void> {\n\t\tif (this.resolverAddress && this.chainId) {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ”„ BasenameResolver already initialized for chain ${this.chainId} with resolver ${this.resolverAddress}`\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(\"๐Ÿ”„ Initializing BasenameResolver...\")\n\t\t\tthis.chainId = await this.baseClient.getChainId()\n\t\t\tconsole.log(`๐Ÿ”— Chain ID detected: ${this.chainId}`)\n\n\t\t\tthis.resolverAddress = getResolverAddress()\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“ Resolver address for chain ${this.chainId}: ${this.resolverAddress}`\n\t\t\t)\n\n\t\t\tconsole.log(\n\t\t\t\t`โœ… Initialized BasenameResolver for chain ${this.chainId} with resolver ${this.resolverAddress}`\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"โŒ Failed to initialize BasenameResolver:\", error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get the resolver address, initializing if necessary\n\t */\n\tprivate async getResolverAddress(): Promise<Address> {\n\t\tawait this.initializeResolver()\n\t\tif (!this.resolverAddress) {\n\t\t\tthrow new Error(\"Failed to initialize resolver address\")\n\t\t}\n\t\treturn this.resolverAddress\n\t}\n\n\t/**\n\t * Resolve a basename from an Ethereum address\n\t */\n\tasync getBasename(address: Address): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ” Starting basename resolution for address: ${address}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedBasename(address)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved basename from cache: ${cached}`)\n\t\t\t\treturn cached\n\t\t\t}\n\t\t\tconsole.log(`๐Ÿ“ญ No cached basename found for address: ${address}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting chain ID...\")\n\t\t\tconst chainId = await this.baseClient.getChainId()\n\t\t\tconsole.log(`๐Ÿ”— Chain ID: ${chainId}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting address to reverse node...\")\n\t\t\tconst addressReverseNode = convertReverseNodeToBytes(\n\t\t\t\t// address.toUpperCase() as `0x${string}`,\n\t\t\t\taddress as `0x${string}`,\n\t\t\t\tchainId\n\t\t\t)\n\t\t\tconsole.log(`๐Ÿ”— Reverse node: ${addressReverseNode}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Reading contract to resolve basename...\")\n\t\t\tconst basename = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"name\",\n\t\t\t\targs: [addressReverseNode]\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“‹ Contract returned basename: \"${basename}\" (length: ${basename?.length || 0})`\n\t\t\t)\n\n\t\t\tif (basename && basename.length > 0) {\n\t\t\t\tthis.setCachedBasename(address, basename)\n\t\t\t\tconsole.log(`โœ… Resolved basename: ${basename} for address: ${address}`)\n\t\t\t\treturn basename as BaseName\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No basename found for address: ${address} (empty or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving basename for address ${address}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get the avatar URL for a basename\n\t */\n\tasync getBasenameAvatar(basename: BaseName): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ–ผ๏ธ Getting avatar for basename: ${basename}`)\n\t\treturn this.getBasenameTextRecord(basename, BasenameTextRecordKeys.Avatar)\n\t}\n\n\t/**\n\t * Get a text record for a basename\n\t */\n\tasync getBasenameTextRecord(\n\t\tbasename: BaseName,\n\t\tkey: BasenameTextRecordKey\n\t): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ“ Getting text record \"${key}\" for basename: ${basename}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedTextRecord(basename, key)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved text record from cache: ${key}=${cached}`)\n\t\t\t\treturn cached\n\t\t\t}\n\t\t\tconsole.log(`๐Ÿ“ญ No cached text record found for ${basename}.${key}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting basename to node...\")\n\t\t\tconst node = convertBasenameToNode(basename)\n\t\t\tconsole.log(`๐Ÿ”— Node hash: ${node}`)\n\n\t\t\tconsole.log(`๐Ÿ”„ Reading contract for text record \"${key}\"...`)\n\t\t\tconst textRecord = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"text\",\n\t\t\t\targs: [node, key]\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“‹ Contract returned text record: \"${textRecord}\" (length: ${textRecord?.length || 0})`\n\t\t\t)\n\n\t\t\tif (textRecord && textRecord.length > 0) {\n\t\t\t\tthis.setCachedTextRecord(basename, key, textRecord)\n\t\t\t\tconsole.log(`โœ… Resolved text record: ${key}=${textRecord}`)\n\t\t\t\treturn textRecord\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No text record found for ${basename}.${key} (empty or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving text record ${key} for ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get the Ethereum address that owns a basename\n\t */\n\tasync getBasenameAddress(basename: BaseName): Promise<Address | null> {\n\t\tconsole.log(`๐Ÿ” Getting address for basename: ${basename}`)\n\n\t\ttry {\n\t\t\tconsole.log(\"๐Ÿ”„ Getting resolver address...\")\n\t\t\tconst resolverAddress = await this.getResolverAddress()\n\t\t\tconsole.log(`๐Ÿ“ Using resolver address: ${resolverAddress}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Converting basename to node...\")\n\t\t\tconst node = convertBasenameToNode(basename)\n\t\t\tconsole.log(`๐Ÿ”— Node hash: ${node}`)\n\n\t\t\tconsole.log(\"๐Ÿ”„ Reading contract to resolve address...\")\n\t\t\tconst address = await this.baseClient.readContract({\n\t\t\t\tabi: L2ResolverAbi,\n\t\t\t\taddress: resolverAddress,\n\t\t\t\tfunctionName: \"addr\",\n\t\t\t\targs: [node]\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ Contract returned address: \"${address}\"`)\n\n\t\t\tif (address && address !== \"0x0000000000000000000000000000000000000000\") {\n\t\t\t\tconsole.log(`โœ… Resolved address: ${address} for basename: ${basename}`)\n\t\t\t\treturn address as Address\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โŒ No address found for basename: ${basename} (zero address or null response)`\n\t\t\t)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving address for basename ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get all basic metadata for a basename\n\t */\n\tasync getBasenameMetadata(basename: BaseName) {\n\t\tconsole.log(`๐Ÿ“Š Getting metadata for basename: ${basename}`)\n\n\t\ttry {\n\t\t\tconst [avatar, description, twitter, github, url] = await Promise.all([\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Avatar),\n\t\t\t\tthis.getBasenameTextRecord(\n\t\t\t\t\tbasename,\n\t\t\t\t\tBasenameTextRecordKeys.Description\n\t\t\t\t),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Twitter),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Github),\n\t\t\t\tthis.getBasenameTextRecord(basename, BasenameTextRecordKeys.Url)\n\t\t\t])\n\n\t\t\tconst metadata = {\n\t\t\t\tbasename,\n\t\t\t\tavatar,\n\t\t\t\tdescription,\n\t\t\t\ttwitter,\n\t\t\t\tgithub,\n\t\t\t\turl\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… Resolved metadata for ${basename}:`, metadata)\n\t\t\treturn metadata\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving metadata for basename ${basename}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Resolve a full basename profile (name + metadata) from an address\n\t */\n\tasync resolveBasenameProfile(address: Address) {\n\t\tconsole.log(`๐Ÿ‘ค Resolving full basename profile for address: ${address}`)\n\n\t\ttry {\n\t\t\tconst basename = await this.getBasename(address)\n\t\t\tif (!basename) {\n\t\t\t\tconsole.log(`โŒ No basename found for address: ${address}`)\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ”„ Getting metadata for resolved basename: ${basename}`)\n\t\t\tconst metadata = await this.getBasenameMetadata(basename)\n\n\t\t\tconst profile = {\n\t\t\t\taddress,\n\t\t\t\t...metadata\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… Resolved full profile for ${address}:`, profile)\n\t\t\treturn profile\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error resolving basename profile for ${address}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t\tconsole.error(`โŒ Error stack:`, error.stack)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get cached basename if not expired\n\t */\n\tprivate getCachedBasename(address: Address): string | null {\n\t\tconst entry = this.cache.get(address.toLowerCase())\n\t\tif (!entry) {\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ“ญ No cache entry found for address: ${address.toLowerCase()}`\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst age = now - entry.timestamp\n\t\tconsole.log(`๐Ÿ• Cache entry age: ${age}ms (TTL: ${this.cacheTtl}ms)`)\n\n\t\tif (age > this.cacheTtl) {\n\t\t\tconsole.log(\n\t\t\t\t`โฐ Cache entry expired for address: ${address.toLowerCase()}`\n\t\t\t)\n\t\t\tthis.cache.delete(address.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`โœ… Valid cache entry found for ${address.toLowerCase()}: \"${entry.basename}\"`\n\t\t)\n\t\treturn entry.basename\n\t}\n\n\t/**\n\t * Cache basename with LRU eviction\n\t */\n\tprivate setCachedBasename(address: Address, basename: string): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.cache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.cache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tconsole.log(`๐Ÿ—‘๏ธ Cache full, removing oldest entry: ${firstKey}`)\n\t\t\t\tthis.cache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`๐Ÿ’พ Caching basename \"${basename}\" for address: ${address.toLowerCase()}`\n\t\t)\n\t\tthis.cache.set(address.toLowerCase(), {\n\t\t\tbasename,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached text record if not expired\n\t */\n\tprivate getCachedTextRecord(basename: string, key: string): string | null {\n\t\tconst basenameCache = this.textRecordCache.get(basename)\n\t\tif (!basenameCache) {\n\t\t\tconsole.log(`๐Ÿ“ญ No text record cache found for basename: ${basename}`)\n\t\t\treturn null\n\t\t}\n\n\t\tconst entry = basenameCache.get(key)\n\t\tif (!entry) {\n\t\t\tconsole.log(`๐Ÿ“ญ No cached text record found for ${basename}.${key}`)\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst age = now - entry.timestamp\n\t\tconsole.log(\n\t\t\t`๐Ÿ• Text record cache entry age: ${age}ms (TTL: ${this.cacheTtl}ms)`\n\t\t)\n\n\t\tif (age > this.cacheTtl) {\n\t\t\tconsole.log(`โฐ Text record cache entry expired for ${basename}.${key}`)\n\t\t\tbasenameCache.delete(key)\n\t\t\treturn null\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`โœ… Valid text record cache entry found for ${basename}.${key}: \"${entry.value}\"`\n\t\t)\n\t\treturn entry.value\n\t}\n\n\t/**\n\t * Cache text record\n\t */\n\tprivate setCachedTextRecord(\n\t\tbasename: string,\n\t\tkey: string,\n\t\tvalue: string\n\t): void {\n\t\tlet basenameCache = this.textRecordCache.get(basename)\n\t\tif (!basenameCache) {\n\t\t\tconsole.log(`๐Ÿ“ Creating new text record cache for basename: ${basename}`)\n\t\t\tbasenameCache = new Map()\n\t\t\tthis.textRecordCache.set(basename, basenameCache)\n\t\t}\n\n\t\tconsole.log(\n\t\t\t`๐Ÿ’พ Caching text record \"${key}\" = \"${value}\" for basename: ${basename}`\n\t\t)\n\t\tbasenameCache.set(key, {\n\t\t\tvalue,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tconst basenameCount = this.cache.size\n\t\tconst textRecordCount = this.textRecordCache.size\n\n\t\tthis.cache.clear()\n\t\tthis.textRecordCache.clear()\n\n\t\tconsole.log(`๐Ÿ—‘๏ธ Basename cache cleared (${basenameCount} entries removed)`)\n\t\tconsole.log(\n\t\t\t`๐Ÿ—‘๏ธ Text record cache cleared (${textRecordCount} basename caches removed)`\n\t\t)\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats(): {\n\t\tbasenameCache: { size: number; maxSize: number }\n\t\ttextRecordCache: { size: number }\n\t\tchainId: number | null\n\t\tresolverAddress: Address | null\n\t} {\n\t\treturn {\n\t\t\tbasenameCache: {\n\t\t\t\tsize: this.cache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\ttextRecordCache: {\n\t\t\t\tsize: this.textRecordCache.size\n\t\t\t},\n\t\t\tchainId: this.chainId,\n\t\t\tresolverAddress: this.resolverAddress\n\t\t}\n\t}\n}\n","export const L2ResolverAbi = [\n {\n inputs: [\n { internalType: \"contract ENS\", name: \"ens_\", type: \"address\" },\n {\n internalType: \"address\",\n name: \"registrarController_\",\n type: \"address\",\n },\n { internalType: \"address\", name: \"reverseRegistrar_\", type: \"address\" },\n { internalType: \"address\", name: \"owner_\", type: \"address\" },\n ],\n stateMutability: \"nonpayable\",\n type: \"constructor\",\n },\n { inputs: [], name: \"AlreadyInitialized\", type: \"error\" },\n { inputs: [], name: \"CantSetSelfAsDelegate\", type: \"error\" },\n { inputs: [], name: \"CantSetSelfAsOperator\", type: \"error\" },\n { inputs: [], name: \"NewOwnerIsZeroAddress\", type: \"error\" },\n { inputs: [], name: \"NoHandoverRequest\", type: \"error\" },\n { inputs: [], name: \"Unauthorized\", type: \"error\" },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"uint256\",\n name: \"contentType\",\n type: \"uint256\",\n },\n ],\n name: \"ABIChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"address\", name: \"a\", type: \"address\" },\n ],\n name: \"AddrChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"uint256\",\n name: \"coinType\",\n type: \"uint256\",\n },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"newAddress\",\n type: \"bytes\",\n },\n ],\n name: \"AddressChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"owner\",\n type: \"address\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"operator\",\n type: \"address\",\n },\n { indexed: false, internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"ApprovalForAll\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: false,\n internalType: \"address\",\n name: \"owner\",\n type: \"address\",\n },\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"address\",\n name: \"delegate\",\n type: \"address\",\n },\n { indexed: true, internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"Approved\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"ContenthashChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"name\", type: \"bytes\" },\n {\n indexed: false,\n internalType: \"uint16\",\n name: \"resource\",\n type: \"uint16\",\n },\n { indexed: false, internalType: \"bytes\", name: \"record\", type: \"bytes\" },\n ],\n name: \"DNSRecordChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes\", name: \"name\", type: \"bytes\" },\n {\n indexed: false,\n internalType: \"uint16\",\n name: \"resource\",\n type: \"uint16\",\n },\n ],\n name: \"DNSRecordDeleted\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"lastzonehash\",\n type: \"bytes\",\n },\n {\n indexed: false,\n internalType: \"bytes\",\n name: \"zonehash\",\n type: \"bytes\",\n },\n ],\n name: \"DNSZonehashChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"bytes4\",\n name: \"interfaceID\",\n type: \"bytes4\",\n },\n {\n indexed: false,\n internalType: \"address\",\n name: \"implementer\",\n type: \"address\",\n },\n ],\n name: \"InterfaceChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"string\", name: \"name\", type: \"string\" },\n ],\n name: \"NameChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"pendingOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipHandoverCanceled\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"pendingOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipHandoverRequested\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"oldOwner\",\n type: \"address\",\n },\n {\n indexed: true,\n internalType: \"address\",\n name: \"newOwner\",\n type: \"address\",\n },\n ],\n name: \"OwnershipTransferred\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { indexed: false, internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n name: \"PubkeyChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"newRegistrarController\",\n type: \"address\",\n },\n ],\n name: \"RegistrarControllerUpdated\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n {\n indexed: true,\n internalType: \"address\",\n name: \"newReverseRegistrar\",\n type: \"address\",\n },\n ],\n name: \"ReverseRegistrarUpdated\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: true,\n internalType: \"string\",\n name: \"indexedKey\",\n type: \"string\",\n },\n { indexed: false, internalType: \"string\", name: \"key\", type: \"string\" },\n { indexed: false, internalType: \"string\", name: \"value\", type: \"string\" },\n ],\n name: \"TextChanged\",\n type: \"event\",\n },\n {\n anonymous: false,\n inputs: [\n { indexed: true, internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n {\n indexed: false,\n internalType: \"uint64\",\n name: \"newVersion\",\n type: \"uint64\",\n },\n ],\n name: \"VersionChanged\",\n type: \"event\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"contentTypes\", type: \"uint256\" },\n ],\n name: \"ABI\",\n outputs: [\n { internalType: \"uint256\", name: \"\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"\", type: \"bytes\" },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"addr\",\n outputs: [{ internalType: \"address payable\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"coinType\", type: \"uint256\" },\n ],\n name: \"addr\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"approve\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"cancelOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"clearRecords\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"pendingOwner\", type: \"address\" },\n ],\n name: \"completeOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"contenthash\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"name\", type: \"bytes32\" },\n { internalType: \"uint16\", name: \"resource\", type: \"uint16\" },\n ],\n name: \"dnsRecord\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"ens\",\n outputs: [{ internalType: \"contract ENS\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"name\", type: \"bytes32\" },\n ],\n name: \"hasDNSRecords\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" },\n ],\n name: \"interfaceImplementer\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"owner\", type: \"address\" },\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n ],\n name: \"isApprovedFor\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"account\", type: \"address\" },\n { internalType: \"address\", name: \"operator\", type: \"address\" },\n ],\n name: \"isApprovedForAll\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes[]\", name: \"data\", type: \"bytes[]\" }],\n name: \"multicall\",\n outputs: [{ internalType: \"bytes[]\", name: \"results\", type: \"bytes[]\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"nodehash\", type: \"bytes32\" },\n { internalType: \"bytes[]\", name: \"data\", type: \"bytes[]\" },\n ],\n name: \"multicallWithNodeCheck\",\n outputs: [{ internalType: \"bytes[]\", name: \"results\", type: \"bytes[]\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"name\",\n outputs: [{ internalType: \"string\", name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"owner\",\n outputs: [{ internalType: \"address\", name: \"result\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"pendingOwner\", type: \"address\" },\n ],\n name: \"ownershipHandoverExpiresAt\",\n outputs: [{ internalType: \"uint256\", name: \"result\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"pubkey\",\n outputs: [\n { internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"\", type: \"bytes32\" }],\n name: \"recordVersions\",\n outputs: [{ internalType: \"uint64\", name: \"\", type: \"uint64\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"registrarController\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"renounceOwnership\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"requestOwnershipHandover\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes\", name: \"\", type: \"bytes\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"resolve\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"reverseRegistrar\",\n outputs: [{ internalType: \"address\", name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"contentType\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"setABI\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"uint256\", name: \"coinType\", type: \"uint256\" },\n { internalType: \"bytes\", name: \"a\", type: \"bytes\" },\n ],\n name: \"setAddr\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"address\", name: \"a\", type: \"address\" },\n ],\n name: \"setAddr\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"operator\", type: \"address\" },\n { internalType: \"bool\", name: \"approved\", type: \"bool\" },\n ],\n name: \"setApprovalForAll\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"setContenthash\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"data\", type: \"bytes\" },\n ],\n name: \"setDNSRecords\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" },\n { internalType: \"address\", name: \"implementer\", type: \"address\" },\n ],\n name: \"setInterface\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"newName\", type: \"string\" },\n ],\n name: \"setName\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"x\", type: \"bytes32\" },\n { internalType: \"bytes32\", name: \"y\", type: \"bytes32\" },\n ],\n name: \"setPubkey\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n {\n internalType: \"address\",\n name: \"registrarController_\",\n type: \"address\",\n },\n ],\n name: \"setRegistrarController\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"reverseRegistrar_\", type: \"address\" },\n ],\n name: \"setReverseRegistrar\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"key\", type: \"string\" },\n { internalType: \"string\", name: \"value\", type: \"string\" },\n ],\n name: \"setText\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"bytes\", name: \"hash\", type: \"bytes\" },\n ],\n name: \"setZonehash\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes4\", name: \"interfaceID\", type: \"bytes4\" }],\n name: \"supportsInterface\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"bytes32\", name: \"node\", type: \"bytes32\" },\n { internalType: \"string\", name: \"key\", type: \"string\" },\n ],\n name: \"text\",\n outputs: [{ internalType: \"string\", name: \"\", type: \"string\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"address\", name: \"newOwner\", type: \"address\" }],\n name: \"transferOwnership\",\n outputs: [],\n stateMutability: \"payable\",\n type: \"function\",\n },\n {\n inputs: [{ internalType: \"bytes32\", name: \"node\", type: \"bytes32\" }],\n name: \"zonehash\",\n outputs: [{ internalType: \"bytes\", name: \"\", type: \"bytes\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;","import { type Address, PublicClient } from \"viem\"\n\ninterface ENSResolverOptions {\n\t/**\n\t * Maximum number of ENS names to cache\n\t * @default 500\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n\t/**\n\t * Mainnet public client for ENS resolution\n\t */\n\tmainnetClient: PublicClient\n}\n\ninterface CacheEntry {\n\taddress: string\n\ttimestamp: number\n}\n\ninterface ReverseCacheEntry {\n\tensName: string\n\ttimestamp: number\n}\n\n/**\n * ENS Resolver for mainnet .eth names\n * Handles resolution of ENS names to addresses and reverse resolution\n */\nexport class ENSResolver {\n\tprivate cache = new Map<string, CacheEntry>()\n\tprivate reverseCache = new Map<string, ReverseCacheEntry>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly mainnetClient: PublicClient\n\n\tconstructor(options: ENSResolverOptions) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 500\n\t\tthis.cacheTtl = options.cacheTtl ?? 3600000 // 1 hour\n\t\tthis.mainnetClient = options.mainnetClient\n\t}\n\n\t/**\n\t * Resolve an ENS name to an Ethereum address\n\t */\n\tasync resolveENSName(ensName: string): Promise<Address | null> {\n\t\tconsole.log(`๐Ÿ” Resolving ENS name: ${ensName}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedAddress(ensName)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(`โœ… Resolved ENS from cache: ${ensName} โ†’ ${cached}`)\n\t\t\t\treturn cached as Address\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ“ญ No cached address found for ENS: ${ensName}`)\n\n\t\t\t// Resolve using mainnet ENS\n\t\t\tconsole.log(\"๐Ÿ”„ Reading ENS contract...\")\n\t\t\tconst address = await this.mainnetClient.getEnsAddress({\n\t\t\t\tname: ensName\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ ENS contract returned address: \"${address}\"`)\n\n\t\t\tif (address && address !== \"0x0000000000000000000000000000000000000000\") {\n\t\t\t\tthis.setCachedAddress(ensName, address)\n\t\t\t\tconsole.log(`โœ… Resolved ENS: ${ensName} โ†’ ${address}`)\n\t\t\t\treturn address\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No address found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error resolving ENS name ${ensName}:`, error)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Resolve an address to its primary ENS name (reverse resolution)\n\t */\n\tasync resolveAddressToENS(address: Address): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ” Reverse resolving address to ENS: ${address}`)\n\n\t\ttry {\n\t\t\t// Check cache first\n\t\t\tconst cached = this.getCachedENSName(address)\n\t\t\tif (cached) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… Resolved ENS from reverse cache: ${address} โ†’ ${cached}`\n\t\t\t\t)\n\t\t\t\treturn cached\n\t\t\t}\n\n\t\t\tconsole.log(`๐Ÿ“ญ No cached ENS name found for address: ${address}`)\n\n\t\t\t// Reverse resolve using mainnet ENS\n\t\t\tconsole.log(\"๐Ÿ”„ Reading ENS reverse resolver...\")\n\t\t\tconst ensName = await this.mainnetClient.getEnsName({\n\t\t\t\taddress: address\n\t\t\t})\n\n\t\t\tconsole.log(`๐Ÿ“‹ ENS reverse resolver returned: \"${ensName}\"`)\n\n\t\t\tif (ensName && ensName.length > 0) {\n\t\t\t\tthis.setCachedENSName(address, ensName)\n\t\t\t\tconsole.log(`โœ… Reverse resolved: ${address} โ†’ ${ensName}`)\n\t\t\t\treturn ensName\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No ENS name found for address: ${address}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error reverse resolving address ${address}:`, error)\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconsole.error(`โŒ Error details: ${error.message}`)\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get ENS avatar for a name\n\t */\n\tasync getENSAvatar(ensName: string): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ–ผ๏ธ Getting ENS avatar for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst avatar = await this.mainnetClient.getEnsAvatar({\n\t\t\t\tname: ensName\n\t\t\t})\n\n\t\t\tif (avatar) {\n\t\t\t\tconsole.log(`โœ… Found ENS avatar: ${avatar}`)\n\t\t\t\treturn avatar\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No avatar found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error getting ENS avatar for ${ensName}:`, error)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get ENS text record\n\t */\n\tasync getENSTextRecord(ensName: string, key: string): Promise<string | null> {\n\t\tconsole.log(`๐Ÿ“ Getting ENS text record \"${key}\" for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst textRecord = await this.mainnetClient.getEnsText({\n\t\t\t\tname: ensName,\n\t\t\t\tkey: key\n\t\t\t})\n\n\t\t\tif (textRecord && textRecord.length > 0) {\n\t\t\t\tconsole.log(`โœ… Found ENS text record: ${key}=${textRecord}`)\n\t\t\t\treturn textRecord\n\t\t\t}\n\n\t\t\tconsole.log(`โŒ No text record \"${key}\" found for ENS: ${ensName}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ Error getting ENS text record ${key} for ${ensName}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get comprehensive ENS profile\n\t */\n\tasync getENSProfile(ensName: string) {\n\t\tconsole.log(`๐Ÿ‘ค Getting ENS profile for: ${ensName}`)\n\n\t\ttry {\n\t\t\tconst [address, avatar, description, twitter, github, url] =\n\t\t\t\tawait Promise.all([\n\t\t\t\t\tthis.resolveENSName(ensName),\n\t\t\t\t\tthis.getENSAvatar(ensName),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"description\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"com.twitter\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"com.github\"),\n\t\t\t\t\tthis.getENSTextRecord(ensName, \"url\")\n\t\t\t\t])\n\n\t\t\tconst profile = {\n\t\t\t\tensName,\n\t\t\t\taddress,\n\t\t\t\tavatar,\n\t\t\t\tdescription,\n\t\t\t\ttwitter,\n\t\t\t\tgithub,\n\t\t\t\turl\n\t\t\t}\n\n\t\t\tconsole.log(`โœ… ENS profile for ${ensName}:`, profile)\n\t\t\treturn profile\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error getting ENS profile for ${ensName}:`, error)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Check if a name is a valid ENS name (.eth)\n\t */\n\tisENSName(name: string): boolean {\n\t\treturn name.endsWith(\".eth\") && !name.endsWith(\".base.eth\")\n\t}\n\n\t/**\n\t * Get cached address if not expired\n\t */\n\tprivate getCachedAddress(ensName: string): string | null {\n\t\tconst entry = this.cache.get(ensName.toLowerCase())\n\t\tif (!entry) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.cache.delete(ensName.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.address\n\t}\n\n\t/**\n\t * Cache address with LRU eviction\n\t */\n\tprivate setCachedAddress(ensName: string, address: string): void {\n\t\tif (this.cache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.cache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.cache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.cache.set(ensName.toLowerCase(), {\n\t\t\taddress,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached ENS name if not expired\n\t */\n\tprivate getCachedENSName(address: Address): string | null {\n\t\tconst entry = this.reverseCache.get(address.toLowerCase())\n\t\tif (!entry) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.reverseCache.delete(address.toLowerCase())\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.ensName\n\t}\n\n\t/**\n\t * Cache ENS name with LRU eviction\n\t */\n\tprivate setCachedENSName(address: Address, ensName: string): void {\n\t\tif (this.reverseCache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.reverseCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.reverseCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.reverseCache.set(address.toLowerCase(), {\n\t\t\tensName,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tconst addressCount = this.cache.size\n\t\tconst ensCount = this.reverseCache.size\n\n\t\tthis.cache.clear()\n\t\tthis.reverseCache.clear()\n\n\t\tconsole.log(`๐Ÿ—‘๏ธ ENS address cache cleared (${addressCount} entries removed)`)\n\t\tconsole.log(`๐Ÿ—‘๏ธ ENS reverse cache cleared (${ensCount} entries removed)`)\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats() {\n\t\treturn {\n\t\t\taddressCache: {\n\t\t\t\tsize: this.cache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\treverseCache: {\n\t\t\t\tsize: this.reverseCache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { XmtpClient, XmtpMessage } from \"../types\"\n\ninterface XmtpResolverOptions {\n\t/**\n\t * Maximum number of addresses to cache\n\t * @default 1000\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 86400000 (24 hours)\n\t */\n\tcacheTtl?: number\n\t/**\n\t * Maximum number of messages to cache\n\t * @default 1000\n\t */\n\tmaxMessageCacheSize?: number\n\t/**\n\t * Message cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tmessageCacheTtl?: number\n}\n\ninterface AddressCacheEntry {\n\taddress: string\n\ttimestamp: number\n}\n\ninterface MessageCacheEntry {\n\tmessage: XmtpMessage | null\n\ttimestamp: number\n}\n\nexport class XmtpResolver {\n\tprivate addressCache = new Map<string, AddressCacheEntry>()\n\tprivate messageCache = new Map<string, MessageCacheEntry>()\n\tprivate readonly maxCacheSize: number\n\tprivate readonly cacheTtl: number\n\tprivate readonly maxMessageCacheSize: number\n\tprivate readonly messageCacheTtl: number\n\n\tconstructor(\n\t\tprivate client: XmtpClient,\n\t\toptions: XmtpResolverOptions = {}\n\t) {\n\t\tthis.maxCacheSize = options.maxCacheSize ?? 1000\n\t\tthis.cacheTtl = options.cacheTtl ?? 86400000 // 24 hours\n\t\tthis.maxMessageCacheSize = options.maxMessageCacheSize ?? 1000\n\t\tthis.messageCacheTtl = options.messageCacheTtl ?? 3600000 // 1 hour\n\t}\n\n\t/**\n\t * Resolve user address from inbox ID with caching\n\t */\n\tasync resolveAddress(\n\t\tinboxId: string,\n\t\tconversationId?: string\n\t): Promise<`0x${string}` | null> {\n\t\t// Check cache first (fastest)\n\t\tconst cached = this.getCachedAddress(inboxId)\n\t\tif (cached) {\n\t\t\tconsole.log(\n\t\t\t\t`โœ… [XmtpResolver] Resolved user address from cache: ${cached}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\tlet userAddress = undefined\n\n\t\ttry {\n\t\t\t// Try conversation members lookup first (faster than network call)\n\t\t\tif (conversationId) {\n\t\t\t\tconst conversation =\n\t\t\t\t\tawait this.client.conversations.getConversationById(conversationId)\n\t\t\t\tif (conversation) {\n\t\t\t\t\tuserAddress = await this.resolveFromConversation(\n\t\t\t\t\t\tconversation,\n\t\t\t\t\t\tinboxId\n\t\t\t\t\t)\n\t\t\t\t\tif (userAddress) {\n\t\t\t\t\t\tthis.setCachedAddress(inboxId, userAddress)\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`โœ… [XmtpResolver] Resolved user address: ${userAddress}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn userAddress\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Fallback to inboxStateFromInboxIds\n\t\t\tuserAddress = await this.resolveFromInboxState(inboxId)\n\t\t\tif (userAddress) {\n\t\t\t\tthis.setCachedAddress(inboxId, userAddress)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… [XmtpResolver] Resolved user address via fallback: ${userAddress}`\n\t\t\t\t)\n\t\t\t\treturn userAddress\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] No identifiers found for inbox ${inboxId}`)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving user address for ${inboxId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Find any message by ID with caching\n\t */\n\tasync findMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\t// Check cache first\n\t\tconst cached = this.getCachedMessage(messageId)\n\t\tif (cached !== undefined) {\n\t\t\tconsole.log(\n\t\t\t\tcached\n\t\t\t\t\t? `โœ… [XmtpResolver] Found message from cache: ${cached.id}`\n\t\t\t\t\t: `โœ… [XmtpResolver] Found cached null message for: ${messageId}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ” [XmtpResolver] Finding message: ${messageId}`)\n\t\t\tconst message = await this.client.conversations.getMessageById(messageId)\n\n\t\t\tif (message) {\n\t\t\t\tthis.setCachedMessage(messageId, message)\n\t\t\t\tconsole.log(`โœ… [XmtpResolver] Found and cached message: ${message.id}`)\n\t\t\t\treturn message\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] Message not found: ${messageId}`)\n\t\t\tthis.setCachedMessage(messageId, null)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error finding message ${messageId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tthis.setCachedMessage(messageId, null)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Find root message with caching\n\t */\n\tasync findRootMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\t// Check if we already have the root cached with a special key\n\t\tconst rootCacheKey = `root:${messageId}`\n\t\tconst cached = this.getCachedMessage(rootCacheKey)\n\t\tif (cached !== undefined) {\n\t\t\tconsole.log(\n\t\t\t\tcached\n\t\t\t\t\t? `โœ… [XmtpResolver] Found root message from cache: ${cached.id}`\n\t\t\t\t\t: `โœ… [XmtpResolver] Found cached null root for: ${messageId}`\n\t\t\t)\n\t\t\treturn cached\n\t\t}\n\n\t\ttry {\n\t\t\tconsole.log(`๐Ÿ” [XmtpResolver] Finding root message for: ${messageId}`)\n\t\t\tconst rootMessage = await this.findRootMessageRecursive(messageId)\n\n\t\t\tif (rootMessage) {\n\t\t\t\tthis.setCachedMessage(rootCacheKey, rootMessage)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โœ… [XmtpResolver] Found and cached root message: ${rootMessage.id}`\n\t\t\t\t)\n\t\t\t\treturn rootMessage\n\t\t\t}\n\n\t\t\tconsole.log(`โš ๏ธ [XmtpResolver] No root message found for: ${messageId}`)\n\t\t\tthis.setCachedMessage(rootCacheKey, null)\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error finding root message for ${messageId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\tthis.setCachedMessage(rootCacheKey, null)\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Recursively finds the root message in a reply chain by following reply references\n\t */\n\tprivate async findRootMessageRecursive(\n\t\tmessageId: string,\n\t\tvisitedIds = new Set<string>()\n\t): Promise<XmtpMessage | null> {\n\t\t// Prevent infinite loops\n\t\tif (visitedIds.has(messageId)) {\n\t\t\tconsole.warn(\n\t\t\t\t`โš ๏ธ Circular reference detected in message chain at ${messageId}`\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\t\tvisitedIds.add(messageId)\n\n\t\tconst message = await this.client.conversations.getMessageById(messageId)\n\n\t\tif (!message) {\n\t\t\tconsole.warn(`โš ๏ธ [findRootMessage] Message not found: ${messageId}`)\n\t\t\treturn null\n\t\t}\n\n\t\t// Debug: Log the raw message structure as returned by XMTP client\n\t\tconsole.log(`๐Ÿ” [findRootMessage] Raw message ${messageId}:`, {\n\t\t\tid: message.id,\n\t\t\tcontentType: message.contentType,\n\t\t\tcontent: message.content,\n\t\t\tsentAt: message.sentAt\n\t\t})\n\n\t\t// Method 1: Try the parameters (as seen in webhook data)\n\t\tif ((message as any).content?.reference) {\n\t\t\treturn this.findRootMessageRecursive(\n\t\t\t\t(message as any).content.reference,\n\t\t\t\tvisitedIds\n\t\t\t)\n\t\t}\n\n\t\treturn message\n\t}\n\n\t/**\n\t * Resolve address from conversation members\n\t */\n\tprivate async resolveFromConversation(\n\t\tconversation: any,\n\t\tinboxId: string\n\t): Promise<`0x${string}` | null> {\n\t\ttry {\n\t\t\tconst members = await conversation.members()\n\t\t\tconst sender = members.find(\n\t\t\t\t(member: any) => member.inboxId.toLowerCase() === inboxId.toLowerCase()\n\t\t\t)\n\n\t\t\tif (sender) {\n\t\t\t\tconst ethIdentifier = sender.accountIdentifiers.find(\n\t\t\t\t\t(id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n\t\t\t\t)\n\t\t\t\tif (ethIdentifier) {\n\t\t\t\t\treturn ethIdentifier.identifier\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`โš ๏ธ [XmtpResolver] No Ethereum identifier found for inbox ${inboxId}`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`โš ๏ธ [XmtpResolver] Sender not found in conversation members for inbox ${inboxId}`\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving from conversation members:`,\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\n\t\treturn null\n\t}\n\n\t/**\n\t * Resolve address from inbox state (network fallback)\n\t */\n\tprivate async resolveFromInboxState(\n\t\tinboxId: string\n\t): Promise<`0x${string}` | null> {\n\t\ttry {\n\t\t\tconst inboxState = await this.client.preferences.inboxStateFromInboxIds([\n\t\t\t\tinboxId\n\t\t\t])\n\t\t\tconst firstState = inboxState?.[0]\n\t\t\tif (firstState?.identifiers && firstState.identifiers.length > 0) {\n\t\t\t\tconst firstIdentifier = firstState.identifiers[0]\n\t\t\t\treturn firstIdentifier?.identifier as `0x${string}`\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpResolver] Error resolving from inbox state:`,\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\n\t\treturn null\n\t}\n\n\t/**\n\t * Get cached address if not expired\n\t */\n\tprivate getCachedAddress(inboxId: string): `0x${string}` | null {\n\t\tconst entry = this.addressCache.get(inboxId)\n\t\tif (!entry) return null\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.cacheTtl) {\n\t\t\tthis.addressCache.delete(inboxId)\n\t\t\treturn null\n\t\t}\n\n\t\treturn entry.address as `0x${string}`\n\t}\n\n\t/**\n\t * Cache address with LRU eviction\n\t */\n\tprivate setCachedAddress(inboxId: string, address: `0x${string}`): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.addressCache.size >= this.maxCacheSize) {\n\t\t\tconst firstKey = this.addressCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.addressCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.addressCache.set(inboxId, {\n\t\t\taddress,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Get cached message if not expired\n\t */\n\tprivate getCachedMessage(messageId: string): XmtpMessage | null | undefined {\n\t\tconst entry = this.messageCache.get(messageId)\n\t\tif (!entry) return undefined\n\n\t\tconst now = Date.now()\n\t\tif (now - entry.timestamp > this.messageCacheTtl) {\n\t\t\tthis.messageCache.delete(messageId)\n\t\t\treturn undefined\n\t\t}\n\n\t\treturn entry.message\n\t}\n\n\t/**\n\t * Cache message with LRU eviction\n\t */\n\tprivate setCachedMessage(\n\t\tmessageId: string,\n\t\tmessage: XmtpMessage | null\n\t): void {\n\t\t// Simple LRU: if cache is full, remove oldest entry\n\t\tif (this.messageCache.size >= this.maxMessageCacheSize) {\n\t\t\tconst firstKey = this.messageCache.keys().next().value\n\t\t\tif (firstKey) {\n\t\t\t\tthis.messageCache.delete(firstKey)\n\t\t\t}\n\t\t}\n\n\t\tthis.messageCache.set(messageId, {\n\t\t\tmessage,\n\t\t\ttimestamp: Date.now()\n\t\t})\n\t}\n\n\t/**\n\t * Pre-populate address cache from existing conversations\n\t */\n\tasync prePopulateCache(): Promise<void> {\n\t\tconsole.log(\"๐Ÿ”„ [XmtpResolver] Pre-populating address cache...\")\n\t\ttry {\n\t\t\tconst conversations = await this.client.conversations.list()\n\t\t\tlet cachedCount = 0\n\n\t\t\tfor (const conversation of conversations) {\n\t\t\t\ttry {\n\t\t\t\t\tconst members = await conversation.members()\n\t\t\t\t\tfor (const member of members) {\n\t\t\t\t\t\tconst ethIdentifier = member.accountIdentifiers.find(\n\t\t\t\t\t\t\t(id: any) => id.identifierKind === 0 // IdentifierKind.Ethereum\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif (ethIdentifier) {\n\t\t\t\t\t\t\tthis.setCachedAddress(\n\t\t\t\t\t\t\t\tmember.inboxId,\n\t\t\t\t\t\t\t\tethIdentifier.identifier as `0x${string}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcachedCount++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"[XmtpResolver] Error pre-caching conversation members:\",\n\t\t\t\t\t\terror\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`โœ… [XmtpResolver] Pre-cached ${cachedCount} address mappings`\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[XmtpResolver] Error pre-populating cache:\", error)\n\t\t}\n\t}\n\n\t/**\n\t * Clear all caches\n\t */\n\tclearCache(): void {\n\t\tthis.addressCache.clear()\n\t\tthis.messageCache.clear()\n\t\tconsole.log(\"๐Ÿ—‘๏ธ [XmtpResolver] All caches cleared\")\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetCacheStats(): {\n\t\taddress: { size: number; maxSize: number }\n\t\tmessage: { size: number; maxSize: number }\n\t} {\n\t\treturn {\n\t\t\taddress: {\n\t\t\t\tsize: this.addressCache.size,\n\t\t\t\tmaxSize: this.maxCacheSize\n\t\t\t},\n\t\t\tmessage: {\n\t\t\t\tsize: this.messageCache.size,\n\t\t\t\tmaxSize: this.maxMessageCacheSize\n\t\t\t}\n\t\t}\n\t}\n}\n","import { type Address, type PublicClient } from \"viem\"\nimport type { XmtpClient, XmtpMessage, XmtpSender } from \"../types\"\nimport { AddressResolver } from \"./address-resolver\"\nimport {\n\ttype BaseName,\n\tBasenameResolver,\n\ttype BasenameTextRecordKey\n} from \"./basename-resolver\"\nimport { ENSResolver } from \"./ens-resolver\"\nimport { XmtpResolver } from \"./xmtp-resolver\"\n\ninterface ResolverOptions {\n\t/**\n\t * XMTP Client for message and address resolution\n\t */\n\txmtpClient: XmtpClient\n\t/**\n\t * Mainnet public client for ENS resolution\n\t */\n\tmainnetClient: PublicClient\n\t/**\n\t * Base network public client for basename resolution\n\t */\n\tbaseClient: PublicClient\n\t/**\n\t * Maximum cache size for each resolver\n\t * @default 1000\n\t */\n\tmaxCacheSize?: number\n\t/**\n\t * Cache TTL in milliseconds\n\t * @default 3600000 (1 hour)\n\t */\n\tcacheTtl?: number\n}\n\n/**\n * Master Resolver that wraps all individual resolvers\n * Provides a unified interface for basename, ENS, address, and XMTP resolution\n */\nexport class Resolver {\n\tprivate addressResolver: AddressResolver\n\tprivate ensResolver: ENSResolver\n\tprivate basenameResolver: BasenameResolver\n\tprivate xmtpResolver: XmtpResolver\n\n\tconstructor(options: ResolverOptions) {\n\t\tconst resolverOptions = {\n\t\t\tmaxCacheSize: options.maxCacheSize ?? 1000,\n\t\t\tcacheTtl: options.cacheTtl ?? 3600000\n\t\t}\n\n\t\tthis.addressResolver = new AddressResolver(\n\t\t\toptions.xmtpClient,\n\t\t\tresolverOptions\n\t\t)\n\t\tthis.xmtpResolver = new XmtpResolver(options.xmtpClient, resolverOptions)\n\n\t\t// Type assertions needed due to viem version differences across monorepo packages\n\t\t// Both clients are PublicClient-compatible but TypeScript sees them as incompatible types\n\t\tthis.ensResolver = new ENSResolver({\n\t\t\t...resolverOptions,\n\t\t\tmainnetClient: options.mainnetClient as PublicClient\n\t\t})\n\t\tthis.basenameResolver = new BasenameResolver({\n\t\t\t...resolverOptions,\n\t\t\tpublicClient: options.baseClient as PublicClient\n\t\t})\n\t}\n\n\t// === Address Resolution Methods ===\n\n\t/**\n\t * Resolve user address from inbox ID with caching\n\t * Uses both AddressResolver and XmtpResolver for redundancy\n\t */\n\tasync resolveAddress(\n\t\tinboxId: string,\n\t\tconversationId?: string\n\t): Promise<`0x${string}` | null> {\n\t\t// Try AddressResolver first, fallback to XmtpResolver\n\t\tlet result = await this.addressResolver.resolveAddress(\n\t\t\tinboxId,\n\t\t\tconversationId\n\t\t)\n\t\tif (!result) {\n\t\t\tresult = await this.xmtpResolver.resolveAddress(inboxId, conversationId)\n\t\t}\n\t\treturn result\n\t}\n\n\t// === ENS Resolution Methods ===\n\n\t/**\n\t * Resolve an ENS name to an Ethereum address\n\t */\n\tasync resolveENSName(ensName: string): Promise<Address | null> {\n\t\treturn this.ensResolver.resolveENSName(ensName)\n\t}\n\n\t/**\n\t * Resolve an address to its primary ENS name (reverse resolution)\n\t */\n\tasync resolveAddressToENS(address: Address): Promise<string | null> {\n\t\treturn this.ensResolver.resolveAddressToENS(address)\n\t}\n\n\t/**\n\t * Get ENS avatar for a given ENS name\n\t */\n\tasync getENSAvatar(ensName: string): Promise<string | null> {\n\t\treturn this.ensResolver.getENSAvatar(ensName)\n\t}\n\n\t/**\n\t * Get ENS text record for a given ENS name and key\n\t */\n\tasync getENSTextRecord(ensName: string, key: string): Promise<string | null> {\n\t\treturn this.ensResolver.getENSTextRecord(ensName, key)\n\t}\n\n\t/**\n\t * Get complete ENS profile for a given ENS name\n\t */\n\tasync getENSProfile(ensName: string) {\n\t\treturn this.ensResolver.getENSProfile(ensName)\n\t}\n\n\t// === Basename Resolution Methods ===\n\n\t/**\n\t * Get basename from an Ethereum address\n\t */\n\tasync getBasename(address: Address): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasename(address)\n\t}\n\n\t/**\n\t * Get basename avatar for a given basename\n\t */\n\tasync getBasenameAvatar(basename: BaseName): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasenameAvatar(basename)\n\t}\n\n\t/**\n\t * Get basename text record for a given basename and key\n\t */\n\tasync getBasenameTextRecord(\n\t\tbasename: BaseName,\n\t\tkey: BasenameTextRecordKey\n\t): Promise<string | null> {\n\t\treturn this.basenameResolver.getBasenameTextRecord(basename, key)\n\t}\n\n\t/**\n\t * Resolve basename to an Ethereum address\n\t */\n\tasync getBasenameAddress(basename: BaseName): Promise<Address | null> {\n\t\treturn this.basenameResolver.getBasenameAddress(basename)\n\t}\n\n\t/**\n\t * Get basename metadata for a given basename\n\t */\n\tasync getBasenameMetadata(basename: BaseName) {\n\t\treturn this.basenameResolver.getBasenameMetadata(basename)\n\t}\n\n\t/**\n\t * Get complete basename profile for a given address\n\t */\n\tasync resolveBasenameProfile(address: Address) {\n\t\treturn this.basenameResolver.resolveBasenameProfile(address)\n\t}\n\n\t// === XMTP Message Methods ===\n\n\t/**\n\t * Find any message by ID with caching\n\t */\n\tasync findMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\treturn this.xmtpResolver.findMessage(messageId)\n\t}\n\n\t/**\n\t * Find root message by ID (traverses reply chain)\n\t */\n\tasync findRootMessage(messageId: string): Promise<XmtpMessage | null> {\n\t\treturn this.xmtpResolver.findRootMessage(messageId)\n\t}\n\n\t// === Universal Resolution Methods ===\n\n\t/**\n\t * Universal name resolution - tries to resolve any name (ENS or basename) to an address\n\t */\n\tasync resolveName(name: string): Promise<Address | null> {\n\t\t// Try ENS first (more common)\n\t\tif (name.endsWith(\".eth\")) {\n\t\t\treturn this.resolveENSName(name)\n\t\t}\n\n\t\t// Try basename\n\t\tif (name.endsWith(\".base.eth\")) {\n\t\t\treturn this.getBasenameAddress(name)\n\t\t}\n\n\t\t// If no TLD, try both\n\t\tconst ensResult = await this.resolveENSName(name)\n\t\tif (ensResult) {\n\t\t\treturn ensResult\n\t\t}\n\n\t\treturn this.getBasenameAddress(name)\n\t}\n\n\t/**\n\t * Universal reverse resolution - tries to resolve an address to any name (ENS or basename)\n\t */\n\tasync resolveAddressToName(address: Address): Promise<string | null> {\n\t\t// Try basename first (more relevant for this project)\n\t\tconst basename = await this.getBasename(address)\n\t\tif (basename) {\n\t\t\treturn basename\n\t\t}\n\n\t\t// Try ENS as fallback\n\t\treturn this.resolveAddressToENS(address)\n\t}\n\n\t/**\n\t * Get complete profile for an address (combines ENS and basename data)\n\t */\n\tasync getCompleteProfile(address: Address) {\n\t\tconst [ensName, basename, ensProfile, basenameProfile] =\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.resolveAddressToENS(address),\n\t\t\t\tthis.getBasename(address),\n\t\t\t\tthis.resolveAddressToENS(address).then((name) =>\n\t\t\t\t\tname ? this.getENSProfile(name) : null\n\t\t\t\t),\n\t\t\t\tthis.resolveBasenameProfile(address)\n\t\t\t])\n\n\t\treturn {\n\t\t\taddress,\n\t\t\tensName: ensName.status === \"fulfilled\" ? ensName.value : null,\n\t\t\tbasename: basename.status === \"fulfilled\" ? basename.value : null,\n\t\t\tensProfile: ensProfile.status === \"fulfilled\" ? ensProfile.value : null,\n\t\t\tbasenameProfile:\n\t\t\t\tbasenameProfile.status === \"fulfilled\" ? basenameProfile.value : null\n\t\t}\n\t}\n\n\t// === Cache Management Methods ===\n\n\t/**\n\t * Pre-populate all resolver caches\n\t */\n\tasync prePopulateAllCaches(): Promise<void> {\n\t\tawait Promise.allSettled([\n\t\t\tthis.addressResolver.prePopulateCache(),\n\t\t\tthis.xmtpResolver.prePopulateCache()\n\t\t])\n\t}\n\n\t/**\n\t * Create a complete XmtpSender object from an address or inboxId\n\t * Uses the resolver to get the best available name and profile information\n\t */\n\tasync createXmtpSender(\n\t\taddressOrInboxId: string,\n\t\tconversationId?: string\n\t): Promise<XmtpSender> {\n\t\tlet address: `0x${string}` | null = null\n\t\tlet inboxId = addressOrInboxId\n\n\t\t// Check if input looks like an Ethereum address\n\t\tif (addressOrInboxId.startsWith(\"0x\") && addressOrInboxId.length === 42) {\n\t\t\taddress = addressOrInboxId as `0x${string}`\n\t\t\t// When we have an address, we need to find the actual inboxId\n\t\t\t// For now, use address as fallback but this should be resolved from XMTP\n\t\t\tinboxId = addressOrInboxId // This will be improved when we have proper address->inboxId resolution\n\t\t} else {\n\t\t\t// Assume it's an inboxId, try to resolve to address\n\t\t\taddress = await this.resolveAddress(addressOrInboxId, conversationId)\n\t\t}\n\n\t\t// Get the best available name using universal resolution\n\t\tlet name = \"Unknown\"\n\t\tlet basename: string | undefined\n\n\t\tif (address) {\n\t\t\t// Try basename first since that's what we expect for this address\n\t\t\tconst basenameResult = await this.getBasename(address)\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” [RESOLVER] Direct basename lookup for ${address}:`,\n\t\t\t\tbasenameResult\n\t\t\t)\n\n\t\t\t// Try to get a human-readable name\n\t\t\tconst resolvedName = await this.resolveAddressToName(address)\n\t\t\tconsole.log(\n\t\t\t\t`๐Ÿ” [RESOLVER] Universal name resolution for ${address}:`,\n\t\t\t\tresolvedName\n\t\t\t)\n\n\t\t\tif (resolvedName) {\n\t\t\t\tname = resolvedName\n\t\t\t\t// Check if it's a basename specifically\n\t\t\t\tif (resolvedName.endsWith(\".base.eth\")) {\n\t\t\t\t\tbasename = resolvedName\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Fallback to shortened address\n\t\t\t\tname = `${address.slice(0, 6)}...${address.slice(-4)}`\n\t\t\t}\n\n\t\t\t// Always try to get basename even if ENS was found\n\t\t\tif (!basename) {\n\t\t\t\tconst resolvedBasename = await this.getBasename(address)\n\t\t\t\tbasename = resolvedBasename || undefined\n\t\t\t}\n\t\t} else {\n\t\t\t// No address resolution available, use inboxId\n\t\t\tname = `${inboxId.slice(0, 8)}...${inboxId.slice(-4)}`\n\t\t}\n\n\t\treturn {\n\t\t\taddress: address || addressOrInboxId,\n\t\t\tinboxId,\n\t\t\tname,\n\t\t\tbasename\n\t\t}\n\t}\n}\n","import type { BasenameResolver } from \"../resolver/basename-resolver\"\nimport type { ENSResolver } from \"../resolver/ens-resolver\"\n\n/**\n * Extract basenames/ENS names from message content using @mention pattern\n * @param content The message content to parse\n * @returns Array of unique names found in the message\n */\nexport function extractMentionedNames(content: string): string[] {\n\t// Match @basename.eth and @basename.base.eth patterns (case insensitive)\n\tconst nameRegex = /@([a-zA-Z0-9-_]+\\.(?:base\\.)?eth)\\b/gi\n\tconst matches = content.match(nameRegex)\n\n\tif (!matches) {\n\t\treturn []\n\t}\n\n\t// Remove @ symbol and deduplicate\n\tconst names = matches.map((match) => match.slice(1).toLowerCase())\n\treturn [...new Set(names)]\n}\n\n/**\n * Resolve mentioned names to addresses and return as subjects object\n * @param mentionedNames Array of names to resolve\n * @param basenameResolver Basename resolver instance\n * @param ensResolver ENS resolver instance\n * @returns Promise that resolves to subjects object mapping names to addresses\n */\nexport async function resolveSubjects(\n\tmentionedNames: string[],\n\tbasenameResolver: BasenameResolver,\n\tensResolver: ENSResolver\n): Promise<Record<string, `0x${string}`>> {\n\tconst subjects: Record<string, `0x${string}`> = {}\n\n\tif (mentionedNames.length === 0) {\n\t\treturn subjects\n\t}\n\n\tconsole.log(\n\t\t`๐Ÿ” Found ${mentionedNames.length} name mentions:`,\n\t\tmentionedNames\n\t)\n\n\tfor (const mentionedName of mentionedNames) {\n\t\ttry {\n\t\t\tlet resolvedAddress: string | null = null\n\n\t\t\t// Check if it's an ENS name (.eth but not .base.eth)\n\t\t\tif (ensResolver.isENSName(mentionedName)) {\n\t\t\t\tconsole.log(`๐Ÿ” Resolving ENS name: ${mentionedName}`)\n\t\t\t\tresolvedAddress = await ensResolver.resolveENSName(mentionedName)\n\t\t\t} else {\n\t\t\t\t// It's a basename (.base.eth or other format)\n\t\t\t\tconsole.log(`๐Ÿ” Resolving basename: ${mentionedName}`)\n\t\t\t\tresolvedAddress =\n\t\t\t\t\tawait basenameResolver.getBasenameAddress(mentionedName)\n\t\t\t}\n\n\t\t\tif (resolvedAddress) {\n\t\t\t\tsubjects[mentionedName] = resolvedAddress as `0x${string}`\n\t\t\t\tconsole.log(`โœ… Resolved ${mentionedName} โ†’ ${resolvedAddress}`)\n\t\t\t} else {\n\t\t\t\tconsole.log(`โŒ Could not resolve address for: ${mentionedName}`)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`โŒ Error resolving ${mentionedName}:`, error)\n\t\t}\n\t}\n\n\treturn subjects\n}\n\n/**\n * Extract subjects from message content (combines extraction and resolution)\n * @param content The message content to parse\n * @param basenameResolver Basename resolver instance\n * @param ensResolver ENS resolver instance\n * @returns Promise that resolves to subjects object mapping names to addresses\n */\nexport async function extractSubjects(\n\tcontent: string,\n\tbasenameResolver: BasenameResolver,\n\tensResolver: ENSResolver\n): Promise<Record<string, `0x${string}`>> {\n\tconst mentionedNames = extractMentionedNames(content)\n\treturn await resolveSubjects(mentionedNames, basenameResolver, ensResolver)\n}\n","/**\n * @fileoverview XMTP Service Client Library\n *\n * Clean, reusable client for making HTTP calls to the XMTP listener service.\n * Handles authentication, request formatting, and error handling.\n *\n * This is different from the direct XMTP client - this is for external services\n * talking to our XMTP listener service.\n */\n\nimport type {\n\tGetMessageParams,\n\tSendMessageParams,\n\tSendMessageResponse,\n\tSendReactionParams,\n\tSendReactionResponse,\n\tSendReplyParams,\n\tSendReplyResponse,\n\tSendTransactionParams,\n\tSendTransactionResponse,\n\tXmtpServiceClientConfig,\n\tXmtpServiceMessage,\n\tXmtpServiceResponse\n} from \"./types\"\n\nexport class XmtpServiceClient {\n\tprivate config: XmtpServiceClientConfig\n\n\tconstructor(config: XmtpServiceClientConfig) {\n\t\tthis.config = config\n\t}\n\n\tprivate async request<T = unknown>(\n\t\tendpoint: string,\n\t\tbody?: Record<string, unknown>,\n\t\tmethod: \"GET\" | \"POST\" = \"POST\"\n\t): Promise<XmtpServiceResponse<T>> {\n\t\ttry {\n\t\t\tconst baseUrl = this.config.serviceUrl.replace(/\\/+$/, \"\")\n\n\t\t\t// Use Authorization header for xmtp-tools endpoints, query parameter for others\n\t\t\tconst isXmtpToolsEndpoint = endpoint.startsWith(\"/xmtp-tools/\")\n\t\t\tconst url = `${baseUrl}${endpoint}?token=${this.config.serviceToken}`\n\n\t\t\tconst headers: Record<string, string> = {\n\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t}\n\n\t\t\t// Add Authorization header for xmtp-tools endpoints\n\t\t\tif (isXmtpToolsEndpoint) {\n\t\t\t\theaders.Authorization = `Bearer ${this.config.serviceToken}`\n\t\t\t}\n\n\t\t\tconst fetchOptions: RequestInit = {\n\t\t\t\tmethod,\n\t\t\t\theaders\n\t\t\t}\n\n\t\t\tif (method === \"POST\" && body) {\n\t\t\t\tfetchOptions.body = JSON.stringify(body)\n\t\t\t}\n\n\t\t\tconst response = await fetch(url, fetchOptions)\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`\n\t\t\t\ttry {\n\t\t\t\t\tconst responseText = await response.text()\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst errorData = JSON.parse(responseText) as { error?: string }\n\t\t\t\t\t\terrorMessage = errorData.error || errorMessage\n\t\t\t\t\t} catch {\n\t\t\t\t\t\terrorMessage = responseText || errorMessage\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If we can't read the response at all, use the status\n\t\t\t\t}\n\t\t\t\tthrow new Error(errorMessage)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: (await response.json()) as T\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\t`โŒ [XmtpServiceClient] Request to ${endpoint} failed:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: error instanceof Error ? error.message : \"Unknown error\"\n\t\t\t}\n\t\t}\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendMessageParams\n\t): Promise<XmtpServiceResponse<SendMessageResponse>> {\n\t\treturn this.request<SendMessageResponse>(\"/xmtp-tools/send\", {\n\t\t\tcontent: params.content\n\t\t})\n\t}\n\n\tasync sendReply(\n\t\tparams: SendReplyParams\n\t): Promise<XmtpServiceResponse<SendReplyResponse>> {\n\t\treturn this.request<SendReplyResponse>(\"/xmtp-tools/reply\", {\n\t\t\tcontent: params.content,\n\t\t\tmessageId: params.messageId\n\t\t})\n\t}\n\n\tasync sendReaction(\n\t\tparams: SendReactionParams\n\t): Promise<XmtpServiceResponse<SendReactionResponse>> {\n\t\treturn this.request<SendReactionResponse>(\"/xmtp-tools/react\", {\n\t\t\tmessageId: params.messageId,\n\t\t\temoji: params.emoji,\n\t\t\taction: params.action\n\t\t})\n\t}\n\n\tasync sendTransaction(\n\t\tparams: SendTransactionParams\n\t): Promise<XmtpServiceResponse<SendTransactionResponse>> {\n\t\treturn this.request<SendTransactionResponse>(\"/xmtp-tools/transaction\", {\n\t\t\tfromAddress: params.fromAddress,\n\t\t\tchainId: params.chainId,\n\t\t\tcalls: params.calls.map((call) => ({\n\t\t\t\tto: call.to,\n\t\t\t\tdata: call.data,\n\t\t\t\t...(call.gas && { gas: call.gas }),\n\t\t\t\tvalue: call.value || \"0x0\",\n\t\t\t\tmetadata: {\n\t\t\t\t\t...call.metadata,\n\t\t\t\t\tchainId: params.chainId,\n\t\t\t\t\tfrom: params.fromAddress,\n\t\t\t\t\tversion: \"1\"\n\t\t\t\t}\n\t\t\t}))\n\t\t})\n\t}\n\n\t/**\n\t * Get a single message by ID\n\t */\n\tasync getMessage(\n\t\tparams: GetMessageParams\n\t): Promise<XmtpServiceResponse<XmtpServiceMessage>> {\n\t\treturn this.request<XmtpServiceMessage>(\n\t\t\t`/xmtp-tools/messages/${params.messageId}`,\n\t\t\tundefined,\n\t\t\t\"GET\"\n\t\t)\n\t}\n\n\t// getConversationMessages removed - superseded by thread-based approach\n}\n\n/**\n * Create an XMTP service client from runtime context\n * Expects the runtime context to have xmtpServiceUrl and xmtpServiceToken\n */\nexport function createXmtpServiceClient(\n\tserviceUrl: string,\n\tserviceToken: string\n): XmtpServiceClient {\n\tif (!serviceUrl || !serviceToken) {\n\t\tthrow new Error(\"Missing XMTP service URL or token from runtime context\")\n\t}\n\n\treturn new XmtpServiceClient({\n\t\tserviceUrl,\n\t\tserviceToken\n\t})\n}\n\nexport interface XmtpAuthConfig {\n\tserviceUrl: string\n\tserviceToken: string\n\tsource: \"callback\" | \"environment\"\n}\n\n/**\n * Get XMTP authentication configuration from multiple sources\n * Priority: callback credentials > environment credentials\n */\nexport function getXmtpAuthConfig(\n\tcallbackUrl?: string,\n\tcallbackToken?: string\n): XmtpAuthConfig | null {\n\t// Priority 1: Use callback credentials if available\n\tif (callbackUrl && callbackToken) {\n\t\tconsole.log(\"๐Ÿ”‘ [XmtpAuth] Using callback-provided credentials\")\n\t\treturn {\n\t\t\tserviceUrl: callbackUrl,\n\t\t\tserviceToken: callbackToken,\n\t\t\tsource: \"callback\"\n\t\t}\n\t}\n\n\t// Priority 2: Use environment credentials\n\tconst envUrl = process.env.XMTP_HOST\n\tconst envToken = process.env.XMTP_API_KEY\n\n\tif (envUrl && envToken) {\n\t\tconsole.log(\"๐Ÿ”‘ [XmtpAuth] Using environment credentials\")\n\t\treturn {\n\t\t\tserviceUrl: envUrl,\n\t\t\tserviceToken: envToken,\n\t\t\tsource: \"environment\"\n\t\t}\n\t}\n\n\t// No valid credentials found\n\tconsole.error(\n\t\t\"โŒ [XmtpAuth] No XMTP credentials found in callback or environment\"\n\t)\n\tconsole.error(\n\t\t\"๐Ÿ’ก [XmtpAuth] Expected: XMTP_HOST + XMTP_API_KEY or callback credentials\"\n\t)\n\treturn null\n}\n\n/**\n * Create an authenticated XMTP service client\n * Handles both callback and environment credential sources\n */\nexport function createAuthenticatedXmtpClient(\n\tcallbackUrl?: string,\n\tcallbackToken?: string\n): XmtpServiceClient {\n\tconst authConfig = getXmtpAuthConfig(callbackUrl, callbackToken)\n\n\tif (!authConfig) {\n\t\tthrow new Error(\"No XMTP credentials found\")\n\t}\n\n\tconsole.log(\n\t\t`๐Ÿ”— [XmtpAuth] Creating XMTP client (${authConfig.source} credentials)`\n\t)\n\n\treturn createXmtpServiceClient(authConfig.serviceUrl, authConfig.serviceToken)\n}\n\n/**\n * Constructs a URL for XMTP tools API endpoints with token authentication\n *\n * @param {string} baseUrl - The base URL of the XMTP service (e.g., \"https://api.example.com\")\n * @param {string} action - The specific action/endpoint to call (e.g., \"send\", \"receive\", \"status\")\n * @param {string} token - Authentication token (either JWT or API key)\n * @returns {string} Complete URL with token as query parameter\n *\n * @description\n * Builds URLs for XMTP tools endpoints using query parameter authentication.\n * The token is appended as a query parameter for GET request authentication,\n * following the pattern: `/xmtp-tools/{action}?token={token}`\n *\n * @example\n * ```typescript\n * const url = getXMTPToolsUrl(\n * \"https://api.hybrid.dev\",\n * \"send\",\n * \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n * );\n * // Returns: \"https://api.hybrid.dev/xmtp-tools/send?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n * ```\n *\n * @example\n * ```typescript\n * // Using with API key\n * const url = getXMTPToolsUrl(\n * process.env.XMTP_BASE_URL,\n * \"status\",\n * process.env.XMTP_API_KEY\n * );\n * ```\n */\nexport function getXMTPToolsUrl(\n\tbaseUrl: string,\n\taction: string,\n\ttoken: string\n): string {\n\treturn `${baseUrl}/xmtp-tools/${action}?token=${token}`\n}\n","import { ContentTypeReaction } from \"@xmtp/content-type-reaction\"\nimport { ContentTypeReply, Reply } from \"@xmtp/content-type-reply\"\nimport { ContentTypeText } from \"@xmtp/content-type-text\"\nimport { ContentTypeWalletSendCalls, WalletSendCallsParams } from \"@xmtp/content-type-wallet-send-calls\"\nimport { Hono } from \"hono\"\nimport { getValidatedPayload, validateXMTPToolsToken } from \"./lib/jwt\"\nimport type { HonoVariables, SendMessageParams, SendReactionParams, SendReplyParams, SendTransactionParams } from \"./types\"\n\nconst app = new Hono<{ Variables: HonoVariables }>()\n\napp.get(\"/messages/:messageId\", async (c) => {\n\tconst xmtpClient = c.get(\"xmtpClient\")\n\n\tif (!xmtpClient) {\n\t\treturn c.json({ error: \"XMTP client not initialized\" }, 500)\n\t}\n\n\tconst token = c.req.query(\"token\")\n\n\tif (!token) {\n\t\treturn c.json({ error: \"Token required\" }, 401)\n\t}\n\n\tconst payload = validateXMTPToolsToken(token)\n\tif (!payload) {\n\t\treturn c.json({ error: \"Invalid or expired token\" }, 401)\n\t}\n\n\tconst messageId = c.req.param(\"messageId\")\n\n\ttry {\n\t\tconst message = await xmtpClient.conversations.getMessageById(messageId)\n\t\tif (!message) {\n\t\t\treturn c.json({ error: \"Message not found\" }, 404)\n\t\t}\n\n\t\tconsole.log(`โœ… Retrieved message ${messageId}`)\n\n\t\tconst transformedMessage = {\n\t\t\tid: message.id,\n\t\t\tsenderInboxId: message.senderInboxId,\n\t\t\tsentAt: message.sentAt.toISOString(),\n\t\t\tcontent:\n\t\t\t\ttypeof message.content === \"object\"\n\t\t\t\t\t? JSON.stringify(message.content)\n\t\t\t\t\t: message.content,\n\t\t\tcontentType: message.contentType?.typeId || \"text\",\n\t\t\tconversationId: message.conversationId,\n\t\t\tparameters: (message.contentType as any)?.parameters || {}\n\t\t}\n\n\t\treturn c.json(transformedMessage)\n\t} catch (error) {\n\t\tconsole.error(\"โŒ Error fetching message:\", error)\n\t\treturn c.json({ error: \"Failed to fetch message\" }, 500)\n\t}\n})\n\n// XMTP Tools endpoints\napp.post(\"/send\", async (c) => {\n\tconst xmtpClient = c.get(\"xmtpClient\")\n\n\tif (!xmtpClient) {\n\t\treturn c.json({ error: \"XMTP client not initialized\" }, 500)\n\t}\n\n\tconst payload = getValidatedPayload(c)\n\tif (!payload) {\n\t\treturn c.json({ error: \"Invalid or expired token\" }, 401)\n\t}\n\n\t// Get request body data\n\tconst body = await c.req.json<SendMessageParams>()\n\n\t// Content can come from JWT payload or request body\n\tconst content = body.content || payload.content\n\tif (!content) {\n\t\treturn c.json({ error: \"Content required for send action\" }, 400)\n\t}\n\n\tconst conversationId = payload.conversationId\n\n\t// Conversation ID can come from JWT payload or request body (for API key auth)\n\t// const conversationId = payload.conversationId || body.conversationId\n\tif (!conversationId) {\n\t\treturn c.json({ error: \"Conversation ID required\" }, 400)\n\t}\n\n\ttry {\n\t\tconst conversation =\n\t\t\tawait xmtpClient.conversations.getConversationById(conversationId)\n\t\tif (!conversation) {\n\t\t\treturn c.json({ error: \"Conversation not found\" }, 404)\n\t\t}\n\n\t\tawait conversation.send(content)\n\t\tconsole.log(`โžก Sent message to conversation ${conversationId}`)\n\n\t\treturn c.json({\n\t\t\tsuccess: true,\n\t\t\taction: \"send\",\n\t\t\tconversationId: payload.conversationId\n\t\t})\n\t} catch (error) {\n\t\tconsole.error(\"โŒ Error sending message:\", error)\n\t\treturn c.json({ error: \"Failed to send message\" }, 500)\n\t}\n})\n\napp.post(\"/reply\", async (c) => {\n\tconst xmtpClient = c.get(\"xmtpClient\")\n\n\tif (!xmtpClient) {\n\t\treturn c.json({ error: \"XMTP client not initialized\" }, 500)\n\t}\n\n\tconst payload = getValidatedPayload(c)\n\tif (!payload) {\n\t\treturn c.json({ error: \"Invalid or expired token\" }, 401)\n\t}\n\n\t// Get request body data\n\tconst body = await c.req.json<SendReplyParams>()\n\n\t// Content can come from JWT payload or request body\n\tconst content = body.content || payload.content\n\tif (!content) {\n\t\treturn c.json({ error: \"Content required for reply action\" }, 400)\n\t}\n\n\t// Reference message ID can come from JWT payload or request body\n\tconst messageId = body.messageId\n\n\tif (!messageId) {\n\t\treturn c.json(\n\t\t\t{ error: \"Reference message ID required for reply action\" },\n\t\t\t400\n\t\t)\n\t}\n\n\ttry {\n\t\tconst conversation = await xmtpClient.conversations.getConversationById(\n\t\t\tpayload.conversationId\n\t\t)\n\t\tif (!conversation) {\n\t\t\treturn c.json({ error: \"Conversation not found\" }, 404)\n\t\t}\n\n\t\t// Create proper XMTP reply structure\n\t\tconst reply: Reply = {\n\t\t\treference: messageId,\n\t\t\tcontentType: ContentTypeText,\n\t\t\tcontent: content\n\t\t}\n\n\t\t// Send as a proper threaded reply\n\t\tawait conversation.send(reply, ContentTypeReply)\n\t\tconsole.log(\n\t\t\t`โžก Sent reply \"${content}\" to conversation ${payload.conversationId}`\n\t\t)\n\n\t\treturn c.json({\n\t\t\tsuccess: true,\n\t\t\taction: \"reply\",\n\t\t\tconversationId: payload.conversationId\n\t\t})\n\t} catch (error) {\n\t\tconsole.error(\"โŒ Error sending reply:\", error)\n\t\treturn c.json({ error: \"Failed to send reply\" }, 500)\n\t}\n})\n\napp.post(\"/react\", async (c) => {\n\tconst xmtpClient = c.get(\"xmtpClient\")\n\n\tif (!xmtpClient) {\n\t\treturn c.json({ error: \"XMTP client not initialized\" }, 500)\n\t}\n\n\tconst payload = getValidatedPayload(c)\n\tif (!payload) {\n\t\treturn c.json({ error: \"Invalid or expired token\" }, 401)\n\t}\n\n\t// Get request body data\n\tconst body = await c.req.json<SendReactionParams>()\n\n\tif (!body.emoji) {\n\t\treturn c.json({ error: \"Emoji required for react action\" }, 400)\n\t}\n\n\ttry {\n\t\tconst conversation = await xmtpClient.conversations.getConversationById(\n\t\t\tpayload.conversationId\n\t\t)\n\t\tif (!conversation) {\n\t\t\treturn c.json({ error: \"Conversation not found\" }, 404)\n\t\t}\n\n\t\tconst reaction = {\n\t\t\tschema: \"unicode\",\n\t\t\treference: body.messageId,\n\t\t\taction: body.action,\n\t\t\tcontentType: ContentTypeReaction,\n\t\t\tcontent: body.emoji\n\t\t}\n\n\t\t// For now, send the reaction content as a simple text message\n\t\t// This will send \"eyes\" as text content to indicate message was seen\n\t\tawait conversation.send(reaction, ContentTypeReaction)\n\n\t\tconsole.log(\n\t\t\t`โžก Sent reaction ${body.emoji} to message ${body.messageId} in conversation ${payload.conversationId}`\n\t\t)\n\n\t\treturn c.json({\n\t\t\tsuccess: true,\n\t\t\taction: \"react\",\n\t\t\tconversationId: payload.conversationId\n\t\t})\n\t} catch (error) {\n\t\tconsole.error(\"โŒ Error sending reaction:\", error)\n\t\treturn c.json({ error: \"Failed to send reaction\" }, 500)\n\t}\n})\n\napp.post(\"/transaction\", async (c) => {\n\tconst xmtpClient = c.get(\"xmtpClient\")\n\n\tif (!xmtpClient) {\n\t\treturn c.json({ error: \"XMTP client not initialized\" }, 500)\n\t}\n\n\tconst payload = getValidatedPayload(c)\n\tif (!payload) {\n\t\treturn c.json({ error: \"Invalid or expired token\" }, 401)\n\t}\n\n\t// Get request body data for backward compatibility\n\tlet body: any = {}\n\ttry {\n\t\tbody = await c.req.json<SendTransactionParams>()\n\t} catch (error) {\n\t\tbody = {}\n\t}\n\n\t// Transaction data can come from JWT payload (preferred) or request body (fallback)\n\tconst fromAddress = payload.fromAddress || body.fromAddress\n\tconst chainId = payload.chainId || body.chainId\n\tconst calls = payload.calls || body.calls\n\n\tif (!calls || !fromAddress || !chainId) {\n\t\treturn c.json(\n\t\t\t{ error: \"Transaction data required for transaction action\" },\n\t\t\t400\n\t\t)\n\t}\n\n\t// CRITICAL: Detect data truncation that can cause transaction failures\n\tcalls.forEach((call: any, index: number) => {\n\t\tif (call.data && typeof call.data === \"string\") {\n\t\t\tconst actualStart = call.data.substring(0, 10)\n\n\t\t\tif (actualStart === \"0x010f2e2e\") {\n\t\t\t\tconsole.error(\"๐Ÿšจ CRITICAL: Transaction data truncation detected!\")\n\t\t\t\tconsole.error(\" Function selector corrupted - transaction will fail\")\n\t\t\t\tconsole.error(\n\t\t\t\t\t\" This indicates a bug in wallet software or XMTP transmission\"\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t})\n\n\ttry {\n\t\tconst conversation = await xmtpClient.conversations.getConversationById(\n\t\t\tpayload.conversationId\n\t\t)\n\t\tif (!conversation) {\n\t\t\treturn c.json({ error: \"Conversation not found\" }, 404)\n\t\t}\n\n\t\tconst params: WalletSendCallsParams = {\n\t\t\tversion: \"1\",\n\t\t\tchainId,\n\t\t\tfrom: fromAddress,\n\t\t\tcalls\n\t\t}\n\n\t\tawait conversation.send(params, ContentTypeWalletSendCalls)\n\n\t\tconsole.log(\n\t\t\t`โœ… Sent transaction request to conversation ${payload.conversationId}`\n\t\t)\n\n\t\treturn c.json({\n\t\t\tsuccess: true,\n\t\t\taction: \"transaction\",\n\t\t\tconversationId: payload.conversationId\n\t\t})\n\t} catch (error) {\n\t\tconsole.error(\"โŒ Error sending transaction:\", error)\n\t\treturn c.json({ error: \"Failed to send transaction\" }, 500)\n\t}\n})\n\nexport default app\n","import { Context } from \"hono\"\nimport jwt from \"jsonwebtoken\"\n\nexport interface XMTPToolsPayload {\n\taction: \"send\" | \"reply\" | \"react\" | \"transaction\" | \"blockchain-event\"\n\tconversationId: string\n\t// Action-specific data\n\tcontent?: string\n\treferenceMessageId?: string\n\temoji?: string\n\tactionType?: \"added\" | \"removed\"\n\tfromAddress?: string\n\tchainId?: string\n\tcalls?: Array<{\n\t\tto: string\n\t\tdata: string\n\t\tmetadata?: {\n\t\t\tdescription: string\n\t\t\ttransactionType: string\n\t\t}\n\t}>\n\t// Metadata\n\tissued: number\n\texpires: number\n}\n\n/**\n * Validates token and returns payload for both GET and POST endpoints\n *\n * @param {Context} c - Hono context object containing request information\n * @returns {XMTPToolsPayload | null} The validated payload or null if invalid\n *\n * @description\n * Supports two authentication methods:\n * - Authorization header with Bearer token (for POST endpoints)\n * - Query parameter token (for GET endpoints)\n *\n * @example\n * ```typescript\n * app.post(\"/api/endpoint\", async (c) => {\n * const payload = getValidatedPayload(c);\n * if (!payload) {\n * return c.json({ error: \"Invalid token\" }, 401);\n * }\n * // Use payload data\n * });\n * ```\n */\nexport function getValidatedPayload(c: Context): XMTPToolsPayload | null {\n\t// Try Authorization header first (for POST endpoints)\n\tconst authHeader = c.req.header(\"Authorization\")\n\tif (authHeader?.startsWith(\"Bearer \")) {\n\t\tconst token = authHeader.substring(7) // Remove \"Bearer \" prefix\n\t\treturn validateXMTPToolsToken(token)\n\t}\n\n\t// Fall back to query parameter (for GET endpoints)\n\tconst token = c.req.query(\"token\")\n\tif (!token) {\n\t\treturn null\n\t}\n\n\treturn validateXMTPToolsToken(token)\n}\n\n/**\n * JWT secret key used for signing and verifying tokens\n * Uses XMTP_ENCRYPTION_KEY environment variable for consistency\n * Only falls back to development secret in development/test environments\n */\nconst JWT_SECRET = (() => {\n\tconst secret = process.env.XMTP_ENCRYPTION_KEY\n\tconst nodeEnv = process.env.NODE_ENV || \"development\"\n\n\t// In production, require a real JWT secret\n\tif (nodeEnv === \"production\" && !secret) {\n\t\tthrow new Error(\n\t\t\t\"XMTP_ENCRYPTION_KEY environment variable is required in production. \" +\n\t\t\t\t\"Generate a secure random secret for JWT token signing.\"\n\t\t)\n\t}\n\n\t// In development/test, allow fallback but warn\n\tif (!secret) {\n\t\tconsole.warn(\n\t\t\t\"โš ๏ธ [SECURITY] Using fallback JWT secret for development. \" +\n\t\t\t\t\"Set XMTP_ENCRYPTION_KEY environment variable for production.\"\n\t\t)\n\t\treturn \"fallback-secret-for-dev-only\"\n\t}\n\n\treturn secret\n})()\n\n/**\n * API key used for simple authentication bypass\n * Requires XMTP_API_KEY environment variable in production\n * Only falls back to development key in development/test environments\n */\nconst API_KEY = (() => {\n\tconst apiKey = process.env.XMTP_API_KEY\n\tconst nodeEnv = process.env.NODE_ENV || \"development\"\n\n\t// In production, require a real API key\n\tif (nodeEnv === \"production\" && !apiKey) {\n\t\tthrow new Error(\n\t\t\t\"XMTP_API_KEY environment variable is required in production. \" +\n\t\t\t\t\"Generate a secure random API key for authentication.\"\n\t\t)\n\t}\n\n\t// In development/test, allow fallback but warn\n\tif (!apiKey) {\n\t\tconsole.warn(\n\t\t\t\"โš ๏ธ [SECURITY] Using fallback API key for development. \" +\n\t\t\t\t\"Set XMTP_API_KEY environment variable for production.\"\n\t\t)\n\t\treturn \"fallback-api-key-for-dev-only\"\n\t}\n\n\treturn apiKey\n})()\n\n/**\n * JWT token expiry time in seconds (5 minutes)\n */\nconst JWT_EXPIRY = 5 * 60 // 5 minutes in seconds\n\n/**\n * Generates a signed JWT token for XMTP tools authentication\n *\n * @param {Omit<XMTPToolsPayload, \"issued\" | \"expires\">} payload - Token payload without timestamp fields\n * @returns {string} Signed JWT token\n *\n * @description\n * Creates a JWT token with automatic timestamp fields:\n * - issued: Current timestamp\n * - expires: Current timestamp + JWT_EXPIRY\n *\n * @example\n * ```typescript\n * const token = generateXMTPToolsToken({\n * action: \"send\",\n * conversationId: \"0x123...\"\n * });\n * ```\n */\nexport function generateXMTPToolsToken(\n\tpayload: Omit<XMTPToolsPayload, \"issued\" | \"expires\">\n): string {\n\tconst now = Math.floor(Date.now() / 1000)\n\tconst fullPayload: XMTPToolsPayload = {\n\t\t...payload,\n\t\tissued: now,\n\t\texpires: now + JWT_EXPIRY\n\t}\n\n\treturn jwt.sign(fullPayload, JWT_SECRET, {\n\t\texpiresIn: JWT_EXPIRY\n\t})\n}\n\n/**\n * Validates an XMTP tools token using either API key or JWT verification\n *\n * @param {string} token - Token to validate (either API key or JWT)\n * @returns {XMTPToolsPayload | null} Validated payload or null if invalid\n *\n * @description\n * Supports two authentication methods in order of precedence:\n * 1. API key authentication - Direct comparison with XMTP_API_KEY\n * 2. JWT token authentication - Signature verification and expiry check\n *\n * For API key authentication, returns a default payload with 1-hour expiry.\n * For JWT authentication, validates signature and checks expiry timestamp.\n *\n * @example\n * ```typescript\n * const payload = validateXMTPToolsToken(userToken);\n * if (payload) {\n * console.log(`Action: ${payload.action}`);\n * console.log(`Conversation: ${payload.conversationId}`);\n * }\n * ```\n */\nexport function validateXMTPToolsToken(token: string): XMTPToolsPayload | null {\n\t// First try API key authentication\n\tif (token === API_KEY) {\n\t\tconsole.log(\"๐Ÿ”‘ [Auth] Using API key authentication\")\n\t\t// Return a valid payload for API key auth\n\t\tconst now = Math.floor(Date.now() / 1000)\n\t\treturn {\n\t\t\taction: \"send\", // Default action\n\t\t\tconversationId: \"\", // Will be filled by endpoint\n\t\t\tissued: now,\n\t\t\texpires: now + 3600 // API keys are valid for 1 hour\n\t\t}\n\t}\n\n\t// Then try JWT token authentication\n\ttry {\n\t\tconst decoded = jwt.verify(token, JWT_SECRET) as XMTPToolsPayload\n\t\tconsole.log(\"๐Ÿ”‘ [Auth] Using JWT token authentication\")\n\n\t\t// Additional expiry check\n\t\tconst now = Math.floor(Date.now() / 1000)\n\t\tif (decoded.expires < now) {\n\t\t\tconsole.warn(\"๐Ÿ”’ XMTP tools token has expired\")\n\t\t\treturn null\n\t\t}\n\n\t\treturn decoded\n\t} catch (error) {\n\t\tconsole.error(\n\t\t\t\"๐Ÿ”’ Invalid XMTP tools token and not matching API key:\",\n\t\t\terror\n\t\t)\n\t\treturn null\n\t}\n}\n","import { Hono } from \"hono\"\nimport xmtpEndpoints from \"./endpoints\"\nimport type { MessageListenerConfig } from \"./lib/message-listener\"\nimport type { HonoVariables } from \"./types\"\n\nexport interface Plugin<TContext = unknown> {\n\tname: string\n\tdescription?: string\n\tapply: (\n\t\tapp: Hono<{ Variables: HonoVariables }>,\n\t\tcontext?: TContext\n\t) => void | Promise<void>\n}\n\nexport interface XMTPPluginContext {\n\tagent: unknown\n}\n\n/**\n * XMTP Plugin that provides XMTP functionality to the agent\n *\n * @description\n * This plugin integrates XMTP messaging capabilities into the agent's\n * HTTP server. It mounts the XMTP endpoints for handling XMTP tools requests.\n */\nexport function XMTPPlugin({\n\tfilter\n}: {\n\tfilter?: MessageListenerConfig[\"filter\"]\n} = {}): Plugin<XMTPPluginContext> {\n\treturn {\n\t\tname: \"xmtp\",\n\t\tdescription: \"Provides XMTP messaging functionality\",\n\t\tapply: (app, context) => {\n\t\t\t// Mount the XMTP endpoints at /xmtp-tools\n\t\t\tapp.route(\"/xmtp-tools\", xmtpEndpoints)\n\t\t}\n\t}\n}\n","// ===================================================================\n// XMTP Package - Main Entry Point\n// ===================================================================\n// This package provides a clean interface to XMTP functionality\n// Re-exports core XMTP SDK types and utilities\n\nexport * from \"./client\"\nexport * from \"./constants\"\nexport * from \"./lib/message-listener\"\nexport * from \"./lib/subjects\"\nexport * from \"./resolver\"\nexport * from \"./resolver/basename-resolver\"\nexport * from \"./resolver/ens-resolver\"\nexport * from \"./resolver/xmtp-resolver\"\nexport * from \"./service-client\"\nexport * from \"./types\"\n\n// ===================================================================\n// XMTP Plugin for Agent Integration\n// ===================================================================\nexport { XMTPPlugin } from \"./plugin\"\nexport type { Plugin, XMTPPluginContext } from \"./plugin\"\n\n// ===================================================================\n// JWT Utilities for XMTP Tools\n// ===================================================================\nexport { generateXMTPToolsToken } from \"./lib/jwt\"\nexport type { XMTPToolsPayload } from \"./lib/jwt\"\n\n// ===================================================================\n// Enhanced XMTP Client & Connection Management\n// ===================================================================\nexport {\n\t// Enhanced connection management\n\tXMTPConnectionManager,\n\tcreateXMTPConnectionManager,\n\ttype XMTPConnectionConfig,\n\ttype XMTPConnectionHealth\n} from \"./client\"\n\n// ===================================================================\n// XMTP Service Client (for external service communication)\n// ===================================================================\nexport {\n\tXmtpServiceClient,\n\tcreateXmtpServiceClient\n} from \"./service-client\"\n\n// Service Client Types\nexport type {\n\tGetMessageParams,\n\tGetRootMessageParams,\n\t// Function parameter types\n\tSendMessageParams,\n\t// Response types\n\tSendMessageResponse,\n\tSendReactionParams,\n\tSendReactionResponse,\n\tSendReplyParams,\n\tSendReplyResponse,\n\tSendTransactionParams,\n\tSendTransactionResponse,\n\tTransactionCall,\n\tTransactionRequest,\n\tXmtpRootMessageResponse,\n\tXmtpServiceClientConfig,\n\tXmtpServiceMessage,\n\tXmtpServiceResponse\n} from \"./types\"\n\n// ===================================================================\n// XMTP Core SDK Exports\n// ===================================================================\nexport {\n\tClient,\n\tIdentifierKind,\n\t// type Conversation,\n\ttype DecodedMessage,\n\ttype Dm,\n\t// type Group,\n\ttype LogLevel,\n\ttype Signer,\n\ttype XmtpEnv\n} from \"@xmtp/node-sdk\"\n\n// ===================================================================\n// XMTP Content Types\n// ===================================================================\nexport {\n\tContentTypeTransactionReference,\n\ttype TransactionReference\n} from \"@xmtp/content-type-transaction-reference\"\n\nexport { ContentTypeText, type TextParameters } from \"@xmtp/content-type-text\"\n\nexport {\n\tContentTypeReaction,\n\ttype Reaction\n} from \"@xmtp/content-type-reaction\"\n\nexport {\n\tContentTypeReply,\n\tReplyCodec,\n\ttype Reply\n} from \"@xmtp/content-type-reply\"\n\nexport {\n\tContentTypeGroupUpdated,\n\tGroupUpdatedCodec,\n\ttype GroupUpdated\n} from \"@xmtp/content-type-group-updated\"\n\nexport {\n\tContentTypeWalletSendCalls,\n\ttype WalletSendCallsParams\n} from \"@xmtp/content-type-wallet-send-calls\"\n\n// ===================================================================\n// Local Client Utilities\n// ===================================================================\nexport {\n\tbackupDbToPersistentStorage,\n\tcreateSigner,\n\tcreateUser,\n\tcreateXMTPClient,\n\tdiagnoseXMTPIdentityIssue,\n\tgenerateEncryptionKeyHex,\n\tgetEncryptionKeyFromHex,\n\tlogAgentDetails,\n\tstartPeriodicBackup,\n\tvalidateEnvironment\n} from \"./client\"\n\n// ===================================================================\n// Application Constants\n// ===================================================================\nexport {\n\tDEFAULT_AMOUNT,\n\tDEFAULT_OPTIONS,\n\tMAX_USDC_AMOUNT\n} from \"./constants\"\n"],"mappings":"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","names":["Client","Client","identifier","address","http","mainnet","mainnet","http","token","app","IdentifierKind","ContentTypeText","ContentTypeReaction","ContentTypeReply","ReplyCodec","ContentTypeWalletSendCalls"]}