{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/client.ts","../scripts/revoke-installations.ts","../src/lib/secret.ts","../src/plugin.ts","../src/lib/jwt.ts"],"sourcesContent":["export {\n\tAgent,\n\tcreateSigner,\n\tcreateUser,\n\tfilter,\n\tgetTestUrl\n} from \"@xmtp/agent-sdk\"\n\nexport type * from \"./types\"\n\nexport {\n\tDEFAULT_AMOUNT,\n\tDEFAULT_OPTIONS,\n\tMAX_USDC_AMOUNT\n} from \"./constants\"\n// NodeNext/Node16 requires explicit extensions for relative imports\n// NodeNext/Node16 requires explicit extensions for relative imports\n\n// ===================================================================\n// XMTP Client and Connection Management\n// ===================================================================\nexport {\n\tcreateXMTPClient,\n\tcreateSigner as createXMTPSigner,\n\tgetDbPath,\n\tlogAgentDetails,\n\tvalidateEnvironment,\n\tXMTPConnectionManager,\n\tderiveAgentSecret,\n\tresolveAgentSecret\n} from \"./client\"\nexport type { XMTPConnectionConfig } from \"./client\"\n\n// ===================================================================\n// XMTP Plugin for Agent Integration\n// ===================================================================\nexport { XMTPPlugin } from \"./plugin\"\nexport type { Plugin } 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// 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// 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 { getRandomValues } from \"node:crypto\"\nimport fs from \"node:fs\"\nimport path from \"node:path\"\nimport { logger } from \"@hybrd/utils\"\nimport { 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 { fromString, toString as uint8arraysToString } from \"uint8arrays\"\nimport { http, createWalletClient, toBytes } from \"viem\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { sepolia } from \"viem/chains\"\nimport { revokeOldInstallations } from \"../scripts/revoke-installations\"\nimport { resolveAgentSecret } from \"./lib/secret.js\"\nimport { XmtpClient } from \"./types\"\n\nexport { deriveAgentSecret, resolveAgentSecret } from \"./lib/secret.js\"\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\tlogger.debug(\"🧹 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// Default to .hybrid/.xmtp in current working directory\n\t\treturn path.join(process.cwd(), \".hybrid\", \".xmtp\")\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\t// Monorepo root fallback\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\tlogger.debug(`✅ Removed: ${fullPath}`)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tlogger.debug(`⚠️ 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\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 AGENT_WALLET_KEY environment variable is not set\"\n\t\t)\n\t}\n\n\tconst { XMTP_ENV } = process.env\n\tconst agentSecret = resolveAgentSecret(privateKey)\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\tlogger.debug(\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\tconst dbEncryptionKey = getEncryptionKeyFromHex(agentSecret)\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\tlogger.debug(`📁 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\tlogger.debug(\"📡 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(`Wallet: ${address}`)\n\t\t\tconsole.log(`Env: ${XMTP_ENV || \"dev\"}`)\n\t\t\tconsole.log(`Storage: persistent`)\n\n\t\t\treturn client as unknown as XmtpClient\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\t(error.message.includes(\"installations\") ||\n\t\t\t\t\terror.message.match(/\\d+\\/\\d+\\s+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 = getEncryptionKeyFromHex(agentSecret)\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 */\nconst 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// Default to .hybrid/.xmtp in current working directory\n\t\tvolumePath = path.join(process.cwd(), \".hybrid\", \".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\nconst 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 (internal use only)\n */\nasync 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","import { Client, type Signer } from \"@xmtp/node-sdk\"\nimport { createSigner } from \"../src/client\"\n\n// Function to revoke old installations when hitting the limit\nexport async function revokeOldInstallations(signer: Signer, inboxId?: string) {\n\tconsole.log(\"🔧 Attempting to revoke old installations...\")\n\n\ttry {\n\t\t// If we don't have the inboxId, we need to extract it from a temporary client attempt\n\t\tif (!inboxId) {\n\t\t\tconsole.log(\"ℹ️ No inboxId provided, cannot revoke installations\")\n\t\t\treturn false\n\t\t}\n\n\t\tconst inboxStates = await Client.inboxStateFromInboxIds(\n\t\t\t[inboxId],\n\t\t\tprocess.env.XMTP_ENV as \"dev\" | \"production\"\n\t\t)\n\n\t\tif (!inboxStates[0]) {\n\t\t\tconsole.log(\"❌ No inbox state found for the provided inboxId\")\n\t\t\treturn false\n\t\t}\n\n\t\tconst toRevokeInstallationBytes = inboxStates[0].installations.map(\n\t\t\t(i: { bytes: Uint8Array }) => i.bytes\n\t\t)\n\n\t\tawait Client.revokeInstallations(\n\t\t\tsigner,\n\t\t\tinboxId,\n\t\t\ttoRevokeInstallationBytes,\n\t\t\tprocess.env.XMTP_ENV as \"dev\" | \"production\"\n\t\t)\n\n\t\tconst resultingStates = await Client.inboxStateFromInboxIds(\n\t\t\t[inboxId],\n\t\t\tprocess.env.XMTP_ENV as \"dev\" | \"production\"\n\t\t)\n\n\t\tconsole.log(\n\t\t\t`📋 Revoked installations: ${toRevokeInstallationBytes.length} installations`\n\t\t)\n\t\tconsole.log(\n\t\t\t`📋 Resulting state: ${resultingStates[0]?.installations.length || 0} installations`\n\t\t)\n\n\t\treturn true\n\t} catch (error) {\n\t\tconsole.error(\"❌ Error during installation revocation:\", error)\n\t\treturn false\n\t}\n}\n\n// CLI script to revoke installations\nasync function main() {\n\tconst { AGENT_WALLET_KEY } = process.env\n\tconst inboxId = process.argv[2]\n\n\tif (!AGENT_WALLET_KEY) {\n\t\tconsole.error(\"❌ AGENT_WALLET_KEY is required\")\n\t\tprocess.exit(1)\n\t}\n\n\tif (!inboxId) {\n\t\tconsole.error(\"❌ InboxID is required as CLI argument\")\n\t\tconsole.error(\"Usage: tsx revoke-installations.ts <inboxId>\")\n\t\tprocess.exit(1)\n\t}\n\n\tconst signer = createSigner(AGENT_WALLET_KEY)\n\tconst identifier = await signer.getIdentifier()\n\tconst address = identifier.identifier\n\n\tconsole.log(`🔑 Wallet Address: ${address}`)\n\tconsole.log(`📋 Inbox ID: ${inboxId}`)\n\n\t// Try to revoke installations\n\tconst success = await revokeOldInstallations(signer, inboxId)\n\n\tif (success) {\n\t\tconsole.log(\"✅ Successfully revoked installations\")\n\t} else {\n\t\tconsole.log(\"❌ Failed to revoke installations\")\n\t\tprocess.exit(1)\n\t}\n}\n\n// Run if called directly (ESM only)\ntry {\n\tif (import.meta.url === `file://${process.argv[1]}`) {\n\t\tmain().catch((error) => {\n\t\t\tconsole.error(\"💥 Fatal error:\", error)\n\t\t\tprocess.exit(1)\n\t\t})\n\t}\n} catch {\n\t// import.meta not available in CJS - script not run directly\n}\n","import { toBytes } from \"viem\"\nimport { HDKey } from \"viem/accounts\"\n\n/**\n * Derives a deterministic 32-byte secret from an agent wallet private key.\n *\n * Uses BIP-32 HD key derivation at path m/44'/60'/0'/0/41 (coin type 60 = ETH,\n * index 41 is arbitrary but fixed — chosen to avoid collision with standard\n * account derivation paths). The child private key is used directly as the\n * 32-byte secret, returned as a 64-character hex string.\n */\nexport function deriveAgentSecret(walletKey: string): string {\n\tconst keyBytes = toBytes(walletKey as `0x${string}`)\n\tconst hdKey = HDKey.fromMasterSeed(keyBytes)\n\tconst child = hdKey.derive(\"m/44'/60'/0'/0/41\")\n\tif (!child.privateKey) {\n\t\tthrow new Error(\"Failed to derive child key from wallet key\")\n\t}\n\treturn Buffer.from(child.privateKey).toString(\"hex\")\n}\n\n/**\n * Resolves the database encryption secret by deriving it from the provided wallet key.\n *\n * The wallet key must be passed explicitly — this function does not\n * read from environment variables or external stores.\n */\nexport function resolveAgentSecret(walletKey: string): string {\n\tif (!walletKey) {\n\t\tthrow new Error(\"walletKey is required to derive the encryption secret\")\n\t}\n\treturn deriveAgentSecret(walletKey)\n}\n","import {\n\tAgent as XmtpAgent,\n\tXmtpEnv,\n\tcreateSigner,\n\tcreateUser\n} from \"@xmtp/agent-sdk\"\n\nimport { randomUUID } from \"node:crypto\"\nimport type {\n\tAgentMessage,\n\tAgentRuntime,\n\tBehaviorContext,\n\tBehaviorRegistry,\n\tPlugin,\n\tPluginContext,\n\tXmtpClient,\n\tXmtpConversation,\n\tXmtpMessage\n} from \"@hybrd/types\"\nimport { logger } from \"@hybrd/utils\"\nimport { createXMTPClient, getDbPath } from \"./client\"\nimport { ContentTypeReply, ContentTypeText, type Reply } from \"./index\"\n\n// Re-export types from @hybrd/types for backward compatibility\nexport type { Plugin }\n\n/**\n * Send a response with threading support\n */\nasync function sendResponse(\n\tconversation: XmtpConversation,\n\ttext: string,\n\toriginalMessageId: string,\n\tbehaviorContext?: BehaviorContext\n) {\n\tconst shouldThread = behaviorContext?.sendOptions?.threaded ?? false\n\n\tif (shouldThread) {\n\t\t// Send as a reply to the original message\n\t\ttry {\n\t\t\tconst reply: Reply = {\n\t\t\t\treference: originalMessageId,\n\t\t\t\tcontentType: ContentTypeText,\n\t\t\t\tcontent: text\n\t\t\t}\n\t\t\tawait conversation.send(reply, ContentTypeReply)\n\t\t\tlogger.debug(\n\t\t\t\t`✅ [sendResponse] Threaded reply sent successfully to message ${originalMessageId}`\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tlogger.error(\n\t\t\t\t`❌ [sendResponse] Failed to send threaded reply to message ${originalMessageId}:`,\n\t\t\t\terror\n\t\t\t)\n\t\t\t// Fall back to regular message if threaded reply fails\n\t\t\tlogger.debug(`🔄 [sendResponse] Falling back to regular message`)\n\t\t\tawait conversation.send(text)\n\t\t}\n\t} else {\n\t\t// Send as a regular message\n\t\tawait conversation.send(text)\n\t}\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(): Plugin<PluginContext> {\n\treturn {\n\t\tname: \"xmtp\",\n\t\tdescription: \"Provides XMTP messaging functionality\",\n\t\tapply: async (app, context): Promise<void> => {\n\t\t\tconst { AGENT_WALLET_KEY, XMTP_ENV = \"production\" } = process.env\n\n\t\t\tconst { agent } = context\n\t\t\tconst pluginContext = context as PluginContext & {\n\t\t\t\tbehaviors?: BehaviorRegistry\n\t\t\t}\n\n\t\t\tif (!AGENT_WALLET_KEY) {\n\t\t\t\tthrow new Error(\"AGENT_WALLET_KEY must be set\")\n\t\t\t}\n\n\t\t\tconst user = createUser(AGENT_WALLET_KEY as `0x${string}`)\n\t\t\tconst signer = createSigner(user)\n\n\t\t\tconst xmtpClient = await createXMTPClient(\n\t\t\t\tAGENT_WALLET_KEY as `0x${string}`\n\t\t\t)\n\n\t\t\tconst address = user.account.address.toLowerCase()\n\t\t\tconst agentDbPath = await getDbPath(\n\t\t\t\t`agent-${XMTP_ENV || \"dev\"}-${address}`\n\t\t\t)\n\t\t\tlogger.debug(`📁 Using database path: ${agentDbPath}`)\n\n\t\t\tconst xmtp = (await XmtpAgent.create(signer, {\n\t\t\t\tenv: XMTP_ENV as XmtpEnv,\n\t\t\t\tdbPath: agentDbPath\n\t\t\t})) as any\n\n\t\t\tconst botInboxId = xmtp.client?.inboxId\n\t\t\tconst MAX_HISTORY = 20\n\n\t\t\txmtp.on(\"reaction\", async ({ conversation, message }: any) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst text = message.content.content\n\t\t\t\t\tconst messages: AgentMessage[] = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: randomUUID(),\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tparts: [{ type: \"text\", text }]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\n\t\t\t\t\tconst baseRuntime: AgentRuntime = {\n\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\txmtpClient,\n\t\t\t\t\t\t...(context.scheduler ? { scheduler: context.scheduler } : {})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst runtime = await agent.createRuntimeContext(baseRuntime)\n\n\t\t\t\t\t// Execute pre-response behaviors\n\t\t\t\t\tlet behaviorContext: BehaviorContext | undefined\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeBefore(behaviorContext)\n\n\t\t\t\t\t\t// Check if behaviors were stopped early (e.g., due to filtering)\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping reaction response due to behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if message was filtered out by filterMessages behavior\n\t\t\t\t\t\tif (behaviorContext.sendOptions?.filtered) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping reaction response due to message being filtered`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { text: reply } = await agent.generate(messages, { runtime })\n\n\t\t\t\t\t// Execute post-response behaviors\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tif (behaviorContext) {\n\t\t\t\t\t\t\tbehaviorContext.response = reply\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeAfter(behaviorContext)\n\n\t\t\t\t\t\t// Check if post behaviors were stopped early\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping reaction response due to post-behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Create minimal context for send options\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tawait sendResponse(\n\t\t\t\t\t\tconversation as unknown as XmtpConversation,\n\t\t\t\t\t\treply,\n\t\t\t\t\t\tmessage.id,\n\t\t\t\t\t\tbehaviorContext\n\t\t\t\t\t)\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.error(\"❌ Error handling reaction:\", err)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txmtp.on(\"reply\", async ({ conversation, message }: any) => {\n\t\t\t\ttry {\n\t\t\t\t\t// TODO - why isn't this typed better?\n\t\t\t\t\tconst text = message.content.content as string\n\t\t\t\t\tconst messages: AgentMessage[] = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: randomUUID(),\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tparts: [{ type: \"text\", text }]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\n\t\t\t\t\tconst baseRuntime: AgentRuntime = {\n\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\txmtpClient,\n\t\t\t\t\t\t...(context.scheduler ? { scheduler: context.scheduler } : {})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst runtime = await agent.createRuntimeContext(baseRuntime)\n\n\t\t\t\t\t// Execute pre-response behaviors\n\t\t\t\t\tlet behaviorContext: BehaviorContext | undefined\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeBefore(behaviorContext)\n\n\t\t\t\t\t\t// Check if behaviors were stopped early (e.g., due to filtering)\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping reply response due to behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { text: reply } = await agent.generate(messages, { runtime })\n\n\t\t\t\t\t// Execute post-response behaviors\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tif (!behaviorContext) {\n\t\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbehaviorContext.response = reply\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeAfter(behaviorContext)\n\n\t\t\t\t\t\t// Check if post behaviors were stopped early\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping reply response due to post-behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Create minimal context for send options\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tawait sendResponse(\n\t\t\t\t\t\tconversation as unknown as XmtpConversation,\n\t\t\t\t\t\treply,\n\t\t\t\t\t\tmessage.id,\n\t\t\t\t\t\tbehaviorContext\n\t\t\t\t\t)\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.error(\"❌ Error handling reply:\", err)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txmtp.on(\"text\", async ({ conversation, message }: any) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst text = message.content\n\n\t\t\t\t\tlet historyMessages: AgentMessage[] = []\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconsole.log(\"[xmtp] fetching conversation history...\")\n\t\t\t\t\t\tconst history = await conversation.messages({\n\t\t\t\t\t\t\tlimit: MAX_HISTORY + 1,\n\t\t\t\t\t\t\tdirection: 1\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`[xmtp] got ${history.length} messages from conversation.messages()`\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tconst filtered = history\n\t\t\t\t\t\t\t.filter((msg: any) => msg.id !== message.id)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(msg: any) => msg.content && typeof msg.content === \"string\"\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.slice(0, MAX_HISTORY)\n\t\t\t\t\t\t\t.reverse()\n\n\t\t\t\t\t\tconsole.log(`[xmtp] after filter: ${filtered.length} messages`)\n\n\t\t\t\t\t\thistoryMessages = filtered.map((msg: any) => ({\n\t\t\t\t\t\t\tid: msg.id,\n\t\t\t\t\t\t\trole:\n\t\t\t\t\t\t\t\tmsg.senderInboxId === botInboxId\n\t\t\t\t\t\t\t\t\t? (\"assistant\" as const)\n\t\t\t\t\t\t\t\t\t: (\"user\" as const),\n\t\t\t\t\t\t\tparts: [{ type: \"text\" as const, text: msg.content as string }]\n\t\t\t\t\t\t}))\n\t\t\t\t\t} catch (historyErr) {\n\t\t\t\t\t\tconsole.error(`[xmtp] history error:`, historyErr)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst messages: AgentMessage[] = [\n\t\t\t\t\t\t...historyMessages,\n\t\t\t\t\t\t{ id: randomUUID(), role: \"user\", parts: [{ type: \"text\", text }] }\n\t\t\t\t\t]\n\n\t\t\t\t\tconsole.log(`[xmtp] sending ${messages.length} messages to agent`)\n\n\t\t\t\t\tconst baseRuntime: AgentRuntime = {\n\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\txmtpClient,\n\t\t\t\t\t\t...(context.scheduler ? { scheduler: context.scheduler } : {})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst runtime = await agent.createRuntimeContext(baseRuntime)\n\n\t\t\t\t\t// Execute pre-response behaviors\n\t\t\t\t\tlet behaviorContext: BehaviorContext | undefined\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeBefore(behaviorContext)\n\n\t\t\t\t\t\t// Check if behaviors were stopped early (e.g., due to filtering)\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping text response due to behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { text: reply } = await agent.generate(messages, { runtime })\n\n\t\t\t\t\t// Execute post-response behaviors\n\t\t\t\t\tif (context.behaviors) {\n\t\t\t\t\t\tif (!behaviorContext) {\n\t\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbehaviorContext.response = reply\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait context.behaviors.executeAfter(behaviorContext)\n\n\t\t\t\t\t\t// Check if post behaviors were stopped early\n\t\t\t\t\t\tif (behaviorContext.stopped) {\n\t\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t\t`🔇 [XMTP Plugin] Skipping text response due to post-behavior chain being stopped`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Create minimal context for send options\n\t\t\t\t\t\tbehaviorContext = {\n\t\t\t\t\t\t\truntime,\n\t\t\t\t\t\t\tclient: xmtpClient as unknown as XmtpClient,\n\t\t\t\t\t\t\tconversation: conversation as unknown as XmtpConversation,\n\t\t\t\t\t\t\tmessage: message as unknown as XmtpMessage,\n\t\t\t\t\t\t\tresponse: reply\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tawait sendResponse(\n\t\t\t\t\t\tconversation as unknown as XmtpConversation,\n\t\t\t\t\t\treply,\n\t\t\t\t\t\tmessage.id,\n\t\t\t\t\t\tbehaviorContext\n\t\t\t\t\t)\n\t\t\t\t} catch (err) {\n\t\t\t\t\tlogger.error(\"❌ Error handling text:\", err)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// Store xmtpClient in context for scheduler and other components\n\t\t\t;(context as any).xmtpClient = xmtpClient\n\n\t\t\t// Event handlers removed due to incompatibility with current XMTP agent SDK\n\n\t\t\tvoid xmtp\n\t\t\t\t.start()\n\t\t\t\t.then(() => logger.debug(\"✅ XMTP agent listener started\"))\n\t\t\t\t.catch((err: any) =>\n\t\t\t\t\tconsole.error(\"❌ XMTP agent listener failed to start:\", err)\n\t\t\t\t)\n\t\t}\n\t}\n}\n","import { logger } from \"@hybrd/utils\"\nimport { Context } from \"hono\"\nimport jwt from \"jsonwebtoken\"\nimport { resolveAgentSecret } from \"./secret.js\"\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 * Gets the JWT secret for token signing, with lazy initialization\n * Derives secret from AGENT_WALLET_KEY using BIP-32\n * Only falls back to development secret in development/test environments\n */\nfunction getJwtSecret(): string {\n\tconst walletKey = process.env.AGENT_WALLET_KEY\n\tif (walletKey) {\n\t\treturn resolveAgentSecret(walletKey)\n\t}\n\n\tconst nodeEnv = process.env.NODE_ENV || \"development\"\n\tif (nodeEnv === \"production\") {\n\t\tthrow new Error(\n\t\t\t\"AGENT_WALLET_KEY must be set in production for JWT token signing.\"\n\t\t)\n\t}\n\tlogger.warn(\n\t\t\"⚠️  [SECURITY] Using fallback JWT secret for development. \" +\n\t\t\t\"Set AGENT_WALLET_KEY for production.\"\n\t)\n\treturn \"fallback-secret-for-dev-only\"\n}\n\n/**\n * Gets the API key for authentication, with lazy initialization\n * Requires XMTP_API_KEY environment variable in production\n * Only falls back to development key in development/test environments\n */\nfunction getApiKey(): string {\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 only when actually used\n\tif (!apiKey) {\n\t\tlogger.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 startTime = performance.now()\n\tlogger.debug(\"🔐 [JWT] Starting token generation...\")\n\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\tconst token = jwt.sign(fullPayload, getJwtSecret(), {\n\t\texpiresIn: JWT_EXPIRY\n\t})\n\n\tconst endTime = performance.now()\n\tlogger.debug(\n\t\t`🔐 [JWT] Token generation completed in ${(endTime - startTime).toFixed(2)}ms`\n\t)\n\n\treturn token\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\tconst startTime = performance.now()\n\tlogger.debug(\"🔐 [JWT] Starting token validation...\")\n\n\t// First try API key authentication\n\tif (token === getApiKey()) {\n\t\tlogger.debug(\"🔑 [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\tconst result = {\n\t\t\taction: \"send\" as const, // 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\n\t\tconst endTime = performance.now()\n\t\tlogger.debug(\n\t\t\t`🔐 [JWT] API key validation completed in ${(endTime - startTime).toFixed(2)}ms`\n\t\t)\n\t\treturn result\n\t}\n\n\t// Then try JWT token authentication\n\ttry {\n\t\tconst decoded = jwt.verify(token, getJwtSecret()) as XMTPToolsPayload\n\t\tlogger.debug(\"🔑 [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.log(\"🔒 XMTP tools token has expired\")\n\t\t\tconst endTime = performance.now()\n\t\t\tlogger.debug(\n\t\t\t\t`🔐 [JWT] Token validation failed (expired) in ${(endTime - startTime).toFixed(2)}ms`\n\t\t\t)\n\t\t\treturn null\n\t\t}\n\n\t\tconst endTime = performance.now()\n\t\tlogger.debug(\n\t\t\t`🔐 [JWT] JWT validation completed in ${(endTime - startTime).toFixed(2)}ms`\n\t\t)\n\t\treturn decoded\n\t} catch (error) {\n\t\tlogger.error(\"🔒 Invalid XMTP tools token and not matching API key:\", error)\n\t\tconst endTime = performance.now()\n\t\tlogger.debug(\n\t\t\t`🔐 [JWT] Token validation failed in ${(endTime - startTime).toFixed(2)}ms`\n\t\t)\n\t\treturn null\n\t}\n}\n"],"mappings":"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","names":["import_agent_sdk","import_node_sdk","import_viem","import_accounts","path","fs","identifier","address","path","fs","import_node_crypto","import_utils","XmtpAgent","import_utils","jwt","import_node_sdk","import_content_type_transaction_reference","import_content_type_reaction","import_content_type_reply","import_content_type_wallet_send_calls"]}