{"version":3,"file":"safe.mjs","names":[],"sources":["../../../src/tools/safe.ts"],"sourcesContent":["/**\n * Safe Multisig Tool — manage Safe{Wallet} multisig wallets.\n *\n * Actions:\n *   info          — Get Safe details (threshold, owners, nonce, version)\n *   balances      — Get Safe token balances (ETH + ERC-20)\n *   pending_txs   — List pending/queued transactions awaiting signatures\n *   history       — Get executed transaction history\n *   propose       — Propose a new transaction to a Safe\n *   confirm       — Confirm (co-sign) a pending transaction\n *   execute       — Check execution readiness for a pending transaction\n *\n * Uses Safe Transaction Service REST API. No SDK dependency.\n * Supports Ethereum, Base, Arbitrum, Optimism, and Polygon.\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport { getSafeService } from '../services/safe-service.js';\nimport {\n  getWalletState,\n  requirePublicClient,\n} from '../services/walletconnect-service.js';\nimport { resolveAddressOrEns, isEnsName } from '../lib/ens-resolver.js';\n\nconst ACTIONS = ['info', 'balances', 'pending_txs', 'history', 'propose', 'confirm', 'execute'] as const;\n\nconst SafeSchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'info: Safe details. balances: token balances. pending_txs: pending transactions. ' +\n      'history: executed transactions. propose: propose new tx. confirm: co-sign pending tx. ' +\n      'execute: check if pending tx has enough signatures to execute.',\n  }),\n  safe_address: Type.Optional(Type.String({\n    description: 'Safe multisig address or ENS name. Required for most actions.',\n  })),\n  chain: Type.Optional(Type.String({\n    description: 'Chain: \"ethereum\" (default), \"base\", \"arbitrum\", \"optimism\", \"polygon\".',\n  })),\n  safe_tx_hash: Type.Optional(Type.String({\n    description: 'Safe transaction hash. Required for confirm and execute actions.',\n  })),\n  to: Type.Optional(Type.String({\n    description: 'Destination address for propose action.',\n  })),\n  value: Type.Optional(Type.String({\n    description: 'ETH value in wei for propose action. Default: \"0\".',\n  })),\n  data: Type.Optional(Type.String({\n    description: 'Calldata hex for propose action. Default: \"0x\" (plain ETH transfer).',\n  })),\n  signature: Type.Optional(Type.String({\n    description: 'EIP-712 signature for propose/confirm. Must be generated off-chain.',\n  })),\n  limit: Type.Optional(Type.Number({\n    description: 'Max results to return. Default: 20.',\n  })),\n});\n\nexport function createSafeTool() {\n  return {\n    name: 'safe',\n    label: 'Safe Multisig',\n    ownerOnly: true,\n    description:\n      'Manage Safe{Wallet} multisig wallets: view info, balances, pending transactions, ' +\n      'propose new transactions, confirm/co-sign, and check execution readiness. ' +\n      'Supports Ethereum, Base, Arbitrum, Optimism, and Polygon.',\n    parameters: SafeSchema,\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      switch (action) {\n        case 'info':\n          return handleInfo(params);\n        case 'balances':\n          return handleBalances(params);\n        case 'pending_txs':\n          return handlePendingTxs(params);\n        case 'history':\n          return handleHistory(params);\n        case 'propose':\n          return handlePropose(params);\n        case 'confirm':\n          return handleConfirm(params);\n        case 'execute':\n          return handleExecute(params);\n        default:\n          return errorResult(`Unknown action: ${action}. Use: info, balances, pending_txs, history, propose, confirm, execute`);\n      }\n    },\n  };\n}\n\n// ── Action Handlers ─────────────────────────────────────────────────────\n\nasync function handleInfo(params: Record<string, unknown>) {\n  const { safeAddress, chainId } = await resolveSafeParams(params);\n  if (!safeAddress) return errorResult('safe_address is required.');\n\n  try {\n    const service = getSafeService();\n    const info = await service.getInfo(safeAddress, chainId);\n\n    return jsonResult({\n      address: info.address,\n      threshold: info.threshold,\n      owners: info.owners,\n      ownerCount: info.owners.length,\n      nonce: info.nonce,\n      version: info.version,\n      modules: info.modules.length > 0 ? info.modules : undefined,\n      guard: info.guard !== '' && info.guard !== '0x0000000000000000000000000000000000000000' ? info.guard : undefined,\n      chain: chainLabel(chainId),\n      note: `${info.threshold}-of-${info.owners.length} multisig`,\n    });\n  } catch (err) {\n    return errorResult(`Safe info failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleBalances(params: Record<string, unknown>) {\n  const { safeAddress, chainId } = await resolveSafeParams(params);\n  if (!safeAddress) return errorResult('safe_address is required.');\n\n  try {\n    const service = getSafeService();\n    const balances = await service.getBalances(safeAddress, chainId);\n\n    const formatted = balances.map(b => ({\n      symbol: b.token?.symbol ?? (chainId === 137 ? 'MATIC' : 'ETH'),\n      name: b.token?.name ?? 'Native Token',\n      balance: formatBalance(b.balance, b.token?.decimals ?? 18),\n      rawBalance: b.balance,\n      tokenAddress: b.tokenAddress ?? 'native',\n    }));\n\n    return jsonResult({\n      safeAddress,\n      chain: chainLabel(chainId),\n      tokens: formatted,\n      tokenCount: formatted.length,\n    });\n  } catch (err) {\n    return errorResult(`Balances fetch failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handlePendingTxs(params: Record<string, unknown>) {\n  const { safeAddress, chainId } = await resolveSafeParams(params);\n  if (!safeAddress) return errorResult('safe_address is required.');\n  const limit = readNumberParam(params, 'limit') ?? 20;\n\n  try {\n    const service = getSafeService();\n    const txs = await service.getPendingTransactions(safeAddress, chainId, limit);\n\n    if (txs.length === 0) {\n      return jsonResult({\n        safeAddress,\n        chain: chainLabel(chainId),\n        pending: [],\n        message: 'No pending transactions.',\n      });\n    }\n\n    return jsonResult({\n      safeAddress,\n      chain: chainLabel(chainId),\n      count: txs.length,\n      pending: txs.map(tx => ({\n        safeTxHash: tx.safeTxHash,\n        to: tx.to,\n        value: tx.value !== '0' ? formatBalance(tx.value, 18) + ' ETH' : undefined,\n        data: tx.data ? (tx.data.length > 10 ? tx.data.slice(0, 10) + '...' : tx.data) : undefined,\n        dataDecoded: tx.dataDecoded ? summarizeDecoded(tx.dataDecoded) : undefined,\n        nonce: tx.nonce,\n        confirmations: tx.confirmations.length,\n        confirmationsRequired: tx.confirmationsRequired,\n        signers: tx.confirmations.map(c => c.owner),\n        submittedAt: tx.submissionDate,\n        canExecute: tx.confirmations.length >= tx.confirmationsRequired,\n      })),\n    });\n  } catch (err) {\n    return errorResult(`Pending transactions fetch failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleHistory(params: Record<string, unknown>) {\n  const { safeAddress, chainId } = await resolveSafeParams(params);\n  if (!safeAddress) return errorResult('safe_address is required.');\n  const limit = readNumberParam(params, 'limit') ?? 20;\n\n  try {\n    const service = getSafeService();\n    const txs = await service.getTransactionHistory(safeAddress, chainId, limit);\n\n    return jsonResult({\n      safeAddress,\n      chain: chainLabel(chainId),\n      count: txs.length,\n      transactions: txs.map(tx => ({\n        safeTxHash: tx.safeTxHash,\n        to: tx.to,\n        value: tx.value !== '0' ? formatBalance(tx.value, 18) + ' ETH' : undefined,\n        dataDecoded: tx.dataDecoded ? summarizeDecoded(tx.dataDecoded) : undefined,\n        nonce: tx.nonce,\n        executedAt: tx.executionDate,\n        success: tx.isSuccessful,\n        txHash: tx.transactionHash,\n        executor: tx.executor,\n      })),\n    });\n  } catch (err) {\n    return errorResult(`Transaction history fetch failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handlePropose(params: Record<string, unknown>) {\n  const { safeAddress, chainId } = await resolveSafeParams(params);\n  if (!safeAddress) return errorResult('safe_address is required.');\n\n  const to = readStringParam(params, 'to');\n  if (!to) return errorResult('to address is required for propose.');\n\n  const value = readStringParam(params, 'value') ?? '0';\n  if (!/^\\d+$/.test(value)) {\n    return errorResult(`Invalid value \"${value}\". Must be a non-negative integer in wei (e.g. \"1000000000000000000\" for 1 ETH).`);\n  }\n  const data = readStringParam(params, 'data') ?? '0x';\n  if (data !== '0x' && !/^0x[0-9a-fA-F]*$/.test(data)) {\n    return errorResult(`Invalid data \"${data.slice(0, 20)}...\". Must be a hex string starting with \"0x\".`);\n  }\n  const signature = readStringParam(params, 'signature');\n  if (!signature) {\n    return errorResult(\n      'signature is required. You must generate an EIP-712 signature of the Safe transaction hash off-chain. ' +\n      'Use the Safe signing scheme: domain separator + typehash + tx struct hash.',\n    );\n  }\n\n  const state = getWalletState();\n  if (!state.connected || !state.address) {\n    return errorResult('No wallet connected. Connect a wallet first to propose transactions.');\n  }\n\n  try {\n    const service = getSafeService();\n\n    // Verify sender is an owner\n    const isOwner = await service.isOwner(safeAddress, state.address, chainId);\n    if (!isOwner) {\n      return errorResult(`Address ${state.address} is not an owner of Safe ${safeAddress}.`);\n    }\n\n    // Get current nonce for the proposal\n    const info = await service.getInfo(safeAddress, chainId);\n\n    await service.proposeTransaction(\n      {\n        safeAddress,\n        to,\n        value,\n        data,\n        signature,\n        sender: state.address,\n        nonce: info.nonce,\n      },\n      chainId,\n    );\n\n    return jsonResult({\n      status: 'success',\n      action: 'propose',\n      safeAddress,\n      to,\n      value: value !== '0' ? formatBalance(value, 18) + ' ETH' : undefined,\n      hasData: data !== '0x',\n      nonce: info.nonce,\n      chain: chainLabel(chainId),\n      note: `Transaction proposed at nonce ${info.nonce}. Other owners must confirm before execution.`,\n    });\n  } catch (err) {\n    return errorResult(`Propose failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleConfirm(params: Record<string, unknown>) {\n  const safeTxHash = readStringParam(params, 'safe_tx_hash');\n  if (!safeTxHash) return errorResult('safe_tx_hash is required for confirm.');\n\n  const signature = readStringParam(params, 'signature');\n  if (!signature) {\n    return errorResult(\n      'signature is required. Generate an EIP-712 signature of the safeTxHash using the Safe signing scheme.',\n    );\n  }\n\n  const service = getSafeService();\n  const chainId = service.resolveChainId(readStringParam(params, 'chain') ?? undefined);\n\n  try {\n    await service.confirmTransaction(safeTxHash, signature, chainId);\n\n    // Fetch updated tx to show confirmation count\n    const tx = await service.getTransaction(safeTxHash, chainId);\n\n    return jsonResult({\n      status: 'success',\n      action: 'confirm',\n      safeTxHash,\n      confirmations: tx.confirmations.length,\n      confirmationsRequired: tx.confirmationsRequired,\n      canExecute: tx.confirmations.length >= tx.confirmationsRequired,\n      chain: chainLabel(chainId),\n      note: tx.confirmations.length >= tx.confirmationsRequired\n        ? 'Threshold reached — this transaction can now be executed.'\n        : `${tx.confirmationsRequired - tx.confirmations.length} more confirmation(s) needed.`,\n    });\n  } catch (err) {\n    return errorResult(`Confirm failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleExecute(params: Record<string, unknown>) {\n  const safeTxHash = readStringParam(params, 'safe_tx_hash');\n  if (!safeTxHash) return errorResult('safe_tx_hash is required for execute.');\n\n  const service = getSafeService();\n  const chainId = service.resolveChainId(readStringParam(params, 'chain') ?? undefined);\n\n  try {\n    const tx = await service.getTransaction(safeTxHash, chainId);\n\n    if (tx.isExecuted) {\n      return jsonResult({\n        status: 'already_executed',\n        safeTxHash,\n        txHash: tx.transactionHash,\n        success: tx.isSuccessful,\n        executedAt: tx.executionDate,\n        chain: chainLabel(chainId),\n      });\n    }\n\n    const canExecute = tx.confirmations.length >= tx.confirmationsRequired;\n\n    return jsonResult({\n      status: canExecute ? 'ready' : 'not_ready',\n      safeTxHash,\n      to: tx.to,\n      value: tx.value !== '0' ? formatBalance(tx.value, 18) + ' ETH' : undefined,\n      dataDecoded: tx.dataDecoded ? summarizeDecoded(tx.dataDecoded) : undefined,\n      nonce: tx.nonce,\n      confirmations: tx.confirmations.length,\n      confirmationsRequired: tx.confirmationsRequired,\n      signers: tx.confirmations.map(c => c.owner),\n      chain: chainLabel(chainId),\n      note: canExecute\n        ? 'Transaction has enough confirmations and can be executed. Submit via the Safe app or directly on-chain.'\n        : `Needs ${tx.confirmationsRequired - tx.confirmations.length} more confirmation(s) before execution.`,\n    });\n  } catch (err) {\n    return errorResult(`Execute check failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nasync function resolveSafeParams(params: Record<string, unknown>): Promise<{\n  safeAddress: string | null;\n  chainId: number;\n}> {\n  const service = getSafeService();\n  const chainId = service.resolveChainId(readStringParam(params, 'chain') ?? undefined);\n  let safeAddress: string | null = readStringParam(params, 'safe_address') ?? null;\n\n  if (safeAddress && isEnsName(safeAddress)) {\n    try {\n      const publicClient = requirePublicClient();\n      const resolved = await resolveAddressOrEns(safeAddress, publicClient);\n      safeAddress = resolved.address;\n    } catch {\n      // If ENS resolution fails, pass through — the API will error with a clear message\n    }\n  }\n\n  return { safeAddress, chainId };\n}\n\nfunction formatBalance(raw: string, decimals: number): string {\n  const num = Number(raw) / 10 ** decimals;\n  if (num === 0) return '0';\n  if (num < 0.0001) return '<0.0001';\n  if (num < 1) return num.toFixed(4);\n  if (num < 1000) return num.toFixed(2);\n  return num.toLocaleString('en-US', { maximumFractionDigits: 2 });\n}\n\nfunction chainLabel(chainId: number): string {\n  switch (chainId) {\n    case 1: return 'ethereum';\n    case 8453: return 'base';\n    case 42161: return 'arbitrum';\n    case 10: return 'optimism';\n    case 137: return 'polygon';\n    default: return String(chainId);\n  }\n}\n\nfunction summarizeDecoded(decoded: any): string {\n  if (!decoded) return '';\n  const method = decoded.method ?? 'unknown';\n  const params = decoded.parameters?.map((p: any) => `${p.name}=${p.value}`)?.join(', ') ?? '';\n  return params ? `${method}(${params})` : method;\n}\n"],"mappings":"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"}