{"version":3,"file":"bankr-commands.mjs","names":[],"sources":["../../../src/commands/bankr-commands.ts"],"sourcesContent":["/**\n * Bankr commands.\n *\n * /llmcredits   — Credit balance, top-up link, onboarding guidance\n * /llmcost      — Model-by-model usage breakdown (last N days)\n * /automations  — List active Bankr automations (limit orders, DCA, etc.)\n * /topup        — Top up LLM credits from Bankr wallet (via Agent API)\n * /autotopup    — View or configure auto top-up for LLM credits\n *\n * LLM commands call llm.bankr.bot. Agent commands call api.bankr.bot.\n * Credit mutations (topup, autotopup) route through the Agent API's\n * prompt-and-poll pattern since they involve wallet transactions.\n */\n\nimport { guardedFetch } from '../services/endpoint-allowlist.js';\nimport { getCredentialVault } from '../services/credential-vault.js';\n\nconst BANKR_BASE = 'https://llm.bankr.bot';\n\nfunction getBankrKey(): string | null {\n  return process.env.BANKR_LLM_KEY ?? null;\n}\n\nfunction isBankrProvider(): boolean {\n  const provider = process.env.OPENCLAWNCH_LLM_PROVIDER ?? '';\n  if (provider === 'bankr') return true;\n  return !!process.env.BANKR_LLM_KEY;\n}\n\n/** Try to fetch credit balance from the LLM gateway. Returns null on failure. */\nasync function fetchCreditBalance(key: string): Promise<{ balance: number; currency: string } | null> {\n  try {\n    const res = await guardedFetch(`${BANKR_BASE}/v1/credits`, {\n      headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },\n      signal: AbortSignal.timeout(10_000),\n    });\n    if (!res.ok) return null;\n    const data = await res.json() as any;\n    // Accept various response shapes\n    const balance = data?.balance ?? data?.credits ?? data?.remaining ?? null;\n    if (typeof balance !== 'number') return null;\n    return { balance, currency: data?.currency ?? 'USD' };\n  } catch {\n    return null;\n  }\n}\n\n/** Try to fetch auto top-up config from the LLM gateway. Returns null on failure. */\nasync function fetchAutoTopupConfig(key: string): Promise<{\n  enabled: boolean; amount?: number; threshold?: number; tokens?: string[];\n} | null> {\n  try {\n    const res = await guardedFetch(`${BANKR_BASE}/v1/credits/auto`, {\n      headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },\n      signal: AbortSignal.timeout(10_000),\n    });\n    if (!res.ok) return null;\n    const data = await res.json() as any;\n    return {\n      enabled: !!data?.enabled,\n      amount: data?.amount,\n      threshold: data?.threshold,\n      tokens: data?.tokens,\n    };\n  } catch {\n    return null;\n  }\n}\n\n// ── /llmcredits ─────────────────────────────────────────────────────────────\n\nexport const creditsCommand = {\n  name: 'llmcredits',\n  description: 'Bankr LLM credits, top-up, and setup info',\n  acceptsArgs: false,\n  requireAuth: true,\n  handler: async (_ctx: any) => {\n    // Not configured at all — show full onboarding\n    if (!isBankrProvider()) {\n      return {\n        text: [\n          '**Bankr LLM Gateway**',\n          '',\n          'Pay for AI with crypto. One API key for Claude, Gemini, GPT, and more.',\n          '',\n          '**Setup (3 steps):**',\n          '1. Create account: https://bankr.bot',\n          '2. Get an API key with LLM Gateway enabled: https://bankr.bot/api',\n          '3. Top up credits (USDC, ETH, or BNKR on Base): https://bankr.bot/llm',\n          '',\n          'Then add the key:',\n          '  `/flykeys set BANKR_LLM_KEY bk_your_key`',\n          '  /provider_bankr',\n          '',\n          'Docs: https://docs.bankr.bot/llm-gateway/overview/',\n        ].join('\\n'),\n      };\n    }\n\n    const key = getBankrKey();\n    if (!key) {\n      return {\n        text: [\n          'BANKR_LLM_KEY is not set.',\n          '',\n          'Add it:',\n          '  `/flykeys set BANKR_LLM_KEY bk_your_key`',\n          '  /flyrestart',\n          '',\n          'Get a key at: https://bankr.bot/api',\n        ].join('\\n'),\n      };\n    }\n\n    // Try to fetch usage data\n    try {\n      const res = await guardedFetch(`${BANKR_BASE}/v1/usage?days=30`, {\n        headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },\n        signal: AbortSignal.timeout(15_000),\n      });\n\n      if (res.status === 403) {\n        return {\n          text: [\n            '**LLM Gateway not enabled on this key**',\n            '',\n            'Your Bankr API key was recognized but doesn\\'t have LLM Gateway access.',\n            '',\n            '**Fix it:**',\n            '1. Go to https://bankr.bot/api',\n            '2. Find your API key',\n            '3. Enable the \"LLM Gateway\" toggle',\n            '',\n            'Then top up credits at: https://bankr.bot/llm',\n          ].join('\\n'),\n        };\n      }\n\n      if (res.status === 402) {\n        return {\n          text: [\n            '**LLM Credits: $0.00**',\n            '',\n            'Your credits are exhausted. The bot can\\'t respond until you top up.',\n            '',\n            '**Options:**',\n            '  Top up with crypto: https://bankr.bot/llm',\n            '  Switch to Anthropic: /provider_anthropic',\n            '',\n            'You can also enable auto top-up at bankr.bot/llm so you never run out.',\n          ].join('\\n'),\n        };\n      }\n\n      if (res.status === 401) {\n        return {\n          text: [\n            '**Authentication failed**',\n            '',\n            'Your BANKR_LLM_KEY may be invalid or expired.',\n            '',\n            'Generate a new key at: https://bankr.bot/api',\n            'Then update: `/flykeys set BANKR_LLM_KEY bk_new_key`',\n            'Then: /flyrestart',\n          ].join('\\n'),\n        };\n      }\n\n      if (!res.ok) {\n        return {\n          text: `Bankr API returned ${res.status}. Check: https://bankr.bot/llm`,\n        };\n      }\n\n      const data = await res.json() as any;\n      const total = data?.totals;\n      const cost30d = total?.totalCost ?? 0;\n      const requests30d = total?.totalRequests ?? 0;\n\n      // Try to get the actual credit balance\n      const creditInfo = await fetchCreditBalance(key);\n      // Try to get auto top-up config\n      const autoConfig = await fetchAutoTopupConfig(key);\n\n      const lines = ['**Bankr LLM Gateway**', ''];\n\n      // Credit balance (if available)\n      if (creditInfo) {\n        lines.push(`**Credit Balance: $${creditInfo.balance.toFixed(2)}**`);\n        if (creditInfo.balance < 5) {\n          lines.push('  Low balance! Top up: /topup 25');\n        }\n        lines.push('');\n      }\n\n      lines.push(\n        '**Last 30 days:**',\n        `  Requests: ${requests30d.toLocaleString()}`,\n        `  Cost: $${cost30d.toFixed(2)}`,\n        '',\n      );\n\n      // Auto top-up status\n      if (autoConfig) {\n        if (autoConfig.enabled) {\n          lines.push(\n            '**Auto Top-up: ON**',\n            `  Amount: $${autoConfig.amount ?? '?'} when below $${autoConfig.threshold ?? '?'}`,\n            `  Token: ${autoConfig.tokens?.join(', ') ?? 'USDC'}`,\n          );\n        } else {\n          lines.push('**Auto Top-up: OFF** (enable with /autotopup enable)');\n        }\n        lines.push('');\n      }\n\n      lines.push(\n        '**Commands:**',\n        '  /topup 25 — Add $25 credits from wallet',\n        '  /autotopup — Configure auto top-up',\n        '  /llmcost — Usage breakdown by model',\n        '  /llm — Switch model',\n        '',\n        '**Links:**',\n        '  Dashboard: https://bankr.bot/llm',\n        '  Manage keys: https://bankr.bot/api',\n      );\n\n      return { text: lines.join('\\n') };\n    } catch (err) {\n      return {\n        text: `Failed to reach Bankr: ${err instanceof Error ? err.message : String(err)}\\n\\nCheck manually: https://bankr.bot/llm`,\n      };\n    }\n  },\n};\n\n// ── /llmcost ────────────────────────────────────────────────────────────────\n\nexport const usageCommand = {\n  name: 'llmcost',\n  description: 'Show Bankr LLM usage breakdown by model',\n  acceptsArgs: true,\n  requireAuth: true,\n  handler: async (ctx: any) => {\n    if (!isBankrProvider()) {\n      return { text: 'Bankr LLM Gateway is not configured. Run /llmcredits for setup instructions.' };\n    }\n\n    const key = getBankrKey();\n    if (!key) {\n      return { text: 'BANKR_LLM_KEY is not set. Run /llmcredits for setup instructions.' };\n    }\n\n    const args = (ctx?.args ?? ctx?.text ?? '').trim();\n    const daysArg = args.replace(/^\\/llmcost\\s*/, '').trim();\n    const days = Math.min(90, Math.max(1, parseInt(daysArg, 10) || 30));\n\n    try {\n      const res = await guardedFetch(`${BANKR_BASE}/v1/usage?days=${days}`, {\n        headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },\n        signal: AbortSignal.timeout(15_000),\n      });\n\n      if (res.status === 403) {\n        return { text: 'LLM Gateway not enabled on this key. Run /llmcredits for setup instructions.' };\n      }\n\n      if (res.status === 402) {\n        return { text: 'Credits exhausted. Top up at: https://bankr.bot/llm' };\n      }\n\n      if (!res.ok) {\n        return { text: `Bankr API returned ${res.status}. Try again later.` };\n      }\n\n      const data = await res.json() as any;\n      const total = data?.totals;\n      const byModel = data?.byModel ?? [];\n\n      const lines = [\n        `**Bankr LLM Usage (${days} days)**`,\n        '',\n        '**Totals:**',\n        `  Requests: ${(total?.totalRequests ?? 0).toLocaleString()}`,\n        `  Input tokens: ${(total?.totalInputTokens ?? 0).toLocaleString()}`,\n        `  Output tokens: ${(total?.totalOutputTokens ?? 0).toLocaleString()}`,\n        `  Cache reads: ${(total?.totalCacheReadInputTokens ?? 0).toLocaleString()}`,\n        `  Total cost: $${(total?.totalCost ?? 0).toFixed(2)}`,\n      ];\n\n      if (byModel.length > 0) {\n        lines.push('', '**By model:**');\n        const sorted = [...byModel].sort((a: any, b: any) => (b.totalCost ?? 0) - (a.totalCost ?? 0));\n        for (const m of sorted) {\n          lines.push(`  ${m.model}: ${(m.requests ?? 0).toLocaleString()} reqs, $${(m.totalCost ?? 0).toFixed(2)}`);\n        }\n      }\n\n      lines.push('', 'Top up: https://bankr.bot/llm');\n      return { text: lines.join('\\n') };\n    } catch (err) {\n      return { text: `Failed to reach Bankr: ${err instanceof Error ? err.message : String(err)}` };\n    }\n  },\n};\n\n// ── /topup ──────────────────────────────────────────────────────────────────\n\nexport const topupCommand = {\n  name: 'topup',\n  description: 'Top up LLM credits from your Bankr wallet',\n  acceptsArgs: true,\n  requireAuth: true,\n  handler: async (ctx: any) => {\n    // Need Agent API for wallet operations\n    const apiKey = getCredentialVault().getSecret('bankr.apiKey', 'bankr-commands');\n    if (!apiKey) {\n      return {\n        text: [\n          '**Bankr Agent API not configured**',\n          '',\n          'Topping up credits requires a Bankr API key with Agent API enabled.',\n          '',\n          '1. Get a key at: https://bankr.bot/api',\n          '2. Enable \"Agent API\"',\n          '3. `/flykeys set BANKR_API_KEY bk_your_key`',\n          '4. /flyrestart then /connect_bankr',\n          '',\n          'Or top up via the web: https://bankr.bot/llm?tab=credits',\n        ].join('\\n'),\n      };\n    }\n\n    // Parse arguments: /topup <amount> [token]\n    const rawArgs = (ctx?.args ?? ctx?.text ?? '').trim();\n    const argStr = rawArgs.replace(/^\\/topup\\s*/, '').trim();\n    const parts = argStr.split(/\\s+/);\n    const amountStr = parts[0] ?? '';\n    const token = parts[1] ?? 'USDC';\n\n    const amount = parseFloat(amountStr);\n    if (!amountStr || isNaN(amount) || amount <= 0) {\n      return {\n        text: [\n          '**Usage:** `/topup <amount> [token]`',\n          '',\n          '**Examples:**',\n          '  `/topup 25` — Add $25 credits (USDC)',\n          '  `/topup 50 ETH` — Add $50 credits (pay with ETH)',\n          '  `/topup 10 BNKR` — Add $10 credits (pay with BNKR)',\n          '',\n          'Credits are deducted from your Bankr wallet balance.',\n          'Check balance: /llmcredits',\n        ].join('\\n'),\n      };\n    }\n\n    if (amount > 1000) {\n      return { text: 'Maximum single top-up is $1000. For larger amounts, top up multiple times or use the dashboard: https://bankr.bot/llm' };\n    }\n\n    try {\n      const { bankrPromptAndPoll } = await import('../services/bankr-api.js');\n\n      const prompt = token.toUpperCase() === 'USDC'\n        ? `add $${amount} to my LLM credits`\n        : `add $${amount} to my LLM credits using ${token}`;\n\n      const result = await bankrPromptAndPoll(prompt, { timeoutMs: 60_000 });\n\n      if (result.status === 'failed') {\n        const error = result.error ?? 'Unknown error';\n        if (error.includes('insufficient') || error.includes('balance')) {\n          return {\n            text: [\n              `**Top-up failed:** Insufficient ${token} balance`,\n              '',\n              `Your Bankr wallet needs at least $${amount} in ${token} to complete this top-up.`,\n              '',\n              'Check your wallet balance or top up via the web: https://bankr.bot/llm?tab=credits',\n            ].join('\\n'),\n          };\n        }\n        return { text: `**Top-up failed:** ${error}` };\n      }\n\n      return {\n        text: [\n          `**Credits topped up: +$${amount}**`,\n          '',\n          result.response ?? `$${amount} added to your LLM credits from ${token}.`,\n          '',\n          'Check balance: /llmcredits',\n        ].join('\\n'),\n      };\n    } catch (err) {\n      const msg = err instanceof Error ? err.message : String(err);\n      if (msg.includes('Agent API not enabled') || msg.includes('403')) {\n        return { text: 'Agent API not enabled on this key. Enable at: https://bankr.bot/api' };\n      }\n      return { text: `**Top-up failed:** ${msg}\\n\\nTry the web dashboard: https://bankr.bot/llm?tab=credits` };\n    }\n  },\n};\n\n// ── /autotopup ──────────────────────────────────────────────────────────────\n\nexport const autotopupCommand = {\n  name: 'autotopup',\n  description: 'View or configure automatic LLM credit top-up',\n  acceptsArgs: true,\n  requireAuth: true,\n  handler: async (ctx: any) => {\n    if (!isBankrProvider()) {\n      return { text: 'Bankr LLM Gateway is not configured. Run /llmcredits for setup instructions.' };\n    }\n\n    const rawArgs = (ctx?.args ?? ctx?.text ?? '').trim();\n    const argStr = rawArgs.replace(/^\\/autotopup\\s*/, '').trim();\n    const parts = argStr.split(/\\s+/);\n    const subcommand = (parts[0] ?? '').toLowerCase();\n\n    // ── No args: show current config ──\n    if (!subcommand) {\n      // Try the LLM gateway first for structured data\n      const key = getBankrKey();\n      if (key) {\n        const config = await fetchAutoTopupConfig(key);\n        if (config) {\n          if (config.enabled) {\n            return {\n              text: [\n                '**Auto Top-up: ON**',\n                '',\n                `  Amount: $${config.amount ?? '?'}`,\n                `  Threshold: $${config.threshold ?? '?'} (tops up when balance drops below this)`,\n                `  Token: ${config.tokens?.join(', ') ?? 'USDC'}`,\n                '',\n                '**Manage:**',\n                '  `/autotopup disable` — Turn off auto top-up',\n                '  `/autotopup enable 25 5 USDC` — Set: $25 when below $5, pay with USDC',\n              ].join('\\n'),\n            };\n          }\n          return {\n            text: [\n              '**Auto Top-up: OFF**',\n              '',\n              'Your credits will not be automatically replenished.',\n              '',\n              '**Enable:**',\n              '  `/autotopup enable` — Enable with defaults ($25 when below $5, USDC)',\n              '  `/autotopup enable 50 10 ETH` — $50 when below $10, pay with ETH',\n              '',\n              'Or configure at: https://bankr.bot/llm',\n            ].join('\\n'),\n          };\n        }\n      }\n\n      // Fallback: try agent API\n      const apiKey = getCredentialVault().getSecret('bankr.apiKey', 'bankr-commands');\n      if (apiKey) {\n        try {\n          const { bankrPromptAndPoll } = await import('../services/bankr-api.js');\n          const result = await bankrPromptAndPoll('show my LLM auto top-up configuration', { timeoutMs: 30_000 });\n          if (result.status !== 'failed' && result.response) {\n            return { text: result.response };\n          }\n        } catch { /* fall through */ }\n      }\n\n      return {\n        text: [\n          '**Auto Top-up**',\n          '',\n          'Could not fetch current config. Manage at: https://bankr.bot/llm',\n          '',\n          '**Commands:**',\n          '  `/autotopup enable` — Enable with defaults',\n          '  `/autotopup enable 25 5 USDC` — $25 when below $5, pay USDC',\n          '  `/autotopup disable` — Turn off',\n        ].join('\\n'),\n      };\n    }\n\n    // ── Enable / Disable: route through Agent API ──\n    const apiKey = getCredentialVault().getSecret('bankr.apiKey', 'bankr-commands');\n    if (!apiKey) {\n      return {\n        text: [\n          '**Bankr Agent API required**',\n          '',\n          'Configuring auto top-up requires the Agent API.',\n          '1. Get a key at: https://bankr.bot/api',\n          '2. `/flykeys set BANKR_API_KEY bk_your_key`',\n          '3. /flyrestart',\n          '',\n          'Or configure at: https://bankr.bot/llm',\n        ].join('\\n'),\n      };\n    }\n\n    if (subcommand === 'disable' || subcommand === 'off') {\n      try {\n        const { bankrPromptAndPoll } = await import('../services/bankr-api.js');\n        const result = await bankrPromptAndPoll('disable my LLM auto top-up', { timeoutMs: 30_000 });\n        if (result.status === 'failed') {\n          return { text: `**Failed:** ${result.error ?? 'Unknown error'}\\n\\nTry: https://bankr.bot/llm` };\n        }\n        return {\n          text: [\n            '**Auto top-up disabled.**',\n            '',\n            result.response ?? 'Your LLM credits will no longer be automatically replenished.',\n            '',\n            'Re-enable anytime: `/autotopup enable`',\n          ].join('\\n'),\n        };\n      } catch (err) {\n        return { text: `**Failed:** ${err instanceof Error ? err.message : String(err)}\\n\\nTry: https://bankr.bot/llm` };\n      }\n    }\n\n    if (subcommand === 'enable' || subcommand === 'on') {\n      // Parse optional: /autotopup enable [amount] [threshold] [token]\n      const amount = parseFloat(parts[1] ?? '') || 25;\n      const threshold = parseFloat(parts[2] ?? '') || 5;\n      const token = parts[3] ?? 'USDC';\n\n      try {\n        const { bankrPromptAndPoll } = await import('../services/bankr-api.js');\n        const prompt = `enable LLM auto top-up: add $${amount} ${token} when my LLM credits drop below $${threshold}`;\n        const result = await bankrPromptAndPoll(prompt, { timeoutMs: 30_000 });\n        if (result.status === 'failed') {\n          return { text: `**Failed:** ${result.error ?? 'Unknown error'}\\n\\nTry: https://bankr.bot/llm` };\n        }\n        return {\n          text: [\n            '**Auto top-up enabled!**',\n            '',\n            result.response ?? `Will add $${amount} in ${token} when credits drop below $${threshold}.`,\n            '',\n            'View config: /autotopup',\n            'Disable: `/autotopup disable`',\n          ].join('\\n'),\n        };\n      } catch (err) {\n        return { text: `**Failed:** ${err instanceof Error ? err.message : String(err)}\\n\\nTry: https://bankr.bot/llm` };\n      }\n    }\n\n    return {\n      text: [\n        '**Usage:** `/autotopup [enable|disable] [amount] [threshold] [token]`',\n        '',\n        '**Examples:**',\n        '  `/autotopup` — Show current config',\n        '  `/autotopup enable` — Enable with defaults ($25 when below $5, USDC)',\n        '  `/autotopup enable 50 10 ETH` — $50 when below $10, pay with ETH',\n        '  `/autotopup disable` — Turn off auto top-up',\n      ].join('\\n'),\n    };\n  },\n};\n\n// ── /automations ────────────────────────────────────────────────────────────\n\nexport const automationsCommand = {\n  name: 'automations',\n  description: 'List your active Bankr automations (limit orders, DCA, etc.)',\n  acceptsArgs: false,\n  requireAuth: true,\n  handler: async (_ctx: any) => {\n    const apiKey = getCredentialVault().getSecret('bankr.apiKey', 'bankr-commands');\n    if (!apiKey) {\n      return {\n        text: [\n          '**Bankr Agent API not configured**',\n          '',\n          'Automations require a Bankr API key with Agent API enabled.',\n          '',\n          '1. Get a key at: https://bankr.bot/api',\n          '2. Enable \"Agent API\"',\n          '3. `/flykeys set BANKR_API_KEY bk_your_key`',\n          '4. /flyrestart then /connect_bankr',\n        ].join('\\n'),\n      };\n    }\n\n    try {\n      const { bankrPromptAndPoll } = await import('../services/bankr-api.js');\n      const result = await bankrPromptAndPoll('show my active automations', { timeoutMs: 30_000 });\n\n      if (result.status === 'failed') {\n        return { text: `Failed to fetch automations: ${result.error ?? 'Unknown error'}` };\n      }\n\n      return { text: result.response ?? 'No active automations found.' };\n    } catch (err) {\n      const msg = err instanceof Error ? err.message : String(err);\n      if (msg.includes('Agent API not enabled') || msg.includes('403')) {\n        return {\n          text: 'Agent API not enabled on this key. Enable at: https://bankr.bot/api',\n        };\n      }\n      return { text: `Failed to fetch automations: ${msg}` };\n    }\n  },\n};\n"],"mappings":"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"}