Skip to content

Cachet 0.3.0

Choose a tag to compare

@0xpierre-dev 0xpierre-dev released this 01 Sep 06:30
· 120 commits to main since this release

The release that closes the trust chain. The asset page now re-derives the asset id itself from the issuer key and the served description (ZIP 227), through a dedicated 247 KB verification engine with no proving circuit in it, so "trust the math, not the registry" stopped being half true. Around it: a continuity page that answers what survives this instance, a registry that surfaces attested names instead of burying them, one meaning per word for "sealed", and a security posture where every advisory is either fixed or documented with its migration already built.

Live at cachetzec.com, against the public ZSA testnet.

Added

  • The asset id itself is verified, in the browser. The page used to re-hash the metadata bundle against the sha256 inside the on-chain description and call that "trust the math, not the registry". Nothing checked the description itself, so a registry serving a fabricated description with a matching fabricated bundle passed with a green badge. ZIP 227 makes identity derived rather than assigned, so the page now recomputes the asset id from the issuance validating key and the served description and compares it with the id it asked for: a registry can serve any description, but not one that derives the right id. The check covers every asset with a description, so ZMD-1 and free-text names are checkable too, not only sealed ones.
  • cachet-verify-engine: a second, much smaller wasm module (247 KB against the mint engine's 4 MB) carrying the derivation and nothing else: no Halo2 circuit, no keys. Loaded once per session, only when there is a description to check, and tested against a real asset confirmed at testnet height 520.
  • A continuity page, /continuity, answering the question infrastructure gets asked and rarely answers: what happens if this instance disappears. What would be lost, what would not, and how to take over without asking anyone, including the honest remainder that a successor inherits neither the domain nor the signing key.
  • GET /api/v1/assets?resolved=true narrows a listing to assets whose description is known. The landing showcase uses it: most of this testnet is script-minted under a shared demo key with no description, so an unfiltered showcase was five rows of hex.
  • The files a public site is expected to serve: robots.txt with the sitemap pointer, sitemap.xml (entry points only, since asset pages change with every block), and an Apple touch icon that Safari probed on every visit and turned into a console error. The site origin behind them is a build argument (CACHET_SITE_URL) like the API origin, so a fork's robots.txt stops pointing crawlers at this deployment.

Changed

  • The registry lists attested names first: sealed, then ZMD-1, then unverified label, then unresolved. Reordering, not filtering: every asset stays listed, the count is unchanged, and one click returns to strict chain order.
  • The verification badge states what was actually established (full verification, description only, or bundle only) instead of one fixed sentence. An asset id mismatch outranks a bundle mismatch, because it makes everything under it moot.
  • One word no longer means two things. "Sealed" named committed metadata on the landing and finalized supply everywhere else, which is exactly how a reader concludes an unsealed asset has editable metadata (it does not: the description hash derives the asset id). The landing step is now "Bind"; both supply states are stated instead of one being the absence of a stamp ("sealed" / "open supply", the latter in the attention colour since it carries dilution risk for the holder); and reissuing announces itself before proving and on the receipt, instead of silently adding units to an existing asset.
  • Names in the landing showcase carry their provenance visibly ("zmd-1", "unverified"): the anti-phishing display rule applied where only typeface used to carry it.
  • Working paper v1.1: every engine measurement re-taken after three rebuilds had drifted them (4.0 MB module, 1.56 MB zstd on the wire, 74 percent; load restated as 24 ms warm / ~0.5 s cold), the provenance point made with a chain-wide aggregate instead of naming one project's batch, issuer moderation verbs added to the CLI listing, P1 through P8, and no heading is ever the last thing on a page.
  • Documentation reconciled with the code as it ships: the three non-chain-derivable tables named consistently everywhere, the GC keep-set described as the resolved description journal (what the code does) rather than "on-chain assets" (what it does not), and DEPLOY's one-time setup no longer omits the third mandatory secret.
  • CI actions moved off the Node 20 runtimes before their removal (checkout v7, setup-node v7, cache v6, upload-artifact v7, pnpm/action-setup v6), with automatic package-manager caching opted out in the one job that installs no package manager.
  • The navbar and footer GitHub links land on the repository rather than the organization page.

Fixed

  • The verification engine was served with max-age=0, so every asset page revalidated 247 KB per visit. Same cache rule as the mint engines now: an hour, plus a stale-while-revalidate day.
  • The mint page printed eight copies of a wasm-bindgen deprecation warning, one per spawned thread, from the generated rayon worker bootstrap. Same call, object form, silence; re-applied by the engine build script so the next rebuild does not undo it.
  • In attested order the ledger index counted down from the registry total, labelling the best-attested assets as the chain's newest. Rows are numbered by rank there; the countdown remains only in chain order, where it is true.

Security

  • The four postcss advisories are resolved rather than accepted: next pins postcss 8.4.31 exactly, so the patched line was unreachable until a pnpm override reached it. Verified against the build and the end-to-end suite.
  • The critical halo2_gadgets soundness advisory (under-constrained base in variable-base scalar multiplication) is now described in SECURITY.md as what it is, with the exposure reasoning stated so a reader can disagree with it. The full migration to the fixed circuit is built and tested on chore/bump-qedit-stack, blocked on consensus rather than on this repository: the fix changes the verifying key, and the deployed testnet still verifies with the old one. Tracked in #3, reported upstream in QED-it/zebra#164.

Full history in CHANGELOG.md.