Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9368831
v40.7.2
kojibai Jan 11, 2026
7a0aec2
Add shareable verification receipt links
kojibai Jan 11, 2026
f1b132b
Allow pasting receipt JSON in verifier
kojibai Jan 11, 2026
eef3274
Validate shared receipt checks before success
kojibai Jan 11, 2026
00ddd3b
Verify author signatures for shared receipts
kojibai Jan 11, 2026
28096b9
Fix shared receipt ZK verification
kojibai Jan 11, 2026
bb3e002
Fix shared receipt seal data
kojibai Jan 11, 2026
1d65eab
Fix shared receipt seal data
kojibai Jan 11, 2026
3edd07d
Merge pull request #216 from kojibai/codex/fix-verification-not-indic…
kojibai Jan 11, 2026
3835b8d
Merge pull request #215 from kojibai/codex/fix-verification-not-indic…
kojibai Jan 11, 2026
fd47e32
Merge pull request #214 from kojibai/codex/fix-zk-proof-verification-…
kojibai Jan 11, 2026
f76392e
v40.7.3
kojibai Jan 11, 2026
5eb8bd5
Merge pull request #212 from kojibai/codex/update-shared-url-to-show-…
kojibai Jan 11, 2026
f88a986
v40.7.5
kojibai Jan 11, 2026
adddacb
Update verify SEO for shared receipts
kojibai Jan 11, 2026
8371282
Merge pull request #217 from kojibai/codex/update-seo-for-verified-si…
kojibai Jan 11, 2026
0b15be3
v40.7.6
kojibai Jan 11, 2026
16e9dc4
v40.7.7
kojibai Jan 11, 2026
bb17732
v40.7.9
kojibai Jan 11, 2026
d5373d7
v40.8.0
kojibai Jan 11, 2026
1e82932
v40.8.1
kojibai Jan 11, 2026
fe9f118
Adjust verify header sizing on small screens
kojibai Jan 11, 2026
a063893
Slim verify proof action row
kojibai Jan 11, 2026
bac2f30
Update Verifypage text
kojibai Jan 11, 2026
55a0e41
Merge pull request #221 from kojibai/codex/fix-layout-for-smaller-scr…
kojibai Jan 11, 2026
779f89d
v40.8.2
kojibai Jan 11, 2026
fc8d828
v40.8.3
kojibai Jan 11, 2026
9aebd96
v40.8.4
kojibai Jan 11, 2026
93785d0
v40.8.5
kojibai Jan 11, 2026
0bc5d16
v40.8.6
kojibai Jan 11, 2026
07a0613
v41.0.0
kojibai Jan 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/og/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ function drawBadge(png: PngInstance, x: number, y: number, ok: boolean | null):
fillRect(png, x, y, 2, size, stroke);
fillRect(png, x + size - 2, y, 2, size, stroke);

if (ok === null) {
drawLine(png, x + 4, y + 9, x + 14, y + 9, [140, 170, 210, 220]);
return;
}
if (ok) {
drawLine(png, x + 4, y + 10, x + 8, y + 14, [56, 231, 166, 255]);
drawLine(png, x + 8, y + 14, x + 14, y + 4, [56, 231, 166, 255]);
Expand Down
81 changes: 78 additions & 3 deletions api/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ type SlugInfo = {
shortSig: string | null;
};

type ProofCapsule = {
v: "KPV-1";
pulse: number;
chakraDay: string;
kaiSignature: string;
phiKey: string;
verifierSlug: string;
};

type SharedReceipt = {
proofCapsule: ProofCapsule;
authorSig?: unknown;
zkVerified?: boolean;
};

function parseSlug(rawSlug: string): SlugInfo {
let raw = (rawSlug || "").trim();
try {
Expand All @@ -31,6 +46,53 @@ function statusFromQuery(value: string | null): "verified" | "failed" | "standby
return "standby";
}

function parseProofCapsule(raw: unknown): ProofCapsule | null {
if (!raw || typeof raw !== "object") return null;
const record = raw as Record<string, unknown>;
if (record.v !== "KPV-1") return null;
if (typeof record.pulse !== "number" || !Number.isFinite(record.pulse)) return null;
if (typeof record.chakraDay !== "string") return null;
if (typeof record.kaiSignature !== "string") return null;
if (typeof record.phiKey !== "string") return null;
if (typeof record.verifierSlug !== "string") return null;
return record as ProofCapsule;
}

function parseSharedReceipt(raw: unknown): SharedReceipt | null {
if (!raw || typeof raw !== "object") return null;
const record = raw as Record<string, unknown>;
const proofCapsule = parseProofCapsule(record.proofCapsule);
if (!proofCapsule) return null;
return {
proofCapsule,
authorSig: record.authorSig,
zkVerified: typeof record.zkVerified === "boolean" ? record.zkVerified : undefined,
};
}

function decodeBase64Url(input: string): string | null {
try {
const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
const pad = base64.length % 4 === 0 ? "" : "=".repeat(4 - (base64.length % 4));
return Buffer.from(`${base64}${pad}`, "base64").toString("utf-8");
} catch {
return null;
}
}

function readReceiptFromParams(params: URLSearchParams): SharedReceipt | null {
const encoded = params.get("r") ?? params.get("receipt");
if (!encoded) return null;
const decoded = decodeBase64Url(encoded);
if (!decoded) return null;
try {
const raw = JSON.parse(decoded);
return parseSharedReceipt(raw);
} catch {
return null;
}
}

function buildMetaTags(params: {
title: string;
description: string;
Expand Down Expand Up @@ -151,19 +213,32 @@ export default async function handler(
const requestUrl = new URL(req.url ?? "/", origin);
const slugRaw = requestUrl.searchParams.get("slug") ?? "";
const slug = parseSlug(slugRaw);
const status = statusFromQuery(requestUrl.searchParams.get("status"));
const receipt = readReceiptFromParams(requestUrl.searchParams);
const receiptSlug = receipt?.proofCapsule.verifierSlug ?? "";
const canonicalSlug = slug.raw || slugRaw || receiptSlug;
const receiptMatchesSlug =
receipt != null && (!canonicalSlug || receipt.proofCapsule.verifierSlug === canonicalSlug);
const statusParam = statusFromQuery(requestUrl.searchParams.get("status"));
const status = receiptMatchesSlug && statusParam === "standby" ? "verified" : statusParam;

const statusLabel = status === "verified" ? "VERIFIED" : status === "failed" ? "FAILED" : "STANDBY";
const pulseLabel = slug.pulse ? String(slug.pulse) : "—";
const receiptPulse = receiptMatchesSlug ? receipt?.proofCapsule.pulse : null;
const pulseLabel = receiptPulse ? String(receiptPulse) : slug.pulse ? String(slug.pulse) : "—";
const title = `Proof of Breath™ — ${statusLabel}`;
const description = `Proof of Breath™ • ${statusLabel} • Pulse ${pulseLabel}`;

const canonicalSlug = slug.raw || slugRaw;
const verifyUrl = `${origin}/verify/${encodeURIComponent(canonicalSlug)}`;

const ogUrl = new URL(`${origin}/api/og/verify`);
ogUrl.searchParams.set("slug", canonicalSlug);
ogUrl.searchParams.set("status", status);
if (receiptMatchesSlug && receipt) {
ogUrl.searchParams.set("pulse", String(receipt.proofCapsule.pulse));
ogUrl.searchParams.set("phiKey", receipt.proofCapsule.phiKey);
if (receipt.proofCapsule.chakraDay) ogUrl.searchParams.set("chakraDay", receipt.proofCapsule.chakraDay);
if (receipt.authorSig) ogUrl.searchParams.set("kas", "1");
if (receipt.zkVerified != null) ogUrl.searchParams.set("g16", receipt.zkVerified ? "1" : "0");
}

const meta = buildMetaTags({
title: escapeHtml(title),
Expand Down
Binary file added dist/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 0 additions & 29 deletions dist/assets/EternalKlock-Ai4RXs-m.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/assets/EternalKlock-BxZZdEPS.js

This file was deleted.

1 change: 1 addition & 0 deletions dist/assets/EternalKlock-CfKWqeTU.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions dist/assets/EternalKlock-CgOJptA0.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions dist/assets/KaiVohApp-6rNHpMY-.js

Large diffs are not rendered by default.

88 changes: 0 additions & 88 deletions dist/assets/KaiVohApp-PIjmJ__q.js

This file was deleted.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading