11import { CreateSpace } from '@/components/create-space' ;
22import { Button } from '@/components/ui/button' ;
3- import { useSpaces } from '@/hooks/use-spaces' ;
3+ import { usePrivateSpaces } from '@/hooks/use-private-spaces' ;
4+ import { type PublicSpaceData , usePublicSpaces } from '@/hooks/use-public-spaces' ;
45import { Connect , type Identity , Key , type Messages , StoreConnect , Utils } from '@graphprotocol/hypergraph' ;
56import { GEOGENESIS , GEO_TESTNET } from '@graphprotocol/hypergraph/connect/smart-account' ;
67import { useIdentityToken , usePrivy , useWallets } from '@privy-io/react-auth' ;
@@ -137,7 +138,31 @@ function AuthenticateComponent() {
137138
138139 const state = useSelector ( componentStore , ( state ) => state . context ) ;
139140
140- const { isPending, error : spacesError , data : spacesData } = useSpaces ( ) ;
141+ const { isPending : privateSpacesPending , error : privateSpacesError , data : privateSpacesData } = usePrivateSpaces ( ) ;
142+ const {
143+ isPending : publicSpacesPending ,
144+ error : publicSpacesError ,
145+ data : publicSpacesData ,
146+ } = usePublicSpaces ( import . meta. env . VITE_HYPERGRAPH_API_URL ) ;
147+
148+ const selectedPrivateSpaces = new Set < string > ( ) ;
149+ const selectedPublicSpaces = new Set < string > ( ) ;
150+
151+ const handlePrivateSpaceToggle = ( spaceId : string , checked : boolean ) => {
152+ if ( checked ) {
153+ selectedPrivateSpaces . add ( spaceId ) ;
154+ } else {
155+ selectedPrivateSpaces . delete ( spaceId ) ;
156+ }
157+ } ;
158+
159+ const handlePublicSpaceToggle = ( spaceId : string , checked : boolean ) => {
160+ if ( checked ) {
161+ selectedPublicSpaces . add ( spaceId ) ;
162+ } else {
163+ selectedPublicSpaces . delete ( spaceId ) ;
164+ }
165+ } ;
141166
142167 useEffect ( ( ) => {
143168 const run = async ( ) => {
@@ -217,55 +242,57 @@ function AuthenticateComponent() {
217242 return ;
218243 }
219244
220- const spacesInput = spacesData
221- ? spacesData . map ( ( space ) => {
222- // TODO: currently without checking we assume all keyboxes exists and we don't create any - we should check if the keyboxes exist and create them if they don't
223- if ( space . appIdentities . some ( ( spaceAppIdentity ) => spaceAppIdentity . address === appIdentity . address ) )
224- return {
225- id : space . id ,
226- keyBoxes : [ ] ,
227- } ;
228-
229- const spaceKeys = space . keyBoxes . map ( ( keyboxData ) => {
230- const key = Key . decryptKey ( {
231- privateKey : Utils . hexToBytes ( keys . encryptionPrivateKey ) ,
232- publicKey : Utils . hexToBytes ( keyboxData . authorPublicKey ) ,
233- keyBoxCiphertext : Utils . hexToBytes ( keyboxData . ciphertext ) ,
234- keyBoxNonce : Utils . hexToBytes ( keyboxData . nonce ) ,
245+ const privateSpacesInput = privateSpacesData
246+ ? privateSpacesData
247+ . filter ( ( space ) => selectedPrivateSpaces . has ( space . id ) )
248+ . map ( ( space ) => {
249+ // TODO: currently without checking we assume all keyboxes exists and we don't create any - we should check if the keyboxes exist and create them if they don't
250+ if ( space . appIdentities . some ( ( spaceAppIdentity ) => spaceAppIdentity . address === appIdentity . address ) )
251+ return {
252+ id : space . id ,
253+ keyBoxes : [ ] ,
254+ } ;
255+
256+ const spaceKeys = space . keyBoxes . map ( ( keyboxData ) => {
257+ const key = Key . decryptKey ( {
258+ privateKey : Utils . hexToBytes ( keys . encryptionPrivateKey ) ,
259+ publicKey : Utils . hexToBytes ( keyboxData . authorPublicKey ) ,
260+ keyBoxCiphertext : Utils . hexToBytes ( keyboxData . ciphertext ) ,
261+ keyBoxNonce : Utils . hexToBytes ( keyboxData . nonce ) ,
262+ } ) ;
263+ return {
264+ id : keyboxData . id ,
265+ key : key ,
266+ } ;
235267 } ) ;
236- return {
237- id : keyboxData . id ,
238- key : key ,
239- } ;
240- } ) ;
241268
242- const keyBoxes = spaceKeys . map ( ( keyData ) => {
243- const keyBox = Key . encryptKey ( {
244- privateKey : Utils . hexToBytes ( keys . encryptionPrivateKey ) ,
245- publicKey : Utils . hexToBytes ( appIdentity . encryptionPublicKey ) ,
246- key : keyData . key ,
269+ const keyBoxes = spaceKeys . map ( ( keyData ) => {
270+ const keyBox = Key . encryptKey ( {
271+ privateKey : Utils . hexToBytes ( keys . encryptionPrivateKey ) ,
272+ publicKey : Utils . hexToBytes ( appIdentity . encryptionPublicKey ) ,
273+ key : keyData . key ,
274+ } ) ;
275+ return {
276+ id : keyData . id ,
277+ ciphertext : Utils . bytesToHex ( keyBox . keyBoxCiphertext ) ,
278+ nonce : Utils . bytesToHex ( keyBox . keyBoxNonce ) ,
279+ authorPublicKey : appIdentity . encryptionPublicKey ,
280+ accountAddress : accountAddress ,
281+ } ;
247282 } ) ;
283+
248284 return {
249- id : keyData . id ,
250- ciphertext : Utils . bytesToHex ( keyBox . keyBoxCiphertext ) ,
251- nonce : Utils . bytesToHex ( keyBox . keyBoxNonce ) ,
252- authorPublicKey : appIdentity . encryptionPublicKey ,
253- accountAddress : accountAddress ,
285+ id : space . id ,
286+ keyBoxes,
254287 } ;
255- } ) ;
256-
257- return {
258- id : space . id ,
259- keyBoxes,
260- } ;
261- } )
288+ } )
262289 : [ ] ;
263290
264291 const message : Messages . RequestConnectAddAppIdentityToSpaces = {
265292 type : 'connect-add-app-identity-to-spaces' ,
266293 appIdentityAddress : appIdentity . address ,
267294 accountAddress,
268- spacesInput,
295+ spacesInput : privateSpacesInput ,
269296 } ;
270297
271298 // TODO add loading indicator by updating the state
@@ -293,7 +320,8 @@ function AuthenticateComponent() {
293320 signaturePrivateKey : appIdentity . signaturePrivateKey ,
294321 signaturePublicKey : appIdentity . signaturePublicKey ,
295322 encryptionPublicKey : appIdentity . encryptionPublicKey ,
296- spaces : spacesData ?. map ( ( space ) => ( { id : space . id } ) ) ?? [ ] ,
323+ privateSpaces : privateSpacesInput ?. map ( ( space ) => ( { id : space . id } ) ) ?? [ ] ,
324+ publicSpaces : publicSpacesData ?. map ( ( space ) => ( { id : space . id } ) ) ?? [ ] ,
297325 expiry : appInfo . expiry ,
298326 sessionToken : appIdentity . sessionToken ,
299327 sessionTokenExpires : appIdentity . sessionTokenExpires . getTime ( ) ,
@@ -336,7 +364,8 @@ function AuthenticateComponent() {
336364 } ;
337365
338366 const newAppIdentity = Connect . createAppIdentity ( ) ;
339- // TODO: add spaces and additional actions
367+
368+ // TODO: add additional actions (must be passed from the app)
340369 const permissionId = await Connect . createSmartSession (
341370 walletClient ,
342371 accountAddress ,
@@ -345,7 +374,16 @@ function AuthenticateComponent() {
345374 import . meta. env . VITE_HYPERGRAPH_RPC_URL ,
346375 {
347376 allowCreateSpace : true ,
348- spaces : [ ] ,
377+ spaces :
378+ publicSpacesData
379+ ?. filter ( ( space ) => selectedPublicSpaces . has ( space . id ) )
380+ . map ( ( space ) => ( {
381+ address :
382+ space . type === 'personal'
383+ ? ( space . personalAddress as `0x${string } `)
384+ : ( space . mainVotingAddress as `0x${string } `) ,
385+ type : space . type as 'personal' | 'public' ,
386+ } ) ) ?? [ ] ,
349387 additionalActions : [ ] ,
350388 } ,
351389 ) ;
@@ -472,20 +510,53 @@ function AuthenticateComponent() {
472510 </ div >
473511 < h2 className = "font-bold mb-2 mt-2" > Spaces</ h2 >
474512 < ul className = "space-y-4" >
475- { isPending && < p > Loading spaces …</ p > }
476- { spacesError && < p > An error has occurred loading spaces: { spacesError . message } </ p > }
477- { ! isPending && ! spacesError && spacesData ?. length === 0 && < p > No spaces found</ p > }
478- { spacesData ?. map ( ( space ) => (
479- < li key = { space . id } >
480- < p > { space . name } </ p >
481- < p className = "text-xs text-gray-500 mt-2 mb-1" > Apps with access to this space</ p >
482- < ul >
483- { space . apps . map ( ( app ) => (
484- < li key = { app . id } className = "text-sm" >
485- { app . name }
486- </ li >
487- ) ) }
488- </ ul >
513+ { privateSpacesPending && < p > Loading private spaces …</ p > }
514+ { privateSpacesError && < p > An error has occurred loading private spaces: { privateSpacesError . message } </ p > }
515+ { ! privateSpacesPending && ! privateSpacesError && privateSpacesData ?. length === 0 && (
516+ < p > No private spaces found</ p >
517+ ) }
518+ { privateSpacesData ?. map ( ( space ) => (
519+ < li key = { space . id } className = "flex items-center gap-3 p-3 border rounded-lg" >
520+ < input
521+ type = "checkbox"
522+ id = { `private-${ space . id } ` }
523+ checked = { selectedPrivateSpaces . has ( space . id ) }
524+ onChange = { ( e ) => handlePrivateSpaceToggle ( space . id , e . target . checked ) }
525+ className = "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"
526+ />
527+ < label htmlFor = { `private-${ space . id } ` } className = "flex-1 cursor-pointer" >
528+ < p className = "font-medium" > { space . name } </ p >
529+ < p className = "text-xs text-gray-500 mt-2 mb-1" > Apps with access to this space</ p >
530+ < ul >
531+ { space . apps . map ( ( app ) => (
532+ < li key = { app . id } className = "text-sm" >
533+ { app . name }
534+ </ li >
535+ ) ) }
536+ </ ul >
537+ </ label >
538+ </ li >
539+ ) ) }
540+ </ ul >
541+ < h2 className = "font-bold mb-2 mt-2" > Public Spaces</ h2 >
542+ < ul className = "space-y-4" >
543+ { publicSpacesPending && < p > Loading public spaces …</ p > }
544+ { publicSpacesError && < p > An error has occurred loading public spaces: { publicSpacesError . message } </ p > }
545+ { ! publicSpacesPending && ! publicSpacesError && publicSpacesData ?. length === 0 && (
546+ < p > No public spaces found</ p >
547+ ) }
548+ { publicSpacesData ?. map ( ( space : PublicSpaceData ) => (
549+ < li key = { space . id } className = "flex items-center gap-3 p-3 border rounded-lg" >
550+ < input
551+ type = "checkbox"
552+ id = { `public-${ space . id } ` }
553+ checked = { selectedPublicSpaces . has ( space . id ) }
554+ onChange = { ( e ) => handlePublicSpaceToggle ( space . id , e . target . checked ) }
555+ className = "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"
556+ />
557+ < label htmlFor = { `public-${ space . id } ` } className = "flex-1 cursor-pointer" >
558+ < p className = "font-medium" > { space . name } </ p >
559+ </ label >
489560 </ li >
490561 ) ) }
491562 </ ul >
0 commit comments