Skip to content
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

Addressing code reviews #18

Merged
merged 28 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9b6792e
remove external nullifier and watermark default value
veronicaz41 Jul 17, 2024
8059bfb
rewrite readme example use case section
veronicaz41 Jul 17, 2024
d78a5f0
rewrite what's inside section
veronicaz41 Jul 17, 2024
52e2857
delete unhelpful readmes
veronicaz41 Jul 17, 2024
c8865a6
move toString inside tryRecordNullifierHash
veronicaz41 Jul 17, 2024
4865685
move nullifierHash check to the last due to side-effects
veronicaz41 Jul 17, 2024
cb7c680
remove unused public folder
veronicaz41 Jul 17, 2024
9f3bd0e
more comments for generateProof
veronicaz41 Jul 18, 2024
1783ccc
externalNullifer and watermark in proofConfig should be PODValue
veronicaz41 Jul 18, 2024
5241266
separate out proof request in a separate file
veronicaz41 Jul 18, 2024
ed58a97
fix client side semaphoreCommitment declaration, should be string
veronicaz41 Jul 18, 2024
1806d10
use dateOfBirth, instead of age
veronicaz41 Jul 19, 2024
dd0f943
check startDate and issueDate
veronicaz41 Jul 19, 2024
2e5c4b1
put login logic in handleLogin
veronicaz41 Jul 19, 2024
54907d7
separate out UI code
veronicaz41 Jul 19, 2024
9be38ee
add socialSecurityNumber check
veronicaz41 Jul 19, 2024
c48e716
env vars
veronicaz41 Jul 19, 2024
7094d41
use separate JWT_SECRET_KEY
veronicaz41 Jul 19, 2024
0d9f006
fix startDate
veronicaz41 Jul 19, 2024
03a3c72
need to memorize proofRequest
veronicaz41 Jul 19, 2024
d5d9bf4
add script to generate public keys
veronicaz41 Jul 19, 2024
e7b5f20
yarn localenv
veronicaz41 Jul 19, 2024
7a14e63
fix dateOfBirth
veronicaz41 Jul 19, 2024
7685639
fix warnings
veronicaz41 Jul 23, 2024
9fdbe06
fix cors issue when connecting to the local kv store for developing
veronicaz41 Jul 23, 2024
7a396e2
Merge pull request #21 from proofcarryingdata/vzheng/cors
veronicaz41 Jul 23, 2024
6c2bf76
add a debug page in verifier to remove nullifier hash from kv store
veronicaz41 Jul 23, 2024
011abd7
more explanation for yarn localdb
veronicaz41 Jul 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 67 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
# Zukyc

This is an example app using POD & GPC.
For details about POD & GPC, see [this doc](https://0xparc.notion.site/POD-GPC-Development-6547d2e60c184ad0984f933672246e0b#25ea9b2a90464663b36486f5e6064106).
For details about POD & GPC, see [this doc](https://zupass.org/pod).
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved

## Example use case

This example app demonstrated an end to end use case for POD & GPC. The story goes, Gerry would like to borrow some money, so he goes to ZooLender. The ZooLender wants him to prove that he has a valid ID, and has monthly income over $X amount, among other things. Gerry doesn't know ZooLender well, so he doesn't feel comfortable to send him his ID and paystubs. So they decide to use ZooKyc (in `gpc-prover-client`).
This example app demonstrates an end to end use case for POD & GPC. The story goes, Gerry the giraffe would like to borrow some money, so he goes to [ZooLender](https://zukyc-gpc-verifier.vercel.app). ZooLender wants him to prove that he has a valid ID, and has annual income over $20,000 amount among other things. Gerry doesn't know ZooLender well. He doesn't feel comfortable to send him his ID and paystubs. So they decide to use [ZooKyc](https://zukyc-gpc-prover-client.vercel.app) (KYC stands for [Know Your Customer](https://en.wikipedia.org/wiki/Know_your_customer)).

To use ZooKyc, Gerry first goes to ZooGov (in `pod-issuer-client/app/gov`, `pod-issuer-server`), and ZooGov issues him an ID POD signed by ZooGov. Gerry then goes to ZooDeel (in `pod-issuer-client/app/deel`, `pod-issuer-server`), and ZooDeel issues him a Paystub POD signed by ZooDeel. All the PODs have a owner field with Gerry's Semaphore public identity.
ZooKyc manages the user's identity (e.g. [Semaphore identity](https://docs.semaphore.pse.dev/V3/guides/identities)), PODs, and generate proofs upon requests.

Gerry then goes to ZooKyc with his ID POD, Paystub POD, and Semaphore identity. ZooKyc creates a ZK proof that Gerry has a valid ID, and has monthly income over $X amount, without leaking other information. ZooKyc is a browser only app. In fact, Gerry can take the code from ZooKyc and run it himself.
Now with the proof generated by ZooKyc, Gerry goes back to ZooLender (in `gpc-verifier-client`). ZooLender verifies the proof, and lends Gerry the money.
To use ZooKyc, Gerry first goes to [ZooGov](https://zukyc-issuer-client.vercel.app/gov) (a govenment website), and ZooGov issues him a govenment ID POD signed by ZooGov. Gerry then goes to [ZooDeel](https://zukyc-issuer-client.vercel.app/deel) (a payroll service provider website), and ZooDeel issues him a paystub POD signed by ZooDeel. All the PODs have a owner field with Gerry's Semaphore public identity.

ZooLender provides Gerry a [proof request](https://github.com/proofcarryingdata/zukyc/blob/main/apps/gpc-verifier/app/hooks/useProofRequest.ts) which specifics what he wants Gerry to prove about the govenment ID POD and the paystub POD.

Gerry then goes to ZooKyc with his ID POD, Paystub POD, and the proof request from ZooLender. ZooKyc creates a zero knowledge proof that Gerry has a valid ID, and has annual income over $20,000 amount (among other things) without leaking other information. ZooKyc is a browser only app. In fact, Gerry can take the code from ZooKyc and run it himself.
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved

Now with the proof generated by ZooKyc, Gerry goes back to ZooLender. ZooLender verifies the proof, and lends Gerry the money.

You can walk through Gerry's experience using the deployed app links below.
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved

## Deployed app

- [ZooLender](https://zukyc-gpc-verifier.vercel.app): a lending website. To apply for a loan, the user can use ZooKyc to generate a proof with the proof request ZooLender provides. ZooLender will verify the proof, and decide whether to lend the user the money.
- [ZooKyc](https://zukyc-gpc-prover-client.vercel.app): manages the user's identity, PODs, and generate proofs upon requests.
- [ZooGov](https://zukyc-issuer-client.vercel.app/gov): a govenment website. It can issue govenment ID POD.
- [ZooDeel](https://zukyc-issuer-client.vercel.app/deel): a payroll service provider website. It can issue paystub POD.
- [ZooAdmin](https://zukyc-issuer-client.vercel.app/debug): for debugging purposes. It allows you to generate govenment ID POD and paystub POD with the information you provide.

## Example code

Expand All @@ -21,46 +36,65 @@ Now with the proof generated by ZooKyc, Gerry goes back to ZooLender (in `gpc-ve

## What's inside?

This Turborepo includes the following apps:
This Turborepo includes the following apps (inside the `apps/` folder):

### Apps
### POD issuers (ZooGov, ZooDeel, ZooAdmin)

- `pod-issuer-client`: http://localhost:3000, deployed at https://zukyc-issuer-client.vercel.app. It includes:
- [ZooGov](https://zukyc-issuer-client.vercel.app/gov): Govenment ID POD issuer.
- [ZooDeel](https://zukyc-issuer-client.vercel.app/deel): Paystub POD issuer.
- [ZooAdmin](https://zukyc-issuer-client.vercel.app/debug): For debugging purposes, it allows you to generate ID PODs and Paystub PODs with the information you provide.
- `pod-issuer-server`: http://localhost:8080, deployed at https://zukyc-issuer-server.vercel.app.
- This is the Express server for pod-issuer-client. It provides the APIs to issues PODs to the user.
- `gpc-prover-client` (ZooKyc): http://localhost:3002, deployed at https://zukyc-gpc-prover-client.vercel.app.
- This is a Next.js app which uses the GPC library to generate ZK proofs. GPCs can prove properties of one POD or serveral PODs together. PODs can be proven to be owned by the prover, using their Semaphore identity.
- `gpc-verifier` (ZooLender): http://localhost:3001, deployed at https://zukyc-gpc-verifier.vercel.app.
- This is a Next.js app which uses the GPC library to verify ZK proofs.
- I didn't build a server side app for this, because the verification code would be similar. But in reality, the proof needs to be verified on the server side too.
#### `pod-issuer-client`

### Turborepo
- http://localhost:3000, deployed at https://zukyc-issuer-client.vercel.app.
- This is the frontend of POD issuers (ZooGov, ZooDeel and ZooAdmin).
- It includes:
- `app/gov`: ZooGov
- `app/deel`: ZooDeel
- `app/debug`: ZooAdmin
- In real world, those would be three independent websites.
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved

This project was bootstrapped with [Turborepo starter](https://github.com/vercel/turbo/tree/main/examples/basic) by running the following command:
#### `pod-issuer-server`

```sh
npx create-turbo@latest -e with-yarn
```
- http://localhost:8080, deployed at https://zukyc-issuer-server.vercel.app.
- This is the server for pod-issuer-client. It provides the server-side APIs to issues PODs to the user.
- It includes:
- `routes/gov.ts`: server-side APIs for ZooGov
- `routes/deel.ts`: server-side APIs for ZooDeel
- `routes/debug.ts`: server-side APIs for ZooAdmin
- Similarly, in real world, those would be three independent server-side applications issuing PODs independently.
- A server is needed because in real world, the server would have a user database; and the server would hold a signing key for issuing PODs.

## Getting started
### ZooKyc

### Build
#### `gpc-prover-client`

To build all apps and packages, run the following command:
- http://localhost:3002, deployed at https://zukyc-gpc-prover-client.vercel.app.
- This is a frontend app which manages Semaphore identity, PODs, and uses the GPC library to generate ZK proofs based on proof requests.

```
cd zukyc
yarn build
```
### ZooLender

#### `gpc-verifier`

- http://localhost:3001, deployed at https://zukyc-gpc-verifier.vercel.app.
- This is a frontend app which provides the proof request, and uses the GPC library to verify ZK proofs.
- In this demo, the server side code is not included, because the proof verification code would be similar. But in real world, the proof needs to be verified on the server side too.
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved

## Local development

### Develop
### Running the project

To develop all apps and packages, run the following command:
In the root of this project, execute the following commands locally.

```
cd zukyc
# installs dependencies for all apps and packages in this repository
yarn

# this will copy all the environment variable file .env.example into an adjacent file .env or .env.local
veronicaz41 marked this conversation as resolved.
Show resolved Hide resolved
yarn localenv

# this will run a docker image for Vercel KV store (a durable Redis database) local development
# you need to install docker first and make sure it is running, see this: https://docs.docker.com/engine/install/
# the Vercel KV store is currently used by `pod-issuer-server` `gov` and `deel` routes, as well as
# `gpc-verifier` for storing nullifier hash.
yarn localdb
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I didn't have to do this, maybe because I'd already done it for the zupass or pod-arg repos?

Copy link
Collaborator Author

@veronicaz41 veronicaz41 Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, i'm not sure, the pod-arg repo used to have a .env.local file with all those env vars set. I don't want to expose those here because this is a public repo.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was commenting on "yarn localdb" in particular, which I never ran when I set up this repo.

Copy link
Collaborator Author

@veronicaz41 veronicaz41 Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible your KV_REST_API_URL and KV_REST_API_TOKEN in .env.local and .env files point to the Vercel KV store.
Otherwise, if it points to the local redis (http://localhost:8079), you will see errors when issuing PODs in gov and deel routes; also when you try to verify a proof in ZooLender.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I just misremembered how far I ever got in my local testing.
After pulling the latest code, I was able to follow the steps here successfully, and did see various errors if I skipped steps.


# starts all the applications contained in the `/apps` folder of the repository
yarn dev
```
5 changes: 3 additions & 2 deletions apps/gpc-prover-client/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
NEXT_PUBLIC_POD_ISSUER_CLIENT_URL=
NEXT_PUBLIC_GPC_VERIFIER_URL=
# URLs to other zukyc applications
NEXT_PUBLIC_POD_ISSUER_CLIENT_URL=http://localhost:3000
NEXT_PUBLIC_GPC_VERIFIER_URL=http://localhost:3001
28 changes: 0 additions & 28 deletions apps/gpc-prover-client/README.md

This file was deleted.

2 changes: 2 additions & 0 deletions apps/gpc-prover-client/app/components/PODs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const PODs = () => {
value={idPODStr}
placeholder="Past your ID POD here!"
onChange={(e) => setIdPODStr(e.target.value.trim())}
id="id-pod"
/>
</div>

Expand All @@ -44,6 +45,7 @@ const PODs = () => {
value={paystubPODStr}
placeholder="Past your Paystub POD here!"
onChange={(e) => setPaystubPODStr(e.target.value.trim())}
id="paystub-pod"
/>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions apps/gpc-prover-client/app/components/SemaphoreID.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const SemaphoreID = () => {
readOnly
rows={1}
value={identity?.commitment.toString()}
id="identity-commitment"
/>
</div>

Expand All @@ -62,6 +63,7 @@ const SemaphoreID = () => {
readOnly
rows={1}
value={identity?.toString()}
id="identity"
/>
</div>
</div>
Expand Down
21 changes: 12 additions & 9 deletions apps/gpc-prover-client/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,27 @@ import PODs from "@/components/PODs";
import usePODs from "@/hooks/usePODs";

export default function Prover() {
const [requestStr, setRequestStr] = useState("");
const [proofResult, setProofResult] = useState("");
const [proofRequestStr, setProofRequestStr] = useState("");
const [proofResult, setProofResult] = useState<string | null>(null);

const identity = useIdentity();
const { idPODStr, paystubPODStr } = usePODs();

const generate = useCallback(() => {
const generate = async () => {
if (!identity) {
alert("Identity cannot be empty!");
return;
}

generateProof(
const proof = await generateProof(
identity,
idPODStr,
paystubPODStr,
requestStr,
setProofResult
proofRequestStr
);
}, [identity, idPODStr, paystubPODStr, requestStr]);

setProofResult(proof);
};

const reset = useCallback(() => {
if (
Expand Down Expand Up @@ -69,9 +70,10 @@ export default function Prover() {
</div>
<textarea
rows={20}
value={requestStr}
value={proofRequestStr}
placeholder="Past your proof request here!"
onChange={(e) => setRequestStr(e.target.value.trim())}
onChange={(e) => setProofRequestStr(e.target.value.trim())}
id="proof-request"
/>
<div>
<button onClick={generate}>Generate Proof</button>
Expand All @@ -95,6 +97,7 @@ export default function Prover() {
readOnly
rows={30}
value={proofResult}
id="proof-result"
/>
</div>
)}
Expand Down
Loading