Skip to content

Commit

Permalink
Implement dAG per project & some UI improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
luistorres committed Apr 4, 2024
1 parent 8b60492 commit 5da4210
Show file tree
Hide file tree
Showing 31 changed files with 803 additions and 546 deletions.
2 changes: 1 addition & 1 deletion packages/web-app/.env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Wallet Connect Test Project ID
NEXT_PUBLIC_WC_PROJECT_ID=dc06360fc1be7532d4b5c25fc78bcfe9
NEXT_PUBLIC_ENABLE_TESTNETS=true
NEXT_PUBLIC_PROFILE_PROVIDER_BASE=https://app.next.fractal.id/authorize?client_id=PVPpKr2UQmc86cmf_2xsjUB5gDECYPGsAh5P3vyQM_4&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&response_type=code&scope=contact%3Aread%20verification.basic%3Aread%20verification.basic.details%3Aread%20verification.liveness%3Aread%20verification.liveness.details%3Aread
NEXT_PUBLIC_PROFILE_PROVIDER_BASE=https://app.next.fractal.id/authorize?client_id=PVPpKr2UQmc86cmf_2xsjUB5gDECYPGsAh5P3vyQM_4&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&response_type=code&scope=contact%3Aread%20verification.plus%3Aread%20verification.plus.details%3Aread
NEXT_PUBLIC_IDOS_NODE_URL=https://nodes.playground.idos.network
NEXT_PUBLIC_IDOS_DB_ID=x625a832c84f02fbebb229ee3b5e66b6767802b29d87acf72b8dd05d1
NEXT_PUBLIC_IDOS_CONTRACT_ADDRESS=0x1673b9fD14C30332990314d99826F22a628A2601
Expand Down
43 changes: 1 addition & 42 deletions packages/web-app/app/_lib/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const useInsertGrantBySignatureMutation = () => {
// invalidate queries after 10 seconds
setTimeout(() => {
// update once we know the id
queryClient.invalidateQueries({ queryKey: ['grants', owner, grantee] });
queryClient.invalidateQueries({ queryKey: ['grants', owner] });
}, 10000);
},
});
Expand All @@ -81,41 +81,6 @@ type TNewDataIdMutation = {
encryptionPublicKey: string;
};

// export const useGenerateNewDataIdMutation = () => {
// const { sdk, hasSigner } = useIdOS();

// return useMutation({
// mutationFn: async ({ id, encryptionPublicKey }: TNewDataIdMutation) => {
// if (!sdk || !hasSigner) return null;

// console.log(
// '%c==>',
// 'color: green; background: yellow; font-size: 20px',
// id,
// encryptionPublicKey,
// );

// try {
// const { id: dataId } = await sdk.data.share(
// 'credentials',
// id,
// encryptionPublicKey,
// );

// return dataId;
// } catch (error) {
// console.log(
// '%c==>',
// 'color: green; background: purple; font-size: 20px',
// error,
// );

// return null;
// }
// },
// });
// };

export const useSignDelegatedAccessGrant = (
grantee: string,
encryptionPublicKey: string,
Expand Down Expand Up @@ -155,12 +120,6 @@ export const useSignDelegatedAccessGrant = (
!isGrantInsertSuccess &&
!isServerPending
) {
console.log(
'%c==>',
'color: green; background: yellow; font-size: 20px',
'INSERT GRANT',
);

insertGrant({
grantee,
dataId,
Expand Down
87 changes: 54 additions & 33 deletions packages/web-app/app/_lib/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,63 +47,84 @@ export const useKycCredential = () => {
};

export const useHasCitizendGrant = () => {
const { shares, isLoading, error, isSuccess } = useKyc();
const { data: citizendPublicInfo, isSuccess: isServerQuerySuccess } =
usePublicInfo();
const {
data: citizendGrants,
isLoading: isLoadingGrants,
error: grantsError,
isSuccess: isGrantsSuccess,
refetch,
} = useFetchGrants(citizendPublicInfo?.grantee);
shares,
grants,
isLoading: isKycLoading,
error: kycError,
isSuccess: isKycSucces,
} = useKyc();
const {
data: citizendPublicInfo,
isLoading: isProjectInfoLoading,
isSuccess: isServerQuerySuccess,
} = usePublicInfo();
const isLoading = isKycLoading || isProjectInfoLoading;
const error = kycError;
const isSuccess = isKycSucces && isServerQuerySuccess;

const citizendGrants = useMemo(
() =>
grants?.filter((grant) => grant.grantee === citizendPublicInfo?.grantee),
[grants, citizendPublicInfo],
);

// check if at least one of the citizendGrants dataId exists in the credential shares array
const hasGrant = useMemo(() => {
if (!citizendGrants || !shares) return false;
if (!citizendGrants?.length || !shares) return false;

return citizendGrants.some(
(grant) =>
shares.includes(grant.dataId) && isValidGrant(grant.lockedUntil),
);
}, [citizendGrants, shares]);

return {
hasGrant,
isLoading: isLoading || isLoadingGrants,
error: error || grantsError,
isSuccess: isSuccess && isServerQuerySuccess && isGrantsSuccess,
refetch,
};
return useMemo(() => {
return {
hasGrant,
isLoading,
error,
isSuccess,
};
}, [hasGrant, isLoading, error, isSuccess]);
};

export const useHasProjectGrant = (projectId: string) => {
const { shares, isLoading, error, isSuccess } = useKyc();
const {
shares,
grants,
isLoading: isKycLoading,
error: kycError,
isSuccess: isKycSucces,
} = useKyc();
const { data: projectPublicInfo, isSuccess: isProjectSuccess } =
useProjectPublicInfo(projectId as TProjectInfoArgs);
const {
data: projectGrants,
isLoading: isLoadingGrants,
error: grantsError,
isSuccess: isGrantsSuccess,
refetch,
} = useFetchGrants(projectPublicInfo?.address);
const isLoading = isKycLoading || !projectPublicInfo;
const error = kycError;
const isSuccess = isKycSucces && isProjectSuccess;

const projectGrants = useMemo(
() =>
grants?.filter((grant) => grant.grantee === projectPublicInfo?.address),
[grants, projectPublicInfo],
);

// check if at least one of the projectGrants dataId exists in the credential shares array
const hasGrant = useMemo(() => {
if (!projectGrants || !shares) return false;
if (!projectGrants?.length || !shares) return false;

return projectGrants.some(
(grant) =>
shares.includes(grant.dataId) && isValidGrant(grant.lockedUntil),
);
}, [projectGrants, shares]);

return {
hasGrant,
isLoading: isLoading || isLoadingGrants,
error: error || grantsError,
isSuccess: isSuccess && isProjectSuccess && isGrantsSuccess,
refetch,
};
return useMemo(() => {
return {
hasGrant,
isLoading,
error,
isSuccess,
};
}, [hasGrant, isLoading, error, isSuccess]);
};
10 changes: 5 additions & 5 deletions packages/web-app/app/_lib/queries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,16 @@ export const useFetchWallets = () => {
});
};

export const useFetchGrants = (grantee: string | undefined) => {
export const useFetchGrants = () => {
const { sdk, address, hasSigner } = useIdOS();

return useQuery({
queryKey: ['grants', address, grantee],
queryKey: ['grants', address],
queryFn: async () => {
if (!address || !grantee) return null;
return sdk?.grants.list({ owner: address, grantee });
if (!address) return null;
return sdk?.grants.list({ owner: address });
},
enabled: !!(sdk && hasSigner && address && grantee),
enabled: !!(sdk && hasSigner && address),
});
};

Expand Down
8 changes: 6 additions & 2 deletions packages/web-app/app/_providers/dialog/context.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
//create a dialog manager context
import { createContext, useContext, PropsWithChildren } from 'react';
import { createContext, useContext } from 'react';

export type TProps = {
[key: string]: string;
};

type TDialogContextValue = {
openDialog: string;
open: (name: string) => void;
open: (name: string, props?: TProps) => void;
close: () => void;
};

Expand Down
28 changes: 20 additions & 8 deletions packages/web-app/app/_providers/dialog/index.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
import { useMemo, useState, PropsWithChildren } from 'react';
import { DialogContext } from './context';
import { DialogContext, TProps } from './context';
import { DialogWrapper } from '@/app/_ui/components/dialogs/dialog-wrapper';
import { ContributeDialog, SettingsDialog } from '@/app/_ui/components/dialogs';
import { ApplyDialog, SettingsDialog } from '@/app/_ui/components/dialogs';

type TDialogComponent = {
(): JSX.Element;
displayName: string;
(props: TProps): JSX.Element;
};

const dialogComponents: TDialogComponent[] = [SettingsDialog, ContributeDialog];
const dialogComponents: TDialogComponent[] = [SettingsDialog, ApplyDialog];

const emptyProps = {};

export const DialogProvider = ({ children }: PropsWithChildren) => {
const [openDialog, setOpenDialog] = useState('');
const [props, setProps] = useState(emptyProps);

const state = useMemo(() => {
return {
openDialog,
open: setOpenDialog,
open: (name: string, props?: TProps) => {
setOpenDialog(name);
if (props) setProps(props);
},
close: () => {
setOpenDialog('');
// clear props after 300 ms to avoid flashes
if (props !== emptyProps) {
setTimeout(() => {
setProps(emptyProps);
}, 300);
}
},
};
}, [openDialog]);
}, [openDialog, props]);

return (
<DialogContext.Provider value={state}>
{children}
{dialogComponents.map((DialogComponent, index) => (
{dialogComponents.map((DialogComponent) => (
<DialogWrapper
key={DialogComponent.displayName}
show={openDialog === DialogComponent.displayName}
close={state.close}
>
<DialogComponent />
<DialogComponent {...props} />
</DialogWrapper>
))}
</DialogContext.Provider>
Expand Down
36 changes: 36 additions & 0 deletions packages/web-app/app/_providers/kyc/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { idOSCredentialStatus } from '@/app/_types/idos';
import { Grant } from '@idos-network/idos-sdk';
import { QueryObserverResult, RefetchOptions } from '@tanstack/react-query';
import { createContext, useContext } from 'react';

export type TWallet = {
address: string;
verified: boolean;
};

export type TKycContextValue = {
country: string | undefined;
wallet: TWallet | undefined;
id: string | undefined;
status: idOSCredentialStatus | undefined;
isLoading: boolean;
isSuccess: boolean;
error: any;
shares: string[] | undefined;
grants: Grant[] | null | undefined;
refetchGrants: (
options?: RefetchOptions | undefined,
) => Promise<QueryObserverResult<Grant[] | null | undefined, Error>>;
};

export const KycContext = createContext<TKycContextValue | null>(null);

export const useKyc = () => {
const kyc = useContext(KycContext);

if (!kyc) {
throw new Error('Kyc is not initialized');
}

return kyc;
};
Loading

0 comments on commit 5da4210

Please sign in to comment.