DID minting has been completely broken since the didwebvh-ts 2.8 upgrade - #218
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The re-mint still didn't fire after #217. The cause turned out to be much bigger than the re-mint.
No
did:webvhcan be created at all — and hasn't been since the didwebvh-ts 2.8 upgrade in this branch series. Every mint throws:Root cause
2.8's
isKeyAuthorizedparses the proof'sverificationMethoddown to its barekeyMultibase, then compares by exact equality:Every call site passed
signer.getVerificationMethodId()— the fulldid: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
remintDidinvocation: 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:
src/lib/webvh.tsconvex/didCreation.tsconvex/siteActions.ts×2createDIDandupdateDID— site publishing had the same defectTest
scripts/webvh-mint.test.mjsperforms a real mint. didwebvh-ts verifies its own output, so a malformedupdateKeysfails 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 readonlylocalStorage) and restores them afterwards, since bun shares globals across test files.Also
Removes
convex/remintDid.ts. It was meant to go in #217 — thermwas inside a command the sandbox blocked, so it merged as dead code. The client now uses the JWT-authorized/api/user/remintDidendpoint.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:🤖 Generated with Claude Code
Note
Fix DID minting broken by didwebvh-ts 2.8 by using raw
publicKeyMultibaseinupdateKeysdidwebvh-ts 2.8 changed key authorization to compare exact
keyMultibasevalues, but the code was still passingverificationMethodIdstrings toupdateKeys, breaking all DID minting.createUserWebVHDid,createDIDRecord, and bothsiteActionshandlers to pass the barepublicKeyMultibaseinstead ofverificationMethodIdremintDid.tsmodule and removes it from generated API typesscripts/webvh-mint.test.mjsthat verifies end-to-end DID minting produces a valid, non-staledid:webvhMacroscope summarized 23434b6.