feat(web): forge-v2 writes and limited-key sign-in - #24
Merged
Merged
Conversation
|
Warning Review limit reachedNext included review available in 20 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (34)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PastaPastaPasta
force-pushed
the
feat/web-limited-key-auth
branch
from
September 26, 2026 18:12
ecbf04a to
f44b804
Compare
PastaPastaPasta
force-pushed
the
feat/web-v2-writes
branch
from
September 26, 2026 18:12
96ea657 to
936b49d
Compare
PastaPastaPasta
force-pushed
the
feat/web-limited-key-auth
branch
from
September 26, 2026 18:28
f44b804 to
ca256d6
Compare
Vault: AES-256-GCM under a passkey PRF (HKDF) or Argon2id (64 MiB, t=3) in IndexedDB, AAD-bound to network+identity, unlocked only in module memory with a 12 h auto-lock; the plaintext localStorage keystore is removed and legacy entries purged. Sign-in sheet: unlock, App Connect (verified on chain), create identity (mnemonic, 3-word quiz, deposit QR, asset lock ported from mint-identity and byte-identical to it, IdentityCreate carrying the limited key), import file or phrase (master key signs one IdentityUpdate registering a HIGH key bound to the dash-forge group with budget and expiry), Advanced raw key for this tab only. Settings shows the key's budget and expiry, renew, lock and forget. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
v2-auth.spec.ts: a1 imports an identity file and checks from Node that the new key is live, HIGH, bound to the dash-forge group with a 0.05 DASH budget and a ~90-day expiry, that localStorage holds no key, and that the vault unlocks after a reload. a2 creates an identity in the browser, funding the deposit from the devnet faucet key through mint-identity's fundFromKey. The write specs now sign in through the import ceremony. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The create-identity and wallet flows can start before any page connected (from the landing page); they used getSdk() and failed with 'EvoSDK not initialized' after the deposit arrived. ensureSdk(network) connects on demand. Live on moutai the whole create flow now passes: words, quiz, passphrase, deposit funded from the devnet key, chain-lock proof, IdentityCreate with the limited key, in 4.3 minutes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Identity creation stores the browser key in the vault before IdentityCreate, saves the signed asset lock before broadcasting it, re-registers a key from the mnemonic when the identity already exists, and clears the journal only after the session opens; unfinished creations can be discarded (with a warning if the deposit holds funds); one run at a time, aborted on unmount; a wrong phrase is caught before any QR. Passkeys get a random user id. Forget acts on the selected key with a confirmation; the auto-lock ends the session; Renew opens Import directly; a key stored but not opened says so; wallet responses that fail verification are retried. Renewal disables the previous key in the same update; the sheet offers Unlock for an identity already stored; the file network check is back. One typed SDK facade and shared sheet pieces. e2e reuses one stored key per identity instead of registering a key per test. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Asset-lock inputs are proven from their raw funding transactions (hash checked against the txid, value and script parsed from the bytes), so a lying explorer can no longer burn a deposit; the fee is asserted. App Connect asks for the dash-forge group, pages through every reply, retries a reply whose key is not visible yet, refuses when two identities answer, and makes the user confirm the full identity id and DPNS name. The vault refuses to run on shared origins (github.io project sites, IPFS path gateways), pins the Argon2 parameters instead of reading them from the record, and clears signed retry writes on sign-out and forget. Keys: random passkey user ids, renewal disables the previous key, Revoke on chain in Settings (forgetting is not revoking), verifyLimitedKey rejects expired or spent keys and checks the requested limits, the group is checked on chain to hold forge-core and forge-collab before a key binds to it, the raw-key path accepts only HIGH or CRITICAL. Secrets (identity file text, mnemonic, PRF output, granted WIF) live in refs, not React state. CSP drops 'unsafe-eval'. docs/guides/identity-and-keys.md documents the trust roots and the vault's limits. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A contract re-registration leaves limited keys bound to the old group: they still validate but every write is refused. Unlock now reports them as needing renewal; renew and revoke accept any group-bound budgeted HIGH key so old keys can be disabled. The e2e reads the group from the deployment file. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tests Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A lagging node answered 'key N is not on identity' right after the update landed (live a1). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PastaPastaPasta
force-pushed
the
feat/web-limited-key-auth
branch
from
September 26, 2026 18:33
ca256d6 to
21174c0
Compare
This was referenced Sep 26, 2026
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.
What
This is PR F part 2, stacked on #23 (base
feat/web-v2-writes). It adds limited-key sign-in, the browser vault, and in-browser identity creation fromux-dx-spec.md§2 (P0 items 1 and 2). After this PR, the web app only ever keeps a PV14 limited key:dash-forgecontract group, so it can sign batches on forge-core and forge-collab only;The master key is used only in one-time ceremonies and is not retained. The plaintext
localStoragekeystore is gone, and any leftoverforge_key_*entries are purged.Sign-in sheet
App Connect in detail:
On testnet, where there is no forge-v2 group, only the v1 identity-file sign-in is available, for the current tab only.
Vault (
lib/auth/vault.ts)*.github.ioproject sites, IPFS path gateways). Pages serves forge.dashhq.org, as the repo's Pages settings confirm.Header and Settings
Live on moutai (all green:
E2E_DEVNET=moutai E2E_WRITE=1)23iVLZ…, budget 5,000,000,000 credits, remaining 5,000,000,000, expiry ~90 days.localStorageholds no WIF.fundFromKey.AypWjSj19Wpn…got 0.028 DASH of credits from a 0.03 DASH deposit, with a 0.05 DASH / 90-day browser key.auth-write) pass.Screenshots: browser key in Settings, create: the 12 words, create: the deposit QR, identity created, key live.
The asset-lock transaction builder is byte-identical to
tools/mint-identity. A unit test pins mint-identity's output as a vector.Reviews
Security review (independent, adversarial). All 12 must-fix items are fixed in ecbf04a:
user.id.verifyLimitedKeyrejects expired or spent keys and compares against the request.Also:
'unsafe-eval'(only'wasm-unsafe-eval'). Everything, including the live writes, runs without it.frame-ancestorson Pages) are documented indocs/guides/identity-and-keys.md.Correctness review: all 5 must-fix, 7 should-fix and 8 simplification items are fixed. They include:
user.id;Known gaps
loginKeyResponseschema has no field for a wallet signature over the request. Until it does, the user's confirmation of the identity is the check. It has not been tested against a real wallet (none speaks the group-scoped request yet).IdentityKeyLimitsUpdatetop-ups (P1) are not wired; renewing registers a new key instead.🤖 Generated with Claude Code