Skip to content

Commit

Permalink
Merge pull request #18 from proofcarryingdata/vzheng/readme
Browse files Browse the repository at this point in the history
Addressing code reviews
  • Loading branch information
veronicaz41 authored Jul 23, 2024
2 parents e71a1a6 + 011abd7 commit 6f4e544
Show file tree
Hide file tree
Showing 66 changed files with 1,137 additions and 981 deletions.
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).

## 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.

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.

## 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.

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.

## 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
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
# 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

0 comments on commit 6f4e544

Please sign in to comment.