Skip to content

Commit

Permalink
fix issue on onchain platform
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdi-torabiv committed Aug 29, 2024
1 parent fd7950a commit d600346
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 41 deletions.
5 changes: 4 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ const App: React.FC = () => {
</ProtectedRoute>
}
>
<Route path="/" element={<Dashboard />} />
<Route
path="/"
element={<Navigate to="/identifiers" />}
/>
<Route path="/identifiers" element={<Identifiers />} />
<Route
path="identifiers/:providers/attestation"
Expand Down
10 changes: 10 additions & 0 deletions src/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import { Navigate } from 'react-router-dom';
import CircularProgress from '@mui/material/CircularProgress';
import Backdrop from '@mui/material/Backdrop';
import { useAccount } from 'wagmi';

interface ProtectedRouteProps {
children: JSX.Element;
Expand All @@ -11,6 +12,15 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
const [loading, setLoading] = useState<boolean>(true);
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);

const { isConnected } = useAccount();

useEffect(() => {
if (!isConnected) {
setIsAuthenticated(false);
localStorage.removeItem('OCI_TOKEN');
}
}, [isConnected]);

useEffect(() => {
const checkAuthStatus = async () => {
const token = localStorage.getItem('OCI_TOKEN');
Expand Down
12 changes: 6 additions & 6 deletions src/libs/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import SpaceDashboardIcon from '@mui/icons-material/SpaceDashboard';
// import SpaceDashboardIcon from '@mui/icons-material/SpaceDashboard';
import FingerprintIcon from '@mui/icons-material/Fingerprint';
import { SiAdguard } from 'react-icons/si';
import { SvgIconComponent } from '@mui/icons-material';
Expand All @@ -13,11 +13,11 @@ export interface MenuItem {
export const DRAWER_WIDTH = 240;

export const SIDEBAR_MENU: MenuItem[] = [
{
title: 'Dashboard',
path: '/',
icon: SpaceDashboardIcon,
},
// {
// title: 'Dashboard',
// path: '/',
// icon: SpaceDashboardIcon,
// },
{
title: 'Identifiers',
path: '/identifiers',
Expand Down
21 changes: 20 additions & 1 deletion src/pages/Identifiers/Attestation/Attestation.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, useEffect } from 'react';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
Expand All @@ -21,6 +22,7 @@ import {
convertStringsToBigInts,
getTokenForProvider,
} from '../../../utils/helper';
import useSnackbarStore from '../../../store/useSnackbarStore';

const steps = [{ label: 'Auth' }, { label: 'Attest' }, { label: 'Transact' }];

Expand All @@ -31,7 +33,7 @@ type DecodedToken = { provider: Provider; iat: number; exp: number };
export function Attestation() {
const { isConnected, address } = useAccount();
const signer = useSigner();

const { showSnackbar } = useSnackbarStore();
const { providers } = useParams<{ providers: 'DISCORD' | 'GOOGLE' }>();
const location = useLocation();
const navigate = useNavigate();
Expand Down Expand Up @@ -149,9 +151,26 @@ export function Attestation() {

const newAttestationUID = await tx.wait();

showSnackbar('Attestation created successfully', {
severity: 'success',
});

navigate('/identifiers');

console.log('New attestation UID:', newAttestationUID);

console.log('Transaction receipt:', tx.receipt);
} catch (error: any) {
const errorCode = error?.info?.error?.code || '';

if (errorCode === 4001) {
showSnackbar(
`${errorCode}, you reject the transaction. please try again...`,
{
severity: 'error',
}
);
}
} finally {
setIsAttesting(false);
}
Expand Down
30 changes: 23 additions & 7 deletions src/pages/Identifiers/Identifiers.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState, useCallback } from 'react';
import {
Expand Down Expand Up @@ -38,6 +39,7 @@ import {
} from '../../services/api/eas/query';
import { RevokePayload } from '../../interfaces';
import { convertStringsToBigInts } from '../../utils/helper';
import useSnackbarStore from '../../store/useSnackbarStore';

interface IdentifierItemProps {
identifier: {
Expand Down Expand Up @@ -108,7 +110,7 @@ const IdentifierItem: React.FC<IdentifierItemProps> = ({
{identifier.verified ? (
<Button
variant="outlined"
color="error"
color="inherit"
onClick={() => onRevoke(identifier.uid)}
disabled={isLoading}
startIcon={isLoading ? <CircularProgress size={16} /> : null}
Expand All @@ -131,7 +133,10 @@ const IdentifierItem: React.FC<IdentifierItemProps> = ({
);

export function Identifiers() {
const { showSnackbar } = useSnackbarStore();
const { chainId } = useAccount();
const navigate = useNavigate();

const signer = useSigner();

const [identifiers, setIdentifiers] = useState([
Expand Down Expand Up @@ -226,8 +231,6 @@ export function Identifiers() {
setRevealedIdentifiers(initialRevealedState);
}, [attestations]);

const navigate = useNavigate();

const handleRevoke = useCallback(
(uid: string) => {
const siweJwt = localStorage.getItem('OCI_TOKEN');
Expand Down Expand Up @@ -307,7 +310,7 @@ export function Identifiers() {
useEffect(() => {
const revokeIdentifier = async () => {
if (revokeIdentifierResponse) {
console.log('Revoke identifier response', revokeIdentifierResponse);
console.log('Revoke identifier response:', revokeIdentifierResponse);

const payload: RevokePayload = convertStringsToBigInts(
revokeIdentifierResponse.data
Expand Down Expand Up @@ -337,8 +340,12 @@ export function Identifiers() {
};

const tx = await eas.revokeByDelegation(transformedPayload);

await tx.wait();
console.log({ tx });

showSnackbar('Identifier revoked successfully', {
severity: 'success',
});

setLoadingIdentifiers((prev) => ({
...prev,
Expand All @@ -347,8 +354,17 @@ export function Identifiers() {
} else {
throw new Error('Invalid message type for revocation');
}
} catch (error) {
console.error('Error during revocation:', error);
} catch (error: any) {
const errorCode = error?.info?.error?.code || '';

if (errorCode === 4001) {
showSnackbar(
`${errorCode}, you reject the transaction. please try again...`,
{
severity: 'error',
}
);
}

if ('uid' in payload.message) {
setLoadingIdentifiers((prev) => ({
Expand Down
149 changes: 123 additions & 26 deletions src/pages/Permissions/Permissions.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useEffect, useMemo, useState } from 'react';
import { useReadContract, useReadContracts, useWriteContract } from 'wagmi';
import {
useReadContract,
useReadContracts,
useWriteContract,
useWaitForTransactionReceipt,
} from 'wagmi';
import { Address, Abi } from 'viem';
import { Backdrop, CircularProgress, Stack, Typography } from '@mui/material';
import {
Alert,
Backdrop,
Box,
Button,
CircularProgress,
Stack,
Typography,
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useGetAttestations } from '../../services/eas/query';
import sepoliaChainAppConctract from '../../utils/contracts/app/sepoliaChain.json';
import sepoliaChainOidonctract from '../../utils/contracts/oid/sepoliaChain.json';
Expand All @@ -11,11 +26,26 @@ import CustomTable, {
Platform,
AccessData,
} from '../../components/shared/CustomTable';
import useSnackbarStore from '../../store/useSnackbarStore';

export function Permissions() {
const { writeContract, isPending: isWriting } = useWriteContract();
const { data: attestationsResponse, isLoading: isLoadingAttestations } =
useGetAttestations();
const { showSnackbar } = useSnackbarStore();
const navigate = useNavigate();
const {
data: transactionHash,
writeContract,
isPending: isWriting,
} = useWriteContract();
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash: transactionHash,
});

const {
data: attestationsResponse,
isLoading: isLoadingAttestations,
refetch: refetchAttestations,
} = useGetAttestations();
const [applicationsArgs] = useState<[number, number]>([0, 10]);
const [attestations, setAttestations] = useState<
(IAttestation & { provider?: string; id?: string })[]
Expand All @@ -28,6 +58,7 @@ export function Permissions() {
data,
isLoading: isLoadingApplications,
error,
refetch: refetchApplications,
} = useReadContract({
abi: sepoliaChainAppConctract.appContractABI,
address: sepoliaChainAppConctract.appContractAddress as Address,
Expand Down Expand Up @@ -87,10 +118,13 @@ export function Permissions() {
[attestations, applications]
);

const { data: hasPermissionsOnApp, isLoading: isLoadingPermissions } =
useReadContracts({
contracts: contractCalls,
});
const {
data: hasPermissionsOnApp,
isLoading: isLoadingPermissions,
refetch: refetchPermissions,
} = useReadContracts({
contracts: contractCalls,
});

useEffect(() => {
if (hasPermissionsOnApp) {
Expand Down Expand Up @@ -137,21 +171,51 @@ export function Permissions() {
}));

const handleGrantOrRevokeAccess = (application: any, platform: any) => {
writeContract({
abi: sepoliaChainOidonctract.oidContractAbi as Abi,
address: sepoliaChainOidonctract.oidContractAddress as Address,
functionName: application.hasPermission
? 'revokePermission'
: 'grantPermission',
args: [platform.uid, application.account],
});
writeContract(
{
abi: sepoliaChainOidonctract.oidContractAbi as Abi,
address: sepoliaChainOidonctract.oidContractAddress as Address,
functionName: application.hasPermission
? 'revokePermission'
: 'grantPermission',
args: [platform.uid, application.account],
},
{
// eslint-disable-next-line @typescript-eslint/no-shadow
onError: (error: any) => {
const errorCode = error.cause?.code || error.code;

if (errorCode === 4001) {
showSnackbar(
`${errorCode}, you rejected the transaction. Please try again...`,
{
severity: 'error',
}
);
} else {
showSnackbar(`Transaction failed: ${error.message}`, {
severity: 'error',
});
}
},
}
);
};

useEffect(() => {
if (isConfirmed) {
refetchAttestations();
refetchApplications();
refetchPermissions();
}
}, [isConfirmed]);

const isLoading =
isWriting ||
isLoadingAttestations ||
isLoadingApplications ||
isLoadingPermissions;
isLoadingPermissions ||
isConfirming;

return (
<div>
Expand All @@ -176,14 +240,47 @@ export function Permissions() {
</Typography>
</Stack>
</Backdrop>
<Typography variant="h6" gutterBottom>
Permissions
</Typography>
<CustomTable
xcolumns={providers}
ycolumns={permissionsWithUidsAndApps}
handleGrantOrRevokeAccess={handleGrantOrRevokeAccess}
/>
{!isLoading && providers.length === 0 ? (
<Box
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '80vh',
}}
>
<Alert severity="warning" sx={{ mb: 2 }}>
To be able to grant or revoke access to applications, you need to
have at least one identifier.
</Alert>
<Button
variant="contained"
color="warning"
onClick={() => {
navigate('/identifiers');
}}
>
Go to Identifiers
</Button>
</Box>
) : (
<>
<Typography variant="h6" gutterBottom>
Permissions
</Typography>
<Alert severity="info" sx={{ mb: 2 }}>
<b>Note</b>: The process of revoking or granting access to
applications may take some time.
</Alert>
<CustomTable
xcolumns={providers}
ycolumns={permissionsWithUidsAndApps}
handleGrantOrRevokeAccess={handleGrantOrRevokeAccess}
/>
</>
)}
</div>
);
}
Loading

0 comments on commit d600346

Please sign in to comment.