divhanimajokweni-ctrl's picture
feat: submit ProofBridge Liner to LabLab AI AMD Developer Hackathon
93c7565
const crypto = require("crypto");
const IPFS_GATEWAYS = [
"https://ipfs.io/ipfs/",
"https://cloudflare-ipfs.com/ipfs/",
"https://gateway.pinata.cloud/ipfs/",
"https://dweb.link/ipfs/",
"https://w3s.link/ipfs/"
];
const FETCH_TIMEOUT_MS = 5000;
const BACKOFF_MS = [500, 1000, 2000]; // 0.5s → 1s → 2s
async function fetchWithTimeout(url, timeoutMs) {
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch(url, {
signal: controller.signal,
headers: { "Accept": "application/octet-stream" }
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buf = Buffer.from(await res.arrayBuffer());
return buf;
} finally {
clearTimeout(t);
}
}
function sha256(buffer) {
return crypto.createHash("sha256").update(buffer).digest("hex");
}
async function resolveCID(cid) {
const results = [];
for (const gateway of IPFS_GATEWAYS) {
try {
const data = await fetchWithTimeout(`${gateway}${cid}`, FETCH_TIMEOUT_MS);
results.push({
gateway,
ok: true,
hash: sha256(data),
});
} catch (err) {
results.push({
gateway,
ok: false,
error: err.message,
});
}
}
return results;
}
function evaluateResolution(results, expectedHash) {
const successes = results.filter(r => r.ok);
const failures = results.filter(r => !r.ok);
if (successes.length === 0) {
return { status: "NETWORK_UNAVAILABLE" };
}
const mismatches = successes.filter(r => r.hash !== expectedHash);
if (mismatches.length >= 2) {
return {
status: "HASH_MISMATCH",
evidence: mismatches
};
}
return {
status: "CONSISTENT",
observedHash: successes[0].hash,
failures
};
}
module.exports = {
IPFS_GATEWAYS,
FETCH_TIMEOUT_MS,
BACKOFF_MS,
resolveCID,
evaluateResolution,
sha256
};