{"version":3,"sources":["../src/management.ts"],"sourcesContent":["// src/management.ts\n// RelAI Management API client — create and manage monetised APIs programmatically.\n// Docs: https://relai.fi/documentation/management-api\n\nconst RELAI_API_BASE = 'https://api.relai.fi';\nconst BOOTSTRAP_URL = `${RELAI_API_BASE}/mcp/management/bootstrap/agent`;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ManagementClientConfig {\n  /** Service key (sk_live_...) for authenticating management API calls */\n  serviceKey: string;\n  /** Override base URL (default: https://api.relai.fi) */\n  baseUrl?: string;\n}\n\nexport interface RelaiApi {\n  apiId: string;\n  name: string;\n  description?: string;\n  baseUrl: string;\n  subdomain?: string | null;\n  network: string;\n  facilitator: string;\n  x402Version: number;\n  status: string;\n  merchantWallet: string;\n  solanaWallet?: string | null;\n  /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n  evmCrossChainWallet?: string | null;\n  websiteUrl?: string;\n  logoUrl?: string;\n  createdAt: string;\n  updatedAt: string;\n}\n\nexport interface ApiEndpointInput {\n  path: string;\n  method: string;\n  usdPrice: number;\n  enabled?: boolean;\n}\n\nexport interface ApiEndpoint extends ApiEndpointInput {\n  network: string;\n  enabled: boolean;\n}\n\nexport interface CreateApiInput {\n  name: string;\n  baseUrl: string;\n  merchantWallet: string;\n  /** Solana wallet for cross-chain payments. Only relevant when network is EVM. */\n  solanaWallet?: string;\n  /** EVM wallet for cross-chain payments. Only relevant when network is Solana. */\n  evmCrossChainWallet?: string;\n  network: string;\n  description?: string;\n  websiteUrl?: string;\n  logoUrl?: string;\n  endpoints?: ApiEndpointInput[];\n}\n\nexport interface UpdateApiInput {\n  name?: string;\n  description?: string;\n  baseUrl?: string;\n  merchantWallet?: string;\n  /** Solana wallet for cross-chain payments. Set to null to remove. */\n  solanaWallet?: string | null;\n  /** EVM wallet for cross-chain payments. Set to null to remove. */\n  evmCrossChainWallet?: string | null;\n  websiteUrl?: string;\n  logoUrl?: string;\n}\n\nexport interface ApiStats {\n  apiId: string;\n  totalRequests: number;\n  totalRevenue: number;\n  currency: string;\n}\n\nexport interface ApiPayment {\n  transaction: string;\n  path: string;\n  method: string;\n  amount: number;\n  currency: string;\n  network: string;\n  status: string;\n  success: boolean;\n  payer: string;\n  createdAt: string;\n}\n\nexport interface ApiPaymentsResult {\n  apiId: string;\n  payments: ApiPayment[];\n  nextCursor: string | null;\n}\n\nexport interface ApiLogItem {\n  id: string;\n  timestamp: string;\n  method: string;\n  path: string;\n  status: string;\n  cost: number;\n  currency: string;\n  duration: number;\n  transaction: string;\n  network: string;\n  success: boolean;\n  payer: string;\n}\n\nexport interface ApiLogsResult {\n  items: ApiLogItem[];\n  nextCursor: string | null;\n}\n\n// ── Bridge types ─────────────────────────────────────────────────────────────\n\nexport interface BridgeQuoteResult {\n  inputAmount: number;\n  outputAmount: number;\n  fee: number;\n  feeBps: number;\n  inputUsd: number;\n  outputUsd: number;\n  direction: 'solana-to-skale' | 'skale-to-solana';\n  from: string;\n  to: string;\n}\n\nexport interface BridgeBalances {\n  solana:   { atomic: number; usd: number };\n  skaleBase: { atomic: number; usd: number };\n  base:      { atomic: number; usd: number };\n}\n\nexport interface BridgeResult {\n  success: boolean;\n  direction: 'solana-to-skale' | 'skale-to-solana';\n  destinationWallet: string;\n  amountOut: number;\n  amountOutUsd: number;\n  txHash: string;\n  explorerUrl: string;\n}\n\nexport interface AgentBootstrapResult {\n  key: string;\n  label: string;\n  active: boolean;\n  createdAt: string;\n}\n\n// ============================================================================\n// Agent bootstrap (autonomous key provisioning)\n// ============================================================================\n\n/**\n * Bootstrap a service key for a Solana agent.\n * Run once — store the returned key securely.\n *\n * @param keypair  A Solana Keypair (from @solana/web3.js)\n * @param label    Human-readable label for the key\n */\nexport async function bootstrapAgentKeySolana(\n  keypair: { publicKey: { toBase58(): string }; secretKey: Uint8Array },\n  label = 'agent',\n): Promise<AgentBootstrapResult> {\n  const { sign } = await import('tweetnacl');\n\n  const publicKey = keypair.publicKey.toBase58();\n\n  // Step 1 — request challenge\n  const challengeRes = await fetch(BOOTSTRAP_URL, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ publicKey }),\n  });\n  if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n  const { message } = await challengeRes.json() as { message: string };\n\n  // Step 2 — sign\n  const msgBytes = new TextEncoder().encode(message);\n  const sigBytes = sign.detached(msgBytes, keypair.secretKey);\n  const signature = Buffer.from(sigBytes).toString('base64');\n\n  // Step 3 — get service key\n  const keyRes = await fetch(BOOTSTRAP_URL, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ publicKey, signature, message, label }),\n  });\n  if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n  return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n/**\n * Bootstrap a service key for an EVM agent.\n * Run once — store the returned key securely.\n *\n * @param wallet  An ethers.js Wallet or Signer with address + signMessage\n * @param label   Human-readable label for the key\n */\nexport async function bootstrapAgentKeyEvm(\n  wallet: { address: string; signMessage(message: string): Promise<string> },\n  label = 'agent',\n): Promise<AgentBootstrapResult> {\n  const publicKey = wallet.address;\n\n  // Step 1 — request challenge\n  const challengeRes = await fetch(BOOTSTRAP_URL, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ publicKey }),\n  });\n  if (!challengeRes.ok) throw new Error(`Challenge request failed: ${challengeRes.status}`);\n  const { message } = await challengeRes.json() as { message: string };\n\n  // Step 2+3 — sign and get key\n  const signature = await wallet.signMessage(message);\n  const keyRes = await fetch(BOOTSTRAP_URL, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({ publicKey, signature, message, label }),\n  });\n  if (!keyRes.ok) throw new Error(`Key provisioning failed: ${keyRes.status}`);\n  return keyRes.json() as Promise<AgentBootstrapResult>;\n}\n\n// ============================================================================\n// Management client\n// ============================================================================\n\nexport interface RelaiManagementClient {\n  // APIs\n  createApi(input: CreateApiInput): Promise<RelaiApi>;\n  listApis(): Promise<RelaiApi[]>;\n  getApi(apiId: string): Promise<RelaiApi>;\n  updateApi(apiId: string, input: UpdateApiInput): Promise<RelaiApi>;\n  deleteApi(apiId: string): Promise<{ success: boolean; apiId: string }>;\n\n  // Pricing\n  getPricing(apiId: string): Promise<{ apiId: string; endpoints: ApiEndpoint[] }>;\n  setPricing(apiId: string, endpoints: ApiEndpointInput[]): Promise<{ success: boolean; apiId: string; updated: number }>;\n\n  // Analytics\n  getStats(apiId: string): Promise<ApiStats>;\n  getPayments(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiPaymentsResult>;\n  getLogs(apiId: string, options?: { limit?: number; from?: string; cursor?: string }): Promise<ApiLogsResult>;\n\n  // Bridge\n  /**\n   * Get a bridge quote — fee and net output for a given USD amount.\n   * @param amount  Amount in USD (e.g. 10.0)\n   * @param from    Source network: 'solana' | 'skale-base' (default: 'solana')\n   */\n  getBridgeQuote(amount: number, from?: 'solana' | 'skale-base'): Promise<BridgeQuoteResult>;\n\n  /**\n   * Get current USDC liquidity on all bridge networks.\n   * Use this before bridging to confirm availability.\n   */\n  getBridgeBalances(): Promise<BridgeBalances>;\n\n  /**\n   * Bridge USDC from Solana to SKALE Base via x402 payment.\n   * This call returns HTTP 402 — pass a createX402Client instance to handle payment automatically.\n   *\n   * @param amount            Amount in USD\n   * @param destinationWallet EVM address on SKALE Base\n   * @param x402Client        A configured createX402Client instance for Solana\n   */\n  bridgeSolanaToSkale(\n    amount: number,\n    destinationWallet: string,\n    x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n  ): Promise<BridgeResult>;\n\n  /**\n   * Bridge USDC from SKALE Base to Solana via x402 payment.\n   *\n   * @param amount            Amount in USD\n   * @param destinationWallet Solana public key (base58)\n   * @param x402Client        A configured createX402Client instance for EVM/SKALE Base\n   */\n  bridgeSkaleToSolana(\n    amount: number,\n    destinationWallet: string,\n    x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n  ): Promise<BridgeResult>;\n}\n\n/**\n * Create a RelAI Management API client.\n *\n * @example\n * ```typescript\n * import { createManagementClient } from '@relai-fi/x402/management';\n *\n * const mgmt = createManagementClient({ serviceKey: process.env.RELAI_SERVICE_KEY! });\n *\n * const api = await mgmt.createApi({\n *   name: 'My ML API',\n *   baseUrl: 'https://inference.example.com',\n *   merchantWallet: '0xYourWallet',\n *   network: 'base',\n *   endpoints: [{ path: '/v1/predict', method: 'post', usdPrice: 0.05 }],\n * });\n * ```\n */\nexport function createManagementClient(config: ManagementClientConfig): RelaiManagementClient {\n  const base = (config.baseUrl ?? RELAI_API_BASE).replace(/\\/$/, '');\n  const headers = {\n    'X-Service-Key': config.serviceKey,\n    'Content-Type': 'application/json',\n  };\n\n  async function req<T>(method: string, path: string, body?: unknown): Promise<T> {\n    const res = await fetch(`${base}${path}`, {\n      method,\n      headers,\n      ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n    });\n    if (!res.ok) {\n      const text = await res.text().catch(() => '');\n      throw new Error(`[relai-mgmt] ${method} ${path} → ${res.status}: ${text}`);\n    }\n    return res.json() as Promise<T>;\n  }\n\n  async function bridgeReq<T>(\n    method: string,\n    path: string,\n    x402Client: { fetch(url: string, init?: RequestInit): Promise<Response> },\n    body?: unknown,\n  ): Promise<T> {\n    const res = await x402Client.fetch(`${base}${path}`, {\n      method,\n      headers: { ...headers, 'Content-Type': 'application/json' },\n      ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n    });\n    if (!res.ok) {\n      const text = await res.text().catch(() => '');\n      let parsed: Record<string, unknown> = {};\n      try { parsed = JSON.parse(text); } catch { /* ignore */ }\n      if (res.status === 503 && parsed['reason'] === 'insufficient_liquidity') {\n        const avail = parsed['available'] as number | undefined;\n        throw new Error(\n          `Bridge temporarily unavailable — insufficient liquidity` +\n          (avail != null ? ` (available: $${Number(avail).toFixed(2)} USDC)` : ''),\n        );\n      }\n      throw new Error(`[relai-bridge] ${method} ${path} → ${res.status}: ${text}`);\n    }\n    return res.json() as Promise<T>;\n  }\n\n  return {\n    // ── APIs ──────────────────────────────────────────────────────────────\n\n    createApi(input) {\n      return req<RelaiApi>('POST', '/v1/apis', input);\n    },\n\n    async listApis() {\n      const data = await req<{ apis: RelaiApi[] }>('GET', '/v1/apis');\n      return data.apis;\n    },\n\n    getApi(apiId) {\n      return req<RelaiApi>('GET', `/v1/apis/${apiId}`);\n    },\n\n    updateApi(apiId, input) {\n      return req<RelaiApi>('PATCH', `/v1/apis/${apiId}`, input);\n    },\n\n    deleteApi(apiId) {\n      return req<{ success: boolean; apiId: string }>('DELETE', `/v1/apis/${apiId}`);\n    },\n\n    // ── Pricing ──────────────────────────────────────────────────────────\n\n    getPricing(apiId) {\n      return req<{ apiId: string; endpoints: ApiEndpoint[] }>('GET', `/v1/apis/${apiId}/pricing`);\n    },\n\n    setPricing(apiId, endpoints) {\n      return req<{ success: boolean; apiId: string; updated: number }>('PUT', `/v1/apis/${apiId}/pricing`, { endpoints });\n    },\n\n    // ── Analytics ────────────────────────────────────────────────────────\n\n    getStats(apiId) {\n      return req<ApiStats>('GET', `/v1/apis/${apiId}/stats`);\n    },\n\n    getPayments(apiId, options = {}) {\n      const params = new URLSearchParams();\n      if (options.limit)  params.set('limit',  String(options.limit));\n      if (options.from)   params.set('from',   options.from);\n      if (options.cursor) params.set('cursor', options.cursor);\n      const qs = params.toString() ? `?${params}` : '';\n      return req<ApiPaymentsResult>('GET', `/v1/apis/${apiId}/payments${qs}`);\n    },\n\n    getLogs(apiId, options = {}) {\n      const params = new URLSearchParams();\n      if (options.limit)  params.set('limit',  String(options.limit));\n      if (options.from)   params.set('from',   options.from);\n      if (options.cursor) params.set('cursor', options.cursor);\n      const qs = params.toString() ? `?${params}` : '';\n      return req<ApiLogsResult>('GET', `/v1/apis/${apiId}/logs${qs}`);\n    },\n\n    // ── Bridge ──────────────────────────────────────────────────\n\n    getBridgeQuote(amount, from = 'solana') {\n      const params = new URLSearchParams({ amount: String(amount), from });\n      return req<BridgeQuoteResult>('GET', `/v1/bridge/quote?${params}`);\n    },\n\n    getBridgeBalances() {\n      return req<BridgeBalances>('GET', '/v1/bridge/balances');\n    },\n\n    async bridgeSolanaToSkale(amount, destinationWallet, x402Client) {\n      return bridgeReq<BridgeResult>(\n        'POST',\n        '/v1/bridge/solana-to-skale',\n        x402Client,\n        { amount, destinationWallet },\n      );\n    },\n\n    async bridgeSkaleToSolana(amount, destinationWallet, x402Client) {\n      return bridgeReq<BridgeResult>(\n        'POST',\n        '/v1/bridge/skale-to-solana',\n        x402Client,\n        { amount, destinationWallet },\n      );\n    },\n  };\n}\n"],"mappings":"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","names":[]}