#!/usr/bin/env node 'use strict'; /* * scan-gratuit.mjs - the free scan, produced as the reply a prospect actually receives. * * WHY THIS EXISTS. The paid report is worth 149 EUR because it is reproducible. The free scan has * to earn the reply, not just tease it: it must tell the reader something true and useful about * THEIR address, in language they can forward to their boss, and it must be honest about what it * did not measure. A free scan that hides the finding behind a paywall teaches the reader that we * hide things, which is the opposite of what we are selling. * * So this prints a short, plain answer, plus the exact command they can run themselves. If they * never pay us, they still got something real, and they can check that we did not lie. * * node scan-gratuit.mjs 0xAddr --rpc https://rpc.aere.network * node scan-gratuit.mjs 0xAddr --rpc URL --email # formatted as an email reply */ import { execFileSync } from 'node:child_process'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { citesteVerdict } from './lib/bytecode.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const argv = process.argv.slice(2); const arg = (n, d) => { const i = argv.indexOf(n); return i >= 0 && i + 1 < argv.length ? argv[i + 1] : d; }; const ADRESA = argv.find((a) => /^0x[0-9a-fA-F]{40}$/.test(a)); const RPC = arg('--rpc', 'https://rpc.aere.network'); const EMAIL = argv.includes('--email'); if (!ADRESA) { console.error('folosire: node scan-gratuit.mjs 0xAdresa [--rpc URL] [--email]'); process.exitCode = 2; } else { let text = ''; try { text = execFileSync(process.execPath, ['scan.js', ADRESA, '--rpc', RPC], { cwd: __dirname, encoding: 'utf8', timeout: 120000 }).trim(); } catch (e) { text = String((e.stdout || '') + (e.stderr || e.message)).trim(); } // Verdictul vine din functia comuna din lib/bytecode.js. Un tipar scris aici ar fi a doua sursa // a aceluiasi adevar, si exact asa a ajuns un contract hibrid, adica clientul care a inceput deja // migrarea, sa primeasca "nu am putut masura adresa". const stare = citesteVerdict(text); const cod = (text.match(/code:\s*(\d+)\s*bytes/) || [])[1] || null; const verif = [...text.matchAll(/^\s*-\s*(0x[0-9a-f]+)\s+(.+?)\s*(\[[a-z]+\])?$/gim)].map((m) => m[2].trim()); const deschise = [...text.matchAll(/^\s*\*\s*(\[(?:VERIFY|MEASURE)\][^\n]*)/gim)].map((m) => m[1].trim()); // The one sentence that has to be true and has to be useful. let verdict; if (!stare) verdict = 'We could not measure this address from the endpoint we used. That is a result about our reach, not about your contract, and we are not going to dress it up as a finding.'; else if (!cod || cod === '0') verdict = 'This address holds no contract code, so there is nothing on chain to migrate here. Whatever authorises it is an ordinary account key, and account keys are the harder half of the problem.'; else if (verif.length) { // The scanner finds the verifier ADDRESSES in the bytecode. Whether the contract actually // CALLS them is a separate question the scanner often cannot settle from bytecode alone, and // it says so in its own [VERIFY] note. Claiming "can reach" in the sales hook when the tool // itself refused to settle it would be selling a maybe as a yes, in the first sentence a // prospect reads. So the wording follows the measurement, and the caveat travels with it. const nesigur = deschise.some((d) => /no CALL to it was resolved|may be staged/i.test(d)); verdict = 'The bytecode of this contract references ' + verif.length + ' live post-quantum verifier' + (verif.length === 1 ? '' : 's') + ' (' + verif.slice(0, 3).join(', ') + (verif.length > 3 ? ', and more' : '') + '). ' + (nesigur ? 'We could NOT confirm from bytecode alone that it calls them: the addresses are pushed, but the call target may be assembled at runtime. So this is a promising sign, not a proven capability, and settling it needs the source or a call trace.' : 'The calls to them resolved from the bytecode, so the verification half of a migration is already reachable in this contract.'); } else verdict = 'This contract reaches no post-quantum verifier. Everything it authorises today rests on ECDSA secp256k1, which is exactly the primitive the published migration timelines are about. That is the normal situation in 2026, not a criticism.'; const linii = []; if (EMAIL) linii.push('Subject: Free quantum exposure scan for ' + ADRESA.slice(0, 10) + '...', ''); linii.push('AERE free quantum exposure scan'); linii.push('address : ' + ADRESA); linii.push('measured: ' + new Date().toISOString().slice(0, 16).replace('T', ' ') + 'Z, chain 2800, read from ' + RPC); linii.push(''); linii.push('WHAT WE FOUND'); linii.push(' ' + verdict); if (stare) linii.push(' Verdict from the scanner: ' + stare + (cod ? ', ' + cod + ' bytes of code' : '')); linii.push(''); if (deschise.length) { linii.push('WHAT WE COULD NOT SETTLE, carried through word for word'); for (const d of deschise) linii.push(' - ' + d); linii.push(' These are the questions the tool refuses to answer from bytecode alone. A tool that'); linii.push(' never says this is not being careful, it is being quiet.'); linii.push(''); } linii.push('CHECK US, DO NOT TRUST US'); linii.push(' git clone the toolkit and run the same thing against a node you operate:'); linii.push(' node scan.js ' + ADRESA + ' --rpc https://your-own-node'); linii.push(' If your number differs from ours, that difference is the interesting part and we'); linii.push(' want to hear about it.'); linii.push(''); linii.push('WHAT THE PAID REPORT ADDS, so you can decide honestly'); linii.push(' - every address in your estate, not one, with the same treatment'); linii.push(' - the answers written against the published criteria (NIST IR 8547, CNSA 2.0), in the'); linii.push(' wording a supervisor uses, as criteria and never as a certification'); linii.push(' - a digest manifest, so an edited report is detectable'); linii.push(' - the report digest anchored on chain under a post-quantum validator certificate,'); linii.push(' with a public verifier you run yourself'); linii.push(' 149 EUR, one address portfolio up to 50 for 490. Details: https://aere.network/quantum-exposure-report.html'); linii.push(''); linii.push('WHAT WE ARE NOT'); linii.push(' Not an accredited audit firm, and this is not an audit. We measure the on-chain slice:'); linii.push(' bytecode and what it can reach. Repos, TLS, dependencies and key custody are out of'); linii.push(' scope. A post-quantum verifier called from a transaction authorised with ECDSA gives'); linii.push(' no post-quantum security, and anyone telling you otherwise can be taken apart in five'); linii.push(' minutes. Our own chain has one operator and no external audit yet; we publish that.'); console.log(linii.join('\n')); }