import { importPKCS8, SignJWT } from "jose"; const ARC_API_BASE_URL = process.env.ARC_API_BASE_URL; const ARC_JWT_PRIVATE_KEY = process.env.ARC_JWT_PRIVATE_KEY; let cachedKey: CryptoKey | null = null; async function getSigningKey(): Promise { if (cachedKey) return cachedKey; if (!ARC_JWT_PRIVATE_KEY) { throw new Error("ARC_JWT_PRIVATE_KEY environment variable is not set"); } cachedKey = await importPKCS8(ARC_JWT_PRIVATE_KEY, "EdDSA"); return cachedKey; } async function signToken(): Promise { const key = await getSigningKey(); return new SignJWT({ iss: "arc-web" }) .setProtectedHeader({ alg: "EdDSA" }) .setIssuedAt() .setExpirationTime("30s") .sign(key); } /** * Fetch wrapper that signs requests with a JWT for service-to-service auth. */ export async function apiFetch( path: string, init?: RequestInit ): Promise { if (!ARC_API_BASE_URL) { throw new Error("ARC_API_BASE_URL environment variable is not set"); } const headers = new Headers(init?.headers); if (ARC_JWT_PRIVATE_KEY) { const token = await signToken(); headers.set("Authorization", `Bearer ${token}`); } return fetch(`${ARC_API_BASE_URL}${path}`, { ...init, headers, }); } /** * Typed JSON fetch helper. Calls apiFetch and parses the JSON response. */ export async function apiJson(path: string, init?: RequestInit): Promise { const res = await apiFetch(path, init); if (!res.ok) throw new Response(await res.text(), { status: res.status }); return res.json() as Promise; }