useLitSession.ts
1 import { useState, useCallback } from 'react' 2 import { useAccount, useSignMessage } from 'wagmi' 3 import { litProtocolService } from '../lib/litProtocol' 4 import { 5 createSiweMessageWithRecaps, 6 generateAuthSig, 7 LitActionResource 8 } from '@lit-protocol/auth-helpers' 9 import { LIT_ABILITY } from '@lit-protocol/constants' 10 11 export function useLitSession() { 12 const { address } = useAccount() 13 const { signMessageAsync } = useSignMessage() 14 const [sessionSigs, setSessionSigs] = useState<any>(null) 15 const [isCreatingSession, setIsCreatingSession] = useState(false) 16 const [error, setError] = useState<string | null>(null) 17 18 const createSession = useCallback(async () => { 19 if (!address) { 20 setError('Wallet not connected') 21 return null 22 } 23 24 setIsCreatingSession(true) 25 setError(null) 26 27 try { 28 // Ensure Lit Protocol is connected 29 await litProtocolService.connect() 30 31 if (!litProtocolService.litNodeClient) { 32 throw new Error('Failed to initialize Lit Protocol') 33 } 34 35 console.log('🔐 Creating Lit session for:', address) 36 37 // Create session configuration based on whether we have capacity delegation 38 const sessionConfig: any = { 39 chain: 'ethereum', // Use ethereum for session (user's wallet chain) 40 expiration: new Date(Date.now() + 1000 * 60 * 60).toISOString(), // 1 hour 41 resourceAbilityRequests: [ 42 { 43 resource: new LitActionResource('*'), 44 ability: LIT_ABILITY.LitActionExecution, 45 }, 46 ], 47 authNeededCallback: async ({ 48 uri, 49 expiration, 50 resourceAbilityRequests, 51 }: { 52 uri?: string; 53 expiration?: string; 54 resourceAbilityRequests?: any[]; 55 }) => { 56 const toSign = await createSiweMessageWithRecaps({ 57 uri: uri || window.location.origin, 58 expiration: expiration || new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), 59 resources: resourceAbilityRequests || [], 60 walletAddress: address, 61 nonce: await litProtocolService.litNodeClient!.getLatestBlockhash(), 62 litNodeClient: litProtocolService.litNodeClient!, 63 domain: window.location.hostname, 64 statement: "Sign in to search songs", // Simple ASCII statement 65 }) 66 67 // Create a signer object that works with wagmi's signMessageAsync 68 const signer = { 69 signMessage: async (message: string) => signMessageAsync({ message }), 70 getAddress: async () => address 71 } 72 73 return await generateAuthSig({ 74 signer: signer as any, 75 toSign 76 }) 77 }, 78 } 79 80 // No capacity delegation needed for dev network 81 console.log('📋 Creating session for dev network (no capacity delegation needed)') 82 83 const sessionSigs = await litProtocolService.litNodeClient.getSessionSigs(sessionConfig) 84 85 console.log('✅ Session created successfully') 86 87 setSessionSigs(sessionSigs) 88 89 // Store in the service for use in grading 90 litProtocolService.setSessionSigs(sessionSigs) 91 92 return sessionSigs 93 } catch (err) { 94 console.error('❌ Failed to create session:', err) 95 setError(err instanceof Error ? err.message : 'Failed to create session') 96 return null 97 } finally { 98 setIsCreatingSession(false) 99 } 100 }, [address, signMessageAsync]) 101 102 return { 103 sessionSigs, 104 isCreatingSession, 105 error, 106 createSession, 107 hasValidSession: !!sessionSigs 108 } 109 }