#!/usr/bin/env node // proba-plata-fara-verificator.mjs (2026-10-27, R9-S10): the testnet flow (proba-plata-28001.mjs) refuses BEFORE it reads or sends anything // when the AIP-23 reference verifier it needs is not usable. No key is used and nothing is sent: the flow is pointed at a local JSON-RPC stub // that counts every request (127.0.0.1), with a key file that exists and holds no key. Until this date the flow checked only the key and // ethers, sent its payments and came out red afterwards, on the verifier's rows; a public clone does not hold the verifier at the default path. // F1 no verifier at the path given -> exit 2, NEMASURAT 'no reference verifier', 0 requests to the chain // F2 the verifier alone, without the files it imports -> exit 2, NEMASURAT 'has no verify-anchor.mjs beside it', 0 requests // F3 the verifier with its files, but it does not start -> exit 2, NEMASURAT 'does not start', 0 requests // F4 (positive control of this harness) a verifier that starts and judges offline -> the flow goes on to the chain: at least one // request reaches the stub (which answers chain 2800, so the flow stops there: 'only testnet 28001'), and no transaction is sent // F1, F2 and F3 are red on the form before 2026-10-27: AERE_PROBA_PLATA_CLI= runs this on it. // node proba-plata-fara-verificator.mjs -> 0 every row as named, 1 otherwise, 2 the harness itself did not run import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import http from 'node:http'; import { spawn } from 'node:child_process'; import { createRequire } from 'node:module'; import { fileURLToPath } from 'node:url'; const AICI = path.dirname(fileURLToPath(import.meta.url)); const CLI = process.env.AERE_PROBA_PLATA_CLI ? path.resolve(process.env.AERE_PROBA_PLATA_CLI) : path.join(AICI, 'proba-plata-28001.mjs'); const ETHERS = process.env.AERE_ETHERS_DIR || path.resolve(AICI, '..', '..', 'contracts'); // 2026-10-27: the flow F4 starts needs ethers, and the default path exists only in the development tree; a fresh public clone has no // ethers there, so F4 started nothing and the harness said STRICAT with a reason that named a package.json. It now says what is missing. try { createRequire(path.join(ETHERS, 'package.json'))('ethers'); } catch { console.log(`STRICAT: ethers is not loadable from ${ETHERS}; the positive control F4 starts the real flow, which needs it: set AERE_ETHERS_DIR to a directory with node_modules/ethers (for example after npm install ethers@6 there)`); process.exit(2); } const D = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-plata-fara-vp-')); const KF = path.join(D, 'cheie.key'); fs.writeFileSync(KF, 'no key here\n'); // verifiers: alone (F2), beside its files but not starting (F3), beside its files and judging offline (F4) const singur = path.join(D, 'singur'), mort = path.join(D, 'mort'), bun = path.join(D, 'bun'); for (const d of [singur, mort, bun]) fs.mkdirSync(d); fs.writeFileSync(path.join(singur, 'verify-proof.mjs'), "console.log(JSON.stringify({ verdict: 'VALID', levels: [] }));\n"); for (const d of [mort, bun]) for (const x of ['verify-anchor.mjs', 'mpt.mjs', 'falcon512.mjs', 'registry-v3.mjs']) fs.writeFileSync(path.join(d, x), '// beside it\n'); fs.writeFileSync(path.join(mort, 'verify-proof.mjs'), "import '@noble/pachet-care-nu-exista-r9';\n"); fs.writeFileSync(path.join(bun, 'verify-proof.mjs'), "if (!process.argv.includes('--offline')) process.exitCode = 2;\nconsole.log(JSON.stringify({ verdict: process.argv.includes('--offline') ? 'VALID' : 'PARTIAL', levels: [] }));\n"); let cereri = []; const srv = http.createServer((q, s) => { let b = ''; q.on('data', (d) => { b += d; }); q.on('end', () => { let j = {}; try { j = JSON.parse(b); } catch { /* */ } for (const x of (Array.isArray(j) ? j : [j])) cereri.push(x.method); const raspunde = (x) => ({ jsonrpc: '2.0', id: x.id ?? 1, result: x.method === 'eth_chainId' ? '0xaf0' : x.method === 'net_version' ? '2800' : null }); s.writeHead(200, { 'content-type': 'application/json' }); s.end(JSON.stringify(Array.isArray(j) ? j.map(raspunde) : raspunde(j))); }); }); await new Promise((ok) => srv.listen(0, '127.0.0.1', ok)); const RPC = `http://127.0.0.1:${srv.address().port}`; const ruleaza = (vp) => new Promise((ok) => { cereri = []; const p = spawn(process.execPath, [CLI], { cwd: AICI, env: { ...process.env, AERE_TESTNET_KEY_FILE: KF, AERE_ETHERS_DIR: ETHERS, AERE_TESTNET_RPC: RPC, AERE_VERIFY_PROOF: vp }, stdio: ['ignore', 'pipe', 'pipe'] }); let out = ''; p.stdout.on('data', (d) => { out += d; }); p.stderr.on('data', (d) => { out += d; }); const t = setTimeout(() => p.kill(), 120000); p.on('close', (cod) => { clearTimeout(t); ok({ cod, out, cereri: [...cereri] }); }); }); let rele = 0, n = 0, stricat = null; const cer = (nume, r, cod, re, nCereri) => { n++; const trimise = r.cereri.filter((m) => /^eth_send/.test(m)).length; const ok = r.cod === cod && re.test(r.out) && trimise === 0 && (nCereri === 0 ? r.cereri.length === 0 : r.cereri.length >= nCereri); console.log(` [${ok ? 'VERDE ' : 'ROSU '}] ${nume}: exit ${r.cod}, ${r.cereri.length} request(s) to the chain (${trimise} sending), "${r.out.trim().split('\n').pop().slice(0, 150)}"`); if (!ok) rele++; }; try { const r4 = await ruleaza(path.join(bun, 'verify-proof.mjs')); if (!r4.cereri.length) stricat = 'the positive control F4 reached no request to the stub (the flow did not start, or did not read the chain): ' + r4.out.trim().split('\n').pop().slice(0, 200); else { cer('F1 no reference verifier at the path given: NEMASURAT before anything is read or sent', await ruleaza(path.join(D, 'lipsa', 'verify-proof.mjs')), 2, /NEMASURAT: no reference verifier at/, 0); cer('F2 the verifier alone, without the files it imports: NEMASURAT before anything is read or sent', await ruleaza(path.join(singur, 'verify-proof.mjs')), 2, /NEMASURAT: the reference verifier at .* has no verify-anchor\.mjs beside it/, 0); cer('F3 the verifier does not start (an import that does not resolve): NEMASURAT before anything is read or sent', await ruleaza(path.join(mort, 'verify-proof.mjs')), 2, /NEMASURAT: the reference verifier at .* does not start/, 0); cer('F4 (positive control) a verifier that starts: the flow reads the chain (the stub answers 2800 and it stops there), nothing sent', r4, 2, /only testnet 28001/, 1); } } finally { await new Promise((ok) => srv.close(ok)); fs.rmSync(D, { recursive: true, force: true }); } if (stricat) { console.log('STRICAT: ' + stricat); process.exitCode = 2; } else { console.log(`\nthe testnet flow without a usable verifier (${path.basename(CLI)}): ${n - rele}/${n} as named`); process.exitCode = rele ? 1 : 0; }