From 911713e9aacf21c9dd6826fbc09f20c5348fc480 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 11 Mar 2026 20:21:18 -0700 Subject: [PATCH] fix(rcart): use rstack-identity auth instead of separate passkey flow folk-payment-request now triggers the rstack-identity auth modal instead of its own passkey flow. This ensures the username displays correctly in the identity badge and avoids duplicate session management. Also checks both session sources for wallet address and access token. Co-Authored-By: Claude Opus 4.6 --- .../rcart/components/folk-payment-request.ts | 102 ++++++++---------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/modules/rcart/components/folk-payment-request.ts b/modules/rcart/components/folk-payment-request.ts index 1c61e8e..65e84cb 100644 --- a/modules/rcart/components/folk-payment-request.ts +++ b/modules/rcart/components/folk-payment-request.ts @@ -71,75 +71,56 @@ class FolkPaymentRequest extends HTMLElement { private async checkExistingSession() { try { + // Check both session managers (SessionManager + rstack-identity) const { getSessionManager } = await import('../../../src/encryptid/session'); - const session = getSessionManager(); - if (session.isValid()) { - this.did = session.getDID() || ''; - const state = session.getSession(); - this.walletAddress = state?.claims?.eid?.walletAddress || ''; + const sm = getSessionManager(); + const { getSession } = await import('../../../shared/components/rstack-identity'); + const rstackSession = getSession(); - // If session exists but no wallet address, try deriving from key manager - if (!this.walletAddress) { - try { - const { getKeyManager } = await import('../../../src/encryptid/key-derivation'); - const km = getKeyManager(); - if (km.isInitialized()) { - const keys = await km.getKeys(); - if (keys.eoaAddress) this.walletAddress = keys.eoaAddress; - } - } catch { /* key manager not ready */ } - } + const hasSession = sm.isValid() || !!rstackSession; + if (!hasSession) return; - if (this.walletAddress) { - this.authenticated = true; - this.render(); - } + // Get DID from either source + this.did = sm.getDID() || rstackSession?.claims?.did || rstackSession?.claims?.sub || ''; + + // Get wallet address from session claims + const smState = sm.getSession(); + this.walletAddress = smState?.claims?.eid?.walletAddress || rstackSession?.claims?.eid?.walletAddress || ''; + + // If session exists but no wallet address, try deriving from key manager + if (!this.walletAddress) { + try { + const { getKeyManager } = await import('../../../src/encryptid/key-derivation'); + const km = getKeyManager(); + if (km.isInitialized()) { + const keys = await km.getKeys(); + if (keys.eoaAddress) this.walletAddress = keys.eoaAddress; + } + } catch { /* key manager not ready */ } + } + + if (this.walletAddress) { + this.authenticated = true; + this.render(); + } } } catch { /* session module not available */ } } private async authenticate() { - this.authenticating = true; - this.authError = ''; - this.render(); - - try { - const { authenticatePasskey } = await import('../../../src/encryptid/webauthn'); - const { deriveEOAFromPRF } = await import('../../../src/encryptid/eoa-derivation'); - const { getSessionManager } = await import('../../../src/encryptid/session'); - const { EncryptIDKeyManager } = await import('../../../src/encryptid/key-derivation'); - - const result = await authenticatePasskey(); - if (!result.prfOutput) { - throw new Error('Your passkey does not support PRF — wallet address cannot be derived'); - } - - const eoa = deriveEOAFromPRF(new Uint8Array(result.prfOutput)); - this.walletAddress = eoa.address; - - // Initialize key manager for session - const km = new EncryptIDKeyManager(); - await km.initFromPRF(result.prfOutput); - const keys = await km.getKeys(); - this.did = keys.did; - - // Create session - const session = getSessionManager(); - await session.createSession(result, keys.did, { - encrypt: true, - sign: true, - wallet: true, + // Trigger the rstack-identity auth modal instead of a separate passkey flow + const identity = document.querySelector('rstack-identity') as any; + if (identity?.showAuthModal) { + identity.showAuthModal({ + onSuccess: () => { + // Re-check session after auth completes + this.checkExistingSession(); + }, }); - - // Zero private key — we don't need to sign anything here - eoa.privateKey.fill(0); - - this.authenticated = true; - } catch (e) { - this.authError = e instanceof Error ? e.message : String(e); + } else { + this.authError = 'Identity component not available. Please sign in from the top-right menu.'; + this.render(); } - this.authenticating = false; - this.render(); } // ── Load existing payment from URL ── @@ -195,8 +176,9 @@ class FolkPaymentRequest extends HTMLElement { try { const { getSessionManager } = await import('../../../src/encryptid/session'); + const { getSession: getRstackSession } = await import('../../../shared/components/rstack-identity'); const session = getSessionManager(); - const accessToken = session.getSession()?.accessToken; + const accessToken = session.getSession()?.accessToken || getRstackSession()?.accessToken; const res = await fetch(`${this.getApiBase()}/api/payments`, { method: 'POST',