Skip to content

Commit

Permalink
Proof generation (#62)
Browse files Browse the repository at this point in the history
* add gen proof modal
  • Loading branch information
lukachi authored Mar 18, 2024
1 parent df3b73b commit e22fffb
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 207 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@mui/x-charts": "^6.19.5",
"@mui/x-date-pickers": "^6.18.7",
"@rarimo/client": "^2.0.0",
"@rarimo/rarime-connector": "^2.1.0-rc.12",
"@rarimo/rarime-connector": "^2.1.0-rc.13",
"canvas-confetti": "^1.9.2",
"copy-to-clipboard": "^3.3.3",
"i18next": "^22.4.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { Button, Dialog, DialogProps, Divider, Typography, useTheme } from '@mui/material'
import { Stack } from '@mui/system'
import { CircuitId, W3CCredential, ZKProof } from '@rarimo/rarime-connector'
import { useCallback, useMemo, useState } from 'react'

import { zkpSnap } from '@/api/clients'
import { Icons } from '@/enums'
import { ErrorHandler } from '@/helpers'
import { useCopyToClipboard } from '@/hooks'
import { UiDialogActions, UiDialogContent, UiDialogTitle, UiIcon } from '@/ui'

interface Props extends DialogProps {
vc: W3CCredential
}

export default function ProofGenerationModal({ vc, ...rest }: Props) {
const { isCopied, copy } = useCopyToClipboard()

const [isPending, setIsPending] = useState(false)
const { palette, spacing } = useTheme()

const [generatedProof, setGeneratedProof] = useState<ZKProof>()

const createProofRequest = useMemo(() => {
return {
circuitId: CircuitId.AtomicQueryMTPV2OnChain,
accountAddress: vc.credentialSubject.address as string,
issuerDid: vc.issuer,

// TODO: get proof query based on the VC
query: {
allowedIssuers: ['*'],
credentialSubject: {
isNatural: {
$eq: 1,
},
},
type: vc.type,
},
}
}, [vc.credentialSubject.address, vc.issuer, vc.type])

const generateProof = useCallback(async () => {
setIsPending(true)

try {
const proof = await zkpSnap.createProof({
// FIXME: some DOM elements or large functions is in _prototype,
// so metamask API can't serialize it
...JSON.parse(JSON.stringify(createProofRequest)),
})

setGeneratedProof(proof.zkpProof)
} catch (error) {
ErrorHandler.process(error)
}

setIsPending(false)
}, [createProofRequest])

const generationDetails = useMemo(() => {
return [
{
text: 'Query',
value: (
<Typography
component='pre'
variant='body4'
bgcolor={palette.action.active}
p={2}
borderRadius={1}
sx={{ overflowX: 'auto' }}
>
{JSON.stringify(createProofRequest, null, 2)}
</Typography>
),
},
...(generatedProof
? [
{
text: 'Proof',
value: (
<Stack spacing={2}>
<Typography
component='pre'
variant='body4'
bgcolor={palette.action.active}
p={2}
borderRadius={1}
sx={{ overflowX: 'auto' }}
>
{JSON.stringify(generatedProof, null, 2)}
</Typography>

<Button
fullWidth
startIcon={<UiIcon name={isCopied ? Icons.Check : Icons.CopySimple} size={5} />}
onClick={() => copy(JSON.stringify(vc, null, 2))}
>
{isCopied ? 'Copied' : 'Copy Proof'}
</Button>
</Stack>
),
},
]
: []),
]
}, [palette.action.active, createProofRequest, generatedProof, isCopied, copy, vc])

return (
<Dialog {...rest} PaperProps={{ sx: { maxWidth: spacing(160) } }}>
<UiDialogTitle onClose={rest.onClose}>Generate Proof</UiDialogTitle>
<UiDialogContent>
<Stack spacing={2}>
{generationDetails.map(({ text, value }, index) => (
<Stack key={index} spacing={2}>
<Stack spacing={1}>
<Typography variant='body4' color={palette.text.secondary}>
{text}
</Typography>
{value}
</Stack>
{index < generationDetails.length - 1 && <Divider />}
</Stack>
))}
</Stack>
</UiDialogContent>
<UiDialogActions>
<Button
fullWidth
startIcon={
<UiIcon name={isPending ? Icons.Lock : Icons.ArrowCounterClockwise} size={5} />
}
onClick={generateProof}
disabled={isPending}
>
{isPending ? 'Generating...' : 'Generate Proof'}
</Button>
</UiDialogActions>
</Dialog>
)
}
16 changes: 14 additions & 2 deletions src/pages/Credentials/pages/CredentialsId/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getClaimIdFromVC } from '@/api/modules/zkp'
import { BackLink, CredentialCard, NoDataView } from '@/common'
import { Icons, RoutePaths } from '@/enums'
import { ErrorHandler } from '@/helpers'
import ProofGenerationModal from '@/pages/Credentials/pages/CredentialsId/components/ProofGenerationModal'
import { useCredentialsState } from '@/store'
import { UiIcon } from '@/ui'

Expand All @@ -20,6 +21,7 @@ export default function CredentialsId() {

const [isPending, setIsPending] = useState(false)
const [isInfoModalOpen, setIsInfoModalOpen] = useState(false)
const [isProofGenModalOpen, setIsProofGenModalOpen] = useState(false)

const vc = useMemo(() => {
return vcs.find(vc => getClaimIdFromVC(vc) === claimId)
Expand Down Expand Up @@ -107,9 +109,13 @@ export default function CredentialsId() {

<Stack spacing={10} direction='row' justifyContent='center'>
{/* TODO: uncomment when actions are available */}
{/* <ActionButton iconProps={{ name: Icons.Plus }} disabled={isPending}>
<ActionButton
iconProps={{ name: Icons.Plus }}
onClick={() => setIsProofGenModalOpen(true)}
>
Generate proof
</ActionButton> */}
</ActionButton>

<ActionButton
iconProps={{ name: Icons.Info }}
disabled={isPending}
Expand All @@ -134,6 +140,12 @@ export default function CredentialsId() {
vc={vc}
onClose={() => setIsInfoModalOpen(false)}
/>

<ProofGenerationModal
vc={vc}
open={isProofGenModalOpen}
onClose={() => setIsProofGenModalOpen(false)}
/>
</Stack>
</Stack>
) : (
Expand Down
Loading

0 comments on commit e22fffb

Please sign in to comment.