import fs from "fs"; import path from "path"; export interface CheckCodeEvidenceEntry { status: "passed"; network: string; instanceId: string; contractInfoKey: string; address: string; artifactHash: string; runId: string; checkedAt: string; } export interface CheckCodeEvidenceIndex { version: 1; entries: Record; } export interface ReusableDeploymentExpectation { network: string; instanceId: string; address: string; artifactHash: string; } const isRecord = (value: unknown): value is Record => { return !!value && typeof value === "object" && !Array.isArray(value); }; const evidenceIndexPath = (root: string): string => { return path.join(root, "scripts", "checkcode", "index.json"); }; const writeJsonAtomic = (filePath: string, value: unknown): void => { fs.mkdirSync(path.dirname(filePath), { recursive: true }); const temporary = filePath + "." + process.pid + "." + Date.now() + ".tmp"; try { fs.writeFileSync(temporary, JSON.stringify(value, null, 2) + "\n"); fs.renameSync(temporary, filePath); } catch (error) { if (fs.existsSync(temporary)) fs.unlinkSync(temporary); throw error; } }; export const loadCheckCodeEvidenceIndex = (root: string): CheckCodeEvidenceIndex => { const filePath = evidenceIndexPath(root); if (!fs.existsSync(filePath)) { throw new Error("Existing deployment has no passed CheckCode evidence index"); } let parsed: unknown; try { parsed = JSON.parse(fs.readFileSync(filePath, "utf8")); } catch (error) { throw new Error( "CheckCode evidence index must contain valid JSON: " + (error instanceof Error ? error.message : String(error)), ); } if (!isRecord(parsed) || parsed.version !== 1 || !isRecord(parsed.entries)) { throw new Error("CheckCode evidence index must contain version 1 entries"); } const entries: Record = {}; for (const [key, entryValue] of Object.entries(parsed.entries)) { if (!isRecord(entryValue) || entryValue.status !== "passed") { throw new Error("CheckCode evidence entry " + key + " must have passed status"); } for (const field of [ "network", "instanceId", "contractInfoKey", "address", "artifactHash", "runId", "checkedAt", ] as const) { if (typeof entryValue[field] !== "string" || !String(entryValue[field]).trim()) { throw new Error("CheckCode evidence entry " + key + "." + field + " is required"); } } entries[key] = entryValue as unknown as CheckCodeEvidenceEntry; } return { version: 1, entries }; }; export const assertReusableDeployment = ( root: string, expected: ReusableDeploymentExpectation, ): CheckCodeEvidenceEntry => { const index = loadCheckCodeEvidenceIndex(root); const evidence = Object.values(index.entries).find((entry) => ( entry.network === expected.network && entry.instanceId === expected.instanceId )); if (!evidence) { throw new Error( "Existing deployment " + expected.network + "." + expected.instanceId + " has no passed CheckCode evidence", ); } if (evidence.address.toLowerCase() !== expected.address.toLowerCase()) { throw new Error("CheckCode address does not match the existing deployment"); } if (evidence.artifactHash !== expected.artifactHash) { throw new Error("CheckCode artifactHash does not match the execution artifactHash"); } return evidence; }; export const updateCheckCodeEvidenceIndex = ( root: string, evidenceEntries: CheckCodeEvidenceEntry[], ): CheckCodeEvidenceIndex => { const filePath = evidenceIndexPath(root); let current: CheckCodeEvidenceIndex = { version: 1, entries: {} }; if (fs.existsSync(filePath)) { current = loadCheckCodeEvidenceIndex(root); } const entries = { ...current.entries }; for (const evidence of evidenceEntries) { entries[evidence.network + "." + evidence.instanceId] = evidence; } const next = { version: 1 as const, entries }; writeJsonAtomic(filePath, next); return next; };