-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add discourse * fix * fix * update ts config * fix * fix * fix * fix * fix * fix * fix * fix
- Loading branch information
1 parent
e71e426
commit 39e3596
Showing
14 changed files
with
12,644 additions
and
20,940 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
104 changes: 104 additions & 0 deletions
104
src/components/pages/attestations/DiscourseStepFour.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { useState } from 'react'; | ||
import { | ||
Box, | ||
Button, | ||
CircularProgress, | ||
Stack, | ||
Typography, | ||
} from '@mui/material'; | ||
import { FaLink } from 'react-icons/fa'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { Address } from 'viem'; | ||
import { useAccount } from 'wagmi'; | ||
|
||
import { AttestPayload } from '../../../interfaces'; | ||
import EASService from '../../../services/eas.service'; | ||
import useSnackbarStore from '../../../store/useSnackbarStore'; | ||
import { contracts } from '../../../utils/contracts/eas/contracts'; | ||
import { useSigner } from '../../../utils/eas-wagmi-utils'; | ||
|
||
interface DiscourseStepFourProps { | ||
attestedSignutare: AttestPayload | null; | ||
} | ||
|
||
const DiscourseStepFour: React.FC<DiscourseStepFourProps> = ({ | ||
attestedSignutare, | ||
}) => { | ||
const { showSnackbar } = useSnackbarStore(); | ||
const navigate = useNavigate(); | ||
const signer = useSigner(); | ||
const { chainId } = useAccount(); | ||
const [isLoading, setIsLoading] = useState<boolean>(false); | ||
|
||
const easContractAddress = contracts.find( | ||
(contract) => contract.chainId === chainId | ||
)?.easContractAddress; | ||
|
||
const easService = signer | ||
? new EASService(easContractAddress as Address, signer) | ||
: null; | ||
|
||
const handleAttestByDelegation = async () => { | ||
if (!easService) { | ||
throw new Error('EAS service not initialized'); | ||
} | ||
if (!attestedSignutare) throw new Error('No attested signature provided'); | ||
|
||
setIsLoading(true); | ||
try { | ||
await easService.attestByDelegation(attestedSignutare); | ||
showSnackbar('Attestation successfully completed.', { | ||
severity: 'success', | ||
}); | ||
navigate('/identifiers'); | ||
} catch (error) { | ||
console.error('Error attesting identifier:', error); | ||
showSnackbar('Failed to complete the attestation. Please try again.', { | ||
severity: 'error', | ||
}); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<Stack | ||
spacing={3} | ||
sx={{ | ||
textAlign: 'center', | ||
py: 12, | ||
px: 2, | ||
}} | ||
> | ||
<Typography variant="h5" fontWeight="bold"> | ||
Finalize Delegated Attestation | ||
</Typography> | ||
<Typography> | ||
To complete the process, you will be asked to sign a message with your | ||
wallet, confirming ownership of the provided address. | ||
</Typography> | ||
<Box> | ||
<Button | ||
variant="contained" | ||
startIcon={ | ||
isLoading ? ( | ||
<CircularProgress color="inherit" size={20} /> | ||
) : ( | ||
<FaLink /> | ||
) | ||
} | ||
sx={{ mt: 2, px: 4 }} | ||
onClick={handleAttestByDelegation} | ||
disabled={isLoading} | ||
> | ||
{isLoading ? 'Processing...' : 'Sign Delegated Attestation'} | ||
</Button> | ||
</Box> | ||
<Typography variant="caption"> | ||
You need to pay some <b>gas</b> to complete the process. | ||
</Typography> | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default DiscourseStepFour; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Box, Button, Stack, Typography } from '@mui/material'; | ||
import { jwtDecode } from 'jwt-decode'; | ||
import { FaDiscourse } from 'react-icons/fa'; | ||
|
||
import { useGenerateDiscourseVerificationTokenMutation } from '../../../services/api/eas/query'; | ||
import useSnackbarStore from '../../../store/useSnackbarStore'; | ||
|
||
interface DiscourseStepOneProps { | ||
handleNextStep: () => void; | ||
} | ||
|
||
const DiscourseStepOne: React.FC<DiscourseStepOneProps> = ({ | ||
handleNextStep, | ||
}) => { | ||
const { showSnackbar } = useSnackbarStore(); | ||
const { mutate: mutateGenerateDiscourseVerificationToken, isPending } = | ||
useGenerateDiscourseVerificationTokenMutation(); | ||
|
||
const handleGenerateDiscourseVerificationToken = async () => { | ||
const siweJwt = localStorage.getItem('OCI_TOKEN') as string; | ||
|
||
mutateGenerateDiscourseVerificationToken( | ||
{ | ||
siweJwt, | ||
}, | ||
{ | ||
onSuccess: (response) => { | ||
const { data } = response; | ||
|
||
localStorage.setItem( | ||
'DISCOURSE_VERIFICATION_TOKEN', | ||
data.verificationJwt | ||
); | ||
|
||
const { code } = jwtDecode(data.verificationJwt) as { code: string }; | ||
localStorage.setItem('DISCOURSE_VERIFICATION_CODE', code); | ||
|
||
handleNextStep(); | ||
}, | ||
onError: (error) => { | ||
console.error('Failed to generate token:', error); | ||
showSnackbar( | ||
'Failed to generate verification token. Please try again.', | ||
{ | ||
severity: 'error', | ||
} | ||
); | ||
}, | ||
} | ||
); | ||
}; | ||
|
||
return ( | ||
<Stack | ||
spacing={2} | ||
sx={{ | ||
textAlign: 'center', | ||
py: 12, | ||
}} | ||
> | ||
<Typography variant="h5" fontWeight="bold"> | ||
Let’s get started! | ||
</Typography> | ||
<Typography variant="body2"> | ||
To attest your Discourse account, you need to generate a token. | ||
</Typography> | ||
<Box sx={{ display: 'block' }}> | ||
<Button | ||
variant="contained" | ||
startIcon={<FaDiscourse />} | ||
disabled={isPending} | ||
onClick={handleGenerateDiscourseVerificationToken} | ||
aria-busy={isPending} | ||
aria-live="polite" | ||
> | ||
{isPending ? 'Generating token...' : 'Generate token'} | ||
</Button> | ||
</Box> | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default DiscourseStepOne; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import React from 'react'; | ||
import { | ||
Box, | ||
Button, | ||
CircularProgress, | ||
Stack, | ||
Typography, | ||
} from '@mui/material'; | ||
import { FaLink } from 'react-icons/fa6'; | ||
import { useAccount } from 'wagmi'; | ||
|
||
import { Provider } from '../../../enums'; | ||
import { AttestPayload } from '../../../interfaces'; | ||
import { useLinkIdentifierMutation } from '../../../services/api/eas/query'; | ||
import { capitalize } from '../../../utils/helper'; | ||
|
||
interface DiscourseStepThreeProps { | ||
provider: Provider | undefined; | ||
handlePrepareAttestation: (payload: AttestPayload) => void; | ||
} | ||
|
||
const DiscourseStepThree: React.FC<DiscourseStepThreeProps> = ({ | ||
provider, | ||
handlePrepareAttestation, | ||
}) => { | ||
const { chainId } = useAccount(); | ||
const { mutate: mutateIdentifier, isPending } = useLinkIdentifierMutation( | ||
chainId as number | ||
); | ||
|
||
const handleGenerateSignedDelegation = async () => { | ||
const siweJwt = localStorage.getItem('OCI_TOKEN'); | ||
if (!siweJwt || !provider) return; | ||
|
||
const anyJwt = localStorage.getItem('DISCOURSE_JWT') as string; | ||
|
||
mutateIdentifier( | ||
{ | ||
siweJwt, | ||
anyJwt, | ||
}, | ||
{ | ||
onSuccess: (response) => { | ||
const { data } = response; | ||
handlePrepareAttestation(data); | ||
}, | ||
onError: (error) => { | ||
console.error(error); | ||
}, | ||
} | ||
); | ||
}; | ||
|
||
if (!provider) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Stack | ||
spacing={3} | ||
sx={{ | ||
textAlign: 'center', | ||
py: 12, | ||
px: 2, | ||
}} | ||
> | ||
<Typography variant="h5" fontWeight="bold"> | ||
Connect Your {capitalize(provider)} Account to Your Wallet | ||
</Typography> | ||
<Typography> | ||
To proceed, please verify your account by linking it to your wallet | ||
address. This step ensures your {capitalize(provider)} account is | ||
securely associated with your wallet. | ||
</Typography> | ||
<Box> | ||
<Button | ||
variant="contained" | ||
startIcon={ | ||
isPending ? ( | ||
<CircularProgress color="inherit" size={20} /> | ||
) : ( | ||
<FaLink /> | ||
) | ||
} | ||
sx={{ mt: 2, px: 4 }} | ||
onClick={handleGenerateSignedDelegation} | ||
disabled={isPending} | ||
> | ||
{isPending ? 'Processing...' : 'Get Signed Delegated Attestation'} | ||
</Button> | ||
</Box> | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default DiscourseStepThree; |
Oops, something went wrong.