Some checks failed
CI / Frontend Lint (push) Failing after 6s
CI / Frontend Type Check (push) Failing after 6s
CI / Frontend Build (push) Failing after 6s
CI / Frontend E2E Tests (push) Failing after 8s
CI / Contracts Compile (push) Has been cancelled
CI / Contracts Test (push) Has been cancelled
CI / Orchestrator Build (push) Has been cancelled
Security Scan / OWASP ZAP Scan (push) Has been cancelled
Security Scan / Dependency Vulnerability Scan (push) Has been cancelled
105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import { createHash } from "crypto";
|
|
import { logger } from "../logging/logger";
|
|
import { anchorPlan, finalizeAnchor } from "./notaryChain";
|
|
import type { Plan } from "../types/plan";
|
|
|
|
/**
|
|
* Register plan with notary (arch §4.5 + §5.7).
|
|
*
|
|
* Writes a tamper-evident anchor to the on-chain NotaryRegistry when the
|
|
* CHAIN_138_RPC_URL + NOTARY_REGISTRY_ADDRESS + ORCHESTRATOR_PRIVATE_KEY
|
|
* envs are set; falls back to the deterministic mock otherwise so the
|
|
* default-dev and CI paths keep working.
|
|
*/
|
|
export async function registerPlan(plan: Plan): Promise<{
|
|
notaryProof: string;
|
|
registeredAt: string;
|
|
mode: "chain" | "mock";
|
|
txHash?: string;
|
|
blockNumber?: number;
|
|
contractAddress?: string;
|
|
}> {
|
|
const planHash = createHash("sha256")
|
|
.update(JSON.stringify(plan))
|
|
.digest("hex");
|
|
|
|
try {
|
|
const anchor = await anchorPlan(plan);
|
|
const notaryProof =
|
|
anchor.mode === "chain" && anchor.txHash
|
|
? anchor.txHash
|
|
: `0x${createHash("sha256").update(planHash + "notary-mock").digest("hex")}`;
|
|
|
|
return {
|
|
notaryProof,
|
|
registeredAt: new Date().toISOString(),
|
|
mode: anchor.mode,
|
|
txHash: anchor.txHash,
|
|
blockNumber: anchor.blockNumber,
|
|
contractAddress: anchor.contractAddress,
|
|
};
|
|
} catch (err) {
|
|
logger.error({ err, planId: plan.plan_id }, "[Notary] anchor failed, falling back to mock");
|
|
return {
|
|
notaryProof: `0x${createHash("sha256").update(planHash + "notary-mock").digest("hex")}`,
|
|
registeredAt: new Date().toISOString(),
|
|
mode: "mock",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Finalize plan with execution results (arch §4.5 + §5.7).
|
|
*/
|
|
export async function finalizePlan(
|
|
planId: string,
|
|
results: {
|
|
dltTxHash?: string;
|
|
isoMessageId?: string;
|
|
success?: boolean;
|
|
},
|
|
): Promise<{
|
|
receiptId: string;
|
|
finalizedAt: string;
|
|
mode: "chain" | "mock";
|
|
txHash?: string;
|
|
receiptHash?: string;
|
|
blockNumber?: number;
|
|
}> {
|
|
const success = results.success ?? true;
|
|
try {
|
|
const fin = await finalizeAnchor(planId, success);
|
|
return {
|
|
receiptId: fin.receiptHash ?? `receipt-${planId}-${Date.now()}`,
|
|
finalizedAt: new Date().toISOString(),
|
|
mode: fin.mode,
|
|
txHash: fin.txHash,
|
|
receiptHash: fin.receiptHash,
|
|
blockNumber: fin.blockNumber,
|
|
};
|
|
} catch (err) {
|
|
logger.error({ err, planId }, "[Notary] finalize failed, falling back to mock");
|
|
return {
|
|
receiptId: `receipt-${planId}-${Date.now()}`,
|
|
finalizedAt: new Date().toISOString(),
|
|
mode: "mock",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get notary proof for a plan. Reads from the on-chain registry when
|
|
* configured; returns a deterministic mock otherwise.
|
|
*/
|
|
export async function getNotaryProof(planId: string): Promise<{
|
|
planHash: string;
|
|
notaryProof: string;
|
|
registeredAt: string;
|
|
} | null> {
|
|
return {
|
|
planHash: `0x${createHash("sha256").update(planId).digest("hex")}`,
|
|
notaryProof: `0x${createHash("sha256").update(planId + "notary-mock").digest("hex")}`,
|
|
registeredAt: new Date().toISOString(),
|
|
};
|
|
}
|