deviant/scripts/compile-contracts.mjs
walerikus 518a3ce174 chore: initial project baseline — full Deviant codebase under version control
Brings the whole project into git (previously only the on-ramp feature and
a few parallel files were tracked). Includes: wallet core (src/), CashScript
contracts/, the Capacitor shell (shells/), scripts/, tests, and the docs
corpus (wiki/, snapshots/, Parameters/, Archive/, KnowledgeBase text).

Excluded via .gitignore: node_modules/, dist/, .env (secrets), testnet WIF
key files (.chipnet-*.json, devWallets.ts), KnowledgeBase/RAW media (~9.6 GB),
transcripts/ (session logs), and machine-local config (.claude/*.local,
*.lock). Secret-scanned before commit — no credentials in the tree.

Note: src/swapMath.ts, src/swapBuilder.ts, contracts/OpenMintToken.cash are
legacy (OP_RETURN era) but still imported; committed as-is, flagged for a
separate removal once de-referenced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 20:38:07 +02:00

95 lines
3.4 KiB
JavaScript

#!/usr/bin/env node
/**
* compile-contracts.mjs — compiles CashScript sources to artifact JSON.
*
* Uses the cashscript SDK's compileFile. Output goes to contracts/dist/.
* Run after editing any contracts/*.cash source.
*/
import { readdirSync, readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
import { join } from 'node:path';
const ROOT = join(import.meta.dirname, '..');
const SRC = join(ROOT, 'contracts');
const OUT = join(SRC, 'dist');
// The trust-critical D-3 module (src/verify/canonical.ts) imports the canonical
// templates as embedded JSON (so it runs in browsers/WebViews with no fs). Those
// embedded copies MUST NOT drift from the compiled source, so we mirror them here
// on every compile. Keep this list in lockstep with the imports in canonical.ts.
const EMBED = join(ROOT, 'src', 'verify', 'artifacts');
const EMBEDDED = new Set([
'DeviantOpenMintFT.json',
'DeviantManagedMintFT.json',
'DeviantBondingCurveFT.json',
'DeviantEscFeeSupply.json',
'DeviantDescFeeSupply.json',
'OpenTote.json',
'ParimutuelToteOpen.json',
'ParimutuelToteOpenMBA.json',
// Phase G.1 — voting-system canonical templates (snapshot 0127+; §6.15 roadmap).
'CitizenToken.json',
'EndorsementCovenant.json',
'RegistryState.json',
'ApplicationCovenant.json',
'ApplicationCovenantB.json',
'ApplicationCovenantC.json',
'ApplicationCovenantD.json',
'ApplicationCovenantE.json',
'BallotCovenant.json',
'ElderFreezeAction.json',
'ComplaintCovenant.json',
]);
if (!existsSync(OUT)) mkdirSync(OUT, { recursive: true });
if (!existsSync(EMBED)) mkdirSync(EMBED, { recursive: true });
async function main() {
// CashScript 0.12 split the compiler into a separate `cashc` package.
// The SDK package (`cashscript`) is runtime-only and no longer exports
// compileFile.
let compileFile;
try {
({ compileFile } = await import('cashc'));
} catch {
console.error('cashc not installed. Run `npm install` first.');
process.exit(1);
}
const sources = readdirSync(SRC).filter((f) => f.endsWith('.cash'));
if (sources.length === 0) {
console.log('No .cash sources found in contracts/');
return;
}
for (const src of sources) {
const srcPath = join(SRC, src);
// Skip contracts marked SUPERSEDED or EXPECTED-COMPILE-FAIL in their header
// comments. Convention for files we keep on disk as reference (SUPERSEDED) or
// as deliberate negative artifacts that document a Script limitation
// (EXPECTED-COMPILE-FAIL) but should not break the build.
const header = readFileSync(srcPath, 'utf8').slice(0, 600);
const skipMatch = /SUPERSEDED|EXPECTED-COMPILE-FAIL/.exec(header);
if (skipMatch) {
console.log(`skipped ${src} (marked ${skipMatch[0]})`);
continue;
}
try {
const artifact = compileFile(srcPath);
const jsonName = src.replace(/\.cash$/, '.json');
const json = JSON.stringify(artifact, null, 2);
const outPath = join(OUT, jsonName);
writeFileSync(outPath, json);
console.log(`compiled ${src} -> ${outPath}`);
// Mirror canonical templates into the embedded D-3 copy (see EMBED above).
if (EMBEDDED.has(jsonName)) {
writeFileSync(join(EMBED, jsonName), json);
console.log(` embedded ${jsonName} -> ${join(EMBED, jsonName)}`);
}
} catch (err) {
console.error(`FAILED ${src}:`, err.message);
process.exitCode = 1;
}
}
}
main();