import type { WalletPortfolio } from './governance.js'; const ZERION_API_KEY = process.env.ZERION_API_KEY ?? ''; const ZERION_BASE = 'https://api.zerion.io/v1'; export async function getWalletPortfolio(address: string): Promise { if (!address) return null; // Zerion API uses HTTP Basic Auth with API key as username const authHeader = ZERION_API_KEY ? `Basic ${Buffer.from(`${ZERION_API_KEY}:`).toString('base64')}` : ''; try { const res = await fetch(`${ZERION_BASE}/wallets/${address}/portfolio?currency=usd`, { headers: authHeader ? { 'Authorization': authHeader, 'Accept': 'application/json', } : { 'Accept': 'application/json' }, signal: AbortSignal.timeout(5000), }); if (!res.ok) { console.log(`[Zerion] Portfolio fetch failed: ${res.status}`); return null; } const data = await res.json() as any; const totalValue = data.data?.attributes?.total?.positions ?? 0; // Get token positions const tokensRes = await fetch(`${ZERION_BASE}/wallets/${address}/positions?filter[chain_ids]=base¤cy=usd`, { headers: authHeader ? { 'Authorization': authHeader, 'Accept': 'application/json', } : { 'Accept': 'application/json' }, signal: AbortSignal.timeout(5000), }); const tokens: WalletPortfolio['tokens'] = []; if (tokensRes.ok) { const tokensData = await tokensRes.json() as any; for (const pos of (tokensData.data ?? []).slice(0, 10)) { const attrs = pos.attributes; tokens.push({ symbol: attrs?.fungible_info?.symbol ?? '???', balance: String(attrs?.quantity?.float ?? '0'), valueUsd: attrs?.value ?? 0, }); } } return { totalValueUsd: totalValue, tokens }; } catch (err) { console.log(`[Zerion] Error: ${err}`); return null; } }