Provenance

Trust that survives our servers going away.

A sealed pack can be verified by anyone, forever, without asking Occestra anything. This page specifies the exact constructions — canonical hashing, the leaf encoding, the EIP-712 types — and ends with a standalone script that verifies a real production seal end to end. We ran it; the output is shown; run it yourself.

1 · Canonical manifest hashing

The pack manifest (its artifacts, grades, gaps, and metadata) is serialized with canonicalJson: object keys recursively sorted, no extra whitespace, bigints as decimal strings. Then:

manifest hash (public packs)

manifestHash = keccak256(utf8Bytes(canonicalJson(manifest)))

Personal content never touches the chain — the hash is the only thing that leaves the store. Two manifests differing by one character produce unrelated hashes, so the seal binds the exact delivered work.

Private keepsakes are salted. A public pack's hash is deterministic, which is fine when the pack is public: anyone can recompute it. But a private keepsake — every Remember pack — needs more. A deterministic hash is confirmable by anyone who obtains the pack, and identical manifests commit to identical leaves, which is linkable. So a private keepsake commits to a salted hash instead:

manifest commitment (private packs)

commitment = keccak256(salt || canonicalJson(manifest))   // salt = 32 random bytes
The salt is stored with the pack, never on chain and never in the public page, and is released only to the owner (who presents their owner token). The anchored leaf then proves the keepsake exists and was sealed — while revealing nothing about it and linking to nothing. The owner, holding the salt, can still verify the commitment opens to their pack; a stranger can verify the signature and the anchor, but not the contents. A memory can be proven without being published.

2 · The leaf

What actually lands on-chain is a single 32-byte leaf:

leaf encoding (Solidity abi.encode, mirrored in TS + viem)

leaf = keccak256(abi.encode(
  keccak256(bytes(keepsakeId)),  // bytes32
  manifestHash,                  // bytes32
  packKind,                      // uint8 — celebrate=0, remember=1, launch=2, tool=3
  createdAt                      // uint64 — unix seconds
))

The same construction is implemented three times — Solidity, TypeScript (@occestra/receipts), and the browser (viem on /k pages) — and a cross-language test in the repo executes the real contract bytecode in an in-process EVM to prove all three agree.

3 · The EIP-712 signature

fieldtypenotes
domain.name"Occestra"With version "1", chainId 196, and the registry as verifyingContract.
Keepsake.keepsakeIdstringThe oce_… id.
Keepsake.manifestHashbytes32From step 1.
Keepsake.packKinduint8The studio enum.
Keepsake.createdAtuint64Seal time, unix seconds.

Signer: 0x0d63f9EeB86813230B72017444cea16Cd4A453F2 — also published in the manifest at /.well-known/occestra.json, and readable on-chain as KeepsakeRegistry.sealer(). Sealer rotation is a two-step on-chain handover, so the authority trail is itself verifiable.

4 · The registry

fieldtypenotes
contractX Layer · 1960x1653509df702b45d67b3eb12ca37de9f5fc21f08 — KeepsakeRegistry, Solidity ^0.8.24.
seal(leaf)onlySealerRejects zero and double-seals; records block.timestamp; emits Sealed(leaf, timestamp).
sealBatch(leaves)onlySealerThe anchor worker drains queued leaves in batches (default every 30 min) — a seal can briefly be 'signed, anchoring queued', and everything reports exactly that state.
anchoredAt(leaf)view → uint640 = not anchored. This is the only read verification needs.

5 · Verify a real seal — standalone, runnable

This is examples/verify-seal.mjs from the repository, embedded at build time. Its only dependency is viem. The values in it are a real production pack — not a fixture.

examples/verify-seal.mjs — npm i viem && node verify-seal.mjs

/**
 * Verify a real Occestra seal end-to-end, without trusting Occestra.
 *
 *   npm i viem && node verify-seal.mjs
 *
 * Two independent checks:
 *   1. The EIP-712 signature — did Occestra's sealer really sign this manifest?
 *   2. The on-chain anchor  — is the seal's leaf recorded in KeepsakeRegistry
 *      on X Layer mainnet, and when?
 *
 * The values below are a REAL production seal (pack oce_01kxbz33bb4grnd1xh0gev,
 * served publicly at https://api.occestra.xyz/k/oce_01kxbz33bb4grnd1xh0gev).
 * Swap in any pack's `seal` object to verify it the same way.
 */
import {
  createPublicClient,
  encodeAbiParameters,
  http,
  keccak256,
  toBytes,
  verifyTypedData,
} from "viem";

const seal = {
  keepsakeId: "oce_01kxbz33bb4grnd1xh0gev",
  manifestHash: "0x619057ca10f52bfe9e0a620bb475c224e8d1b7de1d1f93b308a6fe26983a8e25",
  packKind: 0, // celebrate=0, remember=1, launch=2, tool=3
  createdAt: 1783886884,
  signature:
    "0x4bc804f0674a40332dc7891f6c8e2ac28f4d6d11f934790ff450ff48443c32e43c5a941aa1116754e8fd320ac52ad4c9ffbd1ca0760ed7b690c8b0b90d08213c1c",
  signer: "0x0d63f9EeB86813230B72017444cea16Cd4A453F2",
  chainId: 196,
  verifyingContract: "0x1653509df702b45d67b3eb12ca37de9f5fc21f08",
};

/* 1 ── the signature: EIP-712, domain and types exactly as published */

const signatureValid = await verifyTypedData({
  address: seal.signer,
  domain: {
    name: "Occestra",
    version: "1",
    chainId: seal.chainId,
    verifyingContract: seal.verifyingContract,
  },
  types: {
    Keepsake: [
      { name: "keepsakeId", type: "string" },
      { name: "manifestHash", type: "bytes32" },
      { name: "packKind", type: "uint8" },
      { name: "createdAt", type: "uint64" },
    ],
  },
  primaryType: "Keepsake",
  message: {
    keepsakeId: seal.keepsakeId,
    manifestHash: seal.manifestHash,
    packKind: seal.packKind,
    createdAt: BigInt(seal.createdAt),
  },
  signature: seal.signature,
});

console.log("signature valid :", signatureValid);

/* 2 ── the anchor: leaf = keccak256(abi.encode(keccak256(id), hash, kind, ts)) */

const leaf = keccak256(
  encodeAbiParameters(
    [{ type: "bytes32" }, { type: "bytes32" }, { type: "uint8" }, { type: "uint64" }],
    [keccak256(toBytes(seal.keepsakeId)), seal.manifestHash, seal.packKind, BigInt(seal.createdAt)],
  ),
);

const client = createPublicClient({ transport: http("https://rpc.xlayer.tech") });
const anchoredAt = await client.readContract({
  address: seal.verifyingContract,
  abi: [
    {
      name: "anchoredAt",
      type: "function",
      stateMutability: "view",
      inputs: [{ name: "leaf", type: "bytes32" }],
      outputs: [{ type: "uint64" }],
    },
  ],
  functionName: "anchoredAt",
  args: [leaf],
});

console.log("leaf            :", leaf);
console.log(
  "anchored        :",
  anchoredAt > 0n ? `yes — ${new Date(Number(anchoredAt) * 1000).toISOString()}` : "not yet (0)",
);

if (!signatureValid || anchoredAt === 0n) process.exit(1);
console.log("\nBoth checks passed. This pack is exactly what Occestra says it is.");

output, when we ran it against X Layer mainnet

signature valid : true
leaf            : 0xc814215758135400b364fbb5d4614b7e9ab50a114158a1c91e36064ab23a4adc
anchored        : yes — 2026-07-12T20:08:52.000Z

Both checks passed. This pack is exactly what Occestra says it is.
Note what was not required: an Occestra API, an Occestra key, or Occestra being online. The public pack JSON plus a public RPC is enough — that is the point.