{"version":3,"file":"clawnch-info.mjs","names":[],"sources":["../../../src/tools/clawnch-info.ts"],"sourcesContent":["/**\n * Clawnch Info Tool — On-chain reads, portfolio, vault claims, agent management.\n *\n * Consolidates read-heavy operations that were previously missing:\n *   - token_info: On-chain token details via ClawnchReader\n *   - portfolio: Token discovery + portfolio view via ClawnchPortfolio\n *   - vault_claim: Check/claim vested vault allocations\n *   - agent_register: Register as a verified Clawnch agent\n *   - agent_status: Check agent registration status\n *   - platform_stats: Clawnch platform statistics\n *   - list_tokens: List tokens deployed through Clawnch\n *\n * Most actions are read-only (no gas). vault_claim and agent_register\n * are write operations that go through ClawnchConnect.\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport {\n  getWalletState,\n  requireWalletClient,\n  requirePublicClient,\n} from '../services/walletconnect-service.js';\nimport { checkBalance } from '../services/safety-service.js';\nimport { guardedFetch } from '../services/endpoint-allowlist.js';\nimport { getCredentialVault } from '../services/credential-vault.js';\n\nconst CLAWNCH_API_URL = process.env.CLAWNCHER_API_URL || 'https://clawn.ch';\nconst ACTIONS = [\n  'token_info', 'portfolio', 'vault_claim',\n  'agent_register', 'agent_status', 'platform_stats', 'list_tokens',\n] as const;\n\nconst ClawnchInfoSchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'token_info: on-chain token details. portfolio: discovered tokens + values. ' +\n      'vault_claim: check/claim vault allocation. agent_register: register as Clawnch agent. ' +\n      'agent_status: check registration. platform_stats: Clawnch stats. list_tokens: deployed tokens.',\n  }),\n  token: Type.Optional(Type.String({\n    description: 'Token contract address (for token_info, vault_claim).',\n  })),\n  address: Type.Optional(Type.String({\n    description: 'Wallet address (for portfolio, agent_status). Defaults to connected wallet.',\n  })),\n  agent_name: Type.Optional(Type.String({\n    description: 'Agent display name (for agent_register).',\n  })),\n  agent_description: Type.Optional(Type.String({\n    description: 'Agent description (for agent_register).',\n  })),\n  page: Type.Optional(Type.Number({\n    description: 'Page number for list_tokens (default: 1).',\n  })),\n  page_size: Type.Optional(Type.Number({\n    description: 'Items per page for list_tokens (default: 20).',\n  })),\n});\n\nexport function createClawnchInfoTool() {\n  return {\n    name: 'clawnch_info',\n    label: 'Clawnch Info',\n    ownerOnly: true, // vault_claim and agent_register are write operations\n    description:\n      'On-chain token information, portfolio discovery, vault claims, and Clawnch platform data. ' +\n      'Most actions are read-only (no gas cost). ' +\n      'vault_claim and agent_register are write operations requiring a connected wallet.',\n    parameters: ClawnchInfoSchema,\n    execute: async (_toolCallId: string, args: unknown) => {\n      const params = args as Record<string, unknown>;\n      const action = readStringParam(params, 'action', { required: true })!;\n\n      try {\n        switch (action) {\n          case 'token_info':\n            return handleTokenInfo(params);\n          case 'portfolio':\n            return handlePortfolio(params);\n          case 'vault_claim':\n            return handleVaultClaim(params);\n          case 'agent_register':\n            return handleAgentRegister(params);\n          case 'agent_status':\n            return handleAgentStatus(params);\n          case 'platform_stats':\n            return handlePlatformStats();\n          case 'list_tokens':\n            return handleListTokens(params);\n          default:\n            return errorResult(`Unknown action: ${action}`);\n        }\n      } catch (err) {\n        return errorResult(`Clawnch info failed: ${err instanceof Error ? err.message : String(err)}`);\n      }\n    },\n  };\n}\n\n// ─── Token Info (ClawnchReader) ───────────────────────────────────────────\n\nasync function handleTokenInfo(params: Record<string, unknown>) {\n  const tokenAddress = readStringParam(params, 'token', { required: true })!;\n\n  let publicClient: any;\n  try {\n    publicClient = requirePublicClient();\n  } catch {\n    return errorResult('Public client not initialized. Connect a wallet first or ensure the wallet service is started.');\n  }\n  const { ClawnchReader } = await import('@clawnch/clawncher-sdk');\n\n  const reader = new ClawnchReader({\n    publicClient,\n    network: 'mainnet',\n  });\n\n  const details = await reader.getTokenDetails(tokenAddress as `0x${string}`) as any;\n\n  if (!details) {\n    return errorResult(`Token not found or unreadable: ${tokenAddress}`);\n  }\n\n  return jsonResult({\n    address: tokenAddress,\n    name: details.name,\n    symbol: details.symbol,\n    decimals: details.decimals,\n    totalSupply: details.totalSupply?.toString(),\n    owner: details.owner,\n    // Clawnch-specific fields (present for Clawnch-deployed tokens)\n    isClawnchToken: details.isClawnchToken ?? false,\n    creator: details.creator,\n    launchDate: details.launchDate,\n    liquidityLocked: details.liquidityLocked,\n    taxBuy: details.taxBuy,\n    taxSell: details.taxSell,\n    maxWallet: details.maxWallet,\n    vault: details.vault ? {\n      hasVault: true,\n      lockupEndTime: details.vault.lockupEndTime,\n      vestingDuration: details.vault.vestingDuration,\n      totalAllocation: details.vault.totalAllocation?.toString(),\n    } : { hasVault: false },\n  });\n}\n\n// ─── Portfolio (ClawnchPortfolio) ─────────────────────────────────────────\n\nasync function handlePortfolio(params: Record<string, unknown>) {\n  const state = getWalletState();\n  const address = readStringParam(params, 'address') ?? state.address;\n\n  if (!address) {\n    return errorResult('No address provided and no wallet connected.');\n  }\n\n  let publicClient: any;\n  try {\n    publicClient = requirePublicClient();\n  } catch {\n    return errorResult('Public client not initialized. Connect a wallet first or ensure the wallet service is started.');\n  }\n  const { ClawnchPortfolio } = await import('@clawnch/clawncher-sdk');\n\n  const portfolio = new ClawnchPortfolio({\n    publicClient,\n    network: 'mainnet',\n  });\n\n  // Discover tokens held by this wallet\n  const discovered = await portfolio.discoverTokens(address as `0x${string}`) as any;\n\n  // discoverTokens may return an array of addresses or a portfolio object\n  // Normalize to handle both shapes\n  const tokens = Array.isArray(discovered)\n    ? discovered\n    : (discovered?.tokens ?? []);\n\n  if (!tokens || tokens.length === 0) {\n    return jsonResult({\n      address,\n      totalValueUsd: 0,\n      tokens: [],\n      message: 'No tokens discovered for this address.',\n    });\n  }\n\n  // If we got full portfolio objects, sort by value\n  if (typeof tokens[0] === 'object' && tokens[0].valueUsd !== undefined) {\n    const sorted = [...tokens].sort(\n      (a: any, b: any) => (b.valueUsd ?? 0) - (a.valueUsd ?? 0)\n    );\n\n    return jsonResult({\n      address,\n      ethBalance: discovered.ethBalance?.toString(),\n      ethValueUsd: discovered.ethValueUsd,\n      totalValueUsd: discovered.totalValueUsd,\n      tokenCount: sorted.length,\n      tokens: sorted.map((t: any) => ({\n        address: t.address,\n        symbol: t.symbol,\n        name: t.name,\n        balance: t.balanceFormatted,\n        priceUsd: t.priceUsd,\n        valueUsd: t.valueUsd,\n        isClawnchToken: t.isClawnchToken ?? false,\n      })),\n    });\n  }\n\n  // Bare address list — return as-is for the agent to process\n  return jsonResult({\n    address,\n    tokenCount: tokens.length,\n    tokenAddresses: tokens,\n    message: 'Token addresses discovered. Use token_info action to get details for each.',\n  });\n}\n\n// ─── Vault Claim (ClawncherClaimer) ───────────────────────────────────────\n\nasync function handleVaultClaim(params: Record<string, unknown>) {\n  const tokenAddress = readStringParam(params, 'token', { required: true })!;\n\n  const state = getWalletState();\n  if (!state.connected) {\n    return errorResult('No wallet connected. Use clawnchconnect tool to connect first.');\n  }\n\n  const publicClient = requirePublicClient();\n  const { ClawnchReader } = await import('@clawnch/clawncher-sdk');\n\n  const reader = new ClawnchReader({\n    publicClient,\n    network: 'mainnet',\n  });\n\n  // Check vault allocation status first (read-only)\n  const vault = await reader.getVaultAllocation(tokenAddress as `0x${string}`);\n\n  if (!vault) {\n    return jsonResult({\n      token: tokenAddress,\n      hasVault: false,\n      message: 'No vault allocation exists for this token.',\n    });\n  }\n\n  const { formatEther } = await import('viem');\n\n  const status: Record<string, unknown> = {\n    token: tokenAddress,\n    hasVault: true,\n    totalAllocation: formatEther(vault.amountTotal),\n    claimed: formatEther(vault.amountClaimed),\n    available: formatEther(vault.amountAvailable),\n    percentVested: vault.percentVested,\n    isUnlocked: vault.isUnlocked,\n    isFullyVested: vault.isFullyVested,\n  };\n\n  if (!vault.isUnlocked) {\n    status.lockupEnds = new Date(Number(vault.lockupEndTime) * 1000).toISOString();\n    status.message = 'Vault is still locked. Cannot claim yet.';\n    return jsonResult(status);\n  }\n\n  if (vault.amountAvailable === 0n) {\n    status.message = vault.isFullyVested\n      ? 'Fully vested and fully claimed. Nothing left.'\n      : 'No tokens available to claim yet. Vesting in progress.';\n    return jsonResult(status);\n  }\n\n  // Pre-flight gas check\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    status.message = `Cannot claim: ${safety.blockers.join('; ')}`;\n    return jsonResult(status);\n  }\n\n  // Execute claim\n  const wallet = requireWalletClient();\n  const { ClawncherClaimer } = await import('@clawnch/clawncher-sdk');\n\n  const claimer = new ClawncherClaimer({\n    wallet,\n    publicClient,\n    network: 'mainnet',\n  });\n\n  const result = await claimer.claimVault(tokenAddress as `0x${string}`);\n  await result.wait();\n\n  status.claimExecuted = true;\n  status.txHash = result.txHash;\n  status.amountClaimed = formatEther(vault.amountAvailable);\n  status.message = `Successfully claimed ${formatEther(vault.amountAvailable)} tokens.`;\n\n  return jsonResult(status);\n}\n\n// ─── Agent Registration (ClawnchApiDeployer) ──────────────────────────────\n\nasync function handleAgentRegister(params: Record<string, unknown>) {\n  const state = getWalletState();\n  if (!state.connected) {\n    return errorResult('No wallet connected. Use clawnchconnect tool to connect first.');\n  }\n\n  const agentName = readStringParam(params, 'agent_name', { required: true })!;\n  const agentDescription = readStringParam(params, 'agent_description') ?? '';\n\n  const apiKey = getCredentialVault().getSecret('clawnch.apiKey', 'clawnch-info');\n  if (!apiKey) {\n    return errorResult('CLAWNCH_API_KEY not set. Required for agent registration.');\n  }\n\n  const wallet = requireWalletClient();\n  const publicClient = requirePublicClient();\n  const { ClawnchApiDeployer } = await import('@clawnch/clawncher-sdk');\n\n  const deployer = new ClawnchApiDeployer({\n    apiBaseUrl: CLAWNCH_API_URL,\n    apiKey,\n    wallet,\n    publicClient,\n  });\n\n  // register is a static method on ClawnchApiDeployer\n  const result = await (ClawnchApiDeployer as any).register({\n    address: state.address!,\n    name: agentName,\n    description: agentDescription,\n    apiKey,\n    apiBaseUrl: CLAWNCH_API_URL,\n  });\n\n  return jsonResult({\n    status: 'registered',\n    agentId: (result as any).agentId,\n    address: state.address,\n    name: agentName,\n    verified: (result as any).verified,\n  });\n}\n\nasync function handleAgentStatus(params: Record<string, unknown>) {\n  const state = getWalletState();\n  const address = readStringParam(params, 'address') ?? state.address;\n\n  if (!address) {\n    return errorResult('No address provided and no wallet connected.');\n  }\n\n  const apiKey = getCredentialVault().getSecret('clawnch.apiKey', 'clawnch-info');\n  if (!apiKey) {\n    return errorResult('CLAWNCH_API_KEY not set. Required for agent status queries.');\n  }\n\n  // Agent status is a read operation — query the API directly using the\n  // address parameter. No wallet client needed (we're not signing anything).\n  const apiBaseUrl = CLAWNCH_API_URL;\n\n  try {\n    const response = await guardedFetch(\n      `${apiBaseUrl}/api/agents/${address}`,\n      {\n        headers: {\n          'x-api-key': apiKey,\n          Accept: 'application/json',\n        },\n        signal: AbortSignal.timeout(15_000),\n      },\n    );\n\n    if (!response.ok) {\n      if (response.status === 404) {\n        return jsonResult({\n          address,\n          registered: false,\n          agentId: null,\n          name: null,\n          verified: false,\n          registeredAt: null,\n          tokenAddress: null,\n        });\n      }\n      throw new Error(`API returned ${response.status}: ${await response.text()}`);\n    }\n\n    const agentStatus = (await response.json()) as any;\n\n    return jsonResult({\n      address,\n      registered: agentStatus.registeredAt != null,\n      agentId: agentStatus.agentId,\n      name: agentStatus.name,\n      verified: agentStatus.verified,\n      registeredAt: agentStatus.registeredAt,\n      tokenAddress: agentStatus.tokenAddress,\n    });\n  } catch (err) {\n    return errorResult(\n      `Failed to query agent status for ${address}: ${err instanceof Error ? err.message : String(err)}`,\n    );\n  }\n}\n\n// ─── Platform Stats ───────────────────────────────────────────────────────\n\nasync function handlePlatformStats() {\n  const apiUrl = CLAWNCH_API_URL;\n\n  try {\n    const response = await guardedFetch(`${apiUrl}/api/stats`, {\n      headers: { Accept: 'application/json' },\n      signal: AbortSignal.timeout(15_000),\n    });\n\n    if (!response.ok) {\n      return errorResult(`Platform stats unavailable: HTTP ${response.status}`);\n    }\n\n    const stats = await response.json() as any;\n\n    return jsonResult({\n      platform: 'Clawnch',\n      totalTokensDeployed: stats.totalTokens,\n      totalAgents: stats.totalAgents,\n      totalVolumeUsd: stats.totalVolumeUsd,\n      totalLiquidityUsd: stats.totalLiquidityUsd,\n      activeTokens24h: stats.activeTokens24h,\n      topTokens: stats.topTokens?.slice(0, 5),\n    });\n  } catch (err) {\n    return errorResult(`Platform stats failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\n// ─── List Tokens ──────────────────────────────────────────────────────────\n\nasync function handleListTokens(params: Record<string, unknown>) {\n  const page = readNumberParam(params, 'page') ?? 1;\n  const pageSize = readNumberParam(params, 'page_size') ?? 20;\n\n  const apiUrl = CLAWNCH_API_URL;\n\n  try {\n    const queryParams = new URLSearchParams({\n      page: page.toString(),\n      pageSize: pageSize.toString(),\n    });\n\n    const response = await guardedFetch(`${apiUrl}/api/tokens?${queryParams}`, {\n      headers: { Accept: 'application/json' },\n      signal: AbortSignal.timeout(15_000),\n    });\n\n    if (!response.ok) {\n      return errorResult(`Token list unavailable: HTTP ${response.status}`);\n    }\n\n    const data = await response.json() as any;\n\n    return jsonResult({\n      page,\n      pageSize,\n      total: data.total,\n      totalPages: Math.ceil(data.total / pageSize),\n      tokens: (data.tokens ?? []).map((t: any) => ({\n        address: t.address,\n        name: t.name,\n        symbol: t.symbol,\n        creator: t.creator,\n        launchDate: t.launchDate,\n        priceUsd: t.priceUsd,\n        marketCap: t.marketCapUsd,\n        volume24h: t.volume24hUsd,\n        holderCount: t.holderCount,\n      })),\n    });\n  } catch (err) {\n    return errorResult(`Token list failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n"],"mappings":"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"}