import { webEnv } from './env'; const API_URL = webEnv.apiUrl; const BITOK_BASE = process.env.NEXT_PUBLIC_BITOK_URL || 'http://localhost:8000'; let accessToken: string | null = null; export function setAccessToken(token: string | null) { accessToken = token; } export function getAccessToken() { return accessToken; } // ── BITOK auth calls (httpOnly cookies + access_token in body) ── async function bitokRequest(path: string, options: RequestInit = {}): Promise { const headers: Record = { 'Content-Type': 'application/json', ...(options.headers as Record), }; const res = await fetch(`${BITOK_BASE}${path}`, { ...options, headers, credentials: 'include', }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.detail || body.error || `Request failed (${res.status})`); } return res.json(); } export const bitokAuth = { registrationStart: (email: string) => bitokRequest<{ success: boolean }>('/v1/auth/registration/start', { method: 'POST', body: JSON.stringify({ email }), }), registrationComplete: (email: string, password: string, code: string) => bitokRequest<{ id: string; email: string; access_token: string }>('/v1/auth/registration/complete', { method: 'POST', body: JSON.stringify({ email, password, code }), }), loginStart: (email: string) => bitokRequest<{ success: boolean }>('/v1/auth/login/start', { method: 'POST', body: JSON.stringify({ email }), }), loginComplete: (email: string, password: string, code: string) => bitokRequest<{ id: string; email: string; access_token: string }>('/v1/auth/login/complete', { method: 'POST', body: JSON.stringify({ email, password, code }), }), refresh: () => bitokRequest<{ result: boolean; access_token: string }>('/v1/jwt/refresh', { method: 'POST' }), logout: () => bitokRequest<{ ok: boolean }>('/v1/auth/logout', { method: 'POST' }), }; // ── Wallet API calls (uses Bearer token from BITOK) ── async function walletRequest(path: string, options: RequestInit = {}): Promise { const headers: Record = { 'Content-Type': 'application/json', ...(options.headers as Record), }; if (accessToken) { headers['Authorization'] = `Bearer ${accessToken}`; } const res = await fetch(`${API_URL}${path}`, { ...options, headers, credentials: 'include', }); const data = await res.json(); if (!data.success) { throw new Error(data.error || 'Request failed'); } return data.data; } export interface WalletSetupPayload { encryptedVault: string; vaultSalt: string; wallets: { chain: string; address: string; derivationPath: string }[]; } export interface WalletUnlockResponse { encryptedVault: string; vaultSalt: string; wallets: { chain: string; address: string; derivationPath: string }[]; mnemonicShown: boolean; } export const walletApi = { setup: (data: WalletSetupPayload) => walletRequest('/api/wallet/setup', { method: 'POST', body: JSON.stringify(data), }), unlock: () => walletRequest('/api/wallet/unlock'), getWallets: () => walletRequest('/api/wallets'), confirmMnemonic: () => walletRequest('/api/wallet/confirm-mnemonic', { method: 'POST' }), }; // ── Legacy api object (keep for components that still reference it) ── export const api = { getWallets: () => walletRequest('/api/wallets'), getVault: () => walletRequest('/api/vault'), confirmMnemonic: () => walletRequest('/api/wallet/confirm-mnemonic', { method: 'POST' }), };