fix(core): report expired sessions without logging the passkey out - #356
Draft
mariano-aguero wants to merge 15 commits into
Draft
mariano-aguero wants to merge 15 commits into
mariano-aguero wants to merge 15 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Findings outside the diff
These sit on lines this PR did not change, but this PR is what makes them wrong. They cannot be posted as inline comments.
- [WARNING]
.github:2— Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: amannn/action-semantic-pull-request@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Reviewer callouts (1)
Non-blocking observations. Nothing here needs to change before merge.
.github:1— "The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see actions/runner-images#14748"
This branch was successfully deployed
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
When a session expires while the page is open, the provider now tells the dApp: it drops the signer, emits
accountsChangedwith an empty list anddisconnect, and answers later requests as it would for a first visit. The passkey stays logged in and the transport stays up, so reconnecting takes one approval. Signing requests made without a session also clean up their temporary signer when they fail.Why
A signer restored from an earlier visit kept answering after its session had expired. The dApp kept showing the account, and the first signing request came back with 4100, which the provider read as a dead session and tore down completely: passkey logged out, iframe dropped. The provider now treats a signer with no stored account as not connected and reports it once.
A 4100 now disconnects only the session the failing request went through. A late error from a signer that was already dropped cannot log out a session a parallel connect just set up, and a reconnect approved while a read dropped the signer puts that signer back and emits
connect.The ephemeral signer used for
wallet_sendCalls,wallet_sign, the permission methods andwallet_addFundsleft session keys (CrossPlatform) or a persisted account (AppSpecific) behind when the request was rejected. Cleanup now runs in afinally, andAppSpecificSigner.cleanupclears its own state even when the UI handler's cleanup throws. If a connect finished while the temporary signer was open, its cleanup is skipped, because the stored account, signer type and keys now belong to the new session.Backend refusals from #321 are kept: a 4100 the backend marks as a refusal still never disconnects, so the teardown now needs all three: a 4100, from the signer this request used, that is not a backend refusal. Two new tests send a 403 through the real AppSpecific signer, on a live session and on an expired one, and both fail if the refusal check is removed.
The provider conformance suite now runs in both authentication modes, and the comment on the chain lists says the
readonlyguard is shallow.Closes N/A. Part of ENGR-1282.
How to test
bun install bunx nx run-many -t typecheck lint test --projects=@jaw.id/core bunx nx build @jaw.id/coreBy hand, in the playground in AppSpecific mode: connect, then shorten the session (or move the clock past the auth TTL) and call
eth_accounts. The dApp should receiveaccountsChangedwith[]and onedisconnect, and a reconnect should ask for the passkey once without a fresh login. Rejecting awallet_sendCallsmade while disconnected should leave no stored account behind.Checklist
nx releasetakes the version bump from its typebunx prettier --check .andbunx nx affected -t lint test typecheck build api-checkpass, which is what CI runs@jaw.id/core's public API is unchanged, orbunx nx api-update @jaw.id/coreran and the report diff is part of this PR