Zero dependencies, no account, no API. Every command takes --rpc, so it runs against a node you operate and never needs ours. That is the point: an exposure measurement you cannot re-run is an opinion with a logo on it. Ships with two self-checks meant to be run by you, not just by us. The second, proba-vocabular.mjs, exists because of a real defect found on 2026-08-16: the scanner emits RED / YELLOW / GREEN, two downstream files each wrote their own copy of that list, and both wrote AMBER, so a hybrid contract, exactly a client who has already started migrating, was reported as unmeasurable. Both sides were self-consistent, so nothing we had could see it. The vocabulary now has one exported source, and the test walks the whole path with a negative control that makes it able to fail. The same scanner returns RED about our own contracts. See VERIFY-US.md.
85 lines
3.1 KiB
JavaScript
85 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// plan.js, migration-plan CLI. Demonstrates the migration SDK (lib/migrate.js):
|
|
// derive a counterfactual PQC account address and print a step-by-step,
|
|
// honestly-caveated migration plan. Signs and broadcasts NOTHING.
|
|
//
|
|
// node plan.js demo (uses the sample Falcon key)
|
|
// node plan.js --mode pqc --falcon 0x09.. --salt 0
|
|
// node plan.js --mode hybrid --falcon 0x09.. --ecdsa 0xYourEoa
|
|
// node plan.js --json
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { dirname, join } from 'node:path';
|
|
import { buildMigrationPlan, predictPqcAccountAddress, ADDRESSES } from './lib/migrate.js';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
function loadSampleKey() {
|
|
// The real Falcon-512 public key of the live sample account.
|
|
// [CITED: aerenew/contracts/deployments/pqc-account.json sampleAccount.falconPubKey]
|
|
const p = join(__dirname, '..', 'contracts', 'deployments', 'pqc-account.json');
|
|
return JSON.parse(readFileSync(p, 'utf8')).sampleAccount.falconPubKey;
|
|
}
|
|
|
|
function parseArgs(argv) {
|
|
const a = { mode: 'pqc', salt: 0 };
|
|
for (let i = 0; i < argv.length; i++) {
|
|
const t = argv[i];
|
|
if (t === '--mode') a.mode = argv[++i];
|
|
else if (t === '--falcon') a.falcon = argv[++i];
|
|
else if (t === '--ecdsa') a.ecdsa = argv[++i];
|
|
else if (t === '--salt') a.salt = parseInt(argv[++i], 10);
|
|
else if (t === '--json') a.json = true;
|
|
else if (t === '--help' || t === '-h') a.help = true;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
function main() {
|
|
const args = parseArgs(process.argv.slice(2));
|
|
if (args.help) {
|
|
console.log('node plan.js [--mode pqc|hybrid] [--falcon 0x09..] [--ecdsa 0x..] [--salt N] [--json]');
|
|
return;
|
|
}
|
|
const falcon = args.falcon || loadSampleKey();
|
|
const usingSample = !args.falcon;
|
|
|
|
const plan = buildMigrationPlan({
|
|
mode: args.mode,
|
|
falconPubKey: falcon,
|
|
ecdsaSigner: args.ecdsa,
|
|
salt: args.salt,
|
|
});
|
|
|
|
if (args.json) {
|
|
console.log(JSON.stringify(plan, null, 2));
|
|
return;
|
|
}
|
|
|
|
console.log('');
|
|
console.log(`Aere post-quantum migration plan (mode: ${plan.mode})`);
|
|
if (usingSample) console.log(' (demo: using the live sample account\'s real Falcon-512 key)');
|
|
console.log('');
|
|
if (args.mode === 'pqc') {
|
|
const predicted = predictPqcAccountAddress({ falconPubKey: falcon, salt: args.salt });
|
|
console.log(` factory: ${ADDRESSES.AerePQCAccountFactory.address} (live)`);
|
|
console.log(` derived account: ${predicted}`);
|
|
console.log('');
|
|
}
|
|
for (const step of plan.steps) {
|
|
console.log(` Step ${step.n}. ${step.title}`);
|
|
console.log(` how: ${step.how}`);
|
|
if (step.result) console.log(` result: ${step.result}`);
|
|
if (step.identityId) console.log(` identityId: ${step.identityId}`);
|
|
if (step.calldata) console.log(` calldata: ${step.calldata.slice(0, 42)}... (${(step.calldata.length - 2) / 2} bytes)`);
|
|
if (step.note) console.log(` note: ${step.note}`);
|
|
console.log('');
|
|
}
|
|
console.log(' Honest caveats:');
|
|
for (const c of plan.caveats) console.log(` - ${c}`);
|
|
console.log('');
|
|
}
|
|
|
|
main();
|