diff --git a/README.md b/README.md index 01bf56a..fa38ecd 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 ``` diff --git a/apps/gpc-prover-client/.env.example b/apps/gpc-prover-client/.env.example index 63ac31d..9127bd0 100644 --- a/apps/gpc-prover-client/.env.example +++ b/apps/gpc-prover-client/.env.example @@ -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 diff --git a/apps/gpc-prover-client/README.md b/apps/gpc-prover-client/README.md deleted file mode 100644 index 3d7b63a..0000000 --- a/apps/gpc-prover-client/README.md +++ /dev/null @@ -1,28 +0,0 @@ -## Getting Started - -First, run the development server: - -```bash -yarn dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -To create [API routes](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) add an `api/` directory to the `app/` directory with a `route.ts` file. For individual endpoints, create a subfolder in the `api` directory, like `api/hello/route.ts` would map to [http://localhost:3000/api/hello](http://localhost:3000/api/hello). - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/apps/gpc-prover-client/app/components/PODs.tsx b/apps/gpc-prover-client/app/components/PODs.tsx index 103a67e..1ab9b49 100644 --- a/apps/gpc-prover-client/app/components/PODs.tsx +++ b/apps/gpc-prover-client/app/components/PODs.tsx @@ -25,6 +25,7 @@ const PODs = () => { value={idPODStr} placeholder="Past your ID POD here!" onChange={(e) => setIdPODStr(e.target.value.trim())} + id="id-pod" /> @@ -44,6 +45,7 @@ const PODs = () => { value={paystubPODStr} placeholder="Past your Paystub POD here!" onChange={(e) => setPaystubPODStr(e.target.value.trim())} + id="paystub-pod" /> diff --git a/apps/gpc-prover-client/app/components/SemaphoreID.tsx b/apps/gpc-prover-client/app/components/SemaphoreID.tsx index 3030d84..c4023bf 100644 --- a/apps/gpc-prover-client/app/components/SemaphoreID.tsx +++ b/apps/gpc-prover-client/app/components/SemaphoreID.tsx @@ -39,6 +39,7 @@ const SemaphoreID = () => { readOnly rows={1} value={identity?.commitment.toString()} + id="identity-commitment" /> @@ -62,6 +63,7 @@ const SemaphoreID = () => { readOnly rows={1} value={identity?.toString()} + id="identity" /> diff --git a/apps/gpc-prover-client/app/page.tsx b/apps/gpc-prover-client/app/page.tsx index ce7ba9d..e80edab 100644 --- a/apps/gpc-prover-client/app/page.tsx +++ b/apps/gpc-prover-client/app/page.tsx @@ -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(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 ( @@ -69,9 +70,10 @@ export default function Prover() {