// Igneum light client, server half. GET /api/checkpoint returns the latest certified checkpoint with everything a // browser needs to verify it by itself (site/verify/verify.js does the verifying; this function only ships data): // the certificate as carried in a block, the canonical voter list with public keys and weights, and the // selected-chain headers from the previous locked checkpoint to this one. Read from what tools/observer wrote to // Neon (table live_certificates, or fintest_live_certificates for the test network). // // ?source=live Devnet 3 (default: the dn3_ tables, or LIVE_TABLE_PREFIX; falls back to the test network while the chain has no lock yet) // ?source=dn3 the same as live (the Devnet 3 name, for callers that want to say so) // ?source=test the finality test network's tables (fintest_live_certificates) // ?index=N one certified checkpoint by index instead of the newest (the explorer's per-block re-check, 8 October 2026) // // Zero dependencies: Neon's HTTP SQL endpoint over Node's built-in fetch, like live.mjs. const MAX_HEADERS = 200; function neon() { const url = process.env.DATABASE_URL; if (!url) throw new Error('DATABASE_URL is not set'); const host = new URL(url).hostname.replace('-pooler', ''); return async (query, params = []) => { const r = await fetch(`https://${host}/sql`, { method: 'POST', headers: { 'Neon-Connection-String': url, 'Content-Type': 'application/json' }, body: JSON.stringify({ query, params }), }); const j = await r.json(); if (!r.ok) throw new Error(j.message || JSON.stringify(j)); return j.rows || []; }; } const num = v => (v === null || v === undefined ? null : Number(v)); const tablePrefix = () => (process.env.LIVE_TABLE_PREFIX === undefined ? 'dn3_' : process.env.LIVE_TABLE_PREFIX).replace(/[^a-z0-9_]/gi, ''); async function latest(sql, table, index = null) { // A table the observer has not created yet (the live chain before the cut-over) reads as "no certificate" const rows = await (index === null ? sql(`SELECT * FROM ${table} ORDER BY index DESC LIMIT 1`) : sql(`SELECT * FROM ${table} WHERE index = $1 LIMIT 1`, [index])).catch(() => []); return rows[0] || null; } function shape(row, source) { const headers = (row.headers || []).slice(-MAX_HEADERS).map(h => ({ hash: h.hash, version: num(h.version), parents_by_level: h.parentsByLevel || [], hash_merkle_root: h.hashMerkleRoot, accepted_id_merkle_root: h.acceptedIdMerkleRoot, utxo_commitment: h.utxoCommitment, timestamp: String(h.timestamp), bits: num(h.bits), nonce: String(h.nonce), daa_score: String(h.daaScore), blue_work: h.blueWork, blue_score: String(h.blueScore), pruning_point: h.pruningPoint, vote_key_hash: h.voteKeyHash, })); const voters = (row.voters || []).map(v => ({ vote_key_hash: v.key_hash, pubkey_hex: v.pubkey, weight: num(v.weight), participation: num(v.participation) })); return { source, network: row.chain_id, chain_id: row.chain_id, index: num(row.index), hash: row.hash, blue_score: num(row.blue_score), daa_score: num(row.daa_score), certificate: { bytes_hex: row.certificate_hex, voter_count: num(row.voter_count), bitmap_hex: row.bitmap_hex, aggregate_signature_hex: row.signature_hex, aggregator: row.aggregator, aggregator_proof_hex: row.aggregator_proof_hex, carrier: row.carrier, }, voters, voters_at_index: num(row.voters_index), total_weight: num(row.total_weight), active_weight: num(row.active_weight), previous: row.prev_index === null || row.prev_index === undefined ? null : { index: num(row.prev_index), hash: row.prev_hash }, headers, headers_complete: !!row.headers_complete && (row.headers || []).length <= MAX_HEADERS, rule: { quorum_active: '2/3', floor_total: 0.567, floor_total_exact: '17/30', vote_message: 'igneum-vote-v1/ 0x00 index_le64 checkpoint_hash', dst: 'IGNEUM_VOTE_V1_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_', key_hash: 'BLAKE2b-256 keyed IgneumVoteKeyHash over the 48-byte G1 key' }, stored_at: row.created_at, }; } /** The earliest certified Devnet 3 checkpoint whose chain block number is at least `number` (the reference apps' receipt: * the smallest proof that a block is final), from the dn3_ rows; null when no certificate reaches that block yet. * `chainNumberOf(hash)` resolves a checkpoint hash to its chain block number (the exec RPC); rows are tried newest first * until one falls below `number`, so the cost is a few lookups. */ export async function earliestCheckpointAbove(sql, number, chainNumberOf, table = 'dn3_live_certificates') { const rows = await sql(`SELECT index, hash FROM ${table} ORDER BY index DESC LIMIT 400`).catch(() => []); let pick = null; for (const r of rows) { const n = await chainNumberOf(r.hash).catch(() => null); if (n === null) continue; if (n >= number) pick = r; else break; } if (!pick) return null; const full = await sql(`SELECT * FROM ${table} WHERE index = $1 LIMIT 1`, [Number(pick.index)]); return full[0] ? shape(full[0], 'dn3') : null; } /** The latest certified checkpoint of `want` ('live', 'test' or 'dn3') through `sql`, shaped for the verifier, or null * (the reference apps' read service calls this off Vercel: 'dn3' names the dn3_ tables whatever LIVE_TABLE_PREFIX says). */ export async function readCheckpoint(sql, want = 'live') { let row = null, source = null; if (want === 'dn3') { row = await latest(sql, 'dn3_live_certificates'); if (row) source = 'dn3'; } if (!row && want !== 'test' && want !== 'dn3') { row = await latest(sql, `${tablePrefix()}live_certificates`); if (row) source = 'live'; } if (!row && want !== 'dn3') { row = await latest(sql, 'fintest_live_certificates'); if (row) source = 'test'; } return row ? shape(row, source) : null; } export { neon }; export default async function handler(req, res) { res.setHeader('Cache-Control', 'public, max-age=5'); res.setHeader('Access-Control-Allow-Origin', '*'); if (req.method !== 'GET') { res.setHeader('Allow', 'GET'); return res.status(405).json({ ok: false, error: 'method not allowed' }); } try { const sql = neon(); const want = String((req.query && req.query.source) || 'live'); const idx = req.query && req.query.index !== undefined && /^\d{1,12}$/.test(String(req.query.index)) ? Number(req.query.index) : null; let row = null, source = null; if (want !== 'test') { row = await latest(sql, `${tablePrefix()}live_certificates`, idx); if (row) source = 'live'; } if (!row && idx === null) { row = await latest(sql, 'fintest_live_certificates'); if (row) source = 'test'; } if (!row) { res.setHeader('Cache-Control', 'no-store'); return res.status(404).json({ ok: false, error: 'no certified checkpoint stored yet' }); } return res.status(200).json({ ok: true, now: new Date().toISOString(), ...cp }); } catch (e) { res.setHeader('Cache-Control', 'no-store'); return res.status(500).json({ ok: false, error: String(e.message || e) }); } }