{"version":3,"file":"watch-activity.mjs","names":[],"sources":["../../../src/tools/watch-activity.ts"],"sourcesContent":["/**\n * Watch Activity Tool — on-chain monitoring via ClawnchWatcher\n *\n * Monitors swaps, transfers, whale activity, and new token deployments\n * on Base. Read-only — no wallet required.\n *\n * Uses ClawnchWatcher from @clawnch/clawncher-sdk.\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport { requirePublicClient } from '../services/walletconnect-service.js';\n\nconst ACTIONS = [\n  'token_activity', 'recent_swaps', 'recent_transfers', 'deployments',\n] as const;\n\nconst WatchActivitySchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'token_activity: full activity report (swaps + transfers + stats). ' +\n      'recent_swaps: recent swaps for a pool. recent_transfers: token transfers. ' +\n      'deployments: recent Clawnch token deployments.',\n  }),\n  token: Type.Optional(Type.String({\n    description: 'Token contract address to monitor',\n  })),\n  pool_id: Type.Optional(Type.String({\n    description: 'Pool ID (bytes32) for swap monitoring. Auto-derived from token if omitted.',\n  })),\n  blocks: Type.Optional(Type.Number({\n    description: 'Number of blocks to look back (default: 5000, ~3 hours on Base)',\n  })),\n  limit: Type.Optional(Type.Number({\n    description: 'Max results to return (default: 50)',\n  })),\n  admin: Type.Optional(Type.String({\n    description: 'Filter deployments by token admin address',\n  })),\n});\n\nexport function createWatchActivityTool() {\n  return {\n    name: 'watch_activity',\n    label: 'Watch Activity',\n    ownerOnly: false,\n    description:\n      'Monitor on-chain activity: token swaps, transfers, whale alerts, and new deployments. ' +\n      'Read-only — no wallet connection needed, only a public RPC client. ' +\n      'Tracks activity on Base mainnet.',\n    parameters: WatchActivitySchema,\n    execute: async (_toolCallId: string, args: unknown) => {\n      const p = args as Record<string, unknown>;\n      const action = readStringParam(p, 'action', { required: true })!;\n\n      try {\n        const publicClient = requirePublicClient();\n        const { ClawnchWatcher } = await import('@clawnch/clawncher-sdk');\n\n        const network = (process.env.CLAWNCHER_NETWORK as 'mainnet' | 'sepolia') || 'mainnet';\n        const watcher = new ClawnchWatcher({\n          publicClient,\n          network,\n        });\n\n        const blocks = readNumberParam(p, 'blocks') ?? 5000;\n        const currentBlock = await publicClient.getBlockNumber();\n        const fromBlock = currentBlock - BigInt(blocks);\n\n        switch (action) {\n          case 'token_activity': {\n            const token = readStringParam(p, 'token', { required: true })! as `0x${string}`;\n            const poolId = readStringParam(p, 'pool_id');\n\n            if (!poolId) {\n              // Try to get pool ID from ClawnchReader\n              try {\n                const { ClawnchReader } = await import('@clawnch/clawncher-sdk');\n                const reader = new ClawnchReader({ publicClient, network });\n                const rewards = await reader.getTokenRewards(token);\n                const derivedPoolId = (rewards as any)?.poolId ?? (rewards as any)?.pool_id;\n\n                if (derivedPoolId) {\n                  const activity = await watcher.getTokenActivity(\n                    token, derivedPoolId as `0x${string}`,\n                    { fromBlock, transferLimit: 100, swapLimit: 100 },\n                  );\n                  return jsonResult(formatActivity(activity));\n                }\n              } catch {\n                // Fall through to transfers-only\n              }\n\n              // No pool ID — just return transfers\n              const transfers = await watcher.getRecentTransfers(token, {\n                fromBlock,\n                limit: readNumberParam(p, 'limit') ?? 50,\n              });\n              return jsonResult({\n                token,\n                transfers: transfers.map(formatTransfer),\n                transferCount: transfers.length,\n                note: 'No pool ID available — showing transfers only. Provide pool_id for swap data.',\n              });\n            }\n\n            const activity = await watcher.getTokenActivity(\n              token, poolId as `0x${string}`,\n              { fromBlock, transferLimit: 100, swapLimit: 100 },\n            );\n            return jsonResult(formatActivity(activity));\n          }\n\n          case 'recent_swaps': {\n            const poolId = readStringParam(p, 'pool_id', { required: true })! as `0x${string}`;\n            const swaps = await watcher.getRecentSwaps(poolId, {\n              fromBlock,\n              limit: readNumberParam(p, 'limit') ?? 50,\n            });\n            return jsonResult({\n              poolId,\n              swaps: swaps.map(formatSwap),\n              count: swaps.length,\n            });\n          }\n\n          case 'recent_transfers': {\n            const token = readStringParam(p, 'token', { required: true })! as `0x${string}`;\n            const transfers = await watcher.getRecentTransfers(token, {\n              fromBlock,\n              limit: readNumberParam(p, 'limit') ?? 50,\n            });\n            return jsonResult({\n              token,\n              transfers: transfers.map(formatTransfer),\n              count: transfers.length,\n            });\n          }\n\n          case 'deployments': {\n            const admin = readStringParam(p, 'admin') as `0x${string}` | undefined;\n            const deployments = await watcher.getHistoricalDeployments({\n              fromBlock,\n              tokenAdmin: admin,\n            });\n            return jsonResult({\n              deployments: deployments.map(d => ({\n                tokenAddress: d.tokenAddress,\n                name: d.tokenName,\n                symbol: d.tokenSymbol,\n                deployer: d.deployer,\n                poolId: d.poolId,\n                txHash: d.txHash,\n                block: d.blockNumber?.toString(),\n              })),\n              count: deployments.length,\n            });\n          }\n\n          default:\n            return errorResult(`Unknown watch_activity action: ${action}`);\n        }\n      } catch (err) {\n        return errorResult(`Watch activity error: ${err instanceof Error ? err.message : String(err)}`);\n      }\n    },\n  };\n}\n\n// ── Formatting helpers ─────────────────────────────────────────────────\n\nfunction formatActivity(activity: any) {\n  return {\n    token: activity.token,\n    fromBlock: activity.fromBlock?.toString(),\n    toBlock: activity.toBlock?.toString(),\n    stats: activity.stats ? {\n      transferCount: activity.stats.transferCount,\n      swapCount: activity.stats.swapCount,\n      uniqueAddresses: activity.stats.uniqueAddresses,\n      largestTransfer: activity.stats.largestTransfer?.toString(),\n      totalVolume0: activity.stats.totalVolume0?.toString(),\n      totalVolume1: activity.stats.totalVolume1?.toString(),\n    } : undefined,\n    transfers: activity.transfers?.slice(0, 20).map(formatTransfer),\n    swaps: activity.swaps?.slice(0, 20).map(formatSwap),\n  };\n}\n\nfunction formatTransfer(t: any) {\n  return {\n    from: t.from,\n    to: t.to,\n    amount: t.amountFormatted ?? t.amount?.toString(),\n    txHash: t.txHash,\n    block: t.blockNumber?.toString(),\n  };\n}\n\nfunction formatSwap(s: any) {\n  return {\n    sender: s.sender,\n    amount0: s.amount0?.toString(),\n    amount1: s.amount1?.toString(),\n    txHash: s.txHash,\n    block: s.blockNumber?.toString(),\n  };\n}\n"],"mappings":"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"}