#!/usr/bin/env node
/**
 * Adds the 3 Chainlink oracle endpoints to public/.well-known/x402.json:
 *   - /api/x402/oracle/price-feed         ($0.01, GET, Base+Solana USDC)
 *   - /api/x402/oracle/agent-stake-usd    ($0.02, GET, Base+Solana USDC)
 *   - /api/x402/oracle/chainlink-status   (free,  GET)
 *
 * Skips if they're already present (idempotent).
 * Bumps endpointCount and pricedEndpointCount.
 */

import fs from 'node:fs';
import path from 'node:path';

const MANIFEST_PATH = path.resolve('public/.well-known/x402.json');
const m = JSON.parse(fs.readFileSync(MANIFEST_PATH, 'utf8'));

const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const PAY_TO_BASE = '0xfA15Ee28939B222B0448261A22156070f0A7813C';
const SOL_USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const PAY_TO_SOL = '6KpXaFmaR8WPWr79qzsMBvwDbDzYFErwNoWxfwqDr8JU';

const acceptsFor = (priceUsd) => {
  // amount in USDC base units (6 decimals)
  const amount = String(Math.round(priceUsd * 1_000_000));
  return [
    {
      scheme: 'exact',
      network: 'eip155:8453',
      amount,
      asset: BASE_USDC,
      payTo: PAY_TO_BASE,
      maxTimeoutSeconds: 60,
      extra: { name: 'USD Coin', version: '2' },
    },
    {
      scheme: 'exact',
      network: 'solana',
      amount,
      asset: SOL_USDC,
      payTo: PAY_TO_SOL,
      maxTimeoutSeconds: 90,
      extra: { name: 'USD Coin', tokenProgram: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', decimals: 6 },
    },
  ];
};

const newEntries = [
  {
    path: '/api/x402/oracle/price-feed',
    method: 'GET',
    description:
      'Read any supported Chainlink Data Feed (ETH/USD, BTC/USD, LINK/USD, USDC/USD, AVAX/USD, MATIC/USD) on Base, Avalanche, Arbitrum, or Polygon. Returns answer, decimals, roundId, updatedAt, and freshness status. Data source: Chainlink decentralized oracle network — Vaultfire reads the on-chain AggregatorV3 proxy and exposes it via x402.',
    price: '$0.01',
    inputSchema: {
      type: 'object',
      properties: {
        pair: {
          type: 'string',
          enum: ['eth-usd', 'btc-usd', 'usdc-usd', 'link-usd', 'avax-usd', 'matic-usd'],
          description: 'Price pair to read',
        },
        chain: {
          type: 'string',
          enum: ['base', 'avalanche', 'arbitrum', 'polygon'],
          description: 'Chain whose Chainlink feed to query (default: base)',
        },
      },
      required: ['pair'],
    },
    outputSchema: {
      type: 'object',
      properties: {
        pair: { type: 'string' },
        chain: { type: 'string' },
        source: { type: 'string', description: 'Always "chainlink"' },
        feedAddress: { type: 'string' },
        explorerUrl: { type: 'string' },
        answer: { type: 'number', description: 'Human-readable price' },
        answerRaw: { type: 'string' },
        decimals: { type: 'number' },
        roundId: { type: 'string' },
        startedAt: { type: 'number' },
        updatedAt: { type: 'number' },
        ageSeconds: { type: 'number' },
        fresh: { type: 'boolean' },
      },
    },
    accepts: acceptsFor(0.01),
  },
  {
    path: '/api/x402/oracle/agent-stake-usd',
    method: 'GET',
    description:
      "USD-denominated agent stake — composes Vaultfire bond data (ETH stake) × Chainlink ETH/USD price feed. Returns stake in USD with full audit trail (bond count, ETH staked, Chainlink price, feed address). Uniquely enabled by the Chainlink integration: Vaultfire owns the agent-truth side, Chainlink owns the market-data side.",
    price: '$0.02',
    inputSchema: {
      type: 'object',
      properties: {
        address: { type: 'string', description: 'Agent wallet address (0x...)' },
        chain: {
          type: 'string',
          enum: ['base', 'avalanche', 'arbitrum', 'polygon'],
          description: 'Chain to query (default: base)',
        },
      },
      required: ['address'],
    },
    outputSchema: {
      type: 'object',
      properties: {
        address: { type: 'string' },
        chain: { type: 'string' },
        bondCount: { type: 'number' },
        stakeEth: { type: 'number' },
        stakeWei: { type: 'string' },
        ethUsdPrice: { type: 'number' },
        stakeUsd: { type: 'number' },
        feedAddress: { type: 'string' },
        feedUpdatedAt: { type: 'number' },
        feedAgeSeconds: { type: 'number' },
        feedFresh: { type: 'boolean' },
      },
    },
    accepts: acceptsFor(0.02),
  },
  {
    path: '/api/x402/oracle/chainlink-status',
    method: 'GET',
    description:
      'Free discovery beacon for the Vaultfire Chainlink oracle namespace — no payment required. Lists every supported (chain, pair) feed with live freshness, attribution to Chainlink, and links to the priced endpoints.',
    price: 'free',
  },
];

const existing = new Set(m.endpoints.map((e) => e.path));
let added = 0;
let pricedAdded = 0;
for (const e of newEntries) {
  if (existing.has(e.path)) {
    console.log('skip (already present):', e.path);
    continue;
  }
  m.endpoints.push(e);
  added++;
  if (e.price !== 'free') pricedAdded++;
}

m.endpointCount = (m.endpointCount || 0) + added;
m.pricedEndpointCount = (m.pricedEndpointCount || 0) + pricedAdded;

fs.writeFileSync(MANIFEST_PATH, JSON.stringify(m, null, 2) + '\n', 'utf8');
console.log(`\nadded ${added} endpoint(s) (${pricedAdded} priced)`);
console.log(`endpointCount: ${m.endpointCount}`);
console.log(`pricedEndpointCount: ${m.pricedEndpointCount}`);
