Skip to content

DID minting has been completely broken since the didwebvh-ts 2.8 upgrade - #218

Merged
brianorwhatever merged 1 commit into
mainfrom
fix/webvh-updatekeys
Jul 29, 2026
Merged

DID minting has been completely broken since the didwebvh-ts 2.8 upgrade#218
brianorwhatever merged 1 commit into
mainfrom
fix/webvh-updatekeys

Conversation

@brianorwhatever

@brianorwhatever brianorwhatever commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

The re-mint still didn't fire after #217. The cause turned out to be much bigger than the re-mint.

No did:webvh can be created at all — and hasn't been since the didwebvh-ts 2.8 upgrade in this branch series. Every mint throws:

Key did:key:z6Mk… is not authorized to update.

Root cause

2.8's isKeyAuthorized parses the proof's verificationMethod down to its bare keyMultibase, then compares by exact equality:

var isKeyAuthorized = (verificationMethod, updateKeys) => {
  const parsed = parseDidKeyVerificationMethod(verificationMethod);  // → "z6Mk…"
  return updateKeys.some((updateKey) => updateKey === parsed.keyMultibase);
};

Every call site passed signer.getVerificationMethodId() — the full did:key:z6Mk… URI. "did:key:z6Mk…" === "z6Mk…" is never true. didwebvh-ts verifies the log it has just created, so creation fails closed.

How I found it, and a theory I had to discard

I reproduced it locally with a brand-new key and empty localStorage, and it failed identically. That killed my earlier explanation — I'd concluded this was about a controller key lost with the old origin, and built #216's key-intersection authorization on that premise. It was wrong: the failure has nothing to do with which key you hold.

It also explains why prod logs showed no remintDid invocation: the hook died in the browser at the mint step, before any request was ever made. #216 and #217 were both fixing the wrong layer.

Scope

Fixed at all four call sites:

Site Impact
src/lib/webvh.ts user DIDs — signup and re-mint
convex/didCreation.ts server-side DID creation
convex/siteActions.ts ×2 createDID and updateDIDsite publishing had the same defect

Test

scripts/webvh-mint.test.mjs performs a real mint. didwebvh-ts verifies its own output, so a malformed updateKeys fails the test exactly as it failed in the browser — this specific regression cannot return silently.

The harness installs browser globals via defineProperty (bun exposes a readonly localStorage) and restores them afterwards, since bun shares globals across test files.

Also

Removes convex/remintDid.ts. It was meant to go in #217 — the rm was inside a command the sandbox blocked, so it merged as dead code. The client now uses the JWT-authorized /api/user/remintDid endpoint.

116 pass / 0 fail; both typechecks clean; lint on touched files clean (the 9 pre-existing convex/ problems are unchanged from main).

After merge

Wait for Railway to finish, not just Deploy Convex — the last two attempts tested a stale bundle. Then sign in and expect a [remint] line plus a reload. Verify with:

npx convex run --prod migrations/remintUserDidDb:listUsersOnDomain '{"domain":"trypoo.app"}'

🤖 Generated with Claude Code

Note

Fix DID minting broken by didwebvh-ts 2.8 by using raw publicKeyMultibase in updateKeys

didwebvh-ts 2.8 changed key authorization to compare exact keyMultibase values, but the code was still passing verificationMethodId strings to updateKeys, breaking all DID minting.

Macroscope summarized 23434b6.

…roken

No did:webvh could be created at all since the didwebvh-ts 2.8 upgrade. Every
mint threw:

  Key did:key:z6Mk… is not authorized to update.

2.8's isKeyAuthorized parses the proof's verificationMethod down to its
keyMultibase and compares by exact equality:

  updateKeys.some((k) => k === parsed.keyMultibase)

Every call site passed `signer.getVerificationMethodId()` — the full
`did:key:z6Mk…` URI — so the comparison could never match. didwebvh-ts verifies
the log it has just created, so creation failed closed.

Reproduced with a brand-new key and empty localStorage, which ruled out the
earlier theory that this was about a lost controller key: it failed identically
for a fresh identity. That also explains why the re-mint hook never reached
Convex — it died in the browser at the mint step, before any request.

Fixed at all four sites: user DIDs (lib/webvh.ts), server-side DID creation
(didCreation.ts), and both site paths (siteActions.ts createDID + updateDID) —
site publishing carried the same defect.

Adds scripts/webvh-mint.test.mjs, which performs a real mint. didwebvh-ts
verifies its own output, so a malformed updateKeys fails the test exactly as it
failed in the browser. The harness installs browser globals via defineProperty
(bun's localStorage is readonly) and restores them, since bun shares globals
across test files.

Also removes convex/remintDid.ts. It was meant to go in #217 — the `rm` was in a
command the sandbox blocked, so it merged as dead code; the client now uses the
JWT-authorized /api/user/remintDid endpoint.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@brianorwhatever
brianorwhatever merged commit 0eadefe into main Jul 29, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant