Skip to content

Commit

Permalink
integrate attestation & permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdi-torabiv committed Aug 27, 2024
1 parent 916200a commit fa43b93
Show file tree
Hide file tree
Showing 16 changed files with 7,606 additions and 775 deletions.
7,233 changes: 6,636 additions & 597 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,27 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@ethereum-attestation-service/eas-sdk": "^2.5.0",
"@fontsource/inter": "^5.0.19",
"@fontsource/roboto": "^5.0.13",
"@lit-protocol/lit-node-client": "^6.4.0",
"@lit-protocol/types": "^6.4.0",
"@mui/icons-material": "^5.16.0",
"@mui/material": "^5.16.0",
"@rainbow-me/rainbowkit": "^2.1.3",
"@react-icons/all-files": "^4.1.0",
"@tanstack/react-query": "^5.51.21",
"@tanstack/react-query-devtools": "^5.50.1",
"axios": "^1.7.2",
"ethers": "^6.13.2",
"jwt-decode": "^4.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.52.1",
"react-icons": "^5.2.1",
"react-router-dom": "^6.24.1",
"viem": "^2.18.6",
"vite-plugin-node-polyfills": "^0.22.0",
"wagmi": "^2.12.2",
"zod": "^3.23.8",
"zustand": "^4.5.4"
Expand Down
88 changes: 47 additions & 41 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { sepolia } from 'wagmi/chains';
import { getAddress } from 'viem';
import { createSiweMessage } from 'viem/siwe';
import { LitNetwork } from '@lit-protocol/constants';
import Login from './pages/Auth/Login';
import theme from './libs/theme';
import { api } from './services/api';
Expand All @@ -28,6 +29,7 @@ import Permissions from './pages/Permissions';
import Attestation from './pages/Identifiers/Attestation';
import Callback from './pages/Callback';
import ProtectedRoute from './ProtectedRoute';
import { LitProvider } from './hooks/LitProvider';

const queryClient = new QueryClient({
defaultOptions: {
Expand Down Expand Up @@ -108,51 +110,55 @@ const App: React.FC = () => {
console.log('authStatus', authStatus);
}, [authStatus]);

globalThis.Buffer = Buffer;

return (
<BrowserRouter>
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitAuthenticationProvider
adapter={authenticationAdapter}
status={authStatus}
>
<RainbowKitProvider initialChain={sepolia}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Routes>
<Route
path="/auth/login"
element={
authStatus === 'authenticated' ? (
<Navigate to="/" replace />
) : (
<Login />
)
}
/>
<Route
element={
<ProtectedRoute>
<DefaultLayout />
</ProtectedRoute>
}
>
<Route path="/" element={<Dashboard />} />
<Route path="/identifiers" element={<Identifiers />} />
<LitProvider litNetwork={LitNetwork.DatilDev}>
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitAuthenticationProvider
adapter={authenticationAdapter}
status={authStatus}
>
<RainbowKitProvider initialChain={sepolia}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Routes>
<Route
path="identifiers/:provider/attestation"
element={<Attestation />}
path="/auth/login"
element={
authStatus === 'authenticated' ? (
<Navigate to="/" replace />
) : (
<Login />
)
}
/>
<Route path="/permissions" element={<Permissions />} />
</Route>
<Route path="/callback" element={<Callback />} />
<Route path="*" element={<div>Not found</div>} />
</Routes>
</ThemeProvider>
</RainbowKitProvider>
</RainbowKitAuthenticationProvider>
</QueryClientProvider>
</WagmiProvider>
<Route
element={
<ProtectedRoute>
<DefaultLayout />
</ProtectedRoute>
}
>
<Route path="/" element={<Dashboard />} />
<Route path="/identifiers" element={<Identifiers />} />
<Route
path="identifiers/:providers/attestation"
element={<Attestation />}
/>
<Route path="/permissions" element={<Permissions />} />
</Route>
<Route path="/callback" element={<Callback />} />
<Route path="*" element={<div>Not found</div>} />
</Routes>
</ThemeProvider>
</RainbowKitProvider>
</RainbowKitAuthenticationProvider>
</QueryClientProvider>
</WagmiProvider>
</LitProvider>
</BrowserRouter>
);
};
Expand Down
162 changes: 95 additions & 67 deletions src/components/shared/CustomTable.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,110 @@
import { TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Avatar, Typography, Card } from '@mui/material';
import {
TableContainer,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
Avatar,
Typography,
Card,
} from '@mui/material';
import AccessControlButton from './AccessControlButton';

export interface Platform {
name: string;
icon: React.ReactNode;
id: string;
provider: string;
uid: string;
}

export interface AccessData {
application: string;
[platform: string]: boolean | string;
}

export interface Column<T> {
field: keyof T;
headerName?: string;
headerComponent?: React.ReactNode;
renderCell?: (value: any, row: T) => React.ReactNode;
applicationName: string;
account: string;
hasPermission: boolean;
uid: string;
}

export interface CustomTableProps<T> {
xcolumns: Platform[];
ycolumns: T[];
data: T[];
xcolumns: Platform[];
ycolumns: T[];
handleGrantOrRevokeAccess: (application: T, platform: Platform) => void;
}

const CustomTable: React.FC<CustomTableProps<AccessData>> = ({ xcolumns, ycolumns, data }) => {
const handleToggleAccess = (rowIndex: number, platform: string) => {
// Implement the logic to toggle access
console.log(`Toggle access for row ${rowIndex}, platform ${platform}`);
};
const CustomTable: React.FC<CustomTableProps<AccessData>> = ({
xcolumns,
ycolumns,
handleGrantOrRevokeAccess,
}) => {
console.log('xcolumns:', xcolumns);
console.log('ycolumns:', ycolumns);

const groupedApplications = ycolumns.reduce(
(acc, application) => {
if (!acc[application.applicationName]) {
acc[application.applicationName] = [];
}
acc[application.applicationName].push(application);
return acc;
},
{} as Record<string, AccessData[]>
);

const handleToggleAccess = (application: AccessData, platform: Platform) => {
handleGrantOrRevokeAccess(application, platform);
};

return (
<TableContainer>
<Table>
<TableHead>
<TableRow component={Card}>
<TableCell sx={{ padding: 1 }} align="center">
<Typography fontWeight="bold">
Applications \ Identifiers
</Typography>
</TableCell>
{xcolumns.map((platform, index) => (
<TableCell key={index} align="center" sx={{ padding: 1 }}>
<div className="flex flex-row space-x-1.5 items-center justify-center">
<Avatar>
{platform.icon}
</Avatar>
<Typography>{platform.name}</Typography>
</div>
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{ycolumns.map((application, rowIndex) => (
<TableRow component={Card} key={rowIndex}>
<TableCell align="center" sx={{ padding: 1 }}>
<div className='flex flex-col items-center justify-center text-center mx-auto space-y-2'>
<Avatar />
<Typography>
{application.application}
</Typography>
</div>
</TableCell>
{xcolumns.map((platform, colIndex) => (
<TableCell key={colIndex} align="center">
<AccessControlButton
hasAccess={data[rowIndex][platform.name] as boolean}
onToggleAccess={() => handleToggleAccess(rowIndex, platform.name)}
/>
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
return (
<TableContainer>
<Table>
<TableHead>
<TableRow component={Card}>
<TableCell sx={{ padding: 1 }} align="center">
<Typography fontWeight="bold">
Applications \ Providers
</Typography>
</TableCell>
{xcolumns.map((platform, index) => (
<TableCell key={index} align="center" sx={{ padding: 1 }}>
<div className="flex flex-row space-x-1.5 items-center justify-center">
<Avatar>{platform.provider[0].toUpperCase()}</Avatar>
<Typography>{platform.provider}</Typography>
</div>
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{Object.entries(groupedApplications).map(
([applicationName, applications], rowIndex) => (
<TableRow component={Card} key={rowIndex}>
<TableCell align="center" sx={{ padding: 1 }}>
<div className="flex flex-col items-center justify-center text-center mx-auto space-y-2">
<Avatar />
<Typography>{applicationName}</Typography>
</div>
</TableCell>
{xcolumns.map((platform, colIndex) => {
const application = applications.find(
(app) => app.uid === platform.uid
);
return (
<TableCell key={colIndex} align="center">
<AccessControlButton
hasAccess={application?.hasPermission || false}
onToggleAccess={() =>
handleToggleAccess(application!, platform)
}
/>
</TableCell>
);
})}
</TableRow>
)
)}
</TableBody>
</Table>
</TableContainer>
);
};

export default CustomTable;
72 changes: 72 additions & 0 deletions src/hooks/LitProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
ReactElement,
createContext,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { LitNodeClient } from '@lit-protocol/lit-node-client';
import { LitNetwork } from '@lit-protocol/constants';

interface ILitProvider {
litNetwork: LitNetwork;
children: ReactElement;
}

const defaultLitNodeClient = new LitNodeClient({
litNetwork: LitNetwork.DatilDev,
});
const LitClientContext = createContext({
litNodeClient: defaultLitNodeClient,
litConnected: false,
});

export const LitProvider = ({ litNetwork, children }: ILitProvider) => {
const client = useMemo(
() =>
new LitNodeClient({
alertWhenUnauthorized: false,
litNetwork,
debug: true,
}),
[litNetwork] // Include litNetwork as a dependency
);

const [connected, setConnected] = useState(false);

useEffect(() => {
const connect = async () => {
try {
await client.connect();
setConnected(true);
console.log(`Connected to Lit Network: ${litNetwork}`);
} catch (error) {
console.error('Failed to connect to Lit Network:', error);
setConnected(false);
}
};

connect();

return () => {
// Add cleanup if necessary, e.g., disconnect the client
client.disconnect?.();
};
}, [client, litNetwork]); // Include client as a dependency

const contextValue = useMemo(
() => ({ litNodeClient: client, litConnected: connected }),
[client, connected] // Memoize the context value to avoid unnecessary re-renders
);

return (
<LitClientContext.Provider value={contextValue}>
{children}
</LitClientContext.Provider>
);
};

export default function useLit() {
return useContext(LitClientContext);
}
Loading

0 comments on commit fa43b93

Please sign in to comment.