"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchTransactionsInBlockRange = fetchTransactionsInBlockRange; function parseItem(item) { if (!item.hash || !item.from?.hash) return null; const ts = Math.floor(new Date(item.timestamp).getTime() / 1000); return { hash: item.hash, from: item.from.hash, to: item.to?.hash ?? '0x0000000000000000000000000000000000000000', value: BigInt(item.value || '0'), blockNumber: item.block_number, blockTimestamp: Number.isFinite(ts) ? ts : 0, }; } /** * Fetch all validated txs with block_number in [fromBlock, toBlock] (inclusive). * Walks newest-first from Blockscout until block_number < fromBlock. */ async function fetchTransactionsInBlockRange(apiBase, fromBlock, toBlock) { const base = apiBase.replace(/\/$/, ''); const out = []; const seen = new Set(); let url = `${base}/transactions?filter=validated`; let pages = 0; const maxPages = parseInt(process.env.CHECKPOINT_BLOCKSCOUT_MAX_PAGES || '5000', 10); const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); while (url && pages < maxPages) { pages++; let res = await fetch(url); for (let attempt = 0; res.status === 429 && attempt < 5; attempt++) { await sleep(2000 * (attempt + 1)); res = await fetch(url); } if (!res.ok) { throw new Error(`Blockscout ${res.status} ${url}`); } await sleep(parseInt(process.env.CHECKPOINT_BLOCKSCOUT_PAGE_DELAY_MS || '80', 10)); const body = (await res.json()); let stop = false; for (const item of body.items ?? []) { const bn = item.block_number; if (bn < fromBlock) { stop = true; break; } if (bn > toBlock) continue; const tx = parseItem(item); if (!tx || seen.has(tx.hash.toLowerCase())) continue; seen.add(tx.hash.toLowerCase()); out.push(tx); } if (stop) break; const next = body.next_page_params; if (!next) break; const q = new URLSearchParams(); for (const [k, v] of Object.entries(next)) { if (v !== null && v !== undefined) q.set(k, String(v)); } url = `${base}/transactions?${q.toString()}`; } out.sort((a, b) => a.blockNumber - b.blockNumber || a.blockTimestamp - b.blockTimestamp); return out; }