import type { DuniterAdapter, MonetaryData } from './types'; const BMA_URL = 'https://g1.duniter.org'; async function bmaGet(path: string): Promise { const res = await fetch(`${BMA_URL}${path}`); if (!res.ok) throw new Error(`BMA ${path}: ${res.status}`); return res.json(); } const joinBlockCache = new Map(); export const v1Adapter: DuniterAdapter = { async fetchMonetary(): Promise { const [current, udBlocks] = await Promise.all([ bmaGet<{ monetaryMass: number; membersCount: number; number: number; medianTime: number; }>('/blockchain/current'), bmaGet<{ result: { blocks: number[] } }>('/blockchain/with/ud'), ]); const udBlockNumbers = udBlocks.result.blocks; const lastUdBlock = udBlockNumbers[udBlockNumbers.length - 1]; const udBlock = await bmaGet<{ dividend: number }>(`/blockchain/block/${lastUdBlock}`); return { monetaryMass: String(current.monetaryMass), membersCount: current.membersCount, amount: String(udBlock.dividend), timestamp: new Date(current.medianTime * 1000).toISOString(), blockNumber: current.number, udBlockNumbers, }; }, async fetchMemberPubkeys(): Promise { const data = await bmaGet<{ results: { pubkey: string }[] }>('/wot/members'); return data.results.map((m) => m.pubkey); }, async fetchMemberJoinBlocks(pubkeys: string[]): Promise> { const result = new Map(); const toFetch: string[] = []; for (const pk of pubkeys) { const cached = joinBlockCache.get(pk); if (cached !== undefined) { result.set(pk, cached); } else { toFetch.push(pk); } } const CONCURRENT = 10; for (let i = 0; i < toFetch.length; i += CONCURRENT) { const batch = toFetch.slice(i, i + CONCURRENT); await Promise.all( batch.map(async (pk) => { try { const data = await bmaGet<{ results: { uids: { meta: { timestamp: string } }[] }[]; }>(`/wot/lookup/${encodeURIComponent(pk)}`); const ts = data.results?.[0]?.uids?.[0]?.meta?.timestamp; if (ts) { const blockNum = parseInt(ts.split('-')[0], 10); if (!isNaN(blockNum)) { joinBlockCache.set(pk, blockNum); result.set(pk, blockNum); } } } catch { // Skip members we can't look up } }) ); } return result; }, };