Internalize provisioning + session.established event - #1171
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
There was a problem hiding this comment.
should we move this and pendingGiftCardMintTermsAcceptedAt related code after these cache prefetches since they are only needed down there were acceptTerms is called?
There was a problem hiding this comment.
Agreed — pure locality move. The storage get/remove is independent of the prefetches, so reordering doesn't change behavior; it just puts the pending-terms reads next to the acceptTerms call that uses them. I'll fold it in.
There was a problem hiding this comment.
Done in 2aff3f6 — pure move, the pending-terms reads now sit right above the acceptTerms block. Read/remove logic unchanged.
Provisioning moves out of the web host into the SDK, fired on auth
session-start and guarded by an in-memory identity fingerprint. The host
seeds its caches from a new replay-latest auth.session-started event
instead of orchestrating provisioning itself.
SDK:
- Provision the settled user post-establish on every auth transition
(signUp / signInGuest / signIn / restore / mid-session change),
fingerprint-guarded (userId, email, emailVerified) so it re-runs only on
an identity change. Master's failure behavior is preserved: upsert via
withRetry, no retry on ZodError, terminal failure throws.
- New auth.session-started event { user, accounts } with replay-latest;
events.clear() drops all retained replay payloads on session end.
- acceptTerms(timestamp) decoupled from provision; the host stamps the
real acceptance time.
- createUserProvisioner owns the fingerprint guard and its reset;
auth-service only notifies that a session started and the SDK layer
decides that means provisioning.
- accounts.list() and the event return bare Account[]; getExtendedAccounts
stays exported as a caller-side selector for isDefault (see #1170).
Web:
- Delete the hasUserChanged gate and ensureUserData provisioning from
_protected.tsx; a boot-registered session-started consumer seeds the
user + accounts caches.
- Restore path re-throws a terminal provision failure to the error
boundary (matches live), booting anonymous only on a genuine restore
failure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2aff3f6 to
973f625
Compare
…and provisioning Extracts the accounts slice of the wallet into @agicash/wallet-sdk: the web app reads accounts, session keys, user, and provisioning through the SDK contract instead of owning that logic. - accounts namespace (sdk.accounts.*) backed by an in-SDK repository, with a /temporary bridge for repositories not yet migrated. - session-scoped key plumbing: derivation memos fenced by an AbortController scope and revocable on session end; web key queries call the derivation leaves directly. - user provisioning internalized on the auth lifecycle, fingerprint-guarded, fired on a replay-latest auth.session-started event the host seeds its caches from; acceptTerms decoupled from provision. - session-lifecycle hardening: typed SessionEndedError / DisposedError, terminal dispose, explicit guarded Encryption facade. - accounts.list() and the event return bare Account[]; getExtendedAccounts exported as a caller-side selector for isDefault (see #1170). Squashes #1167 (includes #1168 and #1171). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…and provisioning Extracts the accounts slice of the wallet into @agicash/wallet-sdk: the web app reads accounts, session keys, user, and provisioning through the SDK contract instead of owning that logic. - accounts namespace (sdk.accounts.*) backed by an in-SDK repository, with a /temporary bridge for repositories not yet migrated. - session-scoped key plumbing: derivation memos fenced by an AbortController scope and revocable on session end; web key queries call the derivation leaves directly. - user provisioning internalized on the auth lifecycle, fingerprint-guarded, fired on a replay-latest auth.session-started event the host seeds its caches from; acceptTerms decoupled from provision. - session-lifecycle hardening: typed SessionEndedError / DisposedError, terminal dispose, explicit guarded Encryption facade. - accounts.list() and the event return bare Account[]; getExtendedAccounts exported as a caller-side selector for isDefault (see #1170). Squashes #1167 (includes #1168 and #1171). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Moves provisioning into the SDK on the auth lifecycle and adds a
session.establishedevent so the host seeds its caches by plain reads. Removes the web-side provisioning orchestration.SDK
(userId, email, emailVerified)so it re-runs only on identity change.withRetry(2×), no retry onZodError, terminal failure throws. On restore that surfaces the error boundary, as live does today.session.establishedevent{ user, accounts }with replay-latest (a late subscriber gets the current payload immediately); cleared on session end.acceptTerms(timestamp)decoupled from provision — the host stamps the real click timestamp.accounts.list()andsession.establishedreturn bareAccount[];getExtendedAccountsstays exported as a caller-side selector forisDefault. See Accounts — make isDefault a first-class, SDK-owned field with change notification #1170 for the deferred design that would makeisDefaulta first-class SDK-owned field with change notification.Web
hasUserChangedgate andensureUserData's provisioning call from_protected.tsx— provisioning is SDK-internal now.session.establishedconsumer seedsUserCache+AccountsCachefrom the event at boot.acceptTermswith the real click timestamp.Verification
fix:allclean · wallet-sdk 132 pass / 0 fail + typecheck green · web 38 pass / 0 fail + typecheck green.session.established(fingerprint + retained-event reset on session end).Sequencing
Merges into
sdk/accounts-slice; accounts-slice + #1167 then go to master as one whole.