-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: rebuilt wasm tutorial with next.js #5
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Integration Tests | ||
on: | ||
push: | ||
branches: ['main'] | ||
pull_request: | ||
branches: ['main'] | ||
paths-ignore: | ||
- 'README.md' | ||
jobs: | ||
ts-tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Use pnpm 8 | ||
uses: pnpm/action-setup@v2 | ||
with: | ||
version: 8 | ||
- name: Use Node.js 18.12.1 | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: '18.12.1' | ||
cache: 'pnpm' | ||
- name: Run linter | ||
run: pnpm run lint | ||
- name: Install dependencies and run wasm tests | ||
run: | | ||
pnpm install --no-frozen-lockfile | ||
NEXT_PUBLIC_REACT_APP_ENTRY_POINT=test pnpm run build | ||
env: | ||
CI: false | ||
NODE_ENV: development |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
DS_Store | ||
pkg |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
'use client' | ||
import React, { useEffect, useState } from 'react' | ||
|
||
import init from '../pkg/ezkl' | ||
|
||
import GenPK from './GenPk' | ||
import GenVk from './GenVk' | ||
import GenProof from './GenProof' | ||
import Verify from './Verify' | ||
import Hash from './Hash' | ||
|
||
interface Files { | ||
[key: string]: File | null | ||
} | ||
|
||
export default function Home() { | ||
const [files, setFiles] = useState<Files>({}) | ||
|
||
useEffect(() => { | ||
async function run() { | ||
// Initialize the WASM module | ||
await init() | ||
} | ||
run() | ||
}) | ||
|
||
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
const id = event.target.id | ||
const file = event.target.files?.item(0) || null | ||
setFiles((prevFiles) => ({ ...prevFiles, [id]: file })) | ||
} | ||
|
||
return ( | ||
<div className='App'> | ||
<GenPK | ||
files={{ | ||
model: files['model_ser_pk'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should be able to access this the normal way if you feel it's more readable |
||
srs: files['srs_ser_pk'], | ||
circuitSettings: files['circuit_settings_ser_pk'], | ||
}} | ||
handleFileChange={handleFileChange} | ||
/> | ||
|
||
<GenVk | ||
files={{ | ||
pk: files['pk_ser_vk'], | ||
circuitSettings: files['circuit_settings_ser_vk'], | ||
}} | ||
handleFileChange={handleFileChange} | ||
/> | ||
|
||
<GenProof | ||
files={{ | ||
data: files['data_prove'], | ||
pk: files['pk_prove'], | ||
model: files['model_ser_prove'], | ||
circuitSettings: files['circuit_settings_ser_prove'], | ||
srs: files['srs_ser_prove'], | ||
}} | ||
handleFileChange={handleFileChange} | ||
/> | ||
|
||
<Verify | ||
files={{ | ||
proof: files['proof_js'], | ||
vk: files['vk'], | ||
circuitSettings: files['circuit_settings_ser_verify'], | ||
srs: files['srs_ser_verify'], | ||
}} | ||
handleFileChange={handleFileChange} | ||
/> | ||
|
||
<Hash | ||
message={files['message_hash']} | ||
handleFileChange={handleFileChange} | ||
/> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { useState, ChangeEvent } from 'react' | ||
import { FileDownload, handleGenPkButton } from './Utils' | ||
|
||
interface GenPKProps { | ||
files: { | ||
model: File | null | ||
srs: File | null | ||
circuitSettings: File | null | ||
} | ||
handleFileChange: (event: ChangeEvent<HTMLInputElement>) => void | ||
} | ||
|
||
export default function GenPK({ files, handleFileChange }: GenPKProps) { | ||
const [buffer, setBuffer] = useState<Uint8Array | null>(null) | ||
const [pkResult, setPkResult] = useState<string>('') | ||
|
||
return ( | ||
<div> | ||
<h1>Generate Proving Key</h1> | ||
<label htmlFor='model_ser_pk'>Model (.onnx):</label> | ||
<input | ||
id='model_ser_pk' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='model_ser_pk' | ||
/> | ||
<label htmlFor='srs_ser_pk'>SRS:</label> | ||
<input | ||
id='srs_ser_pk' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='srs_ser_pk' | ||
/> | ||
<label htmlFor='circuit_settings_ser_pk'>Circuit settings:</label> | ||
<input | ||
id='circuit_settings_ser_pk' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='circuit_settings_ser_pk' | ||
/> | ||
<button | ||
id='genPkButton' | ||
onClick={async () => { | ||
if (Object.values(files).every((file) => file instanceof File)) { | ||
const result = await handleGenPkButton( | ||
files as { [key: string]: File }, | ||
) | ||
setBuffer(result) | ||
setPkResult( | ||
result ? 'Pk Generation Successful' : 'Pk Generation failed', | ||
) | ||
} | ||
}} | ||
disabled={!Object.values(files).every((file) => file instanceof File)} | ||
> | ||
Generate | ||
</button> | ||
{buffer && ( | ||
<FileDownload | ||
fileName='pk.key' | ||
buffer={buffer} | ||
handleDownloadCompleted={function (): void { | ||
setBuffer(null) | ||
}} | ||
/> | ||
)} | ||
<h2>Result:</h2> | ||
<div>{pkResult}</div> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { useState, ChangeEvent } from 'react' | ||
import { handleGenProofButton, FileDownload } from './Utils' | ||
|
||
interface GenProofProps { | ||
files: { | ||
data: File | null | ||
pk: File | null | ||
model: File | null | ||
circuitSettings: File | null | ||
srs: File | null | ||
} | ||
handleFileChange: (event: ChangeEvent<HTMLInputElement>) => void | ||
} | ||
|
||
export default function GenProof({ files, handleFileChange }: GenProofProps) { | ||
const [proofResult, setProofResult] = useState('') | ||
const [buffer, setBuffer] = useState<Uint8Array | null>(null) | ||
return ( | ||
<div> | ||
<h1>Prove</h1> | ||
<label htmlFor='data_prove'>Input Data:</label> | ||
<input | ||
id='data_prove' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='data_prove' | ||
/> | ||
<label htmlFor='pk_prove'>Proving key:</label> | ||
<input | ||
id='pk_prove' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='pk_prove' | ||
/> | ||
<label htmlFor='model_ser_prove'>Model (.onnx):</label> | ||
<input | ||
id='model_ser_prove' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='model_ser' | ||
/> | ||
<label htmlFor='circuit_settings_ser_prove'>Circuit settings:</label> | ||
<input | ||
id='circuit_settings_ser_prove' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='circuit_settings_ser_prove' | ||
/> | ||
<label htmlFor='srs_ser_prove'>SRS:</label> | ||
<input | ||
id='srs_ser_prove' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='srs_ser_prove' | ||
/> | ||
<button | ||
id='genProofButton' | ||
onClick={async () => { | ||
if (Object.values(files).every((file) => file instanceof File)) { | ||
const result = await handleGenProofButton( | ||
files as { [key: string]: File }, | ||
) | ||
setBuffer(result) | ||
setProofResult( | ||
result | ||
? 'Proof generation successful' | ||
: 'Proof generation failed', | ||
) | ||
} | ||
}} | ||
disabled={!Object.values(files).every((file) => file instanceof File)} | ||
> | ||
Prove | ||
</button> | ||
{buffer && ( | ||
<FileDownload | ||
fileName='proof.proof' | ||
buffer={buffer} | ||
handleDownloadCompleted={function (): void { | ||
setBuffer(null) | ||
}} | ||
/> | ||
)} | ||
<h2>Result:</h2> | ||
<div>{proofResult}</div> | ||
</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { useState, ChangeEvent } from 'react' | ||
import { handleGenVkButton, FileDownload } from './Utils' | ||
|
||
interface GenVKProps { | ||
files: { | ||
pk: File | null | ||
circuitSettings: File | null | ||
} | ||
handleFileChange: (event: ChangeEvent<HTMLInputElement>) => void | ||
} | ||
|
||
export default function GenVk({ files, handleFileChange }: GenVKProps) { | ||
const [vkResult, setVkResult] = useState('') | ||
const [buffer, setBuffer] = useState<Uint8Array | null>(null) | ||
return ( | ||
<div> | ||
<h1>Generate Verification Key</h1> | ||
<label htmlFor='pk_ser_vk'>Proving key:</label> | ||
<input | ||
id='pk_ser_vk' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='pk_ser_vk' | ||
/> | ||
<label htmlFor='circuit_settings_ser_vk'>Circuit settings:</label> | ||
<input | ||
id='circuit_settings_ser_vk' | ||
type='file' | ||
onChange={handleFileChange} | ||
placeholder='circuit_settings_ser_vk' | ||
/> | ||
<button | ||
id='genVkButton' | ||
onClick={async () => { | ||
if (Object.values(files).every((file) => file instanceof File)) { | ||
const result = await handleGenVkButton( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is |
||
files as { [key: string]: File }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually want to avoid type casting with |
||
) | ||
setBuffer(result) | ||
setVkResult( | ||
result ? 'Vk Generation successful' : 'Vk Generation failed', | ||
) | ||
} | ||
}} | ||
disabled={!Object.values(files).every((file) => file instanceof File)} | ||
> | ||
Generate | ||
</button> | ||
{buffer && ( | ||
<FileDownload | ||
fileName='vk.key' | ||
buffer={buffer} | ||
handleDownloadCompleted={function (): void { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. arrow function probably cleaner here. Usually better not to add explicit return types and let TS infer it for you. |
||
setBuffer(null) | ||
}} | ||
/> | ||
)} | ||
<h2>Result:</h2> | ||
<div>{vkResult}</div> | ||
</div> | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There components should live in
/components