diff --git a/src/components/pages/attestations/StepThree.tsx b/src/components/pages/attestations/StepThree.tsx index 43bc0ed..4141b2a 100644 --- a/src/components/pages/attestations/StepThree.tsx +++ b/src/components/pages/attestations/StepThree.tsx @@ -72,12 +72,18 @@ const StepThree: React.FC = ({ attestedSignutare }) => { diff --git a/src/components/pages/attestations/StepTwo.tsx b/src/components/pages/attestations/StepTwo.tsx index cf22455..afbd283 100644 --- a/src/components/pages/attestations/StepTwo.tsx +++ b/src/components/pages/attestations/StepTwo.tsx @@ -71,16 +71,18 @@ const StepTwo: React.FC = ({ diff --git a/src/hooks/useAttestations.tsx b/src/hooks/useAttestations.tsx index da55a42..bec71c9 100644 --- a/src/hooks/useAttestations.tsx +++ b/src/hooks/useAttestations.tsx @@ -1,36 +1,59 @@ -import { useMemo } from 'react'; +import { useEffect, useState } from 'react'; +import { SchemaDecodedItem } from '@ethereum-attestation-service/eas-sdk'; import { useAccount } from 'wagmi'; import { decodeAttestationData } from '../libs/oci'; import { useGetAttestations } from '../services/eas/query'; +interface ProcessedAttestation { + provider: string | undefined; + decodedData: SchemaDecodedItem[]; + uid: `0x${string}`; + schema: `0x${string}`; + refUID: `0x${string}`; + time: bigint; + expirationTime: bigint; + revocationTime: bigint; + recipient: `0x${string}`; + attester: `0x${string}`; + revocable: boolean; + data: `0x${string}`; + id?: string; +} + const useAttestations = () => { const { address, chainId } = useAccount(); const { data: attestationsResponse, error, isLoading, + refetch, } = useGetAttestations(address as `0x${string}`); - const attestations = useMemo(() => { - if (!attestationsResponse) { - return []; - } + const [attestations, setAttestations] = useState([]); - return attestationsResponse.map((attestation) => { - const decodedData = decodeAttestationData(attestation.data); + useEffect(() => { + if (attestationsResponse) { + const processedAttestations: ProcessedAttestation[] = + attestationsResponse.map((attestation) => { + const decodedData = decodeAttestationData(attestation.data); - const providerData = decodedData.find((data) => data.name === 'provider'); + const providerData = decodedData.find( + (data) => data.name === 'provider' + ); - return { - ...attestation, - provider: - typeof providerData?.value.value === 'string' - ? providerData.value.value - : undefined, - decodedData, - }; - }); + return { + ...attestation, + provider: + typeof providerData?.value.value === 'string' + ? providerData.value.value + : undefined, + decodedData, + }; + }); + + setAttestations(processedAttestations); + } }, [attestationsResponse]); return { @@ -38,6 +61,7 @@ const useAttestations = () => { attestations, isLoading, error, + refetch, }; }; diff --git a/src/pages/Identifiers/Identifiers.tsx b/src/pages/Identifiers/Identifiers.tsx index 140b1cc..59bae42 100644 --- a/src/pages/Identifiers/Identifiers.tsx +++ b/src/pages/Identifiers/Identifiers.tsx @@ -31,6 +31,7 @@ import { useRevokeIdentifierMutation, } from '../../services/api/eas/query'; import EASService from '../../services/eas.service'; +import useSnackbarStore from '../../store/useSnackbarStore'; import sepoliaChain from '../../utils/contracts/eas/sepoliaChain.json'; import { useSigner } from '../../utils/eas-wagmi-utils'; @@ -44,6 +45,7 @@ interface Identifier { export default function Identifiers() { const navigate = useNavigate(); + const { showSnackbar } = useSnackbarStore(); const [userIdentifiers, setUserIdentifiers] = useState([ { name: 'Discord', icon: FaDiscord, verified: false, uid: '' }, { name: 'Google', icon: FaGoogle, verified: false, uid: '' }, @@ -52,6 +54,7 @@ export default function Identifiers() { {} ); const [loading, setLoading] = useState<{ [key: string]: boolean }>({}); + const [revoking, setRevoking] = useState<{ [key: string]: boolean }>({}); const signer = useSigner(); @@ -64,6 +67,7 @@ export default function Identifiers() { isLoading: attestationsLoading, error, chainId, + refetch, } = useAttestations(); const { mutate: mutateRevoke } = useRevokeIdentifierMutation(); @@ -98,16 +102,31 @@ export default function Identifiers() { } }, [attestations]); - const revokeDelegation = async (response: RevokePayload) => { + const revokeDelegation = async (response: RevokePayload, uid: string) => { if (!easService) { throw new Error('EAS service not initialized'); } + setRevoking((prev) => ({ ...prev, [uid]: true })); + try { await easService.revokeByDelegation(response); - console.log('Revocation successful:'); + + showSnackbar('Attestation Revoke successfully completed.', { + severity: 'success', + }); + + await refetch(); } catch (error) { console.error('Error revoking identifier:', error); + showSnackbar( + 'Failed to complete the attestation revoke. Please try again.', + { + severity: 'error', + } + ); + } finally { + setRevoking((prev) => ({ ...prev, [uid]: false })); } }; @@ -125,7 +144,7 @@ export default function Identifiers() { { uid, siweJwt, chainId }, { onSuccess: (response) => { - revokeDelegation(response.data as RevokePayload); + revokeDelegation(response.data as RevokePayload, uid); }, onError: (error) => { console.error('Error revoking identifier:', error); @@ -138,8 +157,6 @@ export default function Identifiers() { const handleReveal = useCallback( (identifier: Identifier) => { - console.log('Identifier:', identifier); - const siweJwt = localStorage.getItem('OCI_TOKEN'); if (!siweJwt) throw new Error('OCI SIWE token not found'); @@ -160,7 +177,6 @@ export default function Identifiers() { }, { onSuccess: (response) => { - console.log('Decrypted secret:', response); setUserIdentifiers((prev) => prev.map((id) => { if (id.uid === identifier.uid) { @@ -197,6 +213,19 @@ export default function Identifiers() { setOpenTooltips((prev) => ({ ...prev, [uid]: false })); }; + const renderButtonContent = (identifier: Identifier) => { + if (revoking[identifier.uid]) { + return ( + <> + + Revoking... + + ); + } + + return identifier.verified ? 'Revoke' : 'Connect'; + }; + if (attestationsLoading) { return ; } @@ -305,8 +334,9 @@ export default function Identifiers() { ? () => handleRevokeAttestation(identifier.uid) : () => handleConnectAttestation(identifier.name) } + disabled={revoking[identifier.uid]} > - {identifier.verified ? 'Revoke' : 'Connect'} + {renderButtonContent(identifier)}